LCOV - code coverage report
Current view: top level - libreoffice/framework/source/services - modulemanager.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 76 147 51.7 %
Date: 2012-12-27 Functions: 12 21 57.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "services/modulemanager.hxx"
      22             : #include "services/frame.hxx"
      23             : 
      24             : #include <threadhelp/readguard.hxx>
      25             : #include <threadhelp/writeguard.hxx>
      26             : #include <services.h>
      27             : 
      28             : #include <com/sun/star/frame/XFrame.hpp>
      29             : #include <com/sun/star/frame/XController.hpp>
      30             : #include <com/sun/star/frame/XModel.hpp>
      31             : #include <com/sun/star/frame/XModule.hpp>
      32             : #include <comphelper/configurationhelper.hxx>
      33             : #include <comphelper/sequenceashashmap.hxx>
      34             : #include <comphelper/sequenceasvector.hxx>
      35             : #include <comphelper/enumhelper.hxx>
      36             : 
      37             : #include <rtl/logfile.hxx>
      38             : 
      39             : namespace framework
      40             : {
      41             : 
      42             : static const char CFGPATH_FACTORIES[] = "/org.openoffice.Setup/Office/Factories";
      43             : static const char MODULEPROP_IDENTIFIER[] = "ooSetupFactoryModuleIdentifier";
      44             : 
      45         175 : rtl::OUString ModuleManager::impl_getStaticImplementationName() {
      46         175 :     return IMPLEMENTATIONNAME_MODULEMANAGER;
      47             : }
      48             : 
      49             : css::uno::Reference< css::lang::XSingleServiceFactory >
      50          18 : ModuleManager::impl_createFactory(
      51             :     css::uno::Reference< css::lang::XMultiServiceFactory > const & manager)
      52             : {
      53             :     return cppu::createSingleFactory(
      54             :         manager, impl_getStaticImplementationName(), &impl_createInstance,
      55          18 :         impl_getSupportedServiceNames());
      56             : }
      57             : 
      58             : css::uno::Sequence< rtl::OUString >
      59          18 : ModuleManager::impl_getSupportedServiceNames() {
      60          18 :     css::uno::Sequence< rtl::OUString > s(1);
      61          18 :     s[0] = "com.sun.star.frame.ModuleManager";
      62          18 :     return s;
      63             : }
      64             : 
      65       26914 : css::uno::Reference< css::uno::XInterface > ModuleManager::impl_createInstance(
      66             :     css::uno::Reference< css::lang::XMultiServiceFactory > const & manager)
      67             : {
      68       26914 :     return static_cast< cppu::OWeakObject * >(new ModuleManager(manager));
      69             : }
      70             : 
      71       26914 : ModuleManager::ModuleManager(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
      72             :     : ThreadHelpBase(     )
      73       26914 :     , m_xSMGR       (xSMGR)
      74             : {
      75       26914 : }
      76             : 
      77       80115 : ModuleManager::~ModuleManager()
      78             : {
      79       26705 :     if (m_xCFG.is())
      80         862 :         m_xCFG.clear();
      81       53410 : }
      82             : 
      83           0 : rtl::OUString ModuleManager::getImplementationName()
      84             :     throw (css::uno::RuntimeException)
      85             : {
      86           0 :     return impl_getStaticImplementationName();
      87             : }
      88             : 
      89           0 : sal_Bool ModuleManager::supportsService(rtl::OUString const & ServiceName)
      90             :     throw (css::uno::RuntimeException)
      91             : {
      92           0 :     css::uno::Sequence< rtl::OUString > s(getSupportedServiceNames());
      93           0 :     for (sal_Int32 i = 0; i != s.getLength(); ++i) {
      94           0 :         if (s[i] == ServiceName) {
      95           0 :             return true;
      96             :         }
      97             :     }
      98           0 :     return false;
      99             : }
     100             : 
     101           0 : css::uno::Sequence< rtl::OUString > ModuleManager::getSupportedServiceNames()
     102             :     throw (css::uno::RuntimeException)
     103             : {
     104           0 :     return impl_getSupportedServiceNames();
     105             : }
     106             : 
     107       31911 : ::rtl::OUString SAL_CALL ModuleManager::identify(const css::uno::Reference< css::uno::XInterface >& xModule)
     108             :     throw(css::lang::IllegalArgumentException,
     109             :           css::frame::UnknownModuleException,
     110             :           css::uno::RuntimeException         )
     111             : {
     112             :     // valid parameter?
     113       31911 :     css::uno::Reference< css::frame::XFrame >      xFrame     (xModule, css::uno::UNO_QUERY);
     114       31911 :     css::uno::Reference< css::awt::XWindow >       xWindow    (xModule, css::uno::UNO_QUERY);
     115       31911 :     css::uno::Reference< css::frame::XController > xController(xModule, css::uno::UNO_QUERY);
     116       31911 :     css::uno::Reference< css::frame::XModel >      xModel     (xModule, css::uno::UNO_QUERY);
     117             : 
     118       47031 :     if (
     119       31911 :         (!xFrame.is()     ) &&
     120        5040 :         (!xWindow.is()    ) &&
     121        5040 :         (!xController.is()) &&
     122        5040 :         (!xModel.is()     )
     123             :        )
     124             :     {
     125             :         throw css::lang::IllegalArgumentException(
     126             :                 ::rtl::OUString("Given module is not a frame nor a window, controller or model."),
     127             :                 static_cast< ::cppu::OWeakObject* >(this),
     128           0 :                 1);
     129             :     }
     130             : 
     131       31911 :     if (xFrame.is())
     132             :     {
     133       26871 :         xController = xFrame->getController();
     134       26871 :         xWindow     = xFrame->getComponentWindow();
     135             :     }
     136       31911 :     if (xController.is())
     137       25752 :         xModel = xController->getModel();
     138             : 
     139             :     // modules are implemented by the deepest component in hierarchy ...
     140             :     // Means: model -> controller -> window
     141             :     // No fallbacks to higher components are allowed !
     142             :     // Note : A frame provides access to module components only ... but it's not a module by himself.
     143             : 
     144       31911 :     ::rtl::OUString sModule;
     145       31911 :     if (xModel.is())
     146       30792 :         sModule = implts_identify(xModel);
     147        1119 :     else if (xController.is())
     148           0 :         sModule = implts_identify(xController);
     149        1119 :     else if (xWindow.is())
     150          63 :         sModule = implts_identify(xWindow);
     151             : 
     152       31911 :     if (sModule.isEmpty())
     153             :         throw css::frame::UnknownModuleException(
     154             :                 ::rtl::OUString("Cant find suitable module for the given component."),
     155        1228 :                 static_cast< ::cppu::OWeakObject* >(this));
     156             : 
     157       31911 :     return sModule;
     158             : }
     159             : 
     160           0 : void SAL_CALL ModuleManager::replaceByName(const ::rtl::OUString& sName ,
     161             :                                            const css::uno::Any&   aValue)
     162             :     throw (css::lang::IllegalArgumentException   ,
     163             :            css::container::NoSuchElementException,
     164             :            css::lang::WrappedTargetException     ,
     165             :            css::uno::RuntimeException            )
     166             : {
     167           0 :     ::comphelper::SequenceAsHashMap lProps(aValue);
     168           0 :     if (lProps.empty() )
     169             :     {
     170             :         throw css::lang::IllegalArgumentException(
     171             :                 ::rtl::OUString("No properties given to replace part of module."),
     172             :                 static_cast< cppu::OWeakObject * >(this),
     173           0 :                 2);
     174             :     }
     175             : 
     176             :     // SAFE -> ----------------------------------
     177           0 :     ReadGuard aReadLock(m_aLock);
     178           0 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     179           0 :     aReadLock.unlock();
     180             :     // <- SAFE ----------------------------------
     181             : 
     182             :     // get access to the element
     183             :     // Note: Dont use impl_getConfig() method here. Because it creates a readonly access only, further
     184             :     // it cache it as a member of this module manager instance. If we change some props there ... but dont
     185             :     // flush changes (because an error occurred) we will read them later. If we use a different config access
     186             :     // we can close it without a flush ... and our read data wont be affected .-)
     187             :     css::uno::Reference< css::uno::XInterface >         xCfg      = ::comphelper::ConfigurationHelper::openConfig(
     188             :                                                                         comphelper::getComponentContext(xSMGR),
     189             :                                                                         rtl::OUString(CFGPATH_FACTORIES),
     190           0 :                                                                         ::comphelper::ConfigurationHelper::E_STANDARD);
     191           0 :     css::uno::Reference< css::container::XNameAccess >  xModules (xCfg, css::uno::UNO_QUERY_THROW);
     192           0 :     css::uno::Reference< css::container::XNameReplace > xModule  ;
     193             : 
     194           0 :     xModules->getByName(sName) >>= xModule;
     195           0 :     if (!xModule.is())
     196             :     {
     197             :         throw css::uno::RuntimeException(
     198             :                 ::rtl::OUString("Was not able to get write access to the requested module entry inside configuration."),
     199           0 :                 static_cast< cppu::OWeakObject * >(this));
     200             :     }
     201             : 
     202           0 :     ::comphelper::SequenceAsHashMap::const_iterator pProp;
     203           0 :     for (  pProp  = lProps.begin();
     204           0 :            pProp != lProps.end()  ;
     205             :          ++pProp                  )
     206             :     {
     207           0 :         const ::rtl::OUString& sPropName  = pProp->first;
     208           0 :         const css::uno::Any&   aPropValue = pProp->second;
     209             : 
     210             :         // let "NoSuchElementException" out ! We support the same API ...
     211             :         // and without a flush() at the end all changed data before will be ignored !
     212           0 :         xModule->replaceByName(sPropName, aPropValue);
     213             :     }
     214             : 
     215           0 :     ::comphelper::ConfigurationHelper::flush(xCfg);
     216           0 : }
     217             : 
     218        1032 : css::uno::Any SAL_CALL ModuleManager::getByName(const ::rtl::OUString& sName)
     219             :     throw(css::container::NoSuchElementException,
     220             :           css::lang::WrappedTargetException     ,
     221             :           css::uno::RuntimeException            )
     222             : {
     223             :     // get access to the element
     224        1032 :     css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
     225        1032 :     css::uno::Reference< css::container::XNameAccess > xModule;
     226        1032 :     xCFG->getByName(sName) >>= xModule;
     227        1020 :     if (!xModule.is())
     228             :     {
     229             :         throw css::uno::RuntimeException(
     230             :                 ::rtl::OUString("Was not able to get write access to the requested module entry inside configuration."),
     231           0 :                 static_cast< cppu::OWeakObject * >(this));
     232             :     }
     233             : 
     234             :     // convert it to seq< PropertyValue >
     235        1020 :     const css::uno::Sequence< ::rtl::OUString > lPropNames = xModule->getElementNames();
     236        1020 :           ::comphelper::SequenceAsHashMap       lProps     ;
     237        1020 :           sal_Int32                             c          = lPropNames.getLength();
     238        1020 :           sal_Int32                             i          = 0;
     239             : 
     240        1020 :     lProps[rtl::OUString(MODULEPROP_IDENTIFIER)] <<= sName;
     241       18360 :     for (i=0; i<c; ++i)
     242             :     {
     243       17340 :         const ::rtl::OUString& sPropName         = lPropNames[i];
     244       17340 :                                lProps[sPropName] = xModule->getByName(sPropName);
     245             :     }
     246             : 
     247        1020 :     return css::uno::makeAny(lProps.getAsConstPropertyValueList());
     248             : }
     249             : 
     250          18 : css::uno::Sequence< ::rtl::OUString > SAL_CALL ModuleManager::getElementNames()
     251             :     throw(css::uno::RuntimeException)
     252             : {
     253          18 :     css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
     254          18 :     return xCFG->getElementNames();
     255             : }
     256             : 
     257           0 : sal_Bool SAL_CALL ModuleManager::hasByName(const ::rtl::OUString& sName)
     258             :     throw(css::uno::RuntimeException)
     259             : {
     260           0 :     css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
     261           0 :     return xCFG->hasByName(sName);
     262             : }
     263             : 
     264           0 : css::uno::Type SAL_CALL ModuleManager::getElementType()
     265             :     throw(css::uno::RuntimeException)
     266             : {
     267           0 :     return ::getCppuType((const css::uno::Sequence< css::beans::PropertyValue >*)0);
     268             : }
     269             : 
     270           0 : sal_Bool SAL_CALL ModuleManager::hasElements()
     271             :     throw(css::uno::RuntimeException)
     272             : {
     273           0 :     css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
     274           0 :     return xCFG->hasElements();
     275             : }
     276             : 
     277           0 : css::uno::Reference< css::container::XEnumeration > SAL_CALL ModuleManager::createSubSetEnumerationByQuery(const ::rtl::OUString&)
     278             :     throw(css::uno::RuntimeException)
     279             : {
     280           0 :     return css::uno::Reference< css::container::XEnumeration >();
     281             : }
     282             : 
     283           0 : css::uno::Reference< css::container::XEnumeration > SAL_CALL ModuleManager::createSubSetEnumerationByProperties(const css::uno::Sequence< css::beans::NamedValue >& lProperties)
     284             :     throw(css::uno::RuntimeException)
     285             : {
     286           0 :     ::comphelper::SequenceAsHashMap                 lSearchProps (lProperties);
     287           0 :     css::uno::Sequence< ::rtl::OUString >           lModules     = getElementNames();
     288           0 :     sal_Int32                                       c            = lModules.getLength();
     289           0 :     sal_Int32                                       i            = 0;
     290           0 :     ::comphelper::SequenceAsVector< css::uno::Any > lResult      ;
     291             : 
     292           0 :     for (i=0; i<c; ++i)
     293             :     {
     294             :         try
     295             :         {
     296           0 :             const ::rtl::OUString&                sModule      = lModules[i];
     297           0 :                   ::comphelper::SequenceAsHashMap lModuleProps = getByName(sModule);
     298             : 
     299           0 :             if (lModuleProps.match(lSearchProps))
     300           0 :                 lResult.push_back(css::uno::makeAny(lModuleProps.getAsConstPropertyValueList()));
     301             :         }
     302           0 :         catch(const css::uno::Exception&)
     303             :         {
     304             :         }
     305             :     }
     306             : 
     307           0 :     ::comphelper::OAnyEnumeration*                      pEnum = new ::comphelper::OAnyEnumeration(lResult.getAsConstList());
     308           0 :     css::uno::Reference< css::container::XEnumeration > xEnum(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY_THROW);
     309           0 :     return xEnum;
     310             : }
     311             : 
     312        1050 : css::uno::Reference< css::container::XNameAccess > ModuleManager::implts_getConfig()
     313             :     throw(css::uno::RuntimeException)
     314             : {
     315             :     // SAFE -> ----------------------------------
     316        1050 :     ReadGuard aReadLock(m_aLock);
     317        1050 :     if (m_xCFG.is())
     318         180 :         return m_xCFG;
     319         870 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     320         870 :     aReadLock.unlock();
     321             :     // <- SAFE ----------------------------------
     322             : 
     323         870 :     css::uno::Reference< css::uno::XInterface > xCfg;
     324             :     try
     325             :     {
     326             :         xCfg = ::comphelper::ConfigurationHelper::openConfig(
     327             :                     comphelper::getComponentContext(xSMGR),
     328             :                     rtl::OUString(CFGPATH_FACTORIES),
     329         870 :                     ::comphelper::ConfigurationHelper::E_READONLY);
     330             :     }
     331           0 :     catch(const css::uno::RuntimeException&)
     332             :     {
     333           0 :         throw;
     334             :     }
     335           0 :     catch(const css::uno::Exception&)
     336             :     {
     337           0 :         xCfg.clear();
     338             :     }
     339             : 
     340             :     // SAFE -> ----------------------------------
     341         870 :     WriteGuard aWriteLock(m_aLock);
     342         870 :     m_xCFG = css::uno::Reference< css::container::XNameAccess >(xCfg, css::uno::UNO_QUERY_THROW);
     343         870 :     return m_xCFG;
     344             :     // <- SAFE ----------------------------------
     345             : }
     346             : 
     347       30855 : ::rtl::OUString ModuleManager::implts_identify(const css::uno::Reference< css::uno::XInterface >& xComponent)
     348             : {
     349             :     // Search for an optional (!) interface XModule first.
     350             :     // Its used to overrule an existing service name. Used e.g. by our database form designer
     351             :     // which uses a writer module internaly.
     352       30855 :     css::uno::Reference< css::frame::XModule > xModule(xComponent, css::uno::UNO_QUERY);
     353       30855 :     if (xModule.is())
     354       30792 :         return xModule->getIdentifier();
     355             : 
     356             :     // detect modules in a generic way ...
     357             :     // comparing service names with configured entries ...
     358          63 :     css::uno::Reference< css::lang::XServiceInfo > xInfo(xComponent, css::uno::UNO_QUERY);
     359          63 :     if (!xInfo.is())
     360          63 :         return ::rtl::OUString();
     361             : 
     362           0 :     const css::uno::Sequence< ::rtl::OUString > lKnownModules = getElementNames();
     363           0 :     const ::rtl::OUString*                      pKnownModules = lKnownModules.getConstArray();
     364           0 :           sal_Int32                             c             = lKnownModules.getLength();
     365           0 :           sal_Int32                             i             = 0;
     366             : 
     367           0 :     for (i=0; i<c; ++i)
     368             :     {
     369           0 :         if (xInfo->supportsService(pKnownModules[i]))
     370           0 :             return pKnownModules[i];
     371             :     }
     372             : 
     373           0 :     return ::rtl::OUString();
     374             : }
     375             : 
     376             : } // namespace framework
     377             : 
     378             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10