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

Generated by: LCOV version 1.10