/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #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; namespace sd { namespace framework { static const sal_uInt32 snFactoryPropertyCount (2); static const sal_uInt32 snStartupPropertyCount (1); class ModuleController::ResourceToFactoryMap : public ::boost::unordered_map< rtl::OUString, rtl::OUString, ::rtl::OUStringHash, ::comphelper::UStringEqual> { public: ResourceToFactoryMap (void) {} }; class ModuleController::LoadedFactoryContainer : public ::boost::unordered_map< rtl::OUString, WeakReference, ::rtl::OUStringHash, ::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("com.sun.star.comp.Draw.framework.module.ModuleController"); } Sequence SAL_CALL ModuleController_getSupportedServiceNames (void) throw (RuntimeException) { static const ::rtl::OUString sServiceName("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, "/org.openoffice.Office.Impress/", ConfigurationAccess::READ_ONLY); Reference xFactories ( aConfiguration.GetConfigurationNode("MultiPaneGUI/Framework/ResourceFactories"), UNO_QUERY); ::std::vector aProperties (snFactoryPropertyCount); aProperties[0] = "ServiceName"; aProperties[1] = "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, "URL", aURLs); SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": ModuleController::adding factory " << OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); // Add the resource URLs to the map. ::std::vector::const_iterator iResource; for (iResource=aURLs.begin(); iResource!=aURLs.end(); ++iResource) { (*mpResourceToFactoryMap)[*iResource] = sServiceName; SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": " << OUStringToOString(*iResource, RTL_TEXTENCODING_UTF8).getStr()); } } void ModuleController::InstantiateStartupServices (void) { try { tools::ConfigurationAccess aConfiguration ( "/org.openoffice.Office.Impress/", tools::ConfigurationAccess::READ_ONLY); Reference xFactories ( aConfiguration.GetConfigurationNode("MultiPaneGUI/Framework/StartupServices"), UNO_QUERY); ::std::vector aProperties (snStartupPropertyCount); aProperties[0] = "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); SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": ModuleController::created startup service " << OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr()); } } 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; xFactory = xGlobalFactory->createInstanceWithArguments( iFactory->second, aArguments); // 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 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */