LCOV - code coverage report
Current view: top level - configmgr/source - configurationprovider.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 130 159 81.8 %
Date: 2015-06-13 12:38:46 Functions: 27 33 81.8 %
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             : #include <sal/config.h>
      21             : 
      22             : #include <cassert>
      23             : #include <memory>
      24             : #include <vector>
      25             : 
      26             : #include <com/sun/star/beans/NamedValue.hpp>
      27             : #include <com/sun/star/beans/PropertyValue.hpp>
      28             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      29             : #include <com/sun/star/lang/EventObject.hpp>
      30             : #include <com/sun/star/lang/Locale.hpp>
      31             : #include <com/sun/star/lang/XLocalizable.hpp>
      32             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      33             : #include <com/sun/star/lang/XServiceInfo.hpp>
      34             : #include <com/sun/star/lang/XSingleComponentFactory.hpp>
      35             : #include <com/sun/star/uno/Any.hxx>
      36             : #include <com/sun/star/uno/Exception.hpp>
      37             : #include <com/sun/star/uno/Reference.hxx>
      38             : #include <com/sun/star/uno/RuntimeException.hpp>
      39             : #include <com/sun/star/uno/Sequence.hxx>
      40             : #include <com/sun/star/uno/XComponentContext.hpp>
      41             : #include <com/sun/star/uno/XInterface.hpp>
      42             : #include <com/sun/star/util/XFlushListener.hpp>
      43             : #include <com/sun/star/util/XFlushable.hpp>
      44             : #include <com/sun/star/util/XRefreshListener.hpp>
      45             : #include <com/sun/star/util/XRefreshable.hpp>
      46             : #include <cppu/unotype.hxx>
      47             : #include <cppuhelper/basemutex.hxx>
      48             : #include <cppuhelper/compbase5.hxx>
      49             : #include <cppuhelper/factory.hxx>
      50             : #include <cppuhelper/implbase2.hxx>
      51             : #include <cppuhelper/interfacecontainer.hxx>
      52             : #include <cppuhelper/supportsservice.hxx>
      53             : #include <cppuhelper/weak.hxx>
      54             : #include <osl/mutex.hxx>
      55             : #include <sal/types.h>
      56             : #include <rtl/ref.hxx>
      57             : #include <rtl/ustring.hxx>
      58             : 
      59             : #include <i18nlangtag/languagetag.hxx>
      60             : 
      61             : #include "components.hxx"
      62             : #include "configurationprovider.hxx"
      63             : #include "lock.hxx"
      64             : #include "defaultprovider.hxx"
      65             : #include "rootaccess.hxx"
      66             : 
      67             : namespace configmgr { namespace configuration_provider {
      68             : 
      69             : namespace {
      70             : 
      71             : char const accessServiceName[] =
      72             :     "com.sun.star.configuration.ConfigurationAccess";
      73             : char const updateAccessServiceName[] =
      74             :     "com.sun.star.configuration.ConfigurationUpdateAccess";
      75             : 
      76           0 : void badNodePath() {
      77             :     throw css::uno::Exception(
      78             :         ("com.sun.star.configuration.ConfigurationProvider expects a single,"
      79             :          " non-empty, string nodepath argument"),
      80           0 :         0);
      81             : }
      82             : 
      83             : typedef
      84             :     cppu::WeakComponentImplHelper5<
      85             :         css::lang::XServiceInfo, css::lang::XMultiServiceFactory,
      86             :         css::util::XRefreshable, css::util::XFlushable,
      87             :         css::lang::XLocalizable >
      88             :     ServiceBase;
      89             : 
      90             : class Service:
      91             :     private cppu::BaseMutex, public ServiceBase
      92             : {
      93             : public:
      94         250 :     explicit Service(
      95             :         css::uno::Reference< css::uno::XComponentContext > const context):
      96         250 :         ServiceBase(m_aMutex), context_(context), default_(true)
      97             :     {
      98         250 :         lock_ = lock();
      99             :         assert(context.is());
     100         250 :     }
     101             : 
     102           1 :     Service(
     103             :         css::uno::Reference< css::uno::XComponentContext > const context,
     104             :         OUString const & locale):
     105             :         ServiceBase(m_aMutex), context_(context), locale_(locale),
     106           1 :         default_(false)
     107             :     {
     108           1 :         lock_ = lock();
     109             :         assert(context.is());
     110           1 :     }
     111             : 
     112             : private:
     113             :     Service(const Service&) SAL_DELETED_FUNCTION;
     114             :     Service& operator=(const Service&) SAL_DELETED_FUNCTION;
     115             : 
     116         470 :     virtual ~Service() {}
     117             : 
     118         249 :     virtual void SAL_CALL disposing() SAL_OVERRIDE { flushModifications(); }
     119             : 
     120           2 :     virtual OUString SAL_CALL getImplementationName()
     121             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     122             :     {
     123             :         return default_
     124             :             ? default_provider::getImplementationName()
     125           2 :             : configuration_provider::getImplementationName();
     126             :     }
     127             : 
     128           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
     129             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     130           0 :     { return cppu::supportsService(this, ServiceName); }
     131             : 
     132             :     virtual css::uno::Sequence< OUString > SAL_CALL
     133           2 :     getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     134             :     {
     135             :         return default_
     136             :             ? default_provider::getSupportedServiceNames()
     137           2 :             : configuration_provider::getSupportedServiceNames();
     138             :     }
     139             : 
     140             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
     141             :         OUString const & aServiceSpecifier)
     142             :         throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     143             : 
     144             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     145             :     createInstanceWithArguments(
     146             :         OUString const & ServiceSpecifier,
     147             :         css::uno::Sequence< css::uno::Any > const & Arguments)
     148             :         throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     149             : 
     150             :     virtual css::uno::Sequence< OUString > SAL_CALL
     151             :     getAvailableServiceNames() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     152             : 
     153             :     virtual void SAL_CALL refresh() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     154             : 
     155             :     virtual void SAL_CALL addRefreshListener(
     156             :         css::uno::Reference< css::util::XRefreshListener > const & l)
     157             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     158             : 
     159             :     virtual void SAL_CALL removeRefreshListener(
     160             :         css::uno::Reference< css::util::XRefreshListener > const & l)
     161             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     162             : 
     163             :     virtual void SAL_CALL flush() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     164             : 
     165             :     virtual void SAL_CALL addFlushListener(
     166             :         css::uno::Reference< css::util::XFlushListener > const & l)
     167             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     168             : 
     169             :     virtual void SAL_CALL removeFlushListener(
     170             :         css::uno::Reference< css::util::XFlushListener > const & l)
     171             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     172             : 
     173             :     virtual void SAL_CALL setLocale(css::lang::Locale const & eLocale)
     174             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     175             : 
     176             :     virtual css::lang::Locale SAL_CALL getLocale()
     177             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     178             : 
     179             :     void flushModifications() const;
     180             : 
     181             :     css::uno::Reference< css::uno::XComponentContext > context_;
     182             :     OUString locale_;
     183             :     bool default_;
     184             :     std::shared_ptr<osl::Mutex> lock_;
     185             : };
     186             : 
     187           0 : css::uno::Reference< css::uno::XInterface > Service::createInstance(
     188             :     OUString const & aServiceSpecifier)
     189             :     throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
     190             : {
     191             :     return createInstanceWithArguments(
     192           0 :         aServiceSpecifier, css::uno::Sequence< css::uno::Any >());
     193             : }
     194             : 
     195             : css::uno::Reference< css::uno::XInterface >
     196    26817660 : Service::createInstanceWithArguments(
     197             :     OUString const & ServiceSpecifier,
     198             :     css::uno::Sequence< css::uno::Any > const & Arguments)
     199             :     throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
     200             : {
     201    26817660 :     OUString nodepath;
     202    53635320 :     OUString locale;
     203    53661158 :     for (sal_Int32 i = 0; i < Arguments.getLength(); ++i) {
     204    26843723 :         css::beans::NamedValue v1;
     205    53687221 :         css::beans::PropertyValue v2;
     206    53687221 :         OUString name;
     207    53687221 :         css::uno::Any value;
     208    26843723 :         if (Arguments[i] >>= v1) {
     209       74353 :             name = v1.Name;
     210       74353 :             value = v1.Value;
     211    26769370 :         } else if (Arguments[i] >>= v2) {
     212    26769145 :             name = v2.Name;
     213    26769145 :             value = v2.Value;
     214         225 :         } else if (Arguments.getLength() == 1 && (Arguments[i] >>= nodepath)) {
     215             :             // For backwards compatibility, allow a single string argument that
     216             :             // denotes nodepath.
     217         225 :             if (nodepath.isEmpty()) {
     218           0 :                 badNodePath();
     219             :             }
     220         225 :             break;
     221             :         } else {
     222             :             throw css::uno::Exception(
     223             :                 ("com.sun.star.configuration.ConfigurationProvider expects"
     224             :                  " NamedValue or PropertyValue arguments"),
     225           0 :                 0);
     226             :         }
     227             :         // For backwards compatibility, allow "nodepath" and "Locale" in any
     228             :         // case:
     229    26843498 :         if (name.equalsIgnoreAsciiCase("nodepath")) {
     230    53634870 :             if (!nodepath.isEmpty() || !(value >>= nodepath) ||
     231    26817435 :                 nodepath.isEmpty())
     232             :             {
     233           0 :                 badNodePath();
     234             :             }
     235       26063 :         } else if (name.equalsIgnoreAsciiCase("locale")) {
     236        3736 :             if (!locale.isEmpty() || !(value >>= locale) ||
     237        1868 :                 locale.isEmpty())
     238             :             {
     239             :                 throw css::uno::Exception(
     240             :                     ("com.sun.star.configuration.ConfigurationProvider expects"
     241             :                      " at most one, non-empty, string Locale argument"),
     242           0 :                     0);
     243             :             }
     244             :         }
     245    26843498 :     }
     246    26817660 :     if (nodepath.isEmpty()) {
     247           0 :         badNodePath();
     248             :     }
     249             :     // For backwards compatibility, allow a nodepath that misses the leading
     250             :     // slash:
     251    26817660 :     if (nodepath[0] != '/') {
     252    26736837 :         nodepath = "/" + nodepath;
     253             :     }
     254    26817660 :     if (locale.isEmpty()) {
     255             :         //TODO: should the Access use the dynamically changing locale_ instead?
     256    26815792 :         locale = locale_;
     257    26815792 :         if (locale.isEmpty()) {
     258       59435 :             locale = "en-US";
     259             :         }
     260             :     }
     261             :     bool update;
     262    26817660 :     if (ServiceSpecifier == accessServiceName) {
     263       64215 :         update = false;
     264    26753445 :     } else if (ServiceSpecifier == updateAccessServiceName) {
     265    26753445 :         update = true;
     266             :     } else {
     267             :         throw css::uno::Exception(
     268             :             ("com.sun.star.configuration.ConfigurationProvider does not support"
     269           0 :              " service " + ServiceSpecifier),
     270           0 :             static_cast< cppu::OWeakObject * >(this));
     271             :     }
     272    53635320 :     osl::MutexGuard guard(*lock_);
     273    26817660 :     Components & components = Components::getSingleton(context_);
     274             :     rtl::Reference< RootAccess > root(
     275    53635320 :         new RootAccess(components, nodepath, locale, update));
     276    26817660 :     if (root->isValue()) {
     277             :         throw css::uno::Exception(
     278             :             ("com.sun.star.configuration.ConfigurationProvider: there is a leaf"
     279           0 :              " value at nodepath " + nodepath),
     280           0 :             static_cast< cppu::OWeakObject * >(this));
     281             :     }
     282    26817660 :     components.addRootAccess(root);
     283    53635320 :     return static_cast< cppu::OWeakObject * >(root.get());
     284             : }
     285             : 
     286           2 : css::uno::Sequence< OUString > Service::getAvailableServiceNames()
     287             :     throw (css::uno::RuntimeException, std::exception)
     288             : {
     289           2 :     css::uno::Sequence< OUString > names(2);
     290           2 :     names[0] = accessServiceName;
     291           2 :     names[1] = updateAccessServiceName;
     292           2 :     return names;
     293             : }
     294             : 
     295           2 : void Service::refresh() throw (css::uno::RuntimeException, std::exception) {
     296             :     //TODO
     297             :     cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
     298           2 :         cppu::UnoType< css::util::XRefreshListener >::get());
     299           2 :     if (cont != 0) {
     300           2 :         css::lang::EventObject ev(static_cast< cppu::OWeakObject * >(this));
     301           2 :         cont->notifyEach(&css::util::XRefreshListener::refreshed, ev);
     302             :     }
     303           2 : }
     304             : 
     305           1 : void Service::addRefreshListener(
     306             :     css::uno::Reference< css::util::XRefreshListener > const & l)
     307             :     throw (css::uno::RuntimeException, std::exception)
     308             : {
     309             :     rBHelper.addListener(
     310           1 :         cppu::UnoType< css::util::XRefreshListener >::get(), l);
     311           1 : }
     312             : 
     313           1 : void Service::removeRefreshListener(
     314             :     css::uno::Reference< css::util::XRefreshListener > const & l)
     315             :     throw (css::uno::RuntimeException, std::exception)
     316             : {
     317             :     rBHelper.removeListener(
     318           1 :         cppu::UnoType< css::util::XRefreshListener >::get(), l);
     319           1 : }
     320             : 
     321         348 : void Service::flush() throw (css::uno::RuntimeException, std::exception) {
     322         348 :     flushModifications();
     323             :     cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
     324         348 :         cppu::UnoType< css::util::XFlushListener >::get());
     325         348 :     if (cont != 0) {
     326           1 :         css::lang::EventObject ev(static_cast< cppu::OWeakObject * >(this));
     327           1 :         cont->notifyEach(&css::util::XFlushListener::flushed, ev);
     328             :     }
     329         348 : }
     330             : 
     331           2 : void Service::addFlushListener(
     332             :     css::uno::Reference< css::util::XFlushListener > const & l)
     333             :     throw (css::uno::RuntimeException, std::exception)
     334             : {
     335           2 :     rBHelper.addListener(cppu::UnoType< css::util::XFlushListener >::get(), l);
     336           2 : }
     337             : 
     338           1 : void Service::removeFlushListener(
     339             :     css::uno::Reference< css::util::XFlushListener > const & l)
     340             :     throw (css::uno::RuntimeException, std::exception)
     341             : {
     342             :     rBHelper.removeListener(
     343           1 :         cppu::UnoType< css::util::XFlushListener >::get(), l);
     344           1 : }
     345             : 
     346         118 : void Service::setLocale(css::lang::Locale const & eLocale)
     347             :     throw (css::uno::RuntimeException, std::exception)
     348             : {
     349         118 :     osl::MutexGuard guard(*lock_);
     350         118 :     locale_ = LanguageTag::convertToBcp47( eLocale, false);
     351         118 : }
     352             : 
     353        8876 : css::lang::Locale Service::getLocale() throw (css::uno::RuntimeException, std::exception) {
     354        8876 :     osl::MutexGuard guard(*lock_);
     355        8876 :     css::lang::Locale loc;
     356        8876 :     if (! locale_.isEmpty()) {
     357        1974 :         loc = LanguageTag::convertToLocale( locale_, false);
     358             :     }
     359        8876 :     return loc;
     360             : }
     361             : 
     362         597 : void Service::flushModifications() const {
     363             :     Components * components;
     364             :     {
     365         597 :         osl::MutexGuard guard(*lock_);
     366         597 :         components = &Components::getSingleton(context_);
     367             :     }
     368         597 :     components->flushModifications();
     369         597 : }
     370             : 
     371             : class Factory:
     372             :     public cppu::WeakImplHelper2<
     373             :         css::lang::XSingleComponentFactory, css::lang::XServiceInfo >
     374             : {
     375             : public:
     376           3 :     Factory() {}
     377             : 
     378             : private:
     379             :     Factory(const Factory&) SAL_DELETED_FUNCTION;
     380             :     Factory& operator=(const Factory&) SAL_DELETED_FUNCTION;
     381             : 
     382           6 :     virtual ~Factory() {}
     383             : 
     384             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     385             :     createInstanceWithContext(
     386             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     387             :         throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     388             : 
     389             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     390             :     createInstanceWithArgumentsAndContext(
     391             :         css::uno::Sequence< css::uno::Any > const & Arguments,
     392             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     393             :         throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     394             : 
     395           0 :     virtual OUString SAL_CALL getImplementationName()
     396             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     397           0 :     { return configuration_provider::getImplementationName(); }
     398             : 
     399           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
     400             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     401           0 :     { return cppu::supportsService(this, ServiceName); }
     402             : 
     403             :     virtual css::uno::Sequence< OUString > SAL_CALL
     404           0 :     getSupportedServiceNames() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     405           0 :     { return configuration_provider::getSupportedServiceNames(); }
     406             : };
     407             : 
     408           3 : css::uno::Reference< css::uno::XInterface > Factory::createInstanceWithContext(
     409             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     410             :     throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
     411             : {
     412             :     return createInstanceWithArgumentsAndContext(
     413           3 :         css::uno::Sequence< css::uno::Any >(), Context);
     414             : }
     415             : 
     416             : css::uno::Reference< css::uno::XInterface >
     417           4 : Factory::createInstanceWithArgumentsAndContext(
     418             :     css::uno::Sequence< css::uno::Any > const & Arguments,
     419             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     420             :     throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
     421             : {
     422           4 :     if (Arguments.getLength() == 0) {
     423           3 :         return css::configuration::theDefaultProvider::get(Context);
     424             :     } else {
     425           1 :         OUString locale;
     426           2 :         for (sal_Int32 i = 0; i < Arguments.getLength(); ++i) {
     427           1 :             css::beans::NamedValue v1;
     428           2 :             css::beans::PropertyValue v2;
     429           2 :             OUString name;
     430           2 :             css::uno::Any value;
     431           1 :             if (Arguments[i] >>= v1) {
     432           1 :                 name = v1.Name;
     433           1 :                 value = v1.Value;
     434           0 :             } else if (Arguments[i] >>= v2) {
     435           0 :                 name = v2.Name;
     436           0 :                 value = v2.Value;
     437             :             } else {
     438             :                 throw css::uno::Exception(
     439             :                     ("com.sun.star.configuration.ConfigurationProvider factory"
     440             :                      " expects NamedValue or PropertyValue arguments"),
     441           0 :                     0);
     442             :             }
     443             :             // For backwards compatibility, allow "Locale" and (ignored)
     444             :             // "EnableAsync" in any case:
     445           1 :             if (name.equalsIgnoreAsciiCase("locale")) {
     446           2 :                 if (!locale.isEmpty() || !(value >>= locale) ||
     447           1 :                     locale.isEmpty())
     448             :                 {
     449             :                     throw css::uno::Exception(
     450             :                         ("com.sun.star.configuration.ConfigurationProvider"
     451             :                          " factory expects at most one, non-empty, string"
     452             :                          " Locale argument"),
     453           0 :                         0);
     454             :                 }
     455           0 :             } else if (!name.equalsIgnoreAsciiCase("enableasync")) {
     456             :                 throw css::uno::Exception(
     457             :                     ("com.sun.star.configuration.ConfigurationProvider factory:"
     458           0 :                      " unknown argument " + name),
     459           0 :                     0);
     460             :             }
     461           1 :         }
     462           1 :         return static_cast< cppu::OWeakObject * >(new Service(Context, locale));
     463             :     }
     464             : }
     465             : 
     466             : }
     467             : 
     468         250 : css::uno::Reference< css::uno::XInterface > createDefault(
     469             :     css::uno::Reference< css::uno::XComponentContext > const & context)
     470             : {
     471         250 :     return static_cast< cppu::OWeakObject * >(new Service(context));
     472             : }
     473             : 
     474         686 : OUString getImplementationName() {
     475         686 :     return OUString("com.sun.star.comp.configuration.ConfigurationProvider");
     476             : }
     477             : 
     478           3 : css::uno::Sequence< OUString > getSupportedServiceNames() {
     479           3 :     OUString name("com.sun.star.configuration.ConfigurationProvider");
     480           3 :     return css::uno::Sequence< OUString >(&name, 1);
     481             : }
     482             : 
     483             : css::uno::Reference< css::lang::XSingleComponentFactory >
     484           3 : createFactory(
     485             :     SAL_UNUSED_PARAMETER cppu::ComponentFactoryFunc,
     486             :     SAL_UNUSED_PARAMETER OUString const &,
     487             :     SAL_UNUSED_PARAMETER css::uno::Sequence< OUString > const &,
     488             :     SAL_UNUSED_PARAMETER rtl_ModuleCount *)
     489             : {
     490           3 :     return new Factory;
     491             : }
     492             : 
     493             : } }
     494             : 
     495             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11