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 #include "precompiled_sd.hxx" 29 30 #include "framework/Configuration.hxx" 31 32 #include "framework/FrameworkHelper.hxx" 33 #include <comphelper/stl_types.hxx> 34 35 36 37 using namespace ::com::sun::star; 38 using namespace ::com::sun::star::uno; 39 using namespace ::com::sun::star::drawing::framework; 40 using ::sd::framework::FrameworkHelper; 41 using ::rtl::OUString; 42 43 #undef VERBOSE 44 45 namespace { 46 /** Use the XResourceId::compareTo() method to implement a compare operator 47 for STL containers. 48 */ 49 class XResourceIdLess 50 : public ::std::binary_function <Reference<XResourceId>, Reference<XResourceId>, bool> 51 { 52 public: 53 bool operator () (const Reference<XResourceId>& rId1, const Reference<XResourceId>& rId2) const 54 { 55 return rId1->compareTo(rId2) == -1; 56 } 57 }; 58 59 } // end of anonymous namespace 60 61 62 63 64 namespace sd { namespace framework { 65 66 67 class Configuration::ResourceContainer 68 : public ::std::set<Reference<XResourceId>, XResourceIdLess> 69 { 70 public: 71 ResourceContainer (void) {} 72 }; 73 74 75 76 77 //----- Service --------------------------------------------------------------- 78 79 Reference<XInterface> SAL_CALL Configuration_createInstance ( 80 const Reference<XComponentContext>& rxContext) 81 { 82 (void)rxContext; 83 return Reference<XInterface>(static_cast<XWeak*>(new Configuration(NULL,false))); 84 } 85 86 87 88 89 OUString Configuration_getImplementationName (void) throw(RuntimeException) 90 { 91 return OUString(RTL_CONSTASCII_USTRINGPARAM( 92 "com.sun.star.comp.Draw.framework.configuration.Configuration")); 93 } 94 95 96 97 98 Sequence<rtl::OUString> SAL_CALL Configuration_getSupportedServiceNames (void) 99 throw (RuntimeException) 100 { 101 static const OUString sServiceName(OUString::createFromAscii( 102 "com.sun.star.drawing.framework.Configuration")); 103 return Sequence<rtl::OUString>(&sServiceName, 1); 104 } 105 106 107 108 109 //===== Configuration ========================================================= 110 111 Configuration::Configuration ( 112 const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster, 113 bool bBroadcastRequestEvents) 114 : ConfigurationInterfaceBase(MutexOwner::maMutex), 115 mpResourceContainer(new ResourceContainer()), 116 mxBroadcaster(rxBroadcaster), 117 mbBroadcastRequestEvents(bBroadcastRequestEvents) 118 { 119 } 120 121 122 123 Configuration::Configuration ( 124 const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster, 125 bool bBroadcastRequestEvents, 126 const ResourceContainer& rResourceContainer) 127 : ConfigurationInterfaceBase(MutexOwner::maMutex), 128 mpResourceContainer(new ResourceContainer(rResourceContainer)), 129 mxBroadcaster(rxBroadcaster), 130 mbBroadcastRequestEvents(bBroadcastRequestEvents) 131 { 132 } 133 134 135 136 137 Configuration::~Configuration (void) 138 { 139 } 140 141 142 143 144 void SAL_CALL Configuration::disposing (void) 145 { 146 ::osl::MutexGuard aGuard (maMutex); 147 mpResourceContainer->clear(); 148 mxBroadcaster = NULL; 149 } 150 151 152 153 154 //----- XConfiguration -------------------------------------------------------- 155 156 void SAL_CALL Configuration::addResource (const Reference<XResourceId>& rxResourceId) 157 throw (RuntimeException) 158 { 159 ThrowIfDisposed(); 160 161 if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0) 162 throw ::com::sun::star::lang::IllegalArgumentException(); 163 164 if (mpResourceContainer->find(rxResourceId) == mpResourceContainer->end()) 165 { 166 #ifdef VERBOSE 167 OSL_TRACE("Configuration::addResource() %s", 168 OUStringToOString( 169 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 170 #endif 171 mpResourceContainer->insert(rxResourceId); 172 PostEvent(rxResourceId, true); 173 } 174 } 175 176 177 178 179 void SAL_CALL Configuration::removeResource (const Reference<XResourceId>& rxResourceId) 180 throw (RuntimeException) 181 { 182 ThrowIfDisposed(); 183 184 if ( ! rxResourceId.is() || rxResourceId->getResourceURL().getLength()==0) 185 throw ::com::sun::star::lang::IllegalArgumentException(); 186 187 ResourceContainer::iterator iResource (mpResourceContainer->find(rxResourceId)); 188 if (iResource != mpResourceContainer->end()) 189 { 190 #ifdef VERBOSE 191 OSL_TRACE("Configuration::removeResource() %s", 192 OUStringToOString( 193 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 194 #endif 195 PostEvent(rxResourceId,false); 196 mpResourceContainer->erase(iResource); 197 } 198 } 199 200 201 202 203 Sequence<Reference<XResourceId> > SAL_CALL Configuration::getResources ( 204 const Reference<XResourceId>& rxAnchorId, 205 const ::rtl::OUString& rsResourceURLPrefix, 206 AnchorBindingMode eMode) 207 throw (::com::sun::star::uno::RuntimeException) 208 { 209 ::osl::MutexGuard aGuard (maMutex); 210 ThrowIfDisposed(); 211 212 bool bFilterResources (rsResourceURLPrefix.getLength() > 0); 213 214 // Collect the matching resources in a vector. 215 ::std::vector<Reference<XResourceId> > aResources; 216 ResourceContainer::const_iterator iResource; 217 for (iResource=mpResourceContainer->begin(); 218 iResource!=mpResourceContainer->end(); 219 ++iResource) 220 { 221 if ( ! (*iResource)->isBoundTo(rxAnchorId,eMode)) 222 continue; 223 224 225 if (bFilterResources) 226 { 227 // Apply the given resource prefix as filter. 228 229 // Make sure that the resource is bound directly to the anchor. 230 if (eMode != AnchorBindingMode_DIRECT 231 && ! (*iResource)->isBoundTo(rxAnchorId, AnchorBindingMode_DIRECT)) 232 { 233 continue; 234 } 235 236 // Make sure that the resource URL matches the given prefix. 237 if ( ! (*iResource)->getResourceURL().match(rsResourceURLPrefix)) 238 { 239 continue; 240 } 241 } 242 243 aResources.push_back(*iResource); 244 } 245 246 // Copy the resources from the vector into a new sequence. 247 Sequence<Reference<XResourceId> > aResult (aResources.size()); 248 for (sal_uInt32 nIndex=0; nIndex<aResources.size(); ++nIndex) 249 aResult[nIndex] = aResources[nIndex]; 250 251 return aResult; 252 } 253 254 255 256 257 sal_Bool SAL_CALL Configuration::hasResource (const Reference<XResourceId>& rxResourceId) 258 throw (RuntimeException) 259 { 260 ::osl::MutexGuard aGuard (maMutex); 261 ThrowIfDisposed(); 262 263 return rxResourceId.is() 264 && mpResourceContainer->find(rxResourceId) != mpResourceContainer->end(); 265 } 266 267 268 269 270 //----- XCloneable ------------------------------------------------------------ 271 272 Reference<util::XCloneable> SAL_CALL Configuration::createClone (void) 273 throw (RuntimeException) 274 { 275 ::osl::MutexGuard aGuard (maMutex); 276 ThrowIfDisposed(); 277 278 Configuration* pConfiguration = new Configuration( 279 mxBroadcaster, 280 mbBroadcastRequestEvents, 281 *mpResourceContainer); 282 283 return Reference<util::XCloneable>(pConfiguration); 284 } 285 286 287 288 289 //----- XNamed ---------------------------------------------------------------- 290 291 OUString SAL_CALL Configuration::getName (void) 292 throw (RuntimeException) 293 { 294 ::osl::MutexGuard aGuard (maMutex); 295 OUString aString; 296 297 if (rBHelper.bDisposed || rBHelper.bInDispose) 298 aString += OUString::createFromAscii("DISPOSED "); 299 aString += OUString::createFromAscii("Configuration["); 300 301 ResourceContainer::const_iterator iResource; 302 for (iResource=mpResourceContainer->begin(); 303 iResource!=mpResourceContainer->end(); 304 ++iResource) 305 { 306 if (iResource != mpResourceContainer->begin()) 307 aString += OUString::createFromAscii(", "); 308 aString += FrameworkHelper::ResourceIdToString(*iResource); 309 } 310 aString += OUString::createFromAscii("]"); 311 312 return aString; 313 } 314 315 316 317 318 void SAL_CALL Configuration::setName (const OUString& rsName) 319 throw (RuntimeException) 320 { 321 (void)rsName; // rsName is ignored. 322 } 323 324 325 326 327 328 // ---------------------------------------------------------------------------- 329 330 void Configuration::PostEvent ( 331 const Reference<XResourceId>& rxResourceId, 332 const bool bActivation) 333 { 334 OSL_ASSERT(rxResourceId.is()); 335 336 if (mxBroadcaster.is()) 337 { 338 ConfigurationChangeEvent aEvent; 339 aEvent.ResourceId = rxResourceId; 340 if (bActivation) 341 if (mbBroadcastRequestEvents) 342 aEvent.Type = FrameworkHelper::msResourceActivationRequestEvent; 343 else 344 aEvent.Type = FrameworkHelper::msResourceActivationEvent; 345 else 346 if (mbBroadcastRequestEvents) 347 aEvent.Type = FrameworkHelper::msResourceDeactivationRequestEvent; 348 else 349 aEvent.Type = FrameworkHelper::msResourceDeactivationEvent; 350 aEvent.Configuration = this; 351 352 mxBroadcaster->notifyEvent(aEvent); 353 } 354 } 355 356 357 358 359 void Configuration::ThrowIfDisposed (void) const 360 throw (::com::sun::star::lang::DisposedException) 361 { 362 if (rBHelper.bDisposed || rBHelper.bInDispose) 363 { 364 throw lang::DisposedException ( 365 OUString(RTL_CONSTASCII_USTRINGPARAM( 366 "Configuration object has already been disposed")), 367 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); 368 } 369 } 370 371 372 373 374 //============================================================================= 375 376 bool AreConfigurationsEquivalent ( 377 const Reference<XConfiguration>& rxConfiguration1, 378 const Reference<XConfiguration>& rxConfiguration2) 379 { 380 if (rxConfiguration1.is() != rxConfiguration2.is()) 381 return false; 382 if ( ! rxConfiguration1.is() && ! rxConfiguration2.is()) 383 return true; 384 385 // Get the lists of resources from the two given configurations. 386 const Sequence<Reference<XResourceId> > aResources1( 387 rxConfiguration1->getResources( 388 NULL, OUString(), AnchorBindingMode_INDIRECT)); 389 const Sequence<Reference<XResourceId> > aResources2( 390 rxConfiguration2->getResources( 391 NULL, OUString(), AnchorBindingMode_INDIRECT)); 392 393 // When the number of resources differ then the configurations can not 394 // be equivalent. 395 const sal_Int32 nCount (aResources1.getLength()); 396 const sal_Int32 nCount2 (aResources2.getLength()); 397 if (nCount != nCount2) 398 return false; 399 400 // Comparison of the two lists of resource ids relies on their 401 // ordering. 402 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) 403 { 404 const Reference<XResourceId> xResource1 (aResources1[nIndex]); 405 const Reference<XResourceId> xResource2 (aResources2[nIndex]); 406 if (xResource1.is() && xResource2.is()) 407 { 408 if (xResource1->compareTo(xResource2) != 0) 409 return false; 410 } 411 else if (xResource1.is() != xResource2.is()) 412 { 413 return false; 414 } 415 } 416 417 return true; 418 } 419 420 } } // end of namespace sd::framework 421