#87904# Add support for handling configuration pathes correctly

This commit is contained in:
Jörg Barfurth 2001-07-10 10:13:39 +00:00
parent 08b7c167a4
commit 6bdbf539f4
4 changed files with 542 additions and 8 deletions

View file

@ -2,9 +2,9 @@
*
* $RCSfile: configitem.hxx,v $
*
* $Revision: 1.16 $
* $Revision: 1.17 $
*
* last change: $Author: os $ $Date: 2001-06-25 14:41:45 $
* last change: $Author: jb $ $Date: 2001-07-10 11:12:16 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@ -97,6 +97,16 @@ namespace utl
#define CONFIG_MODE_ALL_LOCALES 0x02
#define CONFIG_MODE_RELEASE_TREE 0x04
enum ConfigNameFormat
{
CONFIG_NAME_PLAINTEXT_NAME, // unescaped local node name, for user display etc.
CONFIG_NAME_LOCAL_NAME, // local node name, for use in XNameAccess etc. ("Item", "Q & A")
CONFIG_NAME_LOCAL_PATH, // one-level relative path, for use when building pathes etc. ("Item", "Typ['Q & A']")
CONFIG_NAME_FULL_PATH, // full absolute path. ("/org.openoffice.Sample/Group/Item", "/org.openoffice.Sample/Set/Typ['Q & A']")
CONFIG_NAME_DEFAULT = CONFIG_NAME_LOCAL_PATH // default format
};
class ConfigChangeListener_Impl;
class ConfigManager;
struct ConfigItem_Impl;
@ -164,9 +174,13 @@ namespace utl
sal_Bool bEnableInternalNotification = sal_False);
#endif
sal_Bool IsInternalNotification()const {return IsInValueChange();}
//returns all members of a node
//returns all members of a node in a specific format
com::sun::star::uno::Sequence< rtl::OUString >
GetNodeNames(const rtl::OUString& rNode);
//returns all members of a node in a specific format
com::sun::star::uno::Sequence< rtl::OUString >
GetNodeNames(const rtl::OUString& rNode, ConfigNameFormat eFormat);
// remove all members of a set
sal_Bool ClearNodeSet(const rtl::OUString& rNode);
// remove selected members of a set

View file

