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 <rtl/string.hxx>
21 #include <osl/diagnose.h>
22 #include <cppuhelper/component.hxx>
23 #include <cppuhelper/queryinterface.hxx>
24 #include <cppuhelper/typeprovider.hxx>
25 #include "com/sun/star/uno/RuntimeException.hpp"
28 using namespace com::sun::star
;
29 using namespace com::sun::star::uno
;
30 using namespace com::sun::star::lang
;
32 using ::rtl::OUString
;
34 using ::rtl::OUStringToOString
;
39 // ----------------------------------------------------
40 // class OComponentHelper
41 // ----------------------------------------------------
43 OComponentHelper::OComponentHelper( Mutex
& rMutex
) SAL_THROW(())
47 OComponentHelper::~OComponentHelper() SAL_THROW( (RuntimeException
) )
51 Any
OComponentHelper::queryInterface( Type
const & rType
) throw (RuntimeException
)
53 return OWeakAggObject::queryInterface( rType
);
55 Any
OComponentHelper::queryAggregation( Type
const & rType
) throw (RuntimeException
)
57 if (rType
== ::getCppuType( (Reference
< lang::XComponent
> const *)0 ))
59 void * p
= static_cast< lang::XComponent
* >( this );
60 return Any( &p
, rType
);
62 else if (rType
== ::getCppuType( (Reference
< lang::XTypeProvider
> const *)0 ))
64 void * p
= static_cast< lang::XTypeProvider
* >( this );
65 return Any( &p
, rType
);
67 return OWeakAggObject::queryAggregation( rType
);
69 void OComponentHelper::acquire() throw ()
71 OWeakAggObject::acquire();
74 void OComponentHelper::release() throw()
76 Reference
<XInterface
> x( xDelegator
);
79 if (osl_atomic_decrement( &m_refCount
) == 0)
81 if (! rBHelper
.bDisposed
)
83 // *before* again incrementing our ref count, ensure that our weak connection point
84 // will not create references to us anymore (via XAdapter::queryAdapted)
85 disposeWeakConnectionPoint();
87 Reference
<XInterface
> xHoldAlive( *this );
93 catch (::com::sun::star::uno::RuntimeException
& exc
)
95 // release should not throw exceptions
96 #if OSL_DEBUG_LEVEL > 0
97 OString
msg( OUStringToOString( exc
.Message
, RTL_TEXTENCODING_ASCII_US
) );
98 OSL_FAIL( msg
.getStr() );
100 (void) exc
; // avoid warning about unused variable
104 // only the alive ref holds the object
105 OSL_ASSERT( m_refCount
== 1 );
106 // destroy the object if xHoldAlive decrement the refcount to 0
110 // restore the reference count
111 osl_atomic_increment( &m_refCount
);
113 OWeakAggObject::release();
116 Sequence
< Type
> OComponentHelper::getTypes() throw (RuntimeException
)
118 static OTypeCollection
* s_pTypes
= 0;
121 MutexGuard
aGuard( Mutex::getGlobalMutex() );
124 static OTypeCollection
s_aTypes(
125 ::getCppuType( (const Reference
< lang::XComponent
> *)0 ),
126 ::getCppuType( (const Reference
< lang::XTypeProvider
> *)0 ),
127 ::getCppuType( (const Reference
< XAggregation
> *)0 ),
128 ::getCppuType( (const Reference
< XWeak
> *)0 ) );
129 s_pTypes
= &s_aTypes
;
132 return s_pTypes
->getTypes();
136 void OComponentHelper::disposing()
141 void OComponentHelper::dispose()
142 throw(::com::sun::star::uno::RuntimeException
)
144 // An frequently programming error is to release the last
145 // reference to this object in the disposing message.
146 // Make it rubust, hold a self Reference.
147 Reference
<XComponent
> xSelf( this );
149 // Guard dispose against multible threading
150 // Remark: It is an error to call dispose more than once
151 sal_Bool bDoDispose
= sal_False
;
153 MutexGuard
aGuard( rBHelper
.rMutex
);
154 if( !rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
156 // only one call go into this section
157 rBHelper
.bInDispose
= sal_True
;
158 bDoDispose
= sal_True
;
162 // Do not hold the mutex because we are broadcasting
165 // Create an event with this as sender
170 Reference
<XInterface
> xSource(
171 Reference
<XInterface
>::query( (XComponent
*)this ) );
173 aEvt
.Source
= xSource
;
174 // inform all listeners to release this object
175 // The listener container are automaticly cleared
176 rBHelper
.aLC
.disposeAndClear( aEvt
);
177 // notify subclasses to do their dispose
182 MutexGuard
aGuard( rBHelper
.rMutex
);
183 // bDispose and bInDisposing must be set in this order:
184 rBHelper
.bDisposed
= sal_True
;
185 rBHelper
.bInDispose
= sal_False
;
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
;
193 catch (RuntimeException
&)
197 catch (Exception
& exc
)
199 throw RuntimeException(
201 "unexpected UNO exception caught: ") +
202 exc
.Message
, Reference
< XInterface
>() );
207 // in a multithreaded environment, it can't be avoided
208 // that dispose is called twice.
209 // However this condition is traced, because it MAY indicate an error.
210 OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" );
215 void OComponentHelper::addEventListener(
216 const Reference
<XEventListener
> & rxListener
)
217 throw(::com::sun::star::uno::RuntimeException
)
219 ClearableMutexGuard
aGuard( rBHelper
.rMutex
);
220 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
223 Reference
< XInterface
> x( (XComponent
*)this, UNO_QUERY
);
224 rxListener
->disposing( EventObject( x
) );
228 rBHelper
.addListener( ::getCppuType( &rxListener
) , rxListener
);
233 void OComponentHelper::removeEventListener(
234 const Reference
<XEventListener
> & rxListener
)
235 throw(::com::sun::star::uno::RuntimeException
)
237 rBHelper
.removeListener( ::getCppuType( &rxListener
) , rxListener
);
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */