/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "precompiled_sd.hxx" #include "framework/ModuleController.hxx" #include "tools/ConfigurationAccess.hxx" #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::drawing::framework; using ::rtl::OUString; using ::sd::tools::ConfigurationAccess; #undef VERBOSE //#define VERBOSE 2 namespace sd { namespace framework { static const sal_uInt32 snFactoryPropertyCount (2); static const sal_uInt32 snStartupPropertyCount (1); class ModuleController::ResourceToFactoryMap : public ::std::hash_map< rtl::OUString, rtl::OUString, ::comphelper::UStringHash, ::comphelper::UStringEqual> { public: ResourceToFactoryMap (void) {} }; class ModuleController::LoadedFactoryContainer : public ::std::hash_map< rtl::OUString, WeakReference, ::comphelper::UStringHash, ::comphelper::UStringEqual> { public: LoadedFactoryContainer (void) {} }; Reference SAL_CALL ModuleController_createInstance ( const Reference& rxContext) { return Reference(ModuleController::CreateInstance(rxContext), UNO_QUERY); } ::rtl::OUString ModuleController_getImplementationName (void) throw(RuntimeException) { return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.Draw.framework.module.ModuleController")); } Sequence SAL_CALL ModuleController_getSupportedServiceNames (void) throw (RuntimeException) { static const ::rtl::OUString sServiceName( ::rtl::OUString::createFromAscii("com.sun.star.drawing.framework.ModuleController")); return Sequence(&sServiceName, 1); } //===== ModuleController ====================================================== Reference ModuleController::CreateInstance ( const Reference& rxContext) { return new ModuleController(rxContext); } ModuleController::ModuleController (const Reference& rxContext) throw() : ModuleControllerInterfaceBase(MutexOwner::maMutex), mxController(), mpResourceToFactoryMap(new ResourceToFactoryMap()), mpLoadedFactories(new LoadedFactoryContainer()) { (void)rxContext; LoadFactories(rxContext); } ModuleController::~ModuleController (void) throw() { } void SAL_CALL ModuleController::disposing (void) { // Break the cyclic reference back to DrawController object mpLoadedFactories.reset(); mpResourceToFactoryMap.reset(); mxController.clear(); } void ModuleController::LoadFactories (const Reference& rxContext) { try { ConfigurationAccess aConfiguration ( rxContext, OUString::createFromAscii("/org.openoffice.Office.Impress/"), ConfigurationAccess::READ_ONLY); Reference xFactories ( aConfiguration.GetConfigurationNode( OUString::createFromAscii("MultiPaneGUI/Framework/ResourceFactories")), UNO_QUERY); ::std::vector aProperties (snFactoryPropertyCount); aProperties[0] = OUString::createFromAscii("ServiceName"); aProperties[1] = OUString::createFromAscii("ResourceList"); ConfigurationAccess::ForAll( xFactories, aProperties, ::boost::bind(&ModuleController::ProcessFactory, this, _2)); } catch (Exception&) { DBG_UNHANDLED_EXCEPTION(); } } void ModuleController::ProcessFactory (const ::std::vector& rValues) { OSL_ASSERT(rValues.size() == snFactoryPropertyCount); // Get the service name of the factory. rtl::OUString sServiceName; rValues[0] >>= sServiceName; // Get all resource URLs that are created by the factory. Reference xResources (rValues[1], UNO_QUERY); ::std::vector aURLs; tools::ConfigurationAccess::FillList( xResources, OUString::createFromAscii("URL"), aURLs); #if defined VERBOSE && VERBOSE>0 OSL_TRACE("ModuleController::adding factory %s", OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); #endif // Add the resource URLs to the map. ::std::vector::const_iterator iResource; for (iResource=aURLs.begin(); iResource!=aURLs.end(); ++iResource) { (*mpResourceToFactoryMap)[*iResource] = sServiceName; #if defined VERBOSE && VERBOSE>1 OSL_TRACE(" %s", OUStringToOString(*iResource, RTL_TEXTENCODING_UTF8).getStr()); #endif } } void ModuleController::InstantiateStartupServices (void) { try { tools::ConfigurationAccess aConfiguration ( OUString::createFromAscii("/org.openoffice.Office.Impress/"), tools::ConfigurationAccess::READ_ONLY); Reference xFactories ( aConfiguration.GetConfigurationNode( OUString::createFromAscii("MultiPaneGUI/Framework/StartupServices")), UNO_QUERY); ::std::vector aProperties (snStartupPropertyCount); aProperties[0] = OUString::createFromAscii("ServiceName"); tools::ConfigurationAccess::ForAll( xFactories, aProperties, ::boost::bind(&ModuleController::ProcessStartupService, this, _2)); } catch (Exception&) { OSL_TRACE("ERROR in ModuleController::InstantiateStartupServices"); } } void ModuleController::ProcessStartupService (const ::std::vector& rValues) { OSL_ASSERT(rValues.size() == snStartupPropertyCount); try { // Get the service name of the startup service. rtl::OUString sServiceName; rValues[0] >>= sServiceName; // Instantiate service. Reference xGlobalFactory ( ::comphelper::getProcessServiceFactory(), UNO_QUERY); if (xGlobalFactory.is()) { // Create the startup service. Sequence aArguments(1); aArguments[0] <<= mxController; // Note that when the new object will be destroyed at the end of // this scope when it does not register itself anywhere. // Typically it will add itself as ConfigurationChangeListener // at the configuration controller. xGlobalFactory->createInstanceWithArguments(sServiceName, aArguments); #if defined VERBOSE && VERBOSE>0 OSL_TRACE("ModuleController::created startup service %s", OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); #endif } } catch (Exception&) { OSL_TRACE("ERROR in ModuleController::ProcessStartupServices"); } } //----- XModuleController ----------------------------------------------------- void SAL_CALL ModuleController::requestResource (const OUString& rsResourceURL) throw (RuntimeException) { ResourceToFactoryMap::const_iterator iFactory (mpResourceToFactoryMap->find(rsResourceURL)); if (iFactory != mpResourceToFactoryMap->end()) { // Check that the factory has already been loaded and not been // destroyed in the meantime. Reference xFactory; LoadedFactoryContainer::const_iterator iLoadedFactory ( mpLoadedFactories->find(iFactory->second)); if (iLoadedFactory != mpLoadedFactories->end()) xFactory = Reference(iLoadedFactory->second, UNO_QUERY); if ( ! xFactory.is()) { // Create a new instance of the factory. Reference xGlobalFactory ( ::comphelper::getProcessServiceFactory(), UNO_QUERY); if (xGlobalFactory.is()) { // Create the factory service. Sequence aArguments(1); aArguments[0] <<= mxController; OSL_TRACE("creating resource %s", OUStringToOString(iFactory->second, RTL_TEXTENCODING_ASCII_US).getStr()); try { xFactory = xGlobalFactory->createInstanceWithArguments( iFactory->second, aArguments); } catch(Exception&e) { OSL_TRACE("caught exception while creating factory."); } // Remember that this factory has been instanced. (*mpLoadedFactories)[iFactory->second] = xFactory; } } } } //----- XInitialization ------------------------------------------------------- void SAL_CALL ModuleController::initialize (const Sequence& aArguments) throw (Exception, RuntimeException) { if (aArguments.getLength() > 0) { try { // Get the XController from the first argument. mxController = Reference(aArguments[0], UNO_QUERY_THROW); InstantiateStartupServices(); } catch (RuntimeException&) {} } } } } // end of namespace sd::framework