update dev300-m58
[ooovba.git] / cppuhelper / source / component.cxx
blob7729dcce1d7d3b01a3b28c70ecc88028b096337f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: component.cxx,v $
10 * $Revision: 1.15 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppuhelper.hxx"
33 #include <rtl/string.hxx>
34 #include <osl/diagnose.h>
35 #include <cppuhelper/component.hxx>
36 #include <cppuhelper/queryinterface.hxx>
37 #include <cppuhelper/typeprovider.hxx>
38 #include "com/sun/star/uno/RuntimeException.hpp"
40 using namespace osl;
41 using namespace rtl;
42 using namespace com::sun::star;
43 using namespace com::sun::star::uno;
44 using namespace com::sun::star::lang;
46 namespace cppu
49 // ----------------------------------------------------
50 // class OComponentHelper
51 // ----------------------------------------------------
53 OComponentHelper::OComponentHelper( Mutex & rMutex ) SAL_THROW( () )
54 : rBHelper( rMutex )
57 OComponentHelper::~OComponentHelper() SAL_THROW( (RuntimeException) )
61 Any OComponentHelper::queryInterface( Type const & rType ) throw (RuntimeException)
63 return OWeakAggObject::queryInterface( rType );
65 Any OComponentHelper::queryAggregation( Type const & rType ) throw (RuntimeException)
67 if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
69 void * p = static_cast< lang::XComponent * >( this );
70 return Any( &p, rType );
72 else if (rType == ::getCppuType( (Reference< lang::XTypeProvider > const *)0 ))
74 void * p = static_cast< lang::XTypeProvider * >( this );
75 return Any( &p, rType );
77 return OWeakAggObject::queryAggregation( rType );
79 void OComponentHelper::acquire() throw ()
81 OWeakAggObject::acquire();
84 void OComponentHelper::release() throw()
86 Reference<XInterface > x( xDelegator );
87 if (! x.is())
89 if (osl_decrementInterlockedCount( &m_refCount ) == 0)
91 if (! rBHelper.bDisposed)
93 Reference<XInterface > xHoldAlive( *this );
94 // First dispose
95 try
97 dispose();
99 catch (::com::sun::star::uno::RuntimeException & exc)
101 // release should not throw exceptions
102 #if OSL_DEBUG_LEVEL > 0
103 OString msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
104 OSL_ENSURE( 0, msg.getStr() );
105 #else
106 (void) exc; // avoid warning about unused variable
107 #endif
110 // only the alive ref holds the object
111 OSL_ASSERT( m_refCount == 1 );
112 // destroy the object if xHoldAlive decrement the refcount to 0
113 return;
116 // restore the reference count
117 osl_incrementInterlockedCount( &m_refCount );
119 OWeakAggObject::release();
122 Sequence< Type > OComponentHelper::getTypes() throw (RuntimeException)
124 static OTypeCollection * s_pTypes = 0;
125 if (! s_pTypes)
127 MutexGuard aGuard( Mutex::getGlobalMutex() );
128 if (! s_pTypes)
130 static OTypeCollection s_aTypes(
131 ::getCppuType( (const Reference< lang::XComponent > *)0 ),
132 ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ),
133 ::getCppuType( (const Reference< XAggregation > *)0 ),
134 ::getCppuType( (const Reference< XWeak > *)0 ) );
135 s_pTypes = &s_aTypes;
138 return s_pTypes->getTypes();
141 // XComponent
142 void OComponentHelper::disposing()
146 // XComponent
147 void OComponentHelper::dispose()
148 throw(::com::sun::star::uno::RuntimeException)
150 // An frequently programming error is to release the last
151 // reference to this object in the disposing message.
152 // Make it rubust, hold a self Reference.
153 Reference<XComponent > xSelf( this );
155 // Guard dispose against multible threading
156 // Remark: It is an error to call dispose more than once
157 sal_Bool bDoDispose = sal_False;
159 MutexGuard aGuard( rBHelper.rMutex );
160 if( !rBHelper.bDisposed && !rBHelper.bInDispose )
162 // only one call go into this section
163 rBHelper.bInDispose = sal_True;
164 bDoDispose = sal_True;
168 // Do not hold the mutex because we are broadcasting
169 if( bDoDispose )
171 // Create an event with this as sender
176 Reference<XInterface > xSource(
177 Reference<XInterface >::query( (XComponent *)this ) );
178 EventObject aEvt;
179 aEvt.Source = xSource;
180 // inform all listeners to release this object
181 // The listener container are automaticly cleared
182 rBHelper.aLC.disposeAndClear( aEvt );
183 // notify subclasses to do their dispose
184 disposing();
186 catch (...)
188 MutexGuard aGuard( rBHelper.rMutex );
189 // bDispose and bInDisposing must be set in this order:
190 rBHelper.bDisposed = sal_True;
191 rBHelper.bInDispose = sal_False;
192 throw;
194 MutexGuard aGuard( rBHelper.rMutex );
195 // bDispose and bInDisposing must be set in this order:
196 rBHelper.bDisposed = sal_True;
197 rBHelper.bInDispose = sal_False;
199 catch (RuntimeException &)
201 throw;
203 catch (Exception & exc)
205 throw RuntimeException(
206 OUString( RTL_CONSTASCII_USTRINGPARAM(
207 "unexpected UNO exception caught: ") ) +
208 exc.Message, Reference< XInterface >() );
211 else
213 // in a multithreaded environment, it can't be avoided,
214 // that dispose is called twice.
215 // However this condition is traced, because it MAY indicate an error.
216 OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" );
220 // XComponent
221 void OComponentHelper::addEventListener(
222 const Reference<XEventListener > & rxListener )
223 throw(::com::sun::star::uno::RuntimeException)
225 ClearableMutexGuard aGuard( rBHelper.rMutex );
226 if (rBHelper.bDisposed || rBHelper.bInDispose)
228 aGuard.clear();
229 Reference< XInterface > x( (XComponent *)this, UNO_QUERY );
230 rxListener->disposing( EventObject( x ) );
232 else
234 rBHelper.addListener( ::getCppuType( &rxListener ) , rxListener );
238 // XComponent
239 void OComponentHelper::removeEventListener(
240 const Reference<XEventListener > & rxListener )
241 throw(::com::sun::star::uno::RuntimeException)
243 rBHelper.removeListener( ::getCppuType( &rxListener ) , rxListener );