bump product version to 4.1.6.2
[LibreOffice.git] / comphelper / source / misc / proxyaggregation.cxx
blob86d0082fbb2f803e4bb18d80e2dcea78da1279a0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "sal/config.h"
22 #include <cassert>
24 #include <comphelper/proxyaggregation.hxx>
25 #include <com/sun/star/reflection/ProxyFactory.hpp>
27 //.............................................................................
28 namespace comphelper
30 //.............................................................................
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::lang;
34 using namespace ::com::sun::star::reflection;
36 //=========================================================================
37 //= OProxyAggregation
38 //=========================================================================
39 //-------------------------------------------------------------------------
40 OProxyAggregation::OProxyAggregation( const Reference< XComponentContext >& _rxContext )
41 :m_xContext( _rxContext )
45 //-------------------------------------------------------------------------
46 void OProxyAggregation::baseAggregateProxyFor( const Reference< XInterface >& _rxComponent, oslInterlockedCount& _rRefCount,
47 ::cppu::OWeakObject& _rDelegator )
49 // first a factory for the proxy
50 Reference< XProxyFactory > xFactory = ProxyFactory::create( m_xContext );
52 // then the proxy itself
53 { // i36686 OJ: achieve the desctruction of the tempoary -> otherwise it leads to _rRefCount -= 2
54 m_xProxyAggregate = xFactory->createProxy( _rxComponent );
56 if ( m_xProxyAggregate.is() )
57 m_xProxyAggregate->queryAggregation( ::getCppuType( &m_xProxyTypeAccess ) ) >>= m_xProxyTypeAccess;
59 // aggregate the proxy
60 osl_atomic_increment( &_rRefCount );
61 if ( m_xProxyAggregate.is() )
63 // At this point in time, the proxy has a ref count of exactly two - in m_xControlContextProxy,
64 // and in m_xProxyTypeAccess.
65 // Remember to _not_ reset these members unless the delegator of the proxy has been reset, too!
66 m_xProxyAggregate->setDelegator( _rDelegator );
68 osl_atomic_decrement( &_rRefCount );
71 //-------------------------------------------------------------------------
72 Any SAL_CALL OProxyAggregation::queryAggregation( const Type& _rType ) throw (RuntimeException)
74 return m_xProxyAggregate.is() ? m_xProxyAggregate->queryAggregation( _rType ) : Any();
77 //-------------------------------------------------------------------------
78 Sequence< Type > SAL_CALL OProxyAggregation::getTypes( ) throw (RuntimeException)
80 Sequence< Type > aTypes;
81 if ( m_xProxyAggregate.is() )
83 if ( m_xProxyTypeAccess.is() )
84 aTypes = m_xProxyTypeAccess->getTypes();
86 return aTypes;
89 //-------------------------------------------------------------------------
90 OProxyAggregation::~OProxyAggregation()
92 if ( m_xProxyAggregate.is() )
93 m_xProxyAggregate->setDelegator( NULL );
94 m_xProxyAggregate.clear();
95 m_xProxyTypeAccess.clear();
96 // this should remove the _two_only_ "real" references (means not delegated to
97 // ourself) to this proxy, and thus delete it
100 //=========================================================================
101 //= OComponentProxyAggregationHelper
102 //=========================================================================
103 //-------------------------------------------------------------------------
104 OComponentProxyAggregationHelper::OComponentProxyAggregationHelper( const Reference< XComponentContext >& _rxContext,
105 ::cppu::OBroadcastHelper& _rBHelper )
106 :OProxyAggregation( _rxContext )
107 ,m_rBHelper( _rBHelper )
109 OSL_ENSURE( _rxContext.is(), "OComponentProxyAggregationHelper::OComponentProxyAggregationHelper: invalid arguments!" );
112 //-------------------------------------------------------------------------
113 void OComponentProxyAggregationHelper::componentAggregateProxyFor(
114 const Reference< XComponent >& _rxComponent, oslInterlockedCount& _rRefCount,
115 ::cppu::OWeakObject& _rDelegator )
117 OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregationHelper::componentAggregateProxyFor: invalid inner component!" );
118 m_xInner = _rxComponent;
120 // aggregate a proxy for the object
121 baseAggregateProxyFor( m_xInner.get(), _rRefCount, _rDelegator );
123 // add as event listener to the inner context, because we want to be notified of disposals
124 osl_atomic_increment( &_rRefCount );
126 if ( m_xInner.is() )
127 m_xInner->addEventListener( this );
129 osl_atomic_decrement( &_rRefCount );
132 //-------------------------------------------------------------------------
133 Any SAL_CALL OComponentProxyAggregationHelper::queryInterface( const Type& _rType ) throw (RuntimeException)
135 Any aReturn( BASE::queryInterface( _rType ) );
136 if ( !aReturn.hasValue() )
137 aReturn = OProxyAggregation::queryAggregation( _rType );
138 return aReturn;
141 //-------------------------------------------------------------------------
142 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OComponentProxyAggregationHelper, BASE, OProxyAggregation )
144 //-------------------------------------------------------------------------
145 OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper( )
147 OSL_ENSURE( m_rBHelper.bDisposed, "OComponentProxyAggregationHelper::~OComponentProxyAggregationHelper: you should dispose your derived class in the dtor, if necessary!" );
148 // if this asserts, add the following to your derived class dtor:
150 // if ( !m_rBHelper.bDisposed )
151 // {
152 // acquire(); // to prevent duplicate dtor calls
153 // dispose();
154 // }
156 m_xInner.clear();
159 //-------------------------------------------------------------------------
160 void SAL_CALL OComponentProxyAggregationHelper::disposing( const EventObject& _rSource ) throw (RuntimeException)
162 if ( _rSource.Source == m_xInner )
163 { // it's our inner context which is dying -> dispose ourself
164 if ( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose )
165 { // (if necessary only, of course)
166 dispose();
171 //-------------------------------------------------------------------------
172 void SAL_CALL OComponentProxyAggregationHelper::dispose() throw( RuntimeException )
174 ::osl::MutexGuard aGuard( m_rBHelper.rMutex );
176 // dispose our inner context
177 // before we do this, remove ourself as listener - else in disposing( EventObject ), we
178 // would dispose ourself a second time
179 Reference< XComponent > xComp( m_xInner, UNO_QUERY );
180 if ( xComp.is() )
182 xComp->removeEventListener( this );
183 xComp->dispose();
184 xComp.clear();
188 //=========================================================================
189 //= OComponentProxyAggregation
190 //=========================================================================
191 //-------------------------------------------------------------------------
192 OComponentProxyAggregation::OComponentProxyAggregation( const Reference< XComponentContext >& _rxContext,
193 const Reference< XComponent >& _rxComponent )
194 :WeakComponentImplHelperBase( m_aMutex )
195 ,OComponentProxyAggregationHelper( _rxContext, rBHelper )
197 OSL_ENSURE( _rxComponent.is(), "OComponentProxyAggregation::OComponentProxyAggregation: accessible is no XComponent!" );
198 if ( _rxComponent.is() )
199 componentAggregateProxyFor( _rxComponent, m_refCount, *this );
202 //-------------------------------------------------------------------------
203 OComponentProxyAggregation::~OComponentProxyAggregation()
205 implEnsureDisposeInDtor( );
208 //-------------------------------------------------------------------------
209 IMPLEMENT_FORWARD_XINTERFACE2( OComponentProxyAggregation, WeakComponentImplHelperBase, OComponentProxyAggregationHelper )
211 //-------------------------------------------------------------------------
212 IMPLEMENT_GET_IMPLEMENTATION_ID( OComponentProxyAggregation )
214 //-------------------------------------------------------------------------
215 Sequence< Type > SAL_CALL OComponentProxyAggregation::getTypes( ) throw (RuntimeException)
217 Sequence< Type > aTypes( OComponentProxyAggregationHelper::getTypes() );
219 // append XComponent, coming from WeakComponentImplHelperBase
220 sal_Int32 nLen = aTypes.getLength();
221 aTypes.realloc( nLen + 1 );
222 aTypes[ nLen ] = ::getCppuType( static_cast< Reference< XComponent >* >( NULL ) );
224 return aTypes;
227 //-------------------------------------------------------------------------
228 void OComponentProxyAggregation::implEnsureDisposeInDtor( )
230 if ( !rBHelper.bDisposed )
232 acquire(); // to prevent duplicate dtor calls
233 dispose();
237 //--------------------------------------------------------------------
238 void SAL_CALL OComponentProxyAggregation::disposing( const EventObject& _rSource ) throw (RuntimeException)
240 // Simply disambiguate---this is necessary for MSVC to distinguish
241 // "disposing(EventObject)" from "disposing()"; but it is also a good
242 // place to check for recursive calls that would be caused by an object
243 // being registered as an XEventListener at itself (cf. rhbz#928568):
244 assert(_rSource.Source != static_cast< cppu::OWeakObject * >(this));
245 OComponentProxyAggregationHelper::disposing( _rSource );
248 //--------------------------------------------------------------------
249 void SAL_CALL OComponentProxyAggregation::disposing() throw (RuntimeException)
251 // call the dispose-functionality of the base, which will dispose our aggregated component
252 OComponentProxyAggregationHelper::dispose();
255 //--------------------------------------------------------------------
256 void SAL_CALL OComponentProxyAggregation::dispose() throw( RuntimeException )
258 // simply disambiguate
259 WeakComponentImplHelperBase::dispose();
263 //.............................................................................
264 } // namespace comphelper
265 //.............................................................................
267 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */