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
10*dde7d3faSAndrew Rist  *
11*dde7d3faSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*dde7d3faSAndrew Rist  *
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.
19*dde7d3faSAndrew Rist  *
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