/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_framework.hxx"
// ______________________________________________
// my own includes

/** Attention: stl headers must(!) be included at first. Otherwise it can make trouble
               with solaris headers ...
*/
#include <vector>
#include <services/pathsettings.hxx>
#include <threadhelp/readguard.hxx>
#include <threadhelp/writeguard.hxx>
#include <services.h>

// ______________________________________________
// interface includes
#include <com/sun/star/beans/Property.hpp>
#include <com/sun/star/beans/XProperty.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/util/XChangesNotifier.hpp>

// ______________________________________________
// includes of other projects
#include <tools/urlobj.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/logfile.hxx>

#include <comphelper/configurationhelper.hxx>
#include <unotools/configpathes.hxx>

#include <fwkdllapi.h>

// ______________________________________________
//	non exported const

#define CFG_READONLY_DEFAULT    sal_False

const ::rtl::OUString CFGPROP_INTERNALPATHES = ::rtl::OUString::createFromAscii("InternalPaths");
const ::rtl::OUString CFGPROP_USERPATHES     = ::rtl::OUString::createFromAscii("UserPaths"    );
const ::rtl::OUString CFGPROP_WRITEPATH      = ::rtl::OUString::createFromAscii("WritePath"    );
const ::rtl::OUString CFGPROP_ISSINGLEPATH   = ::rtl::OUString::createFromAscii("IsSinglePath" );

/*
    0 : old style              "Template"              string using ";" as seperator
    1 : internal paths         "Template_internal"     string list
    2 : user paths             "Template_user"         string list
    3 : write path             "Template_write"        string
 */

const ::rtl::OUString POSTFIX_INTERNAL_PATHES = ::rtl::OUString::createFromAscii("_internal");
const ::rtl::OUString POSTFIX_USER_PATHES     = ::rtl::OUString::createFromAscii("_user"    );
const ::rtl::OUString POSTFIX_WRITE_PATH      = ::rtl::OUString::createFromAscii("_writable");

const sal_Int32 IDGROUP_OLDSTYLE        = 0;
const sal_Int32 IDGROUP_INTERNAL_PATHES = 1;
const sal_Int32 IDGROUP_USER_PATHES     = 2;
const sal_Int32 IDGROUP_WRITE_PATH      = 3;

const sal_Int32 IDGROUP_COUNT           = 4;

sal_Int32 impl_getPropGroup(sal_Int32 nID)
{
	return (nID % IDGROUP_COUNT);
}

// ______________________________________________
//	namespace

namespace framework
{

//-----------------------------------------------------------------------------
// XInterface, XTypeProvider, XServiceInfo

DEFINE_XINTERFACE_7						(   PathSettings                                             ,
                                            OWeakObject                                              ,
                                            DIRECT_INTERFACE ( css::lang::XTypeProvider              ),
                                            DIRECT_INTERFACE ( css::lang::XServiceInfo               ),
                                            DERIVED_INTERFACE( css::lang::XEventListener, css::util::XChangesListener),
                                            DIRECT_INTERFACE ( css::util::XChangesListener           ),
                                            DIRECT_INTERFACE ( css::beans::XPropertySet				 ),
                                            DIRECT_INTERFACE ( css::beans::XFastPropertySet			 ),
                                            DIRECT_INTERFACE ( css::beans::XMultiPropertySet		)
										)

DEFINE_XTYPEPROVIDER_7					(   PathSettings                                            ,
                                            css::lang::XTypeProvider                                ,
                                            css::lang::XServiceInfo                                 ,
                                            css::lang::XEventListener                               ,
                                            css::util::XChangesListener                             ,
                                            css::beans::XPropertySet								,
                                            css::beans::XFastPropertySet							,
                                            css::beans::XMultiPropertySet
										)

DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   PathSettings                                            ,
                                            ::cppu::OWeakObject                                     ,
                                            SERVICENAME_PATHSETTINGS                                ,
											IMPLEMENTATIONNAME_PATHSETTINGS
										)

DEFINE_INIT_SERVICE                     (   PathSettings,
                                            {
                                                /*Attention
                                                    I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
                                                    to create a new instance of this class by our own supported service factory.
                                                    see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further information!
                                                */

                                                // fill cache
                                                impl_readAll();
                                            }
                                        )

