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 //------------------------------------------------------------------------- 42 OProxyAggregation::OProxyAggregation( const Reference< XMultiServiceFactory >& _rxORB ) 43 :m_xORB( _rxORB ) 44 { 45 } 46 47 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 212 OComponentProxyAggregation::~OComponentProxyAggregation() 213 { 214 implEnsureDisposeInDtor( ); 215 } 216 217 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 237 void OComponentProxyAggregation::implEnsureDisposeInDtor( ) 238 { 239 if ( !rBHelper.bDisposed ) 240 { 241 acquire(); // to prevent duplicate dtor calls 242 dispose(); 243 } 244 } 245 246 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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