xref: /AOO41X/main/comphelper/source/misc/proxyaggregation.cxx (revision dde7d3faf6dcd9cbeb7b48ba6d0cea5ffcc883d0)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <comphelper/proxyaggregation.hxx>
27 #include <com/sun/star/reflection/XProxyFactory.hpp>
28 
29 //.............................................................................
30 namespace comphelper
31 {
32 //.............................................................................
33 
34     using namespace ::com::sun::star::uno;
35     using namespace ::com::sun::star::lang;
36     using namespace ::com::sun::star::reflection;
37 
38     //=========================================================================
39     //= OProxyAggregation
40     //=========================================================================
41     //-------------------------------------------------------------------------
OProxyAggregation(const Reference<XMultiServiceFactory> & _rxORB)42     OProxyAggregation::OProxyAggregation( const Reference< XMultiServiceFactory >& _rxORB )
43         :m_xORB( _rxORB )
44     {
45     }
46 
47     //-------------------------------------------------------------------------
baseAggregateProxyFor(const Reference<XInterface> & _rxComponent,oslInterlockedCount & _rRefCount,::cppu::OWeakObject & _rDelegator)48     void OProxyAggregation::baseAggregateProxyFor( const Reference< XInterface >& _rxComponent, oslInterlockedCount& _rRefCount,
49             ::cppu::OWeakObject& _rDelegator )
50     {
51         // first a factory for the proxy
52         Reference< XProxyFactory > xFactory(
53             m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ) ),
54             UNO_QUERY
55         );
56         OSL_ENSURE( xFactory.is(), "OProxyAggregation::baseAggregateProxyFor: could not create a proxy factory!" );
57 
58         // then the proxy itself
59         if ( xFactory.is() )
60         {
61             { // i36686 OJ: achieve the desctruction of the tempoary -> otherwise it leads to _rRefCount -= 2
62                 m_xProxyAggregate = xFactory->createProxy( _rxComponent );
63             }
64             if ( m_xProxyAggregate.is() )
65                 m_xProxyAggregate->queryAggregation( ::getCppuType( &m_xProxyTypeAccess ) ) >>= m_xProxyTypeAccess;
66 
67             // aggregate the proxy
68             osl_incrementInterlockedCount( &_rRefCount );
69             if ( m_xProxyAggregate.is() )
70             {
71                 // At this point in time, the proxy has a ref count of exactly two - in m_xControlContextProxy,
72                 // and in m_xProxyTypeAccess.
73                 // Remember to _not_ reset these members unless the delegator of the proxy has been reset, too!
74                 m_xProxyAggregate->setDelegator( _rDelegator );
75             }
76             osl_decrementInterlockedCount( &_rRefCount );
77         }
78     }
79 
80     //-------------------------------------------------------------------------
queryAggregation(const Type & _rType)81     Any SAL_CALL OProxyAggregation::queryAggregation( const Type& _rType ) throw (RuntimeException)
82     {
83         return m_xProxyAggregate.is() ? m_xProxyAggregate->queryAggregation( _rType ) : Any();
84     }
85 
86     //-------------------------------------------------------------------------
getTypes()87     Sequence< Type > SAL_CALL OProxyAggregation::getTypes(  ) throw (RuntimeException)
88     {
89         Sequence< Type > aTypes;
90         if ( m_xProxyAggregate.is() )
91         {
92             if ( m_xProxyTypeAccess.is() )
93                 aTypes = m_xProxyTypeAccess->getTypes();
94         }
95         return aTypes;
96     }
97 
98     //-------------------------------------------------------------------------
~OProxyAggregation()99     OProxyAggregation::~OProxyAggregation()
100     {
101         if ( m_xProxyAggregate.is() )
102             m_xProxyAggregate->setDelegator( NULL );
103         m_xProxyAggregate.clear();
104         m_xProxyTypeAccess.clear();
105             // this should remove the _two_only_ "real" references (means not delegated to
106             // ourself) to this proxy, and thus delete it
107     }
108 
109     //=========================================================================
110     //= OComponentProxyAggregationHelper
111     //=========================================================================
112     //-------------------------------------------------------------------------
OComponentProxyAggregationHelper(const Reference<XMultiServiceFactory> & _rxORB,::cppu::OBroadcastHelper & _rBHelper)113     OComponentProxyAggregationHelper::OComponentProxyAggregationHelper( const Reference< XMultiServiceFactory >& _rxORB,
114         ::cppu::OBroadcastHelper& _rBHelper )
115         :OProxyAggregation( _rxORB )
116         ,m_rBHelper( _rBHelper )
117     {
118         OSL_ENSURE( _rxORB.is(), "OComponentProxyAggregationHelper::OComponentProxyAggregationHelper: invalid arguments!" );
119     }
120 
121     //-------------------------------------------------------------------------
componentAggregateProxyFor(const Reference<XComponent> & _rxComponent,oslInterlockedCount & _rRefCount,::cppu::OWeakObject & _rDelegator)122     void OComponentProxyAggregationHelper::componentAggregateProxyFor(
123         const Reference< XComponent >& _rxComponent, oslInterlockedCount& _rRefCount,
124         ::cppu::OWeakObject& _rDelegator )
125     {
126         OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregationHelper::componentAggregateProxyFor: invalid inner component!" );
127         m_xInner = _rxComponent;
128 
129         // aggregate a proxy for the object
130         baseAggregateProxyFor( m_xInner.get(), _rRefCount, _rDelegator );
131 
132         // add as event listener to the inner context, because we want to be notified of disposals
133         osl_incrementInterlockedCount( &_rRefCount );
134         {
135             if ( m_xInner.is() )
136                 m_xInner->addEventListener( this );
137         }
138         osl_decrementInterlockedCount( &_rRefCount );
139     }
140 
141     //-------------------------------------------------------------------------
queryInterface(const Type & _rType)142     Any SAL_CALL OComponentProxyAggregationHelper::queryInterface( const Type& _rType ) throw (RuntimeException)
143     {
144         Any aReturn( BASE::queryInterface( _rType ) );
145         if ( !aReturn.hasValue() )
146             aReturn = OProxyAggregation::queryAggregation( _rType );
147         return aReturn;
148     }
149 
150     //-------------------------------------------------------------------------
IMPLEMENT_FORWARD_XTYPEPROVIDER2(OComponentProxyAggregationHelper,BASE,OProxyAggregation)151     IMPLEMENT_FORWARD_XTYPEPROVIDER2( OComponentProxyAggregationHelper, BASE, OProxyAggregation )
152 
153     //-------------------------------------------------------------------------
154     OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper( )
155     {
156         OSL_ENSURE( m_rBHelper.bDisposed, "OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper: you should dispose your derived class in the dtor, if necessary!" );
157             // if this asserts, add the following to your derived class dtor:
158             //
159             // if ( !m_rBHelper.bDisposed )
160             // {
161             //   acquire(); // to prevent duplicate dtor calls
162             //   dispose();
163             // }
164 
165         m_xInner.clear();
166     }
167 
168     //-------------------------------------------------------------------------
disposing(const EventObject & _rSource)169     void SAL_CALL OComponentProxyAggregationHelper::disposing( const EventObject& _rSource ) throw (RuntimeException)
170     {
171         if ( _rSource.Source == m_xInner )
172         {   // it's our inner context which is dying -> dispose ourself
173             if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
174             {   // (if necessary only, of course)
175                 dispose();
176             }
177         }
178     }
179 
180     //-------------------------------------------------------------------------
dispose()181     void SAL_CALL OComponentProxyAggregationHelper::dispose() throw( RuntimeException )
182     {
183         ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
184 
185         // dispose our inner context
186         // before we do this, remove ourself as listener - else in disposing( EventObject ), we
187         // would dispose ourself a second time
188         Reference< XComponent > xComp( m_xInner, UNO_QUERY );
189         if ( xComp.is() )
190         {
191             xComp->removeEventListener( this );
192             xComp->dispose();
193             xComp.clear();
194         }
195     }
196 
197     //=========================================================================
198     //= OComponentProxyAggregation
199     //=========================================================================
200     //-------------------------------------------------------------------------
OComponentProxyAggregation(const Reference<XMultiServiceFactory> & _rxORB,const Reference<XComponent> & _rxComponent)201     OComponentProxyAggregation::OComponentProxyAggregation( const Reference< XMultiServiceFactory >& _rxORB,
202             const Reference< XComponent >& _rxComponent )
203         :OComponentProxyAggregation_CBase( m_aMutex )
204         ,OComponentProxyAggregationHelper( _rxORB, rBHelper )
205     {
206         OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregation::OComponentProxyAggregation: accessible is no XComponent!" );
207         if ( _rxComponent.is() )
208             componentAggregateProxyFor( _rxComponent, m_refCount, *this );
209     }
210 
211     //-------------------------------------------------------------------------
~OComponentProxyAggregation()212     OComponentProxyAggregation::~OComponentProxyAggregation()
213     {
214         implEnsureDisposeInDtor( );
215     }
216 
217     //-------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(OComponentProxyAggregation,OComponentProxyAggregation_CBase,OComponentProxyAggregationHelper)218     IMPLEMENT_FORWARD_XINTERFACE2( OComponentProxyAggregation, OComponentProxyAggregation_CBase, OComponentProxyAggregationHelper )
219 
220     //-------------------------------------------------------------------------
221     IMPLEMENT_GET_IMPLEMENTATION_ID( OComponentProxyAggregation )
222 
223     //-------------------------------------------------------------------------
224     Sequence< Type > SAL_CALL OComponentProxyAggregation::getTypes(  ) throw (RuntimeException)
225     {
226         Sequence< Type > aTypes( OComponentProxyAggregationHelper::getTypes() );
227 
228         // append XComponent, coming from OComponentProxyAggregation_CBase
229         sal_Int32 nLen = aTypes.getLength();
230         aTypes.realloc( nLen + 1 );
231         aTypes[ nLen ] = ::getCppuType( static_cast< Reference< XComponent >* >( NULL ) );
232 
233         return aTypes;
234     }
235 
236     //-------------------------------------------------------------------------
implEnsureDisposeInDtor()237     void OComponentProxyAggregation::implEnsureDisposeInDtor( )
238     {
239         if ( !rBHelper.bDisposed )
240         {
241             acquire();  // to prevent duplicate dtor calls
242             dispose();
243         }
244     }
245 
246     //--------------------------------------------------------------------
disposing(const EventObject & _rSource)247     void SAL_CALL OComponentProxyAggregation::disposing( const EventObject& _rSource ) throw (RuntimeException)
248     {
249         // simly disambiguate - this is necessary for MSVC to distinguish
250         // "disposing( EventObject )" from "disposing()"
251         OComponentProxyAggregationHelper::disposing( _rSource );
252     }
253 
254     //--------------------------------------------------------------------
disposing()255     void SAL_CALL OComponentProxyAggregation::disposing()  throw (RuntimeException)
256     {
257         // call the dispose-functionality of the base, which will dispose our aggregated component
258         OComponentProxyAggregationHelper::dispose();
259     }
260 
261     //--------------------------------------------------------------------
dispose()262     void SAL_CALL OComponentProxyAggregation::dispose() throw( RuntimeException )
263     {
264         // simply disambiguate
265         OComponentProxyAggregation_CBase::dispose();
266     }
267 
268 
269 //.............................................................................
270 }   // namespace comphelper
271 //.............................................................................
272 
273