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