LibreOffice Module comphelper (master)  1
proxyaggregation.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <cassert>
23 
25 #include <com/sun/star/reflection/ProxyFactory.hpp>
26 
27 
28 namespace comphelper
29 {
30 
31 
32  using namespace ::com::sun::star::uno;
33  using namespace ::com::sun::star::lang;
34  using namespace ::com::sun::star::reflection;
35 
37  :m_xContext( _rxContext )
38  {
39  }
40 
41 
42  void OProxyAggregation::baseAggregateProxyFor( const Reference< XInterface >& _rxComponent, oslInterlockedCount& _rRefCount,
43  ::cppu::OWeakObject& _rDelegator )
44  {
45  // first a factory for the proxy
46  Reference< XProxyFactory > xFactory = ProxyFactory::create( m_xContext );
47 
48  // then the proxy itself
49  { // i36686 OJ: achieve the destruction of the temporary -> otherwise it leads to _rRefCount -= 2
50  m_xProxyAggregate = xFactory->createProxy( _rxComponent );
51  }
52  if ( m_xProxyAggregate.is() )
53  m_xProxyAggregate->queryAggregation( cppu::UnoType<decltype(m_xProxyTypeAccess)>::get() ) >>= m_xProxyTypeAccess;
54 
55  // aggregate the proxy
56  osl_atomic_increment( &_rRefCount );
57  if ( m_xProxyAggregate.is() )
58  {
59  // At this point in time, the proxy has a ref count of exactly two - in m_xControlContextProxy,
60  // and in m_xProxyTypeAccess.
61  // Remember to _not_ reset these members unless the delegator of the proxy has been reset, too!
62  m_xProxyAggregate->setDelegator( _rDelegator );
63  }
64  osl_atomic_decrement( &_rRefCount );
65  }
66 
67 
68  Any SAL_CALL OProxyAggregation::queryAggregation( const Type& _rType )
69  {
70  return m_xProxyAggregate.is() ? m_xProxyAggregate->queryAggregation( _rType ) : Any();
71  }
72 
73 
74  Sequence< Type > SAL_CALL OProxyAggregation::getTypes( )
75  {
76  Sequence< Type > aTypes;
77  if ( m_xProxyAggregate.is() )
78  {
79  if ( m_xProxyTypeAccess.is() )
80  aTypes = m_xProxyTypeAccess->getTypes();
81  }
82  return aTypes;
83  }
84 
85 
87  {
88  if ( m_xProxyAggregate.is() )
89  m_xProxyAggregate->setDelegator( nullptr );
90  m_xProxyAggregate.clear();
91  m_xProxyTypeAccess.clear();
92  // this should remove the _two_only_ "real" references (means not delegated to
93  // ourself) to this proxy, and thus delete it
94  }
95 
97  ::cppu::OBroadcastHelper& _rBHelper )
98  :OProxyAggregation( _rxContext )
99  ,m_rBHelper( _rBHelper )
100  {
101  OSL_ENSURE( _rxContext.is(), "OComponentProxyAggregationHelper::OComponentProxyAggregationHelper: invalid arguments!" );
102  }
103 
104 
106  const Reference< XComponent >& _rxComponent, oslInterlockedCount& _rRefCount,
107  ::cppu::OWeakObject& _rDelegator )
108  {
109  OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregationHelper::componentAggregateProxyFor: invalid inner component!" );
110  m_xInner = _rxComponent;
111 
112  // aggregate a proxy for the object
113  baseAggregateProxyFor( m_xInner.get(), _rRefCount, _rDelegator );
114 
115  // add as event listener to the inner context, because we want to be notified of disposals
116  osl_atomic_increment( &_rRefCount );
117  {
118  if ( m_xInner.is() )
119  m_xInner->addEventListener( this );
120  }
121  osl_atomic_decrement( &_rRefCount );
122  }
123 
124 
126  {
127  Any aReturn( BASE::queryInterface( _rType ) );
128  if ( !aReturn.hasValue() )
129  aReturn = OProxyAggregation::queryAggregation( _rType );
130  return aReturn;
131  }
132 
133 
135 
136 
138  {
139  OSL_ENSURE( m_rBHelper.bDisposed, "OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper: you should dispose your derived class in the dtor, if necessary!" );
140  // if this asserts, add the following to your derived class dtor:
141 
142  // if ( !m_rBHelper.bDisposed )
143  // {
144  // acquire(); // to prevent duplicate dtor calls
145  // dispose();
146  // }
147 
148  m_xInner.clear();
149  }
150 
151 
152  void SAL_CALL OComponentProxyAggregationHelper::disposing( const EventObject& _rSource )
153  {
154  if ( _rSource.Source == m_xInner )
155  { // it's our inner context which is dying -> dispose ourself
157  { // (if necessary only, of course)
158  dispose();
159  }
160  }
161  }
162 
163 
165  {
166  ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
167 
168  // dispose our inner context
169  // before we do this, remove ourself as listener - else in disposing( EventObject ), we
170  // would dispose ourself a second time
171  if ( m_xInner.is() )
172  {
173  m_xInner->removeEventListener( this );
174  m_xInner->dispose();
175  m_xInner.clear();
176  }
177  }
178 
180  const Reference< XComponent >& _rxComponent )
181  :WeakComponentImplHelperBase( m_aMutex )
182  ,OComponentProxyAggregationHelper( _rxContext, rBHelper )
183  {
184  OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregation::OComponentProxyAggregation: accessible is no XComponent!" );
185  if ( _rxComponent.is() )
186  componentAggregateProxyFor( _rxComponent, m_refCount, *this );
187  }
188 
189 
191  {
192  if ( !rBHelper.bDisposed )
193  {
194  acquire(); // to prevent duplicate dtor calls
195  dispose();
196  }
197  }
198 
199 
201 
202 
203  IMPLEMENT_GET_IMPLEMENTATION_ID( OComponentProxyAggregation )
204 
205 
206  Sequence< Type > SAL_CALL OComponentProxyAggregation::getTypes( )
207  {
210  // append XComponent, coming from WeakComponentImplHelperBase
211  Sequence { cppu::UnoType<XComponent>::get() });
212  }
213 
214 
215  void SAL_CALL OComponentProxyAggregation::disposing( const EventObject& _rSource )
216  {
217  // Simply disambiguate---this is necessary for MSVC to distinguish
218  // "disposing(EventObject)" from "disposing()"; but it is also a good
219  // place to check for recursive calls that would be caused by an object
220  // being registered as an XEventListener at itself (cf. rhbz#928568):
221  assert(_rSource.Source != static_cast< cppu::OWeakObject * >(this));
223  }
224 
225 
227  {
228  // call the dispose-functionality of the base, which will dispose our aggregated component
230  }
231 
232 
234  {
235  // simply disambiguate
236  WeakComponentImplHelperBase::dispose();
237  }
238 
239 
240 } // namespace comphelper
241 
242 
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Type
::osl::Mutex m_aMutex
css::uno::Reference< css::uno::XComponentContext > m_xContext
#define IMPLEMENT_FORWARD_XTYPEPROVIDER2(classname, baseclass1, baseclass2)
Definition: uno3.hxx:136
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
css::uno::Reference< css::lang::XTypeProvider > m_xProxyTypeAccess
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
OComponentProxyAggregation(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const css::uno::Reference< css::lang::XComponent > &_rxComponent)
css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType)
void baseAggregateProxyFor(const css::uno::Reference< css::uno::XInterface > &_rxComponent, oslInterlockedCount &_rRefCount,::cppu::OWeakObject &_rDelegator)
to be called from within your ctor
css::uno::Type const & get()
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &...rSn)
concat several sequences
Definition: sequence.hxx:49
const SvXMLTokenMapEntry aTypes[]
#define IMPLEMENT_FORWARD_XINTERFACE2(classname, refcountbase, baseclass2)
Definition: uno3.hxx:99
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
css::uno::Reference< css::lang::XComponent > m_xInner
css::uno::Reference< css::uno::XAggregation > m_xProxyAggregate
OComponentProxyAggregationHelper(const css::uno::Reference< css::uno::XComponentContext > &_rxContext,::cppu::OBroadcastHelper &_rBHelper)
virtual void SAL_CALL disposing() override
a helper class for aggregating a proxy to an XComponent
virtual void SAL_CALL dispose() override
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &_rType) override
helper class for aggregating a proxy for a foreign object
void componentAggregateProxyFor(const css::uno::Reference< css::lang::XComponent > &_rxComponent, oslInterlockedCount &_rRefCount,::cppu::OWeakObject &_rDelegator)
to be called from within your ctor
Reference< XSingleServiceFactory > xFactory
Reference< XComponentContext > m_xContext
OProxyAggregation(const css::uno::Reference< css::uno::XComponentContext > &_rxContext)