//-----------------------------------------------------------------------------
PathSettings::PathSettings( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
    //	Init baseclasses first
    //  Attention: Don't change order of initialization!
    //      ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
    //      We must garant right initialization and a valid value of this to initialize other baseclasses!
    :   ThreadHelpBase()
    ,   ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aLock.getShareableOslMutex())
    ,   ::cppu::OPropertySetHelper(*(static_cast< ::cppu::OBroadcastHelper* >(this)))
    ,   ::cppu::OWeakObject()
    // Init member
    ,   m_xSMGR    (xSMGR)
    ,   m_pPropHelp(0    )
	,  m_bIgnoreEvents(sal_False)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::PathSettings" );
}

//-----------------------------------------------------------------------------
PathSettings::~PathSettings()
{
    if (m_pPropHelp)
       delete m_pPropHelp;
}

//-----------------------------------------------------------------------------
void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
    throw (css::uno::RuntimeException)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::changesOccurred" );
	/*
	if (m_bIgnoreEvents)
		return;
	*/

    sal_Int32 c                 = aEvent.Changes.getLength();
    sal_Int32 i                 = 0;
    sal_Bool  bUpdateDescriptor = sal_False;

    for (i=0; i<c; ++i)
    {
        const css::util::ElementChange& aChange = aEvent.Changes[i];

        ::rtl::OUString sChanged;
        aChange.Accessor >>= sChanged;

        ::rtl::OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
        if (sPath.getLength())
        {
            PathSettings::EChangeOp eOp = impl_updatePath(sPath, sal_True);
            if (
                (eOp == PathSettings::E_ADDED  ) ||
                (eOp == PathSettings::E_REMOVED)
               )
                bUpdateDescriptor = sal_True;
        }
    }

    if (bUpdateDescriptor)
        impl_rebuildPropertyDescriptor();
}

//-----------------------------------------------------------------------------
void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
    throw(css::uno::RuntimeException)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::disposing" );
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    if (aSource.Source == m_xCfgNew)
        m_xCfgNew.clear();

    aWriteLock.unlock();
    // <- SAFE
}

//-----------------------------------------------------------------------------
void PathSettings::impl_readAll()
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readAll" );
    RTL_LOGFILE_CONTEXT(aLog, "framework (as96863) ::PathSettings::load config (all)");

    // TODO think about me
    css::uno::Reference< css::container::XNameAccess > xCfg    = fa_getCfgNew();
    css::uno::Sequence< ::rtl::OUString >              lPaths = xCfg->getElementNames();

    sal_Int32 c = lPaths.getLength();
    sal_Int32 i = 0;

    for (i=0; i<c; ++i)
    {
        const ::rtl::OUString& sPath = lPaths[i];
        impl_updatePath(sPath, sal_False);
    }

	impl_rebuildPropertyDescriptor();
}

//-----------------------------------------------------------------------------
// NO substitution here ! It's done outside ...
OUStringList PathSettings::impl_readOldFormat(const ::rtl::OUString& sPath)
{
	RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readOldFormat" );
	css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
	OUStringList aPathVal;

	if( xCfg->hasByName(sPath) )
	{
		css::uno::Any aVal( xCfg->getByName(sPath) );

		::rtl::OUString                       sStringVal;
		css::uno::Sequence< ::rtl::OUString > lStringListVal;

		if (aVal >>= sStringVal)
		{
			aPathVal.push_back(sStringVal);
		}
		else if (aVal >>= lStringListVal)
		{
			aPathVal << lStringListVal;
		}
	}

	return aPathVal;
}

//-----------------------------------------------------------------------------
// NO substitution here ! It's done outside ...
PathSettings::PathInfo PathSettings::impl_readNewFormat(const ::rtl::OUString& sPath)
{
    css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();

    // get access to the "queried" path
    css::uno::Reference< css::container::XNameAccess > xPath;
    xCfg->getByName(sPath) >>= xPath;

    PathSettings::PathInfo aPathVal;

    // read internal path list
    css::uno::Reference< css::container::XNameAccess > xIPath;
    xPath->getByName(CFGPROP_INTERNALPATHES) >>= xIPath;
    aPathVal.lInternalPaths << xIPath->getElementNames();

    // read user defined path list
    aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHES);

    // read the writeable path
    xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;

    // read state props
    xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;

    // analyze finalized/mandatory states
    aPathVal.bIsReadonly = sal_False;
    css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
    if (xInfo.is())
    {
        css::beans::Property aInfo = xInfo->getAsProperty();
        sal_Bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
		//sal_Bool bMandatory = ((aInfo.Attributes & css::beans::PropertyAttribute::REMOVEABLE) != css::beans::PropertyAttribute::REMOVEABLE);

        // Note: Till we support finalized / mandatory on our API more in detail we handle
        // all states simple as READONLY ! But because all really needed paths are "mandatory" by default
        // we have to handle "finalized" as the real "readonly" indicator .
        aPathVal.bIsReadonly = bFinalized;
    }

    return aPathVal;
}

