Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <rtl/string.hxx>
30 : : #include <osl/diagnose.h>
31 : : #include <cppuhelper/component.hxx>
32 : : #include <cppuhelper/queryinterface.hxx>
33 : : #include <cppuhelper/typeprovider.hxx>
34 : : #include "com/sun/star/uno/RuntimeException.hpp"
35 : :
36 : : using namespace osl;
37 : : using namespace com::sun::star;
38 : : using namespace com::sun::star::uno;
39 : : using namespace com::sun::star::lang;
40 : :
41 : : using ::rtl::OUString;
42 : : using ::rtl::OString;
43 : : using ::rtl::OUStringToOString;
44 : :
45 : : namespace cppu
46 : : {
47 : :
48 : : // ----------------------------------------------------
49 : : // class OComponentHelper
50 : : // ----------------------------------------------------
51 : :
52 : 41815 : OComponentHelper::OComponentHelper( Mutex & rMutex ) SAL_THROW(())
53 [ + - ]: 41815 : : rBHelper( rMutex )
54 : : {
55 : 41815 : }
56 [ + - ]: 35966 : OComponentHelper::~OComponentHelper() SAL_THROW( (RuntimeException) )
57 : : {
58 [ - + ]: 35966 : }
59 : :
60 : 404145 : Any OComponentHelper::queryInterface( Type const & rType ) throw (RuntimeException)
61 : : {
62 : 404145 : return OWeakAggObject::queryInterface( rType );
63 : : }
64 : 338957 : Any OComponentHelper::queryAggregation( Type const & rType ) throw (RuntimeException)
65 : : {
66 [ + + ]: 338957 : if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
67 : : {
68 : 20732 : void * p = static_cast< lang::XComponent * >( this );
69 : 20732 : return Any( &p, rType );
70 : : }
71 [ + + ]: 318225 : else if (rType == ::getCppuType( (Reference< lang::XTypeProvider > const *)0 ))
72 : : {
73 : 164 : void * p = static_cast< lang::XTypeProvider * >( this );
74 : 164 : return Any( &p, rType );
75 : : }
76 : 338957 : return OWeakAggObject::queryAggregation( rType );
77 : : }
78 : 3020346 : void OComponentHelper::acquire() throw ()
79 : : {
80 : 3020346 : OWeakAggObject::acquire();
81 : 3020349 : }
82 : :
83 : 2926654 : void OComponentHelper::release() throw()
84 : : {
85 [ + - ]: 2926654 : Reference<XInterface > x( xDelegator );
86 [ + + ]: 2926654 : if (! x.is())
87 : : {
88 [ + - ][ + + ]: 2846751 : if (osl_decrementInterlockedCount( &m_refCount ) == 0)
89 : : {
90 [ + + ]: 58295 : if (! rBHelper.bDisposed)
91 : : {
92 : : // *before* again incrementing our ref count, ensure that our weak connection point
93 : : // will not create references to us anymore (via XAdapter::queryAdapted)
94 [ + - ]: 23952 : disposeWeakConnectionPoint();
95 : :
96 [ + - ]: 23952 : Reference<XInterface > xHoldAlive( *this );
97 : : // First dispose
98 : : try
99 : : {
100 [ + - ]: 23952 : dispose();
101 : : }
102 [ # # ]: 0 : catch (::com::sun::star::uno::RuntimeException & exc)
103 : : {
104 : : // release should not throw exceptions
105 : : #if OSL_DEBUG_LEVEL > 0
106 : : OString msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
107 : : OSL_FAIL( msg.getStr() );
108 : : #else
109 : : (void) exc; // avoid warning about unused variable
110 : : #endif
111 : : }
112 : :
113 : : // only the alive ref holds the object
114 : : OSL_ASSERT( m_refCount == 1 );
115 : : // destroy the object if xHoldAlive decrement the refcount to 0
116 [ # # ]: 2950606 : return;
117 : : }
118 : : }
119 : : // restore the reference count
120 [ + - ]: 2822799 : osl_incrementInterlockedCount( &m_refCount );
121 : : }
122 [ + + ]: 2926654 : OWeakAggObject::release();
123 : : }
124 : :
125 : 106 : Sequence< Type > OComponentHelper::getTypes() throw (RuntimeException)
126 : : {
127 : : static OTypeCollection * s_pTypes = 0;
128 [ + + ]: 106 : if (! s_pTypes)
129 : : {
130 [ + - ][ + - ]: 8 : MutexGuard aGuard( Mutex::getGlobalMutex() );
131 [ + - ]: 8 : if (! s_pTypes)
132 : : {
133 : : static OTypeCollection s_aTypes(
134 [ + - ]: 8 : ::getCppuType( (const Reference< lang::XComponent > *)0 ),
135 [ + - ]: 8 : ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ),
136 [ + - ]: 8 : ::getCppuType( (const Reference< XAggregation > *)0 ),
137 [ + - ][ + - ]: 16 : ::getCppuType( (const Reference< XWeak > *)0 ) );
[ + - ][ + - ]
[ + - ][ + - ]
[ # # ]
138 : 8 : s_pTypes = &s_aTypes;
139 [ + - ]: 8 : }
140 : : }
141 : 106 : return s_pTypes->getTypes();
142 : : }
143 : :
144 : : // XComponent
145 : 33788 : void OComponentHelper::disposing()
146 : : {
147 : 33788 : }
148 : :
149 : : // XComponent
150 : 35034 : void OComponentHelper::dispose()
151 : : throw(::com::sun::star::uno::RuntimeException)
152 : : {
153 : : // An frequently programming error is to release the last
154 : : // reference to this object in the disposing message.
155 : : // Make it rubust, hold a self Reference.
156 [ + - ]: 35034 : Reference<XComponent > xSelf( this );
157 : :
158 : : // Guard dispose against multible threading
159 : : // Remark: It is an error to call dispose more than once
160 : 35034 : sal_Bool bDoDispose = sal_False;
161 : : {
162 [ + - ]: 35034 : MutexGuard aGuard( rBHelper.rMutex );
163 [ + + ][ + - ]: 35034 : if( !rBHelper.bDisposed && !rBHelper.bInDispose )
164 : : {
165 : : // only one call go into this section
166 : 35008 : rBHelper.bInDispose = sal_True;
167 : 35008 : bDoDispose = sal_True;
168 [ + - ]: 35034 : }
169 : : }
170 : :
171 : : // Do not hold the mutex because we are broadcasting
172 [ + + ]: 35034 : if( bDoDispose )
173 : : {
174 : : // Create an event with this as sender
175 : : try
176 : : {
177 : : try
178 : : {
179 : : Reference<XInterface > xSource(
180 [ + - ]: 35008 : Reference<XInterface >::query( (XComponent *)this ) );
181 [ + - ]: 35008 : EventObject aEvt;
182 [ + - ]: 35008 : aEvt.Source = xSource;
183 : : // inform all listeners to release this object
184 : : // The listener container are automaticly cleared
185 [ + - ]: 35008 : rBHelper.aLC.disposeAndClear( aEvt );
186 : : // notify subclasses to do their dispose
187 [ + - ][ + - ]: 35008 : disposing();
188 : : }
189 : 0 : catch (...)
190 : : {
191 [ # # ]: 0 : MutexGuard aGuard( rBHelper.rMutex );
192 : : // bDispose and bInDisposing must be set in this order:
193 : 0 : rBHelper.bDisposed = sal_True;
194 : 0 : rBHelper.bInDispose = sal_False;
195 : 0 : throw;
196 : : }
197 [ + - ]: 35008 : MutexGuard aGuard( rBHelper.rMutex );
198 : : // bDispose and bInDisposing must be set in this order:
199 : 35008 : rBHelper.bDisposed = sal_True;
200 [ + - ]: 35008 : rBHelper.bInDispose = sal_False;
201 : : }
202 : 0 : catch (RuntimeException &)
203 : : {
204 : 0 : throw;
205 : : }
206 [ # # # ]: 0 : catch (Exception & exc)
207 : : {
208 : : throw RuntimeException(
209 : : OUString( RTL_CONSTASCII_USTRINGPARAM(
210 : : "unexpected UNO exception caught: ") ) +
211 [ # # # # ]: 0 : exc.Message, Reference< XInterface >() );
212 : : }
213 : : }
214 : : else
215 : : {
216 : : // in a multithreaded environment, it can't be avoided
217 : : // that dispose is called twice.
218 : : // However this condition is traced, because it MAY indicate an error.
219 : : OSL_TRACE( "OComponentHelper::dispose() - dispose called twice" );
220 : 35034 : }
221 : 35034 : }
222 : :
223 : : // XComponent
224 : 9614 : void OComponentHelper::addEventListener(
225 : : const Reference<XEventListener > & rxListener )
226 : : throw(::com::sun::star::uno::RuntimeException)
227 : : {
228 [ + - ]: 9614 : ClearableMutexGuard aGuard( rBHelper.rMutex );
229 [ + - ][ - + ]: 9614 : if (rBHelper.bDisposed || rBHelper.bInDispose)
230 : : {
231 [ # # ]: 0 : aGuard.clear();
232 [ # # ]: 0 : Reference< XInterface > x( (XComponent *)this, UNO_QUERY );
233 [ # # ][ # # ]: 0 : rxListener->disposing( EventObject( x ) );
[ # # ][ # # ]
234 : : }
235 : : else
236 : : {
237 [ + - ][ + - ]: 9614 : rBHelper.addListener( ::getCppuType( &rxListener ) , rxListener );
238 [ + - ]: 9614 : }
239 : 9614 : }
240 : :
241 : : // XComponent
242 : 1947 : void OComponentHelper::removeEventListener(
243 : : const Reference<XEventListener > & rxListener )
244 : : throw(::com::sun::star::uno::RuntimeException)
245 : : {
246 : 1947 : rBHelper.removeListener( ::getCppuType( &rxListener ) , rxListener );
247 : 1947 : }
248 : :
249 : : }
250 : :
251 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|