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 throw(cssu::RuntimeException,cssl::IllegalArgumentException)
62 {
63 if ( ! rxListener.is())
64 throw css::lang::IllegalArgumentException(A2S("can not add an empty reference"), static_cast<XWeak*>(this), 0);
65
66 ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus));
67 if (iListenerContainer == maListeners.end())
68 {
69 // Create a new listener container for the event focus.
70 iListenerContainer = maListeners.insert(
71 ListenerMap::value_type(
72 rxEventFocus,
73 ListenerContainer())).first;
74 }
75 if (iListenerContainer != maListeners.end())
76 {
77 ListenerContainer& rContainer (iListenerContainer->second);
78 if (::std::find(rContainer.begin(), rContainer.end(), rxListener) == rContainer.end())
79 rContainer.push_back(rxListener);
80 else
81 {
82 // The listener was added for the same event focus
83 // previously. That is an error.
84 throw cssl::IllegalArgumentException(A2S("listener added twice"), static_cast<XWeak*>(this), 0);
85 }
86 }
87 }
88
89
90
91
removeEventListener(const cssu::Reference<css::util::XEventListener> & rxListener,const cssu::Reference<cssu::XInterface> & rxEventFocus)92 void SAL_CALL EventMultiplexer::removeEventListener (
93 const cssu::Reference<css::util::XEventListener>& rxListener,
94 const cssu::Reference<cssu::XInterface>& rxEventFocus)
95 throw(cssu::RuntimeException,cssl::IllegalArgumentException)
96 {
97 if ( ! rxListener.is())
98 throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0);
99
100 ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus));
101 if (iListenerContainer != maListeners.end())
102 {
103 ListenerContainer& rContainer (iListenerContainer->second);
104 const ListenerContainer::iterator iListener (::std::find(rContainer.begin(), rContainer.end(), rxListener));
105 if (iListener != rContainer.end())
106 rContainer.erase(iListener);
107 }
108
109 }
110
111
112
113
removeAllEventListeners(const cssu::Reference<css::util::XEventListener> & rxListener)114 void SAL_CALL EventMultiplexer::removeAllEventListeners (
115 const cssu::Reference<css::util::XEventListener>& rxListener)
116 throw(cssu::RuntimeException,cssl::IllegalArgumentException)
117 {
118 if ( ! rxListener.is())
119 throw cssl::IllegalArgumentException(A2S("can not remove an empty reference"), static_cast<XWeak*>(this), 0);
120
121 for (ListenerMap::iterator
122 iContainer(maListeners.begin()),
123 iEnd(maListeners.end());
124 iContainer!=iEnd;
125 ++iContainer)
126 {
127 const ListenerContainer::iterator iListener (::std::find(iContainer->second.begin(), iContainer->second.end(), rxListener));
128 if (iListener != iContainer->second.end())
129 iContainer->second.erase(iListener);
130 }
131 }
132
133
134
135
136
broadcastEvent(const cssl::EventObject & rEventObject,const cssu::Reference<cssu::XInterface> & rxEventFocus)137 void SAL_CALL EventMultiplexer::broadcastEvent (
138 const cssl::EventObject& rEventObject,
139 const cssu::Reference<cssu::XInterface>& rxEventFocus)
140 throw(cssu::RuntimeException)
141 {
142 BroadcastEventToSingleContainer(rEventObject, rxEventFocus);
143 if (rxEventFocus.is())
144 BroadcastEventToSingleContainer(rEventObject, NULL);
145 }
146
147
148
149
BroadcastEventToSingleContainer(const cssl::EventObject & rEventObject,const cssu::Reference<cssu::XInterface> & rxEventFocus)150 void EventMultiplexer::BroadcastEventToSingleContainer (
151 const cssl::EventObject& rEventObject,
152 const cssu::Reference<cssu::XInterface>& rxEventFocus)
153 {
154 ListenerMap::iterator iListenerContainer (maListeners.find(rxEventFocus));
155 if (iListenerContainer != maListeners.end())
156 {
157 // Create a copy of the listener container to avoid problems
158 // when one of the called listeners calls add... or remove...
159 ListenerContainer aContainer (iListenerContainer->second);
160 for (ListenerContainer::const_iterator
161 iListener(aContainer.begin()),
162 iEnd(aContainer.end());
163 iListener!=iEnd;
164 ++iListener)
165 {
166 (*iListener)->notifyEvent(rEventObject);
167 }
168 }
169 }
170
171
172
173
174 // XSingleComponentFactory
createInstanceWithContext(const cssu::Reference<cssu::XComponentContext> & rxContext)175 cssu::Reference<cssu::XInterface> SAL_CALL EventMultiplexer::createInstanceWithContext (
176 const cssu::Reference<cssu::XComponentContext>& rxContext)
177 throw (cssu::Exception, cssu::RuntimeException)
178 {
179 return cssu::Reference<cssu::XInterface>();
180 }
181
182
183
184
createInstanceWithArgumentsAndContext(const cssu::Sequence<cssu::Any> & rArguments,const cssu::Reference<cssu::XComponentContext> & rxContext)185 cssu::Reference<cssu::XInterface > SAL_CALL EventMultiplexer::createInstanceWithArgumentsAndContext (
186 const cssu::Sequence<cssu::Any>& rArguments,
187 const cssu::Reference<cssu::XComponentContext>& rxContext)
188 throw (cssu::Exception, cssu::RuntimeException)
189 {
190 return cssu::Reference<cssu::XInterface>();
191 }
192
193
194
195
196 // XServiceInfo
197
getImplementationName(void)198 ::rtl::OUString SAL_CALL EventMultiplexer::getImplementationName (void)
199 throw(cssu::RuntimeException)
200 {
201 return impl_getStaticImplementationName();
202 }
203
204
205
206
207
supportsService(const::rtl::OUString & rsServiceName)208 sal_Bool SAL_CALL EventMultiplexer::supportsService (
209 const ::rtl::OUString& rsServiceName)
210 throw (cssu::RuntimeException)
211 {
212 return ::comphelper::findValue(static_GetSupportedServiceNames(), rsServiceName, sal_True).getLength() != 0;
213 }
214
215
216
217
getSupportedServiceNames(void)218 cssu::Sequence<OUString> SAL_CALL EventMultiplexer::getSupportedServiceNames (void)
219 throw (cssu::RuntimeException)
220 {
221 return static_GetSupportedServiceNames();
222 }
223
224
225
226
227 // Local and static methods.
228
impl_getStaticImplementationName(void)229 OUString SAL_CALL EventMultiplexer::impl_getStaticImplementationName (void)
230 {
231 return A2S(IMPLEMENTATION_NAME);
232 }
233
234
235
236
static_GetSupportedServiceNames(void)237 cssu::Sequence<OUString> SAL_CALL EventMultiplexer::static_GetSupportedServiceNames (void)
238 {
239 cssu::Sequence<OUString> aServiceNames (2);
240 aServiceNames[0] = A2S(SERVICE_NAME);
241 aServiceNames[1] = A2S(SINGLETON_NAME);
242 return aServiceNames;
243 }
244
245
246
247
impl_createFactory(const cssu::Reference<cssl::XMultiServiceFactory> & rxServiceManager)248 cssu::Reference<cssu::XInterface> EventMultiplexer::impl_createFactory (
249 const cssu::Reference<cssl::XMultiServiceFactory>& rxServiceManager)
250 {
251 return cppu::createSingleComponentFactory(
252 EventMultiplexer::static_CreateInstance,
253 EventMultiplexer::impl_getStaticImplementationName(),
254 EventMultiplexer::static_GetSupportedServiceNames()
255 );
256 }
257
258
259
260
static_CreateInstance(const cssu::Reference<cssu::XComponentContext> & rxComponentContext)261 cssu::Reference<cssu::XInterface> SAL_CALL EventMultiplexer::static_CreateInstance (
262 const cssu::Reference<cssu::XComponentContext>& rxComponentContext)
263 throw (cssu::Exception)
264 {
265 EventMultiplexer* pObject = new EventMultiplexer(rxComponentContext);
266 cssu::Reference<cssu::XInterface> xService (static_cast<XWeak*>(pObject), cssu::UNO_QUERY);
267 return xService;
268 }
269
270 } // end of namespace framework
271