1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/listenernotification.hxx>
31 
32 /** === begin UNO includes === **/
33 #include <com/sun/star/lang/DisposedException.hpp>
34 /** === end UNO includes === **/
35 
36 //........................................................................
37 namespace comphelper
38 {
39 //........................................................................
40 
41     using namespace ::com::sun::star::uno;
42     using namespace ::com::sun::star::lang;
43 
44 	//====================================================================
45 	//= OListenerContainer
46 	//====================================================================
47 	//--------------------------------------------------------------------
48     OListenerContainer::OListenerContainer( ::osl::Mutex& _rMutex )
49         :m_aListeners( _rMutex )
50     {
51     }
52 
53     OListenerContainer::~OListenerContainer() {}
54 
55 	//--------------------------------------------------------------------
56     void OListenerContainer::impl_addListener( const Reference< XEventListener >& _rxListener )
57     {
58         OSL_PRECOND( _rxListener.is(), "OListenerContainer::impl_addListener: a NULL listener?!" );
59         if ( _rxListener.is() )
60             m_aListeners.addInterface( _rxListener );
61     }
62 
63 	//--------------------------------------------------------------------
64     void OListenerContainer::impl_removeListener( const Reference< XEventListener >& _rxListener )
65     {
66 #if OSL_DEBUG_LEVEL > 0
67 		::cppu::OInterfaceIteratorHelper aIter( m_aListeners );
68         bool bFound = false;
69 		while ( aIter.hasMoreElements() && !bFound )
70 		{
71             bFound = ( Reference< XInterface >( aIter.next() ) == _rxListener );
72         }
73         OSL_ENSURE( bFound, "OListenerContainer::impl_removeListener: sure your listener handling is correct? The given listener is not registered!" );
74 #endif
75         m_aListeners.removeInterface( _rxListener );
76     }
77 
78 	//--------------------------------------------------------------------
79     void OListenerContainer::disposing( const EventObject& _rEventSource )
80     {
81         m_aListeners.disposeAndClear( _rEventSource );
82     }
83 
84 	//--------------------------------------------------------------------
85     void OListenerContainer::clear()
86     {
87         m_aListeners.clear();
88     }
89 
90 	//--------------------------------------------------------------------
91     bool OListenerContainer::impl_notify( const EventObject& _rEvent ) SAL_THROW(( Exception ))
92     {
93 		::cppu::OInterfaceIteratorHelper aIter( m_aListeners );
94         bool bCancelled = false;
95 		while ( aIter.hasMoreElements() && !bCancelled )
96 		{
97             Reference< XEventListener > xListener( static_cast< XEventListener* >( aIter.next() ) );
98             if ( !xListener.is() )
99                 continue;
100 
101             try
102             {
103                 bCancelled = !implNotify( xListener, _rEvent );
104             }
105             catch( const DisposedException& e )
106             {
107                 // DisposedExceptions from the listener might indicate a
108                 // broken connection to a different environment.
109 
110                 OSL_ENSURE( e.Context.is(), "OListenerContainer::impl_notify: caught dispose exception with empty Context field" );
111 
112                 // If the exception stems from the listener then remove it
113                 // from the list of listeners.  If the Context field of the
114                 // exception is empty this is interpreted to indicate the
115                 // listener as well.
116                 if ( e.Context == xListener || !e.Context.is() )
117                     aIter.remove();
118             }
119 		}
120 
121         return !bCancelled;
122     }
123 
124 //........................................................................
125 }   // namespace comphelper
126 //........................................................................
127 
128