//-----------------------------------------------------------------------------
void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_storePath" );
	m_bIgnoreEvents = sal_True;

    css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
    css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();

    // try to replace path-parts with well known and supported variables.
    // So an office can be moved easily to another location without losing
    // its related paths.
    PathInfo aResubstPath(aPath);
    impl_subst(aResubstPath, sal_True);

    // update new configuration
    if (! aResubstPath.bIsSinglePath)
    {
        ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
                                                            aResubstPath.sPathName,
                                                            CFGPROP_USERPATHES,
                                                            css::uno::makeAny(aResubstPath.lUserPaths.getAsConstList()));
    }

    ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
                                                        aResubstPath.sPathName,
                                                        CFGPROP_WRITEPATH,
                                                        css::uno::makeAny(aResubstPath.sWritePath));

    ::comphelper::ConfigurationHelper::flush(xCfgNew);

    // remove the whole path from the old configuration !
    // Otherwise we can't make sure that the diff between new and old configuration
    // on loading time really represent an user setting !!!

    // Check if the given path exists inside the old configuration.
    // Because our new configuration knows more then the list of old paths ... !
    if (xCfgOld->hasByName(aResubstPath.sPathName))
    {
        css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
        xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
        ::comphelper::ConfigurationHelper::flush(xCfgOld);
    }

	m_bIgnoreEvents = sal_False;
}