@ -0,0 +1,219 @@
/*************************************************************************
*
* $RCSfile: configpathes.hxx,v $
*
* $Revision: 1.1 $
*
* last change: $Author: jb $ $Date: 2001-07-10 11:12:16 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#ifndef UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
#define UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif
namespace rtl
{
class OUString;
}
//----------------------------------------------------------------------------
namespace utl
{
//----------------------------------------------------------------------------
/** extract the local nodename and the parent nodepath
from a configuration path.
@param _sInPath
A configuration path that is not an empty or root path.<BR/>
If this is not a valid configuration path, it is interpreted as
local name of a node.
@param _rsOutPath
On exit: The configuration path obtained by dropping
the last level off <var>_sInPath</var>.<BR/>
If <var>_sInPath</var> could not be parsed as a valid
configuration path, this is set to an empty string.
@param _rsLocalName
On exit: The plain (non-escaped) name of the node identified by
<var>_sInPath</var>. <BR/>
If <var>_sInPath</var> could not be parsed as a valid
configuration path, this is set to <var>_sInPath</var>.
@returns
<TRUE/>, if a parent path could be set
<FALSE/>, if the path was a one-level path or an invalid path
*/
sal_Bool splitLastFromConfigurationPath(::rtl::OUString const& _sInPath,
::rtl::OUString& _rsOutPath,
::rtl::OUString& _rsLocalName);
//----------------------------------------------------------------------------
/** extract the first nodename from a configuration path.
@param _sInPath
A relative configuration path that is not empty.<BR/>
If this is not a valid configuration path, it is interpreted as
a single name of a node.
@returns
The plain (non-escaped) name of the node that is the first step
when traversing <var>_sInPath</var>.<BR/>
If <var>_sInPath</var> could not be parsed as a valid
configuration path, it is returned unaltered.
*/
::rtl::OUString extractFirstFromConfigurationPath(::rtl::OUString const& _sInPath);
//----------------------------------------------------------------------------
/** check whether a path is to a nested node with respect to a parent path.
@param _sNestedPath
A configuration path that maybe points to a descendant of the node
identified by <var>_sPrefixPath</var>, with both pathes starting
from the same node (or both being absolute).
@param _sPrefixPath
A configuration path.<BR/>
If this path is absolute, <var>_sNestedPath</var> should be absolute;
If this path is relative, <var>_sNestedPath</var> should be relative;
If this path is empty, <var>_sNestedPath</var> may start with a '/',
which is disregarded.
@returns
<TRUE/>, if <var>_sPrefixPath</var> is a prefix of <var>_sNestedPath</var>;
<FALSE/> otherwise.<BR/>
If both pathes are equal <TRUE/> is returned.
*/
sal_Bool isPrefixOfConfigurationPath(::rtl::OUString const& _sNestedPath,
::rtl::OUString const& _sPrefixPath);
//----------------------------------------------------------------------------
/** get the relative path to a nested node with respect to a parent path.
@param _sNestedPath
A configuration path that points to a descendant of the node
identified by <var>_sPrefixPath</var>, with both pathes starting
from the same node (or both being absolute).
@param _sPrefixPath
A configuration path.<BR/>
If this path is absolute, <var>_sNestedPath</var> must be absolute;
If this path is relative, <var>_sNestedPath</var> must be relative;
If this path is empty, <var>_sNestedPath</var> may start with a '/',
which is stripped.
@returns
The remaining relative path from the target of <var>_sPrefixPath</var>
to the target of <var>_sNestedPath</var>.<BR/>
If <var>_sPrefixPath</var> is not a prefix of <var>_sNestedPath</var>,
<var>_sNestedPath</var> is returned unaltered.
*/
::rtl::OUString dropPrefixFromConfigurationPath(::rtl::OUString const& _sNestedPath,
::rtl::OUString const& _sPrefixPath);
//----------------------------------------------------------------------------
/** Create a one-level relative configuration path from a set element name
without a known set element type.
@param _sElementName
An arbitrary string that is to be interpreted as
name of a configuration set element.
@returns
A one-level relative path to the element, of the form
"*['<Name>']", where <Name> is properly escaped.
*/
::rtl::OUString wrapConfigurationElementName(::rtl::OUString const& _sElementName);
//----------------------------------------------------------------------------
/** Create a one-level relative configuration path from a set element name
and a known set element type.
@param _sElementName
An arbitrary string that is to be interpreted as
name of a configuration set element.
@param _sTypeName
An string identifying the type of the element. Usually this is be
the name of the element-template of the set.<BR/>
@returns
A one-level relative path to the element, of the form
"<Type>['<Name>']", where <Name> is properly escaped.
*/
::rtl::OUString wrapConfigurationElementName(::rtl::OUString const& _sElementName,
::rtl::OUString const& _sTypeName);
//----------------------------------------------------------------------------
} // namespace utl
//----------------------------------------------------------------------------
#endif // UNOTOOLS_CONFIGPATHES_HXX_INCLUDED
/*************************************************************************
* history:
* $Log: not supported by cvs2svn $
*
************************************************************************/

View file

