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 "ConfigurationControllerResourceManager.hxx" 27 #include "ConfigurationControllerBroadcaster.hxx" 28 #include "ResourceFactoryManager.hxx" 29 #include "framework/FrameworkHelper.hxx" 30 #include <com/sun/star/lang/DisposedException.hpp> 31 #include <tools/diagnose_ex.h> 32 #include <algorithm> 33 #include <boost/bind.hpp> 34 35 using namespace ::com::sun::star; 36 using namespace ::com::sun::star::uno; 37 using namespace ::com::sun::star::drawing::framework; 38 using ::rtl::OUString; 39 40 #undef VERBOSE 41 //#define VERBOSE 1 42 43 namespace sd { namespace framework { 44 45 //===== ConfigurationControllerResourceManager ================================ 46 47 ConfigurationControllerResourceManager::ConfigurationControllerResourceManager ( 48 const ::boost::shared_ptr<ResourceFactoryManager>& rpResourceFactoryContainer, 49 const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster) 50 : maResourceMap(ResourceComparator()), 51 mpResourceFactoryContainer(rpResourceFactoryContainer), 52 mpBroadcaster(rpBroadcaster) 53 { 54 } 55 56 57 58 59 ConfigurationControllerResourceManager::~ConfigurationControllerResourceManager (void) 60 { 61 } 62 63 64 65 66 ConfigurationControllerResourceManager::ResourceDescriptor 67 ConfigurationControllerResourceManager::GetResource ( 68 const Reference<XResourceId>& rxResourceId) 69 { 70 ::osl::MutexGuard aGuard (maMutex); 71 ResourceMap::const_iterator iResource (maResourceMap.find(rxResourceId)); 72 if (iResource != maResourceMap.end()) 73 return iResource->second; 74 else 75 return ResourceDescriptor(); 76 } 77 78 79 80 81 void ConfigurationControllerResourceManager::ActivateResources ( 82 const ::std::vector<Reference<XResourceId> >& rResources, 83 const Reference<XConfiguration>& rxConfiguration) 84 { 85 ::osl::MutexGuard aGuard (maMutex); 86 // Iterate in normal order over the resources that are to be 87 // activated so that resources on which others depend are activated 88 // beforet the depending resources are activated. 89 ::std::for_each( 90 rResources.begin(), 91 rResources.end(), 92 ::boost::bind(&ConfigurationControllerResourceManager::ActivateResource, 93 this, _1, rxConfiguration)); 94 } 95 96 97 98 99 void ConfigurationControllerResourceManager::DeactivateResources ( 100 const ::std::vector<Reference<XResourceId> >& rResources, 101 const Reference<XConfiguration>& rxConfiguration) 102 { 103 ::osl::MutexGuard aGuard (maMutex); 104 // Iterate in reverese order over the resources that are to be 105 // deactivated so that resources on which others depend are deactivated 106 // only when the depending resources have already been deactivated. 107 ::std::for_each( 108 rResources.rbegin(), 109 rResources.rend(), 110 ::boost::bind(&ConfigurationControllerResourceManager::DeactivateResource, 111 this, _1, rxConfiguration)); 112 } 113 114 115 116 117 /* In this method we do following steps. 118 1. Get the factory with which the resource will be created. 119 2. Create the resource. 120 3. Add the resource to the URL->Object map of the configuration 121 controller. 122 4. Add the resource id to the current configuration. 123 5. Notify listeners. 124 */ 125 void ConfigurationControllerResourceManager::ActivateResource ( 126 const Reference<XResourceId>& rxResourceId, 127 const Reference<XConfiguration>& rxConfiguration) 128 { 129 if ( ! rxResourceId.is()) 130 { 131 OSL_ASSERT(rxResourceId.is()); 132 return; 133 } 134 135 #if defined VERBOSE && VERBOSE>=1 136 OSL_TRACE("activating resource %s\n", OUStringToOString( 137 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 138 #endif 139 140 // 1. Get the factory. 141 const OUString sResourceURL (rxResourceId->getResourceURL()); 142 Reference<XResourceFactory> xFactory (mpResourceFactoryContainer->GetFactory(sResourceURL)); 143 if ( ! xFactory.is()) 144 { 145 #if defined VERBOSE && VERBOSE>=1 146 OSL_TRACE(" no factory found for %s\n", 147 OUStringToOString(sResourceURL, RTL_TEXTENCODING_UTF8).getStr()); 148 #endif 149 return; 150 } 151 152 try 153 { 154 // 2. Create the resource. 155 Reference<XResource> xResource; 156 try 157 { 158 xResource = xFactory->createResource(rxResourceId); 159 } 160 catch (lang::DisposedException&) 161 { 162 // The factory is disposed and can be removed from the list 163 // of registered factories. 164 mpResourceFactoryContainer->RemoveFactoryForReference(xFactory); 165 } 166 catch (Exception& e) 167 { 168 (void)e; 169 } 170 171 if (xResource.is()) 172 { 173 #if defined VERBOSE && VERBOSE>=1 174 OSL_TRACE(" successfully created\n"); 175 #endif 176 // 3. Add resource to URL->Object map. 177 AddResource(xResource, xFactory); 178 179 // 4. Add resource id to current configuration. 180 rxConfiguration->addResource(rxResourceId); 181 182 // 5. Notify the new resource to listeners of the ConfigurationController. 183 mpBroadcaster->NotifyListeners( 184 FrameworkHelper::msResourceActivationEvent, 185 rxResourceId, 186 xResource); 187 } 188 else 189 { 190 #if defined VERBOSE && VERBOSE>=1 191 OSL_TRACE(" resource creation failed\n"); 192 #endif 193 } 194 } 195 catch (RuntimeException&) 196 { 197 DBG_UNHANDLED_EXCEPTION(); 198 } 199 } 200 201 202 203 204 /* In this method we do following steps. 205 1. Remove the resource from the URL->Object map of the configuration 206 controller. 207 2. Notify listeners that deactivation has started. 208 3. Remove the resource id from the current configuration. 209 4. Release the resource. 210 5. Notify listeners about that deactivation is completed. 211 */ 212 void ConfigurationControllerResourceManager::DeactivateResource ( 213 const Reference<XResourceId>& rxResourceId, 214 const Reference<XConfiguration>& rxConfiguration) 215 { 216 if ( ! rxResourceId.is()) 217 return; 218 219 bool bSuccess (false); 220 try 221 { 222 // 1. Remove resource from URL->Object map. 223 ResourceDescriptor aDescriptor (RemoveResource(rxResourceId)); 224 225 if (aDescriptor.mxResource.is() && aDescriptor.mxResourceFactory.is()) 226 { 227 // 2. Notifiy listeners that the resource is being deactivated. 228 mpBroadcaster->NotifyListeners( 229 FrameworkHelper::msResourceDeactivationEvent, 230 rxResourceId, 231 aDescriptor.mxResource); 232 233 // 3. Remove resource id from current configuration. 234 rxConfiguration->removeResource(rxResourceId); 235 236 // 4. Release the resource. 237 try 238 { 239 aDescriptor.mxResourceFactory->releaseResource(aDescriptor.mxResource); 240 } 241 catch (lang::DisposedException& rException) 242 { 243 if ( ! rException.Context.is() 244 || rException.Context == aDescriptor.mxResourceFactory) 245 { 246 // The factory is disposed and can be removed from the 247 // list of registered factories. 248 mpResourceFactoryContainer->RemoveFactoryForReference( 249 aDescriptor.mxResourceFactory); 250 } 251 } 252 253 bSuccess = true; 254 } 255 } 256 catch (RuntimeException&) 257 { 258 DBG_UNHANDLED_EXCEPTION(); 259 } 260 261 // 5. Notifiy listeners that the resource is being deactivated. 262 mpBroadcaster->NotifyListeners( 263 FrameworkHelper::msResourceDeactivationEndEvent, 264 rxResourceId, 265 NULL); 266 267 #if defined VERBOSE && VERBOSE>=1 268 if (bSuccess) 269 OSL_TRACE("successfully deactivated %s\n", OUStringToOString( 270 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 271 else 272 OSL_TRACE("activating resource %s failed\n", OUStringToOString( 273 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 274 #endif 275 } 276 277 278 279 280 void ConfigurationControllerResourceManager::AddResource ( 281 const Reference<XResource>& rxResource, 282 const Reference<XResourceFactory>& rxFactory) 283 { 284 if ( ! rxResource.is()) 285 { 286 OSL_ASSERT(rxResource.is()); 287 return; 288 } 289 290 // Add the resource to the resource container. 291 ResourceDescriptor aDescriptor; 292 aDescriptor.mxResource = rxResource; 293 aDescriptor.mxResourceFactory = rxFactory; 294 maResourceMap[rxResource->getResourceId()] = aDescriptor; 295 296 #if defined VERBOSE && VERBOSE>=2 297 OSL_TRACE("ConfigurationControllerResourceManager::AddResource(): added %s -> %x\n", 298 OUStringToOString( 299 FrameworkHelper::ResourceIdToString(rxResource->getResourceId()), 300 RTL_TEXTENCODING_UTF8).getStr(), 301 rxResource.get()); 302 #endif 303 } 304 305 306 307 308 ConfigurationControllerResourceManager::ResourceDescriptor 309 ConfigurationControllerResourceManager::RemoveResource ( 310 const Reference<XResourceId>& rxResourceId) 311 { 312 ResourceDescriptor aDescriptor; 313 314 ResourceMap::iterator iResource (maResourceMap.find(rxResourceId)); 315 if (iResource != maResourceMap.end()) 316 { 317 #if defined VERBOSE && VERBOSE>=2 318 OSL_TRACE("ConfigurationControllerResourceManager::RemoveResource(): removing %s -> %x\n", 319 OUStringToOString( 320 FrameworkHelper::ResourceIdToString(rxResourceId), 321 RTL_TEXTENCODING_UTF8).getStr(), 322 *iResource); 323 #endif 324 325 aDescriptor = iResource->second; 326 maResourceMap.erase(rxResourceId); 327 } 328 329 return aDescriptor; 330 } 331 332 333 334 335 //===== ConfigurationControllerResourceManager::ResourceComparator ============ 336 337 bool ConfigurationControllerResourceManager::ResourceComparator::operator() ( 338 const Reference<XResourceId>& rxId1, 339 const Reference<XResourceId>& rxId2) const 340 { 341 if (rxId1.is() && rxId2.is()) 342 return rxId1->compareTo(rxId2)<0; 343 else if (rxId1.is()) 344 return true; 345 else if (rxId2.is()) 346 return false; 347 else 348 return false; 349 } 350 351 352 353 354 } } // end of namespace sd::framework 355 356