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