LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/framework/source/services - modulemanager.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 106 148 71.6 %
Date: 2013-07-09 Functions: 13 21 61.9 %
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        1474 : OUString ModuleManager::impl_getStaticImplementationName() {
      46        1474 :     return IMPLEMENTATIONNAME_MODULEMANAGER;
      47             : }
      48             : 
      49             : css::uno::Reference< css::lang::XSingleServiceFactory >
      50         122 : ModuleManager::impl_createFactory(
      51             :     css::uno::Reference< css::lang::XMultiServiceFactory > const & manager)
      52             : {
      53             :     return cppu::createSingleFactory(
      54             :         manager, impl_getStaticImplementationName(), &impl_createInstance,
      55         122 :         impl_getSupportedServiceNames());
      56             : }
      57             : 
      58             : css::uno::Sequence< OUString >
      59         122 : ModuleManager::impl_getSupportedServiceNames() {
      60         122 :     css::uno::Sequence< OUString > s(1);
      61         122 :     s[0] = "com.sun.star.frame.ModuleManager";
      62         122 :     return s;
      63             : }
      64             : 
      65       73469 : css::uno::Reference< css::uno::XInterface > ModuleManager::impl_createInstance(
      66             :     css::uno::Reference< css::lang::XMultiServiceFactory > const & manager)
      67             : {
      68       73469 :     return static_cast< cppu::OWeakObject * >(new ModuleManager( comphelper::getComponentContext(manager) ));
      69             : }
      70             : 
      71       73469 : ModuleManager::ModuleManager(const css::uno::Reference< css::uno::XComponentContext >& xContext)
      72             :     : ThreadHelpBase(     )
      73       73469 :     , m_xContext    (xContext)
      74             : {
      75       73469 : }
      76             : 
      77      220242 : ModuleManager::~ModuleManager()
      78             : {
      79       73414 :     if (m_xCFG.is())
      80        7566 :         m_xCFG.clear();
      81      146828 : }
      82             : 
      83           0 : OUString ModuleManager::getImplementationName()
      84             :     throw (css::uno::RuntimeException)
      85             : {
      86           0 :     return impl_getStaticImplementationName();
      87             : }
      88             : 
      89           0 : sal_Bool ModuleManager::supportsService(OUString const & ServiceName)
      90             :     throw (css::uno::RuntimeException)
      91             : {
      92           0 :     css::uno::Sequence< 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< OUString > ModuleManager::getSupportedServiceNames()
     102             :     throw (css::uno::RuntimeException)
     103             : {
     104           0 :     return impl_getSupportedServiceNames();
     105             : }
     106             : 
     107      101602 : 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      101602 :     css::uno::Reference< css::frame::XFrame >      xFrame     (xModule, css::uno::UNO_QUERY);
     114      203204 :     css::uno::Reference< css::awt::XWindow >       xWindow    (xModule, css::uno::UNO_QUERY);
     115      203204 :     css::uno::Reference< css::frame::XController > xController(xModule, css::uno::UNO_QUERY);
     116      203204 :     css::uno::Reference< css::frame::XModel >      xModel     (xModule, css::uno::UNO_QUERY);
     117             : 
     118      101602 :     if (
     119      120736 :         (!xFrame.is()     ) &&
     120       38268 :         (!xWindow.is()    ) &&
     121      139870 :         (!xController.is()) &&
     122       19134 :         (!xModel.is()     )
     123             :        )
     124             :     {
     125             :         throw css::lang::IllegalArgumentException(
     126             :                 OUString("Given module is not a frame nor a window, controller or model."),
     127             :                 static_cast< ::cppu::OWeakObject* >(this),
     128         249 :                 1);
     129             :     }
     130             : 
     131      101353 :     if (xFrame.is())
     132             :     {
     133       82468 :         xController = xFrame->getController();
     134       82468 :         xWindow     = xFrame->getComponentWindow();
     135             :     }
     136      101353 :     if (xController.is())
     137       75035 :         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      101353 :     OUString sModule;
     145      101353 :     if (xModel.is())
     146       93710 :         sModule = implts_identify(xModel);
     147        7643 :     else if (xController.is())
     148         210 :         sModule = implts_identify(xController);
     149        7433 :     else if (xWindow.is())
     150         859 :         sModule = implts_identify(xWindow);
     151             : 
     152      101353 :     if (sModule.isEmpty())
     153             :         throw css::frame::UnknownModuleException(
     154             :                 OUString("Cant find suitable module for the given component."),
     155        7650 :                 static_cast< ::cppu::OWeakObject* >(this));
     156             : 
     157      195305 :     return sModule;
     158             : }
     159             : 
     160          60 : void SAL_CALL ModuleManager::replaceByName(const 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          60 :     ::comphelper::SequenceAsHashMap lProps(aValue);
     168          60 :     if (lProps.empty() )
     169             :     {
     170             :         throw css::lang::IllegalArgumentException(
     171             :                 OUString("No properties given to replace part of module."),
     172             :                 static_cast< cppu::OWeakObject * >(this),
     173           0 :                 2);
     174             :     }
     175             : 
     176             :     // SAFE -> ----------------------------------
     177         120 :     ReadGuard aReadLock(m_aLock);
     178         120 :     css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
     179          60 :     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             :                                                                         xContext,
     189             :                                                                         OUString(CFGPATH_FACTORIES),
     190         120 :                                                                         ::comphelper::ConfigurationHelper::E_STANDARD);
     191         120 :     css::uno::Reference< css::container::XNameAccess >  xModules (xCfg, css::uno::UNO_QUERY_THROW);
     192         120 :     css::uno::Reference< css::container::XNameReplace > xModule  ;
     193             : 
     194          60 :     xModules->getByName(sName) >>= xModule;
     195          60 :     if (!xModule.is())
     196             :     {
     197             :         throw css::uno::RuntimeException(
     198             :                 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          60 :     ::comphelper::SequenceAsHashMap::const_iterator pProp;
     203         360 :     for (  pProp  = lProps.begin();
     204         240 :            pProp != lProps.end()  ;
     205             :          ++pProp                  )
     206             :     {
     207          60 :         const OUString& sPropName  = pProp->first;
     208          60 :         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          60 :         xModule->replaceByName(sPropName, aPropValue);
     213             :     }
     214             : 
     215         120 :     ::comphelper::ConfigurationHelper::flush(xCfg);
     216          60 : }
     217             : 
     218        8665 : css::uno::Any SAL_CALL ModuleManager::getByName(const OUString& sName)
     219             :     throw(css::container::NoSuchElementException,
     220             :           css::lang::WrappedTargetException     ,
     221             :           css::uno::RuntimeException            )
     222             : {
     223             :     // get access to the element
     224        8665 :     css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
     225       17330 :     css::uno::Reference< css::container::XNameAccess > xModule;
     226        8665 :     xCFG->getByName(sName) >>= xModule;
     227        8653 :     if (!xModule.is())
     228             :     {
     229             :         throw css::uno::RuntimeException(
     230             :                 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       17306 :     const css::uno::Sequence< OUString > lPropNames = xModule->getElementNames();
     236       17306 :           ::comphelper::SequenceAsHashMap       lProps     ;
     237        8653 :           sal_Int32                             c          = lPropNames.getLength();
     238        8653 :           sal_Int32                             i          = 0;
     239             : 
     240        8653 :     lProps[OUString(MODULEPROP_IDENTIFIER)] <<= sName;
     241      155754 :     for (i=0; i<c; ++i)
     242             :     {
     243      147101 :         const OUString& sPropName         = lPropNames[i];
     244      147101 :                                lProps[sPropName] = xModule->getByName(sPropName);
     245             :     }
     246             : 
     247       17318 :     return css::uno::makeAny(lProps.getAsConstPropertyValueList());
     248             : }
     249             : 
     250        1744 : css::uno::Sequence< OUString > SAL_CALL ModuleManager::getElementNames()
     251             :     throw(css::uno::RuntimeException)
     252             : {
     253        1744 :     css::uno::Reference< css::container::XNameAccess > xCFG = implts_getConfig();
     254        1744 :     return xCFG->getElementNames();
     255             : }
     256             : 
     257           0 : sal_Bool SAL_CALL ModuleManager::hasByName(const 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 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< 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 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       10409 : css::uno::Reference< css::container::XNameAccess > ModuleManager::implts_getConfig()
     313             :     throw(css::uno::RuntimeException)
     314             : {
     315             :     // SAFE -> ----------------------------------
     316       10409 :     ReadGuard aReadLock(m_aLock);
     317       10409 :     if (m_xCFG.is())
     318        2838 :         return m_xCFG;
     319       15142 :     css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
     320        7571 :     aReadLock.unlock();
     321             :     // <- SAFE ----------------------------------
     322             : 
     323       15142 :     css::uno::Reference< css::uno::XInterface > xCfg;
     324             :     try
     325             :     {
     326       15142 :         xCfg = ::comphelper::ConfigurationHelper::openConfig(
     327             :                     xContext,
     328             :                     OUString(CFGPATH_FACTORIES),
     329        7571 :                     ::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       15142 :     WriteGuard aWriteLock(m_aLock);
     342        7571 :     m_xCFG = css::uno::Reference< css::container::XNameAccess >(xCfg, css::uno::UNO_QUERY_THROW);
     343       17980 :     return m_xCFG;
     344             :     // <- SAFE ----------------------------------
     345             : }
     346             : 
     347       94779 : 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       94779 :     css::uno::Reference< css::frame::XModule > xModule(xComponent, css::uno::UNO_QUERY);
     353       94779 :     if (xModule.is())
     354       92331 :         return xModule->getIdentifier();
     355             : 
     356             :     // detect modules in a generic way ...
     357             :     // comparing service names with configured entries ...
     358        4896 :     css::uno::Reference< css::lang::XServiceInfo > xInfo(xComponent, css::uno::UNO_QUERY);
     359        2448 :     if (!xInfo.is())
     360         859 :         return OUString();
     361             : 
     362        3178 :     const css::uno::Sequence< OUString > lKnownModules = getElementNames();
     363        1589 :     const OUString*                      pKnownModules = lKnownModules.getConstArray();
     364        1589 :           sal_Int32                             c             = lKnownModules.getLength();
     365        1589 :           sal_Int32                             i             = 0;
     366             : 
     367       10361 :     for (i=0; i<c; ++i)
     368             :     {
     369       10183 :         if (xInfo->supportsService(pKnownModules[i]))
     370        1411 :             return pKnownModules[i];
     371             :     }
     372             : 
     373       94957 :     return OUString();
     374             : }
     375             : 
     376             : } // namespace framework
     377             : 
     378             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10