summaryrefslogtreecommitdiff
path: root/configmgr/source/tree/cmtree.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'configmgr/source/tree/cmtree.cxx')
-rw-r--r--configmgr/source/tree/cmtree.cxx719
1 files changed, 719 insertions, 0 deletions
diff --git a/configmgr/source/tree/cmtree.cxx b/configmgr/source/tree/cmtree.cxx
new file mode 100644
index 000000000000..ea565365f3e8
--- /dev/null
+++ b/configmgr/source/tree/cmtree.cxx
@@ -0,0 +1,719 @@
+/*************************************************************************
+ *
+ * $RCSfile: cmtree.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:13:42 $
+ *
+ * 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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+/* PLEASE DON'T DELETE ANY COMMENT LINES, ALSO IT'S UNNECESSARY. */
+
+#include <stl/deque>
+#include <stl/vector>
+#include <iostream>
+#include <exception>
+#include <sal/types.h>
+#include <stl/set>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+
+#include "cmtree.hxx"
+#include "confname.hxx" // Iterator for PathName scans
+#include "cmtreemodel.hxx"
+
+#include <com/sun/star/uno/Any.hxx>
+
+#ifndef _CONFIGMGR_TREEACCESS_HXX_
+#include "treeaccess.hxx"
+#endif
+
+// WISDOM
+// !!Never write same code twice!!
+
+using namespace std;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace configmgr
+{
+
+// ------------------------ ChildListSet implementations ------------------------
+ ChildListSet::ChildListSet(ChildListSet const& aSet)
+ {
+ for(ChildList::iterator it = aSet.GetSet().begin();
+ it != aSet.GetSet().end();
+ ++it)
+ m_aChildList.insert(m_aChildList.end(), (*it)->clone());
+ }
+ ChildListSet::~ChildListSet()
+ {
+ for(ChildList::iterator it = m_aChildList.begin();
+ it != m_aChildList.end();
+ ++it)
+ delete *it;
+ }
+
+
+// ---------------------------- Node implementation ----------------------------
+
+ INode::INode(){}
+ INode::INode(OUString const& aName)
+ :m_aName(aName){}
+ // CopyCTor will be create automatically
+
+ INode::~INode() {}
+
+ // Node* Node::clone() {}
+
+ OUString INode::getName() const {return m_aName;}
+ NodeAttributes INode::getAttributes() const {return m_aNodeAttribute;}
+
+ ISubtree* INode::asISubtree(){return NULL;}
+ ISubtree const* INode::asISubtree() const {return NULL;}
+ ValueNode* INode::asValueNode() {return NULL;}
+ ValueNode const* INode::asValueNode() const {return NULL;}
+
+
+// ------------------------- SearchNode implementation -------------------------
+ SearchNode::SearchNode(){}
+ SearchNode::SearchNode(OUString const& aName)
+ :INode(aName){}
+
+ INode* SearchNode::clone() const {return new SearchNode(*this);}
+
+ OUString SearchNode::getName() const {return getName();}
+ SearchNode::~SearchNode(){}
+
+
+// -------------------------- ISubtree implementation --------------------------
+ ISubtree* ISubtree::asISubtree() {return this;}
+ ISubtree const* ISubtree::asISubtree() const {return this;}
+
+// --------------------------- Subtree implementation ---------------------------
+
+ Subtree::Subtree(OUString const& aName)
+ :ISubtree(aName)
+ ,m_nLevel(0)
+ ,m_bComplete(sal_False)
+ {
+ }
+ Subtree::Subtree()
+ :m_nLevel(0)
+ ,m_bComplete(sal_False)
+ {
+ }
+ Subtree::~Subtree() {}
+
+// #pragma message("__FILE__(__LINE__) Subtree::clone() has empty implementation")
+ INode* Subtree::clone() const {return new Subtree(*this);}
+
+// #define MAX_NODE_NAME_LENGTH 256
+
+// RECURSIVE: Node* Subtree::createChild(OUString const& aPath)
+// RECURSIVE: {
+// RECURSIVE: //? configmgr::Node searchObj(aName);
+// RECURSIVE: //? ChildList::iterator it = m_aNode->GetSet().find(&searchObj);
+// RECURSIVE: //? if (it == m_aNode->GetSet().end())
+// RECURSIVE: //? return NULL;
+// RECURSIVE: //? else
+// RECURSIVE: //? return *it;
+// RECURSIVE: sal_Unicode aName[MAX_NODE_NAME_LENGTH];
+// RECURSIVE: int nStartPos = 0;
+// RECURSIVE: int nPos = 0;
+// RECURSIVE:
+// RECURSIVE: if (aPath[0] == '/')
+// RECURSIVE: {
+// RECURSIVE: nStartPos++;
+// RECURSIVE: }
+// RECURSIVE: if (aPath[nStartPos] == '\0')
+// RECURSIVE: {
+// RECURSIVE: return this;
+// RECURSIVE: }
+// RECURSIVE:
+// RECURSIVE: int nEndPos = nStartPos;
+// RECURSIVE: while ((aPath[nEndPos] != '\0') && (aPath[nEndPos] != '/')) {
+// RECURSIVE: aName[nPos++] = aPath[nEndPos++];
+// RECURSIVE: }
+// RECURSIVE: aName[nPos] = '\0';
+// RECURSIVE:
+// RECURSIVE: #ifdef DEBUG
+// RECURSIVE: // list(cout << " searching for [" << aName << "] in\n");
+// RECURSIVE: #endif
+// RECURSIVE:
+// RECURSIVE: // search Node
+// RECURSIVE: SearchNode searchObj(aName);
+// RECURSIVE: ChildList::iterator it = m_aChildren->GetSet().find(&searchObj);
+// RECURSIVE: if (it == m_aChildren->GetSet().end())
+// RECURSIVE: {
+// RECURSIVE: // create new Child
+// RECURSIVE: auto_ptr<Node> pSubtree( new Subtree(aName));
+// RECURSIVE: Node *pN = addChild(pSubtree);
+// RECURSIVE: Subtree *pS = (Subtree*)pN;
+// RECURSIVE: return pS->createChild(aPath + nEndPos);
+// RECURSIVE: }
+// RECURSIVE: else {
+// RECURSIVE: // call recursive the inner child
+// RECURSIVE: Node *pN = *it;
+// RECURSIVE: Subtree *pP = (Subtree*)pN;
+// RECURSIVE: return pP->createChild(aPath + nEndPos);
+// RECURSIVE: }
+// RECURSIVE: }
+
+ INode* Subtree::createChild(OUString const& aName)
+ {
+ // POST: create Subtree if not found
+
+ // search Node
+ SearchNode searchObj(aName);
+ ChildList::iterator it = m_aChildren.GetSet().find(&searchObj);
+ if (it == m_aChildren.GetSet().end())
+ {
+ // create new Child
+ auto_ptr<INode> pSubtree( new Subtree(aName));
+ return addChild(pSubtree);
+ }
+ return *it;
+ }
+
+ INode* Subtree::doGetChild(OUString const& aName) const
+ {
+ SearchNode searchObj(aName);
+ ChildList::iterator it = m_aChildren.GetSet().find(&searchObj);
+ if (it == m_aChildren.GetSet().end())
+ return NULL;
+ else
+ return *it;
+ }
+
+ INode* Subtree::addChild(std::auto_ptr<INode> aNode) // takes ownership
+ {
+ OUString aName = aNode->getName();
+ std::pair<ChildList::iterator, bool> aInserted =
+ m_aChildren.GetSet().insert(aNode.get());
+ if (aInserted.second)
+ aNode.release();
+ return *aInserted.first;
+ }
+
+ ::std::auto_ptr<INode> Subtree::removeChild(OUString const& aName)
+ {
+ SearchNode searchObj(aName);
+ ChildList::const_iterator it = m_aChildren.GetSet().find(&searchObj);
+
+ ::std::auto_ptr<INode> aReturn;
+ if (m_aChildren.GetSet().end() != it)
+ {
+ aReturn = ::std::auto_ptr<INode>(*it);
+ m_aChildren.GetSet().erase(it);
+ }
+ return aReturn;
+ }
+
+ struct OPropagateLevels : public NodeModification
+ {
+ protected:
+ sal_Int32 nChildLevel;
+ public:
+ OPropagateLevels(sal_Int32 _nParentLevel)
+ {
+ nChildLevel = (ITreeProvider::ALL_LEVELS == _nParentLevel) ? ITreeProvider::ALL_LEVELS : _nParentLevel - 1;
+ }
+ virtual void handle(ValueNode&) { /* not interested in value nodes */ }
+ virtual void handle(ISubtree& _rSubtree)
+ {
+ if ((ITreeProvider::ALL_LEVELS == nChildLevel) || (nChildLevel > 0))
+ {
+ OPropagateLevels aDeeperInto(nChildLevel);
+ aDeeperInto.applyToChildren(_rSubtree);
+ }
+ }
+ };
+
+ void Subtree::setLevel(sal_Int16 _nLevel)
+ {
+ m_nLevel = _nLevel;
+ if (0 == _nLevel)
+ // nothing more to do, this means "nothing known about any children"
+ return;
+
+ // forward the level number to any child subtrees we have
+ OPropagateLevels aDeeperInto(_nLevel);
+ aDeeperInto.applyToChildren(*this);
+ }
+
+ void Subtree::forEachChild(NodeAction& anAction) const {
+ for(ChildList::const_iterator it = m_aChildren.GetSet().begin();
+ it != m_aChildren.GetSet().end();
+ ++it)
+ (**it).dispatch(anAction);
+ }
+
+ void Subtree::forEachChild(NodeModification& anAction) {
+ for(ChildList::iterator it = m_aChildren.GetSet().begin();
+ it != m_aChildren.GetSet().end();
+ ++it)
+ (**it).dispatch(anAction);
+ }
+
+// -------------------------- ValueNode implementation --------------------------
+ void ValueNode::check_init() // may throw in the future
+ {
+ if (m_aValue.hasValue())
+ {
+ OSL_ASSERT(m_aType != ::getVoidCppuType());
+ OSL_ASSERT(m_aType == m_aValue.getValueType());
+ }
+ else OSL_ASSERT(getVoidCppuType() == m_aValue.getValueType());
+
+ if (m_aDefaultValue.hasValue())
+ {
+ OSL_ASSERT(m_aType != ::getVoidCppuType());
+ OSL_ASSERT(m_aType == m_aDefaultValue.getValueType());
+ }
+ else OSL_ASSERT(getVoidCppuType() == m_aDefaultValue.getValueType());
+ }
+
+ void ValueNode::init()
+ {
+ OSL_ASSERT(m_aType == ::getVoidCppuType());
+
+ if (m_aDefaultValue.hasValue())
+ {
+ m_aType = m_aDefaultValue.getValueType();
+ OSL_ASSERT(m_aType != ::getVoidCppuType());
+ }
+ else if (m_aValue.hasValue())
+ {
+ m_aType = m_aValue.getValueType();
+ OSL_ASSERT(m_aType != ::getVoidCppuType());
+ }
+ }
+
+ bool ValueNode::isDefault() const
+ {
+ // POST: true, if only m_aDefaultValue is set.
+ return !m_aValue.hasValue() && hasDefault();
+ }
+
+ bool ValueNode::hasDefault() const
+ {
+ // POST: true, if only m_aDefaultValue is set.
+ return getAttributes().optional || m_aDefaultValue.hasValue();
+ }
+
+ bool ValueNode::isNull() const
+ {
+ // POST: true, if neither Any is set.
+ return !m_aValue.hasValue() && !m_aDefaultValue.hasValue();
+ }
+
+
+ Type ValueNode::getValueType() const
+ {
+ // POST: return Type of Any
+ return m_aType;
+ }
+
+ Any ValueNode::getValue() const
+ {
+ // POST: getValue, if not set, get DefaultValue
+ if (isDefault())
+ return m_aDefaultValue;
+ return m_aValue;
+ }
+
+ Any ValueNode::getDefault() const
+ {
+ return m_aDefaultValue;
+ }
+
+
+ void ValueNode::setValue(Any aValue)
+ {
+ m_aValue = aValue;
+ }
+
+ void ValueNode::changeDefault(Any aValue)
+ {
+ m_aDefaultValue = aValue;
+ }
+
+ void ValueNode::setDefault()
+ {
+ // PRE: ????
+ // POST: isDefault() == true
+ m_aValue = Any();
+ }
+
+ INode* ValueNode::clone() const
+ {
+ return new ValueNode(*this);
+ }
+
+ ValueNode* ValueNode::asValueNode() {return this;}
+ ValueNode const* ValueNode::asValueNode() const {return this;}
+
+// ---------------------------- Tree implementation ----------------------------
+
+ Tree::Tree()
+ : m_pRoot(NULL), m_pLock(NULL)
+ {
+ m_pRoot = new Subtree();
+ m_pLock = new OTreeAccessor;
+ }
+
+ Tree::~Tree()
+ {
+ delete m_pLock;
+ }
+
+ void Tree::acquireReadAccess() const
+ {
+ m_pLock->acquireReadAccess();
+ }
+
+ void Tree::releaseReadAccess() const
+ {
+ m_pLock->releaseReadAccess();
+ }
+
+ void Tree::acquireWriteAccess()
+ {
+ m_pLock->acquireWriteAccess();
+ }
+
+ void Tree::releaseWriteAccess()
+ {
+ m_pLock->releaseWriteAccess();
+ }
+
+// -----------------------------------------------------------------------------
+ ISubtree* Tree::requestSubtree( OUString const& aComponentName, sal_Int16 nLevel )
+ {
+ // OLD:
+ // INode* pResult = m_pRoot->getChild(aComponentName);
+ // return pResult->asISubtree();
+
+ // Build SearchName
+ OSL_ENSHURE(m_pRoot, "Tree::requestSubtree : m_pRoot MUST NOT BE ZERO");
+ // hey, don't cry that loud ....
+
+ ISubtree* pSubtree = m_pRoot;
+ ConfigurationName aConfigName(aComponentName,ConfigurationName::Absolute() );
+ for(ConfigurationName::Iterator it = aConfigName.begin();
+ it != aConfigName.end();
+ ++it)
+ {
+ if (pSubtree)
+ {
+ INode* pNode = pSubtree->getChild(*it);
+ if (!pNode)
+ return NULL;
+
+ pSubtree = pNode->asISubtree();
+ }
+ else
+ break;
+ }
+
+ if (pSubtree && (ALL_LEVELS != pSubtree->getLevel()) && (nLevel > pSubtree->getLevel()))
+ pSubtree = NULL;
+ return pSubtree;
+ }
+
+// -----------------------------------------------------------------------------
+ const INode* Tree::getNode(const OUString& _rPath)
+ {
+ OSL_ENSHURE(m_pRoot, "Tree::getNode : invalid root !");
+
+ ConfigurationName aPath(_rPath, ConfigurationName::Absolute() );
+
+ INode* pNodeLoop = m_pRoot;
+ for ( ConfigurationName::Iterator aSearch = aPath.begin();
+ (aSearch != aPath.end()) && pNodeLoop;
+ ++aSearch)
+ {
+ ISubtree* pNodeContainer = pNodeLoop->asISubtree();
+ if (pNodeContainer)
+ pNodeLoop = pNodeContainer->getChild(*aSearch);
+ else
+ return NULL;
+ }
+
+ return pNodeLoop;
+ }
+
+// -----------------------------------------------------------------------------
+ ISubtree const* Tree::getSubtree( OUString const& aComponentName ) const
+ {
+ // Build SearchName
+ OSL_ENSHURE(m_pRoot, "m_pRoot MUST NOT BE ZERO");
+
+ ISubtree const* pSubtree = m_pRoot;
+ ConfigurationName aConfigName(aComponentName,ConfigurationName::Absolute() );
+ for(ConfigurationName::Iterator it = aConfigName.begin();
+ it != aConfigName.end();
+ ++it)
+ {
+ if (pSubtree)
+ {
+ const INode* pNode = pSubtree->getChild(*it);
+ if (!pNode)
+ return NULL;
+
+ pSubtree = pNode->asISubtree();
+ }
+ else
+ break;
+ }
+ return pSubtree;
+ /*
+ sal_Unicode aName[MAX_NODE_NAME_LENGTH];
+ int nStartPos = 0;
+ int nPos = 0;
+
+ if (aPath[0] == '/')
+ {
+ nStartPos++;
+ }
+ if (aPath[nStartPos] == '\0')
+ {
+ return this;
+ }
+
+ int nEndPos = nStartPos;
+ while ((aPath[nEndPos] != '\0') && (aPath[nEndPos] != '/')) {
+ aName[nPos++] = aPath[nEndPos++];
+ }
+ aName[nPos] = '\0';
+
+ ISubtree const* pSubtree = m_pRoot->getChild(aName)->asISubtree();
+
+
+ if (pSubtree)
+ {
+ // call recursive the inner child
+ return pSubtree->getSubtree(aPath + nEndPos);
+ }
+ return NULL;
+ */
+ }
+
+ Subtree * Tree::addSubtree(const ConfigurationName& _rLocation, std::auto_ptr<Subtree> _pSubtree, sal_Int16 nLevels)
+ {
+ OSL_ENSHURE(nLevels != 0, "Tree::addSubtree : invalid level count !");
+ // there was a time where 0 meant "all levels", but we changed the according enum in ITReeProvider
+ // so that it is -1 now. Since this time, 0 isn't valid as level depth anymore !
+
+ auto_ptr<INode> pNode;
+
+ // look for the place where to insert the given node
+ ConfigurationName::Iterator aGoDown = _rLocation.begin();
+ ConfigurationName::Iterator aStopAt = _rLocation.end();
+ Subtree* pInsertInto = m_pRoot;
+ while (aGoDown != aStopAt)
+ {
+ OUString sCurrentName = *aGoDown;
+ ++aGoDown;
+
+ Subtree* pExistentSubtree = static_cast<Subtree*>(pInsertInto->getChild(sCurrentName));
+ if (!pExistentSubtree)
+ {
+ Subtree* pNewChild = NULL;
+ if (aGoDown != aStopAt)
+ { // we already incremented aGoDown, so this means we still have (at least) one level to go
+ // -> we need a new temporary node
+ pNewChild = new Subtree(sCurrentName);
+ pNewChild = static_cast<Subtree*>(pInsertInto->addChild(::std::auto_ptr<INode>(pNewChild)));
+ pNewChild->setLevel(0); // which means "we know nothing about any children"
+ }
+ else
+ { // at this last level, we don't need an intermediate node, instead we have to insert _pSubtree here
+ break;
+ }
+ pExistentSubtree = pNewChild;
+ }
+
+ // one level down
+ pInsertInto = pExistentSubtree;
+ }
+
+ Subtree* pNewSubtree = static_cast<Subtree*>(pInsertInto->addChild(::std::auto_ptr<INode>(_pSubtree.release())));
+ pNewSubtree->setLevel(nLevels);
+ return pNewSubtree;
+ }
+
+
+ // --------------------------------- updateTree ---------------------------------
+ class TreeUpdate : public ChangeTreeModification
+ {
+ ISubtree* m_pCurrentSubtree;
+ std::vector<OString> aLog;
+
+ public:
+ TreeUpdate(ISubtree* pSubtree):m_pCurrentSubtree(pSubtree){}
+
+ void handle(ValueChange& aValueNode);
+ void handle(AddNode& aAddNode);
+ void handle(RemoveNode& aRemoveNode);
+ void handle(SubtreeChange& aSubtree);
+ };
+
+ void TreeUpdate::handle(ValueChange& aValueNode)
+ {
+ // Change a Value
+ OSL_ENSURE(m_pCurrentSubtree,"Cannot apply ValueChange without subtree");
+
+ INode* pBaseNode = m_pCurrentSubtree ? m_pCurrentSubtree->getChild(aValueNode.getNodeName()) : 0;
+ OSL_ENSURE(pBaseNode,"Cannot apply Change: No node to change");
+
+ ValueNode* pValue = pBaseNode ? pBaseNode->asValueNode() : 0;
+ OSL_ENSURE(pValue,"Cannot apply ValueChange: Node is not a value");
+
+ if (pValue)
+ aValueNode.applyTo(*pValue);
+#ifdef DBUG
+ else
+ {
+ ::rtl::OString aStr("TreeUpdate: Can't find value with name:=");
+ aStr += rtl::OUStringToOString(aValueNode.getNodeName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSHURE(pValue, aStr.getStr());
+ aLog.push_back(aStr);
+ }
+#endif
+ }
+
+ void TreeUpdate::handle(AddNode& aAddNode)
+ {
+ // Add a new Value
+ if (m_pCurrentSubtree)
+ m_pCurrentSubtree->addChild(aAddNode.releaseAddedNode());
+#ifdef DBUG
+ else
+ aLog.push_back(OString("TreeUpdate: no CurrentSubtree for AddNode"));
+#endif
+
+ }
+
+ void TreeUpdate::handle(RemoveNode& aRemoveNode)
+ {
+ // remove a Value
+ if (m_pCurrentSubtree)
+ {
+ sal_Bool bOk = (NULL != m_pCurrentSubtree->removeChild(aRemoveNode.getNodeName()).get());
+
+#ifdef DBUG
+ ::rtl::OString aStr("TreeUpdate: Can't remove child with name:=");
+ aStr += rtl::OUStringToOString(aRemoveNode.getNodeName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSHURE(bOk, aStr.getStr());
+ if (!bOk)
+ aLog.push_back(aStr);
+#endif
+ }
+ }
+
+
+ void TreeUpdate::handle(SubtreeChange& aSubtree)
+ {
+ // handle traversion
+ ISubtree *pOldSubtree = m_pCurrentSubtree;
+ OSL_ENSHURE(m_pCurrentSubtree->getChild(aSubtree.getNodeName()), "TreeUpdate::handle : invalid subtree change ... this will crash !");
+ m_pCurrentSubtree = m_pCurrentSubtree->getChild(aSubtree.getNodeName())->asISubtree();
+
+#if DEBUG
+ ::rtl::OString aStr("TreeUpdate: there is no Subtree for name:=");
+ aStr += rtl::OUStringToOString(aSubtree.getNodeName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSHURE(m_pCurrentSubtree, aStr.getStr());
+ if (!m_pCurrentSubtree)
+ aLog.push_back(aStr);
+#endif
+
+ aSubtree.forEachChange(*this);
+ m_pCurrentSubtree = pOldSubtree;
+ }
+
+
+ void Tree::updateTree( TreeChangeList& aTree) throw (starlang::WrappedTargetException, uno::RuntimeException)
+ {
+ ConfigurationName aSubtreeName(aTree.pathToRoot, aTree.root.getNodeName());
+ ISubtree *pSubtree = requestSubtree(aSubtreeName.fullName(), ITreeProvider::ALL_LEVELS);
+
+#ifdef DEBUG
+ ::rtl::OString aStr("Tree: there is no Subtree for name:=");
+ aStr += rtl::OUStringToOString(aSubtreeName.fullName(),RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSHURE(pSubtree, aStr.getStr());
+#endif
+
+ if (pSubtree)
+ {
+ TreeUpdate aTreeUpdate(pSubtree);
+ aTree.root.forEachChange(aTreeUpdate);
+ }
+ // Better:
+ // ISubtree *pCloneTree = m_pRoot->clone();
+ // ISubtree *pSubtree = pCloneTree->requestSubtree(aTree.pathToRoot, ITreeProvider::ALL_LEVELS);
+ // TreeUpdate aTreeUpdate(pSubtree);
+ // aTreeUpdate.handle(aTree.root);
+ // if (aTreeUpdate.isOk())
+ // {
+ // delete m_pRoot;
+ // m_pRoot = pSubtree;
+ // }
+ }
+} // namespace configmgr
+
+