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.cxx381
1 files changed, 381 insertions, 0 deletions
diff --git a/configmgr/source/tree/cmtree.cxx b/configmgr/source/tree/cmtree.cxx
new file mode 100644
index 000000000000..674ddd4e4460
--- /dev/null
+++ b/configmgr/source/tree/cmtree.cxx
@@ -0,0 +1,381 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cmtree.cxx,v $
+ * $Revision: 1.41 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_configmgr.hxx"
+
+#include <stdio.h>
+
+#include "subtree.hxx"
+#include "change.hxx"
+#include "treechangelist.hxx"
+
+//#include "treeactions.hxx"
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/diagnose.h>
+
+#ifndef INCLUDED_DEQUE
+#include <deque>
+#define INCLUDED_DEQUE
+#endif
+#ifndef INCLUDED_VECTOR
+#include <vector>
+#define INCLUDED_VECTOR
+#endif
+#ifndef INCLUDED_EXCEPTION
+#include <exception>
+#define INCLUDED_EXCEPTION
+#endif
+#ifndef INCLUDED_SET
+#include <set>
+#define INCLUDED_SET
+#endif
+#include <algorithm>
+
+namespace configmgr
+{
+
+// ------------------------ ChildListSet implementations ------------------------
+ ChildListSet::ChildListSet(ChildListSet const& aSet, treeop::DeepChildCopy)
+ : m_aChildList(aSet.m_aChildList.size())
+ {
+ for (size_t i = 0; i < aSet.m_aChildList.size(); i++)
+ {
+ m_aChildList[i] = aSet.m_aChildList[i]->clone().release();
+ }
+ }
+ ChildListSet::~ChildListSet()
+ {
+ for (size_t i = 0; i < m_aChildList.size(); i++)
+ delete m_aChildList[i];
+ }
+
+ struct ltNode
+ {
+ ltNode() {}
+
+ bool operator()(const configmgr::INode* n1, const configmgr::INode* n2) const
+ {
+ return n1->getName().compareTo(n2->getName()) < 0;
+ }
+ };
+
+ std::vector< INode* >::iterator ChildListSet::find(INode *pNode) const
+ {
+ std::vector< INode* > &rList = const_cast<std::vector< INode* > &>(m_aChildList);
+ std::pair<std::vector< INode* >::iterator, std::vector< INode* >::iterator> aRange;
+ ltNode aCompare;
+ aRange = std::equal_range(rList.begin(), rList.end(), pNode, aCompare);
+ if (aRange.second - aRange.first == 0)
+ return rList.end();
+ else
+ return aRange.first;
+ }
+
+ // Keep the list sorted ...
+ std::pair<std::vector< INode* >::iterator, bool> ChildListSet::insert(INode *pNode)
+ {
+ // Inserted records are (mostly) already in order
+ if (m_aChildList.size() > 0)
+ {
+ sal_Int32 nCmp = pNode->getName().compareTo(
+ m_aChildList.back()->getName());
+ if (nCmp == 0)
+ {
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.end(), false);
+ }
+ else if (nCmp < 0)
+ {
+ std::vector< INode* >::iterator aIns;
+ ltNode aCompare;
+ aIns = std::lower_bound(m_aChildList.begin(), m_aChildList.end(), pNode, aCompare);
+ if (aIns != m_aChildList.end() && pNode->getName().compareTo((*aIns)->getName()) == 0)
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.end(), false);
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.insert(aIns, pNode), true);
+ }
+ }
+ // simple append - the common case.
+ return std::pair<std::vector< INode* >::iterator, bool>(m_aChildList.insert(m_aChildList.end(), pNode), true);
+ }
+
+ INode *ChildListSet::erase(INode *pNode)
+ {
+ std::vector< INode* >::iterator aIter = find(pNode);
+
+ if (aIter != m_aChildList.end())
+ {
+ INode *pCopy = *aIter;
+ m_aChildList.erase(aIter);
+ return pCopy;
+ }
+ else
+ return NULL;
+ }
+
+// ---------------------------- Node implementation ----------------------------
+
+ INode::INode(rtl::OUString const& aName, node::Attributes _aAttr)
+ :m_aName(aName)
+ ,m_aAttributes(_aAttr){}
+ // CopyCTor will be create automatically
+
+ INode::~INode() {}
+
+ ISubtree* INode::asISubtree(){return NULL;}
+ ISubtree const* INode::asISubtree() const {return NULL;}
+ ValueNode* INode::asValueNode() {return NULL;}
+ ValueNode const* INode::asValueNode() const {return NULL;}
+
+ void INode::modifyState(node::State _eNewState)
+ {
+ m_aAttributes.setState(_eNewState);
+ }
+
+ void INode::modifyAccess(node::Access _aAccessLevel)
+ {
+ OSL_ENSURE( node::accessWritable <= _aAccessLevel && _aAccessLevel <= node::accessReadonly,"Invalid access level for Node");
+
+ m_aAttributes.setAccess(_aAccessLevel);
+ }
+
+ void INode::markMandatory()
+ {
+ m_aAttributes.markMandatory();
+ }
+
+ void INode::markRemovable()
+ {
+ m_aAttributes.markRemovable();
+ }
+
+ void INode::promoteAccessToDefault()
+ {
+ if (m_aAttributes.isFinalized())
+ m_aAttributes.setAccess(node::accessReadonly);
+
+ if ( m_aAttributes.isMandatory())
+ m_aAttributes.setRemovability(false,false);
+ }
+
+// ------------------------- SearchNode implementation -------------------------
+ SearchNode::SearchNode(rtl::OUString const& aName)
+ :INode(aName, node::Attributes()){}
+
+ std::auto_ptr<INode> SearchNode::clone() const {return std::auto_ptr<INode>(new SearchNode(*this));}
+
+ SearchNode::~SearchNode(){}
+
+ //==========================================================================
+ //= OPropagateLevels
+ //==========================================================================
+ /** fills a subtree with the correct level informations
+ */
+ struct OPropagateLevels : public NodeModification
+ {
+ public:
+ OPropagateLevels(sal_Int16 _nParentLevel, sal_Int16 _nParentDefaultLevel)
+ : m_nLevel ( childLevel(_nParentLevel) )
+ , m_nDefaultLevel ( childLevel(_nParentDefaultLevel) )
+ {
+ }
+ virtual void handle(ValueNode&) { /* not interested in value nodes */ }
+ virtual void handle(ISubtree& _rSubtree)
+ {
+ _rSubtree.setLevels(m_nLevel, m_nDefaultLevel);
+ }
+
+ static sal_Int16 childLevel(sal_Int16 _nLevel)
+ {
+ OSL_ASSERT(0 > treeop::ALL_LEVELS);
+ return (_nLevel > 0) ? _nLevel-1 : _nLevel;
+ }
+ protected:
+ sal_Int16 m_nLevel;
+ sal_Int16 m_nDefaultLevel;
+ };
+
+
+// -------------------------- ISubtree implementation --------------------------
+ ISubtree* ISubtree::asISubtree() {return this;}
+ ISubtree const* ISubtree::asISubtree() const {return this;}
+
+ //--------------------------------------------------------------------------
+ static inline bool adjustLevel(sal_Int16& _rLevel, sal_Int16 _nNewLevel)
+ {
+ if (_rLevel == treeop::ALL_LEVELS) return false;
+ if (_nNewLevel <= _rLevel &&
+ _nNewLevel != treeop::ALL_LEVELS) return false;
+
+ _rLevel = _nNewLevel;
+ return true;
+ }
+
+ //--------------------------------------------------------------------------
+ void ISubtree::setLevels(sal_Int16 _nLevel, sal_Int16 _nDefaultLevels)
+ {
+ bool bActive = false;
+
+ if (_nLevel && adjustLevel(m_nLevel, _nLevel))
+ bActive = true;
+
+ if (_nDefaultLevels && adjustLevel(m_nDefaultLevels, _nDefaultLevels))
+ bActive = true;
+
+ // forward the level numbers to any child subtrees we have
+ if (bActive)
+ {
+ OPropagateLevels aPropagate(_nLevel,_nDefaultLevels);
+ aPropagate.applyToChildren(*this);
+ }
+ }
+
+// --------------------------- Subtree implementation ---------------------------
+ std::auto_ptr<INode> Subtree::clone() const
+ {
+ return std::auto_ptr<INode>(new Subtree(*this, treeop::DeepChildCopy()));
+ }
+
+ INode* Subtree::doGetChild(rtl::OUString const& aName) const
+ {
+ SearchNode searchObj(aName);
+
+ std::vector< INode* >::iterator aIter = m_aChildren.find(&searchObj);
+ return aIter != m_aChildren.end() ? *aIter : NULL;
+ }
+
+ INode* Subtree::addChild(std::auto_ptr<INode> aNode) // takes ownership
+ {
+ rtl::OUString aName = aNode->getName();
+ std::pair<std::vector< INode* >::iterator, bool> aInserted =
+ m_aChildren.insert(aNode.get());
+ if (aInserted.second)
+ aNode.release();
+ return *aInserted.first;
+ }
+
+ ::std::auto_ptr<INode> Subtree::removeChild(rtl::OUString const& aName)
+ {
+ SearchNode searchObj(aName);
+ return ::std::auto_ptr<INode>(m_aChildren.erase(&searchObj));
+ }
+// // -------------------------- ValueNode implementation --------------------------
+
+ void Subtree::forEachChild(NodeAction& anAction) const
+ {
+ for(std::vector< INode* >::const_iterator it = m_aChildren.begin();
+ it != m_aChildren.end();
+ ++it)
+ (**it).dispatch(anAction);
+ }
+
+ void Subtree::forEachChild(NodeModification& anAction)
+ {
+ std::vector< INode* >::iterator it = m_aChildren.begin();
+ while( it != m_aChildren.end() )
+ {
+ // modification-safe iteration
+ (**it++).dispatch(anAction);
+ }
+ }
+
+// // -------------------------- ValueNode implementation --------------------------
+ bool ValueNode::setValueType(uno::Type const& _aType)
+ {
+ if (_aType == this->getValueType()) return true;
+
+ if (!this->isNull()) return false;
+
+ uno::TypeClass eTC = this->getValueType().getTypeClass();
+ if (eTC != uno::TypeClass_VOID && eTC != uno::TypeClass_ANY)
+ return false;
+
+ m_aValuePair = AnyPair(_aType);
+
+ OSL_ASSERT(_aType == this->getValueType());
+
+ return true;
+ }
+ bool ValueNode::setValue(com::sun::star::uno::Any const& _aValue)
+ {
+ sal_Bool bRet = m_aValuePair.setFirst(_aValue);
+ if (bRet) this->markAsDefault(false);
+ return !! bRet;
+ }
+
+ bool ValueNode::changeDefault(com::sun::star::uno::Any const& _aValue)
+ {
+ return !! m_aValuePair.setSecond(_aValue);
+ }
+
+ void ValueNode::setDefault()
+ {
+ OSL_PRECOND( hasUsableDefault(), "No default value to set for value node");
+ m_aValuePair.clear( selectValue() );
+ this->markAsDefault();
+ OSL_POSTCOND( isDefault(), "Could not set value node to default");
+ }
+
+ void ValueNode::promoteToDefault()
+ {
+ if (!isDefault())
+ {
+ if (m_aValuePair.hasFirst())
+ {
+ OSL_VERIFY( m_aValuePair.setSecond(m_aValuePair.getFirst()) );
+ m_aValuePair.clear( selectValue() );
+ }
+ else
+ {
+ m_aValuePair.clear( selectDeflt() );
+ OSL_ASSERT( m_aValuePair.isNull() );
+ }
+
+ this->markAsDefault();
+
+ OSL_ENSURE( !m_aValuePair.hasFirst(), "Leaving orphaned value in after promoting to default");
+ }
+ else
+ OSL_ENSURE( !m_aValuePair.hasFirst(), "Orphaned value in default node won't be promoted");
+
+ OSL_POSTCOND( isDefault(), "Could not promote value node to default");
+ }
+
+ std::auto_ptr<INode> ValueNode::clone() const
+ {
+ return std::auto_ptr<INode>(new ValueNode(*this));
+ }
+
+ ValueNode* ValueNode::asValueNode() {return this;}
+ ValueNode const* ValueNode::asValueNode() const {return this;}
+
+} // namespace configmgr
+
+