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