diff options
25 files changed, 7714 insertions, 3 deletions
diff --git a/configmgr/prj/build.lst b/configmgr/prj/build.lst index d67ddb458af4..8f44312d0ab0 100644 --- a/configmgr/prj/build.lst +++ b/configmgr/prj/build.lst @@ -4,6 +4,7 @@ cg configmgr\source\cmdtools nmake - all cg_cmdtools NULL cg configmgr\source\cppugen nmake - all cg_cppugen NULL cg configmgr\source\misc nmake - all cg_misc cg_cppugen NULL cg configmgr\source\session nmake - all cg_session cg_cppugen NULL +cg configmgr\source\data nmake - all cg_data cg_cppugen NULL cg configmgr\source\tree nmake - all cg_tree cg_cppugen NULL cg configmgr\source\treecache nmake - all cg_trcache cg_cppugen NULL cg configmgr\source\xml nmake - all cg_xml cg_cppugen NULL @@ -11,5 +12,5 @@ cg configmgr\source\api nmake - all cg_api cg_cppugen NULL cg configmgr\source\api2 nmake - all cg_api2 cg_cppugen NULL cg configmgr\source\treemgr nmake - all cg_treemgr cg_cppugen NULL cg configmgr\source\registry nmake - all cg_reg cg_cppugen NULL -cg configmgr\util nmake - all cg_util cg_api cg_api2 cg_cmdtools cg_misc cg_reg cg_session cg_trcache cg_tree cg_treemgr cg_xml NULL +cg configmgr\util nmake - all cg_util cg_api cg_api2 cg_cmdtools cg_misc cg_reg cg_session cg_trcache cg_data cg_tree cg_treemgr cg_xml NULL diff --git a/configmgr/source/data/anydata.cxx b/configmgr/source/data/anydata.cxx new file mode 100644 index 000000000000..a499d258aef0 --- /dev/null +++ b/configmgr/source/data/anydata.cxx @@ -0,0 +1,534 @@ +/************************************************************************* + * + * $RCSfile: anydata.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:52 $ + * + * 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 "anydata.hxx" + +#ifndef INCLUDED_SHARABLE_SEQUENCE_HXX +#include "sequence.hxx" +#endif +#ifndef INCLUDED_DATA_FLAGS_HXX +#include "flags.hxx" +#endif +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif + +#ifndef CONFIGMGR_TYPECONVERTER_HXX +#include "typeconverter.hxx" +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace sharable + { +//----------------------------------------------------------------------------- + namespace Type = data::Type; + namespace uno = ::com::sun::star::uno; + typedef AnyData::TypeCode TypeCode; + using memory::Pointer; +//----------------------------------------------------------------------------- + +TypeCode getTypeCode(uno::Type const & _aType) +{ + switch (_aType.getTypeClass()) + { + case uno::TypeClass_ANY: + case uno::TypeClass_VOID: + return Type::value_any; + + case uno::TypeClass_STRING: + return Type::value_string; + + case uno::TypeClass_BOOLEAN: + return Type::value_boolean; + + case uno::TypeClass_SHORT: + return Type::value_short; + + case uno::TypeClass_LONG: + return Type::value_int; + + case uno::TypeClass_HYPER: + return Type::value_long; + + case uno::TypeClass_FLOAT: + case uno::TypeClass_DOUBLE: + return Type::value_double; + + case uno::TypeClass_SEQUENCE: + { + uno::Type aElementType = getSequenceElementType(_aType); + + if (aElementType.getTypeClass() == uno::TypeClass_BYTE) + return Type::value_binary; + + OSL_ASSERT(aElementType != _aType); // would cause infinite recursion + TypeCode aElementTC = getTypeCode(aElementType); + + OSL_ASSERT(Type::value_invalid & Type::flag_sequence); // ensure check works for invalid types + + if (aElementTC & Type::flag_sequence) // no sequence of sequence + return Type::value_invalid; + + return aElementTC | Type::flag_sequence; + } + default: + return Type::value_invalid; + } +} +//----------------------------------------------------------------------------- + +static uno::Type getUnoSimpleType( TypeCode _aSimpleType) +{ + OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" ); + + switch (_aSimpleType) + { + case Type::value_string: + return ::getCppuType(static_cast<rtl::OUString const *>(0)); + + case Type::value_boolean: + return ::getBooleanCppuType(); + + case Type::value_short: + return ::getCppuType(static_cast<sal_Int16 const *>(0)); + + case Type::value_int: + return ::getCppuType(static_cast<sal_Int32 const *>(0)); + + case Type::value_long: + return ::getCppuType(static_cast<sal_Int64 const *>(0)); + + case Type::value_double: + return ::getCppuType(static_cast<double const *>(0)); + + case Type::value_binary: + return ::getCppuType(static_cast<uno::Sequence<sal_Int8> const *>(0)); + + case Type::value_any: + //return ::getVoidCppuType(); + return ::getCppuType(static_cast<uno::Any const *>(0)); + + default: + OSL_ENSURE( false, "Invalid type code" ); + return ::getVoidCppuType(); + } +} +//----------------------------------------------------------------------------- + +static uno::Type getUnoSequenceType( TypeCode _aSimpleType) +{ + OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" ); + + switch (_aSimpleType) + { + case Type::value_string: + return ::getCppuType(static_cast<uno::Sequence<rtl::OUString> const *>(0)); + + case Type::value_boolean: + return ::getCppuType(static_cast<uno::Sequence<sal_Bool> const *>(0)); + + case Type::value_short: + return ::getCppuType(static_cast<uno::Sequence<sal_Int16> const *>(0)); + + case Type::value_int: + return ::getCppuType(static_cast<uno::Sequence<sal_Int32> const *>(0)); + + case Type::value_long: + return ::getCppuType(static_cast<uno::Sequence<sal_Int64> const *>(0)); + + case Type::value_double: + return ::getCppuType(static_cast<uno::Sequence<double> const *>(0)); + + case Type::value_binary: + return ::getCppuType(static_cast<uno::Sequence<uno::Sequence<sal_Int8> > const *>(0)); + + case Type::value_any: // results from value_invalid + default: + OSL_ENSURE( false, "Invalid type code" ); + return ::getVoidCppuType(); + } +} +//----------------------------------------------------------------------------- + +uno::Type getUnoType( TypeCode _aType) +{ + OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" ); + + if (_aType & Type::flag_sequence) + return getUnoSequenceType(_aType & Type::mask_basetype); + + else + return getUnoSimpleType(_aType); +} +//----------------------------------------------------------------------------- + +static +AnyData allocSimpleData(memory::Allocator const& _anAllocator, TypeCode _aSimpleType, uno::Any const & _aAny) +{ + OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" ); + + AnyData aResult; + aResult.data = 0; + + switch (_aSimpleType) + { + case Type::value_string: + { + rtl::OUString sValue; + OSL_VERIFY(_aAny >>= sValue ); + aResult.stringValue = allocString(_anAllocator,sValue); + } + break; + + case Type::value_boolean: + OSL_VERIFY(_aAny >>= aResult.boolValue ); + break; + + case Type::value_short: + OSL_VERIFY(_aAny >>= aResult.shortValue); + break; + + case Type::value_int: + OSL_VERIFY(_aAny >>= aResult.intValue); + break; + + case Type::value_long: + { + sal_Int64 nValue; + OSL_VERIFY(_aAny >>= nValue); + + Address aStorage = _anAllocator.allocate( sizeof nValue ); + *static_cast<sal_Int64*>( _anAllocator.access(aStorage) ) = nValue; + aResult.longValue = aStorage; + } + break; + + case Type::value_double: + { + double dValue; + OSL_VERIFY(_aAny >>= dValue); + + Address aStorage = _anAllocator.allocate( sizeof dValue ); + *static_cast<double*>( _anAllocator.access(aStorage) ) = dValue; + aResult.doubleValue = aStorage; + } + break; + + case Type::value_binary: + { + uno::Sequence<sal_Int8> aValue; + OSL_VERIFY(_aAny >>= aValue); + aResult.binaryValue = allocBinary(_anAllocator,aValue); + } + break; + + case Type::value_any: + OSL_ENSURE( false, "Trying to allocate void value" ); + break; + + default: + OSL_ENSURE( false, "Invalid type code" ); + break; + } + + return aResult; +} +//----------------------------------------------------------------------------- + +template <class E> +inline +sal_Sequence const * extractSequenceData(uno::Sequence< E > & _rSeq, uno::Any const & _aAny) +{ + if (_aAny >>= _rSeq) + { + return _rSeq.get(); + } + + else + { + OSL_ENSURE(false, "Could not extract sequence from Any"); + return NULL; + } +} +//----------------------------------------------------------------------------- + +static +AnyData allocSequenceData(memory::Allocator const& _anAllocator, TypeCode _aSimpleType, uno::Any const & _aAny) +{ + OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" ); + + Sequence aSequence = 0; + + switch (_aSimpleType) + { + case Type::value_string: + { + uno::Sequence<rtl::OUString> aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_boolean: + { + uno::Sequence<sal_Bool> aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_short: + { + uno::Sequence<sal_Int16> aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_int: + { + uno::Sequence<sal_Int32> aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_long: + { + uno::Sequence<sal_Int64> aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_double: + { + uno::Sequence<double> aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_binary: + { + uno::Sequence<uno::Sequence<sal_Int8> > aSeqValue; + if (sal_Sequence const * pData = extractSequenceData(aSeqValue,_aAny)) + aSequence = allocSequence(_anAllocator,_aSimpleType,pData); + } + break; + + case Type::value_any: // results from value_invalid + default: + OSL_ENSURE( false, "Invalid type code" ); + break; + } + + AnyData aResult; + aResult.sequenceValue = aSequence; + return aResult; +} +//----------------------------------------------------------------------------- + +AnyData allocData(memory::Allocator const& _anAllocator, TypeCode _aType, uno::Any const & _aAny) +{ + OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" ); + OSL_ENSURE( _aType == getTypeCode(_aAny.getValueType()), "Type code does not match value" ); + + if (_aType & Type::flag_sequence) + return allocSequenceData(_anAllocator,_aType & Type::mask_basetype,_aAny); + + else + return allocSimpleData(_anAllocator,_aType,_aAny); +} +//----------------------------------------------------------------------------- +/* +AnyData copyData(memory::Allocator const& _anAllocator, TypeCode _aType, AnyData _aData) +{ + OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" ); +} +*/ +//----------------------------------------------------------------------------- + +static +void freeSimpleData(memory::Allocator const& _anAllocator, TypeCode _aSimpleType, AnyData const & _aData) +{ + OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" ); + + switch (_aSimpleType) + { + case Type::value_string: + freeString(_anAllocator, _aData.stringValue); + break; + + case Type::value_boolean: + case Type::value_short: + case Type::value_int: + // nothing to do + break; + + // free memory for oversized values + case Type::value_long: + _anAllocator.deallocate(_aData.longValue); + break; + + case Type::value_double: + _anAllocator.deallocate(_aData.doubleValue); + break; + + case Type::value_binary: + freeBinary(_anAllocator, _aData.binaryValue); + break; + + case Type::value_any: + // nothing to do for void value + break; + + default: + OSL_ENSURE( false, "Invalid type code" ); + break; + } +} +//----------------------------------------------------------------------------- + +void freeData(memory::Allocator const& _anAllocator, TypeCode _aType, AnyData _aData) +{ + OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" ); + + if (_aType & Type::flag_sequence) + freeSequence(_anAllocator,_aType & Type::mask_basetype,_aData.sequenceValue); + + else + freeSimpleData(_anAllocator,_aType,_aData); +} +//----------------------------------------------------------------------------- + +static +uno::Any readSimpleData(memory::Accessor const& _anAccessor, TypeCode _aSimpleType, AnyData const & _aData) +{ + OSL_ENSURE( _aSimpleType == (_aSimpleType & Type::mask_basetype), "Invalid type code" ); + + switch (_aSimpleType) + { + case Type::value_string: + { + rtl::OUString sValue = readString(_anAccessor,_aData.stringValue); + return uno::makeAny(sValue); + } + + case Type::value_boolean: + return uno::makeAny( _aData.boolValue ); + + case Type::value_short: + return uno::makeAny( _aData.shortValue ); + + case Type::value_int: + return uno::makeAny( _aData.intValue ); + + case Type::value_long: + { + void const * pStorage = _anAccessor.validate( Pointer(_aData.longValue) ); + sal_Int64 const * pValue = static_cast<sal_Int64 const *>(pStorage); + return uno::makeAny( *pValue ); + } + + case Type::value_double: + { + void const * pStorage = _anAccessor.validate( Pointer(_aData.doubleValue) ); + double const * pValue = static_cast<double const *>(pStorage); + return uno::makeAny( *pValue ); + } + + case Type::value_binary: + { + uno::Sequence<sal_Int8> aValue = readBinary( _anAccessor, _aData.binaryValue ); + return uno::makeAny( aValue ); + } + + case Type::value_any: // void value + return uno::Any(); + + default: + OSL_ENSURE( false, "Invalid type code" ); + return uno::Any(); + } +} +//----------------------------------------------------------------------------- + +uno::Any readData(memory::Accessor const& _anAccessor, TypeCode _aType, AnyData _aData) +{ + OSL_ENSURE( _aType == (_aType & Type::mask_valuetype), "Invalid type code" ); + + if (_aType & Type::flag_sequence) + return readAnySequence(_anAccessor,_aType & Type::mask_basetype,_aData.sequenceValue); + + else + return readSimpleData(_anAccessor,_aType,_aData); + + return uno::Any(); +} + +//----------------------------------------------------------------------------- + } +//----------------------------------------------------------------------------- +} // namespace + diff --git a/configmgr/source/data/makefile.mk b/configmgr/source/data/makefile.mk new file mode 100644 index 000000000000..99ef64131713 --- /dev/null +++ b/configmgr/source/data/makefile.mk @@ -0,0 +1,95 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1 $ +# +# last change: $Author: jb $ $Date: 2002-02-11 14:55:52 $ +# +# 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): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/.. +PRJINC=$(PRJ)$/source +PRJNAME=configmgr +TARGET=data + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/version.mk + +# --- Files ------------------------------------- + +SLOFILES= \ + $(SLO)$/simpleheap.obj \ + $(SLO)$/heap.obj \ + $(SLO)$/segmentheap.obj \ + $(SLO)$/sequence.obj \ + $(SLO)$/anydata.obj \ + $(SLO)$/sequence.obj \ + $(SLO)$/types.obj \ + $(SLO)$/accessor.obj \ + $(SLO)$/updateaccessor.obj \ + +.IF "$(OS)"=="MACOSX" +SYMBOLPREFIX=$(CFGMGR_TARGET)$(CFGMGR_MAJOR) +.ENDIF + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + diff --git a/configmgr/source/data/sequence.cxx b/configmgr/source/data/sequence.cxx new file mode 100644 index 000000000000..bff935fb1594 --- /dev/null +++ b/configmgr/source/data/sequence.cxx @@ -0,0 +1,534 @@ +/************************************************************************* + * + * $RCSfile: sequence.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:52 $ + * + * 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 "sequence.hxx" + +#ifndef INCLUDED_DATA_FLAGS_HXX +#include "flags.hxx" +#endif +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif + +#ifndef INCLUDED_ALGORITHM +#include <algorithm> +#define INCLUDED_ALGORITHM +#endif + +#ifndef INCLUDED_STRING_H +#include <string.h> +#define INCLUDED_STRING_H +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace sharable + { +//----------------------------------------------------------------------------- + namespace Type = data::Type; + namespace uno = ::com::sun::star::uno; + typedef AnyData::TypeCode TypeCode; + using memory::Allocator; + using memory::Accessor; + using memory::Pointer; +//----------------------------------------------------------------------------- +static +sal_uInt32 implGetElementSize(TypeCode _aElementType) +{ + OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + switch (_aElementType) + { + + case Type::value_boolean: return sizeof(sal_Bool); + + case Type::value_short: return sizeof(sal_Int16); + + case Type::value_int: return sizeof(sal_Int32); + + case Type::value_long: return sizeof(sal_Int64); + + case Type::value_double: return sizeof(double); + + case Type::value_string: return sizeof(String); + + case Type::value_binary: return sizeof(Vector); + + case Type::value_any: // results from value_invalid + default: + OSL_ENSURE( false, "Invalid type code" ); + return 0; + } +} + +//----------------------------------------------------------------------------- +static inline +sal_uInt32 implGetHeaderSize(sal_uInt32 _nElemSize) +{ + // pad header to elem size, if larger (for safe alignment) + OSL_ASSERT(_nElemSize > sizeof(sal_Int32) || sizeof(sal_Int32) % _nElemSize== 0); + return _nElemSize > sizeof(sal_Int32) ? _nElemSize : sizeof(sal_Int32); +} + +//----------------------------------------------------------------------------- +static +inline +sal_Int32& implGetSize(Allocator const& _anAllocator, Sequence _aSeq) +{ + OSL_ASSERT(_aSeq != 0); + void * pBase = _anAllocator.access(_aSeq); + return * static_cast<sal_Int32 *>(pBase); +} + +//----------------------------------------------------------------------------- +static +inline +sal_Int32 implGetSize(Accessor const& _anAccessor, Sequence _aSeq) +{ + OSL_ASSERT(_aSeq != 0); + void const * pBase = _anAccessor.access( Pointer(_aSeq) ); + return * static_cast<sal_Int32 const *>(pBase); +} + +//----------------------------------------------------------------------------- +static +Sequence implSeqAlloc(Allocator const& _anAllocator, sal_Int32 _nElements, sal_uInt32 _nElemSize) +{ + sal_uInt32 nTotalSize = implGetHeaderSize(_nElemSize) + _nElements * _nElemSize; + + Sequence aResult = _anAllocator.allocate(nTotalSize); + + implGetSize(_anAllocator,aResult) = _nElements; + + return aResult; +} + +//----------------------------------------------------------------------------- + +static +void allocSeqData(Allocator const& _anAllocator, Address _aDestAddr, + TypeCode _aElementType, + sal_Int32 _nElements, sal_uInt32 _nElementSize, + void const * _pSourceData) +{ + OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + OSL_ASSERT(_nElementSize == implGetElementSize(_aElementType)); + switch (_aElementType) + { + case Type::value_boolean: + case Type::value_short: + case Type::value_int: + case Type::value_long: + case Type::value_double: + ::memcpy(_anAllocator.access(_aDestAddr),_pSourceData,_nElements * _nElementSize); + break; + + case Type::value_string: + { + OSL_ASSERT(_nElementSize == sizeof(String)); + + rtl::OUString const * pSource = static_cast<rtl::OUString const *>(_pSourceData); + + while (--_nElements >= 0) + { + String aElement = allocString(_anAllocator,*pSource); + + String * pDest = static_cast<String*>( _anAllocator.access(_aDestAddr) ); + *pDest = aElement; + + ++pSource; + _aDestAddr += sizeof *pDest; + } + } + break; + + case Type::value_binary: + { + OSL_ASSERT(_nElementSize == sizeof(Vector)); + + typedef uno::Sequence< sal_Int8 > BinSequence; + BinSequence const * pSource = static_cast<BinSequence const *>(_pSourceData); + + while (--_nElements >= 0) + { + Vector aElement = allocBinary(_anAllocator,*pSource); + + Vector * pDest = static_cast<Vector*>( _anAllocator.access(_aDestAddr) ); + *pDest = aElement; + + ++pSource; + _aDestAddr += sizeof *pDest; + } + } + break; + + case Type::value_any: + default: + OSL_ENSURE(false, "Invalid element type"); + break; + } +} + +//----------------------------------------------------------------------------- +Sequence allocSequence(Allocator const& _anAllocator, TypeCode _aElementType, ::sal_Sequence const * _pSeqData) +{ + OSL_ENSURE(_aElementType == (_aElementType & Type::mask_valuetype), "Invalid type code"); + + OSL_ENSURE(_pSeqData, "ERROR: Trying to allocate from a NULL sequence"); + if (_pSeqData == NULL) return 0; + + // OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + _aElementType &= Type::mask_basetype; + + sal_uInt32 const nElementSize = implGetElementSize(_aElementType); + sal_Int32 const nElements = _pSeqData->nElements; + + Sequence aResult = implSeqAlloc(_anAllocator,nElements,nElementSize); + + if (aResult) + allocSeqData( _anAllocator, aResult + implGetHeaderSize(nElementSize), + _aElementType, nElements, nElementSize, + _pSeqData->elements); + + return aResult; +} + +//----------------------------------------------------------------------------- +Sequence allocBinary(Allocator const& _anAllocator, uno::Sequence<sal_Int8> const & _aBinaryValue) +{ + sal_uInt32 const nElementSize = 1; + sal_Int32 const nLength = _aBinaryValue.getLength(); + + Sequence aResult = implSeqAlloc(_anAllocator,nLength,nElementSize); + + if (aResult) + { + Address aElementBaseAddr = aResult + implGetHeaderSize(nElementSize); + ::memcpy(_anAllocator.access(aElementBaseAddr), _aBinaryValue.getConstArray(), nLength); + } + + return aResult; +} + +//----------------------------------------------------------------------------- +// Sequence copySequence(Allocator const& _anAllocator, TypeCode _aElementType, Sequence _aSeq) + +//----------------------------------------------------------------------------- +// Sequence copyBinary(Allocator const& _anAllocator, Sequence _aSeq) + +//----------------------------------------------------------------------------- +static +void freeSeqData(Allocator const& _anAllocator, Address _aDataAddr, + TypeCode _aElementType, sal_Int32 _nElements) +{ + OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + + switch (_aElementType) + { + case Type::value_boolean: + case Type::value_short: + case Type::value_int: + case Type::value_long: + case Type::value_double: + // nothing to do + break; + + case Type::value_string: + { + String * pElements = static_cast<String*>( _anAllocator.access(_aDataAddr) ); + + for (sal_Int32 i = 0; i < _nElements; ++i) + { + freeString(_anAllocator,pElements[i]); + } + } + break; + + case Type::value_binary: + { + Vector * pElements = static_cast<Vector*>( _anAllocator.access(_aDataAddr) ); + + for (sal_Int32 i = 0; i < _nElements; ++i) + { + freeBinary(_anAllocator,pElements[i]); + } + } + break; + + case Type::value_any: + default: + OSL_ENSURE(false, "Invalid element type"); + break; + } +} + +//----------------------------------------------------------------------------- +void freeSequence(Allocator const& _anAllocator, TypeCode _aElementType, Sequence _aSeq) +{ + OSL_ENSURE(_aElementType == (_aElementType & Type::mask_valuetype), "Invalid type code"); + + OSL_ENSURE(_aSeq, "ERROR: Trying to free a NULL sequence"); + if (_aSeq == 0) return; + + // OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + _aElementType &= Type::mask_basetype; + + sal_uInt32 nHeaderSize = implGetHeaderSize( implGetElementSize( _aElementType ) ); + + freeSeqData(_anAllocator,_aSeq + nHeaderSize, _aElementType, implGetSize(_anAllocator,_aSeq)); + + _anAllocator.deallocate(_aSeq); +} + +//----------------------------------------------------------------------------- +void freeBinary(memory::Allocator const& _anAllocator, Sequence _aSeq) +{ + OSL_ENSURE(_aSeq, "ERROR: Trying to free a NULL sequence"); + if (_aSeq == 0) return; + + _anAllocator.deallocate(_aSeq); +} + +//----------------------------------------------------------------------------- + +static inline +sal_Sequence * implCreateSequence(void const * _pElements, TypeCode _aElementType, sal_Int32 _nElements) +{ + uno::Type aUnoType = getUnoType( _aElementType | Type::flag_sequence ); + + sal_Sequence * pResult = NULL; + ::uno_type_sequence_construct( &pResult, aUnoType.getTypeLibType(), + const_cast< void * >( _pElements ), + _nElements, NULL ); + + OSL_ASSERT(pResult->nRefCount == 1); + return pResult; +} + +//----------------------------------------------------------------------------- +static +sal_Sequence * readSeqData(Accessor const & _anAccessor, Address _aDataAddr, TypeCode _aElementType, sal_Int32 _nElements) +{ + OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + + void const * pElementData = _anAccessor.validate( Pointer(_aDataAddr) ); + switch (_aElementType) + { + case Type::value_boolean: + case Type::value_short: + case Type::value_int: + case Type::value_long: + case Type::value_double: + return implCreateSequence(pElementData,_aElementType,_nElements); + + case Type::value_string: + { + uno::Sequence<rtl::OUString> aResult(_nElements); + rtl::OUString * pResult = aResult.getArray(); + + String const * pElements = static_cast<String const *>( pElementData ); + + for (sal_Int32 i = 0; i < _nElements; ++i) + { + pResult[i] = readString(_anAccessor,pElements[i]); + } + + sal_Sequence * pRet = aResult.get(); + ++pRet->nRefCount; + return pRet; + } + + case Type::value_binary: + { + typedef uno::Sequence< sal_Int8 > BinSequence; + + uno::Sequence<BinSequence> aResult(_nElements); + BinSequence * pResult = aResult.getArray(); + + Vector const * pElements = static_cast<Vector const *>( pElementData ); + + for (sal_Int32 i = 0; i < _nElements; ++i) + { + pResult[i] = readBinary(_anAccessor,pElements[i]); + } + + sal_Sequence * pRet = aResult.get(); + ++pRet->nRefCount; + return pRet; + } + break; + + case Type::value_any: + default: + OSL_ENSURE(false, "Invalid element type"); + return NULL; + } +} + +//----------------------------------------------------------------------------- + +::sal_Sequence * readSequence(Accessor const& _anAccessor, TypeCode _aElementType, Sequence _aSeq) +{ + OSL_ENSURE(_aElementType == (_aElementType & Type::mask_valuetype), "Invalid type code"); + + OSL_ENSURE(_aSeq, "ERROR: Trying to read from a NULL sequence"); + if (_aSeq == 0) return NULL; + + // OSL_ASSERT(_aElementType == (_aElementType & Type::mask_basetype)); + _aElementType &= Type::mask_basetype; + + sal_uInt32 nHeaderSize = implGetHeaderSize( implGetElementSize( _aElementType ) ); + + return readSeqData(_anAccessor,_aSeq + nHeaderSize, _aElementType, implGetSize(_anAccessor,_aSeq)); +} + +//----------------------------------------------------------------------------- +uno::Any readAnySequence(Accessor const& _anAccessor, TypeCode _aElementType, Sequence _aSeq) +{ + sal_Sequence * pRawSequence = readSequence(_anAccessor, _aElementType, _aSeq); + + uno::Any aResult; + + if (pRawSequence != NULL) + switch (_aElementType & Type::mask_basetype) + { + case Type::value_string: + { + uno::Sequence< rtl::OUString > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_boolean: + { + uno::Sequence< sal_Bool > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_short: + { + uno::Sequence< sal_Int16 > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_int: + { + uno::Sequence< sal_Int32 > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_long: + { + uno::Sequence< sal_Int64 > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_double: + { + uno::Sequence< double > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_binary: + { + uno::Sequence< uno::Sequence< sal_Int8 > > aSequence(pRawSequence,SAL_NO_ACQUIRE); + aResult <<=aSequence ; + } + break; + + case Type::value_any: // from value_invalid ?? + default: + OSL_ENSURE( false, "Invalid type code" ); + break; + } + + OSL_ASSERT(!aResult.hasValue() || aResult.getValueType() == getUnoType(_aElementType | Type::flag_sequence)); + + return aResult; +} + +//----------------------------------------------------------------------------- +uno::Sequence<sal_Int8> readBinary(Accessor const& _anAccessor, Sequence _aSeq) +{ + OSL_ENSURE(_aSeq, "ERROR: Trying to read from a NULL sequence"); + if (_aSeq == 0) return NULL; + + sal_Int32 const nElements = implGetSize(_anAccessor,_aSeq); + + void const * const pElementData = _anAccessor.validate( Pointer(_aSeq + implGetHeaderSize(1)) ); + + sal_Int8 const * const pBinaryData = static_cast<sal_Int8 const *>(pElementData); + + uno::Sequence< sal_Int8 > aSequence(pBinaryData,nElements); + + return aSequence; +} + +//----------------------------------------------------------------------------- + } +//----------------------------------------------------------------------------- +} // namespace + diff --git a/configmgr/source/tree/builddata.cxx b/configmgr/source/tree/builddata.cxx new file mode 100644 index 000000000000..ceeb80796c67 --- /dev/null +++ b/configmgr/source/tree/builddata.cxx @@ -0,0 +1,1298 @@ +/************************************************************************* + * + * $RCSfile: builddata.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "builddata.hxx" + +#ifndef CONFIGMGR_TREEADDRESS_HXX +#include "treeaddress.hxx" +#endif +#ifndef CONFIGMGR_TREEACCESSOR_HXX +#include "treeaccessor.hxx" +#endif +#ifndef CONFIGMGR_ACCESSOR_HXX +#include "accessor.hxx" +#endif +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif + +#ifndef CONFIGMGR_NODEACCESS_HXX +#include "nodeaccess.hxx" +#endif +#ifndef CONFIGMGR_SETNODEACCESS_HXX +#include "setnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_VALUENODEACCESS_HXX +#include "valuenodeaccess.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEACCESS_HXX +#include "groupnodeaccess.hxx" +#endif + +#ifndef CONFIGMGR_NODEVISITOR_HXX +#include "nodevisitor.hxx" +#endif + +#ifndef INCLUDED_SHARABLE_NODE_HXX +#include "node.hxx" +#endif +#ifndef INCLUDED_SHARABLE_TREEFRAGMENT_HXX +#include "treefragment.hxx" +#endif + +#ifndef _CONFIGMGR_TREE_VALUENODE_HXX +#include "valuenode.hxx" +#endif +#ifndef CONFIGMGR_TREE_NODEFACTORY_HXX +#include "treenodefactory.hxx" +#endif + +#ifndef INCLUDED_CSTDDEF +#include <cstddef> +#define INCLUDED_CSTDDEF +#endif +#ifndef INCLUDED_ALGORITHM +#include <algorithm> +#define INCLUDED_ALGORITHM +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace data + { + //------------------------------------------------------------------------- + using namespace sharable; + using memory::Pointer; + using memory::Accessor; + using memory::Allocator; + using memory::UpdateAccessor; +//----------------------------------------------------------------------------- + + static + inline + NodeAddress offsetNodeBy(NodeAddress _aNode, Offset _nOffset) + { + Address aRawAddr = _aNode.addressValue() + _nOffset * sizeof(Node); + + return NodeAddress(Pointer(aRawAddr)); + } + + static + inline + NodeAddress addressOfNodeAt(TreeAddress _aTree, Offset _nOffset) + { + Address aRawAddr = _aTree.addressValue() + + offsetof(TreeFragment,nodes) + + _nOffset * sizeof(Node); + + return NodeAddress(Pointer(aRawAddr)); + } + +//----------------------------------------------------------------------------- + + class TreeNodeBuilder + { + TreeFragmentHeader m_header; + std::vector< Node > m_nodes; + Offset m_parent; + public: + TreeNodeBuilder() : m_header(), m_nodes(), m_parent() {} + + TreeFragmentHeader & header() { return m_header; } + + Node & nodeAt(Offset _pos) { checkOffset(_pos); return m_nodes[_pos]; } + NodeInfo & nodeInfoAt(Offset _pos) { checkOffset(_pos); return m_nodes[_pos].node.info; } + + Node & lastNode() { checkOffset(0); return m_nodes.back(); } + NodeInfo & lastNodeInfo() { checkOffset(0); return m_nodes.back().node.info; } + + void resetTreeFragment(); + void resetTreeFragment(sharable::String _treeName, State::Field _state); + + TreeAddress createTreeFragment(UpdateAccessor & _anUpdater); + + Offset startGroup( Name _aName, Flags::Field _aFlags ); + void endGroup( Offset _nPos ); + + void addSet( Name _aName, Flags::Field _aFlags, Address _aElementType ); + + void addValue( Name _aName, Flags::Field _aFlags, + AnyData::TypeCode _aValueType, + AnyData _aUserValue, + AnyData _aDefaultName ); + public: + class CollectSetElements; + class LinkSetNodes; + + private: + TreeAddress allocTreeFragment(UpdateAccessor & _anUpdater); + void linkTreeFragment(UpdateAccessor & _anUpdater, TreeAddress _aTreeAddr); + + Offset addNode(Name _aName, Flags::Field _aFlags, Type::Field _aType); + void checkOffset(Offset _pos); + }; +//----------------------------------------------------------------------------- + + class TreeNodeBuilder::CollectSetElements + { + UpdateAccessor & m_updater; + TreeAddress m_head; + public: + explicit + CollectSetElements(UpdateAccessor & _anUpdater) + : m_updater(_anUpdater) + { + } + + void resetElementList(); + void addElement(TreeAddress _aNewElement); + List getElementListAndClear(); + + UpdateAccessor & updater() const { return m_updater; } + }; +//----------------------------------------------------------------------------- + + class TreeNodeBuilder::LinkSetNodes : private SetVisitor + { + UpdateAccessor & m_updater; + NodeAddress m_aParentAddr; + public: + explicit + TreeNodeBuilder::LinkSetNodes(UpdateAccessor & _anUpdater) + : m_updater(_anUpdater) + , m_aParentAddr() + { + } + + Result linkTree(TreeAddress const & _aFragment); + Result linkSet(SetNodeAccess const & _aSet); + private: + Result handle(TreeAccessor const & _aElement); + Result handle(SetNodeAccess const & _aSet); + }; +//----------------------------------------------------------------------------- + + class BasicDataTreeBuilder + { + public: + explicit + BasicDataTreeBuilder(UpdateAccessor & _anUpdater) + : m_updater(_anUpdater) + {} + + TreeAddress createTree() { return m_builder.createTreeFragment(m_updater); } + + protected: + TreeNodeBuilder& builder() { return m_builder; } + UpdateAccessor & updater() const { return m_updater; } + Accessor accessor() const { return m_updater.accessor(); } + Allocator allocator() const { return m_updater.allocator(); } + private: + UpdateAccessor & m_updater; + TreeNodeBuilder m_builder; + }; +//----------------------------------------------------------------------------- + + class ConvertingDataTreeBuilder : private NodeAction, public BasicDataTreeBuilder + { + rtl::OUString m_sRootName; + bool m_bWithDefaults; + public: + explicit + ConvertingDataTreeBuilder(UpdateAccessor & _anUpdater) + : BasicDataTreeBuilder(_anUpdater) + {} + + TreeAddress buildTree(OUString const & _aTreeName, INode const& _aNode, bool _bWithDefault); + TreeAddress buildElement(INode const& _aNode, OUString const & _aTypeName, bool _bWithDefault); + private: + class ElementListBuilder; + + virtual void handle(ISubtree const & _aNode); + virtual void handle(ValueNode const & _aNode); + + Address makeTemplateData(rtl::OUString const & _aTemplateName, rtl::OUString const & _aTemplateModule); + + Name allocName(INode const & _aNode); + State::Field makeState(node::Attributes const & _aAttributes); + Flags::Field makeFlags(node::Attributes const & _aAttributes); + }; +//----------------------------------------------------------------------------- + + class ConvertingDataTreeBuilder::ElementListBuilder : private NodeAction + { + TreeNodeBuilder::CollectSetElements m_aCollector; + + rtl::OUString m_sTypeName; + bool m_bWithDefaults; + public: + explicit + ElementListBuilder(UpdateAccessor & _anUpdater) + : m_aCollector(_anUpdater) + , m_sTypeName() + , m_bWithDefaults() + {} + + List buildElementList(ISubtree const & _aSet, bool _bWithDefaults); + private: + void handleNode(INode const & _aSourceNode); + + void handle(ValueNode const & _aSourceNode); + void handle(ISubtree const & _aSourceNode); + }; +//----------------------------------------------------------------------------- + + class CopyingDataTreeBuilder : private NodeVisitor, public BasicDataTreeBuilder + { + public: + explicit + CopyingDataTreeBuilder(UpdateAccessor & _anUpdater) + : BasicDataTreeBuilder(_anUpdater) + {} + + TreeAddress buildTree(TreeAccessor const & _aSourceTree); + private: + class ElementListBuilder; + + Result handle(ValueNodeAccess const & _aNode); + Result handle(GroupNodeAccess const & _aNode); + Result handle(SetNodeAccess const & _aNode); + + Address makeTemplateData(Accessor const & _aSourceAccessor, Address _aSourceTemplate); + }; +//----------------------------------------------------------------------------- + + class CopyingDataTreeBuilder::ElementListBuilder : private SetVisitor + { + TreeNodeBuilder::CollectSetElements m_aCollector; + public: + explicit + ElementListBuilder(UpdateAccessor & _anUpdater) + : m_aCollector(_anUpdater) + {} + + List buildElementList(SetNodeAccess const & _aSet); + private: + Result handle(TreeAccessor const & _aSourceTree); + }; +//----------------------------------------------------------------------------- + + class ConvertingNodeBuilder : private NodeVisitor + { + OTreeNodeFactory & m_rNodeFactory; + + std::auto_ptr<INode> m_pNode; + public: + ConvertingNodeBuilder(OTreeNodeFactory & _rNodeFactory) + : m_rNodeFactory(_rNodeFactory) + , m_pNode() + { + } + + std::auto_ptr<INode> buildNode(TreeAccessor const& _aTree, bool _bUseTreeName); + std::auto_ptr<INode> buildNode(NodeAccess const& _aTree); + + std::auto_ptr<ISubtree> buildNodeTree(GroupNodeAccess const& _aGroupNode) const; + std::auto_ptr<ISubtree> buildNodeTree(SetNodeAccess const& _aSetNode) const; + std::auto_ptr<ValueNode> buildNode(ValueNodeAccess const& _aValueNode) const + { return this->convertNode(_aValueNode); } + + static node::Attributes convertAttributes(NodeAccess const& _aNode) + { return _aNode.getAttributes(); } + private: + std::auto_ptr<ISubtree> convertNode(GroupNodeAccess const& _aGroupNode) const; + std::auto_ptr<ISubtree> convertNode(SetNodeAccess const& _aSetNode) const; + std::auto_ptr<ValueNode> convertNode(ValueNodeAccess const& _aValueNode) const; + + Result handle(ValueNodeAccess const & _aNode); + Result handle(GroupNodeAccess const & _aNode); + Result handle(SetNodeAccess const & _aNode); + }; +//----------------------------------------------------------------------------- + + class ConvertingSubnodeBuilder : private SetVisitor + { + ConvertingNodeBuilder m_aSubnodeBuilder; + ISubtree & m_rParentNode; + public: + ConvertingSubnodeBuilder(OTreeNodeFactory & _rNodeFactory, ISubtree & _rParentNode) + : m_aSubnodeBuilder(_rNodeFactory) + , m_rParentNode(_rParentNode) + { + } + + void addElements(SetNodeAccess const & _aSet) { this->visitElements(_aSet); } + void addChildren(GroupNodeAccess const & _aGroup) { this->visitChildren(_aGroup); } + private: + Result handle(TreeAccessor const & _aElement); + Result handle(NodeAccess const & _aMember); + }; +//----------------------------------------------------------------------------- + + class DataTreeDefaultMerger : private NodeAction + { + public: + explicit + DataTreeDefaultMerger(UpdateAccessor & _anUpdater) + : m_updater(_anUpdater) + {} + + void mergeDefaults(TreeAddress _aBaseAddress, INode const& _aDefaultNode); + private: + void handle(ValueNode const & _aNode); + void handle(ISubtree const & _aNode); + protected: + UpdateAccessor & updater() const { return m_updater; } + Accessor accessor() const { return m_updater.accessor(); } + Allocator allocator() const { return m_updater.allocator(); } + private: + UpdateAccessor & m_updater; + }; + +//----------------------------------------------------------------------------- + + class DataTreeCleanup + { + public: + explicit + DataTreeCleanup(UpdateAccessor & _anUpdater) + : m_updater(_anUpdater) + {} + + TreeAddress destroyTree(TreeAddress _aBaseAddress); + private: + void destroyNode(NodeAddress _aNodeAddress); + + void destroyData(TreeFragmentHeader * _pHeader); + void destroyData(NodeInfo * _pNodeInfo); + + void destroyData(sharable::GroupNode * _pNode); + void destroyData(sharable::ValueNode * _pNode); + void destroyData(sharable::SetNode * _pNode); + private: + UpdateAccessor & updater() const { return m_updater; } + Accessor accessor() const { return m_updater.accessor(); } + Allocator allocator() const { return m_updater.allocator(); } + private: + UpdateAccessor & m_updater; + }; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +TreeAddress buildTree(memory::UpdateAccessor& _aTargetMemory, TreeAccessor const& _aTree) +{ + CopyingDataTreeBuilder aBuilder(_aTargetMemory); + + TreeAddress aResult = aBuilder.buildTree(_aTree); + + return aResult; +} +//----------------------------------------------------------------------------- + +TreeAddress buildTree(memory::UpdateAccessor& _aTargetMemory, rtl::OUString const & _aTreeName, INode const& _aNode, bool _bWithDefaults) +{ + ConvertingDataTreeBuilder aBuilder(_aTargetMemory); + + TreeAddress aResult = aBuilder.buildTree(_aTreeName, _aNode,_bWithDefaults); + + return aResult; +} +//----------------------------------------------------------------------------- + +TreeAddress buildElementTree(memory::UpdateAccessor& _aTargetMemory, INode const& _aNode, rtl::OUString const & _aTypeName, bool _bWithDefaults) +{ + ConvertingDataTreeBuilder aBuilder(_aTargetMemory); + + TreeAddress aResult = aBuilder.buildElement(_aNode, _aTypeName, _bWithDefaults); + + return aResult; +} +//----------------------------------------------------------------------------- + +void mergeDefaults(memory::UpdateAccessor& _aTargetMemory, TreeAddress _aBaseAddress, INode const& _aDefaultNode) +{ + DataTreeDefaultMerger aMergeHelper(_aTargetMemory); + + aMergeHelper.mergeDefaults(_aBaseAddress, _aDefaultNode); +} +//----------------------------------------------------------------------------- + +void destroyTree(memory::UpdateAccessor& _aTreeMemory, TreeAddress _aBaseAddress) +{ + DataTreeCleanup aCleaner(_aTreeMemory); + + aCleaner.destroyTree(_aBaseAddress); +} +//----------------------------------------------------------------------------- + +std::auto_ptr<INode> convertTree(TreeAccessor const & _aTree, bool _bUseTreeName) +{ + ConvertingNodeBuilder aBuilder( configmgr::getDefaultTreeNodeFactory() ); + + return aBuilder.buildNode(_aTree,_bUseTreeName); +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +inline +void TreeNodeBuilder::CollectSetElements::resetElementList() +{ + OSL_ENSURE(m_head.isNull(), "Joining to a element list that was forgotten"); +} +//----------------------------------------------------------------------------- + +inline +List TreeNodeBuilder::CollectSetElements::getElementListAndClear() +{ + List aResult = m_head.addressValue(); + m_head = TreeAddress(); + return aResult; +} +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::CollectSetElements::addElement(TreeAddress _aNewElement) +{ + if (TreeFragment * pNewFragment = TreeAccessor::access(_aNewElement,m_updater)) + { + pNewFragment->header.parent = 0; // data not available here + pNewFragment->header.next = m_head.addressValue(); + + m_head = _aNewElement; + } + else + OSL_ENSURE(false, "Cannot add NULL element"); +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +NodeVisitor::Result TreeNodeBuilder::LinkSetNodes::linkTree(TreeAddress const & _aTree) +{ + TreeAccessor aTreeAccess(m_updater.accessor(), _aTree); + + TreeFragment const & rTreeData = aTreeAccess.data(); + + NodeAddress aOldParent = m_aParentAddr; + m_aParentAddr = NodeAddress(); + + Result eResult = CONTINUE; + + Offset nCount = rTreeData.header.count; + for(Offset i=0; i < nCount; ++i) + { + NodeAccess aNode(aTreeAccess.accessor(),&rTreeData.nodes[i]); + eResult =this->visitNode( aNode ); + + if (eResult == DONE) break; + } + + m_aParentAddr = aOldParent; + + return eResult; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result TreeNodeBuilder::LinkSetNodes::linkSet(SetNodeAccess const & _aSet) +{ + OSL_ENSURE(m_aParentAddr.isNull(),"Linking set data already in progress"); + m_aParentAddr = _aSet.address(); + + Result aResult = this->visitElements(_aSet); + + m_aParentAddr = NodeAddress(); + + return aResult; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result TreeNodeBuilder::LinkSetNodes::handle(TreeAccessor const & _aSourceTree) +{ + OSL_ENSURE(m_aParentAddr.is(),"Cannot link set element without parent address"); + + TreeFragment * pFragment = _aSourceTree.access(_aSourceTree.address(), m_updater); + + pFragment->header.parent = m_aParentAddr.addressValue(); + + return CONTINUE; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result TreeNodeBuilder::LinkSetNodes::handle(SetNodeAccess const & _aNode) +{ + return this->linkSet(_aNode); +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +inline void TreeNodeBuilder::checkOffset(Offset _pos) +{ + OSL_ENSURE(_pos < m_nodes.size(), "TreeNodeBuilder: Node access past end."); +} +//----------------------------------------------------------------------------- + +Offset TreeNodeBuilder::addNode(Name _aName, Flags::Field _aFlags, Type::Field _aType) +{ + OSL_PRECOND(_aName, "TreeNodeBuilder: Unexpected NULL name"); + + // TODO: consistenc checks for flags + OSL_ENSURE(m_nodes.size() == m_header.count, "TreeNodeBuilder: node count mismatch"); + + Offset nNewOffset = m_header.count++; + + m_nodes.push_back( Node() ); + + OSL_ASSERT( &lastNode() == &nodeAt(nNewOffset) ); + + NodeInfo & rInfo = lastNode().node.info; + + rInfo.name = _aName; + rInfo.flags = _aFlags; + rInfo.type = _aType; + + OSL_ENSURE(0 <= m_parent && m_parent <= nNewOffset, "ERROR - TreeNodeBuilder: invalid parent"); + OSL_ENSURE( (nNewOffset == 0) == (nNewOffset == m_parent), "ERROR - TreeNodeBuilder: node is own parent"); + + rInfo.parent = nNewOffset - m_parent; + + return nNewOffset; +} +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::resetTreeFragment() +{ + State::Field nNullState = State::merged | State::flag_mandatory | State::flag_readonly; + this->resetTreeFragment(0,nNullState); +} +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::resetTreeFragment(sharable::String _name, State::Field _state) +{ + m_header.next = 0; + m_header.name = _name; + + m_header.parent = 0; + + m_header.count = 0; + m_header.state = _state; + + m_nodes.clear(); + m_parent = 0; +} +//----------------------------------------------------------------------------- + +TreeAddress TreeNodeBuilder::allocTreeFragment(UpdateAccessor & _anUpdater) +{ + OSL_ENSURE(m_nodes.size() == m_header.count, "TreeNodeBuilder: node count mismatch"); + + sal_uInt32 const nFragmentSize = sizeof(TreeFragment) + (m_header.count-1)*sizeof(Node); + + OSL_ASSERT(nFragmentSize >= sizeof m_header + m_header.count*sizeof(Node)); + + Address aBaseAddress = _anUpdater.allocator().allocate(nFragmentSize); + + TreeAddress aResult( static_cast<memory::Pointer>(aBaseAddress) ); + + if (TreeFragment * pFragment = TreeAccessor::access(aResult,_anUpdater)) + { + pFragment->header = m_header; + std::copy(m_nodes.begin(),m_nodes.end(),pFragment->nodes); + } + + return aResult; +} +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::linkTreeFragment(UpdateAccessor & _anUpdater, TreeAddress _aTreeFragment) +{ + LinkSetNodes(_anUpdater).linkTree(_aTreeFragment); +} +//----------------------------------------------------------------------------- + +TreeAddress TreeNodeBuilder::createTreeFragment(UpdateAccessor & _anUpdater) +{ + TreeAddress aResult = allocTreeFragment(_anUpdater); + + if (aResult.is()) + { + linkTreeFragment(_anUpdater,aResult); + + m_nodes.clear(); // ownership of indirect data has gone ... + } + return aResult; +} +//----------------------------------------------------------------------------- + +Offset TreeNodeBuilder::startGroup( Name _aName, Flags::Field _aFlags ) +{ + Offset nNewIndex = addNode(_aName,_aFlags,Type::nodetype_group); + + lastNode().group.numDescendants = 0; + + m_parent = nNewIndex; + + return nNewIndex; +} +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::endGroup( Offset _nPos ) +{ + // while (_nPos < m_parent) endGroup(m_parent); + OSL_PRECOND(_nPos == m_parent, "TreeNodeBuilder: Group being closed is not the current parent"); + + OSL_ENSURE(nodeAt(_nPos).isGroup(), "TreeNodeBuilder: Group being closed is not a group"); + + OSL_ENSURE(m_nodes.size() == m_header.count, "TreeNodeBuilder: node count mismatch"); + + GroupNode & rGroup = nodeAt(_nPos).group; + + rGroup.numDescendants = m_nodes.size() - _nPos - 1; + m_parent -= rGroup.info.parent; +} +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::addSet( Name _aName, Flags::Field _aFlags, Address _aElementType ) +{ + Offset nNewIndex = addNode(_aName,_aFlags,Type::nodetype_set); + + lastNode().set.elementType = _aElementType; + lastNode().set.elements = 0; +} + +//----------------------------------------------------------------------------- + +void TreeNodeBuilder::addValue( Name _aName, Flags::Field _aFlags, + AnyData::TypeCode _aValueType, + AnyData _aUserValue, + AnyData _aDefaultValue ) +{ + OSL_PRECOND(_aValueType == (_aValueType & Type::mask_valuetype), "TreeNodeBuilder: invalid value type"); + + Offset nNewIndex = addNode(_aName,_aFlags,Type::nodetype_value | _aValueType); + + lastNode().value.value = _aUserValue; + lastNode().value.defaultValue = _aDefaultValue; +} +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +TreeAddress CopyingDataTreeBuilder::buildTree(TreeAccessor const & _aSourceTree) +{ + OSL_ENSURE(_aSourceTree.isValid(), "Trying to build a tree from NULL data"); + if (!_aSourceTree.isValid()) return TreeAddress(); + + TreeFragment const & aSrc = _aSourceTree.data(); + + sharable::String aTreeName = allocString( allocator(), aSrc.getName(_aSourceTree.accessor())); + this->builder().resetTreeFragment(aTreeName, aSrc.header.state); + + this->visitNode(_aSourceTree.getRootNode()); + + return this->createTree(); +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result CopyingDataTreeBuilder::handle(ValueNodeAccess const & _aNode) +{ + sharable::ValueNode const & aSrc = _aNode.data(); + + sharable::Name aNodeName = allocName( allocator(), aSrc.info.getName(_aNode.accessor())); + Flags::Field aFlags = aSrc.info.flags; + + AnyData::TypeCode aType = aSrc.info.type & Type::mask_valuetype; + + AnyData aNewValue, aNewDefault; + if (aFlags & Flags::valueAvailable) + aNewValue = allocData(allocator(), aType, aSrc.getUserValue(_aNode.accessor())); + else + aNewValue.data = 0; + + if (aFlags & Flags::defaultAvailable) + aNewDefault = allocData(allocator(), aType, aSrc.getDefaultValue(_aNode.accessor())); + else + aNewDefault.data = 0; + + this->builder().addValue(aNodeName,aFlags,aType,aNewValue,aNewDefault); + + return CONTINUE; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result CopyingDataTreeBuilder::handle(GroupNodeAccess const & _aNode) +{ + sharable::GroupNode const & aSrc = _aNode.data(); + + sharable::Name aNodeName = allocName( allocator(), aSrc.info.getName(_aNode.accessor())); + Flags::Field aFlags = aSrc.info.flags; + + Offset nGroupOffset = this->builder().startGroup(aNodeName,aFlags); + this->visitChildren(_aNode); + this->builder().endGroup(nGroupOffset); + + return CONTINUE; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result CopyingDataTreeBuilder::handle(SetNodeAccess const & _aNode) +{ + sharable::SetNode const & aSrc = _aNode.data(); + + sharable::Name aNodeName = allocName( allocator(), aSrc.info.getName(_aNode.accessor())); + Flags::Field aFlags = aSrc.info.flags; + Address aTemplate = this->makeTemplateData(_aNode.accessor(), aSrc.elementType); + + this->builder().addSet(aNodeName,aFlags,aTemplate); + + OSL_ASSERT( this->builder().lastNode().isSet() ); + SetNode& _aNewSet = this->builder().lastNode().set; + + _aNewSet.elements = ElementListBuilder( this->updater() ).buildElementList(_aNode); + + return CONTINUE; +} +//----------------------------------------------------------------------------- + +Address CopyingDataTreeBuilder::makeTemplateData(Accessor const & _aSourceAccessor, Address _aSourceTemplate) +{ + NameChar const * pTemplateName = SetNode::getTemplateDataName(_aSourceAccessor,_aSourceTemplate); + NameChar const * pTemplateModule = SetNode::getTemplateDataModule(_aSourceAccessor,_aSourceTemplate); + + return SetNode::allocTemplateData(allocator(), pTemplateName, pTemplateModule ); +} +//----------------------------------------------------------------------------- + +List CopyingDataTreeBuilder::ElementListBuilder::buildElementList(SetNodeAccess const & _aSet) +{ + OSL_PRECOND(_aSet.isValid(), "Node must not be NULL"); + + m_aCollector.resetElementList(); + + this->visitElements(_aSet); + + return m_aCollector.getElementListAndClear(); +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result CopyingDataTreeBuilder::ElementListBuilder::handle(TreeAccessor const & _aSourceTree) +{ + TreeAddress aNewElement = CopyingDataTreeBuilder(m_aCollector.updater()).buildTree(_aSourceTree); + + m_aCollector.addElement(aNewElement); + + return CONTINUE; +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +Name ConvertingDataTreeBuilder::allocName(INode const & _aNode) +{ + rtl::OUString sNextName = _aNode.getName(); + + if (m_sRootName.getLength()) + { + sNextName = m_sRootName; + m_sRootName = rtl::OUString(); + } + + return sharable::allocName( allocator(), sNextName); +} +//----------------------------------------------------------------------------- + +TreeAddress ConvertingDataTreeBuilder::buildElement(INode const& _aNode, OUString const & _aTypeName, bool _bWithDefaults) +{ + m_sRootName = _aTypeName; + m_bWithDefaults = _bWithDefaults; + + sharable::String aTreeName = allocString( allocator(), _aNode.getName()); + this->builder().resetTreeFragment(aTreeName, makeState(_aNode.getAttributes())); + + + this->applyToNode(_aNode); + + return this->createTree(); +} +//----------------------------------------------------------------------------- + +TreeAddress ConvertingDataTreeBuilder::buildTree(OUString const & _aTreeName, INode const& _aNode, bool _bWithDefaults) +{ + m_sRootName = OUString(); + m_bWithDefaults = _bWithDefaults; + + sharable::String aTreeName = allocString( allocator(), _aTreeName ); + this->builder().resetTreeFragment(aTreeName, makeState(_aNode.getAttributes())); + + + this->applyToNode(_aNode); + + return this->createTree(); +} +//----------------------------------------------------------------------------- + +void ConvertingDataTreeBuilder::handle(ISubtree const & _aNode) +{ + sharable::Name aNodeName = allocName( _aNode ); + Flags::Field aFlags = makeFlags(_aNode.getAttributes()); + + if (_aNode.isSetNode()) + { + Address aTemplate = this->makeTemplateData(_aNode.getElementTemplateName(),_aNode.getElementTemplateModule()); + + this->builder().addSet(aNodeName,aFlags,aTemplate); + + OSL_ASSERT( this->builder().lastNode().isSet() ); + SetNode& _aNewSet = this->builder().lastNode().set; + + _aNewSet.elements = ElementListBuilder(this->updater()).buildElementList(_aNode, m_bWithDefaults); + } + else + { + Offset nGroupOffset = this->builder().startGroup(aNodeName,aFlags); + this->applyToChildren(_aNode); + this->builder().endGroup(nGroupOffset); + } +} +//----------------------------------------------------------------------------- + +void ConvertingDataTreeBuilder::handle(ValueNode const & _aNode) +{ + sharable::Name aNodeName = allocName( _aNode ); + Flags::Field aFlags = makeFlags(_aNode.getAttributes()); + + AnyData::TypeCode aType = getTypeCode(_aNode.getValueType()); + + AnyData aNewValue; aNewValue.data = 0; + AnyData aNewDefault; aNewDefault.data = 0; + + OSL_ASSERT( !(aFlags & (Flags::valueAvailable | Flags::defaultAvailable)) ); + + if (!_aNode.isDefault()) + { + uno::Any aValue = _aNode.getValue(); + if (aValue.hasValue()) + { + aNewValue = allocData(allocator(), aType, aValue); + aFlags |= Flags::valueAvailable; + } + } + + if (_aNode.hasUsableDefault()) + { + uno::Any aDefault = _aNode.getDefault(); + if (aDefault.hasValue()) + { + aNewDefault = allocData(allocator(), aType, aDefault); + aFlags |= Flags::defaultAvailable; + } + } + + this->builder().addValue(aNodeName,aFlags,aType,aNewValue,aNewDefault); +} +//----------------------------------------------------------------------------- + +State::Field ConvertingDataTreeBuilder::makeState(node::Attributes const & _aAttributes) +{ + State::Field state; + + switch (_aAttributes.state()) + { + case node::isDefault: state = State::defaulted; m_bWithDefaults = true; break; + case node::isMerged: state = State::merged; break; + case node::isReplaced: state = State::replaced; m_bWithDefaults = false; break; + case node::isAdded: state = State::added; m_bWithDefaults = false; break; + + default: OSL_ASSERT(false); state = 0; break; + } + + if (!_aAttributes.bWritable) + state |= State::flag_readonly; + + if ( m_bWithDefaults ) + state |= State::flag_default_avail; + + return state; +} +//----------------------------------------------------------------------------- + +Flags::Field ConvertingDataTreeBuilder::makeFlags(node::Attributes const & _aAttributes) +{ + Flags::Field flags = 0; + + if (!_aAttributes.bWritable) + flags |= Flags::readonly; + + if ( _aAttributes.bFinalized) + flags |= Flags::finalized; + + if ( _aAttributes.bNullable) + flags |= Flags::nullable; + + if ( _aAttributes.bLocalized) + flags |= Flags::localized; + + if (_aAttributes.isDefault()) + flags |= Flags::defaulted; // somewhat redundant with State + + if (!_aAttributes.isReplacedForUser()) + flags |= Flags::defaultable; // redundant with State (merged || defaulted) + + return flags; +} +//----------------------------------------------------------------------------- + +Address ConvertingDataTreeBuilder::makeTemplateData(rtl::OUString const & _aTemplateName, rtl::OUString const & _aTemplateModule) +{ + NameChar const * pTemplateName = _aTemplateName.getStr(); + NameChar const * pTemplateModule = _aTemplateModule.getStr(); + + return SetNode::allocTemplateData(allocator(), pTemplateName, pTemplateModule ); +} +//----------------------------------------------------------------------------- + +List ConvertingDataTreeBuilder::ElementListBuilder::buildElementList(ISubtree const & _aSet, bool _bWithDefaults) +{ + OSL_PRECOND(_aSet.isSetNode(), "Node must be a set"); + + m_aCollector.resetElementList(); + + m_sTypeName = _aSet.getElementTemplateName(); + m_bWithDefaults = _bWithDefaults; + + this->applyToChildren(_aSet); + + return m_aCollector.getElementListAndClear(); +} +//----------------------------------------------------------------------------- + +void ConvertingDataTreeBuilder::ElementListBuilder::handleNode(INode const & _aSourceNode) +{ + TreeAddress aNewElement = ConvertingDataTreeBuilder(m_aCollector.updater()) + .buildElement(_aSourceNode,m_sTypeName,m_bWithDefaults); + + m_aCollector.addElement(aNewElement); +} +//----------------------------------------------------------------------------- + +void ConvertingDataTreeBuilder::ElementListBuilder::handle(ValueNode const & _aSourceNode) +{ + handleNode(_aSourceNode); +} +//----------------------------------------------------------------------------- + +void ConvertingDataTreeBuilder::ElementListBuilder::handle(ISubtree const & _aSourceNode) +{ + handleNode(_aSourceNode); +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +std::auto_ptr<INode> ConvertingNodeBuilder::buildNode(TreeAccessor const & _aSourceTree, bool _bUseTreeName) +{ + std::auto_ptr<INode> pResult = this->buildNode(_aSourceTree.getRootNode()); + if (pResult.get != NULL) + { + // use the element name ! + if (_bUseTreeName) pResult->setName( _aSourceTree.getName().toString() ); + + // do something about attributes here ? + } + return pResult; +} +//----------------------------------------------------------------------------- + +std::auto_ptr<INode> ConvertingNodeBuilder::buildNode(NodeAccess const & _aSourceNode) +{ + OSL_ENSURE( !m_pNode.get(), "Old node tree will be dropped"); + this->visitNode(_aSourceNode); + return m_pNode; +} +//----------------------------------------------------------------------------- + +std::auto_ptr<ISubtree> ConvertingNodeBuilder::buildNodeTree(GroupNodeAccess const& _aGroupNode) const +{ + std::auto_ptr<ISubtree> pResult = convertNode(_aGroupNode); + + if (pResult.get() != NULL) + { + ConvertingSubnodeBuilder aCollector(m_rNodeFactory, *pResult); + aCollector.addChildren(_aGroupNode); + } + + return pResult; +} +//----------------------------------------------------------------------------- + +std::auto_ptr<ISubtree> ConvertingNodeBuilder::buildNodeTree(SetNodeAccess const& _aSetNode) const +{ + std::auto_ptr<ISubtree> pResult = convertNode(_aSetNode); + + if (pResult.get() != NULL) + { + ConvertingSubnodeBuilder aCollector(m_rNodeFactory, *pResult); + aCollector.addElements(_aSetNode); + } + + return pResult; +} +//----------------------------------------------------------------------------- + +std::auto_ptr<ISubtree> ConvertingNodeBuilder::convertNode(GroupNodeAccess const& _aGroupNode) const +{ + return m_rNodeFactory.createGroupNode( _aGroupNode.getName().toString(), + convertAttributes(_aGroupNode)); +} +//----------------------------------------------------------------------------- + +std::auto_ptr<ISubtree> ConvertingNodeBuilder::convertNode(SetNodeAccess const& _aSetNode) const +{ + return m_rNodeFactory.createSetNode(_aSetNode.getName().toString(), + _aSetNode.getElementTemplateName().toString(), + _aSetNode.getElementTemplateModule().toString(), + convertAttributes(_aSetNode)); +} +//----------------------------------------------------------------------------- + +std::auto_ptr<ValueNode> ConvertingNodeBuilder::convertNode(ValueNodeAccess const& _aValueNode) const +{ + uno::Any aUserValue = _aValueNode.getUserValue(); + uno::Any aDefValue = _aValueNode.getDefaultValue(); + + if (aUserValue.hasValue() || aDefValue.hasValue()) + { + return m_rNodeFactory.createValueNode(_aValueNode.getName().toString(), + aUserValue, aDefValue, + convertAttributes(_aValueNode)); + } + else + { + return m_rNodeFactory.createNullValueNode(_aValueNode.getName().toString(), + _aValueNode.getValueType(), + convertAttributes(_aValueNode)); + } +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result ConvertingNodeBuilder::handle(ValueNodeAccess const & _aNode) +{ + m_pNode = base_ptr(buildNode(_aNode)); + return DONE; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result ConvertingNodeBuilder::handle(GroupNodeAccess const & _aNode) +{ + m_pNode = base_ptr(buildNodeTree(_aNode)); + return DONE; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result ConvertingNodeBuilder::handle(SetNodeAccess const & _aNode) +{ + m_pNode = base_ptr(buildNodeTree(_aNode)); + return DONE; +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +NodeVisitor::Result ConvertingSubnodeBuilder::handle(TreeAccessor const & _aElement) +{ + OSL_ASSERT(m_rParentNode.isSetNode()); + m_rParentNode.addChild( m_aSubnodeBuilder.buildNode(_aElement,true) ); + return CONTINUE; +} +//----------------------------------------------------------------------------- + +NodeVisitor::Result ConvertingSubnodeBuilder::handle(NodeAccess const & _aMember) +{ + OSL_ASSERT(!m_rParentNode.isSetNode()); + m_rParentNode.addChild( m_aSubnodeBuilder.buildNode(_aMember) ); + return CONTINUE; +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +void DataTreeDefaultMerger::mergeDefaults(TreeAddress _aBaseAddress, INode const& _aDefaultNode) +{ +} +//----------------------------------------------------------------------------- + +void DataTreeDefaultMerger::handle(ISubtree const & _aNode) +{ +} +//----------------------------------------------------------------------------- + +void DataTreeDefaultMerger::handle(ValueNode const & _aNode) +{ +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +TreeAddress DataTreeCleanup::destroyTree(TreeAddress _aBaseAddress) +{ + TreeFragment * pData = TreeAccessor::access(_aBaseAddress,updater()); + + List aNext = pData->header.next; + + Offset const nCount = pData->header.count; + + destroyData( & pData->header ); + + for (Offset i = 0; i< nCount; ++i) + { + destroyNode( addressOfNodeAt(_aBaseAddress,i) ); + } + + allocator().deallocate( _aBaseAddress.addressValue() ); + + return TreeAddress( Pointer(aNext) ); +} +//----------------------------------------------------------------------------- + +void DataTreeCleanup::destroyNode(NodeAddress _aNodeAddress) +{ + Node * pNode = NodeAccess::access(_aNodeAddress,updater()); + + Type::Field aTypeTag = pNode->node.info.type; + switch ( aTypeTag & Type::mask_nodetype ) + { + case Type::nodetype_group: + destroyData( &pNode->group ); + break; + case Type::nodetype_value: + destroyData( &pNode->value ); + break; + case Type::nodetype_set: + destroyData( &pNode->set ); + break; + default: + OSL_ENSURE(false, "Cannot destroy node: Invalid type tag in node"); + break; + } +} +//----------------------------------------------------------------------------- + +void DataTreeCleanup::destroyData(TreeFragmentHeader * _pHeader) +{ + // 'component' is owned elsewhere -> leave alone + + sharable::String aName = _pHeader->name; + + freeString( allocator(), aName ); +} +//----------------------------------------------------------------------------- + +void DataTreeCleanup::destroyData(NodeInfo * _pNodeInfo) +{ + Name aName = _pNodeInfo->name; + + if (aName) freeName( allocator(), aName ); +} +//----------------------------------------------------------------------------- + +void DataTreeCleanup::destroyData(sharable::SetNode * _pNode) +{ + TreeAddress aElement( Pointer( _pNode->elements ) ); + + Address aTemplate = _pNode->elementType;; + + destroyData(&_pNode->info); + + while (aElement.is()) + aElement = destroyTree(aElement); + + SetNode::releaseTemplateData( allocator(), aTemplate ); +} +//----------------------------------------------------------------------------- + +void DataTreeCleanup::destroyData(sharable::GroupNode * _pNode) +{ + destroyData(&_pNode->info); + // nothing more to do +} +//----------------------------------------------------------------------------- + +void DataTreeCleanup::destroyData(sharable::ValueNode * _pNode) +{ + AnyData::TypeCode aValueType = _pNode->info.type & Type::mask_valuetype; + Flags::Field aFlags = _pNode->info.flags; + + destroyData(&_pNode->info); + + if (aFlags & Flags::valueAvailable) + freeData( allocator(), aValueType, _pNode->value ); + + if (aFlags & Flags::defaultAvailable) + freeData( allocator(), aValueType, _pNode->defaultValue ); + +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + } +//----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/tree/node.cxx b/configmgr/source/tree/node.cxx new file mode 100644 index 000000000000..9902e26e60cd --- /dev/null +++ b/configmgr/source/tree/node.cxx @@ -0,0 +1,564 @@ +/************************************************************************* + * + * $RCSfile: node.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "node.hxx" + +#ifndef INCLUDED_SHARABLE_ANYDATA_HXX +#include "anydata.hxx" +#endif +#ifndef INCLUDED_SHARABLE_TREEFRAGMENT_HXX +#include "treefragment.hxx" +#endif +#ifndef CONFIGMGR_ACCESSOR_HXX +#include "accessor.hxx" +#endif +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif +#ifndef CONFIGMGR_CONFIGURATION_ATTRIBUTES_HXX_ +#include "attributes.hxx" +#endif + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#ifndef INCLUDED_CSTDDEF +#include <cstddef> +#define INCLUDED_CSTDDEF +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace sharable + { +//----------------------------------------------------------------------------- + +// Name name; + // Offset parent; // always counts backwards + // Flags::Field flags; + // Type ::Field type; // contains discriminator for union + +rtl::OUString NodeInfo::getName(memory::Accessor const & _aAccessor) const +{ + return readString(_aAccessor,this->name); +} +//----------------------------------------------------------------------------- + +node::Attributes NodeInfo::getAttributes() const +{ + node::Attributes aResult; + + aResult.bWritable = ! (flags & Flags::readonly); + aResult.bFinalized = !!(flags & Flags::finalized); + + aResult.bNullable = !!(flags & Flags::nullable); + aResult.bLocalized = !!(flags & Flags::localized); + +// aResult.bNotified = !!(flags & Flags::notified); +// aResult.bConstrained= !!(flags & Flags::constrained); + + node::State state = (flags & Flags::defaulted) ? node::isDefault : + (flags & Flags::defaultable) ? node::isMerged : + node::isReplaced; + aResult.setState(state); + + return aResult; +} +//----------------------------------------------------------------------------- + +bool NodeInfo::isDefault() const +{ + return !!(this->flags & Flags::defaulted); +} +//----------------------------------------------------------------------------- + +bool NodeInfo::isLocalized() const +{ + return !!(this->flags & Flags::localized); +} +//----------------------------------------------------------------------------- + +void NodeInfo::markAsDefault(bool bDefault) +{ + if (bDefault) + { + OSL_ENSURE(flags & Flags::defaultable,"Marking a non-defaultable node as default"); + this->flags |= Flags::defaulted; + } + else + this->flags &= ~Flags::defaulted; +} +//----------------------------------------------------------------------------- + +bool GroupNode::hasDefaultsAvailable() const +{ + if (this->info.isDefault()) + return true; + + if (node(this)->getTreeFragment()->hasDefaultsAvailable()) + return true; + +#if 0 // extended check for default state + for (Node const * pChild = getFirstChild(); pChild != NULL; pChild = getNextChild(pChild)) + if (! pChild->isDefault() ) + return false; + + return true; +#endif + + return false; +} +//----------------------------------------------------------------------------- + +Node * GroupNode::getFirstChild() +{ + OSL_ENSURE(numDescendants, "Groups MUST have at least one child"); + return node(this) + 1; +} +//----------------------------------------------------------------------------- + +Node const * GroupNode::getFirstChild() const +{ + OSL_ENSURE(numDescendants, "Groups MUST have at least one child"); + return node(this) + 1; +} +//----------------------------------------------------------------------------- + +static +Offset implGetNextChildOffset(GroupNode const * _pParent, Node const * _pChild) +{ + OSL_PRECOND(_pChild, "getNextChild: previous child must not be NULL"); + OSL_PRECOND(_pChild->getParentNode() == node(_pParent), "getNextChild: not a child of this node"); + + + OSL_ENSURE( node(_pParent) < _pChild && _pChild <= node(_pParent) + _pParent->numDescendants, + "getNextChild: child out of descendants range"); + + // offset to child's next sibling + Offset next = 1; + if ( _pChild->isGroup()) + { + next += _pChild->group.numDescendants; + } + + if (_pChild->node.info.parent + next > _pParent->numDescendants) + { + OSL_ENSURE(_pChild->node.info.parent + next == _pParent->numDescendants+1, "Next child candidate should match next sibling here"); + return 0; + } + + OSL_POSTCOND( (_pChild+next)->getParentNode() == node(_pParent), "getNextChild: not a child of this node"); + return next; +} +//----------------------------------------------------------------------------- + +Node * GroupNode::getNextChild(Node * _pChild) +{ + if (Offset next = implGetNextChildOffset(this, _pChild)) + return _pChild + next; + + else + return NULL; +} +//----------------------------------------------------------------------------- + +Node const * GroupNode::getNextChild(Node const * _pChild) const +{ + if (Offset next = implGetNextChildOffset(this, _pChild)) + return _pChild + next; + + else + return NULL; +} +//----------------------------------------------------------------------------- + +bool SetNode::isLocalizedValue() const +{ + return info.isLocalized(); +} +//----------------------------------------------------------------------------- + +// TODO: optimize this - keep a list of such structs .... +struct SetNodeTemplateData +{ + Name name; + Name module; +}; +//----------------------------------------------------------------------------- +static inline +SetNodeTemplateData * readTemplateData(memory::Allocator const & _anAllocator, Address _aTemplateData) +{ + return static_cast<SetNodeTemplateData *>( _anAllocator.access(_aTemplateData) ); +} +//----------------------------------------------------------------------------- +static inline +SetNodeTemplateData const * readTemplateData(memory::Accessor const & _anAccessor, Address _aTemplateData) +{ + return static_cast<SetNodeTemplateData const*>( _anAccessor.access(memory::Pointer(_aTemplateData)) ); +} +//----------------------------------------------------------------------------- + +Address SetNode::allocTemplateData(memory::Allocator const & _anAllocator, NameChar const * pName, NameChar const * pModule) +{ + rtl::OUString aName(pName), aModule(pModule); + + Address aData = _anAllocator.allocate(sizeof(SetNodeTemplateData)); + + if (aData) + { + SetNodeTemplateData * pData = readTemplateData(_anAllocator,aData); + + OSL_ENSURE(pData, "Creating template data: unexpected NULL data"); + + pData->name = allocName(_anAllocator,aName); + pData->module = allocName(_anAllocator,aModule); + } + return aData; +} +//----------------------------------------------------------------------------- + +void SetNode::releaseTemplateData(memory::Allocator const & _anAllocator, Address _aTemplateData) +{ + if (!_aTemplateData) return; + + SetNodeTemplateData const * pData = readTemplateData(_anAllocator,_aTemplateData); + + OSL_ENSURE(pData, "Freeing template data: unexpected NULL data"); + + freeName(_anAllocator,pData->name); + freeName(_anAllocator,pData->module); + + _anAllocator.deallocate(_aTemplateData); +} +//----------------------------------------------------------------------------- + +NameChar const * SetNode::getTemplateDataName(memory::Accessor const & _anAccessor, Address _aTemplateData) +{ + OSL_PRECOND(_aTemplateData, "Reading template data: unexpected NULL pointer"); + + SetNodeTemplateData const * pData = readTemplateData(_anAccessor,_aTemplateData); + + OSL_ENSURE(pData, "Reading template data: unexpected NULL data"); + + return accessName(_anAccessor,pData->name); +} +//----------------------------------------------------------------------------- + +NameChar const * SetNode::getTemplateDataModule(memory::Accessor const & _anAccessor, Address _aTemplateData) +{ + OSL_PRECOND(_aTemplateData, "Reading template data: unexpected NULL pointer"); + + SetNodeTemplateData const * pData = readTemplateData(_anAccessor,_aTemplateData); + + OSL_ENSURE(pData, "Reading template data: unexpected NULL data"); + + return accessName(_anAccessor,pData->module); +} +//----------------------------------------------------------------------------- + +rtl::OUString SetNode::getElementTemplateName(memory::Accessor const & _anAccessor) const +{ + SetNodeTemplateData const * pData = readTemplateData(_anAccessor,this->elementType); + + OSL_ENSURE(pData, "ERROR: No template data found for set"); + + return readName(_anAccessor,pData->name); +} +//----------------------------------------------------------------------------- + +rtl::OUString SetNode::getElementTemplateModule(memory::Accessor const & _anAccessor) const +{ + SetNodeTemplateData const * pData = readTemplateData(_anAccessor,this->elementType); + + OSL_ENSURE(pData, "ERROR: No template data found for set"); + + return readName(_anAccessor,pData->module); +} +//----------------------------------------------------------------------------- + +static inline +TreeFragment const * implGetFragmentFromList(memory::Accessor const & _anAccessor, List _aListEntry) +{ + return static_cast<TreeFragment const *>(_anAccessor.access(memory::Pointer(_aListEntry))); +} +//----------------------------------------------------------------------------- + +TreeFragment const * SetNode::getFirstElement(memory::Accessor const & _anAccessor) const +{ + return implGetFragmentFromList(_anAccessor, this->elements); +} +//----------------------------------------------------------------------------- + +TreeFragment const * SetNode::getNextElement(memory::Accessor const & _anAccessor, TreeFragment const * _pElement) const +{ + OSL_PRECOND(_pElement, "getNextElement: previous element must not be NULL"); + OSL_PRECOND(_pElement->header.parent == _anAccessor.address(this).value(), + "getNextElement: not an element of this node"); + + return implGetFragmentFromList(_anAccessor, _pElement->header.next); +} +//----------------------------------------------------------------------------- + +bool ValueNode::isEmpty() const +{ + Type::Field const empty_value_type = Type::value_any | Type::nodetype_value; + + return info.type == empty_value_type; +} +//----------------------------------------------------------------------------- + +bool ValueNode::isNull() const +{ + Flags::Type availmask = (info.flags & Flags::defaulted) ? + Flags::defaultAvailable : + Flags::valueAvailable; + + return !(info.flags & availmask); +} +//----------------------------------------------------------------------------- + +bool ValueNode::hasUsableDefault() const +{ + return (info.flags & Flags::defaultable) && + (info.flags & (Flags::defaultAvailable| Flags::nullable)); +} +//----------------------------------------------------------------------------- + +uno::Type ValueNode::getValueType() const +{ + AnyData::TypeCode aType = info.type & Type::mask_valuetype; + + return getUnoType(aType); +} +//----------------------------------------------------------------------------- + +uno::Any ValueNode::getValue(memory::Accessor const & _aAccessor) const +{ + if (info.flags & Flags::defaulted) + return getDefaultValue(_aAccessor); + + else + return getUserValue(_aAccessor); +} +//----------------------------------------------------------------------------- + +uno::Any ValueNode::getUserValue(memory::Accessor const & _aAccessor) const +{ + if (info.flags & Flags::valueAvailable) + { + AnyData::TypeCode aType = info.type & Type::mask_valuetype; + + return readData(_aAccessor,aType,this->value); + } + else + return uno::Any(); +} +//----------------------------------------------------------------------------- + +uno::Any ValueNode::getDefaultValue(memory::Accessor const & _aAccessor) const +{ + if (info.flags & Flags::defaultAvailable) + { + AnyData::TypeCode aType = info.type & Type::mask_valuetype; + + return readData(_aAccessor,aType,this->defaultValue); + } + else + return uno::Any(); +} +//----------------------------------------------------------------------------- + +bool Node::isNamed(rtl::OUString const & _aName, memory::Accessor const & _aAccessor) const +{ + // TODO: optimize comparison + return !!(this->getName(_aAccessor) == _aName); +} +//----------------------------------------------------------------------------- + +rtl::OUString Node::getName(memory::Accessor const & _aAccessor) const +{ + return node.info.getName(_aAccessor); +} +//----------------------------------------------------------------------------- + +node::Attributes Node::getAttributes() const +{ + return node.info.getAttributes(); +} +//----------------------------------------------------------------------------- + +bool Node::isDefault() const +{ + return node.info.isDefault(); +} +//----------------------------------------------------------------------------- + +bool Node::isLocalized() const +{ + return node.info.isLocalized(); +} +//----------------------------------------------------------------------------- + +bool Node::isGroup() const +{ + return (node.info.type & Type::mask_nodetype) == Type::nodetype_group; +} +//----------------------------------------------------------------------------- + +bool Node::isSet() const +{ + return (node.info.type & Type::mask_nodetype) == Type::nodetype_set; +} +//----------------------------------------------------------------------------- + +bool Node::isValue() const +{ + return (node.info.type & Type::mask_nodetype) == Type::nodetype_value; +} +//----------------------------------------------------------------------------- + +GroupNode * Node::groupData() +{ + return isGroup() ? &this->group : NULL; +} +//----------------------------------------------------------------------------- + +GroupNode const * Node::groupData() const +{ + return isGroup() ? &this->group : NULL; +} +//----------------------------------------------------------------------------- + +SetNode * Node::setData() +{ + return isSet() ? &this->set : NULL; +} +//----------------------------------------------------------------------------- +SetNode const * Node::setData() const +{ + return isSet() ? &this->set : NULL; +} +//----------------------------------------------------------------------------- +ValueNode * Node::valueData() +{ + return isValue() ? &this->value : NULL; +} +//----------------------------------------------------------------------------- +ValueNode const * Node::valueData() const +{ + return isValue() ? &this->value : NULL; +} +//----------------------------------------------------------------------------- + +Node * Node::getParentNode() +{ + return node.info.parent ? this - node.info.parent : NULL; +} +//----------------------------------------------------------------------------- + +Node const * Node::getParentNode() const +{ + return node.info.parent ? this - node.info.parent : NULL; +} +//----------------------------------------------------------------------------- + +static Offset getFragmentIndex(Node const * pNode) +{ + Offset result = 0; + while (Offset step = pNode->node.info.parent) + { + result += step; + pNode -= step; + } + return result; +} +//----------------------------------------------------------------------------- + +TreeFragment * Node::getTreeFragment() +{ + void * pRoot = this - getFragmentIndex(this); + + void * pFrag = static_cast<char*>(pRoot) - offsetof(TreeFragment,nodes); + + return static_cast<TreeFragment *>(pFrag); +} +//----------------------------------------------------------------------------- + +TreeFragment const * Node::getTreeFragment() const +{ + void const * pRoot = this - getFragmentIndex(this); + + void const * pFrag = static_cast<char const*>(pRoot) - offsetof(TreeFragment,nodes); + + return static_cast<TreeFragment const *>(pFrag); +} + +//----------------------------------------------------------------------------- + } // namespace sharable +//----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/tree/nodeaccess.cxx b/configmgr/source/tree/nodeaccess.cxx new file mode 100644 index 000000000000..5f3ef192bae7 --- /dev/null +++ b/configmgr/source/tree/nodeaccess.cxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * $RCSfile: nodeaccess.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "nodeaccess.hxx" + +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif + +#ifndef CONFIGMGR_TREEACCESSOR_HXX +#include "treeaccessor.hxx" +#endif +#ifndef CONFIGMGR_SETNODEACCESS_HXX +#include "setnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEACCESS_HXX +#include "groupnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_VALUENODEACCESS_HXX +#include "valuenodeaccess.hxx" +#endif + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +// ----------------------------------------------------------------------------- + +namespace configmgr +{ +// ----------------------------------------------------------------------------- + namespace data + { + // ------------------------------------------------------------------------- + + NodeAddress::DataType* NodeAccess::access(NodeAddressType const& _aNodeRef, memory::UpdateAccessor& _rUpdateAccess) + { + return static_cast<NodeAddress::DataType*>(_rUpdateAccess.access(_aNodeRef.m_pData)); + } + // ------------------------------------------------------------------------- + + NodeAccess getSubnode(NodeAccess const & _aParent, NodeAccess::Name const & _aName) + { + if (GroupNodeAccess::isInstance(_aParent)) + { + return GroupNodeAccess(_aParent).getChildNode(_aName); + } + else if (SetNodeAccess::isInstance(_aParent)) + { + TreeAccessor aElement = SetNodeAccess(_aParent).getElementTree(_aName); + return aElement.isValid() ? aElement.getRootNode() : NodeAccess::emptyNode(); + } + else + { + OSL_ENSURE( ValueNodeAccess::isInstance(_aParent),"ERROR: Unknown node type"); + OSL_ENSURE(!ValueNodeAccess::isInstance(_aParent),"ERROR: Trying to access child of value node"); + return NodeAccess::emptyNode(); + } + } + // ------------------------------------------------------------------------- + + NodeAddress getSubnodeAddress(memory::Accessor const& _aAccess, NodeAddress const & _aNodeAddress, NodeAccess::Name const & _aName) + { + return getSubnode( NodeAccess(_aAccess,_aNodeAddress), _aName ).address(); + } + // ------------------------------------------------------------------------- + + NodeAddress getSubnodeAddress(memory::UpdateAccessor& _aAccess, NodeAddress const & _aNodeAddress, NodeAccess::Name const & _aName) + { + return getSubnode( NodeAccess(_aAccess.accessor(),_aNodeAddress), _aName ).address(); + } + // ------------------------------------------------------------------------- + + SetNodeAddress toSetNodeAddress(memory::Accessor const & _aAccess, NodeAddress const & _aNodeAddr) + { + SetNodeAccess aNodeAccess( NodeAccess(_aAccess,_aNodeAddr) ); + return aNodeAccess.address(); + } + // ------------------------------------------------------------------------- + + SetNodeAddress toSetNodeAddress(memory::UpdateAccessor & _aAccess, NodeAddress const & _aNodeAddr) + { + SetNodeAccess aNodeAccess( NodeAccess(_aAccess.accessor(),_aNodeAddr) ); + return aNodeAccess.address(); + } + // ------------------------------------------------------------------------- + + GroupNodeAddress toGroupNodeAddress(memory::Accessor const & _aAccess, NodeAddress const & _aNodeAddr) + { + GroupNodeAccess aNodeAccess( NodeAccess(_aAccess,_aNodeAddr) ); + return aNodeAccess.address(); + } + // ------------------------------------------------------------------------- + + GroupNodeAddress toGroupNodeAddress(memory::UpdateAccessor & _aAccess, NodeAddress const & _aNodeAddr) + { + GroupNodeAccess aNodeAccess( NodeAccess(_aAccess.accessor(),_aNodeAddr) ); + return aNodeAccess.address(); + } + // ------------------------------------------------------------------------- + + ValueNodeAddress toValueNodeAddress(memory::Accessor const & _aAccess, NodeAddress const & _aNodeAddr) + { + ValueNodeAccess aNodeAccess( NodeAccess(_aAccess,_aNodeAddr) ); + return aNodeAccess.address(); + } + // ------------------------------------------------------------------------- + + ValueNodeAddress toValueNodeAddress(memory::UpdateAccessor & _aAccess, NodeAddress const & _aNodeAddr) + { + ValueNodeAccess aNodeAccess( NodeAccess(_aAccess.accessor(),_aNodeAddr) ); + return aNodeAccess.address(); + } + // ------------------------------------------------------------------------- + } +// ----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/tree/nodevisitor.cxx b/configmgr/source/tree/nodevisitor.cxx new file mode 100644 index 000000000000..f8f4360c9751 --- /dev/null +++ b/configmgr/source/tree/nodevisitor.cxx @@ -0,0 +1,373 @@ +/************************************************************************* + * + * $RCSfile: nodevisitor.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "nodevisitor.hxx" + +#ifndef CONFIGMGR_NODEACCESS_HXX +#include "nodeaccess.hxx" +#endif +#ifndef CONFIGMGR_VALUENODEACCESS_HXX +#include "valuenodeaccess.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEACCESS_HXX +#include "groupnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_SETNODEACCESS_HXX +#include "setnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_TREEACCESSOR_HXX +#include "treeaccessor.hxx" +#endif + +#ifndef _CONFIGMGR_TREE_VALUENODE_HXX +#include "valuenode.hxx" +#endif + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +// ----------------------------------------------------------------------------- + +namespace configmgr +{ +// ----------------------------------------------------------------------------- + namespace data + { +// ------------------------------------------------------------------------- +typedef NodeVisitor::Result Result; + +// ------------------------------------------------------------------------- +#ifdef NON_SHARABLE_DATA + // ------------------------------------------------------------------------- + #define applyToTree applyToNode + #define applyToElements applyToChildren + // ------------------------------------------------------------------------- + struct NodeVisitor::Dispatcher : NodeAction + { + NodeVisitor& m_target; + Accessor m_accessor; + Result m_result; + + Dispatcher(NodeVisitor& _rTarget, Accessor const& _aAccessor) + : m_target(_rTarget) + , m_accessor(_aAccessor) + , m_result(NodeVisitor::CONTINUE) + {} + + virtual void handle(ValueNode const&); + virtual void handle(ISubtree const&); + + Result dispatch(ISubtree const&); + }; + + // ------------------------------------------------------------------------- + + inline + Result NodeVisitor::Dispatcher::dispatch(ISubtree const& _aNode) + { + if (_aNode.isSetNode()) + return m_target.handle( SetNodeAccess(m_accessor, &_aNode) ); + + else + return m_target.handle( GroupNodeAccess(m_accessor, &_aNode) ); + } + // ------------------------------------------------------------------------- + + void NodeVisitor::Dispatcher::handle(ValueNode const& _aNode) + { + if (m_result != NodeVisitor::DONE) + m_result = m_target.handle( ValueNodeAccess(m_accessor, &_aNode) ); + } + // ------------------------------------------------------------------------- + + void NodeVisitor::Dispatcher::handle(ISubtree const& _aNode) + { + if (m_result != NodeVisitor::DONE) + m_result = dispatch( _aNode ); + } + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + struct SetVisitor::Dispatcher : NodeAction + { + SetVisitor& m_target; + Accessor m_accessor; + Result m_result; + + Dispatcher(SetVisitor& _rTarget, Accessor const& _aAccessor) + : m_target(_rTarget) + , m_accessor(_aAccessor) + , m_result(NodeVisitor::CONTINUE) + {} + + virtual void handle(ValueNode const&); + virtual void handle(ISubtree const&); + + Result dispatch(INode const&); + }; + + // ------------------------------------------------------------------------- + + inline + Result SetVisitor::Dispatcher::dispatch(INode const& _aRootNode) + { + return m_target.handle( TreeAccessor(m_accessor, &_aRootNode) ); + } + // ------------------------------------------------------------------------- + + void SetVisitor::Dispatcher::handle(ValueNode const& _aNode) + { + if (m_result != NodeVisitor::DONE) + m_result = dispatch( _aNode ); + } + // ------------------------------------------------------------------------- + + void SetVisitor::Dispatcher::handle(ISubtree const& _aNode) + { + if (m_result != NodeVisitor::DONE) + m_result = dispatch( _aNode ); + } + // ------------------------------------------------------------------------- +#else // SHARABLE_DATA + // ------------------------------------------------------------------------- + struct NodeVisitor::Dispatcher + { + NodeVisitor& m_target; + Accessor m_accessor; + Result m_result; + + Dispatcher(NodeVisitor& _rTarget, Accessor const& _aAccessor) + : m_target(_rTarget) + , m_accessor(_aAccessor) + , m_result(NodeVisitor::CONTINUE) + {} + + void applyToNode(sharable::Node const & _aNode); + void applyToChildren(sharable::GroupNode const & _aNode); + + Result dispatch(sharable::Node const& _aNode); + }; + + // ------------------------------------------------------------------------- + struct SetVisitor::Dispatcher + { + SetVisitor& m_target; + Accessor m_accessor; + Result m_result; + + Dispatcher(SetVisitor& _rTarget, Accessor const& _aAccessor) + : m_target(_rTarget) + , m_accessor(_aAccessor) + , m_result(NodeVisitor::CONTINUE) + {} + + void applyToTree(sharable::TreeFragment const & _aElement); + void applyToElements(sharable::SetNode const & _aNode); + + Result dispatch(sharable::TreeFragment const& _aElement); + }; + + // ------------------------------------------------------------------------- + + inline + Result NodeVisitor::Dispatcher::dispatch(sharable::Node const& _aNode) + { + using namespace sharable::Type; + switch (_aNode.node.info.type & mask_nodetype) + { + case nodetype_value: + return m_target.handle( ValueNodeAccess(m_accessor, &_aNode.value) ); + break; + + case nodetype_group: + return m_target.handle( GroupNodeAccess(m_accessor, &_aNode.group) ); + + case nodetype_set: + return m_target.handle( SetNodeAccess(m_accessor, &_aNode.set) ); + + default: + OSL_ENSURE(false,"NodeVisitor: invalid node type detected"); // invalid node + return m_target.handle( NodeAccess(m_accessor, &_aNode) ); + } + } + // ------------------------------------------------------------------------- + + inline + Result SetVisitor::Dispatcher::dispatch(sharable::TreeFragment const& _aElement) + { + return m_target.handle( TreeAccessor(m_accessor, &_aElement) ); + } + // ------------------------------------------------------------------------- + + void NodeVisitor::Dispatcher::applyToNode(sharable::Node const & _aNode) + { + if (m_result != NodeVisitor::DONE) + m_result = dispatch(_aNode); + } + // ------------------------------------------------------------------------- + + void SetVisitor::Dispatcher::applyToTree(sharable::TreeFragment const & _aElement) + { + if (m_result != NodeVisitor::DONE) + m_result = dispatch(_aElement); + } + // ------------------------------------------------------------------------- + + void NodeVisitor::Dispatcher::applyToChildren(sharable::GroupNode const & _aNode) + { + using sharable::Node; + for (Node const * pChild = _aNode.getFirstChild(); + pChild != NULL && m_result != NodeVisitor::DONE; + pChild = _aNode.getNextChild(pChild) ) + m_result = dispatch(*pChild); + } + // ------------------------------------------------------------------------- + + void SetVisitor::Dispatcher::applyToElements(sharable::SetNode const & _aNode) + { + using sharable::TreeFragment; + for (TreeFragment const * pElement = _aNode.getFirstElement(m_accessor); + pElement != NULL && m_result != NodeVisitor::DONE; + pElement = _aNode.getNextElement(m_accessor,pElement) ) + m_result = dispatch(*pElement); + + } + // ------------------------------------------------------------------------- +#endif // SHARABLE_DATA +// ------------------------------------------------------------------------- + +Result NodeVisitor::visitNode(NodeAccess const& _aNode) +{ + Dispatcher aDispatcher(*this, _aNode.accessor()); + + aDispatcher.applyToNode(_aNode.data()); + + return aDispatcher.m_result; +} +// ------------------------------------------------------------------------- + +Result SetVisitor::visitTree(TreeAccessor const& _aNode) +{ + Dispatcher aDispatcher(*this, _aNode.accessor()); + + aDispatcher.applyToTree(_aNode.data()); + + return aDispatcher.m_result; +} +// ------------------------------------------------------------------------- + +Result NodeVisitor::visitChildren(GroupNodeAccess const& _aNode) +{ + Dispatcher aDispatcher(*this, _aNode.accessor()); + + aDispatcher.applyToChildren(_aNode.data()); + + return aDispatcher.m_result; +} +// ------------------------------------------------------------------------- + +Result SetVisitor::visitElements(SetNodeAccess const& _aNode) +{ + Dispatcher aDispatcher(*this, _aNode.accessor()); + + aDispatcher.applyToElements(_aNode.data()); + + return aDispatcher.m_result; +} +// ------------------------------------------------------------------------- + +Result NodeVisitor::handle(NodeAccess const& _aNode) +{ + return CONTINUE; +} +// ------------------------------------------------------------------------- + +Result NodeVisitor::handle(ValueNodeAccess const& _aNode) +{ + return handle(static_cast<NodeAccess>(_aNode)); +} +// ------------------------------------------------------------------------- + +Result NodeVisitor::handle(GroupNodeAccess const& _aNode) +{ + return handle(static_cast<NodeAccess>(_aNode)); +} +// ------------------------------------------------------------------------- + +Result NodeVisitor::handle(SetNodeAccess const& _aNode) +{ + return handle(static_cast<NodeAccess>(_aNode)); +} +// ------------------------------------------------------------------------- + +Result SetVisitor::handle(TreeAccessor const& _aTree) +{ + return NodeVisitor::visitNode(_aTree.getRootNode()); +} +// ------------------------------------------------------------------------- + +// ------------------------------------------------------------------------- + } +// ----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/tree/treefragment.cxx b/configmgr/source/tree/treefragment.cxx new file mode 100644 index 000000000000..b4218cb785f6 --- /dev/null +++ b/configmgr/source/tree/treefragment.cxx @@ -0,0 +1,154 @@ +/************************************************************************* + * + * $RCSfile: treefragment.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "treefragment.hxx" + +#ifndef CONFIGMGR_CONFIGURATION_ATTRIBUTES_HXX_ +#include "attributes.hxx" +#endif + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace sharable + { +//----------------------------------------------------------------------------- +rtl::OUString TreeFragment::getName(memory::Accessor const & _aAccessor) const +{ + return readString(_aAccessor,this->header.name); +} +//----------------------------------------------------------------------------- + +bool TreeFragment::isNamed(rtl::OUString const & _aName, memory::Accessor const & _aAccessor) const +{ + // TODO: optimize comparison + return !!(this->getName(_aAccessor) == _aName); +} +//----------------------------------------------------------------------------- + +bool TreeFragment::hasDefaults() const +{ + switch (this->header.state & State::mask_state) + { + default: OSL_ASSERT(false); // not reachable + + case State::merged: + case State::defaulted: return true; + + case State::replaced: + case State::added: return false; + } +} +//----------------------------------------------------------------------------- + +bool TreeFragment::hasDefaultsAvailable() const +{ + return (this->header.state & State::flag_default_avail) || isDefault(); +} +//----------------------------------------------------------------------------- + + +bool TreeFragment::isDefault() const +{ + return (this->header.state & State::mask_state) == State::defaulted; +} +//----------------------------------------------------------------------------- + +bool TreeFragment::isNew() const +{ + return (this->header.state & State::mask_state) == State::added; +} +//----------------------------------------------------------------------------- + +node::Attributes TreeFragment::getAttributes() const +{ + node::Attributes aResult; + + switch (this->header.state & State::mask_state) + { + case State::merged: aResult.setState(node::isMerged); break; + case State::defaulted: aResult.setState(node::isDefault); break; + case State::replaced: aResult.setState(node::isReplaced); break; + case State::added: aResult.setState(node::isAdded); break; + default: OSL_ASSERT(false); break; // not reachable + } + + aResult.bWritable = ! (this->header.state & State::flag_readonly); + + OSL_ASSERT( header.count != 0 ); + NodeInfo const & aRootNodeInfo = this->nodes[0].node.info; + + aResult.bFinalized = !!(aRootNodeInfo.flags & Flags::finalized); + aResult.bLocalized = !!(aRootNodeInfo.flags & Flags::localized); + + return aResult; +} + +//----------------------------------------------------------------------------- + } // namespace sharable +//----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/tree/treesegment.cxx b/configmgr/source/tree/treesegment.cxx new file mode 100644 index 000000000000..65b451370c9a --- /dev/null +++ b/configmgr/source/tree/treesegment.cxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * $RCSfile: treesegment.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "treesegment.hxx" + +#ifndef CONFIGMGR_BUILDDATA_HXX +#include "builddata.hxx" +#endif +#ifndef CONFIGMGR_SEGMENT_HXX +#include "segment.hxx" +#endif +#ifndef CONFIGMGR_HEAPFACTORY_HXX +#include "heapfactory.hxx" +#endif +#ifndef CONFIGMGR_ACCESSOR_HXX +#include "accessor.hxx" +#endif +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif +#ifndef CONFIGMGR_TREEACCESSOR_HXX +#include "treeaccessor.hxx" +#endif + +#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ +#include <salhelper/simplereferenceobject.hxx> +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +// ----------------------------------------------------------------------------- + +namespace configmgr +{ +// ----------------------------------------------------------------------------- + namespace data + { +// ----------------------------------------------------------------------------- + +// typedef std::auto_ptr<INode> RawTreeData; +// typedef configuration::Name Name; + using memory::Pointer; + +// ----------------------------------------------------------------------------- +#ifdef NON_SHARABLE_DATA +// ----------------------------------------------------------------------------- +struct TreeSegment::Impl : salhelper::SimpleReferenceObject +{ + Impl(RawTreeData& _tree) : tree(_tree), data() {} + RawTreeData tree; + memory::Segment data; +}; + +// ----------------------------------------------------------------------------- +#else // SHARABLE_DATA +// ----------------------------------------------------------------------------- +struct TreeSegment::Impl : salhelper::SimpleReferenceObject +{ + Impl() : data( memory::localHeap() ), base() {} + ~Impl(); + + memory::Segment data; + data::TreeAddress base; +}; +// ----------------------------------------------------------------------------- +#endif // SHARABLE_DATA +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +TreeSegment::TreeSegment() +: m_pImpl() +{ +} + +// ----------------------------------------------------------------------------- +TreeSegment::TreeSegment(Impl * _pImpl) +: m_pImpl(_pImpl) +{ +} + +// ----------------------------------------------------------------------------- +TreeSegment::TreeSegment(TreeSegment const & _aOther) +: m_pImpl( _aOther.m_pImpl ) +{ +} + +// ----------------------------------------------------------------------------- +TreeSegment& TreeSegment::operator=(TreeSegment const & _aOther) +{ + m_pImpl = _aOther.m_pImpl; + return *this; +} + +// ----------------------------------------------------------------------------- +TreeSegment::~TreeSegment() +{ +} + +// ----------------------------------------------------------------------------- +void TreeSegment::clear() +{ + m_pImpl.clear(); +} + +// ----------------------------------------------------------------------------- +memory::Segment * TreeSegment::getSegment() const +{ + return is() ? &m_pImpl->data : 0; +} + +// ----------------------------------------------------------------------------- +memory::Accessor TreeSegment::getAccessor() const +{ + return memory::Accessor(getSegment()); +} + +// ----------------------------------------------------------------------------- +TreeAccessor TreeSegment::getTreeAccess() const +{ + return TreeAccessor( getAccessor(), getTreeData() ); +} + +// ----------------------------------------------------------------------------- +#ifdef NON_SHARABLE_DATA +// ----------------------------------------------------------------------------- +TreeSegment::Impl* TreeSegment::createNewSegment(RawTreeData& _aTree) +{ + return new Impl(_aTree); +} + +// ----------------------------------------------------------------------------- +TreeSegment TreeSegment::cloneSegment() const +{ + if (!is()) return TreeSegment(); + + // TODO: Improve cloning for shared data + + RawTreeData aClonedTree = this->cloneData(); + + return createNew( aClonedTree ); +} + +// ----------------------------------------------------------------------------- +bool TreeSegment::is() const +{ + return hasData() && (m_pImpl->tree.get() != NULL); +} + +// ----------------------------------------------------------------------------- +TreeSegment::Name TreeSegment::getName() const +{ + OSL_ENSURE(is(), "Operation requires a valid tree"); + + if (!is()) return Name(); + + return configuration::makeElementName( getTreeData()->getName(), Name::NoValidate() ); +} + +// ----------------------------------------------------------------------------- +void TreeSegment::setName(Name const & _aNewName) +{ + OSL_ENSURE(is(), "Operation requires a valid tree"); + + if (is()) getTreeDataForUpdate()->setName(_aNewName.toString()); +} + +// ----------------------------------------------------------------------------- +TreeSegment::RawTreeData TreeSegment::cloneData() const +{ + OSL_ENSURE(is(), "Accessing tree data requires a valid tree"); + RawTreeData aResult; + if (is()) + { + aResult = m_pImpl->tree->clone(); + } + return aResult; +} + +// ----------------------------------------------------------------------------- +TreeAddress TreeSegment::getBaseAddress() const +{ + return TreeAddress(Pointer(getTreeData())); +} + +// ----------------------------------------------------------------------------- +TreeSegment::TreeDataPtr TreeSegment::getTreeData() const +{ + return hasData() ? m_pImpl->tree.get() : 0; +} + +// ----------------------------------------------------------------------------- +TreeSegment::TreeDataUpdatePtr TreeSegment::getTreeDataForUpdate(memory::UpdateAccessor& _anUpdater) const +{ + OSL_ASSERT(_anUpdater.is()); + return hasData() ? m_pImpl->tree.get() : 0; +} + +// ----------------------------------------------------------------------------- +TreeSegment::NodeDataPtr TreeSegment::getSegmentRootNode() const +{ + return getTreeData(); +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +#else // SHARABLE_DATA +// ----------------------------------------------------------------------------- +TreeSegment::Impl::~Impl() +{ + if (base.is()) + { + memory::UpdateAccessor aAccess( & this->data ); + destroyTree(aAccess,base); + } +} + +// ----------------------------------------------------------------------------- +TreeSegment::Impl* TreeSegment::createNewSegment(RawTreeData& _aTree, RawName const & _aTypeName) +{ + if (_aTree.get() == NULL) return NULL; + + std::auto_ptr<Impl> aNewImpl( new Impl ); + + memory::UpdateAccessor aNewAccess( & aNewImpl->data ); + + aNewImpl->base = buildElementTree(aNewAccess,*_aTree,_aTypeName,false); // no defaults for set element trees + + if (!aNewImpl->base.is()) aNewImpl.reset(); + + return aNewImpl.release(); +} + +// ----------------------------------------------------------------------------- +TreeSegment::Impl* TreeSegment::createNewSegment(RawName const & _aTreeName, RawTreeData& _aTree) +{ + if (_aTree.get() == NULL) return NULL; + + std::auto_ptr<Impl> aNewImpl( new Impl ); + + memory::UpdateAccessor aNewAccess( & aNewImpl->data ); + + aNewImpl->base = buildTree(aNewAccess,_aTreeName,*_aTree,false); // no defaults for set element trees + + if (!aNewImpl->base.is()) aNewImpl.reset(); + + return aNewImpl.release(); +} + + +// ----------------------------------------------------------------------------- +TreeSegment::Impl* TreeSegment::createNewSegment(TreeAccessor const & _aTree) +{ + if (!_aTree.isValid()) return NULL; + + std::auto_ptr<Impl> aNewImpl( new Impl ); + + memory::UpdateAccessor aNewAccess( & aNewImpl->data ); + + aNewImpl->base = _aTree.copyTree(aNewAccess); + + if (!aNewImpl->base.is()) aNewImpl.reset(); + + return aNewImpl.release(); +} + +// ----------------------------------------------------------------------------- +TreeSegment::RawTreeData TreeSegment::cloneData(bool _bUseTreeName) const +{ + return convertTree( this->getTreeAccess(), _bUseTreeName ); +} + +// ----------------------------------------------------------------------------- +TreeSegment TreeSegment::cloneSegment() const +{ + if (!is()) return TreeSegment(); + + return createNew( this->getTreeAccess() ); +} + +// ----------------------------------------------------------------------------- +bool TreeSegment::is() const +{ + return hasData() && m_pImpl->base.is(); +} + +// ----------------------------------------------------------------------------- +TreeSegment::Name TreeSegment::getName() const +{ + OSL_ENSURE(is(), "Operation requires a valid tree"); + + if (!is()) return Name(); + + Accessor accessor = getAccessor(); + + return configuration::makeElementName( getTreeData()->getName(accessor), Name::NoValidate() ); +} + +// ----------------------------------------------------------------------------- +void TreeSegment::setName(Name const & _aNewName) +{ + OSL_ENSURE(is(), "Operation requires a valid tree"); + + if (is()) + { + memory::UpdateAccessor aUpdater( this->getSegment() ); + + sharable::String aOldName = getTreeDataForUpdate(aUpdater)->header.name; + + sharable::String aNewName = sharable::allocString(aUpdater.allocator(),_aNewName.toString()); + + getTreeDataForUpdate(aUpdater)->header.name = aNewName; + + sharable::freeString(aUpdater.allocator(),aOldName); + } +} + +// ----------------------------------------------------------------------------- +TreeAddress TreeSegment::getBaseAddress() const +{ + return hasData() ? m_pImpl->base : TreeAddress(); +} + +// ----------------------------------------------------------------------------- +TreeSegment::TreeDataPtr TreeSegment::getTreeData() const +{ + if (!is()) return NULL; + + return TreeAccessor::access(m_pImpl->base, this->getAccessor()); +} + +// ----------------------------------------------------------------------------- +TreeSegment::TreeDataUpdatePtr TreeSegment::getTreeDataForUpdate(memory::UpdateAccessor& _anUpdater) const +{ + OSL_ASSERT(_anUpdater.is()); + OSL_ASSERT(this->is()); + + if (!is()) return NULL; + + return TreeAccessor::access(m_pImpl->base,_anUpdater); +} + +// ----------------------------------------------------------------------------- +TreeSegment::NodeDataPtr TreeSegment::getSegmentRootNode() const +{ + if (sharable::TreeFragment const * pTree = getTreeData()) + return & pTree->nodes[0]; + + else + return NULL; +} +// ----------------------------------------------------------------------------- +#endif // SHARABLE_DATA +// ----------------------------------------------------------------------------- +#if 0 +TreeSegment::RawTreeData TreeSegment::releaseData() +{ + OSL_ENSURE(is(), "Accessing tree data requires a valid tree"); + RawTreeData aResult; + if (hasData()) + { + aResult = m_pImpl->tree; + m_pImpl.clear(); + } + return aResult; +} +#endif +// ----------------------------------------------------------------------------- + } +// ----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/tree/valuenodeaccess.cxx b/configmgr/source/tree/valuenodeaccess.cxx new file mode 100644 index 000000000000..8871bfbbd5d6 --- /dev/null +++ b/configmgr/source/tree/valuenodeaccess.cxx @@ -0,0 +1,286 @@ +/************************************************************************* + * + * $RCSfile: valuenodeaccess.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "valuenodeaccess.hxx" + +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +// ----------------------------------------------------------------------------- + +namespace configmgr +{ +// ----------------------------------------------------------------------------- + namespace data + { + // ------------------------------------------------------------------------- + using memory::Pointer; + // ------------------------------------------------------------------------- + static + ValueNodeAddress::DataType* accessValue(Pointer const& _p, memory::UpdateAccessor& _rUpdateAccess) + { + return static_cast<ValueNodeAddress::DataType*>( _rUpdateAccess.validate(_p) ); + } + // ------------------------------------------------------------------------- +#ifdef NON_SHARABLE_DATA + // ------------------------------------------------------------------------- + + Pointer ValueNodeAccess::check(NodeAccess const& _aNode) + { + if (INode const* pNode = _aNode.getDataPtr()) + return pNode->asValueNode(); + + else + return NULL; + } + // ------------------------------------------------------------------------- + + void ValueNodeAccess::setValue(memory::UpdateAccessor & _aUpdater, NodeAddressType _aValueNode, uno::Any const& _aValue) + { + accessValue(_aValueNode.m_pData,_aUpdater)->setValue(_aValue); + } + // ------------------------------------------------------------------------- + + void ValueNodeAccess::setToDefault(memory::UpdateAccessor & _aUpdater, NodeAddressType _aValueNode) + { + accessValue(_aValueNode.m_pData,_aUpdater)->setDefault(); + } + // ------------------------------------------------------------------------- + + void ValueNodeAccess::changeDefault(memory::UpdateAccessor & _aUpdater, NodeAddressType _aValueNode, uno::Any const& _aValue) + { + accessValue(_aValueNode.m_pData,_aUpdater)->setValue(_aValue); + } + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- +#else // SHARABLE_DATA + // ------------------------------------------------------------------------- + + Pointer ValueNodeAccess::check(NodeAccess const& _aNode) + { + if (sharable::Node const* pNode = _aNode.getDataPtr()) + return _aNode.accessor().address(pNode->valueData()); + + else + return Pointer(); + } + // ------------------------------------------------------------------------- + +void ValueNodeAccess::setValue(memory::UpdateAccessor & _aUpdater, NodeAddressType _aValueNode, uno::Any const& _aValue) +{ + sharable::ValueNode * node = accessValue(_aValueNode.m_pData,_aUpdater); + + using namespace sharable; + AnyData::TypeCode aType = node->info.type & Type::mask_valuetype; + + // release old data + if (node->info.flags & Flags::valueAvailable) + { + OSL_ASSERT(aType != Type::value_any); + + freeData(_aUpdater.allocator(),aType,node->value); + node = accessValue(_aValueNode.m_pData,_aUpdater); + + node->value.data = 0; + node->info.flags ^= Flags::valueAvailable; + } + + // set new value + if (_aValue.hasValue()) + { + AnyData::TypeCode aNewType = getTypeCode(_aValue.getValueType()); + OSL_ASSERT(aNewType != Type::value_any); + + // set new type, if appropriate + if (aType == Type::value_any) + { + OSL_ASSERT(Type::value_any == 0); + OSL_ASSERT(aNewType != Type::value_any); + + aType = aNewType & Type::mask_valuetype; + + node->info.type |= aType; + } + + OSL_ENSURE(aType == aNewType, "ERROR: setValue() - Value type does not match"); + if (aType == aNewType) + { + // store the data + sharable::AnyData aNewData = allocData(_aUpdater.allocator(),aType,_aValue); + node = accessValue(_aValueNode.m_pData,_aUpdater); + + node->value = aNewData; + node->info.flags |= Flags::valueAvailable; + } + } + node->info.flags &= ~Flags::defaulted; +} +//----------------------------------------------------------------------------- + +void ValueNodeAccess::setToDefault(memory::UpdateAccessor & _aUpdater, NodeAddressType _aValueNode) +{ + sharable::ValueNode * node = accessValue(_aValueNode.m_pData,_aUpdater); + + using namespace sharable; + OSL_ENSURE(node->hasUsableDefault(), "ERROR: setToDefault() - Value does not have a default"); + + // release value data + if (node->info.flags & Flags::valueAvailable) + { + AnyData::TypeCode aType = node->info.type & Type::mask_valuetype; + OSL_ASSERT(aType != Type::value_any); + + freeData(_aUpdater.allocator(),aType,node->value); + node = accessValue(_aValueNode.m_pData,_aUpdater); + + node->value.data = 0; + node->info.flags ^= Flags::valueAvailable; + } + + node->info.flags |= Flags::defaulted; +} +//----------------------------------------------------------------------------- + +void ValueNodeAccess::changeDefault(memory::UpdateAccessor & _aUpdater, NodeAddressType _aValueNode, uno::Any const& _aValue) +{ + sharable::ValueNode * node = accessValue(_aValueNode.m_pData,_aUpdater); + + using namespace sharable; + AnyData::TypeCode aType = node->info.type & Type::mask_valuetype; + + // release old data + if (node->info.flags & Flags::defaultAvailable) + { + OSL_ASSERT(aType != Type::value_any); + + freeData(_aUpdater.allocator(),aType,node->defaultValue); + node = accessValue(_aValueNode.m_pData,_aUpdater); + + node->defaultValue.data = 0; + node->info.flags ^= Flags::defaultAvailable; + } + + // set new value + if (_aValue.hasValue()) + { + AnyData::TypeCode aNewType = getTypeCode(_aValue.getValueType()); + OSL_ASSERT(aNewType != Type::value_any); + + // set new type, if appropriate + if (aType == Type::value_any) + { + OSL_ASSERT(Type::value_any == 0); + OSL_ASSERT(aNewType != Type::value_any); + + aType = aNewType & Type::mask_valuetype; + + node->info.type |= aType; + } + + OSL_ENSURE(aType == aNewType, "ERROR: changeDefault() - Value type does not match"); + if (aType == aNewType) + { + // store the data + sharable::AnyData aNewData = allocData(_aUpdater.allocator(),aType,_aValue); + node = accessValue(_aValueNode.m_pData,_aUpdater); + + node->defaultValue = aNewData; + node->info.flags |= Flags::defaultAvailable; + } + } +} +//----------------------------------------------------------------------------- +/* +void ValueNode::clearData(data::Allocator const & _aAlloc) +{ + AnyData::TypeCode aType = info.type & Type::mask_valuetype; + + if (info.flags & Flags::valueAvailable) + { + OSL_ASSERT(aType != Type::value_any); + freeData(_aAlloc,aType,this->value); + info.flags ^= Flags::valueAvailable; + this->value.data = 0; + } + + if (info.flags & Flags::defaultAvailable) + { + OSL_ASSERT(aType != Type::value_any); + freeData(_aAlloc,aType,this->defaultValue); + info.flags ^= Flags::defaultAvailable; + this->defaultValue.data = 0; + } +} +*/ +//----------------------------------------------------------------------------- +#endif // SHARABLE_DATA + // ------------------------------------------------------------------------- + } +// ----------------------------------------------------------------------------- +} // namespace configmgr + + diff --git a/configmgr/source/treemgr/deferredview.cxx b/configmgr/source/treemgr/deferredview.cxx new file mode 100644 index 000000000000..2ea213f547f4 --- /dev/null +++ b/configmgr/source/treemgr/deferredview.cxx @@ -0,0 +1,483 @@ +/************************************************************************* + * + * $RCSfile: deferredview.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 <stdio.h> +#include "deferredview.hxx" + +#ifndef CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_ +#include "viewfactory.hxx" +#endif +#ifndef CONFIGMGR_NODEIMPLOBJECTS_HXX_ +#include "nodeimplobj.hxx" +#endif + +namespace configmgr +{ + namespace view + { +//----------------------------------------------------------------------------- +using configuration::DeferredGroupNodeImpl; +using configuration::DeferredSetNodeImpl; + +//----------------------------------------------------------------------------- +static inline DeferredGroupNodeImpl* deferredGroupNode(Node const& _aNode) +{ + return static_cast<DeferredGroupNodeImpl*>(_aNode.get_impl()); +} +//----------------------------------------------------------------------------- + +static inline DeferredGroupNodeImpl* deferredGroupNode(GroupNode const& _aNode) +{ + return static_cast<DeferredGroupNodeImpl*>(_aNode.get_impl()); +} +//----------------------------------------------------------------------------- + +static inline DeferredSetNodeImpl* deferredSetNode(Node const& _aNode) +{ + return static_cast<DeferredSetNodeImpl*>(_aNode.get_impl()); +} +//----------------------------------------------------------------------------- + +static inline DeferredSetNodeImpl* deferredSetNode(SetNode const& _aNode) +{ + return static_cast<DeferredSetNodeImpl*>(_aNode.get_impl()); +} +//----------------------------------------------------------------------------- + +static inline void deferredValueNode(Node const& _aNode) +{ + OSL_ENSURE( _aNode.isValueNode(),"Unknown Node type in deferred view"); + OSL_ENSURE(_aNode.get_offset() == _aNode.tree().get_impl()->root_(), "TreeImpl: Unexpected node type - non-root value element"); +} +//----------------------------------------------------------------------------- + +static void deferredValueNodeChanged(Node const& _aNode) +{ + OSL_ENSURE( _aNode.isValueNode(),"Unknown Node type in deferred view"); + OSL_ENSURE(_aNode.get_offset() == _aNode.tree().get_impl()->root_(), "TreeImpl: Unexpected node type - non-root value element"); + OSL_ENSURE(!_aNode.isValueNode(),"Value node changes not supported in deferred view"); + throw configuration::Exception("Internal Error: Invalid operation applied to element"); +} +//----------------------------------------------------------------------------- + +bool DeferredViewStrategy::doHasChanges(Node const& _aNode) const +{ + if (_aNode.isGroupNode()) + return deferredGroupNode(_aNode)->hasChanges(); + + else if (_aNode.isSetNode()) + return deferredSetNode(_aNode)->hasChanges(); + + else + deferredValueNode(_aNode); + + return false; +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doMarkChanged(Node const& _aNode) +{ + if (_aNode.isGroupNode()) + deferredGroupNode(_aNode)->markChanged(); + + else if (_aNode.isSetNode()) + deferredSetNode(_aNode)->markChanged(); + + else + deferredValueNodeChanged(_aNode); +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doCollectChanges(Node const& _aNode, configuration::NodeChanges& _rChanges) const +{ + implCollectChangesIn(_aNode,_rChanges); +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::implCollectChangesIn(Node const& _aNode, configuration::NodeChanges& _rChanges) const +{ + if ( hasChanges(_aNode) ) + { + if (_aNode.isSetNode()) + { + deferredSetNode(_aNode)->collectElementChanges( _aNode.accessor(), _rChanges); + } + else if (_aNode.isGroupNode()) + { + GroupNode aGroup(_aNode); + + deferredGroupNode(aGroup)->collectValueChanges( aGroup.accessor(), _rChanges, _aNode.tree().get_impl(), _aNode.get_offset()); + + for( Node aChild = aGroup.getFirstChild(); + aChild.is(); + aChild = aGroup.getNextChild(aChild) + ) + { + this->implCollectChangesIn( aChild, _rChanges ); + } + } + else + OSL_ASSERT(!"Unreachable code"); + } +} + +//----------------------------------------------------------------------------- +std::auto_ptr<SubtreeChange> DeferredViewStrategy::doPreCommitChanges(Tree const& _aTree, configuration::ElementList& _rRemovedElements) +{ + std::auto_ptr<SubtreeChange> pRet; + if (hasChanges(_aTree)) + { + pRet = implPreCommitChanges(getRootNode(_aTree),_rRemovedElements); + if (pRet.get() != NULL) + { + pRet->setNodeName(getSimpleRootName(_aTree).toString()); + } + } + return pRet; +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doFailedCommit(Tree const& _aTree, SubtreeChange& rChanges) +{ + implFailedCommit(getRootNode(_aTree),rChanges); +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doFinishCommit(Tree const& _aTree, SubtreeChange& rChanges) +{ + implFinishCommit(getRootNode(_aTree),rChanges); +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doRevertCommit(Tree const& _aTree, SubtreeChange& rChanges) +{ + implRevertCommit(getRootNode(_aTree),rChanges); +} + +//----------------------------------------------------------------------------- +configuration::ValueChangeImpl* DeferredViewStrategy::doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& _aName, ValueChange const& rExternalChange) +{ + using configuration::ValueChangeImpl; + DeferredGroupNodeImpl::MemberChange aChange = deferredGroupNode(_aGroupNode)->findValueChange(_aName); + + if (aChange.is()) + { + if (ValueChangeImpl* pValueChange = aChange->adjustToChange(rExternalChange)) + { + OSL_ENSURE(aChange->isChange(), "Got an adjusted change from a non-changing value"); + + return pValueChange; + } + else // a non-change + { + OSL_ENSURE(!aChange->isChange(), "Got no adjusted change from a changing value") ; + OSL_ENSURE(false, "Got a non-change from a (deferred) group") ; + // then do as without deferred change + } + } + + return ViewStrategy::doAdjustToValueChange(_aGroupNode, _aName, rExternalChange); + +} + +//----------------------------------------------------------------------------- +node::Attributes DeferredViewStrategy::doAdjustAttributes(node::Attributes const& _aAttributes) const +{ + return _aAttributes; +} + +//----------------------------------------------------------------------------- +configuration::ValueMemberNode DeferredViewStrategy::doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const +{ + return deferredGroupNode(_aNode)->makeValueMember(_aNode.accessor(),_aName,_bForUpdate); +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doInsertElement(SetNode const& _aNode, Name const& aName, configuration::SetEntry const& _aNewEntry) +{ + // move to this memory segment + // should be direct (as any free-floating one) + + //implMakeElement(aNewEntry) + SetNodeElement aNewElement = implMakeElement(_aNode, _aNewEntry ); + // _aNewEntry.tree()->rebuild(this, _aNode.accessor()); + + deferredSetNode(_aNode)->insertNewElement(aName, aNewElement); +} + +//----------------------------------------------------------------------------- +void DeferredViewStrategy::doRemoveElement(SetNode const& _aNode, Name const& aName) +{ + deferredSetNode(_aNode)->removeOldElement(aName); +} + +//----------------------------------------------------------------------------- +extern NodeFactory& getDeferredChangeFactory(); + +NodeFactory& DeferredViewStrategy::doGetNodeFactory() +{ + return getDeferredChangeFactory(); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +ViewStrategyRef createDeferredChangeStrategy(memory::Segment const * _pSegment) +{ + return new DeferredViewStrategy(_pSegment); +} + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +std::auto_ptr<SubtreeChange> DeferredViewStrategy::implPreCommitChanges(Node const& _aNode, configuration::ElementList& _rRemovedElements) +{ + std::auto_ptr<SubtreeChange> aRet; + + OSL_ASSERT (this->hasChanges( _aNode) ); + + if (_aNode.isSetNode()) + { + aRet = deferredSetNode(_aNode)->preCommitChanges(_aNode.accessor(),_rRemovedElements); + } + else if (_aNode.isGroupNode()) + { + std::auto_ptr<SubtreeChange> aGroupChange(deferredGroupNode(_aNode)->preCommitValueChanges(_aNode.accessor())); + + OSL_ASSERT(aGroupChange.get()); + if (aGroupChange.get()) + implPreCommitSubChanges( GroupNode(_aNode), _rRemovedElements, *aGroupChange); + + aRet = aGroupChange; + } + else + deferredValueNode(_aNode); + + return aRet; +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implFinishCommit(Node const& _aNode, SubtreeChange& rSubtreeChange) +{ + OSL_PRECOND( getSimpleNodeName(_aNode).toString() == rSubtreeChange.getNodeName(), "ERROR: Change name does not match node"); + + if (_aNode.isSetNode()) + { + OSL_ENSURE(rSubtreeChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); + + deferredSetNode(_aNode)->finishCommit(_aNode.accessor(),rSubtreeChange); + } + else if (_aNode.isGroupNode()) + { + OSL_ENSURE(!rSubtreeChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); + + deferredGroupNode(_aNode)->finishCommit(_aNode.accessor(),rSubtreeChange); + implFinishSubCommitted( GroupNode(_aNode), rSubtreeChange ); + } + else + { + deferredValueNode(_aNode); + OSL_ENSURE(false, "TreeImpl: Cannot finish commit: Unexpected node type"); + } +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implRevertCommit(Node const& _aNode, SubtreeChange& rSubtreeChange) +{ + OSL_PRECOND( getSimpleNodeName(_aNode).toString() == rSubtreeChange.getNodeName(), "ERROR: Change name does not match node"); + + if (_aNode.isSetNode()) + { + OSL_ENSURE(rSubtreeChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); + + deferredSetNode(_aNode)->revertCommit(_aNode.accessor(),rSubtreeChange); + } + else if (_aNode.isGroupNode()) + { + OSL_ENSURE(!rSubtreeChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); + + deferredGroupNode(_aNode)->revertCommit(_aNode.accessor(),rSubtreeChange); + implRevertSubCommitted( GroupNode(_aNode), rSubtreeChange ); + } + else + { + deferredValueNode(_aNode); + OSL_ENSURE(false, "TreeImpl: Cannot revert commit: Unexpected node type"); + } +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implFailedCommit(Node const& _aNode, SubtreeChange& rSubtreeChange) +{ + OSL_PRECOND( getSimpleNodeName(_aNode).toString() == rSubtreeChange.getNodeName(), "ERROR: Change name does not match node"); + + if (_aNode.isSetNode()) + { + OSL_ENSURE(rSubtreeChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); + + deferredSetNode(_aNode)->failedCommit(_aNode.accessor(),rSubtreeChange); + } + else if (_aNode.isGroupNode()) + { + OSL_ENSURE(!rSubtreeChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); + + deferredGroupNode(_aNode)->failedCommit(_aNode.accessor(),rSubtreeChange); + implFailedSubCommitted( GroupNode(_aNode), rSubtreeChange ); + } + else + { + deferredValueNode(_aNode); + OSL_ENSURE(false, "TreeImpl: Cannot handle commit failure: Unexpected node type"); + } +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implPreCommitSubChanges(GroupNode const & _aGroup, configuration::ElementList& _rRemovedElements, SubtreeChange& _rParentChange) +{ + for( Node aChild = _aGroup.getFirstChild(); aChild.is(); aChild = _aGroup.getNextChild(aChild) ) + { + if (this->hasChanges(aChild)) + { + std::auto_ptr<SubtreeChange> aSubChanges( this->implPreCommitChanges(aChild,_rRemovedElements) ); + std::auto_ptr<Change> aSubChangesBase( aSubChanges.release() ); + _rParentChange.addChange( aSubChangesBase ); + } + } +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implFinishSubCommitted(GroupNode const & _aGroup, SubtreeChange& aChangesParent) +{ + for(SubtreeChange::MutatingChildIterator + it = aChangesParent.begin_changes(), + stop = aChangesParent.end_changes(); + it != stop; + ++it) + { + if ( it->ISA(SubtreeChange) ) + { + Node aChild = _aGroup.findChild( configuration::makeNodeName(it->getNodeName(), Name::NoValidate()) ); + OSL_ENSURE( aChild.is(), "Changed sub-node not found in tree"); + + this->implFinishCommit(aChild, static_cast<SubtreeChange&>(*it)); + } + else + { + OSL_ENSURE(it->ISA(ValueChange), "Unexpected change type for nner node; change is ignored"); + OSL_ENSURE(! _aGroup.findChild( configuration::makeNodeName(it->getNodeName(), Name::NoValidate())).is() , + "Found sub(tree) node where a value was changed"); + } + } +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implRevertSubCommitted(GroupNode const & _aGroup, SubtreeChange& aChangesParent) +{ + for(SubtreeChange::MutatingChildIterator + it = aChangesParent.begin_changes(), + stop = aChangesParent.end_changes(); + it != stop; + ++it) + { + if ( it->ISA(SubtreeChange) ) + { + Node aChild = _aGroup.findChild( configuration::makeNodeName(it->getNodeName(), Name::NoValidate()) ); + OSL_ENSURE( aChild.is(), "Changed sub-node not found in tree"); + + this->implRevertCommit(aChild, static_cast<SubtreeChange&>(*it)); + } + else + { + OSL_ENSURE(it->ISA(ValueChange), "Unexpected change type for nner node; change is ignored"); + OSL_ENSURE(! _aGroup.findChild( configuration::makeNodeName(it->getNodeName(), Name::NoValidate())).is() , + "Found sub(tree) node where a value was changed"); + } + } +} +//----------------------------------------------------------------------------- + +void DeferredViewStrategy::implFailedSubCommitted(GroupNode const & _aGroup, SubtreeChange& aChangesParent) +{ + for(SubtreeChange::MutatingChildIterator + it = aChangesParent.begin_changes(), + stop = aChangesParent.end_changes(); + it != stop; + ++it) + { + if ( it->ISA(SubtreeChange) ) + { + Node aChild = _aGroup.findChild( configuration::makeNodeName(it->getNodeName(), Name::NoValidate()) ); + OSL_ENSURE( aChild.is(), "Changed sub-node not found in tree"); + + this->implFailedCommit(aChild, static_cast<SubtreeChange&>(*it)); + } + else + { + OSL_ENSURE(it->ISA(ValueChange), "Unexpected change type for nner node; change is ignored"); + OSL_ENSURE(! _aGroup.findChild( configuration::makeNodeName(it->getNodeName(), Name::NoValidate())).is() , + "Found sub(tree) node where a value was changed"); + } + } +} +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- + } +} diff --git a/configmgr/source/treemgr/deferredview.hxx b/configmgr/source/treemgr/deferredview.hxx new file mode 100644 index 000000000000..7c4bffab798d --- /dev/null +++ b/configmgr/source/treemgr/deferredview.hxx @@ -0,0 +1,138 @@ +/************************************************************************* + * + * $RCSfile: deferredview.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_DEFERREDVIEW_HXX_ +#define CONFIGMGR_DEFERREDVIEW_HXX_ + +#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_ +#include "viewstrategy.hxx" +#endif + + +namespace configmgr +{ + namespace view + { +//----------------------------------------------------------------------------- +// View behavior for direct data access +//----------------------------------------------------------------------------- + + class DeferredViewStrategy : public ViewStrategy + { + memory::Segment const * m_pSegment; + public: + explicit + DeferredViewStrategy(memory::Segment const * _pSegment) + : m_pSegment(_pSegment) + {} + + // ViewStrategy implementation + private: + // change handling -required + virtual bool doHasChanges(Node const& _aNode) const; + virtual void doMarkChanged(Node const& _aNode); + + + // change handling + virtual void doCollectChanges(Node const& _aNode, configuration::NodeChanges& rChanges) const; + + // commit protocol + virtual std::auto_ptr<SubtreeChange> doPreCommitChanges(Tree const& _aTree, configuration::ElementList& _rRemovedElements); + virtual void doFailedCommit(Tree const& _aTree, SubtreeChange& rChanges); + virtual void doFinishCommit(Tree const& _aTree, SubtreeChange& rChanges); + virtual void doRevertCommit(Tree const& _aTree, SubtreeChange& rChanges); + + // notification protocol + virtual configuration::ValueChangeImpl* doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& aName, ValueChange const& rExternalChange); + // virtual void doAdjustToElementChanges(configuration::NodeChangesInformation& rLocalChanges, SetNode const& _aNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth); + + // common attributes + virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const; + + // group member access + virtual configuration::ValueMemberNode doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const; + + // set element access + virtual void doInsertElement(SetNode const& _aNode, Name const& aName, configuration::SetEntry const& aNewEntry); + virtual void doRemoveElement(SetNode const& _aNode, Name const& aName); + + virtual memory::Segment const * doGetDataSegment() const { return m_pSegment; } + + virtual NodeFactory& doGetNodeFactory(); + private: + void implCollectChangesIn(Node const& _aNode, NodeChanges& rChanges) const; + // commit protocol + std::auto_ptr<SubtreeChange> implPreCommitChanges(Node const& _aNode, configuration::ElementList& _rRemovedElements); + void implFailedCommit(Node const& _aNode, SubtreeChange& rChanges); + void implFinishCommit(Node const& _aNode, SubtreeChange& rChanges); + void implRevertCommit(Node const& _aNode, SubtreeChange& rChanges); + + void implPreCommitSubChanges(GroupNode const & _aGroup, configuration::ElementList& _rRemovedElements, SubtreeChange& _rParentChange); + void implFailedSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges); + void implFinishSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges); + void implRevertSubCommitted(GroupNode const & _aGroup, SubtreeChange& rChanges); + + }; +//----------------------------------------------------------------------------- + } +} + +#endif // CONFIGMGR_DEFERREDVIEW_HXX_ diff --git a/configmgr/source/treemgr/directview.cxx b/configmgr/source/treemgr/directview.cxx new file mode 100644 index 000000000000..48ce08e6156d --- /dev/null +++ b/configmgr/source/treemgr/directview.cxx @@ -0,0 +1,177 @@ +/************************************************************************* + * + * $RCSfile: directview.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 <stdio.h> +#include "directview.hxx" + +#ifndef CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_ +#include "viewfactory.hxx" +#endif + +#ifndef CONFIGMGR_SETNODEBEHAVIOR_HXX_ +#include "setnodeimpl.hxx" +#endif +#ifndef CONFIGMGR_SETNODEACCESS_HXX +#include "setnodeaccess.hxx" +#endif + +namespace configmgr +{ + namespace view + { +//----------------------------------------------------------------------------- + +void DirectViewStrategy::implMarkNondefault(SetNode const& _aSetNode) +{ + data::SetNodeAccess aSetAccess = _aSetNode.getAccess(); + + OSL_ASSERT(aSetAccess.isValid()); + +// ----------------------------------------------------------------------------- +#ifdef NON_SHARABLE_DATA +// ----------------------------------------------------------------------------- + ISubtree* pTree = this->getDataForUpdate(aSetAccess); + + OSL_ASSERT(pTree); + + pTree->markAsDefault(false); +// ----------------------------------------------------------------------------- +#else // SHARABLE_DATA +// ----------------------------------------------------------------------------- + sharable::SetNode* pNode = this->getDataForUpdate(aSetAccess); + + OSL_ASSERT(pNode); + + pNode->info.markAsDefault(false); +// ----------------------------------------------------------------------------- +#endif // SHARABLE_DATA +// ----------------------------------------------------------------------------- +} +//----------------------------------------------------------------------------- + +bool DirectViewStrategy::doHasChanges(Node const& ) const +{ + return false; +} +//----------------------------------------------------------------------------- + +void DirectViewStrategy::doMarkChanged(Node const& ) +{ + // do nothing +} +//----------------------------------------------------------------------------- + +node::Attributes DirectViewStrategy::doAdjustAttributes(node::Attributes const& _aAttributes) const +{ + node::Attributes aAttributes = _aAttributes; + aAttributes.bFinalized |= !aAttributes.bWritable; + aAttributes.bWritable = true; + return aAttributes; +} +//----------------------------------------------------------------------------- + +configuration::ValueMemberNode DirectViewStrategy::doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const +{ + return ViewStrategy::doGetValueMember(_aNode,_aName,_bForUpdate); +} +//----------------------------------------------------------------------------- +void DirectViewStrategy::doInsertElement(SetNode const& _aNode, Name const& _aName, SetNodeEntry const& _aNewEntry) +{ + // move to this memory segment + // should already be direct (as any free-floating one) + + //implMakeElement(aNewEntry) + SetNodeElement aNewElement = implMakeElement(_aNode, _aNewEntry ); + // _aNewEntry.tree()->rebuild(this, _aNode.accessor()); + + _aNode.get_impl()->insertElement(_aName, aNewElement); + + aNewElement->attachTo( _aNode.getAccess(), _aName ); + + implMarkNondefault( _aNode ); +} +//----------------------------------------------------------------------------- + +void DirectViewStrategy::doRemoveElement(SetNode const& _aNode, Name const& _aName) +{ + SetNodeElement aOldElement = _aNode.get_impl()->removeElement(_aName); + + aOldElement->detachFrom( _aNode.getAccess(), _aName); + + implMarkNondefault( _aNode ); +} +//----------------------------------------------------------------------------- + +extern NodeFactory& getDirectAccessFactory(); + +NodeFactory& DirectViewStrategy::doGetNodeFactory() +{ + return getDirectAccessFactory(); +} +//----------------------------------------------------------------------------- + +ViewStrategyRef createDirectAccessStrategy(data::TreeSegment const & _aTreeSegment) +{ + return new DirectViewStrategy(_aTreeSegment); +} + +//----------------------------------------------------------------------------- + } +} diff --git a/configmgr/source/treemgr/directview.hxx b/configmgr/source/treemgr/directview.hxx new file mode 100644 index 000000000000..7916c1158e59 --- /dev/null +++ b/configmgr/source/treemgr/directview.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: directview.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_DIRECTVIEW_HXX_ +#define CONFIGMGR_DIRECTVIEW_HXX_ + +#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_ +#include "viewstrategy.hxx" +#endif + +#ifndef CONFIGMGR_TREESEGMENT_HXX +#include "treesegment.hxx" +#endif + +namespace configmgr +{ + namespace view + { +//----------------------------------------------------------------------------- +// View behavior for direct data access +//----------------------------------------------------------------------------- + + class DirectViewStrategy : public ViewStrategy + { + data::TreeSegment m_aTreeSegment; + public: + explicit + DirectViewStrategy(data::TreeSegment const & _aTreeSegment) + : m_aTreeSegment(_aTreeSegment) + {} + + protected: + // change handling -required + virtual bool doHasChanges(Node const& _aNode) const; + virtual void doMarkChanged(Node const& _aNode); + + // direct data access + virtual memory::Segment const * doGetDataSegment() const { return m_aTreeSegment.getSegment(); } + virtual memory::Segment * doGetDataSegmentForUpdate() { return m_aTreeSegment.getSegment(); } + + // common attributes + virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const; + + // group member access + virtual ValueMemberNode doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const; + + // set element access + virtual void doInsertElement(SetNode const& _aNode, Name const& aName, SetNodeEntry const& aNewEntry); + virtual void doRemoveElement(SetNode const& _aNode, Name const& aName); + + virtual NodeFactory& doGetNodeFactory(); + + private: + void implMarkNondefault(SetNode const& _aNode); + }; +//----------------------------------------------------------------------------- + } +} + +#endif // CONFIGMGR_DIRECTVIEW_HXX_ diff --git a/configmgr/source/treemgr/readonlyview.cxx b/configmgr/source/treemgr/readonlyview.cxx new file mode 100644 index 000000000000..756dadd66b18 --- /dev/null +++ b/configmgr/source/treemgr/readonlyview.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * $RCSfile: readonlyview.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 <stdio.h> +#include "readonlyview.hxx" + +#ifndef CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_ +#include "viewfactory.hxx" +#endif +#ifndef CONFIGMGR_CONFIGEXCEPT_HXX_ +#include "configexcept.hxx" +#endif + +namespace configmgr +{ + namespace view + { +//----------------------------------------------------------------------------- +void ReadOnlyViewStrategy::failReadOnly() const +{ + OSL_ENSURE(false, "Changing operation attempted on read-only node data"); + throw configuration::ConstraintViolation("INTERNAL ERROR: Trying to update a read-only node"); +} + +//----------------------------------------------------------------------------- + +bool ReadOnlyViewStrategy::doHasChanges(Node const& ) const +{ + return false; +} +//----------------------------------------------------------------------------- + +void ReadOnlyViewStrategy::doMarkChanged(Node const& ) +{ + failReadOnly(); +} +//----------------------------------------------------------------------------- + +node::Attributes ReadOnlyViewStrategy::doAdjustAttributes(node::Attributes const& _aAttributes) const +{ + node::Attributes aAttributes = _aAttributes; + aAttributes.bWritable = false; + return aAttributes; +} +//----------------------------------------------------------------------------- + +configuration::ValueMemberNode ReadOnlyViewStrategy::doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const +{ + if (_bForUpdate) failReadOnly(); + + return ViewStrategy::doGetValueMember(_aNode,_aName,_bForUpdate); +} +//----------------------------------------------------------------------------- + +void ReadOnlyViewStrategy::doInsertElement(SetNode const& , Name const& , SetNodeEntry const& ) +{ + failReadOnly(); +} +//----------------------------------------------------------------------------- + +void ReadOnlyViewStrategy::doRemoveElement(SetNode const& _aNode, Name const& _aName) +{ + failReadOnly(); +} +//----------------------------------------------------------------------------- + +extern NodeFactory& getReadAccessFactory(); + +NodeFactory& ReadOnlyViewStrategy::doGetNodeFactory() +{ + return getReadAccessFactory(); +} +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +ViewStrategyRef createReadOnlyStrategy(memory::Segment const * _pSegment) +{ + return new ReadOnlyViewStrategy(_pSegment); +} + +//----------------------------------------------------------------------------- + + } +} diff --git a/configmgr/source/treemgr/readonlyview.hxx b/configmgr/source/treemgr/readonlyview.hxx new file mode 100644 index 000000000000..d7dbb2040e0c --- /dev/null +++ b/configmgr/source/treemgr/readonlyview.hxx @@ -0,0 +1,112 @@ +/************************************************************************* + * + * $RCSfile: readonlyview.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_READONLYVIEW_HXX_ +#define CONFIGMGR_READONLYVIEW_HXX_ + +#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_ +#include "viewstrategy.hxx" +#endif + + +namespace configmgr +{ + namespace view + { +//----------------------------------------------------------------------------- +// View behavior for direct read-only access +//----------------------------------------------------------------------------- + + class ReadOnlyViewStrategy : public ViewStrategy + { + memory::Segment const * m_pSegment; + public: + explicit + ReadOnlyViewStrategy(memory::Segment const * _pSegment) + : m_pSegment(_pSegment) + {} + + protected: + // change handling -required + virtual bool doHasChanges(Node const& _aNode) const; + virtual void doMarkChanged(Node const& _aNode); + + // common attributes + virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const; + + // group member access + virtual ValueMemberNode doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const; + + // set element access + virtual void doInsertElement(SetNode const& _aNode, Name const& aName, SetNodeEntry const& aNewEntry); + virtual void doRemoveElement(SetNode const& _aNode, Name const& aName); + + virtual memory::Segment const * doGetDataSegment() const { return m_pSegment; } + + virtual NodeFactory& doGetNodeFactory(); + private: + void failReadOnly() const; + }; +//----------------------------------------------------------------------------- + } +} + +#endif // CONFIGMGR_READONLYVIEW_HXX_ diff --git a/configmgr/source/treemgr/viewaccess.cxx b/configmgr/source/treemgr/viewaccess.cxx new file mode 100644 index 000000000000..6c3b37b5b3cd --- /dev/null +++ b/configmgr/source/treemgr/viewaccess.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * $RCSfile: viewaccess.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "viewaccess.hxx" + +#ifndef CONFIGMGR_CONFIGNODEIMPL_HXX_ +#include "treeimpl.hxx" +#endif +#ifndef CONFIGMGR_CONFIGNODE_HXX_ +#include "noderef.hxx" +#endif + +//----------------------------------------------------------------------------- +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace view + { +//----------------------------------------------------------------------------- +bool ViewTreeAccess::isValid(configuration::NodeRef const& _aNodeArg) const +{ + return _aNodeArg.isValid(); +} + +//----------------------------------------------------------------------------- +configuration::NodeData* ViewTreeAccess::nodeData(configuration::NodeRef const& _aNodeArg) const +{ + return this->nodeData(_aNodeArg.getOffset()); +} + +//----------------------------------------------------------------------------- +configuration::NodeData* ViewTreeAccess::nodeData(NodeOffset _aNodePos) const +{ + return m_aTree.get_impl()->nodeData(_aNodePos); +} + +//----------------------------------------------------------------------------- + } +} + diff --git a/configmgr/source/treemgr/viewaccess.hxx b/configmgr/source/treemgr/viewaccess.hxx new file mode 100644 index 000000000000..5e89565bc241 --- /dev/null +++ b/configmgr/source/treemgr/viewaccess.hxx @@ -0,0 +1,290 @@ +/************************************************************************* + * + * $RCSfile: viewaccess.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_VIEWACCESS_HXX_ +#define CONFIGMGR_VIEWACCESS_HXX_ + +#ifndef CONFIGMGR_VIEWNODE_HXX_ +#include "viewnode.hxx" +#endif +#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_ +#include "viewstrategy.hxx" +#endif + +#ifndef _RTL_REF_HXX_ +#include <rtl/ref.hxx> +#endif + +//----------------------------------------------------------------------------- +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace configuration { class NodeRef; } +//----------------------------------------------------------------------------- + namespace view + { +//----------------------------------------------------------------------------- + + class ViewTreeAccess + { + rtl::Reference< ViewStrategy > m_xStrategy; + Tree m_aTree; + + private: + data::Accessor accessor() const { return m_aTree.accessor(); } + + public: + explicit ViewTreeAccess(Tree const & _aTree); + ViewTreeAccess(data::Accessor const & _aAccessor, configuration::TreeImpl& _rTree); + + rtl::Reference< view::ViewStrategy > getViewBehavior() { return m_xStrategy; } + public: + typedef configuration::NodeRef const& NodeArg; + typedef configuration::NodeOffset NodeOffset; + configuration::NodeData* nodeData(NodeArg _aNodeArg) const; + configuration::NodeData* nodeData(NodeOffset _aNodePos) const; + bool isValid(NodeArg _aNodeArg) const; + + Node makeNode(NodeArg _aNodeArg) const { return Node(m_aTree,nodeData(_aNodeArg)); } + Node makeNode(NodeOffset _aNodePos) const { return Node(m_aTree,nodeData(_aNodePos)); } + + bool isSetNode (NodeArg _aNodeArg) const { return makeNode(_aNodeArg).isSetNode(); } + bool isGroupNode(NodeArg _aNodeArg) const { return makeNode(_aNodeArg).isGroupNode(); } + bool isValueNode(NodeArg _aNodeArg) const { return makeNode(_aNodeArg).isValueNode(); } + + bool isSetNodeAt (NodeOffset _aNodeArg) const { return makeNode(_aNodeArg).isSetNode(); } + bool isGroupNodeAt(NodeOffset _aNodeArg) const { return makeNode(_aNodeArg).isGroupNode(); } + bool isValueNodeAt(NodeOffset _aNodeArg) const { return makeNode(_aNodeArg).isValueNode(); } + + SetNode toSetNode (NodeArg _aNodeArg) const + { return SetNode (makeNode(_aNodeArg)); } + + GroupNode toGroupNode(NodeArg _aNodeArg) const + { return GroupNode(makeNode(_aNodeArg)); } + + ValueNode toValueNode(NodeArg _aNodeArg) const + { return ValueNode(makeNode(_aNodeArg)); } + + SetNode getSetNodeAt (NodeOffset _aNodeArg) const + { return SetNode (makeNode(_aNodeArg)); } + + GroupNode getGroupNodeAt(NodeOffset _aNodeArg) const + { return GroupNode(makeNode(_aNodeArg)); } + + ValueNode getValueNodeAt(NodeOffset _aNodeArg) const + { return ValueNode(makeNode(_aNodeArg)); } + // node attributes + public: + /// retrieve the name of the node + Name getName(NodeArg _aNode) const + { return m_xStrategy->getName(makeNode(_aNode)); } + + /// retrieve the attributes of the node + node::Attributes getAttributes(NodeArg _aNode) const + { return m_xStrategy->getAttributes(makeNode(_aNode)); } + + /// retrieve the name of the tree root + Name getRootName() const + { return m_xStrategy->getName( getRootNode(m_aTree) ); } + + /// retrieve the attributes of the tree root + node::Attributes getRootAttributes() const + { return m_xStrategy->getAttributes( getRootNode(m_aTree) ); } + + // tracking pending changes + public: + void collectChanges(configuration::NodeChanges& rChanges) const + { m_xStrategy->collectChanges(m_aTree,rChanges); } + + bool hasChanges() const + { return m_xStrategy->hasChanges(m_aTree); } + + bool hasChanges(NodeArg _aNode) const + { return m_xStrategy->hasChanges(makeNode(_aNode)); } + + void markChanged(NodeArg _aNode) + { m_xStrategy->markChanged(makeNode(_aNode)); } + + // commit protocol + public: + std::auto_ptr<SubtreeChange> preCommitChanges(configuration::ElementList& _rRemovedElements) + { return m_xStrategy->preCommitChanges(m_aTree,_rRemovedElements); } + + void finishCommit(SubtreeChange& rRootChange) + { m_xStrategy->finishCommit(m_aTree,rRootChange); } + + void revertCommit(SubtreeChange& rRootChange) + { m_xStrategy->revertCommit(m_aTree,rRootChange); } + + void recoverFailedCommit(SubtreeChange& rRootChange) + { m_xStrategy->recoverFailedCommit(m_aTree,rRootChange); } + + // notification protocol + public: + /// Adjust the internal representation after external changes to the original data - build NodeChangeInformation objects for notification + void adjustToChanges(configuration::NodeChangesInformation& rLocalChanges, NodeArg _aNode, SubtreeChange const& aExternalChange) + { m_xStrategy->adjustToChanges(rLocalChanges,makeNode(_aNode), aExternalChange); } + + // visitor dispatch + public: + configuration::GroupMemberVisitor::Result dispatchToValues(GroupNode const& _aNode, configuration::GroupMemberVisitor& _aVisitor) const + { return m_xStrategy->dispatchToValues(_aNode,_aVisitor); } + + /// Call <code>aVisitor.visit(aElement)</code> for each element in this set until SetNodeVisitor::DONE is returned. + configuration::SetNodeVisitor::Result dispatchToElements(SetNode const& _aNode, configuration::SetNodeVisitor& _aVisitor) const + { return m_xStrategy->dispatchToElements(_aNode,_aVisitor); } + + // value (element) node specific operations + public: + /// Does this node assume its default value + /// retrieve the current value of this node + UnoAny getValue(ValueNode const& _aNode) const + { return m_xStrategy->getValue(_aNode); } + + /// get the type of this value + UnoType getValueType(ValueNode const& _aNode) const + { return m_xStrategy->getValueType(_aNode); } + + + // group node specific operations + public: + /// does this hold a child value of the given name + bool hasValue(GroupNode const& _aNode, Name const& _aName) const + { return m_xStrategy->hasValue(_aNode,_aName); } + + /// are defaults for this node available ? + bool areValueDefaultsAvailable(GroupNode const& _aNode) const + { return m_xStrategy->areValueDefaultsAvailable(_aNode); } + + /// retrieve data for the child value of the given name + configuration::ValueMemberNode getValue(GroupNode & _aNode, Name const& _aName) const + { return m_xStrategy->getValue(_aNode,_aName); } + + /// retrieve data for updating the child value of the given name + configuration::ValueMemberUpdate getValueForUpdate(GroupNode const & _aNode, Name const& _aName) const + { return m_xStrategy->getValueForUpdate(_aNode,_aName); } + + // set node specific operations + public: + /// does this set contain any elements (loads elements if needed) + bool isEmpty(SetNode const& _aNode) const + { return m_xStrategy->isEmpty(_aNode); } + + /// does this set contain an element named <var>aName</var> (loads elements if needed) + configuration::SetEntry findElement(SetNode const& _aNode, Name const& aName) const + { return m_xStrategy->findElement(_aNode,aName); } + + /// does this set contain an element named <var>aName</var> (and is that element loaded ?) + configuration::SetEntry findAvailableElement(SetNode const& _aNode, Name const& aName) const + { return m_xStrategy->findAvailableElement(_aNode,aName); } + + /// insert a new entry into this set + void insertElement(SetNode const& _aNode, Name const& aName, configuration::SetEntry const& aNewEntry) + { m_xStrategy->insertElement(_aNode,aName,aNewEntry); } + + /// remove an existing entry into this set + void removeElement(SetNode const& _aNode, Name const& aName) + { m_xStrategy->removeElement(_aNode,aName); } + + /** Create a Subtree change as 'diff' which allows transforming the set to its default state + (given that <var>_rDefaultTree</var> points to a default instance of this set) + <p>Ownership of added trees should be transferred to the SubtreeChange.</p> + */ + std::auto_ptr<SubtreeChange> differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree) + { return m_xStrategy->differenceToDefaultState(_aNode,_rDefaultTree); } + + /// Get the template that describes elements of this set + configuration::TemplateHolder getElementTemplate(SetNode const& _aNode) const + { return m_xStrategy->getElementTemplate(_aNode); } + + /// Get a template provider that can create new elements for this set + configuration::TemplateProvider getTemplateProvider(SetNode const& _aNode) const + { return m_xStrategy->getTemplateProvider(_aNode); } + + // changing state/strategy + public: + // replace m_xStrategy by a direct ViewStrategy (commiting changes to the data), if possible + // void makeDirect (); + + }; + +//----------------------------------------------------------------------------- + inline + ViewTreeAccess::ViewTreeAccess(Tree const & _aTree) + : m_xStrategy() + , m_aTree(_aTree) + { + m_xStrategy = _aTree.get_impl()->getViewBehavior(); + } + +//----------------------------------------------------------------------------- + inline + ViewTreeAccess::ViewTreeAccess(data::Accessor const & _aAccessor, configuration::TreeImpl& _rTree) + : m_xStrategy(_rTree.getViewBehavior()) + , m_aTree(_aAccessor,_rTree) + { + } + +//----------------------------------------------------------------------------- + } +} + +#endif // CONFIGMGR_VIEWACCESS_HXX_ diff --git a/configmgr/source/treemgr/viewfactory.hxx b/configmgr/source/treemgr/viewfactory.hxx new file mode 100644 index 000000000000..e99c0e364bb1 --- /dev/null +++ b/configmgr/source/treemgr/viewfactory.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * $RCSfile: viewfactory.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_ +#define CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_ + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace memory { class Segment; } + namespace data { class TreeSegment; } + + namespace view + { + // Different standard (static) strategies + //--------------------------------------------------------------------- + typedef rtl::Reference<ViewStrategy> ViewStrategyRef; + + /// provides a factory for read-only node implementations + ViewStrategyRef createReadOnlyStrategy(memory::Segment const * _pSegment); + /// provides a factory for nodes that cache changes temporarily + ViewStrategyRef createDeferredChangeStrategy(memory::Segment const * _pSegment); + /// provides a factory for immediately commiting node implementations + ViewStrategyRef createDirectAccessStrategy(data::TreeSegment const & _aTreeSegment); + //--------------------------------------------------------------------- + } + +//----------------------------------------------------------------------------- + +} + +#endif // CONFIGMGR_VIEWBEHAVIORFACTORY_HXX_ diff --git a/configmgr/source/treemgr/viewnode.cxx b/configmgr/source/treemgr/viewnode.cxx new file mode 100644 index 000000000000..2ad71a53cd0a --- /dev/null +++ b/configmgr/source/treemgr/viewnode.cxx @@ -0,0 +1,179 @@ +/************************************************************************* + * + * $RCSfile: viewnode.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "viewnode.hxx" + +#ifndef CONFIGMGR_VALUENODEACCESS_HXX +#include "valuenodeaccess.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEACCESS_HXX +#include "groupnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_SETNODEACCESS_HXX +#include "setnodeaccess.hxx" +#endif + +#ifndef CONFIGMGR_SETNODEBEHAVIOR_HXX_ +#include "setnodeimpl.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEBEHAVIOR_HXX_ +#include "groupnodeimpl.hxx" +#endif +#ifndef CONFIGMGR_VALUENODEBEHAVIOR_HXX_ +#include "valuenodeimpl.hxx" +#endif + +#ifndef CONFIGMGR_CONFIGNODEIMPL_HXX_ +#include "treeimpl.hxx" +#endif +#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_ +#include "viewstrategy.hxx" +#endif + +//----------------------------------------------------------------------------- +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace view + { +//----------------------------------------------------------------------------- + rtl::Reference< view::ViewStrategy > getViewBehavior(Tree const & _aTree) + { + Tree::TreeData* pTreeData = _aTree.get_impl(); + return pTreeData->getViewBehavior(); + } + +//----------------------------------------------------------------------------- + static inline Node makeNode_(Tree const & _aTree, configuration::NodeOffset nOffset) + { + Tree::TreeData * pTreeData = _aTree.get_impl(); + return Node(_aTree, pTreeData->nodeData(nOffset)); + } +//----------------------------------------------------------------------------- + Node Node::getParent() const + { + Tree::TreeData * pTreeData = this->tree().get_impl(); + return makeNode_(tree(), pTreeData->parent_(this->get_offset())); + } + +//----------------------------------------------------------------------------- + Node Node::getNextSibling() const + { + Tree::TreeData * pTreeData = this->tree().get_impl(); + return makeNode_(tree(), pTreeData->nextSibling_(this->get_offset())); + } + +//----------------------------------------------------------------------------- + Node GroupNode::findChild(configuration::Name const& _aName) const + { + Tree::TreeData * pTreeData = this->tree().get_impl(); + return makeNode_(tree(), pTreeData->findChild_(node().get_offset(), _aName)); + } + +//----------------------------------------------------------------------------- + Node GroupNode::getFirstChild() const + { + Tree::TreeData * pTreeData = this->tree().get_impl(); + return makeNode_(tree(), pTreeData->firstChild_(node().get_offset())); + } + +//----------------------------------------------------------------------------- + Node GroupNode::getNextChild(Node const& _aAfterNode) const + { + Tree::TreeData * pTreeData = this->tree().get_impl(); + OSL_ASSERT(pTreeData->parent_(_aAfterNode.get_offset()) == this->node().get_offset()); + return makeNode_(tree(), pTreeData->findNextChild_(node().get_offset(),_aAfterNode.get_offset())); + } + +//----------------------------------------------------------------------------- +/* data::TreeAccessor Tree::getAccess() const // has a TreeAccessor + { + return get_impl()->getOriginalTreeAccess(m_accessor); + } +*/ +//----------------------------------------------------------------------------- + data::NodeAccess Node::getAccess() const + { + return get_impl()->getOriginalNodeAccess(accessor()); + } + +//----------------------------------------------------------------------------- + data::ValueNodeAccess ValueNode::getAccess() const + { + return get_impl()->getDataAccess(accessor()); + } + +//----------------------------------------------------------------------------- + data::GroupNodeAccess GroupNode::getAccess() const + { + return get_impl()->getDataAccess(accessor()); + } + +//----------------------------------------------------------------------------- + data::SetNodeAccess SetNode::getAccess() const + { + return get_impl()->getDataAccess(accessor()); + } + +//----------------------------------------------------------------------------- + } +} + diff --git a/configmgr/source/treemgr/viewnode.hxx b/configmgr/source/treemgr/viewnode.hxx new file mode 100644 index 000000000000..839b18fcfbff --- /dev/null +++ b/configmgr/source/treemgr/viewnode.hxx @@ -0,0 +1,288 @@ +/************************************************************************* + * + * $RCSfile: viewnode.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_VIEWNODE_HXX_ +#define CONFIGMGR_VIEWNODE_HXX_ + +#ifndef CONFIGMGR_CONFIGNODEIMPL_HXX_ +#include "treeimpl.hxx" +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace configuration + { + class Name; + struct ElementTreeData; + } +//----------------------------------------------------------------------------- + namespace view + { + //------------------------------------------------------------------------- + using configuration::Name; + //------------------------------------------------------------------------- + struct Tree // is a tree fragment + { + typedef configuration::TreeImpl TreeData; + + Tree(data::Accessor const& _accessor, TreeData& _ref) + : m_accessor(_ref.getDataAccessor(_accessor)), m_addr(&_ref) + {} + + // low-level access +// TreeData* operator->() const { return m_addr; } + + TreeData* get_impl() const + { return m_addr; } + + data::Accessor accessor() const // has a Accessor + { return m_accessor; } + + // data::TreeAccessor getAccess() const; // has a TreeAccessor + + private: + data::Accessor m_accessor; // has a TreeAccessor + TreeData * m_addr; // has a TreeAddress or NodeAddress + }; + //------------------------------------------------------------------------- + struct Node + { + typedef configuration::NodeOffset NodeOffset; + typedef configuration::NodeData NodeData; + typedef configuration::NodeImpl * NodeAddress; + + Node(Tree const& _tree, NodeData* _addr) + : m_tree(_tree), m_addr(_addr) + {} + + Node(data::Accessor const& _accessor, Tree::TreeData& _ref, NodeOffset _offs) + : m_tree(_accessor,_ref), m_addr( _ref.nodeData(_offs)) + {} + + bool is() const { return m_addr != 0; } + + Node getParent() const; + Node getNextSibling() const; + + bool isSetNode() const { return is() && data().isSetNode(this->accessor()); } + bool isGroupNode() const { return is() && data().isGroupNode(this->accessor()); } + bool isValueNode() const { return is() && data().isValueElementNode(this->accessor()); } + + // low-level access +// NodeAddress operator->() const { return &data().nodeImpl(); } + + NodeData& data() const { return *m_addr; } + + NodeAddress get_impl() const + { return is() ? &data().nodeImpl() : NULL; } + + NodeOffset get_offset() const + { return is() ? m_tree.get_impl()->nodeOffset( this->data() ) : 0; } + + Tree tree() const // has a Tree + { return m_tree; } + + data::Accessor accessor() const // has a Accessor + { return m_tree.accessor(); } + + data::NodeAccess getAccess() const; // has a NodeAccess + + private: + Tree m_tree; // has a Tree + Accessor + NodeData* m_addr; // has a NodeAddress + }; + //------------------------------------------------------------------------- + struct ValueNode // has/is a Node + { + typedef configuration::ValueElementNodeImpl NodeType; + Node m_node; + + explicit + ValueNode(Node const& _node) + : m_node(_node) + {} + + bool is() const { return m_node.isValueNode(); } + + // low-level access + // NodeType* operator->() const { return &m_node.data().valueElementImpl(accessor()); } + + NodeType* get_impl() const + { return is() ? &m_node.data().valueElementImpl(accessor()) : NULL; } + + Node node() const // has a Node + { return m_node; } + + Tree tree() const // has a Tree + { return m_node.tree(); } + + data::Accessor accessor() const // has a TreeAccessor + { return m_node.accessor(); } + + data::ValueNodeAccess getAccess() const; // has a NodeAccess + }; + //------------------------------------------------------------------------- + struct GroupNode // has/is a Node + { + typedef configuration::GroupNodeImpl NodeType; + Node m_node; + + explicit + GroupNode(Node const& _node) + : m_node(_node) + {} + + bool is() const { return m_node.isGroupNode(); } + + Node findChild(configuration::Name const& _aName) const; + Node getFirstChild() const; + Node getNextChild(Node const& _aAfterNode) const; + +// NodeType* operator->() const { return &m_node.data().groupImpl(accessor()); } + + NodeType* get_impl() const + { return is() ? &m_node.data().groupImpl(accessor()) : NULL; } + + Node node() const // has a Node + { return m_node; } + + Tree tree() const // has a Tree + { return m_node.tree(); } + + data::Accessor accessor() const // has a TreeAccessor + { return m_node.accessor(); } + + data::GroupNodeAccess getAccess() const; // has a NodeAccess + }; + //------------------------------------------------------------------------- + struct SetNode // has/is a Node + { + typedef configuration::SetNodeImpl NodeType; + typedef configuration::ElementTreeData Element; + + Node m_node; + + explicit + SetNode(Node const& _node) + : m_node(_node) + {} + + bool is() const { return m_node.isSetNode(); } + + // NodeType* operator->() const { return &m_node.data().setImpl(accessor()); } + + NodeType* get_impl() const + { return is() ? &m_node.data().setImpl(accessor()) : 0; } + + Node node() const // has a Node + { return m_node; } + + Tree tree() const // has a Tree + { return m_node.tree(); } + + data::Accessor accessor() const // has a TreeAccessor + { return m_node.accessor(); } + + data::SetNodeAccess getAccess() const; // has a NodeAccess + }; + //------------------------------------------------------------------------- + inline + Node getRootNode(Tree const & _aTree) + { + Tree::TreeData* pTreeData = _aTree.get_impl(); + return Node(_aTree,pTreeData->nodeData(pTreeData->root_())); + } + + //------------------------------------------------------------------------- + inline + Name getSimpleRootName(Tree const & _aTree) + { + Tree::TreeData* pTreeData = _aTree.get_impl(); + return pTreeData->getSimpleRootName(); + } + + //------------------------------------------------------------------------- + inline + bool isValidNode(Node const & _aNode) + { + Tree::TreeData* pTreeData = _aNode.tree().get_impl(); + return pTreeData->isValidNode(_aNode.get_offset()); + } + + //------------------------------------------------------------------------- + inline + Name getSimpleNodeName(Node const & _aNode) + { + Tree::TreeData* pTreeData = _aNode.tree().get_impl(); + return pTreeData->getSimpleNodeName(_aNode.get_offset()); + } + + //------------------------------------------------------------------------- + extern + rtl::Reference< view::ViewStrategy > getViewBehavior(Tree const & _aTree); + //------------------------------------------------------------------------- + } +//----------------------------------------------------------------------------- +} +//----------------------------------------------------------------------------- + +#endif // CONFIGMGR_VIEWNODE_HXX_ diff --git a/configmgr/source/treemgr/viewstrategy.cxx b/configmgr/source/treemgr/viewstrategy.cxx new file mode 100644 index 000000000000..4cf03f02dc2f --- /dev/null +++ b/configmgr/source/treemgr/viewstrategy.cxx @@ -0,0 +1,820 @@ +/************************************************************************* + * + * $RCSfile: viewstrategy.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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 "viewstrategy.hxx" + +#ifndef CONFIGMGR_VALUENODEBEHAVIOR_HXX_ +#include "valuenodeimpl.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEBEHAVIOR_HXX_ +#include "groupnodeimpl.hxx" +#endif +#ifndef CONFIGMGR_SETNODEBEHAVIOR_HXX_ +#include "setnodeimpl.hxx" +#endif +#ifndef CONFIGMGR_CHANGE_HXX +#include "change.hxx" +#endif + +#ifndef CONFIGMGR_NODEVISITOR_HXX +#include "nodevisitor.hxx" +#endif +#ifndef CONFIGMGR_GROUPNODEACCESS_HXX +#include "groupnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_SETNODEACCESS_HXX +#include "setnodeaccess.hxx" +#endif +#ifndef CONFIGMGR_UPDATEACCESSOR_HXX +#include "updateaccessor.hxx" +#endif + +#ifndef CONFIGMGR_CONFIGCHANGE_HXX_ +#include "nodechange.hxx" +#endif +#ifndef CONFIGMGR_CONFIGCHANGEIMPL_HXX_ +#include "nodechangeimpl.hxx" +#endif +#ifndef CONFIGMGR_NODECONVERTER_HXX +#include "nodeconverter.hxx" +#endif +//----------------------------------------------------------------------------- +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace view + { +//----------------------------------------------------------------------------- + using configuration::SetEntry; + using configuration::ElementList; + using configuration::GroupMemberVisitor; + using configuration::SetNodeVisitor; +//----------------------------------------------------------------------------- +// virtual void doInitElements( data::SetNodeAccess const& _aNode, TreeDepth nDepth); + + static + inline + data::ValueNodeAccess getMemberValueAccess( GroupNode const & _aGroupNode, Name const & _aName ) + { + configuration::GroupNodeImpl* pGroupData = _aGroupNode.get_impl(); + return pGroupData->getOriginalValueNode(_aGroupNode.accessor(),_aName); + } + +//----------------------------------------------------------------------------- + void ViewStrategy::checkInstance(Tree const& _aTreeForThis) const + { + OSL_ENSURE( getViewBehavior(_aTreeForThis).get() == this, + "Tree operation dispatched to wrong strategy instance"); + } +//----------------------------------------------------------------------------- + void ViewStrategy::collectChanges(Tree const& _aTree, NodeChanges& rChanges) const + { + checkInstance(_aTree); + doCollectChanges( getRootNode(_aTree), rChanges ); + } + + bool ViewStrategy::hasChanges(Tree const& _aTree) const + { + checkInstance(_aTree); + return hasChanges( getRootNode(_aTree) ); + } + + // mark the given node and all its ancestors (we can stop when we hit a node that already is marked) + void ViewStrategy::markChanged(Node const& _aNode) + { + Tree aTree = _aNode.tree(); + checkInstance(aTree); + + Node aNode = _aNode; + if (aNode.is()) + { + do + { + this->doMarkChanged(aNode); + + aNode = aNode.getParent(); + } + while (aNode.is() && !this->hasChanges( aNode )); + } + + if (!aNode.is()) // just marked the root + { + configuration::TreeImpl* pTreeData = aTree.get_impl(); + configuration::TreeImpl* pContext = pTreeData->getContextTree(); + NodeOffset nContext = pTreeData->getContextNode(); + if (pContext) + { + OSL_ASSERT(pContext->isValidNode(nContext)); + + view::Node aContextNode(aNode.accessor(),*pContext,nContext); + pContext->getViewBehavior()->markChanged(aContextNode); + } + } + } + +//----------------------------------------------------------------------------- + data::NodeAddress::DataType * ViewStrategy::getDataForUpdate(data::NodeAccess const & _aNode) + { + typedef data::NodeAddress::DataType DataType; + DataType * pResult = implAccessForUpdate(_aNode); + OSL_ASSERT(!pResult || _aNode.getDataPtr() == pResult); + return pResult; + } + + data::SetNodeAddress::DataType * ViewStrategy::getDataForUpdate(data::SetNodeAccess const & _aNode) + { + typedef data::SetNodeAddress::DataType DataType; +#ifdef NON_SHARABLE_DATA + DataType * pResult = static_cast<DataType *>(implAccessForUpdate(_aNode)); +#else // SHARABLE_DATA + sharable::Node * pNode = implAccessForUpdate(_aNode); + DataType * pResult = pNode ? pNode->setData() : 0; +#endif // SHARABLE_DATA + OSL_ASSERT(!pResult || &_aNode.data() == pResult); + return pResult; + } + + data::GroupNodeAddress::DataType * ViewStrategy::getDataForUpdate(data::GroupNodeAccess const & _aNode) + { + typedef data::GroupNodeAddress::DataType DataType; +#ifdef NON_SHARABLE_DATA + DataType * pResult = static_cast<DataType *>(implAccessForUpdate(_aNode)); +#else // SHARABLE_DATA + sharable::Node * pNode = implAccessForUpdate(_aNode); + DataType * pResult = pNode ? pNode->groupData() : 0; +#endif // SHARABLE_DATA + OSL_ASSERT(!pResult || &_aNode.data() == pResult); + return pResult; + } + + data::ValueNodeAddress::DataType * ViewStrategy::getDataForUpdate(data::ValueNodeAccess const & _aNode) + { + typedef data::ValueNodeAddress::DataType DataType; +#ifdef NON_SHARABLE_DATA + DataType * pResult = static_cast<DataType *>(implAccessForUpdate(_aNode)); +#else // SHARABLE_DATA + sharable::Node * pNode = implAccessForUpdate(_aNode); + DataType * pResult = pNode ? pNode->valueData() : 0; +#endif // SHARABLE_DATA + OSL_ASSERT(!pResult || &_aNode.data() == pResult); + return pResult; + } + +//----------------------------------------------------------------------------- + data::NodeAddress::DataType * ViewStrategy::implAccessForUpdate(data::NodeAccess const & _aNode) + { + if (memory::Segment * pUpdatableSegment = doGetDataSegmentForUpdate()) + { + void * p = memory::UpdateAccessor(pUpdatableSegment).validate(_aNode.rawAddress()); + + OSL_ASSERT(const_cast<const void *>(p) == _aNode.getDataPtr()); + + return static_cast<data::NodeAddress::DataType*>(p); + } + + else + return NULL; + } + +//----------------------------------------------------------------------------- + memory::Segment * ViewStrategy::doGetDataSegmentForUpdate() + { + return NULL; + } + + +//----------------------------------------------------------------------------- + std::auto_ptr<SubtreeChange> ViewStrategy::preCommitChanges(Tree const& _aTree, ElementList& _rRemovedElements) + { + checkInstance(_aTree); + return doPreCommitChanges( _aTree, _rRemovedElements); + } + + void ViewStrategy::finishCommit(Tree const& _aTree, SubtreeChange& rRootChange) + { + checkInstance(_aTree); + doFinishCommit(_aTree, rRootChange); + } + + void ViewStrategy::revertCommit(Tree const& _aTree, SubtreeChange& rRootChange) + { + checkInstance(_aTree); + doRevertCommit(_aTree, rRootChange); + } + + void ViewStrategy::recoverFailedCommit(Tree const& _aTree, SubtreeChange& rRootChange) + { + checkInstance(_aTree); + doFailedCommit(_aTree, rRootChange); + } + +//----------------------------------------------------------------------------- + void ViewStrategy::adjustToChanges(NodeChangesInformation& rLocalChanges, Node const& _aNode, SubtreeChange const& aExternalChange) + { + OSL_PRECOND( isValidNode(_aNode), "ERROR: Valid node required for adjusting to changes" ); + OSL_PRECOND( getSimpleNodeName(_aNode).toString() == aExternalChange.getNodeName(), "Name of change does not match actual node" ); + + checkInstance(_aNode.tree()); + + configuration::TreeImpl * pTreeData = _aNode.tree().get_impl(); + + if (_aNode.isSetNode()) + { + OSL_ENSURE(aExternalChange.isSetNodeChange(),"ERROR: Change type GROUP does not match set"); + + TreeDepth nDepth = pTreeData->getRemainingDepth(_aNode.get_offset()); + + implAdjustToElementChanges( rLocalChanges, SetNode(_aNode), aExternalChange, nDepth); + } + else if (_aNode.isGroupNode()) + { + OSL_ENSURE(!aExternalChange.isSetNodeChange(),"ERROR: Change type SET does not match group"); + + GroupNode aGroupNode(_aNode); + + implAdjustToValueChanges(rLocalChanges, aGroupNode, aExternalChange); + implAdjustToSubChanges( rLocalChanges, aGroupNode, aExternalChange); + } + else // might occur on external change (?) + { + OSL_ENSURE(_aNode.isValueNode(), "TreeImpl: Unknown node type to adjust to changes"); + + OSL_ENSURE(_aNode.get_offset() == pTreeData->root_(), "TreeImpl: Unexpected node type - non-root value element"); + + OSL_ENSURE(false,"ERROR: Change type does not match node: Trying to apply subtree change to value element."); + } + } + +//----------------------------------------------------------------------------- + + void ViewStrategy::addLocalChangeHelper( NodeChangesInformation& rLocalChanges_, configuration::NodeChange const& aChange_) + { + aChange_.getChangeInfos(rLocalChanges_); + } + +//----------------------------------------------------------------------------- + // TO DO: create CommitAction class, which is returned by precommit (if applicable) + + std::auto_ptr<SubtreeChange> ViewStrategy::doPreCommitChanges(Tree const& _aTree, configuration::ElementList& ) + { + OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View"); + return std::auto_ptr<SubtreeChange>(); + } + + void ViewStrategy::doFinishCommit(Tree const& _aTree, SubtreeChange& ) + { + OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View"); + OSL_ENSURE(false,"ERROR: Cannot finish commit for unexpected changes"); + } + + void ViewStrategy::doRevertCommit(Tree const& _aTree, SubtreeChange& ) + { + OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View"); + OSL_ENSURE(false,"ERROR: Cannot revert commit for unexpected changes"); + } + + void ViewStrategy::doFailedCommit(Tree const& _aTree, SubtreeChange& ) + { + OSL_ENSURE(!hasChanges(getRootNode(_aTree)),"Unexpected changes in View"); + OSL_ENSURE(false,"ERROR: Cannot recover commit for unexpected changes"); + } + +//----------------------------------------------------------------------------- + void ViewStrategy::implAdjustToElementChange(NodeChangesInformation& rLocalChanges, SetNode const& _aSetNode, Change const& rElementChange, TreeDepth nDepth) + { + using namespace configuration; + + SetNodeImpl * pSetData = _aSetNode.get_impl(); + + OSL_ENSURE( pSetData->implHasLoadedElements() , "Unexpected call: Processing element change in uninitialized set"); + + Name aName = makeElementName( rElementChange.getNodeName(), Name::NoValidate() ); + + SetElementChangeImpl* pThisChange = 0; + if (rElementChange.ISA(AddNode)) + { + AddNode const& aAddNode = static_cast<AddNode const&>(rElementChange); + + SetNodeElement aNewElement = pSetData->makeAdditionalElement(_aSetNode.accessor(),this,aAddNode,nDepth); + + pThisChange = pSetData->doAdjustToAddedElement(_aSetNode.accessor(), aName, aAddNode,aNewElement); + } + else if (rElementChange.ISA(RemoveNode)) + { + RemoveNode const& aRemoveNode = static_cast<RemoveNode const&>(rElementChange); + + pThisChange = pSetData->doAdjustToRemovedElement(_aSetNode.accessor(), aName, aRemoveNode); + } + else + { + if (nDepth > 0 || (NULL != pSetData->doFindElement(aName)) )// found even beyond nDepth ? + { + pThisChange = pSetData->doAdjustChangedElement(_aSetNode.accessor(),rLocalChanges,aName, rElementChange); + } + } + + if (pThisChange) + { + addLocalChangeHelper( rLocalChanges, NodeChange(pThisChange) ); + } + } + + void ViewStrategy::implAdjustToElementChanges(NodeChangesInformation& rLocalChanges, SetNode const& _aSetNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth) + { + + if (nDepth > 0) + { + configuration::SetNodeImpl * pSetData = _aSetNode.get_impl(); + + OSL_ENSURE( pSetData->getTemplateProvider().isValid(), "Cannot adjust SetNode to changes - node was never initialized" ); + + if (pSetData->implHasLoadedElements()) + { + TreeDepth const nElementDepth = configuration::childDepth(nDepth); + for (SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it) + { + this->implAdjustToElementChange(rLocalChanges, _aSetNode, *it, nElementDepth); + } + } + else + { + OSL_ENSURE( !hasChanges(_aSetNode.node()),"Cannot have changes to consider when no elements are loaded"); + + pSetData->convertChanges( rLocalChanges, _aSetNode.accessor(), rExternalChanges, nDepth); + } + } + } + + configuration::ValueChangeImpl* ViewStrategy::doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& _aName, ValueChange const& _rExternalChange) + { + using namespace configuration; + + ValueChangeImpl* pChangeImpl = NULL; + + data::ValueNodeAccess aLocalNode = getMemberValueAccess(_aGroupNode,_aName); + if (aLocalNode.isValid()) + { + switch( _rExternalChange. getMode() ) + { + case ValueChange::wasDefault: + case ValueChange::changeValue: + pChangeImpl = new ValueReplaceImpl( _rExternalChange.getNewValue(), _rExternalChange.getOldValue() ); + break; + + break; + + case ValueChange::setToDefault: + pChangeImpl = new ValueResetImpl( _rExternalChange.getNewValue(), _rExternalChange.getOldValue() ); + break; + + default: OSL_ENSURE(false, "Unknown change mode"); + // fall thru to next case for somewhat meaningful return value + case ValueChange::changeDefault: + { + UnoAny aLocalValue = aLocalNode.getValue(); + + pChangeImpl = new ValueReplaceImpl( aLocalValue, aLocalValue ); + } + break; + } + OSL_ASSERT( pChangeImpl ); + } + else + { + OSL_ENSURE(false, "ERROR: Notification tries to change nonexistent value within group"); + } + + return pChangeImpl; + } + + void ViewStrategy::implAdjustToValueChanges(NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges) + { + for (SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it) + { + using namespace configuration; + + if (it->ISA(ValueChange)) + { + ValueChange const& rValueChange = static_cast<ValueChange const&>(*it); + + Name aValueName = makeNodeName( rValueChange.getNodeName(), Name::NoValidate() ); + + if (ValueChangeImpl* pThisChange = doAdjustToValueChange(_aGroupNode, aValueName, rValueChange)) + { + pThisChange->setTarget(_aGroupNode,aValueName); + addLocalChangeHelper(rLocalChanges, NodeChange(pThisChange)); + } + else + OSL_TRACE("WARNING: Configuration: derived class hides an external value member change from listeners"); + } + else + OSL_ENSURE(it->ISA(SubtreeChange), "Unexpected change type within group"); + } + } + + void ViewStrategy::implAdjustToSubChanges(NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges) + { + using namespace configuration; + + for(SubtreeChange::ChildIterator it = rExternalChanges.begin(); it != rExternalChanges.end(); ++it) + { + TreeImpl * pTreeData = _aGroupNode.tree().get_impl(); + + if ( it->ISA(SubtreeChange) ) + { + Node aSubNode = _aGroupNode.findChild( makeNodeName(it->getNodeName(), Name::NoValidate()) ); + OSL_ENSURE( aSubNode.is() || pTreeData->depthTo(_aGroupNode.node().get_offset()) >= pTreeData->getAvailableDepth(), "Changed node not found in tree"); + + if (aSubNode.is()) + { + OSL_ENSURE( pTreeData->getRemainingDepth(_aGroupNode.node().get_offset()) > 0, "Depth is smaller than expected for tree"); + this->adjustToChanges(rLocalChanges, aSubNode, static_cast<SubtreeChange const&>(*it)); + } + } + else + { + OSL_ENSURE(it->ISA(ValueChange), "Unexpected change type for child of group node; change is ignored"); + OSL_ENSURE( !_aGroupNode.findChild(makeNodeName(it->getNodeName(), Name::NoValidate())).is(), + "Found sub(tree) node where a value was expected"); + } + } + } +//----------------------------------------------------------------------------- + void ViewStrategy::doCollectChanges(Node const& _aNode, NodeChanges& ) const + { + // no-op: there are no changes to collect + OSL_ENSURE(!hasChanges(_aNode),"Unexpected changes in View"); + } + + +//----------------------------------------------------------------------------- + UnoAny ViewStrategy::getValue(ValueNode const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.get_impl()->getValue(_aNode.accessor()); + } + + UnoType ViewStrategy::getValueType(ValueNode const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.get_impl()->getValueType(_aNode.accessor()); + } + +//----------------------------------------------------------------------------- +// group member access + +//----------------------------------------------------------------------------- + namespace { // helpers + using configuration::GroupMemberVisitor; + + struct GroupMemberDispatch : data::NodeVisitor + { + GroupMemberDispatch(ViewStrategy& _rStrategy, GroupNode const& _aGroup, GroupMemberVisitor& rVisitor) + : m_aGroup(_aGroup) + , m_rVisitor(rVisitor) + , m_rStrategy(_rStrategy) + {} + + static Result mapResult(GroupMemberVisitor::Result _aResult) + { + + OSL_ASSERT( DONE == GroupMemberVisitor::DONE ); + OSL_ASSERT( CONTINUE == GroupMemberVisitor::CONTINUE ); + return static_cast<Result>(_aResult); + } + + static GroupMemberVisitor::Result unmapResult(Result _aResult) + { + OSL_ASSERT( DONE == GroupMemberVisitor::DONE ); + OSL_ASSERT( CONTINUE == GroupMemberVisitor::CONTINUE ); + return static_cast<GroupMemberVisitor::Result>(_aResult); + } + + virtual Result handle(data::ValueNodeAccess const& _aValue); + virtual Result handle(data::NodeAccess const& _aNonValue); + + bool test_value(data::NodeAccess const & _aNode) const; + + ViewStrategy& m_rStrategy; + GroupNode m_aGroup; + GroupMemberVisitor& m_rVisitor; + + GroupMemberVisitor::Result m_aResult; + }; + + bool GroupMemberDispatch::test_value(data::NodeAccess const& _aNode) const + { + Name aName = _aNode.getName(); + + return m_rStrategy.hasValue( m_aGroup, aName ); + } + + GroupMemberDispatch::Result GroupMemberDispatch::handle(data::ValueNodeAccess const& _aValue) + { + OSL_ENSURE( test_value(_aValue), "ERROR: Group MemberDispatch:Did not find a ValueMember for a value child."); + + Name aValueName = _aValue.getName(); + + return mapResult( m_rVisitor.visit( m_rStrategy.getValue(m_aGroup,aValueName) ) ); + } + + GroupMemberDispatch::Result GroupMemberDispatch::handle(data::NodeAccess const& _aNonValue) + { + OSL_ENSURE( !test_value(_aNonValue), "ERROR: Group MemberDispatch:Found a ValueMember for a subtree child."); + + return CONTINUE; + } + } +//----------------------------------------------------------------------------- + configuration::ValueMemberNode ViewStrategy::doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool ) const + { + using data::ValueNodeAccess; + + ValueNodeAccess aValueData = getMemberValueAccess(_aNode,_aName); + + return _aNode.get_impl()->makeValueMember( aValueData ); + } + + bool ViewStrategy::hasValue(GroupNode const& _aNode, Name const& _aName) const + { + checkInstance(_aNode.tree()); + return getMemberValueAccess(_aNode,_aName).isValid(); + } + + bool ViewStrategy::areValueDefaultsAvailable(GroupNode const& _aNode) const + { + checkInstance(_aNode.tree()); + + return _aNode.get_impl()->areValueDefaultsAvailable( _aNode.accessor() ); + } + + configuration::ValueMemberNode ViewStrategy::getValue(GroupNode & _aNode, Name const& _aName) const + { + checkInstance(_aNode.tree()); + return doGetValueMember(_aNode,_aName,false); + } + + configuration::ValueMemberUpdate ViewStrategy::getValueForUpdate(GroupNode const & _aNode, Name const& _aName) + { + checkInstance(_aNode.tree()); + return ValueMemberUpdate( doGetValueMember(_aNode,_aName,true), *this ); + } + + GroupMemberVisitor::Result ViewStrategy::dispatchToValues(GroupNode const& _aNode, GroupMemberVisitor& _aVisitor) + { + checkInstance(_aNode.tree()); + + GroupMemberDispatch aDispatch(*this,_aNode,_aVisitor); + + GroupMemberDispatch::Result eResult = aDispatch.visitChildren( _aNode.getAccess() ); + + return aDispatch.unmapResult(eResult); + } + +//----------------------------------------------------------------------------- + ViewStrategy::SetNodeElement ViewStrategy::implMakeElement(SetNode const& _aNode, SetNodeEntry const& anEntry) const + { + configuration::SetNodeImpl * pNodeData = _aNode.get_impl(); + return pNodeData->implValidateElement(anEntry.accessor(), pNodeData->entryToElement(anEntry)); + } +//----------------------------------------------------------------------------- + SetEntry ViewStrategy::implFindElement(SetNode const& _aNode, Name const& aName) const + { + configuration::SetNodeImpl * pNodeData = _aNode.get_impl(); + + OSL_ENSURE(pNodeData->implHasLoadedElements(),"Cannot find elements in set that is not loaded"); + configuration::ElementTreeImpl * pElement = pNodeData->doFindElement(aName); + + return SetEntry(_aNode.accessor(), pElement); + } + + SetEntry ViewStrategy::findElement(SetNode const& _aNode, Name const& aName) const + { + checkInstance(_aNode.tree()); + _aNode.get_impl()->implEnsureElementsLoaded(_aNode.accessor()); + return implFindElement(_aNode,aName); + } + + SetEntry ViewStrategy::findAvailableElement(SetNode const& _aNode, Name const& aName) const + { + checkInstance(_aNode.tree()); + if (_aNode.get_impl()->implHasLoadedElements()) + return implFindElement(_aNode,aName); + else + return SetEntry(_aNode.accessor(),0); + } + + static + inline + std::auto_ptr<SubtreeChange> makeChangeToDefault(data::SetNodeAccess const & _aSetNode) + { + return std::auto_ptr<SubtreeChange>( + new SubtreeChange( + _aSetNode.getName().toString(), + _aSetNode.getElementTemplateName().toString(), + _aSetNode.getElementTemplateModule().toString(), + _aSetNode.getAttributes(), + true // to default + ) ); + } + + std::auto_ptr<SubtreeChange> ViewStrategy::differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree) const + { + checkInstance(_aNode.tree()); + std::auto_ptr<SubtreeChange> aResult; + + data::SetNodeAccess aOriginalSetNode = _aNode.getAccess(); + if (!aOriginalSetNode.isDefault()) + { + OSL_ASSERT(aOriginalSetNode.isValid()); + + aResult = makeChangeToDefault( aOriginalSetNode ); + + configuration::SetNodeImpl * pNodeData = _aNode.get_impl(); + if (this->hasChanges(_aNode.node())) + { + OSL_ENSURE(pNodeData->implHasLoadedElements(),"Unexpected: Found set with changes but elements are not loaded"); + pNodeData->doDifferenceToDefaultState(_aNode.accessor(),*aResult,_rDefaultTree); + } + else + pNodeData->implDifferenceToDefaultState(_aNode.accessor(),*aResult,_rDefaultTree); + } + return aResult; + } + + configuration::TemplateHolder ViewStrategy::getElementTemplate(SetNode const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.get_impl()->getElementTemplate(); + } + + configuration::TemplateProvider ViewStrategy::getTemplateProvider(SetNode const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.get_impl()->getTemplateProvider(); + } + +//----------------------------------------------------------------------------- +/* // virtual rtl::Reference<ViewStrategy> doCloneIndirect(); // fails* / + rtl::Reference<ViewStrategy> ViewStrategy::makeIndirect(Tree const& _aTree) + { + _aTree->makeIndirect(true); + return this; + } + + void ViewStrategy::doCommitChanges(Node const& _aNode) + { + // nothing to do + } + + // TODO: move this to deferred impl + void ViewStrategy::implCommitDirectIn(data::TreeAccessor const& _aPlaceHolder, Node const& _aNode) + { + if (this->hasChanges(_aNode) ) + { + this->doCommitChanges(_aNode); + + GroupNode aGroup(_aNode); + + for (Node aChild = aGroup.getFirstChild(); aChild.is(); aChild = aGroup.getNextChild(aChild) ) + { + implCommitDirectIn(_aPlaceHolder, aChild); + } + } + } + + void ViewStrategy::commitDirectly(data::TreeAccessor const& _aPlaceHolder, Tree const& _aTree) + { + implCommitDirectIn( _aPlaceHolder, getRootNode(_aTree) ); + } + + // virtual rtl::Reference<ViewStrategy> doCloneDirect(); // returns 'this' + rtl::Reference<ViewStrategy> ViewStrategy::makeDirect (Tree const& _aTree) + { + commitDirectly(_aTree.accessor(), _aTree); + _aTree->makeIndirect(false); + return this; + } +*/ +//----------------------------------------------------------------------------- + data::NodeAccess ViewStrategy::getNodeAccess(Node const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.getAccess(); + } + + Name ViewStrategy::getNodeName(Node const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.data().getName(); + } + + node::Attributes ViewStrategy::getNodeAttributes(Node const& _aNode) const + { + checkInstance(_aNode.tree()); + return _aNode.getAccess().getAttributes(); + } + +//----------------------------------------------------------------------------- + SetNodeVisitor::Result ViewStrategy::dispatchToElements(SetNode const& _aNode, SetNodeVisitor& _aVisitor) + { + checkInstance(_aNode.tree()); + + configuration::SetNodeImpl * pNodeData = _aNode.get_impl(); + + if (pNodeData->implLoadElements(_aNode.accessor())) + return pNodeData->doDispatchToElements(_aNode.accessor(), _aVisitor); + + else + return SetNodeVisitor::CONTINUE; + } + + bool ViewStrategy::isEmpty(SetNode const& _aNode) const + { + checkInstance(_aNode.tree()); + + configuration::SetNodeImpl * pNodeData = _aNode.get_impl(); + + return !pNodeData->implLoadElements(_aNode.accessor()) || pNodeData->doIsEmpty(); + } +//----------------------------------------------------------------------------- + + void ViewStrategy::insertElement(SetNode const& _aNode, Name const& _aName, SetEntry const& _aNewEntry) + { + // cannot insert, if we cannot check for collisions + checkInstance(_aNode.tree()); + _aNode.get_impl()->implEnsureElementsLoaded(_aNode.accessor()); + doInsertElement(_aNode,_aName,_aNewEntry); + } + + void ViewStrategy::removeElement(SetNode const& _aNode, Name const& _aName) + { + // cannot remove, if we cannot check for existance + checkInstance(_aNode.tree()); + _aNode.get_impl()->implEnsureElementsLoaded(_aNode.accessor()); + doRemoveElement(_aNode,_aName); + } + +//----------------------------------------------------------------------------- + } +//----------------------------------------------------------------------------- +} + diff --git a/configmgr/source/treemgr/viewstrategy.hxx b/configmgr/source/treemgr/viewstrategy.hxx new file mode 100644 index 000000000000..a7402c63afc8 --- /dev/null +++ b/configmgr/source/treemgr/viewstrategy.hxx @@ -0,0 +1,328 @@ +/************************************************************************* + * + * $RCSfile: viewstrategy.hxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: jb $ $Date: 2002-02-11 14:55:53 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef CONFIGMGR_VIEWBEHAVIOR_HXX_ +#define CONFIGMGR_VIEWBEHAVIOR_HXX_ + +#ifndef CONFIGMGR_VIEWNODE_HXX_ +#include "viewnode.hxx" +#endif + +#ifndef CONFIGMGR_GROUPNODEBEHAVIOR_HXX_ +#include "groupnodeimpl.hxx" +#endif +#ifndef CONFIGMGR_SETNODEBEHAVIOR_HXX_ +#include "setnodeimpl.hxx" +#endif + +#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ +#include <salhelper/simplereferenceobject.hxx> +#endif +#ifndef _RTL_REF_HXX_ +#include <rtl/ref.hxx> +#endif + +namespace configmgr +{ +//----------------------------------------------------------------------------- + namespace memory { class Segment; } +//----------------------------------------------------------------------------- + namespace configuration + { + class SetElementChangeImpl; + class ValueChangeImpl; + } +//----------------------------------------------------------------------------- + namespace view + { +//----------------------------------------------------------------------------- + struct NodeFactory; +//----------------------------------------------------------------------------- + using configuration::Name; + using configuration::NodeOffset; + using configuration::TreeDepth; + + typedef com::sun::star::uno::Any UnoAny; + typedef com::sun::star::uno::Type UnoType; +//----------------------------------------------------------------------------- + class ViewStrategy : public salhelper::SimpleReferenceObject + { + // node attributes + public: + /// retrieve the attributes of the node + Name getName(Node const& _aNode) const; + + /// retrieve the attributes of the node + node::Attributes getAttributes(Node const& _aNode) const; + + // tracking pending changes + public: + typedef configuration::NodeChanges NodeChanges; + + void collectChanges(Tree const& _aTree, NodeChanges& rChanges) const; + + bool hasChanges(Tree const& _aTree) const; + + bool hasChanges(Node const& _aNode) const; + + void markChanged(Node const& _aNode); + + // commit protocol + public: + std::auto_ptr<SubtreeChange> preCommitChanges(Tree const& _aTree, configuration::ElementList& _rRemovedElements); + + void finishCommit(Tree const& _aTree, SubtreeChange& rRootChange); + + void revertCommit(Tree const& _aTree, SubtreeChange& rRootChange); + + void recoverFailedCommit(Tree const& _aTree, SubtreeChange& rRootChange); + + // notification protocol + public: + typedef configuration::NodeChangesInformation NodeChangesInformation; + + /// Adjust the internal representation after external changes to the original data - build NodeChangeInformation objects for notification + void adjustToChanges(NodeChangesInformation& rLocalChanges, Node const & _aNode, SubtreeChange const& aExternalChange); + + // visitor dispatch + public: + typedef configuration::GroupMemberVisitor GroupMemberVisitor; + typedef configuration::SetNodeVisitor SetNodeVisitor; + + GroupMemberVisitor::Result dispatchToValues(GroupNode const& _aNode, GroupMemberVisitor& _aVisitor); + + /// Call <code>aVisitor.visit(aElement)</code> for each element in this set until SetNodeVisitor::DONE is returned. + SetNodeVisitor::Result dispatchToElements(SetNode const& _aNode, SetNodeVisitor& _aVisitor); + + // value (element) node specific operations + public: + /// Does this node assume its default value + /// retrieve the current value of this node + UnoAny getValue(ValueNode const& _aNode) const; + + /// get the type of this value + UnoType getValueType(ValueNode const& _aNode) const; + + + // group node specific operations + public: + typedef configuration::ValueMemberNode ValueMemberNode; + typedef configuration::ValueMemberUpdate ValueMemberUpdate; + + /// does this hold a child value of the given name + bool hasValue(GroupNode const& _aNode, Name const& _aName) const; + + /// are defaults for this node available ? + bool areValueDefaultsAvailable(GroupNode const& _aNode) const; + + /// retrieve data for the child value of the given name + ValueMemberNode getValue(GroupNode & _aNode, Name const& _aName) const; + + /// retrieve data for updating the child value of the given name + ValueMemberUpdate getValueForUpdate(GroupNode const & _aNode, Name const& _aName); + + // set node specific operations + public: + typedef configuration::ElementTreeData SetNodeElement; + typedef configuration::SetEntry SetNodeEntry; + + /// does this set contain any elements (loads elements if needed) + bool isEmpty(SetNode const& _aNode) const; + + /// does this set contain an element named <var>aName</var> (loads elements if needed) + SetNodeEntry findElement(SetNode const& _aNode, Name const& aName) const; + + /// does this set contain an element named <var>aName</var> (and is that element loaded ?) + SetNodeEntry findAvailableElement(SetNode const& _aNode, Name const& aName) const; + + /// insert a new entry into this set + void insertElement(SetNode const& _aNode, Name const& aName, SetNodeEntry const& aNewEntry); + + /// remove an existing entry into this set + void removeElement(SetNode const& _aNode, Name const& aName); + + /** Create a Subtree change as 'diff' which allows transforming the set to its default state + (given that <var>_rDefaultTree</var> points to a default instance of this set) + <p>Ownership of added trees should be transferred to the SubtreeChange.</p> + */ + std::auto_ptr<SubtreeChange> differenceToDefaultState(SetNode const& _aNode, ISubtree& _rDefaultTree) const; + + /// Get the template that describes elements of this set + configuration::TemplateHolder getElementTemplate(SetNode const& _aNode) const; + + /// Get a template provider that can create new elements for this set + configuration::TemplateProvider getTemplateProvider(SetNode const& _aNode) const; + + // create a view::Tree from a configuration::SetEntry + Tree extractTree(SetNodeEntry const& _anEntry); + + // creating/changing state/strategy + public: + NodeFactory& getNodeFactory(); + + // direct update access to data + public: + memory::Segment const * getDataSegment() const; + memory::Segment * getDataSegmentForUpdate(); + + data::NodeAddress ::DataType * getDataForUpdate(data::NodeAccess const & _aNode); + data::SetNodeAddress::DataType * getDataForUpdate(data::SetNodeAccess const & _aNode); + data::GroupNodeAddress::DataType * getDataForUpdate(data::GroupNodeAccess const & _aNode); + data::ValueNodeAddress::DataType * getDataForUpdate(data::ValueNodeAccess const & _aNode); + + // access to node innards + protected: + /// provide access to the data of the underlying node + data::NodeAccess getNodeAccess(Node const& _aNode) const; + + /// provide access to the address of the underlying node + data::NodeAddress getNodeAddress(Node const& _aNode) const; + + /// retrieve the name of the underlying node + Name getNodeName(Node const& _aNode) const; + + /// retrieve the attributes of the underlying node + node::Attributes getNodeAttributes(Node const& _aNode) const; + + protected: + //helper for migration to new (info based) model for adjusting to changes + static void addLocalChangeHelper( NodeChangesInformation& rLocalChanges, configuration::NodeChange const& aChange); + + private: + void implAdjustToValueChanges(NodeChangesInformation& rLocalChanges, GroupNode const& _aGroupNode, SubtreeChange const& rExternalChanges); + void implAdjustToSubChanges(NodeChangesInformation& rLocalChanges, GroupNode const & _aGroupNode, SubtreeChange const& rExternalChanges); + void implAdjustToElementChanges(NodeChangesInformation& rLocalChanges, SetNode const& _aNode, SubtreeChange const& rExternalChanges, TreeDepth nDepth); + void implAdjustToElementChange (NodeChangesInformation& rLocalChanges, SetNode const& _aNode, Change const& rElementChange, TreeDepth nElementDepth); + void implCommitDirectIn(data::TreeAccessor const& _aPlaceHolder, Node const& _aNode); + + protected: + void checkInstance(Tree const& _aTreeForThis) const; + SetNodeEntry implFindElement(SetNode const& _aNode, Name const& aName) const; + SetNodeElement implMakeElement(SetNode const& _aNode, SetNodeEntry const& anEntry) const; + + // virtual interface - these functions must be provided + private: + // change handling + virtual bool doHasChanges(Node const& _aNode) const = 0; + virtual void doMarkChanged(Node const& _aNode) = 0; + + virtual NodeFactory& doGetNodeFactory() = 0; + + // virtual interface - these functions all have default implementations without support for pending changes + protected: + // special support for direct changes to underlying data - default is no support + virtual data::NodeAddress::DataType * implAccessForUpdate(data::NodeAccess const & _aDataAccess); + virtual memory::Segment const * doGetDataSegment() const = 0; + virtual memory::Segment * doGetDataSegmentForUpdate(); + + // change handling + virtual void doCollectChanges(Node const& _aNode, NodeChanges& rChanges) const; + + // commit protocol + virtual std::auto_ptr<SubtreeChange> doPreCommitChanges(Tree const& _aTree, configuration::ElementList& _rRemovedElements); + virtual void doFailedCommit(Tree const& _aTree, SubtreeChange& rChanges); + virtual void doFinishCommit(Tree const& _aTree, SubtreeChange& rChanges); + virtual void doRevertCommit(Tree const& _aTree, SubtreeChange& rChanges); + + // notification protocol + virtual configuration::ValueChangeImpl* doAdjustToValueChange(GroupNode const& _aGroupNode, Name const& aName, ValueChange const& rExternalChange); + + // common attributes + virtual node::Attributes doAdjustAttributes(node::Attributes const& _aAttributes) const = 0; + + // group member access + virtual ValueMemberNode doGetValueMember(GroupNode const& _aNode, Name const& _aName, bool _bForUpdate) const = 0; + + // set element access + virtual void doInsertElement(SetNode const& _aNode, Name const& aName, SetNodeEntry const& aNewEntry) = 0; + virtual void doRemoveElement(SetNode const& _aNode, Name const& aName) = 0; + + // strategy change support +/* virtual void doCommitChanges(Node const& _aNode); + virtual rtl::Reference<ViewStrategy> doCloneDirect() = 0; + virtual rtl::Reference<ViewStrategy> doCloneIndirect() = 0; +*/ }; + +//----------------------------------------------------------------------------- + inline Name ViewStrategy::getName(Node const& _aNode) const + { return getNodeName(_aNode); } + + inline node::Attributes ViewStrategy::getAttributes(Node const& _aNode) const + { return doAdjustAttributes(getNodeAttributes(_aNode)); } + + inline bool ViewStrategy::hasChanges(Node const& _aNode) const + { return doHasChanges(_aNode); } + + inline NodeFactory& ViewStrategy::getNodeFactory() + { return doGetNodeFactory(); } + + inline memory::Segment const * ViewStrategy::getDataSegment() const + { return doGetDataSegment(); } + + inline memory::Segment * ViewStrategy::getDataSegmentForUpdate() + { return doGetDataSegmentForUpdate(); } + +//----------------------------------------------------------------------------- + } +//----------------------------------------------------------------------------- +} + +#endif // CONFIGMGR_CONFIGNODEBEHAVIOR_HXX_ diff --git a/configmgr/util/makefile.mk b/configmgr/util/makefile.mk index e5a44ac1f18a..57184fa9e9c9 100644 --- a/configmgr/util/makefile.mk +++ b/configmgr/util/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.13 $ +# $Revision: 1.14 $ # -# last change: $Author: jb $ $Date: 2001-11-02 12:18:25 $ +# last change: $Author: jb $ $Date: 2002-02-11 14:58:31 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -102,6 +102,7 @@ SHL1LIBS= $(SLB)$/registry.lib \ $(SLB)$/treemgr.lib \ $(SLB)$/api2.lib \ $(SLB)$/api.lib \ + $(SLB)$/data.lib \ $(SLB)$/cm.lib SHL1DEF= $(MISC)$/$(SHL1TARGET).def @@ -141,6 +142,7 @@ SHL2LIBS= $(SLB)$/registry.lib \ $(SLB)$/treemgr.lib \ $(SLB)$/api2.lib \ $(SLB)$/api.lib \ + $(SLB)$/data.lib \ $(SLB)$/cm.lib SHL2DEF= $(MISC)$/$(SHL2TARGET).def |