LCOV - code coverage report
Current view: top level - libreoffice/framework/source/accelerators - presethandler.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 221 398 55.5 %
Date: 2012-12-17 Functions: 21 30 70.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 <accelerators/presethandler.hxx>
      21             : 
      22             : #include <classes/fwkresid.hxx>
      23             : 
      24             : #include "classes/resource.hrc"
      25             : #include <threadhelp/readguard.hxx>
      26             : #include <threadhelp/writeguard.hxx>
      27             : #include <services.h>
      28             : 
      29             : #include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
      30             : #include <com/sun/star/container/NoSuchElementException.hpp>
      31             : #include <com/sun/star/container/XNameAccess.hpp>
      32             : #include <com/sun/star/beans/XPropertySet.hpp>
      33             : #include <com/sun/star/embed/ElementModes.hpp>
      34             : #include <com/sun/star/embed/XTransactedObject.hpp>
      35             : #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
      36             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      37             : 
      38             : #include <vcl/svapp.hxx>
      39             : #include <cppuhelper/exc_hlp.hxx>
      40             : #include <rtl/ustrbuf.hxx>
      41             : 
      42             : 
      43             : #define SUBSTORAGE_GLOBAL       DECLARE_ASCII("global" )
      44             : #define SUBSTORAGE_MODULES      DECLARE_ASCII("modules")
      45             : 
      46             : #define BASEPATH_SHARE_LAYER    DECLARE_ASCII("UIConfig"  )
      47             : #define BASEPATH_USER_LAYER     DECLARE_ASCII("UserConfig")
      48             : 
      49             : #define RELPATH_SHARE_LAYER     DECLARE_ASCII("soffice.cfg")
      50             : #define RELPATH_USER_LAYER      DECLARE_ASCII("soffice.cfg")
      51             : 
      52             : #define FILE_EXTENSION          DECLARE_ASCII(".xml")
      53             : 
      54             : #define PATH_SEPERATOR          DECLARE_ASCII("/")
      55             : 
      56             : static const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE   = 1;
      57             : static const ::sal_Int32 ID_CORRUPT_UICONFIG_USER    = 2;
      58             : static const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL = 3;
      59             : 
      60             : 
      61             : namespace framework
      62             : {
      63             : 
      64             : //-----------------------------------------------
      65           2 : ::rtl::OUString PresetHandler::PRESET_DEFAULT()
      66             : {
      67           2 :     return ::rtl::OUString("default");
      68             : }
      69             : 
      70             : //-----------------------------------------------
      71           2 : ::rtl::OUString PresetHandler::TARGET_CURRENT()
      72             : {
      73           2 :     return ::rtl::OUString("current");
      74             : }
      75             : 
      76             : //-----------------------------------------------
      77          44 : ::rtl::OUString PresetHandler::RESOURCETYPE_MENUBAR()
      78             : {
      79          44 :     return ::rtl::OUString("menubar");
      80             : }
      81             : 
      82             : //-----------------------------------------------
      83          44 : ::rtl::OUString PresetHandler::RESOURCETYPE_TOOLBAR()
      84             : {
      85          44 :     return ::rtl::OUString("toolbar");
      86             : }
      87             : 
      88             : //-----------------------------------------------
      89           2 : ::rtl::OUString PresetHandler::RESOURCETYPE_ACCELERATOR()
      90             : {
      91           2 :     return ::rtl::OUString("accelerator");
      92             : }
      93             : 
      94             : //-----------------------------------------------
      95          44 : ::rtl::OUString PresetHandler::RESOURCETYPE_STATUSBAR()
      96             : {
      97          44 :     return ::rtl::OUString("statusbar");
      98             : }
      99             : 
     100             : //-----------------------------------------------
     101         134 : PresetHandler::PresetHandler(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
     102         134 :     : ThreadHelpBase     (&Application::GetSolarMutex()        )
     103             :     , m_xSMGR            (xSMGR                                )
     104             :     , m_aSharedStorages  (                                     )
     105             :     , m_lDocumentStorages(xSMGR                                )
     106         134 :     , m_aLocale          (::comphelper::Locale::X_NOTRANSLATE())
     107             : {
     108         134 : }
     109             : 
     110             : //-----------------------------------------------
     111           0 : PresetHandler::PresetHandler(const PresetHandler& rCopy)
     112           0 :     : ThreadHelpBase     (&Application::GetSolarMutex()        )
     113             : {
     114           0 :     m_xSMGR                 = rCopy.m_xSMGR;
     115           0 :     m_eConfigType           = rCopy.m_eConfigType;
     116           0 :     m_sResourceType         = rCopy.m_sResourceType;
     117           0 :     m_sModule               = rCopy.m_sModule;
     118             :     m_aSharedStorages       = rCopy.m_aSharedStorages;
     119           0 :     m_xWorkingStorageShare  = rCopy.m_xWorkingStorageShare;
     120           0 :     m_xWorkingStorageNoLang = rCopy.m_xWorkingStorageNoLang;
     121           0 :     m_xWorkingStorageUser   = rCopy.m_xWorkingStorageUser;
     122           0 :     m_lPresets              = rCopy.m_lPresets;
     123           0 :     m_lTargets              = rCopy.m_lTargets;
     124           0 :     m_aLocale               = rCopy.m_aLocale;
     125           0 :     m_lDocumentStorages     = rCopy.m_lDocumentStorages;
     126           0 :     m_sRelPathShare         = rCopy.m_sRelPathShare;
     127           0 :     m_sRelPathNoLang        = rCopy.m_sRelPathNoLang;
     128           0 :     m_sRelPathUser          = rCopy.m_sRelPathUser;
     129           0 : }
     130             : 
     131             : //-----------------------------------------------
     132         220 : PresetHandler::~PresetHandler()
     133             : {
     134          74 :     m_xWorkingStorageShare.clear();
     135          74 :     m_xWorkingStorageNoLang.clear();
     136          74 :     m_xWorkingStorageUser.clear();
     137             : 
     138             :     /* #i46497#
     139             :         Dont call forgetCachedStorages() here for shared storages.
     140             :         Because we opened different sub storages by using openPath().
     141             :         And every already open path was reused and referenced (means it's
     142             :         ref count was increased!)
     143             :         So now we have to release our ref counts to these shared storages
     144             :         only ... and not to free all used storages.
     145             :         Otherwise we will disconnect all other open configuration access
     146             :         objects which base on these storages.
     147             :      */
     148          74 :     m_aSharedStorages->m_lStoragesShare.closePath(m_sRelPathShare);
     149          74 :     m_aSharedStorages->m_lStoragesUser.closePath (m_sRelPathUser );
     150             : 
     151             :     /* On the other side closePath() is not needed for our special handled
     152             :        document storage. Because it's not shared with others ... so we can
     153             :        free it.
     154             :      */
     155          74 :     m_lDocumentStorages.forgetCachedStorages();
     156         146 : }
     157             : 
     158             : //-----------------------------------------------
     159           0 : void PresetHandler::forgetCachedStorages()
     160             : {
     161             :     // SAFE -> ----------------------------------
     162           0 :     WriteGuard aWriteLock(m_aLock);
     163             : 
     164           0 :     if (m_eConfigType == E_DOCUMENT)
     165             :     {
     166           0 :         m_xWorkingStorageShare.clear();
     167           0 :         m_xWorkingStorageNoLang.clear();
     168           0 :         m_xWorkingStorageUser.clear();
     169             :     }
     170             : 
     171           0 :     m_lDocumentStorages.forgetCachedStorages();
     172             : 
     173           0 :     aWriteLock.unlock();
     174             :     // <- SAFE ----------------------------------
     175           0 : }
     176             : 
     177             : namespace {
     178             : 
     179           0 : ::rtl::OUString lcl_getLocalizedMessage(::sal_Int32 nID)
     180             : {
     181           0 :     ::rtl::OUString sMessage("Unknown error.");
     182             : 
     183           0 :     switch(nID)
     184             :     {
     185             :         case ID_CORRUPT_UICONFIG_SHARE :
     186           0 :                 sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_SHARE )));
     187             : 
     188           0 :                 break;
     189             : 
     190             :         case ID_CORRUPT_UICONFIG_USER :
     191           0 :                 sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_USER )));
     192           0 :                 break;
     193             : 
     194             :         case ID_CORRUPT_UICONFIG_GENERAL :
     195           0 :                 sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_GENERAL )));
     196           0 :                 break;
     197             :     }
     198             : 
     199           0 :     return sMessage;
     200             : }
     201             : 
     202           0 : void lcl_throwCorruptedUIConfigurationException(
     203             :     css::uno::Any const & exception, sal_Int32 id)
     204             : {
     205           0 :     css::uno::Exception e;
     206           0 :     bool ok = (exception >>= e);
     207             :     OSL_ASSERT(ok); (void) ok; // avoid warnings
     208             :     throw css::configuration::CorruptedUIConfigurationException(
     209             :         lcl_getLocalizedMessage(id),
     210             :         css::uno::Reference< css::uno::XInterface >(),
     211             :         (exception.getValueTypeName() +
     212           0 :          rtl::OUString(": \"") + e.Message +
     213           0 :          rtl::OUString("\"")));
     214             : }
     215             : 
     216             : }
     217             : 
     218         132 : css::uno::Reference< css::embed::XStorage > PresetHandler::getOrCreateRootStorageShare()
     219             : {
     220         132 :     css::uno::Reference< css::embed::XStorage > xRoot = m_aSharedStorages->m_lStoragesShare.getRootStorage();
     221         132 :     if (xRoot.is())
     222          88 :         return xRoot;
     223             : 
     224             :     // SAFE -> ----------------------------------
     225          44 :     ReadGuard aReadLock(m_aLock);
     226          44 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     227          44 :     aReadLock.unlock();
     228             :     // <- SAFE ----------------------------------
     229             : 
     230             :     css::uno::Reference< css::beans::XPropertySet > xPathSettings(
     231          44 :         xSMGR->createInstance(SERVICENAME_PATHSETTINGS),
     232          44 :         css::uno::UNO_QUERY_THROW);
     233             : 
     234          44 :     ::rtl::OUString sShareLayer;
     235          44 :     xPathSettings->getPropertyValue(BASEPATH_SHARE_LAYER) >>= sShareLayer;
     236             : 
     237             :     // "UIConfig" is a "multi path" ... use first part only here!
     238          44 :     sal_Int32 nPos = sShareLayer.indexOf(';');
     239          44 :     if (nPos > 0)
     240          42 :         sShareLayer = sShareLayer.copy(0, nPos);
     241             : 
     242             :     // Note: May be an user uses URLs without a final slash! Check it ...
     243          44 :     nPos = sShareLayer.lastIndexOf('/');
     244          44 :     if (nPos != sShareLayer.getLength()-1)
     245          44 :         sShareLayer += ::rtl::OUString("/");
     246             : 
     247          44 :     sShareLayer += RELPATH_SHARE_LAYER; // folder
     248             :     /*
     249             :     // TODO remove me!
     250             :     // Attention: This is temp. workaround ... We create a temp. storage file
     251             :     // based of a sytem directory. This must be used so, till the storage implementation
     252             :     // can work on directories too.
     253             :     */
     254          44 :     css::uno::Sequence< css::uno::Any > lArgs(2);
     255          44 :     lArgs[0] <<= sShareLayer;
     256          44 :     lArgs[1] <<= css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE;
     257             : 
     258          44 :     css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory = css::embed::FileSystemStorageFactory::create( comphelper::getComponentContext(xSMGR) );
     259          44 :     css::uno::Reference< css::embed::XStorage >             xStorage;
     260             : 
     261             :     try
     262             :     {
     263          44 :         xStorage = css::uno::Reference< css::embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
     264             :     }
     265           0 :     catch(const css::uno::Exception&)
     266             :     {
     267           0 :         css::uno::Any ex(cppu::getCaughtException());
     268             :         lcl_throwCorruptedUIConfigurationException(
     269           0 :             ex, ID_CORRUPT_UICONFIG_SHARE);
     270             :     }
     271             : 
     272          44 :     m_aSharedStorages->m_lStoragesShare.setRootStorage(xStorage);
     273             : 
     274          44 :     return xStorage;
     275             : }
     276             : 
     277             : //-----------------------------------------------
     278         176 : css::uno::Reference< css::embed::XStorage > PresetHandler::getOrCreateRootStorageUser()
     279             : {
     280         176 :     css::uno::Reference< css::embed::XStorage > xRoot = m_aSharedStorages->m_lStoragesUser.getRootStorage();
     281         176 :     if (xRoot.is())
     282         132 :         return xRoot;
     283             : 
     284             :     // SAFE -> ----------------------------------
     285          44 :     ReadGuard aReadLock(m_aLock);
     286          44 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
     287          44 :     aReadLock.unlock();
     288             :     // <- SAFE ----------------------------------
     289             : 
     290             :     css::uno::Reference< css::beans::XPropertySet > xPathSettings(
     291          44 :         xSMGR->createInstance(SERVICENAME_PATHSETTINGS),
     292          44 :         css::uno::UNO_QUERY_THROW);
     293             : 
     294          44 :     ::rtl::OUString sUserLayer;
     295          44 :     xPathSettings->getPropertyValue(BASEPATH_USER_LAYER) >>= sUserLayer ;
     296             : 
     297             :     // Note: May be an user uses URLs without a final slash! Check it ...
     298          44 :     sal_Int32 nPos = sUserLayer.lastIndexOf('/');
     299          44 :     if (nPos != sUserLayer.getLength()-1)
     300          44 :         sUserLayer += ::rtl::OUString("/");
     301             : 
     302          44 :     sUserLayer  += RELPATH_USER_LAYER; // storage file
     303             : 
     304          44 :     css::uno::Sequence< css::uno::Any > lArgs(2);
     305          44 :     lArgs[0] <<= sUserLayer;
     306          44 :     lArgs[1] <<= css::embed::ElementModes::READWRITE;
     307             : 
     308          44 :     css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory = css::embed::FileSystemStorageFactory::create( comphelper::getComponentContext(xSMGR) );
     309          44 :     css::uno::Reference< css::embed::XStorage >             xStorage;
     310             : 
     311             :     try
     312             :     {
     313          44 :         xStorage = css::uno::Reference< css::embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
     314             :     }
     315           0 :     catch(const css::uno::Exception&)
     316             :     {
     317           0 :         css::uno::Any ex(cppu::getCaughtException());
     318             :         lcl_throwCorruptedUIConfigurationException(
     319           0 :             ex, ID_CORRUPT_UICONFIG_USER);
     320             :     }
     321             : 
     322          44 :     m_aSharedStorages->m_lStoragesUser.setRootStorage(xStorage);
     323             : 
     324          44 :     return xStorage;
     325             : }
     326             : 
     327             : //-----------------------------------------------
     328          44 : css::uno::Reference< css::embed::XStorage > PresetHandler::getWorkingStorageShare()
     329             : {
     330             :     // SAFE -> ----------------------------------
     331          44 :     ReadGuard aReadLock(m_aLock);
     332          44 :     return m_xWorkingStorageShare;
     333             :     // <- SAFE ----------------------------------
     334             : }
     335             : 
     336             : //-----------------------------------------------
     337         176 : css::uno::Reference< css::embed::XStorage > PresetHandler::getWorkingStorageUser()
     338             : {
     339             :     // SAFE -> ----------------------------------
     340         176 :     ReadGuard aReadLock(m_aLock);
     341         176 :     return m_xWorkingStorageUser;
     342             :     // <- SAFE ----------------------------------
     343             : }
     344             : 
     345             : //-----------------------------------------------
     346          44 : css::uno::Reference< css::embed::XStorage > PresetHandler::getParentStorageShare(const css::uno::Reference< css::embed::XStorage >& /*xChild*/)
     347             : {
     348             :     // SAFE -> ----------------------------------
     349          44 :     ReadGuard aReadLock(m_aLock);
     350          44 :     css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageShare;
     351          44 :     aReadLock.unlock();
     352             :     // <- SAFE ----------------------------------
     353             : 
     354          44 :     return m_aSharedStorages->m_lStoragesShare.getParentStorage(xWorking);
     355             : }
     356             : 
     357             : //-----------------------------------------------
     358          44 : css::uno::Reference< css::embed::XStorage > PresetHandler::getParentStorageUser(const css::uno::Reference< css::embed::XStorage >& /*xChild*/)
     359             : {
     360             :     // SAFE -> ----------------------------------
     361          44 :     ReadGuard aReadLock(m_aLock);
     362          44 :     css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageUser;
     363          44 :     aReadLock.unlock();
     364             :     // <- SAFE ----------------------------------
     365             : 
     366          44 :     return m_aSharedStorages->m_lStoragesUser.getParentStorage(xWorking);
     367             : }
     368             : 
     369             : //-----------------------------------------------
     370         134 : void PresetHandler::connectToResource(      PresetHandler::EConfigType                   eConfigType  ,
     371             :                                       const ::rtl::OUString&                             sResource    ,
     372             :                                       const ::rtl::OUString&                             sModule      ,
     373             :                                       const css::uno::Reference< css::embed::XStorage >& xDocumentRoot,
     374             :                                       const ::comphelper::Locale&                        aLocale      )
     375             : {
     376             :     // TODO free all current open storages!
     377             : 
     378             :     // SAFE -> ----------------------------------
     379         134 :     WriteGuard aWriteLock(m_aLock);
     380             : 
     381         134 :     m_eConfigType   = eConfigType  ;
     382         134 :     m_sResourceType = sResource    ;
     383         134 :     m_sModule       = sModule      ;
     384         134 :     m_aLocale       = aLocale      ;
     385             : 
     386         134 :     aWriteLock.unlock();
     387             :     // <- SAFE ----------------------------------
     388             : 
     389         134 :     css::uno::Reference< css::embed::XStorage > xShare;
     390         134 :     css::uno::Reference< css::embed::XStorage > xNoLang;
     391         134 :     css::uno::Reference< css::embed::XStorage > xUser;
     392             : 
     393             :     // special case for documents
     394             :     // use outside root storage, if we run in E_DOCUMENT mode!
     395         134 :     if (eConfigType == E_DOCUMENT)
     396             :     {
     397           2 :         if (!xDocumentRoot.is())
     398             :             throw css::uno::RuntimeException(
     399             :                     ::rtl::OUString("There is valid root storage, where the UI configuration can work on."),
     400           0 :                     css::uno::Reference< css::uno::XInterface >());
     401           2 :         m_lDocumentStorages.setRootStorage(xDocumentRoot);
     402           2 :         xShare = xDocumentRoot;
     403           2 :         xUser  = xDocumentRoot;
     404             :     }
     405             :     else
     406             :     {
     407         132 :         xShare = getOrCreateRootStorageShare();
     408         132 :         xUser  = getOrCreateRootStorageUser();
     409             :     }
     410             : 
     411             :     // #...#
     412             :     try
     413             :     {
     414             : 
     415             :     // a) inside share layer we should not create any new structures ... We jave to use
     416             :     //    existing ones only!
     417             :     // b) inside user layer we can (SOFT mode!) but sometimes we shouldnt (HARD mode!)
     418             :     //    create new empty structures. We should preferr using of any existing structure.
     419         134 :     sal_Int32 eShareMode = (css::embed::ElementModes::READ      | css::embed::ElementModes::NOCREATE);
     420         134 :     sal_Int32 eUserMode  = (css::embed::ElementModes::READWRITE                                     );
     421             : 
     422         134 :     ::rtl::OUStringBuffer sRelPathBuf(1024);
     423         134 :     ::rtl::OUString       sRelPathShare;
     424         134 :     ::rtl::OUString       sRelPathNoLang;
     425         134 :     ::rtl::OUString       sRelPathUser;
     426         134 :     switch(eConfigType)
     427             :     {
     428             :         case E_GLOBAL :
     429             :         {
     430           0 :             sRelPathBuf.append(SUBSTORAGE_GLOBAL);
     431           0 :             sRelPathBuf.append(PATH_SEPERATOR   );
     432           0 :             sRelPathBuf.append(sResource        );
     433           0 :             sRelPathShare = sRelPathBuf.makeStringAndClear();
     434           0 :             sRelPathUser  = sRelPathShare;
     435             : 
     436           0 :             xShare = impl_openPathIgnoringErrors(sRelPathShare, eShareMode, sal_True );
     437           0 :             xUser  = impl_openPathIgnoringErrors(sRelPathUser , eUserMode , sal_False);
     438             :         }
     439           0 :         break;
     440             : 
     441             :         case E_MODULES :
     442             :         {
     443         132 :             sRelPathBuf.append(SUBSTORAGE_MODULES);
     444         132 :             sRelPathBuf.append(PATH_SEPERATOR    );
     445         132 :             sRelPathBuf.append(sModule           );
     446         132 :             sRelPathBuf.append(PATH_SEPERATOR    );
     447         132 :             sRelPathBuf.append(sResource         );
     448         132 :             sRelPathShare = sRelPathBuf.makeStringAndClear();
     449         132 :             sRelPathUser  = sRelPathShare;
     450             : 
     451         132 :             xShare = impl_openPathIgnoringErrors(sRelPathShare, eShareMode, sal_True );
     452         132 :             xUser  = impl_openPathIgnoringErrors(sRelPathUser , eUserMode , sal_False);
     453             :         }
     454         132 :         break;
     455             : 
     456             :         case E_DOCUMENT :
     457             :         {
     458             :             // A document does not have a share layer in real.
     459             :             // It has one layer only, and this one should be opened READ_WRITE.
     460             :             // So we open the user layer here only and set the share layer equals to it .-)
     461             : 
     462           2 :             sRelPathBuf.append(sResource);
     463           2 :             sRelPathUser  = sRelPathBuf.makeStringAndClear();
     464           2 :             sRelPathShare = sRelPathUser;
     465             : 
     466             :             try
     467             :             {
     468           2 :                 xUser  = m_lDocumentStorages.openPath(sRelPathUser , eUserMode );
     469           2 :                 xShare = xUser;
     470             :             }
     471           0 :             catch(const css::uno::RuntimeException&)
     472           0 :                 { throw; }
     473           0 :             catch(const css::uno::Exception&)
     474           0 :                 { xShare.clear(); xUser.clear(); }
     475             :         }
     476           2 :         break;
     477             :     }
     478             : 
     479             :     // Non-localized global share
     480         134 :     xNoLang = xShare;
     481         134 :     sRelPathNoLang = sRelPathShare;
     482             : 
     483         536 :     if (
     484         402 :         (aLocale     != ::comphelper::Locale::X_NOTRANSLATE()) && // localized level?
     485             :         (eConfigType != E_DOCUMENT                           )    // no localization in document mode!
     486             :        )
     487             :     {
     488             :         // First try to find the right localized set inside share layer.
     489             :         // Fallbacks are allowed there.
     490           0 :         ::comphelper::Locale aShareLocale       = aLocale      ;
     491           0 :         ::rtl::OUString      sLocalizedSharePath(sRelPathShare);
     492           0 :         sal_Bool             bAllowFallbacks    = sal_True     ;
     493           0 :         xShare = impl_openLocalizedPathIgnoringErrors(sLocalizedSharePath, eShareMode, sal_True , aShareLocale, bAllowFallbacks);
     494             : 
     495             :         // The try to locate the right sub dir inside user layer ... without using fallbacks!
     496             :         // Normaly the corresponding sub dir should be created matching the specified locale.
     497             :         // Because we allow creation of storages inside user layer by default.
     498           0 :         ::comphelper::Locale aUserLocale        = aLocale    ;
     499           0 :         ::rtl::OUString      sLocalizedUserPath(sRelPathUser);
     500           0 :                              bAllowFallbacks    = sal_False  ;
     501           0 :         xUser = impl_openLocalizedPathIgnoringErrors(sLocalizedUserPath, eUserMode , sal_False, aUserLocale, bAllowFallbacks);
     502             : 
     503           0 :         sRelPathShare = sLocalizedSharePath;
     504           0 :         sRelPathUser  = sLocalizedUserPath ;
     505             :     }
     506             : 
     507             :     // read content of level 3 (presets, targets)
     508         134 :           css::uno::Reference< css::container::XNameAccess > xAccess ;
     509         134 :           css::uno::Sequence< ::rtl::OUString >              lNames  ;
     510             :     const ::rtl::OUString*                                   pNames  ;
     511             :           sal_Int32                                          c       ;
     512             :           sal_Int32                                          i       ;
     513         134 :           OUStringList                                       lPresets;
     514         134 :           OUStringList                                       lTargets;
     515             : 
     516             :     // read preset names of share layer
     517         134 :     xAccess = css::uno::Reference< css::container::XNameAccess >(xShare, css::uno::UNO_QUERY);
     518         134 :     if (xAccess.is())
     519             :     {
     520         134 :         lNames  = xAccess->getElementNames();
     521         134 :         pNames  = lNames.getConstArray();
     522         134 :         c       = lNames.getLength();
     523             : 
     524         215 :         for (i=0; i<c; ++i)
     525             :         {
     526          81 :             ::rtl::OUString sTemp = pNames[i];
     527          81 :             sal_Int32       nPos  = sTemp.indexOf(FILE_EXTENSION);
     528          81 :             if (nPos > -1)
     529          81 :                 sTemp = sTemp.copy(0,nPos);
     530          81 :             lPresets.push_back(sTemp);
     531          81 :         }
     532             :     }
     533             : 
     534             :     // read preset names of user layer
     535         134 :     xAccess = css::uno::Reference< css::container::XNameAccess >(xUser, css::uno::UNO_QUERY);
     536         134 :     if (xAccess.is())
     537             :     {
     538         134 :         lNames  = xAccess->getElementNames();
     539         134 :         pNames  = lNames.getConstArray();
     540         134 :         c       = lNames.getLength();
     541             : 
     542         135 :         for (i=0; i<c; ++i)
     543             :         {
     544           1 :             ::rtl::OUString sTemp = pNames[i];
     545           1 :             sal_Int32       nPos  = sTemp.indexOf(FILE_EXTENSION);
     546           1 :             if (nPos > -1)
     547           1 :                 sTemp = sTemp.copy(0,nPos);
     548           1 :             lTargets.push_back(sTemp);
     549           1 :         }
     550             :     }
     551             : 
     552             :     // SAFE -> ----------------------------------
     553         134 :     aWriteLock.lock();
     554             : 
     555         134 :     m_xWorkingStorageShare = xShare  ;
     556         134 :     m_xWorkingStorageNoLang= xNoLang;
     557         134 :     m_xWorkingStorageUser  = xUser   ;
     558         134 :     m_lPresets             = lPresets;
     559         134 :     m_lTargets             = lTargets;
     560         134 :     m_sRelPathShare        = sRelPathShare;
     561         134 :     m_sRelPathNoLang       = sRelPathNoLang;
     562         134 :     m_sRelPathUser         = sRelPathUser;
     563             : 
     564         134 :     aWriteLock.unlock();
     565             :     // <- SAFE ----------------------------------
     566             : 
     567             :     }
     568           0 :     catch(const css::uno::Exception&)
     569             :     {
     570           0 :         css::uno::Any ex(cppu::getCaughtException());
     571             :         lcl_throwCorruptedUIConfigurationException(
     572           0 :             ex, ID_CORRUPT_UICONFIG_GENERAL);
     573         134 :     }
     574         134 : }
     575             : 
     576             : //-----------------------------------------------
     577           0 : void PresetHandler::copyPresetToTarget(const ::rtl::OUString& sPreset,
     578             :                                        const ::rtl::OUString& sTarget)
     579             : {
     580             :     // dont check our preset list, if element exists
     581             :     // We try to open it and forward all errors to the user!
     582             : 
     583             :     // SAFE -> ----------------------------------
     584           0 :     ReadGuard aReadLock(m_aLock);
     585           0 :     css::uno::Reference< css::embed::XStorage > xWorkingShare = m_xWorkingStorageShare;
     586           0 :     css::uno::Reference< css::embed::XStorage > xWorkingNoLang= m_xWorkingStorageNoLang;
     587           0 :     css::uno::Reference< css::embed::XStorage > xWorkingUser  = m_xWorkingStorageUser ;
     588           0 :     aReadLock.unlock();
     589             :     // <- SAFE ----------------------------------
     590             : 
     591             :     // e.g. module without any config data ?!
     592           0 :     if (
     593           0 :         (!xWorkingShare.is()) ||
     594           0 :         (!xWorkingUser.is() )
     595             :        )
     596             :     {
     597           0 :        return;
     598             :     }
     599             : 
     600           0 :     ::rtl::OUString sPresetFile(sPreset);
     601           0 :     sPresetFile += FILE_EXTENSION;
     602             : 
     603           0 :     ::rtl::OUString sTargetFile(sTarget);
     604           0 :     sTargetFile += FILE_EXTENSION;
     605             : 
     606             :     // remove existing elements before you try to copy the preset to that location ...
     607             :     // Otherwise w will get an ElementExistException inside copyElementTo()!
     608           0 :     css::uno::Reference< css::container::XNameAccess > xCheckingUser(xWorkingUser, css::uno::UNO_QUERY_THROW);
     609           0 :     if (xCheckingUser->hasByName(sTargetFile))
     610           0 :         xWorkingUser->removeElement(sTargetFile);
     611             : 
     612           0 :     xWorkingShare->copyElementTo(sPresetFile, xWorkingUser, sTargetFile);
     613             : 
     614             :     // If our storages work in transacted mode, we have
     615             :     // to commit all changes from bottom to top!
     616           0 :     commitUserChanges();
     617             : }
     618             : 
     619             : //-----------------------------------------------
     620           2 : css::uno::Reference< css::io::XStream > PresetHandler::openPreset(const ::rtl::OUString& sPreset,
     621             :                                                                   sal_Bool bUseNoLangGlobal)
     622             : {
     623             :     // SAFE -> ----------------------------------
     624           2 :     ReadGuard aReadLock(m_aLock);
     625           2 :     css::uno::Reference< css::embed::XStorage > xFolder = bUseNoLangGlobal? m_xWorkingStorageNoLang: m_xWorkingStorageShare;
     626           2 :     aReadLock.unlock();
     627             :     // <- SAFE ----------------------------------
     628             : 
     629             :     // e.g. module without any config data ?!
     630           2 :     if (!xFolder.is())
     631           0 :        return css::uno::Reference< css::io::XStream >();
     632             : 
     633           2 :     ::rtl::OUString sFile(sPreset);
     634           2 :     sFile += FILE_EXTENSION;
     635             : 
     636             :     // inform user about errors (use original exceptions!)
     637           2 :     css::uno::Reference< css::io::XStream > xStream = xFolder->openStreamElement(sFile, css::embed::ElementModes::READ);
     638           0 :     return xStream;
     639             : }
     640             : 
     641             : //-----------------------------------------------
     642           2 : css::uno::Reference< css::io::XStream > PresetHandler::openTarget(const ::rtl::OUString& sTarget         ,
     643             :                                                                         sal_Bool         bCreateIfMissing)
     644             : {
     645             :     // SAFE -> ----------------------------------
     646           2 :     ReadGuard aReadLock(m_aLock);
     647           2 :     css::uno::Reference< css::embed::XStorage > xFolder = m_xWorkingStorageUser;
     648           2 :     aReadLock.unlock();
     649             :     // <- SAFE ----------------------------------
     650             : 
     651             :     // e.g. module without any config data ?!
     652           2 :     if (!xFolder.is())
     653           0 :        return css::uno::Reference< css::io::XStream >();
     654             : 
     655           2 :     ::rtl::OUString sFile(sTarget);
     656           2 :     sFile += FILE_EXTENSION;
     657             : 
     658           2 :     sal_Int32 nOpenMode = css::embed::ElementModes::READWRITE;
     659           2 :     if (!bCreateIfMissing)
     660           0 :         nOpenMode |= css::embed::ElementModes::NOCREATE;
     661             : 
     662             :     // try it in read/write mode first and ignore errors.
     663           2 :     css::uno::Reference< css::io::XStream > xStream;
     664             :     try
     665             :     {
     666           2 :         xStream = xFolder->openStreamElement(sFile, nOpenMode);
     667           2 :         return xStream;
     668             :     }
     669           0 :     catch(const css::uno::RuntimeException&)
     670           0 :         { throw; }
     671           0 :     catch(const css::uno::Exception&)
     672           0 :         { xStream.clear(); }
     673             : 
     674             :     // try it readonly if it failed before.
     675             :     // inform user about errors (use original exceptions!)
     676           0 :     nOpenMode &= ~css::embed::ElementModes::WRITE;
     677           0 :     xStream    = xFolder->openStreamElement(sFile, nOpenMode);
     678             : 
     679           0 :     return xStream;
     680             : }
     681             : 
     682             : //-----------------------------------------------
     683           0 : void PresetHandler::commitUserChanges()
     684             : {
     685             :     // SAFE -> ----------------------------------
     686           0 :     ReadGuard aReadLock(m_aLock);
     687           0 :     css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageUser;
     688           0 :     EConfigType                                 eCfgType = m_eConfigType;
     689           0 :     aReadLock.unlock();
     690             :     // <- SAFE ----------------------------------
     691             : 
     692             :     // e.g. module without any config data ?!
     693           0 :     if (!xWorking.is())
     694           0 :        return;
     695             : 
     696           0 :     ::rtl::OUString sPath;
     697             : 
     698           0 :     switch(eCfgType)
     699             :     {
     700             :         case E_GLOBAL :
     701             :         case E_MODULES :
     702             :         {
     703           0 :             sPath = m_aSharedStorages->m_lStoragesUser.getPathOfStorage(xWorking);
     704           0 :             m_aSharedStorages->m_lStoragesUser.commitPath(sPath);
     705           0 :             m_aSharedStorages->m_lStoragesUser.notifyPath(sPath);
     706             :         }
     707           0 :         break;
     708             : 
     709             :         case E_DOCUMENT :
     710             :         {
     711           0 :             sPath = m_lDocumentStorages.getPathOfStorage(xWorking);
     712           0 :             m_lDocumentStorages.commitPath(sPath);
     713           0 :             m_lDocumentStorages.notifyPath(sPath);
     714             :         }
     715           0 :         break;
     716           0 :     }
     717             : }
     718             : 
     719             : //-----------------------------------------------
     720           2 : void PresetHandler::addStorageListener(IStorageListener* pListener)
     721             : {
     722             :     // SAFE -> ----------------------------------
     723           2 :     ReadGuard aReadLock(m_aLock);
     724           2 :     ::rtl::OUString sRelPath = m_sRelPathUser; // use user path ... because we dont work directly on the share layer!
     725           2 :     EConfigType     eCfgType = m_eConfigType;
     726           2 :     aReadLock.unlock();
     727             :     // <- SAFE ----------------------------------
     728             : 
     729           2 :     if (sRelPath.isEmpty())
     730           2 :         return;
     731             : 
     732           2 :     switch(eCfgType)
     733             :     {
     734             :         case E_GLOBAL :
     735             :         case E_MODULES :
     736             :         {
     737           0 :             m_aSharedStorages->m_lStoragesUser.addStorageListener(pListener, sRelPath);
     738             :         }
     739           0 :         break;
     740             : 
     741             :         case E_DOCUMENT :
     742             :         {
     743           2 :             m_lDocumentStorages.addStorageListener(pListener, sRelPath);
     744             :         }
     745           2 :         break;
     746           2 :     }
     747             : }
     748             : 
     749             : //-----------------------------------------------
     750           2 : void PresetHandler::removeStorageListener(IStorageListener* pListener)
     751             : {
     752             :     // SAFE -> ----------------------------------
     753           2 :     ReadGuard aReadLock(m_aLock);
     754           2 :     ::rtl::OUString sRelPath = m_sRelPathUser; // use user path ... because we dont work directly on the share layer!
     755           2 :     EConfigType     eCfgType = m_eConfigType;
     756           2 :     aReadLock.unlock();
     757             :     // <- SAFE ----------------------------------
     758             : 
     759           2 :     if (sRelPath.isEmpty())
     760           2 :         return;
     761             : 
     762           2 :     switch(eCfgType)
     763             :     {
     764             :         case E_GLOBAL :
     765             :         case E_MODULES :
     766             :         {
     767           0 :             m_aSharedStorages->m_lStoragesUser.removeStorageListener(pListener, sRelPath);
     768             :         }
     769           0 :         break;
     770             : 
     771             :         case E_DOCUMENT :
     772             :         {
     773           2 :             m_lDocumentStorages.removeStorageListener(pListener, sRelPath);
     774             :         }
     775           2 :         break;
     776           2 :     }
     777             : }
     778             : 
     779             : //-----------------------------------------------
     780         264 : css::uno::Reference< css::embed::XStorage > PresetHandler::impl_openPathIgnoringErrors(const ::rtl::OUString& sPath ,
     781             :                                                                                              sal_Int32        eMode ,
     782             :                                                                                              sal_Bool         bShare)
     783             : {
     784         264 :     css::uno::Reference< css::embed::XStorage > xPath;
     785             :     try
     786             :     {
     787         264 :         if (bShare)
     788         132 :             xPath = m_aSharedStorages->m_lStoragesShare.openPath(sPath, eMode);
     789             :         else
     790         132 :             xPath = m_aSharedStorages->m_lStoragesUser.openPath(sPath, eMode);
     791             :     }
     792           0 :     catch(const css::uno::RuntimeException&)
     793           0 :         { throw; }
     794           0 :     catch(const css::uno::Exception&)
     795           0 :         { xPath.clear(); }
     796         264 :     return xPath;
     797             : }
     798             : 
     799             : //-----------------------------------------------
     800           0 : ::std::vector< ::rtl::OUString >::const_iterator PresetHandler::impl_findMatchingLocalizedValue(const ::std::vector< ::rtl::OUString >& lLocalizedValues,
     801             :                                                                                                       ::comphelper::Locale&             aLocale         ,
     802             :                                                                                                       sal_Bool                          bAllowFallbacks )
     803             : {
     804           0 :     ::std::vector< ::rtl::OUString >::const_iterator pFound = lLocalizedValues.end();
     805           0 :     if (bAllowFallbacks)
     806             :     {
     807           0 :         pFound = ::comphelper::Locale::getFallback(lLocalizedValues, aLocale.toISO());
     808             :     }
     809             :     else
     810             :     {
     811           0 :         for (  pFound  = lLocalizedValues.begin();
     812           0 :                pFound != lLocalizedValues.end()  ;
     813             :              ++pFound                            )
     814             :         {
     815           0 :             const ::rtl::OUString&     sCheckISO   = *pFound;
     816           0 :                   ::comphelper::Locale aCheckLocale(sCheckISO);
     817           0 :             if (aCheckLocale.equals(aLocale))
     818             :                 break;
     819           0 :         }
     820             :     }
     821             : 
     822             :     // if we found a valid locale ... take it over to our in/out parameter aLocale
     823           0 :     if (pFound != lLocalizedValues.end())
     824             :     {
     825           0 :         const ::rtl::OUString& sISOLocale = *pFound;
     826           0 :         aLocale.fromISO(sISOLocale);
     827             :     }
     828             : 
     829           0 :     return pFound;
     830             : }
     831             : 
     832             : //-----------------------------------------------
     833           0 : css::uno::Reference< css::embed::XStorage > PresetHandler::impl_openLocalizedPathIgnoringErrors(::rtl::OUString&      sPath         ,
     834             :                                                                                                 sal_Int32             eMode         ,
     835             :                                                                                                 sal_Bool              bShare        ,
     836             :                                                                                                 ::comphelper::Locale& aLocale       ,
     837             :                                                                                                 sal_Bool              bAllowFallback)
     838             : {
     839           0 :     css::uno::Reference< css::embed::XStorage >      xPath         = impl_openPathIgnoringErrors(sPath, eMode, bShare);
     840           0 :     ::std::vector< ::rtl::OUString >                 lSubFolders   = impl_getSubFolderNames(xPath);
     841           0 :     ::std::vector< ::rtl::OUString >::const_iterator pLocaleFolder = impl_findMatchingLocalizedValue(lSubFolders, aLocale, bAllowFallback);
     842             : 
     843             :     // no fallback ... creation not allowed => no storage
     844           0 :     if (
     845           0 :         (pLocaleFolder == lSubFolders.end()                                                ) &&
     846             :         ((eMode & css::embed::ElementModes::NOCREATE) == css::embed::ElementModes::NOCREATE)
     847             :        )
     848           0 :         return css::uno::Reference< css::embed::XStorage >();
     849             : 
     850             :     // it doesnt matter, if there is a locale fallback or not
     851             :     // If creation of storages is allowed, we do it anyway.
     852             :     // Otherwhise we have no acc config at all, which can make other trouble.
     853           0 :     ::rtl::OUString sLocalizedPath;
     854           0 :     sLocalizedPath  = sPath;
     855           0 :     sLocalizedPath += PATH_SEPERATOR;
     856           0 :     if (pLocaleFolder != lSubFolders.end())
     857           0 :         sLocalizedPath += *pLocaleFolder;
     858             :     else
     859           0 :         sLocalizedPath += aLocale.toISO();
     860             : 
     861           0 :     css::uno::Reference< css::embed::XStorage > xLocalePath = impl_openPathIgnoringErrors(sLocalizedPath, eMode, bShare);
     862             : 
     863           0 :     if (xLocalePath.is())
     864           0 :         sPath = sLocalizedPath;
     865             :     else
     866           0 :         sPath = ::rtl::OUString();
     867             : 
     868           0 :     return xLocalePath;
     869             : }
     870             : 
     871             : //-----------------------------------------------
     872           0 : ::std::vector< ::rtl::OUString > PresetHandler::impl_getSubFolderNames(const css::uno::Reference< css::embed::XStorage >& xFolder)
     873             : {
     874           0 :     css::uno::Reference< css::container::XNameAccess > xAccess(xFolder, css::uno::UNO_QUERY);
     875           0 :     if (!xAccess.is())
     876           0 :         return ::std::vector< ::rtl::OUString >();
     877             : 
     878           0 :           ::std::vector< ::rtl::OUString >      lSubFolders;
     879           0 :     const css::uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames();
     880           0 :     const ::rtl::OUString*                      pNames = lNames.getConstArray();
     881           0 :           sal_Int32                             c      = lNames.getLength();
     882           0 :           sal_Int32                             i      = 0;
     883             : 
     884           0 :     for (i=0; i<c; ++i)
     885             :     {
     886             :         try
     887             :         {
     888           0 :             if (xFolder->isStorageElement(pNames[i]))
     889           0 :                 lSubFolders.push_back(pNames[i]);
     890             :         }
     891           0 :         catch(const css::uno::RuntimeException&)
     892           0 :             { throw; }
     893           0 :         catch(const css::uno::Exception&)
     894             :             {}
     895             :     }
     896             : 
     897           0 :     return lSubFolders;
     898             : }
     899             : 
     900             : //-----------------------------------------------
     901             : } // namespace framework
     902             : 
     903             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10