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 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 48 EventMultiplexer::~EventMultiplexer (void) 49 { 50 maListeners.clear(); 51 } 52 53 54 55 56 // XEventMultiplexer 57 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 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 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 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 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 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 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 198 ::rtl::OUString SAL_CALL EventMultiplexer::getImplementationName (void) 199 throw(cssu::RuntimeException) 200 { 201 return impl_getStaticImplementationName(); 202 } 203 204 205 206 207 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 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 229 OUString SAL_CALL EventMultiplexer::impl_getStaticImplementationName (void) 230 { 231 return A2S(IMPLEMENTATION_NAME); 232 } 233 234 235 236 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 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 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