//-----------------------------------------------------------------------------
#ifdef MIGRATE_OLD_USER_PATHES
void PathSettings::impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
                                          const OUStringList&           lOld )
{
    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_mergeOldUserPaths" );
    OUStringList::const_iterator pIt;
    for (  pIt  = lOld.begin();
           pIt != lOld.end()  ;
         ++pIt                )
    {
        const ::rtl::OUString& sOld = *pIt;

        if (rPath.bIsSinglePath)
        {
            LOG_ASSERT2(lOld.size()>1, "PathSettings::impl_mergeOldUserPaths()", "Single path has more then one path value inside old configuration (Common.xcu)!")
            if (! rPath.sWritePath.equals(sOld))
               rPath.sWritePath = sOld;
        }
        else
        {
            if (
                (  rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
                (  rPath.lUserPaths.findConst(sOld)     == rPath.lUserPaths.end()    ) &&
                (! rPath.sWritePath.equals(sOld)                                     )
               )
               rPath.lUserPaths.push_back(sOld);
        }
    }
}
#endif // MIGRATE_OLD_USER_PATHES

//-----------------------------------------------------------------------------
PathSettings::EChangeOp PathSettings::impl_updatePath(const ::rtl::OUString& sPath          ,
                                                            sal_Bool         bNotifyListener)
{
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    PathSettings::PathInfo* pPathOld = 0;
    PathSettings::PathInfo* pPathNew = 0;
    PathSettings::EChangeOp eOp      = PathSettings::E_UNDEFINED;
    PathSettings::PathInfo  aPath;

    try
    {
        aPath = impl_readNewFormat(sPath);
        aPath.sPathName = sPath;
        // replace all might existing variables with real values
        // Do it before these old paths will be compared against the
        // new path configuration. Otherwise some strings uses different variables ... but substitution
        // will produce strings with same content (because some variables are redundant!)
        impl_subst(aPath, sal_False);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::container::NoSuchElementException&)
        { eOp = PathSettings::E_REMOVED; }
    catch(const css::uno::Exception& exAny)
        { throw exAny; }

    #ifdef MIGRATE_OLD_USER_PATHES
    try
    {
        // migration of old user defined values on demand
        // can be disabled for a new major
        OUStringList lOldVals = impl_readOldFormat(sPath);
        // replace all might existing variables with real values
        // Do it before these old paths will be compared against the
        // new path configuration. Otherwise some strings uses different variables ... but substitution
        // will produce strings with same content (because some variables are redundant!)
        impl_subst(lOldVals, fa_getSubstitution(), sal_False);
        impl_mergeOldUserPaths(aPath, lOldVals);
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    // Normal(!) exceptions can be ignored!
    // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
    // we can't find a value for it inside the "old" configuration. So a NoSuchElementException
    // will be normal .-)
    catch(const css::uno::Exception&)
        {}
    #endif // MIGRATE_OLD_USER_PATHES

    PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
    if (eOp == PathSettings::E_UNDEFINED)
    {
        if (pPath != m_lPaths.end())
            eOp = PathSettings::E_CHANGED;
        else
            eOp = PathSettings::E_ADDED;
    }

    switch(eOp)
    {
        case PathSettings::E_ADDED :
             {
                if (bNotifyListener)
                {
                    pPathOld = 0;
                    pPathNew = &aPath;
                    impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
                }
                m_lPaths[sPath] = aPath;
             }
             break;

        case PathSettings::E_CHANGED :
             {
                if (bNotifyListener)
                {
                    pPathOld = &(pPath->second);
                    pPathNew = &aPath;
                    impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
                }
                m_lPaths[sPath] = aPath;
             }
             break;

        case PathSettings::E_REMOVED :
             {
                if (pPath != m_lPaths.end())
                {
                    if (bNotifyListener)
                    {
                        pPathOld = &(pPath->second);
                        pPathNew = 0;
                        impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
                    }
                    m_lPaths.erase(pPath);
                }
             }
             break;

		default: // to let compiler be happy
			 break;
    }

    return eOp;
}

//-----------------------------------------------------------------------------
css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const ::rtl::OUString& sPath)
{
    ::rtl::OUString sOldStyleProp = sPath;
    ::rtl::OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHES;
    ::rtl::OUString sUserProp     = sPath+POSTFIX_USER_PATHES;
    ::rtl::OUString sWriteProp    = sPath+POSTFIX_WRITE_PATH;

    // Attention: The default set of IDs is fix and must follow these schema.
    // Otherwise the outside code ant work for new added properties.
    // Why ?
    // The outside code must fire N events for every changed property.
    // And the knowing about packaging of variables of the structure PathInfo
    // follow these group IDs ! But if such ID isn't in the range of [0..IDGROUP_COUNT]
    // the outside can't determine the right group ... and can't fire the right events .-)

    css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
    lIDs[0] = IDGROUP_OLDSTYLE       ;
    lIDs[1] = IDGROUP_INTERNAL_PATHES;
    lIDs[2] = IDGROUP_USER_PATHES    ;
    lIDs[3] = IDGROUP_WRITE_PATH     ;

    sal_Int32 c = m_lPropDesc.getLength();
    sal_Int32 i = 0;
    for (i=0; i<c; ++i)
    {
        const css::beans::Property& rProp = m_lPropDesc[i];

        if (rProp.Name.equals(sOldStyleProp))
            lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
        else
        if (rProp.Name.equals(sInternalProp))
            lIDs[IDGROUP_INTERNAL_PATHES] = rProp.Handle;
        else
        if (rProp.Name.equals(sUserProp))
            lIDs[IDGROUP_USER_PATHES] = rProp.Handle;
        else
        if (rProp.Name.equals(sWriteProp))
            lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
    }

    return lIDs;
}

//-----------------------------------------------------------------------------
void PathSettings::impl_notifyPropListener(      PathSettings::EChangeOp /*eOp*/     ,
                                           const ::rtl::OUString&        sPath   ,
                                           const PathSettings::PathInfo* pPathOld,
                                           const PathSettings::PathInfo* pPathNew)
{
    css::uno::Sequence< sal_Int32 >     lHandles(1);
    css::uno::Sequence< css::uno::Any > lOldVals(1);
    css::uno::Sequence< css::uno::Any > lNewVals(1);

    css::uno::Sequence< sal_Int32 > lIDs   = impl_mapPathName2IDList(sPath);
    sal_Int32                       c      = lIDs.getLength();
    sal_Int32                       i      = 0;
    sal_Int32                       nMaxID = m_lPropDesc.getLength()-1;
    for (i=0; i<c; ++i)
    {
        sal_Int32 nID = lIDs[i];

        if (
            (nID < 0     ) ||
            (nID > nMaxID)
           )
           continue;

        lHandles[0] = nID;
        switch(impl_getPropGroup(nID))
        {
            case IDGROUP_OLDSTYLE :
                 {
                    if (pPathOld)
                    {
                        ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathOld);
                        lOldVals[0] <<= sVal;
                    }
                    if (pPathNew)
                    {
                        ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathNew);
                        lNewVals[0] <<= sVal;
                    }
                 }
                 break;

            case IDGROUP_INTERNAL_PATHES :
                 {
                    if (pPathOld)
                        lOldVals[0] <<= pPathOld->lInternalPaths.getAsConstList();
                    if (pPathNew)
                        lNewVals[0] <<= pPathNew->lInternalPaths.getAsConstList();
                 }
                 break;

            case IDGROUP_USER_PATHES :
                 {
                    if (pPathOld)
                        lOldVals[0] <<= pPathOld->lUserPaths.getAsConstList();
                    if (pPathNew)
                        lNewVals[0] <<= pPathNew->lUserPaths.getAsConstList();
                 }
                 break;

            case IDGROUP_WRITE_PATH :
                 {
                    if (pPathOld)
                        lOldVals[0] <<= pPathOld->sWritePath;
                    if (pPathNew)
                        lNewVals[0] <<= pPathNew->sWritePath;
                 }
                 break;
        }

        fire(lHandles.getArray(),
             lNewVals.getArray(),
             lOldVals.getArray(),
             1,
             sal_False);
    }
}

