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/ModuleController.hxx" 31 32 #include "tools/ConfigurationAccess.hxx" 33 #include <comphelper/processfactory.hxx> 34 #include <comphelper/stl_types.hxx> 35 #include <boost/bind.hpp> 36 #include <hash_map> 37 38 #include <tools/diagnose_ex.h> 39 40 using namespace ::com::sun::star; 41 using namespace ::com::sun::star::uno; 42 using namespace ::com::sun::star::drawing::framework; 43 using ::rtl::OUString; 44 using ::sd::tools::ConfigurationAccess; 45 46 #undef VERBOSE 47 //#define VERBOSE 2 48 49 namespace sd { namespace framework { 50 51 static const sal_uInt32 snFactoryPropertyCount (2); 52 static const sal_uInt32 snStartupPropertyCount (1); 53 54 55 56 57 class ModuleController::ResourceToFactoryMap 58 : public ::std::hash_map< 59 rtl::OUString, 60 rtl::OUString, 61 ::comphelper::UStringHash, 62 ::comphelper::UStringEqual> 63 { 64 public: 65 ResourceToFactoryMap (void) {} 66 }; 67 68 69 class ModuleController::LoadedFactoryContainer 70 : public ::std::hash_map< 71 rtl::OUString, 72 WeakReference<XInterface>, 73 ::comphelper::UStringHash, 74 ::comphelper::UStringEqual> 75 { 76 public: 77 LoadedFactoryContainer (void) {} 78 }; 79 80 81 82 83 84 Reference<XInterface> SAL_CALL ModuleController_createInstance ( 85 const Reference<XComponentContext>& rxContext) 86 { 87 return Reference<XInterface>(ModuleController::CreateInstance(rxContext), UNO_QUERY); 88 } 89 90 91 92 93 ::rtl::OUString ModuleController_getImplementationName (void) throw(RuntimeException) 94 { 95 return ::rtl::OUString( 96 RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.module.ModuleController")); 97 } 98 99 100 101 102 Sequence<rtl::OUString> SAL_CALL ModuleController_getSupportedServiceNames (void) 103 throw (RuntimeException) 104 { 105 static const ::rtl::OUString sServiceName( 106 ::rtl::OUString::createFromAscii("com.sun.star.drawing.framework.ModuleController")); 107 return Sequence<rtl::OUString>(&sServiceName, 1); 108 } 109 110 111 112 113 //===== ModuleController ====================================================== 114 115 Reference<XModuleController> ModuleController::CreateInstance ( 116 const Reference<XComponentContext>& rxContext) 117 { 118 return new ModuleController(rxContext); 119 } 120 121 122 123 124 ModuleController::ModuleController (const Reference<XComponentContext>& rxContext) throw() 125 : ModuleControllerInterfaceBase(MutexOwner::maMutex), 126 mxController(), 127 mpResourceToFactoryMap(new ResourceToFactoryMap()), 128 mpLoadedFactories(new LoadedFactoryContainer()) 129 { 130 (void)rxContext; 131 LoadFactories(rxContext); 132 } 133 134 135 136 137 ModuleController::~ModuleController (void) throw() 138 { 139 } 140 141 142 143 144 void SAL_CALL ModuleController::disposing (void) 145 { 146 // Break the cyclic reference back to DrawController object 147 mpLoadedFactories.reset(); 148 mpResourceToFactoryMap.reset(); 149 mxController.clear(); 150 } 151 152 153 154 155 void ModuleController::LoadFactories (const Reference<XComponentContext>& rxContext) 156 { 157 try 158 { 159 ConfigurationAccess aConfiguration ( 160 rxContext, 161 OUString::createFromAscii("/org.openoffice.Office.Impress/"), 162 ConfigurationAccess::READ_ONLY); 163 Reference<container::XNameAccess> xFactories ( 164 aConfiguration.GetConfigurationNode( 165 OUString::createFromAscii("MultiPaneGUI/Framework/ResourceFactories")), 166 UNO_QUERY); 167 ::std::vector<rtl::OUString> aProperties (snFactoryPropertyCount); 168 aProperties[0] = OUString::createFromAscii("ServiceName"); 169 aProperties[1] = OUString::createFromAscii("ResourceList"); 170 ConfigurationAccess::ForAll( 171 xFactories, 172 aProperties, 173 ::boost::bind(&ModuleController::ProcessFactory, this, _2)); 174 } 175 catch (Exception&) 176 { 177 DBG_UNHANDLED_EXCEPTION(); 178 } 179 } 180 181 182 183 184 void ModuleController::ProcessFactory (const ::std::vector<Any>& rValues) 185 { 186 OSL_ASSERT(rValues.size() == snFactoryPropertyCount); 187 188 // Get the service name of the factory. 189 rtl::OUString sServiceName; 190 rValues[0] >>= sServiceName; 191 192 // Get all resource URLs that are created by the factory. 193 Reference<container::XNameAccess> xResources (rValues[1], UNO_QUERY); 194 ::std::vector<rtl::OUString> aURLs; 195 tools::ConfigurationAccess::FillList( 196 xResources, 197 OUString::createFromAscii("URL"), 198 aURLs); 199 200 #if defined VERBOSE && VERBOSE>0 201 OSL_TRACE("ModuleController::adding factory %s", 202 OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); 203 #endif 204 205 // Add the resource URLs to the map. 206 ::std::vector<rtl::OUString>::const_iterator iResource; 207 for (iResource=aURLs.begin(); iResource!=aURLs.end(); ++iResource) 208 { 209 (*mpResourceToFactoryMap)[*iResource] = sServiceName; 210 #if defined VERBOSE && VERBOSE>1 211 OSL_TRACE(" %s", 212 OUStringToOString(*iResource, RTL_TEXTENCODING_UTF8).getStr()); 213 #endif 214 } 215 } 216 217 218 219 220 void ModuleController::InstantiateStartupServices (void) 221 { 222 try 223 { 224 tools::ConfigurationAccess aConfiguration ( 225 OUString::createFromAscii("/org.openoffice.Office.Impress/"), 226 tools::ConfigurationAccess::READ_ONLY); 227 Reference<container::XNameAccess> xFactories ( 228 aConfiguration.GetConfigurationNode( 229 OUString::createFromAscii("MultiPaneGUI/Framework/StartupServices")), 230 UNO_QUERY); 231 ::std::vector<rtl::OUString> aProperties (snStartupPropertyCount); 232 aProperties[0] = OUString::createFromAscii("ServiceName"); 233 tools::ConfigurationAccess::ForAll( 234 xFactories, 235 aProperties, 236 ::boost::bind(&ModuleController::ProcessStartupService, this, _2)); 237 } 238 catch (Exception&) 239 { 240 OSL_TRACE("ERROR in ModuleController::InstantiateStartupServices"); 241 } 242 } 243 244 245 246 247 void ModuleController::ProcessStartupService (const ::std::vector<Any>& rValues) 248 { 249 OSL_ASSERT(rValues.size() == snStartupPropertyCount); 250 251 try 252 { 253 // Get the service name of the startup service. 254 rtl::OUString sServiceName; 255 rValues[0] >>= sServiceName; 256 257 // Instantiate service. 258 Reference<lang::XMultiServiceFactory> xGlobalFactory ( 259 ::comphelper::getProcessServiceFactory(), UNO_QUERY); 260 if (xGlobalFactory.is()) 261 { 262 // Create the startup service. 263 Sequence<Any> aArguments(1); 264 aArguments[0] <<= mxController; 265 // Note that when the new object will be destroyed at the end of 266 // this scope when it does not register itself anywhere. 267 // Typically it will add itself as ConfigurationChangeListener 268 // at the configuration controller. 269 xGlobalFactory->createInstanceWithArguments(sServiceName, aArguments); 270 271 #if defined VERBOSE && VERBOSE>0 272 OSL_TRACE("ModuleController::created startup service %s", 273 OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); 274 #endif 275 } 276 } 277 catch (Exception&) 278 { 279 OSL_TRACE("ERROR in ModuleController::ProcessStartupServices"); 280 } 281 } 282 283 284 285 286 //----- XModuleController ----------------------------------------------------- 287 288 void SAL_CALL ModuleController::requestResource (const OUString& rsResourceURL) 289 throw (RuntimeException) 290 { 291 ResourceToFactoryMap::const_iterator iFactory (mpResourceToFactoryMap->find(rsResourceURL)); 292 if (iFactory != mpResourceToFactoryMap->end()) 293 { 294 // Check that the factory has already been loaded and not been 295 // destroyed in the meantime. 296 Reference<XInterface> xFactory; 297 LoadedFactoryContainer::const_iterator iLoadedFactory ( 298 mpLoadedFactories->find(iFactory->second)); 299 if (iLoadedFactory != mpLoadedFactories->end()) 300 xFactory = Reference<XInterface>(iLoadedFactory->second, UNO_QUERY); 301 if ( ! xFactory.is()) 302 { 303 // Create a new instance of the factory. 304 Reference<lang::XMultiServiceFactory> xGlobalFactory ( 305 ::comphelper::getProcessServiceFactory(), UNO_QUERY); 306 if (xGlobalFactory.is()) 307 { 308 // Create the factory service. 309 Sequence<Any> aArguments(1); 310 aArguments[0] <<= mxController; 311 xFactory = xGlobalFactory->createInstanceWithArguments( 312 iFactory->second, 313 aArguments); 314 315 // Remember that this factory has been instanced. 316 (*mpLoadedFactories)[iFactory->second] = xFactory; 317 } 318 } 319 } 320 } 321 322 323 324 325 //----- XInitialization ------------------------------------------------------- 326 327 void SAL_CALL ModuleController::initialize (const Sequence<Any>& aArguments) 328 throw (Exception, RuntimeException) 329 { 330 if (aArguments.getLength() > 0) 331 { 332 try 333 { 334 // Get the XController from the first argument. 335 mxController = Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW); 336 337 InstantiateStartupServices(); 338 } 339 catch (RuntimeException&) 340 {} 341 } 342 } 343 344 345 } } // end of namespace sd::framework 346