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