//-----------------------------------------------------------------------------
void PathSettings::impl_subst(      OUStringList&                                          lVals   ,
                              const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
                                    sal_Bool                                               bReSubst)
{
    OUStringList::iterator pIt;

    for (  pIt  = lVals.begin();
           pIt != lVals.end()  ;
         ++pIt                 )
    {
        const ::rtl::OUString& sOld = *pIt;
              ::rtl::OUString  sNew ;
        if (bReSubst)
            sNew = xSubst->reSubstituteVariables(sOld);
        else
            sNew = xSubst->substituteVariables(sOld, sal_False);

        *pIt = sNew;
    }
}

//-----------------------------------------------------------------------------
void PathSettings::impl_subst(PathSettings::PathInfo& aPath   ,
                              sal_Bool                bReSubst)
{
    css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();

    impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
    impl_subst(aPath.lUserPaths    , xSubst, bReSubst);
    if (bReSubst)
        aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
    else
        aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
}

//-----------------------------------------------------------------------------
::rtl::OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
{
    OUStringList::const_iterator pIt;
	OUStringList				 lTemp;
    lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);

    for (  pIt  = rPath.lInternalPaths.begin();
           pIt != rPath.lInternalPaths.end()  ;
         ++pIt                                 )
    {
        lTemp.push_back(*pIt);
    }
    for (  pIt  = rPath.lUserPaths.begin();
           pIt != rPath.lUserPaths.end()  ;
         ++pIt                             )
    {
        lTemp.push_back(*pIt);
    }

	if (rPath.sWritePath.getLength() > 0)
        lTemp.push_back(rPath.sWritePath);

    ::rtl::OUStringBuffer sPathVal(256);
    for (  pIt  = lTemp.begin();
           pIt != lTemp.end()  ;
                               )
    {
        sPathVal.append(*pIt);
        ++pIt;
        if (pIt != lTemp.end())
            sPathVal.appendAscii(";");
    }

    return sPathVal.makeStringAndClear();
}

//-----------------------------------------------------------------------------
OUStringList PathSettings::impl_convertOldStyle2Path(const ::rtl::OUString& sOldStylePath) const
{
    OUStringList lList;
    sal_Int32    nToken = 0;
    do
    {
        ::rtl::OUString sToken = sOldStylePath.getToken(0, ';', nToken);
        if (sToken.getLength())
            lList.push_back(sToken);
    }
    while(nToken >= 0);

    return lList;
}

//-----------------------------------------------------------------------------
void PathSettings::impl_purgeKnownPaths(const PathSettings::PathInfo& rPath,
                                               OUStringList&           lList)
{
    OUStringList::const_iterator pIt;
    for (  pIt  = rPath.lInternalPaths.begin();
           pIt != rPath.lInternalPaths.end()  ;
         ++pIt                                 )
    {
        const ::rtl::OUString& rItem = *pIt;
        OUStringList::iterator pItem = lList.find(rItem);
        if (pItem != lList.end())
            lList.erase(pItem);
    }
    for (  pIt  = rPath.lUserPaths.begin();
           pIt != rPath.lUserPaths.end()  ;
         ++pIt                             )
    {
        const ::rtl::OUString& rItem = *pIt;
        OUStringList::iterator pItem = lList.find(rItem);
        if (pItem != lList.end())
            lList.erase(pItem);
    }

    OUStringList::iterator pItem = lList.find(rPath.sWritePath);
    if (pItem != lList.end())
        lList.erase(pItem);
}

