1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: component.cxx,v $
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"
42 using namespace com::sun::star
;
43 using namespace com::sun::star::uno
;
44 using namespace com::sun::star::lang
;
49 // ----------------------------------------------------
50 // class OComponentHelper
51 // ----------------------------------------------------
53 OComponentHelper::OComponentHelper( Mutex
& rMutex
) SAL_THROW( () )
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
);
89 if (osl_decrementInterlockedCount( &m_refCount
) == 0)
91 if (! rBHelper
.bDisposed
)
93 Reference
<XInterface
> xHoldAlive( *this );
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() );
106 (void) exc
; // avoid warning about unused variable
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
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;
127 MutexGuard
aGuard( Mutex::getGlobalMutex() );
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();
142 void OComponentHelper::disposing()
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
171 // Create an event with this as sender
176 Reference
<XInterface
> xSource(
177 Reference
<XInterface
>::query( (XComponent
*)this ) );
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
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
;
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
&)
203 catch (Exception
& exc
)
205 throw RuntimeException(
206 OUString( RTL_CONSTASCII_USTRINGPARAM(
207 "unexpected UNO exception caught: ") ) +
208 exc
.Message
, Reference
< XInterface
>() );
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" );
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
)
229 Reference
< XInterface
> x( (XComponent
*)this, UNO_QUERY
);
230 rxListener
->disposing( EventObject( x
) );
234 rBHelper
.addListener( ::getCppuType( &rxListener
) , rxListener
);
239 void OComponentHelper::removeEventListener(
240 const Reference
<XEventListener
> & rxListener
)
241 throw(::com::sun::star::uno::RuntimeException
)
243 rBHelper
.removeListener( ::getCppuType( &rxListener
) , rxListener
);