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