//-----------------------------------------------------------------------------
void PathSettings::impl_rebuildPropertyDescriptor()
{
    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    sal_Int32 c = (sal_Int32)m_lPaths.size();
    sal_Int32 i = 0;
    m_lPropDesc.realloc(c*IDGROUP_COUNT);

    PathHash::const_iterator pIt;
    for (  pIt  = m_lPaths.begin();
           pIt != m_lPaths.end()  ;
         ++pIt                     )
    {
        const PathSettings::PathInfo& rPath = pIt->second;
              css::beans::Property*   pProp = 0;

        pProp             = &(m_lPropDesc[i]);
        pProp->Name       = rPath.sPathName;
        pProp->Handle     = i;
        pProp->Type       = ::getCppuType((::rtl::OUString*)0);
        pProp->Attributes = css::beans::PropertyAttribute::BOUND;
        if (rPath.bIsReadonly)
            pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
        ++i;

        pProp             = &(m_lPropDesc[i]);
        pProp->Name       = rPath.sPathName+POSTFIX_INTERNAL_PATHES;
        pProp->Handle     = i;
        pProp->Type       = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
        pProp->Attributes = css::beans::PropertyAttribute::BOUND   |
                            css::beans::PropertyAttribute::READONLY;
        ++i;

        pProp             = &(m_lPropDesc[i]);
        pProp->Name       = rPath.sPathName+POSTFIX_USER_PATHES;
        pProp->Handle     = i;
        pProp->Type       = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
        pProp->Attributes = css::beans::PropertyAttribute::BOUND;
        if (rPath.bIsReadonly)
            pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
        ++i;

        pProp             = &(m_lPropDesc[i]);
        pProp->Name       = rPath.sPathName+POSTFIX_WRITE_PATH;
        pProp->Handle     = i;
        pProp->Type       = ::getCppuType((::rtl::OUString*)0);
        pProp->Attributes = css::beans::PropertyAttribute::BOUND;
        if (rPath.bIsReadonly)
            pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
        ++i;
    }

    if (m_pPropHelp)
       delete m_pPropHelp;
    m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper

    aWriteLock.unlock();
    // <- SAFE
}

//-----------------------------------------------------------------------------
css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
{
    const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
    if (! pPath)
        throw css::container::NoSuchElementException();

    css::uno::Any aVal;
    switch(impl_getPropGroup(nID))
    {
        case IDGROUP_OLDSTYLE :
             {
                ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPath);
                aVal <<= sVal;
             }
             break;

        case IDGROUP_INTERNAL_PATHES :
             {
                aVal <<= pPath->lInternalPaths.getAsConstList();
             }
             break;

        case IDGROUP_USER_PATHES :
             {
                aVal <<= pPath->lUserPaths.getAsConstList();
             }
             break;

        case IDGROUP_WRITE_PATH :
             {
                aVal <<= pPath->sWritePath;
             }
             break;
    }

    return aVal;
}

