xref: /trunk/main/framework/source/services/EventMultiplexer.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "precompiled_framework.hxx"
23 
24 #include "services/EventMultiplexer.hxx"
25 #include "services.h"
26 
27 using ::rtl::OUString;
28 
29 #define A2S(s) ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
30 
31 namespace framework {
32 
33 #define IMPLEMENTATION_NAME "org.apache.openoffice.comp.framework.EventMultiplexer"
34 #define SERVICE_NAME "com.sun.star.ui.ContextChangeEventMultiplexer"
35 #define SINGLETON_NAME "org.apache.openoffice.comp.framework.EventMultiplexer"
36 
37 
EventMultiplexer(const cssu::Reference<css::uno::XComponentContext> & rxContext)38 EventMultiplexer::EventMultiplexer (const cssu::Reference<css::uno::XComponentContext>& rxContext)
39     : EventMultiplexerInterfaceBase(m_aMutex),
40       maListeners()
41 {
42     (void)rxContext;
43 }
44 
45 
46 
47 
~EventMultiplexer(void)48 EventMultiplexer::~EventMultiplexer (void)
49 {
50     maListeners.clear();
51 }
52 
53 
54 
55 
56 // XEventMultiplexer
57 
addEventListener(const cssu::Reference<css::util::XEventListener> & rxListener,const cssu::Reference<cssu::XInterface> & rxEventFocus)58 void SAL_CALL EventMultiplexer::addEventListener (
59     const cssu::Reference<css::util::XEventListener>& rxListener,
60     const cssu::Reference<cssu::XInterface>& rxEventFocus)
61 {
62     if ( ! rxListener.is())
63         throw css::lang::IllegalArgumentException(A2S("can not add an empty reference"), static_cast<XWeak*>(this), 0);
64 
65     ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus));
66     if (iListenerContainer == maListeners.end())
67     {
68         // Create a new listener container for the event focus.
69         iListenerContainer = maListeners.insert(
70             ListenerMap::value_type(
71                 rxEventFocus,
72                 ListenerContainer())).first;
73     }
74     if (iListenerContainer != maListeners.end())
75     {
76         ListenerContainer& rContainer (iListenerContainer->second);
77         if (::std::find(rContainer.begin(), rContainer.end(), rxListener) == rContainer.end())
78             rContainer.push_back(rxListener);
79         else
80         {
81             // The listener was added for the same event focus
82             // previously.  That is an error.
83             throw cssl::IllegalArgumentException(A2S("listener added twice"), static_cast<XWeak*>(this), 0);
84         }
85     }
86 }
87 
88 
89 
90 
removeEventListener(const cssu::Reference<css::util::XEventListener> & rxListener,const cssu::Reference<cssu::XInterface> & rxEventFocus)91 void SAL_CALL EventMultiplexer::removeEventListener (
92     const cssu::Reference<css::util::XEventListener>& rxListener,
93     const cssu::Reference<cssu::XInterface>& rxEventFocus)
94 {
95     if ( ! rxListener.is())
96         throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0);
97 
98     ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus));
99     if (iListenerContainer != maListeners.end())
100     {
101         ListenerContainer& rContainer (iListenerContainer->second);
102         const ListenerContainer::iterator iListener (::std::find(rContainer.begin(), rContainer.end(), rxListener));
103         if (iListener != rContainer.end())
104             rContainer.erase(iListener);
105     }
106 
107 }
108 
109 
110 
111 
removeAllEventListeners(const cssu::Reference<css::util::XEventListener> & rxListener)112 void SAL_CALL EventMultiplexer::removeAllEventListeners (
113     const cssu::Reference<css::util::XEventListener>& rxListener)
114 {
115     if ( ! rxListener.is())
116         throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0);
117 
118     for (ListenerMap::iterator
119              iContainer(maListeners.begin()),
120              iEnd(maListeners.end());
121          iContainer!=iEnd;
122          ++iContainer)
123     {
124         const ListenerContainer::iterator iListener (::std::find(iContainer->second.begin(), iContainer->second.end(), rxListener));
125         if (iListener != iContainer->second.end())
126             iContainer->second.erase(iListener);
127     }
128 }
129 
130 
131 
132 
133 
broadcastEvent(const cssl::EventObject & rEventObject,const cssu::Reference<cssu::XInterface> & rxEventFocus)134 void SAL_CALL EventMultiplexer::broadcastEvent (
135     const cssl::EventObject& rEventObject,
136     const cssu::Reference<cssu::XInterface>& rxEventFocus)
137 {
138     BroadcastEventToSingleContainer(rEventObject, rxEventFocus);
139     if (rxEventFocus.is())
140         BroadcastEventToSingleContainer(rEventObject, NULL);
141 }
142 
143 
144 
145 
BroadcastEventToSingleContainer(const cssl::EventObject & rEventObject,const cssu::Reference<cssu::XInterface> & rxEventFocus)146 void EventMultiplexer::BroadcastEventToSingleContainer (
147     const cssl::EventObject& rEventObject,
148     const cssu::Reference<cssu::XInterface>& rxEventFocus)
149 {
150     ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus));
151     if (iListenerContainer != maListeners.end())
152     {
153         // Create a copy of the listener container to avoid problems
154         // when one of the called listeners calls add... or remove...
155         ListenerContainer aContainer (iListenerContainer->second);
156         for (ListenerContainer::const_iterator
157                  iListener(aContainer.begin()),
158                  iEnd(aContainer.end());
159              iListener!=iEnd;
160              ++iListener)
161         {
162             (*iListener)->notifyEvent(rEventObject);
163         }
164     }
165 }
166 
167 
168 
169 
170 // XSingleComponentFactory
createInstanceWithContext(const cssu::Reference<cssu::XComponentContext> & rxContext)171 cssu::Reference<cssu::XInterface> SAL_CALL EventMultiplexer::createInstanceWithContext (
172     const cssu::Reference<cssu::XComponentContext>& rxContext)
173 {
174     return cssu::Reference<cssu::XInterface>();
175 }
176 
177 
178 
179 
createInstanceWithArgumentsAndContext(const cssu::Sequence<cssu::Any> & rArguments,const cssu::Reference<cssu::XComponentContext> & rxContext)180 cssu::Reference<cssu::XInterface > SAL_CALL EventMultiplexer::createInstanceWithArgumentsAndContext (
181     const cssu::Sequence<cssu::Any>& rArguments,
182     const cssu::Reference<cssu::XComponentContext>& rxContext)
183 {
184     return cssu::Reference<cssu::XInterface>();
185 }
186 
187 
188 
189 
190 // XServiceInfo
191 
getImplementationName(void)192 ::rtl::OUString SAL_CALL EventMultiplexer::getImplementationName (void)
193 {
194     return impl_getStaticImplementationName();
195 }
196 
197 
198 
199 
200 
supportsService(const::rtl::OUString & rsServiceName)201 sal_Bool SAL_CALL EventMultiplexer::supportsService (
202     const ::rtl::OUString& rsServiceName)
203 {
204     return ::comphelper::findValue(static_GetSupportedServiceNames(), rsServiceName, sal_True).getLength() != 0;
205 }
206 
207 
208 
209 
getSupportedServiceNames(void)210 cssu::Sequence<OUString> SAL_CALL EventMultiplexer::getSupportedServiceNames (void)
211 {
212     return static_GetSupportedServiceNames();
213 }
214 
215 
216 
217 
218 // Local and static methods.
219 
impl_getStaticImplementationName(void)220 OUString SAL_CALL EventMultiplexer::impl_getStaticImplementationName (void)
221 {
222     return A2S(IMPLEMENTATION_NAME);
223 }
224 
225 
226 
227 
static_GetSupportedServiceNames(void)228 cssu::Sequence<OUString> SAL_CALL EventMultiplexer::static_GetSupportedServiceNames (void)
229 {
230     cssu::Sequence<OUString> aServiceNames (2);
231     aServiceNames[0] = A2S(SERVICE_NAME);
232     aServiceNames[1] = A2S(SINGLETON_NAME);
233     return aServiceNames;
234 }
235 
236 
237 
238 
impl_createFactory(const cssu::Reference<cssl::XMultiServiceFactory> & rxServiceManager)239 cssu::Reference<cssu::XInterface> EventMultiplexer::impl_createFactory (
240     const cssu::Reference<cssl::XMultiServiceFactory>& rxServiceManager)
241 {
242     return cppu::createSingleComponentFactory(
243         EventMultiplexer::static_CreateInstance,
244         EventMultiplexer::impl_getStaticImplementationName(),
245         EventMultiplexer::static_GetSupportedServiceNames()
246         );
247 }
248 
249 
250 
251 
static_CreateInstance(const cssu::Reference<cssu::XComponentContext> & rxComponentContext)252 cssu::Reference<cssu::XInterface> SAL_CALL EventMultiplexer::static_CreateInstance (
253     const cssu::Reference<cssu::XComponentContext>& rxComponentContext)
254 {
255     EventMultiplexer* pObject = new EventMultiplexer(rxComponentContext);
256     cssu::Reference<cssu::XInterface> xService (static_cast<XWeak*>(pObject), cssu::UNO_QUERY);
257     return xService;
258 }
259 
260 }  // end of namespace framework
261