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