//-----------------------------------------------------------------------------
void PathSettings::impl_setPathValue(      sal_Int32      nID ,
                                     const css::uno::Any& aVal)
{
    PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
    if (! pOrgPath)
        throw css::container::NoSuchElementException();

    // We work on a copied path ... so we can be sure that errors during this operation
    // does not make our internal cache invalid .-)
    PathSettings::PathInfo aChangePath(*pOrgPath);

    switch(impl_getPropGroup(nID))
    {
        case IDGROUP_OLDSTYLE :
             {
                ::rtl::OUString sVal;
                aVal >>= sVal;
                OUStringList lList = impl_convertOldStyle2Path(sVal);
                impl_subst(lList, fa_getSubstitution(), sal_False);
                impl_purgeKnownPaths(aChangePath, lList);
                if (! impl_isValidPath(lList))
                    throw css::lang::IllegalArgumentException();

                if (aChangePath.bIsSinglePath)
                {
                    LOG_ASSERT2(lList.size()>1, "PathSettings::impl_setPathValue()", "You try to set more then path value for a defined SINGLE_PATH!")
                    if ( !lList.empty() )
                        aChangePath.sWritePath = *(lList.begin());
                    else
                        aChangePath.sWritePath = ::rtl::OUString();
                }
                else
                {
					OUStringList::const_iterator pIt;
					for (  pIt  = lList.begin();
						   pIt != lList.end()  ;
						 ++pIt                 )
					{
	                    aChangePath.lUserPaths.push_back(*pIt);
					}
                }
             }
             break;

        case IDGROUP_INTERNAL_PATHES :
             {
                if (aChangePath.bIsSinglePath)
                {
                    ::rtl::OUStringBuffer sMsg(256);
                    sMsg.appendAscii("The path '"    );
                    sMsg.append     (aChangePath.sPathName);
                    sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.");
                    throw css::uno::Exception(sMsg.makeStringAndClear(),
                                              static_cast< ::cppu::OWeakObject* >(this));
                }

                OUStringList lList;
                lList << aVal;
                if (! impl_isValidPath(lList))
                    throw css::lang::IllegalArgumentException();
                aChangePath.lInternalPaths = lList;
             }
             break;

        case IDGROUP_USER_PATHES :
             {
                if (aChangePath.bIsSinglePath)
                {
                    ::rtl::OUStringBuffer sMsg(256);
                    sMsg.appendAscii("The path '"    );
                    sMsg.append     (aChangePath.sPathName);
                    sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.");
                    throw css::uno::Exception(sMsg.makeStringAndClear(),
                                              static_cast< ::cppu::OWeakObject* >(this));
                }

                OUStringList lList;
                lList << aVal;
                if (! impl_isValidPath(lList))
                    throw css::lang::IllegalArgumentException();
                aChangePath.lUserPaths = lList;
             }
             break;

        case IDGROUP_WRITE_PATH :
             {
                ::rtl::OUString sVal;
                aVal >>= sVal;
                if (! impl_isValidPath(sVal))
                    throw css::lang::IllegalArgumentException();
                aChangePath.sWritePath = sVal;
             }
             break;
    }

    // TODO check if path has at least one path value set
    // At least it depends from the feature using this path, if an empty path list is allowed.
    /*
    if (impl_isPathEmpty(aChangePath))
    {
        ::rtl::OUStringBuffer sMsg(256);
        sMsg.appendAscii("The path '"    );
        sMsg.append     (aChangePath.sPathName);
        sMsg.appendAscii("' is empty now ... Not a real good idea.");
        throw css::uno::Exception(sMsg.makeStringAndClear(),
                                  static_cast< ::cppu::OWeakObject* >(this));
    }
    */

    // first we should try to store the changed (copied!) path ...
    // In case an error occurs on saving time an exception is thrown ...
    // If no exception occurs we can update our internal cache (means
    // we can overwrite pOrgPath !
    impl_storePath(aChangePath);
    pOrgPath->takeOver(aChangePath);
}

//-----------------------------------------------------------------------------
sal_Bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
{
    OUStringList::const_iterator pIt;
    for (  pIt  = lPath.begin();
           pIt != lPath.end()  ;
         ++pIt                 )
    {
        const ::rtl::OUString& rVal = *pIt;
        if (! impl_isValidPath(rVal))
            return sal_False;
    }

	return sal_True;
}

//-----------------------------------------------------------------------------
sal_Bool PathSettings::impl_isValidPath(const ::rtl::OUString& sPath) const
{
	// allow empty path to reset a path.
// idea by LLA to support empty paths
//	if (sPath.getLength() == 0)
//	{
//		return sal_True;
//	}

	return (! INetURLObject(sPath).HasError());
}

//-----------------------------------------------------------------------------
::rtl::OUString impl_extractBaseFromPropName(const ::rtl::OUString& sPropName)
{
	sal_Int32 i = -1;

	i = sPropName.indexOf(POSTFIX_INTERNAL_PATHES);
	if (i > -1)
		return sPropName.copy(0, i);
	i = sPropName.indexOf(POSTFIX_USER_PATHES);
	if (i > -1)
		return sPropName.copy(0, i);
	i = sPropName.indexOf(POSTFIX_WRITE_PATH);
	if (i > -1)
		return sPropName.copy(0, i);

	return sPropName;
}

//-----------------------------------------------------------------------------
PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    if (nHandle > (m_lPropDesc.getLength()-1))
        return 0;

    const css::beans::Property&            rProp = m_lPropDesc[nHandle];
          ::rtl::OUString                  sProp = impl_extractBaseFromPropName(rProp.Name);
          PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);

    if (rPath != m_lPaths.end())
       return &(rPath->second);

    return 0;
    // <- SAFE
}

