1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
24 #include <comphelper/proxyaggregation.hxx>
25 #include <com/sun/star/reflection/ProxyFactory.hpp>
27 //.............................................................................
30 //.............................................................................
32 using namespace ::com::sun::star::uno
;
33 using namespace ::com::sun::star::lang
;
34 using namespace ::com::sun::star::reflection
;
36 //=========================================================================
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();
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
);
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
);
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 )
152 // acquire(); // to prevent duplicate dtor calls
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)
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
);
182 xComp
->removeEventListener( this );
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
) );
227 //-------------------------------------------------------------------------
228 void OComponentProxyAggregation::implEnsureDisposeInDtor( )
230 if ( !rBHelper
.bDisposed
)
232 acquire(); // to prevent duplicate dtor calls
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: */