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 fo %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&) 167 { 168 DBG_UNHANDLED_EXCEPTION(); 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. 208 3. Remove the resource id from the current configuration. 209 4. Release the resource. 210 */ 211 void ConfigurationControllerResourceManager::DeactivateResource ( 212 const Reference<XResourceId>& rxResourceId, 213 const Reference<XConfiguration>& rxConfiguration) 214 { 215 if ( ! rxResourceId.is()) 216 return; 217 218 bool bSuccess (false); 219 try 220 { 221 // 1. Remove resource from URL->Object map. 222 ResourceDescriptor aDescriptor (RemoveResource(rxResourceId)); 223 224 if (aDescriptor.mxResource.is() && aDescriptor.mxResourceFactory.is()) 225 { 226 // 2. Notifiy listeners that the resource is being deactivated. 227 mpBroadcaster->NotifyListeners( 228 FrameworkHelper::msResourceDeactivationEvent, 229 rxResourceId, 230 aDescriptor.mxResource); 231 232 // 3. Remove resource id from current configuration. 233 rxConfiguration->removeResource(rxResourceId); 234 235 // 4. Release the resource. 236 try 237 { 238 aDescriptor.mxResourceFactory->releaseResource(aDescriptor.mxResource); 239 } 240 catch (lang::DisposedException& rException) 241 { 242 if ( ! rException.Context.is() 243 || rException.Context == aDescriptor.mxResourceFactory) 244 { 245 // The factory is disposed and can be removed from the 246 // list of registered factories. 247 mpResourceFactoryContainer->RemoveFactoryForReference( 248 aDescriptor.mxResourceFactory); 249 } 250 } 251 252 bSuccess = true; 253 } 254 } 255 catch (RuntimeException&) 256 { 257 DBG_UNHANDLED_EXCEPTION(); 258 } 259 260 #if defined VERBOSE && VERBOSE>=1 261 if (bSuccess) 262 OSL_TRACE("successfully deactivated %s\n", OUStringToOString( 263 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 264 else 265 OSL_TRACE("activating resource %s failed\n", OUStringToOString( 266 FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr()); 267 #endif 268 } 269 270 271 272 273 void ConfigurationControllerResourceManager::AddResource ( 274 const Reference<XResource>& rxResource, 275 const Reference<XResourceFactory>& rxFactory) 276 { 277 if ( ! rxResource.is()) 278 { 279 OSL_ASSERT(rxResource.is()); 280 return; 281 } 282 283 // Add the resource to the resource container. 284 ResourceDescriptor aDescriptor; 285 aDescriptor.mxResource = rxResource; 286 aDescriptor.mxResourceFactory = rxFactory; 287 maResourceMap[rxResource->getResourceId()] = aDescriptor; 288 289 #if defined VERBOSE && VERBOSE>=2 290 OSL_TRACE("ConfigurationControllerResourceManager::AddResource(): added %s -> %x\n", 291 OUStringToOString( 292 FrameworkHelper::ResourceIdToString(rxResource->getResourceId()), 293 RTL_TEXTENCODING_UTF8).getStr(), 294 rxResource.get()); 295 #endif 296 } 297 298 299 300 301 ConfigurationControllerResourceManager::ResourceDescriptor 302 ConfigurationControllerResourceManager::RemoveResource ( 303 const Reference<XResourceId>& rxResourceId) 304 { 305 ResourceDescriptor aDescriptor; 306 307 ResourceMap::iterator iResource (maResourceMap.find(rxResourceId)); 308 if (iResource != maResourceMap.end()) 309 { 310 #if defined VERBOSE && VERBOSE>=2 311 OSL_TRACE("ConfigurationControllerResourceManager::RemoveResource(): removing %s -> %x\n", 312 OUStringToOString( 313 FrameworkHelper::ResourceIdToString(rxResourceId), 314 RTL_TEXTENCODING_UTF8).getStr(), 315 *iResource); 316 #endif 317 318 aDescriptor = iResource->second; 319 maResourceMap.erase(rxResourceId); 320 } 321 322 return aDescriptor; 323 } 324 325 326 327 328 //===== ConfigurationControllerResourceManager::ResourceComparator ============ 329 330 bool ConfigurationControllerResourceManager::ResourceComparator::operator() ( 331 const Reference<XResourceId>& rxId1, 332 const Reference<XResourceId>& rxId2) const 333 { 334 if (rxId1.is() && rxId2.is()) 335 return rxId1->compareTo(rxId2)<0; 336 else if (rxId1.is()) 337 return true; 338 else if (rxId2.is()) 339 return false; 340 else 341 return false; 342 } 343 344 345 346 347 } } // end of namespace sd::framework 348 349