@ -0,0 +1,297 @@
/*************************************************************************
*
* $RCSfile: configpathes.cxx,v $
*
* $Revision: 1.1 $
*
* last change: $Author: jb $ $Date: 2001-07-10 11:12:18 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#include "unotools/configpathes.hxx"
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif
#ifndef _RTL_USTRBUF_HXX_
#include <rtl/ustrbuf.hxx>
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
//----------------------------------------------------------------------------
namespace utl
{
//----------------------------------------------------------------------------
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
//----------------------------------------------------------------------------
sal_Bool splitLastFromConfigurationPath(OUString const& _sInPath,
OUString& _rsOutPath,
OUString& _rsLocalName)
{
sal_Int32 nStart,nEnd;
sal_Int32 nPos = _sInPath.getLength()-1;
// strip trailing slash
if (nPos > 0 && _sInPath[ nPos ] == sal_Unicode('/'))
{
OSL_ENSURE(false, "Invalid config path: trailing '/' is not allowed");
--nPos;
}
// check for predicate ['xxx'] or ["yyy"]
if (nPos > 0 && _sInPath[ nPos ] == sal_Unicode(']'))
{
sal_Unicode chQuote = _sInPath[--nPos];
if (chQuote == '\'' || chQuote == '\"')
{
nEnd = nPos;
nPos = _sInPath.lastIndexOf(chQuote,nEnd);
nStart = nPos + 1;
--nPos; // nPos = rInPath.lastIndexOf('[',nPos);
}
else // allow [xxx]
{
nEnd = nPos + 1;
nPos = _sInPath.lastIndexOf('[',nEnd);
nStart = nPos + 1;
}
OSL_ENSURE(nPos >= 0 && _sInPath[nPos] == '[', "Invalid config path: unmatched quotes or brackets");
if (nPos >= 0 && _sInPath[nPos] == '[')
{
nPos = _sInPath.lastIndexOf('/',nPos);
}
else // defined behavior for invalid pathes
{
nStart = 0, nEnd = _sInPath.getLength();
nPos = -1;
}
}
else
{
nEnd = nPos+1;
nPos = _sInPath.lastIndexOf('/',nEnd);
nStart = nPos + 1;
}
OSL_ASSERT( -1 <= nPos &&
nPos < nStart &&
nStart < nEnd &&
nEnd <= _sInPath.getLength() );
OSL_ASSERT(nPos == -1 || _sInPath[nPos] == '/');
OSL_ENSURE(nPos != 0 , "Invalid config child path: immediate child of root");
_rsLocalName = _sInPath.copy(nStart, nEnd-nStart);
_rsOutPath = (nPos > 0) ? _sInPath.copy(0,nPos) : OUString();
return nPos >= 0;
}
//----------------------------------------------------------------------------
OUString extractFirstFromConfigurationPath(OUString const& _sInPath)
{
sal_Int32 nSep = _sInPath.indexOf('/');
sal_Int32 nBracket = _sInPath.indexOf('[');
sal_Int32 nStart = nBracket + 1;
sal_Int32 nEnd = nSep;
if (0 <= nBracket) // found a bracket-quoted relative path
{
if (nSep < 0 || nBracket < nSep) // and the separator comes after it
{
sal_Unicode chQuote = _sInPath[nStart];
if (chQuote == '\'' || chQuote == '\"')
{
++nStart;
nEnd = _sInPath.indexOf(chQuote, nStart+1);
nBracket = nEnd+1;
}
else
{
nEnd = _sInPath.indexOf(']',nStart);
nBracket = nEnd;
}
OSL_ENSURE(nEnd > nStart && _sInPath[nBracket] == ']', "Invalid config path: improper mismatch of quote or bracket");
OSL_DEBUG_ONLY(nSep = nBracket+1);
OSL_ENSURE(nSep == _sInPath.getLength() || _sInPath[nSep] == '/', "Invalid config path: brackets not followed by slash");
}
else // ... but our initial element name is in simple form
nStart = 0;
}
OUString sResult = (nEnd >= 0) ? _sInPath.copy(nStart, nEnd-nStart) : _sInPath;
return sResult;
}
//----------------------------------------------------------------------------
// find the position after the prefix in the nested path
static inline
sal_Int32 lcl_findPrefixEnd(OUString const& _sNestedPath, OUString const& _sPrefixPath)
{
// TODO: currently handles only exact prefix matches
sal_Int32 nPrefixLength = _sPrefixPath.getLength();
OSL_ENSURE(nPrefixLength == 0 || _sPrefixPath[nPrefixLength-1] != '/',
"Cannot handle slash-terminated prefix pathes");
sal_Bool bIsPrefix;
if (_sNestedPath.getLength() > nPrefixLength)
{
bIsPrefix = _sNestedPath[nPrefixLength] == '/' &&
_sNestedPath.compareTo(_sPrefixPath,nPrefixLength) == 0;
++nPrefixLength;
}
else if (_sNestedPath.getLength() == nPrefixLength)
{
bIsPrefix = _sNestedPath.equals(_sPrefixPath);
}
else
{
bIsPrefix = false;
}
return bIsPrefix ? nPrefixLength : 0;
}
//----------------------------------------------------------------------------
sal_Bool isPrefixOfConfigurationPath(OUString const& _sNestedPath,
OUString const& _sPrefixPath)
{
return _sPrefixPath.getLength() == 0 || lcl_findPrefixEnd(_sNestedPath,_sPrefixPath) != 0;
}
//----------------------------------------------------------------------------
OUString dropPrefixFromConfigurationPath(OUString const& _sNestedPath,
OUString const& _sPrefixPath)
{
if ( sal_Int32 nPrefixEnd = lcl_findPrefixEnd(_sNestedPath,_sPrefixPath) )
{
return _sNestedPath.copy(nPrefixEnd);
}
else
{
OSL_ENSURE(_sPrefixPath.getLength() == 0, "Path does not start with expected prefix");
return _sNestedPath;
}
}
//----------------------------------------------------------------------------
static
OUString lcl_wrapName(const OUString& _sContent, const OUString& _sType)
{
const sal_Unicode * const pBeginContent = _sContent.getStr();
const sal_Unicode * const pEndContent = pBeginContent + _sContent.getLength();
OSL_PRECOND(_sType.getLength(), "Unexpected config type name: empty");
OSL_PRECOND(pBeginContent <= pEndContent, "Invalid config name: empty");
if (pBeginContent == pEndContent)
return _sType;
rtl::OUStringBuffer aNormalized(_sType.getLength() + _sContent.getLength() + 4); // reserve approximate size initially
// prefix: type, opening bracket and quote
aNormalized.append( _sType ).appendAscii( RTL_CONSTASCII_STRINGPARAM("['") );
// content: copy over each char and handle escaping
for(const sal_Unicode* pCur = pBeginContent; pCur != pEndContent; ++pCur)
{
// append (escape if needed)
switch(*pCur)
{
case sal_Unicode('&') : aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("&amp;") ); break;
case sal_Unicode('\''): aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("&apos;") ); break;
case sal_Unicode('\"'): aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("&quot;") ); break;
default: aNormalized.append( *pCur );
}
}
// suffix: closing quote and bracket
aNormalized.appendAscii( RTL_CONSTASCII_STRINGPARAM("']") );
return aNormalized.makeStringAndClear();
}
//----------------------------------------------------------------------------
OUString wrapConfigurationElementName(OUString const& _sElementName)
{
return lcl_wrapName(_sElementName, OUString(RTL_CONSTASCII_USTRINGPARAM("*")) );
}
//----------------------------------------------------------------------------
OUString wrapConfigurationElementName(OUString const& _sElementName,
OUString const& _sTypeName)
{
// todo: check that _sTypeName is valid
return lcl_wrapName(_sElementName, _sTypeName);
}
//----------------------------------------------------------------------------
} // namespace utl

View file

@ -2,9 +2,9 @@
#
# $RCSfile: makefile.mk,v $
#
# $Revision: 1.5 $
# $Revision: 1.6 $
#
# last change: $Author: cd $ $Date: 2001-07-06 07:19:18 $
# last change: $Author: jb $ $Date: 2001-07-10 11:13:39 $
#
# The Contents of this file are made available subject to the terms of
# either of the following licenses
@ -70,6 +70,9 @@ ENABLE_EXCEPTIONS=TRUE
# --- Settings common for the whole project -----
#UNOTYPES=
UNOTYPES+= com.sun.star.configuration.XTemplateContainer
#.INCLUDE : $(PRJINC)$/unotools$/unotools.mk
# --- Settings ----------------------------------
@ -79,10 +82,10 @@ ENABLE_EXCEPTIONS=TRUE
# --- Types -------------------------------------
#UNOUCRDEP=$(SOLARBINDIR)$/applicat.rdb
#UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb
UNOUCRDEP=$(SOLARBINDIR)$/applicat.rdb
UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb
#UNOUCROUT=$(OUT)$/inc
UNOUCROUT=$(OUT)$/inc
#INCPRE+=$(UNOUCROUT)
# --- Types -------------------------------------
@ -97,6 +100,7 @@ SLOFILES=\
$(SLO)$/confignode.obj \
$(SLO)$/configitem.obj \
$(SLO)$/configmgr.obj \
$(SLO)$/configpathes.obj \
$(SLO)$/bootstrap.obj
# --- Targets ----------------------------------