Update ooo320-m1
[ooovba.git] / dbaccess / source / core / dataaccess / documenteventnotifier.cxx
blob37a4f215ec4e69595b74d54364eebf532d3f2deb
1 /*************************************************************************
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * Copyright 2008 by Sun Microsystems, Inc.
6 * OpenOffice.org - a multi-platform office productivity suite
8 * $RCSfile: documenteventnotifier.cxx,v $
10 * $Revision: 1.1.2.4 $
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.
28 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_dbaccess.hxx"
33 #include "documenteventnotifier.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/frame/DoubleInitializationException.hpp>
37 /** === end UNO includes === **/
39 #include <comphelper/asyncnotification.hxx>
40 #include <cppuhelper/interfacecontainer.hxx>
41 #include <cppuhelper/weak.hxx>
42 #include <tools/diagnose_ex.h>
44 //........................................................................
45 namespace dbaccess
47 //........................................................................
49 /** === begin UNO using === **/
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::uno::XInterface;
52 using ::com::sun::star::uno::UNO_QUERY;
53 using ::com::sun::star::uno::UNO_QUERY_THROW;
54 using ::com::sun::star::uno::UNO_SET_THROW;
55 using ::com::sun::star::uno::Exception;
56 using ::com::sun::star::uno::RuntimeException;
57 using ::com::sun::star::uno::Any;
58 using ::com::sun::star::uno::makeAny;
59 using ::com::sun::star::uno::Sequence;
60 using ::com::sun::star::uno::Type;
61 using ::com::sun::star::frame::DoubleInitializationException;
62 using ::com::sun::star::document::XDocumentEventListener;
63 using ::com::sun::star::document::DocumentEvent;
64 using ::com::sun::star::frame::XController2;
65 /** === end UNO using === **/
66 using namespace ::com::sun::star;
68 //==================================================================
69 //= DocumentEventHolder
70 //==================================================================
71 typedef ::comphelper::EventHolder< DocumentEvent > DocumentEventHolder;
73 //====================================================================
74 //= DocumentEventNotifier_Impl
75 //====================================================================
76 class DocumentEventNotifier_Impl : public ::comphelper::IEventProcessor
78 oslInterlockedCount m_refCount;
79 ::cppu::OWeakObject& m_rDocument;
80 ::osl::Mutex& m_rMutex;
81 bool m_bInitialized;
82 bool m_bDisposed;
83 ::rtl::Reference< ::comphelper::AsyncEventNotifier > m_pEventBroadcaster;
84 ::cppu::OInterfaceContainerHelper m_aLegacyEventListeners;
85 ::cppu::OInterfaceContainerHelper m_aDocumentEventListeners;
87 public:
88 DocumentEventNotifier_Impl( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex )
89 :m_refCount( 0 )
90 ,m_rDocument( _rBroadcasterDocument )
91 ,m_rMutex( _rMutex )
92 ,m_bInitialized( false )
93 ,m_bDisposed( false )
94 ,m_aLegacyEventListeners( _rMutex )
95 ,m_aDocumentEventListeners( _rMutex )
99 // IReference
100 virtual void SAL_CALL acquire();
101 virtual void SAL_CALL release();
103 void addLegacyEventListener( const Reference< document::XEventListener >& _Listener )
105 m_aLegacyEventListeners.addInterface( _Listener );
108 void removeLegacyEventListener( const Reference< document::XEventListener >& _Listener )
110 m_aLegacyEventListeners.removeInterface( _Listener );
113 void addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
115 m_aDocumentEventListeners.addInterface( _Listener );
118 void removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
120 m_aDocumentEventListeners.removeInterface( _Listener );
123 void disposing();
125 void onDocumentInitialized();
127 void notifyDocumentEvent( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController,
128 const Any& _Supplement )
130 impl_notifyEvent_nothrow( DocumentEvent(
131 m_rDocument, _EventName, _ViewController, _Supplement ) );
134 void notifyDocumentEventAsync( const ::rtl::OUString& _EventName, const Reference< XController2 >& _ViewController,
135 const Any& _Supplement )
137 impl_notifyEventAsync_nothrow( DocumentEvent(
138 m_rDocument, _EventName, _ViewController, _Supplement ) );
141 protected:
142 virtual ~DocumentEventNotifier_Impl()
146 // IEventProcessor
147 virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );
149 private:
150 void impl_notifyEvent_nothrow( const DocumentEvent& _rEvent );
151 void impl_notifyEventAsync_nothrow( const DocumentEvent& _rEvent );
154 //--------------------------------------------------------------------
155 void SAL_CALL DocumentEventNotifier_Impl::acquire()
157 osl_incrementInterlockedCount( &m_refCount );
160 //--------------------------------------------------------------------
161 void SAL_CALL DocumentEventNotifier_Impl::release()
163 if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
164 delete this;
167 //--------------------------------------------------------------------
168 void DocumentEventNotifier_Impl::disposing()
170 // SYNCHRONIZED ->
171 // cancel any pending asynchronous events
172 ::osl::ResettableMutexGuard aGuard( m_rMutex );
173 if ( m_pEventBroadcaster.is() )
175 m_pEventBroadcaster->removeEventsForProcessor( this );
176 m_pEventBroadcaster->terminate();
177 m_pEventBroadcaster = NULL;
180 lang::EventObject aEvent( m_rDocument );
181 aGuard.clear();
182 // <-- SYNCHRONIZED
184 m_aLegacyEventListeners.disposeAndClear( aEvent );
185 m_aDocumentEventListeners.disposeAndClear( aEvent );
187 // SYNCHRONIZED ->
188 aGuard.reset();
189 m_bDisposed = true;
190 // <-- SYNCHRONIZED
193 //--------------------------------------------------------------------
194 void DocumentEventNotifier_Impl::onDocumentInitialized()
196 if ( m_bInitialized )
197 throw DoubleInitializationException();
199 m_bInitialized = true;
200 if ( m_pEventBroadcaster.is() )
201 // there are already pending asynchronous events
202 m_pEventBroadcaster->create();
205 //--------------------------------------------------------------------
206 void DocumentEventNotifier_Impl::impl_notifyEvent_nothrow( const DocumentEvent& _rEvent )
208 OSL_PRECOND( m_bInitialized,
209 "DocumentEventNotifier_Impl::impl_notifyEvent_nothrow: only to be called when the document is already initialized!" );
212 document::EventObject aLegacyEvent( _rEvent.Source, _rEvent.EventName );
213 m_aLegacyEventListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent );
215 catch(const Exception&)
217 DBG_UNHANDLED_EXCEPTION();
221 m_aDocumentEventListeners.notifyEach( &XDocumentEventListener::documentEventOccured, _rEvent );
223 catch( const Exception& )
225 DBG_UNHANDLED_EXCEPTION();
229 //--------------------------------------------------------------------
230 void DocumentEventNotifier_Impl::impl_notifyEventAsync_nothrow( const DocumentEvent& _rEvent )
232 if ( !m_pEventBroadcaster.is() )
234 m_pEventBroadcaster.set( new ::comphelper::AsyncEventNotifier );
235 if ( m_bInitialized )
236 // start processing the events if and only if we (our document, respectively) are
237 // already initialized
238 m_pEventBroadcaster->create();
240 m_pEventBroadcaster->addEvent( new DocumentEventHolder( _rEvent ), this );
243 // -----------------------------------------------------------------------------
244 void DocumentEventNotifier_Impl::processEvent( const ::comphelper::AnyEvent& _rEvent )
246 // beware, this is called from the notification thread
248 ::osl::MutexGuard aGuard( m_rMutex );
249 if ( m_bDisposed )
250 return;
252 const DocumentEventHolder& rEventHolder = dynamic_cast< const DocumentEventHolder& >( _rEvent );
253 impl_notifyEvent_nothrow( rEventHolder.getEventObject() );
256 //====================================================================
257 //= DocumentEventNotifier
258 //====================================================================
259 //--------------------------------------------------------------------
260 DocumentEventNotifier::DocumentEventNotifier( ::cppu::OWeakObject& _rBroadcasterDocument, ::osl::Mutex& _rMutex )
261 :m_pImpl( new DocumentEventNotifier_Impl( _rBroadcasterDocument, _rMutex ) )
265 //--------------------------------------------------------------------
266 DocumentEventNotifier::~DocumentEventNotifier()
270 //--------------------------------------------------------------------
271 void DocumentEventNotifier::disposing()
273 m_pImpl->disposing();
276 //--------------------------------------------------------------------
277 void DocumentEventNotifier::onDocumentInitialized()
279 m_pImpl->onDocumentInitialized();
282 //--------------------------------------------------------------------
283 void DocumentEventNotifier::addLegacyEventListener( const Reference< document::XEventListener >& _Listener )
285 m_pImpl->addLegacyEventListener( _Listener );
288 //--------------------------------------------------------------------
289 void DocumentEventNotifier::removeLegacyEventListener( const Reference< document::XEventListener >& _Listener )
291 m_pImpl->removeLegacyEventListener( _Listener );
294 //--------------------------------------------------------------------
295 void DocumentEventNotifier::addDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
297 m_pImpl->addDocumentEventListener( _Listener );
300 //--------------------------------------------------------------------
301 void DocumentEventNotifier::removeDocumentEventListener( const Reference< XDocumentEventListener >& _Listener )
303 m_pImpl->removeDocumentEventListener( _Listener );
306 //--------------------------------------------------------------------
307 void DocumentEventNotifier::notifyDocumentEvent( const ::rtl::OUString& _EventName,
308 const Reference< XController2 >& _ViewController, const Any& _Supplement )
310 m_pImpl->notifyDocumentEvent( _EventName, _ViewController, _Supplement );
313 //--------------------------------------------------------------------
314 void DocumentEventNotifier::notifyDocumentEventAsync( const ::rtl::OUString& _EventName,
315 const Reference< XController2 >& _ViewController, const Any& _Supplement )
317 m_pImpl->notifyDocumentEventAsync( _EventName, _ViewController, _Supplement );
320 //........................................................................
321 } // namespace dbaccess
322 //........................................................................