//-----------------------------------------------------------------------------
const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    if (nHandle > (m_lPropDesc.getLength()-1))
        return 0;

    const css::beans::Property&                  rProp = m_lPropDesc[nHandle];
          ::rtl::OUString                        sProp = impl_extractBaseFromPropName(rProp.Name);
          PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);

    if (rPath != m_lPaths.end())
       return &(rPath->second);

    return 0;
    // <- SAFE
}

//-----------------------------------------------------------------------------
sal_Bool SAL_CALL PathSettings::convertFastPropertyValue(      css::uno::Any& aConvertedValue,
                                                               css::uno::Any& aOldValue      ,
                                                               sal_Int32      nHandle        ,
                                                         const css::uno::Any& aValue         )
    throw(css::lang::IllegalArgumentException)
{
    // throws NoSuchElementException !
    css::uno::Any aCurrentVal = impl_getPathValue(nHandle);

    return PropHelper::willPropertyBeChanged(
                aCurrentVal,
                aValue,
                aOldValue,
                aConvertedValue);
}

//-----------------------------------------------------------------------------
void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
                                                             const css::uno::Any& aValue )
    throw(css::uno::Exception)
{
    // throws NoSuchElement- and IllegalArgumentException !
    impl_setPathValue(nHandle, aValue);
}

//-----------------------------------------------------------------------------
void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
                                                 sal_Int32      nHandle) const
{
    aValue = impl_getPathValue(nHandle);
}

//-----------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
{
    return *m_pPropHelp;
}

//-----------------------------------------------------------------------------
css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
    throw(css::uno::RuntimeException)
{
    return css::uno::Reference< css::beans::XPropertySetInfo >(createPropertySetInfo(getInfoHelper()));
}

//-----------------------------------------------------------------------------
css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR  = m_xSMGR;
    css::uno::Reference< css::util::XStringSubstitution >  xSubst = m_xSubstitution;
    aReadLock.unlock();
    // <- SAFE

    if (! xSubst.is())
    {
        // create the needed substitution service.
        // We must replace all used variables inside read path values.
        // In case we can't do so ... the whole office can't work really.
        // That's why it seems to be OK to throw a RuntimeException then.
        xSubst = css::uno::Reference< css::util::XStringSubstitution >(
                                xSMGR->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES),
                                css::uno::UNO_QUERY_THROW);

        // SAFE ->
        WriteGuard aWriteLock(m_aLock);
        m_xSubstitution = xSubst;
        aWriteLock.unlock();
    }

    return xSubst;
}

//-----------------------------------------------------------------------------
css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
{
    const static ::rtl::OUString CFG_NODE_OLD = ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/Path/Current");

    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    css::uno::Reference< css::container::XNameAccess >     xCfg  = m_xCfgOld;
    aReadLock.unlock();
    // <- SAFE

    if (! xCfg.is())
    {
        xCfg = css::uno::Reference< css::container::XNameAccess >(
                   ::comphelper::ConfigurationHelper::openConfig(
                        xSMGR,
                        CFG_NODE_OLD,
                        ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Sometimes we need write access there !!!
                   css::uno::UNO_QUERY_THROW);

        // SAFE ->
        WriteGuard aWriteLock(m_aLock);
        m_xCfgOld = xCfg;
        aWriteLock.unlock();
    }

    return xCfg;
}

//-----------------------------------------------------------------------------
css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
{
    const static ::rtl::OUString CFG_NODE_NEW = ::rtl::OUString::createFromAscii("org.openoffice.Office.Paths/Paths");

    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    css::uno::Reference< css::container::XNameAccess >     xCfg  = m_xCfgNew;
    aReadLock.unlock();
    // <- SAFE

    if (! xCfg.is())
    {
        xCfg = css::uno::Reference< css::container::XNameAccess >(
                   ::comphelper::ConfigurationHelper::openConfig(
                        xSMGR,
                        CFG_NODE_NEW,
                        ::comphelper::ConfigurationHelper::E_STANDARD),
                   css::uno::UNO_QUERY_THROW);

        // SAFE ->
        WriteGuard aWriteLock(m_aLock);
        m_xCfgNew = xCfg;
        aWriteLock.unlock();

        css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
        xBroadcaster->addChangesListener(static_cast< css::util::XChangesListener* >(this));
    }

    return xCfg;
}

} // namespace framework

/* vim: set noet sw=4 ts=4: */
