LCOV - code coverage report
Current view: top level - libreoffice/configmgr/source - configurationprovider.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 61 166 36.7 %
Date: 2012-12-27 Functions: 9 32 28.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             : #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 "comphelper/locale.hxx"
      47             : #include "cppu/unotype.hxx"
      48             : #include "cppuhelper/compbase5.hxx"
      49             : #include "cppuhelper/factory.hxx"
      50             : #include "cppuhelper/implbase2.hxx"
      51             : #include "cppuhelper/interfacecontainer.hxx"
      52             : #include "cppuhelper/weak.hxx"
      53             : #include "osl/mutex.hxx"
      54             : #include "sal/types.h"
      55             : #include "rtl/ref.hxx"
      56             : #include "rtl/unload.h"
      57             : #include "rtl/ustring.h"
      58             : #include "rtl/ustring.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          32 :     Service(
      93             :         css::uno::Reference< css::uno::XComponentContext > const context,
      94             :         OUString const & locale):
      95             :         ServiceBase(*static_cast< osl::Mutex * >(this)), context_(context),
      96          32 :         locale_(locale)
      97             :     {
      98          32 :         lock_ = lock();
      99             :         assert(context.is());
     100          32 :     }
     101             : 
     102             : private:
     103          38 :     virtual ~Service() {}
     104             : 
     105          32 :     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        8292 : 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        8292 :     OUString nodepath;
     180        8292 :     OUString locale;
     181       19502 :     for (sal_Int32 i = 0; i < Arguments.getLength(); ++i) {
     182       11210 :         css::beans::NamedValue v1;
     183       11210 :         css::beans::PropertyValue v2;
     184       11210 :         OUString name;
     185       11210 :         css::uno::Any value;
     186       11210 :         if (Arguments[i] >>= v1) {
     187        4642 :             name = v1.Name;
     188        4642 :             value = v1.Value;
     189        6568 :         } else if (Arguments[i] >>= v2) {
     190        6568 :             name = v2.Name;
     191        6568 :             value = v2.Value;
     192           0 :         } else if (Arguments.getLength() == 1 && (Arguments[i] >>= nodepath)) {
     193             :             // For backwards compatibility, allow a single string argument that
     194             :             // denotes nodepath.
     195           0 :             if (nodepath.isEmpty()) {
     196           0 :                 badNodePath();
     197             :             }
     198             :             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       11210 :         if (name.equalsIgnoreAsciiCaseAsciiL(
     208       11210 :                 RTL_CONSTASCII_STRINGPARAM("nodepath")))
     209             :         {
     210       16584 :             if (!nodepath.isEmpty() || !(value >>= nodepath) ||
     211        8292 :                 nodepath.isEmpty())
     212             :             {
     213           0 :                 badNodePath();
     214             :             }
     215        2918 :         } else if (name.equalsIgnoreAsciiCaseAsciiL(
     216        2918 :                        RTL_CONSTASCII_STRINGPARAM("locale")))
     217             :         {
     218         102 :             if (!locale.isEmpty() || !(value >>= locale) ||
     219          51 :                 locale.isEmpty())
     220             :             {
     221             :                 throw css::uno::Exception(
     222             :                     OUString("com.sun.star.configuration.ConfigurationProvider"
     223             :                             " expects at most one, non-empty, string Locale"
     224             :                             " argument"),
     225           0 :                     0);
     226             :             }
     227             :         }
     228       11210 :     }
     229        8292 :     if (nodepath.isEmpty()) {
     230           0 :         badNodePath();
     231             :     }
     232             :     // For backwards compatibility, allow a nodepath that misses the leading
     233             :     // slash:
     234        8292 :     if (nodepath[0] != '/') {
     235        2177 :         nodepath = OUString("/") + nodepath;
     236             :     }
     237        8292 :     if (locale.isEmpty()) {
     238             :         //TODO: should the Access use the dynamically changing locale_ instead?
     239        8241 :         locale = locale_;
     240        8241 :         if (locale.isEmpty()) {
     241        8241 :             locale = OUString("en-US");
     242             :         }
     243             :     }
     244             :     bool update;
     245        8292 :     if ( ServiceSpecifier == accessServiceName )
     246             :     {
     247        5766 :         update = false;
     248        2526 :     } else if ( ServiceSpecifier == updateAccessServiceName )
     249             :     {
     250        2526 :         update = true;
     251             :     } else {
     252             :         throw css::uno::Exception(
     253             :             (OUString("com.sun.star.configuration.ConfigurationProvider does not"
     254             :                     " support service ") +
     255           0 :              ServiceSpecifier),
     256           0 :             static_cast< cppu::OWeakObject * >(this));
     257             :     }
     258        8292 :     osl::MutexGuard guard(*lock_);
     259        8292 :     Components & components = Components::getSingleton(context_);
     260             :     rtl::Reference< RootAccess > root(
     261        8292 :         new RootAccess(components, nodepath, locale, update));
     262        8292 :     if (root->isValue()) {
     263             :         throw css::uno::Exception(
     264             :             (OUString("com.sun.star.configuration.ConfigurationProvider: there is"
     265             :                     " a leaf value at nodepath ") +
     266           0 :              nodepath),
     267           0 :             static_cast< cppu::OWeakObject * >(this));
     268             :     }
     269        8292 :     components.addRootAccess(root);
     270        8292 :     return static_cast< cppu::OWeakObject * >(root.get());
     271             : }
     272             : 
     273           0 : css::uno::Sequence< OUString > Service::getAvailableServiceNames()
     274             :     throw (css::uno::RuntimeException)
     275             : {
     276           0 :     css::uno::Sequence< OUString > names(2);
     277           0 :     names[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(accessServiceName));
     278           0 :     names[1] = OUString(RTL_CONSTASCII_USTRINGPARAM(updateAccessServiceName));
     279           0 :     return names;
     280             : }
     281             : 
     282           0 : void Service::refresh() throw (css::uno::RuntimeException) {
     283             :     //TODO
     284             :     cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
     285           0 :         cppu::UnoType< css::util::XRefreshListener >::get());
     286           0 :     if (cont != 0) {
     287           0 :         css::lang::EventObject ev(static_cast< cppu::OWeakObject * >(this));
     288           0 :         cont->notifyEach(&css::util::XRefreshListener::refreshed, ev);
     289             :     }
     290           0 : }
     291             : 
     292           0 : void Service::addRefreshListener(
     293             :     css::uno::Reference< css::util::XRefreshListener > const & l)
     294             :     throw (css::uno::RuntimeException)
     295             : {
     296             :     rBHelper.addListener(
     297           0 :         cppu::UnoType< css::util::XRefreshListener >::get(), l);
     298           0 : }
     299             : 
     300           0 : void Service::removeRefreshListener(
     301             :     css::uno::Reference< css::util::XRefreshListener > const & l)
     302             :     throw (css::uno::RuntimeException)
     303             : {
     304             :     rBHelper.removeListener(
     305           0 :         cppu::UnoType< css::util::XRefreshListener >::get(), l);
     306           0 : }
     307             : 
     308           0 : void Service::flush() throw (css::uno::RuntimeException) {
     309           0 :     flushModifications();
     310             :     cppu::OInterfaceContainerHelper * cont = rBHelper.getContainer(
     311           0 :         cppu::UnoType< css::util::XFlushListener >::get());
     312           0 :     if (cont != 0) {
     313           0 :         css::lang::EventObject ev(static_cast< cppu::OWeakObject * >(this));
     314           0 :         cont->notifyEach(&css::util::XFlushListener::flushed, ev);
     315             :     }
     316           0 : }
     317             : 
     318           0 : void Service::addFlushListener(
     319             :     css::uno::Reference< css::util::XFlushListener > const & l)
     320             :     throw (css::uno::RuntimeException)
     321             : {
     322           0 :     rBHelper.addListener(cppu::UnoType< css::util::XFlushListener >::get(), l);
     323           0 : }
     324             : 
     325           0 : void Service::removeFlushListener(
     326             :     css::uno::Reference< css::util::XFlushListener > const & l)
     327             :     throw (css::uno::RuntimeException)
     328             : {
     329             :     rBHelper.removeListener(
     330           0 :         cppu::UnoType< css::util::XFlushListener >::get(), l);
     331           0 : }
     332             : 
     333           0 : void Service::setLocale(css::lang::Locale const & eLocale)
     334             :     throw (css::uno::RuntimeException)
     335             : {
     336           0 :     osl::MutexGuard guard(*lock_);
     337             :     locale_ = comphelper::Locale(
     338           0 :         eLocale.Language, eLocale.Country, eLocale.Variant).toISO();
     339           0 : }
     340             : 
     341         793 : css::lang::Locale Service::getLocale() throw (css::uno::RuntimeException) {
     342         793 :     osl::MutexGuard guard(*lock_);
     343         793 :     css::lang::Locale loc;
     344         793 :     if ( locale_ == "*" ) {
     345           0 :         loc.Language = locale_;
     346         793 :     } else if (! locale_.isEmpty()) {
     347             :         try {
     348           0 :             comphelper::Locale l(locale_);
     349           0 :             loc.Language = l.getLanguage();
     350           0 :             loc.Country = l.getCountry();
     351           0 :             loc.Variant = l.getVariant();
     352           0 :         } catch (comphelper::Locale::MalFormedLocaleException & e) {
     353             :             throw css::uno::RuntimeException(
     354             :                 (OUString("MalformedLocaleException: ") +
     355           0 :                  e.Message),
     356           0 :                 static_cast< cppu::OWeakObject * >(this));
     357             :         }
     358             :     }
     359         793 :     return loc;
     360             : }
     361             : 
     362          32 : void Service::flushModifications() const {
     363             :     Components * components;
     364             :     {
     365          32 :         osl::MutexGuard guard(*lock_);
     366          32 :         components = &Components::getSingleton(context_);
     367             :     }
     368          32 :     components->flushModifications();
     369          32 : }
     370             : 
     371             : class Factory:
     372             :     public cppu::WeakImplHelper2<
     373             :         css::lang::XSingleComponentFactory, css::lang::XServiceInfo >,
     374             :     private boost::noncopyable
     375             : {
     376             : public:
     377           0 :     Factory() {}
     378             : 
     379             : private:
     380           0 :     virtual ~Factory() {}
     381             : 
     382             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     383             :     createInstanceWithContext(
     384             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     385             :         throw (css::uno::Exception, css::uno::RuntimeException);
     386             : 
     387             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL
     388             :     createInstanceWithArgumentsAndContext(
     389             :         css::uno::Sequence< css::uno::Any > const & Arguments,
     390             :         css::uno::Reference< css::uno::XComponentContext > const & Context)
     391             :         throw (css::uno::Exception, css::uno::RuntimeException);
     392             : 
     393           0 :     virtual OUString SAL_CALL getImplementationName()
     394             :         throw (css::uno::RuntimeException)
     395           0 :     { return configuration_provider::getImplementationName(); }
     396             : 
     397           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
     398             :         throw (css::uno::RuntimeException)
     399           0 :     { return ServiceName == getSupportedServiceNames()[0]; } //TODO
     400             : 
     401             :     virtual css::uno::Sequence< OUString > SAL_CALL
     402           0 :     getSupportedServiceNames() throw (css::uno::RuntimeException)
     403           0 :     { return configuration_provider::getSupportedServiceNames(); }
     404             : };
     405             : 
     406           0 : css::uno::Reference< css::uno::XInterface > Factory::createInstanceWithContext(
     407             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     408             :     throw (css::uno::Exception, css::uno::RuntimeException)
     409             : {
     410             :     return createInstanceWithArgumentsAndContext(
     411           0 :         css::uno::Sequence< css::uno::Any >(), Context);
     412             : }
     413             : 
     414             : css::uno::Reference< css::uno::XInterface >
     415           0 : Factory::createInstanceWithArgumentsAndContext(
     416             :     css::uno::Sequence< css::uno::Any > const & Arguments,
     417             :     css::uno::Reference< css::uno::XComponentContext > const & Context)
     418             :     throw (css::uno::Exception, css::uno::RuntimeException)
     419             : {
     420           0 :     if (Arguments.getLength() == 0) {
     421           0 :         return css::configuration::theDefaultProvider::get(Context);
     422             :     } else {
     423           0 :         OUString locale;
     424           0 :         for (sal_Int32 i = 0; i < Arguments.getLength(); ++i) {
     425           0 :             css::beans::NamedValue v1;
     426           0 :             css::beans::PropertyValue v2;
     427           0 :             OUString name;
     428           0 :             css::uno::Any value;
     429           0 :             if (Arguments[i] >>= v1) {
     430           0 :                 name = v1.Name;
     431           0 :                 value = v1.Value;
     432           0 :             } else if (Arguments[i] >>= v2) {
     433           0 :                 name = v2.Name;
     434           0 :                 value = v2.Value;
     435             :             } else {
     436             :                 throw css::uno::Exception(
     437             :                     OUString("com.sun.star.configuration.ConfigurationProvider"
     438             :                             " factory expects NamedValue or PropertyValue"
     439             :                             " arguments"),
     440           0 :                     0);
     441             :             }
     442             :             // For backwards compatibility, allow "Locale" and (ignored)
     443             :             // "EnableAsync" in any case:
     444           0 :             if (name.equalsIgnoreAsciiCaseAsciiL(
     445           0 :                     RTL_CONSTASCII_STRINGPARAM("locale")))
     446             :             {
     447           0 :                 if (!locale.isEmpty() || !(value >>= locale) ||
     448           0 :                     locale.isEmpty())
     449             :                 {
     450             :                     throw css::uno::Exception(
     451             :                         OUString("com.sun.star.configuration."
     452             :                                 "ConfigurationProvider factory expects at most"
     453             :                                 " one, non-empty, string Locale argument"),
     454           0 :                         0);
     455             :                 }
     456           0 :             } else if (!name.equalsIgnoreAsciiCaseAsciiL(
     457           0 :                            RTL_CONSTASCII_STRINGPARAM("enableasync")))
     458             :             {
     459             :                 throw css::uno::Exception(
     460             :                     OUString("com.sun.star.configuration.ConfigurationProvider"
     461           0 :                             " factory: unknown argument ") + name,
     462           0 :                     0);
     463             :             }
     464           0 :         }
     465           0 :         return static_cast< cppu::OWeakObject * >(new Service(Context, locale));
     466             :     }
     467             : }
     468             : 
     469             : }
     470             : 
     471          32 : css::uno::Reference< css::uno::XInterface > createDefault(
     472             :     css::uno::Reference< css::uno::XComponentContext > const & context)
     473             : {
     474             :     return static_cast< cppu::OWeakObject * >(
     475          32 :         new Service(context, OUString()));
     476             : }
     477             : 
     478          66 : OUString getImplementationName() {
     479          66 :     return OUString("com.sun.star.comp.configuration.ConfigurationProvider");
     480             : }
     481             : 
     482           0 : css::uno::Sequence< OUString > getSupportedServiceNames() {
     483           0 :     OUString name("com.sun.star.configuration.ConfigurationProvider");
     484           0 :     return css::uno::Sequence< OUString >(&name, 1);
     485             : }
     486             : 
     487             : css::uno::Reference< css::lang::XSingleComponentFactory >
     488           0 : createFactory(
     489             :     SAL_UNUSED_PARAMETER cppu::ComponentFactoryFunc,
     490             :     SAL_UNUSED_PARAMETER OUString const &,
     491             :     SAL_UNUSED_PARAMETER css::uno::Sequence< OUString > const &,
     492             :     SAL_UNUSED_PARAMETER rtl_ModuleCount *)
     493             :     SAL_THROW(())
     494             : {
     495           0 :     return new Factory;
     496             : }
     497             : 
     498             : } }
     499             : 
     500             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10