update dev300-m58
[ooovba.git] / configmgr / source / treemgr / noderef.cxx
blobc7aeeca267ba2cda4b0bb68b99e73ddbc30a76b9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: noderef.cxx,v $
10 * $Revision: 1.34 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
34 #include "anynoderef.hxx"
35 #include "valueref.hxx"
36 #include "noderef.hxx"
37 #include "tree.hxx"
38 #include "viewaccess.hxx"
39 #include "configpath.hxx"
40 #include "nodechange.hxx"
41 #include "configexcept.hxx"
42 #include "configset.hxx"
43 #include "tracer.hxx"
45 #ifndef INCLUDED_ALGORITHM
46 #include <algorithm> // for swap
47 #define INCLUDED_ALGORITHM
48 #endif
49 #ifndef INCLUDED_FUNCTIONAL
50 #include <functional> // for less
51 #define INCLUDED_FUNCTIONAL
52 #endif
54 namespace configmgr
56 namespace configuration
58 //-----------------------------------------------------------------------------
59 // local helpers
60 //-----------------------------------------------------------------------------
62 namespace
64 //-----------------------------------------------------------------------------
65 struct CollectValueIDs : GroupMemberVisitor
67 CollectValueIDs(NodeID const& aParentID, std::vector<SubNodeID>& rValueList)
68 : m_aParentID(aParentID)
69 , m_rValueList(rValueList)
73 Result visit(ValueMemberNode const& anEntry);
75 NodeID m_aParentID;
76 std::vector<SubNodeID>& m_rValueList;
79 GroupMemberVisitor::Result CollectValueIDs::visit(ValueMemberNode const& aValue)
81 OSL_ASSERT(aValue.isValid());
83 rtl::OUString aValueName = aValue.getNodeName();
85 m_rValueList.push_back(SubNodeID( m_aParentID, aValueName));
87 return CONTINUE;
89 //-----------------------------------------------------------------------------
92 //-----------------------------------------------------------------------------
93 // class NodeRef
94 //-----------------------------------------------------------------------------
96 NodeRef::NodeRef()
97 : m_nPos(0)
98 , m_nDepth(0)
101 //-----------------------------------------------------------------------------
103 NodeRef::NodeRef(unsigned int nPos, unsigned int nDepth)
104 : m_nPos(nPos)
105 , m_nDepth(nDepth)
107 //-----------------------------------------------------------------------------
109 NodeRef::NodeRef(NodeRef const& rOther)
110 : m_nPos(rOther.m_nPos)
111 , m_nDepth(rOther.m_nDepth)
114 //-----------------------------------------------------------------------------
116 NodeRef& NodeRef::operator=(NodeRef const& rOther)
118 NodeRef(rOther).swap(*this);
119 return *this;
121 //-----------------------------------------------------------------------------
123 void NodeRef::swap(NodeRef& rOther)
125 std::swap(m_nPos, rOther.m_nPos);
126 std::swap(m_nDepth, rOther.m_nDepth);
128 //-----------------------------------------------------------------------------
130 NodeRef::~NodeRef()
134 //-----------------------------------------------------------------------------
135 // class ValueRef
136 //-----------------------------------------------------------------------------
138 bool ValueRef::checkValidState() const
140 if (m_nParentPos == 0) return false;
142 // old node semantics for now
143 if ( m_sNodeName.getLength() == 0 ) return false;
145 return true;
147 //-----------------------------------------------------------------------------
149 ValueRef::ValueRef()
150 : m_sNodeName()
151 , m_nParentPos(0)
154 //-----------------------------------------------------------------------------
156 ValueRef::ValueRef(rtl::OUString const& aName, unsigned int nParentPos)
157 : m_sNodeName(aName)
158 , m_nParentPos(nParentPos)
160 OSL_ENSURE( nParentPos == 0 || checkValidState(), "Constructing invalid ValueRef");
162 //-----------------------------------------------------------------------------
164 ValueRef::ValueRef(ValueRef const& rOther)
165 : m_sNodeName(rOther.m_sNodeName)
166 , m_nParentPos(rOther.m_nParentPos)
169 //-----------------------------------------------------------------------------
171 ValueRef& ValueRef::operator=(ValueRef const& rOther)
173 ValueRef(rOther).swap(*this);
174 return *this;
176 //-----------------------------------------------------------------------------
178 void ValueRef::swap(ValueRef& rOther)
180 std::swap(m_sNodeName, rOther.m_sNodeName);
181 std::swap(m_nParentPos, rOther.m_nParentPos);
183 //-----------------------------------------------------------------------------
185 ValueRef::~ValueRef()
189 //-----------------------------------------------------------------------------
190 // class AnyNodeRef
191 //-----------------------------------------------------------------------------
192 #if OSL_DEBUG_LEVEL > 0
193 bool AnyNodeRef::checkValidState() const
195 if (m_nUsedPos == 0) return false;
197 if ( m_sNodeName.getLength() != 0 ) // it's a local value
199 // not used as runtime check as it should not be dangerous
200 OSL_ENSURE(m_nDepth ==0, "AnyNodeRef that wraps a ValueRef should have no depth"); // value has no depth
203 return true;
205 #endif
206 //-----------------------------------------------------------------------------
208 AnyNodeRef::AnyNodeRef()
209 : m_sNodeName()
210 , m_nUsedPos(0)
211 , m_nDepth(0)
214 //-----------------------------------------------------------------------------
216 AnyNodeRef::AnyNodeRef(unsigned int nPos, unsigned int nDepth)
217 : m_sNodeName()
218 , m_nUsedPos(nPos)
219 , m_nDepth(nDepth)
221 //-----------------------------------------------------------------------------
223 AnyNodeRef::AnyNodeRef(rtl::OUString const& aName, unsigned int nParentPos)
224 : m_sNodeName(aName)
225 , m_nUsedPos(nParentPos)
226 , m_nDepth(0)
228 //-----------------------------------------------------------------------------
230 AnyNodeRef::AnyNodeRef(AnyNodeRef const& rOther)
231 : m_sNodeName(rOther.m_sNodeName)
232 , m_nUsedPos(rOther.m_nUsedPos)
233 , m_nDepth(rOther.m_nDepth)
236 //-----------------------------------------------------------------------------
238 AnyNodeRef::AnyNodeRef(NodeRef const& aNodeRef)
239 : m_sNodeName()
240 , m_nUsedPos( aNodeRef.m_nPos )
241 , m_nDepth( aNodeRef.m_nDepth )
243 //-----------------------------------------------------------------------------
245 AnyNodeRef::AnyNodeRef(ValueRef const& aValueRef)
246 : m_sNodeName( aValueRef.m_sNodeName )
247 , m_nUsedPos( aValueRef.m_nParentPos )
248 , m_nDepth( 0 )
250 //-----------------------------------------------------------------------------
252 AnyNodeRef& AnyNodeRef::operator=(AnyNodeRef const& rOther)
254 AnyNodeRef(rOther).swap(*this);
255 return *this;
257 //-----------------------------------------------------------------------------
259 void AnyNodeRef::swap(AnyNodeRef& rOther)
261 std::swap(m_sNodeName, rOther.m_sNodeName);
262 std::swap(m_nUsedPos, rOther.m_nUsedPos);
263 std::swap(m_nDepth, rOther.m_nDepth);
265 //-----------------------------------------------------------------------------
267 AnyNodeRef::~AnyNodeRef()
271 //-----------------------------------------------------------------------------
273 bool AnyNodeRef::isNode() const
275 OSL_PRECOND( isValid(), "ERROR: Configuration: AnyNodeRef operation requires valid node" );
276 if (!isValid()) return false;
278 return m_sNodeName.getLength() == 0;
280 //-----------------------------------------------------------------------------
282 NodeRef AnyNodeRef::toNode() const
284 OSL_PRECOND( isValid(), "ERROR: Configuration: AnyNodeRef operation requires valid node" );
285 if (!isValid() || !isNode()) return NodeRef();
287 return NodeRef(m_nUsedPos,m_nDepth);
289 //-----------------------------------------------------------------------------
291 ValueRef AnyNodeRef::toValue() const
293 OSL_PRECOND( isValid(), "ERROR: Configuration: AnyNodeRef operation requires valid node" );
294 if (!isValid() || isNode()) return ValueRef();
296 return ValueRef(m_sNodeName, m_nUsedPos);
298 //-----------------------------------------------------------------------------
300 //-----------------------------------------------------------------------------
301 // hashing any pointer
302 //-----------------------------------------------------------------------------
303 static // for now
304 // should move this to a more public place sometime
305 // need this, as STLPORT does not hash sal_(u)Int64 (at least on MSVC)
306 inline
307 size_t hash64(sal_uInt64 n)
309 // simple solution (but the same that STLPORT uses for unsigned long long (if enabled))
310 return static_cast<size_t>(n);
312 //-----------------------------------------------------------------------------
314 static // for now
315 // should move this to a more public place sometime
316 inline
317 size_t hashAnyPointer(void* p)
319 // most portable quick solution IMHO (we need this cast for UNO tunnels anyway)
320 sal_uInt64 n = reinterpret_cast<sal_uInt64>(p);
322 return hash64(n);
324 //-----------------------------------------------------------------------------
326 //-----------------------------------------------------------------------------
327 // class NodeID
328 //-----------------------------------------------------------------------------
330 NodeID::NodeID(rtl::Reference< Tree > const& rTree, NodeRef const& rNode)
331 : m_pTree( rTree.get() )
332 , m_nNode( rNode.getOffset() )
335 //-----------------------------------------------------------------------------
337 NodeID::NodeID(Tree* pImpl, unsigned int nNode)
338 : m_pTree( pImpl )
339 , m_nNode( nNode )
342 //-----------------------------------------------------------------------------
344 bool NodeID::isEmpty() const
346 OSL_ENSURE( m_pTree == NULL || m_pTree->isValidNode(m_nNode), "Node does not match tree in NodeID");
347 return m_pTree == NULL;
349 //-----------------------------------------------------------------------------
351 bool NodeID::isValidNode() const
353 return m_pTree != NULL && m_pTree->isValidNode(m_nNode);
355 //-----------------------------------------------------------------------------
357 // hashing
358 size_t NodeID::hashCode() const
360 return hashAnyPointer(m_pTree) + 5*m_nNode;
362 //-----------------------------------------------------------------------------
364 unsigned int NodeID::toIndex() const
366 unsigned int n = m_nNode;
367 if (m_pTree)
369 OSL_ENSURE(m_pTree->isValidNode(n),"Cannot produce valid Index for NodeID");
371 n -= Tree::ROOT;
373 return n;
376 NodeRef NodeID::getNode() const {
377 return m_pTree == 0 ? NodeRef() : m_pTree->getNode(m_nNode);
380 //-----------------------------------------------------------------------------
381 bool operator < (NodeID const& lhs, NodeID const& rhs)
383 if (lhs.m_pTree == rhs.m_pTree)
384 return lhs.m_nNode < rhs.m_nNode;
385 else
386 return std::less<Tree*>()(lhs.m_pTree,rhs.m_pTree);
389 //-----------------------------------------------------------------------------
390 // class SubNodeID
391 //-----------------------------------------------------------------------------
393 SubNodeID::SubNodeID()
394 : m_sNodeName()
395 , m_aParentID(0,0)
398 //-----------------------------------------------------------------------------
400 SubNodeID::SubNodeID(rtl::Reference< Tree > const& rTree, NodeRef const& rParentNode, rtl::OUString const& aName)
401 : m_sNodeName(aName)
402 , m_aParentID(rTree,rParentNode)
405 //-----------------------------------------------------------------------------
407 SubNodeID::SubNodeID(NodeID const& rParentNodeID, rtl::OUString const& aName)
408 : m_sNodeName(aName)
409 , m_aParentID(rParentNodeID)
412 //-----------------------------------------------------------------------------
414 bool SubNodeID::isValidNode() const
416 if (!m_aParentID.isValidNode()) return false;
418 OSL_ENSURE(m_sNodeName.getLength() != 0,"Invalid subnode ID: Missing name");
420 rtl::Reference< Tree > aCheck( m_aParentID.getTree() );
421 return aCheck->hasChild( m_aParentID.getNode(), m_sNodeName );
423 //-----------------------------------------------------------------------------
425 bool operator < (SubNodeID const& lhs, SubNodeID const& rhs)
427 if (lhs.m_aParentID == rhs.m_aParentID)
428 return !!(lhs.m_sNodeName < rhs.m_sNodeName);
429 else
430 return lhs.m_aParentID < rhs.m_aParentID;
433 //-----------------------------------------------------------------------------
434 // Free functions
435 //-----------------------------------------------------------------------------
437 rtl::OUString validateElementName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
439 { (void)aTree; (void)aNode; }
440 OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
441 OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
442 OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
444 OSL_PRECOND( view::ViewTreeAccess(aTree.get()).isSetNode(aNode), "ERROR: Configuration: Set node expected.");
446 return validateElementName(sName);
448 //-----------------------------------------------------------------------------
450 rtl::OUString validateChildName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
452 { (void)aTree; (void)aNode; }
453 OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
454 OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
455 OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
457 OSL_PRECOND( view::ViewTreeAccess(aTree.get()).isGroupNode(aNode), "ERROR: Configuration: Group node expected.");
459 return validateNodeName(sName);
461 //-----------------------------------------------------------------------------
463 rtl::OUString validateChildOrElementName(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
465 OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
466 OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
467 OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
469 OSL_PRECOND( isStructuralNode(aTree,aNode), "ERROR: Configuration: Inner node expected.");
471 if (view::ViewTreeAccess(aTree.get()).isSetNode(aNode))
472 return validateElementName(sName);
474 else
475 return validateNodeName(sName);
477 //-----------------------------------------------------------------------------
479 Path::Component validateElementPathComponent(rtl::OUString const& sName, rtl::Reference< Tree > const& aTree, NodeRef const& aNode )
481 rtl::OUString aElementName = validateElementName(sName,aTree,aNode);
483 rtl::Reference<Template> aTemplate = aTree->extractElementInfo(aNode);
484 if (aTemplate.is())
486 return Path::makeCompositeName( aElementName, aTemplate->getName() );
488 else
490 OSL_ENSURE(false, "WARNING: Cannot find element type information for building an element name");
491 return Path::wrapElementName(aElementName);
494 //-----------------------------------------------------------------------------
496 static void implValidateLocalPath(RelativePath& _rPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
498 if (_rPath.isEmpty())
499 throw InvalidName(_rPath.toString(), "is an empty path.");
501 // FOR NOW: validate only the first component
502 if (!view::ViewTreeAccess(aTree.get()).isSetNode(aNode))
503 if (!_rPath.getFirstName().isSimpleName())
504 throw InvalidName(_rPath.toString(), "is not valid in this context. Predicate expression used to select group member.");
506 //-----------------------------------------------------------------------------
508 RelativePath validateRelativePath(rtl::OUString const& _sPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
510 OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
511 OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
512 OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
514 OSL_PRECOND( isStructuralNode(aTree,aNode), "ERROR: Configuration: Inner node expected.");
516 if ( Path::isAbsolutePath(_sPath) )
518 OSL_ENSURE(false, "Absolute pathes are not allowed here (compatibility support enabled");
519 return validateAndReducePath(_sPath,aTree,aNode);
522 RelativePath aResult = RelativePath::parse(_sPath);
524 implValidateLocalPath(aResult,aTree,aNode);
526 return aResult;
528 //-----------------------------------------------------------------------------
530 RelativePath validateAndReducePath(rtl::OUString const& _sPath, rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
532 OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
533 OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid NodeRef");
534 OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "ERROR: Configuration: NodeRef does not match Tree");
536 OSL_PRECOND( isStructuralNode(aTree,aNode), "ERROR: Configuration: Inner node expected.");
538 if ( !Path::isAbsolutePath(_sPath) )
539 return validateRelativePath(_sPath,aTree,aNode);
541 AbsolutePath aInputPath = AbsolutePath::parse(_sPath);
543 RelativePath aStrippedPath = Path::stripPrefix( aInputPath, aTree->getAbsolutePath(aNode) );
545 implValidateLocalPath(aStrippedPath,aTree,aNode);
547 return aStrippedPath;
549 //-----------------------------------------------------------------------------
551 bool hasChildOrElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, rtl::OUString const& aName)
553 return view::ViewTreeAccess(aTree.get()).isSetNode(aNode) ? aTree->hasElement(aNode,aName) : aTree->hasChild(aNode,aName);
555 //-----------------------------------------------------------------------------
557 bool hasChildOrElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, Path::Component const& aName)
559 return view::ViewTreeAccess(aTree.get()).isSetNode(aNode) ? aTree->hasElement(aNode,aName) : aTree->hasChild(aNode,aName.getName());
561 //-----------------------------------------------------------------------------
563 bool findInnerChildOrAvailableElement(rtl::Reference< Tree > & aTree, NodeRef& aNode, rtl::OUString const& aName)
565 if ( view::ViewTreeAccess(aTree.get()).isSetNode(aNode) )
567 rtl::Reference< ElementTree > aElement = aTree->getAvailableElement(aNode,aName);
568 if (aElement.is())
570 aTree = aElement.get();
571 aNode = aTree->getRootNode();
572 return true;
575 else
577 NodeRef aChild = aTree->getChildNode(aNode,aName);
579 if ( aChild.isValid() )
581 aNode = aChild;
582 return true;
586 return false;
588 //-----------------------------------------------------------------------------
590 AnyNodeRef getChildOrElement(rtl::Reference< Tree > & aTree, NodeRef const& aParentNode, rtl::OUString const& aName)
592 if (aTree->hasChildValue(aParentNode,aName))
594 return AnyNodeRef(aTree->getChildValue(aParentNode,aName));
597 else if ( view::ViewTreeAccess(aTree.get()).isSetNode(aParentNode) )
599 rtl::Reference< ElementTree > aElement = aTree->getElement(aParentNode,aName);
600 if (aElement.is())
602 aTree = aElement.get();
603 return AnyNodeRef(aTree->getRootNode());
607 else
609 NodeRef aChild = aTree->getChildNode(aParentNode,aName);
611 if ( aChild.isValid() )
613 return AnyNodeRef(aChild);
617 return AnyNodeRef();
619 //-----------------------------------------------------------------------------
621 static
622 inline
623 bool findLocalInnerChild(rtl::Reference< Tree > const& aTree, NodeRef& aNode, Path::Component const& aName)
625 NodeRef aChild = aTree->getChildNode(aNode,aName.getName());
627 if ( !aChild.isValid() ) return false;
629 OSL_ENSURE( aName.isSimpleName(), "Child of group was found by request using element name format -failing");
630 if ( !aName.isSimpleName()) return false;
632 aNode = aChild;
634 return true;
636 //-----------------------------------------------------------------------------
638 static
639 inline
640 bool findElement(rtl::Reference< Tree > & aTree, NodeRef& aNode, Path::Component const& aName)
642 rtl::Reference< ElementTree > aElement = aTree->getElement(aNode,aName.getName());
644 if (!aElement.is()) return false;
646 rtl::Reference< Tree > aFoundTree = aElement.get();
648 OSL_ENSURE(matches(aFoundTree->getExtendedRootName(),aName), "Element found, but type prefix does not match - failing");
649 if ( !matches(aFoundTree->getExtendedRootName(),aName) ) return false;
651 aTree = aFoundTree;
652 aNode = aTree->getRootNode();
654 return true;
656 //-----------------------------------------------------------------------------
658 static
659 bool findLocalInnerDescendant(rtl::Reference< Tree > const& aTree, NodeRef& aNode, RelativePath& rPath)
661 while ( !rPath.isEmpty() )
663 if ( view::ViewTreeAccess(aTree.get()).isSetNode(aNode) ) return false;
665 if ( ! findLocalInnerChild(aTree,aNode,rPath.getFirstName()) ) return false;
667 rPath.dropFirstName();
670 return true;
672 //-----------------------------------------------------------------------------
674 static
675 bool findDeepInnerDescendant(rtl::Reference< Tree > & aTree, NodeRef& aNode, RelativePath& rPath)
677 while ( !rPath.isEmpty() )
679 if ( view::ViewTreeAccess(aTree.get()).isSetNode(aNode) )
681 if ( ! findElement(aTree,aNode,rPath.getFirstName()) ) return false;
683 else
685 if ( ! findLocalInnerChild(aTree,aNode,rPath.getFirstName()) ) return false;
688 rPath.dropFirstName();
691 return true;
693 //-----------------------------------------------------------------------------
695 static
696 inline
697 bool identifiesLocalValue(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, RelativePath const& aPath)
699 if ( aPath.getDepth() == 1 )
701 Path::Component const & aLocalName = aPath.getLocalName();
702 rtl::OUString aName = aLocalName.getName();
704 if (aTree->hasChildValue(aNode,aName))
706 OSL_ENSURE( aLocalName.isSimpleName(), "Value in group was found by request using element name format");
707 if ( aLocalName.isSimpleName())
708 return true;
711 return false;
713 //-----------------------------------------------------------------------------
715 AnyNodeRef getLocalDescendant(rtl::Reference< Tree > const& aTree, NodeRef const& aNode, RelativePath const& rPath)
717 NodeRef aNestedNode( aNode );
718 RelativePath aRemainingPath(rPath);
720 if ( findLocalInnerDescendant(aTree,aNestedNode,aRemainingPath) )
722 OSL_ASSERT(
723 aNestedNode.isValid() &&
724 aTree->isValidNode(aNestedNode.getOffset()));
725 return AnyNodeRef(aNestedNode);
728 if ( identifiesLocalValue(aTree,aNestedNode,aRemainingPath) )
730 ValueRef aValue = aTree->getChildValue(aNestedNode,rPath.getLocalName().getName());
731 OSL_ASSERT(aTree->isValidValueNode(aValue));
732 return AnyNodeRef(aValue);
735 return AnyNodeRef();
737 //-----------------------------------------------------------------------------
739 AnyNodeRef getDeepDescendant(rtl::Reference< Tree > & aTree, NodeRef& aNode, RelativePath& rPath)
741 if ( findDeepInnerDescendant(aTree,aNode,rPath) )
743 OSL_ASSERT(
744 aNode.isValid() && aTree->isValidNode(aNode.getOffset()));
745 return AnyNodeRef(aNode);
748 if ( identifiesLocalValue(aTree,aNode,rPath) )
750 ValueRef aValue = aTree->getChildValue(aNode,rPath.getLocalName().getName());
751 OSL_ASSERT(aTree->isValidValueNode(aValue));
752 return AnyNodeRef(aValue);
755 return AnyNodeRef();
757 //-----------------------------------------------------------------------------
759 void getAllContainedNodes(rtl::Reference< Tree > const& aTree, std::vector<NodeID>& aList)
761 aList.clear();
763 if (Tree* pImpl = aTree.get())
765 unsigned int nCount = pImpl->nodeCount();
766 aList.reserve(nCount);
768 unsigned int const nEnd = Tree::ROOT + nCount;
770 for(unsigned int nOffset = Tree::ROOT;
771 nOffset < nEnd;
772 ++nOffset)
774 OSL_ASSERT( pImpl->isValidNode(nOffset) );
775 aList.push_back( NodeID(pImpl,nOffset) );
778 OSL_ASSERT( aList.size()==nCount );
781 //-----------------------------------------------------------------------------
783 void getAllChildrenHelper(NodeID const& aNode, std::vector<SubNodeID>& aList)
785 aList.clear();
787 if (Tree* pTreeImpl = aNode.getTree())
789 view::ViewTreeAccess aView(pTreeImpl);
791 if (unsigned int const nParent = aNode.getOffset())
793 OSL_ASSERT( pTreeImpl->isValidNode(nParent) );
795 if (aView.isGroupNodeAt(nParent))
797 view::GroupNode aParent = aView.getGroupNodeAt(nParent);
800 CollectValueIDs aCollector(aNode, aList);
801 aView.dispatchToValues(aView.getGroupNodeAt(nParent),aCollector);
804 for(view::Node aChild = aParent.getFirstChild();
805 aChild.is();
806 aChild = aParent.getNextChild(aChild))
808 OSL_ASSERT( pTreeImpl->isValidNode(aChild.get_offset()) );
809 aList.push_back( SubNodeID( aNode, pTreeImpl->getSimpleNodeName(aChild.get_offset())) );
816 //-----------------------------------------------------------------------------
817 NodeID findNodeFromIndex(rtl::Reference< Tree > const& aTree, unsigned int nIndex)
819 if (Tree* pImpl = aTree.get())
821 unsigned int nNode = nIndex + Tree::ROOT;
822 if (pImpl->isValidNode(nNode))
824 return NodeID(pImpl,nNode);
827 return NodeID(0,0);
830 //-----------------------------------------------------------------------------
832 static inline bool isRootNode(NodeRef const& aNode)
834 return aNode.getOffset() == Tree::ROOT;
836 //-----------------------------------------------------------------------------
837 #if OSL_DEBUG_LEVEL > 0
838 bool isSimpleValueElement(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
840 OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
841 OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
843 view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
845 OSL_ASSERT( !aNode.isValid() ||
846 aView.isGroupNode(aNode) ||
847 aView.isSetNode(aNode) ||
848 (aView.isValueNode(aNode) && isRootNode(aNode)) );
850 return aNode.isValid() && isRootNode(aNode) && aView.isValueNode(aNode);
852 #endif
853 //-----------------------------------------------------------------------------
855 bool isStructuralNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
857 OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
858 OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
860 view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
862 OSL_ASSERT( !aNode.isValid() ||
863 aView.isGroupNode(aNode) ||
864 aView.isSetNode(aNode) ||
865 (aView.isValueNode(aNode) && isRootNode(aNode)) );
867 return aNode.isValid() && ! aView.isValueNode(aNode);
869 //-----------------------------------------------------------------------------
871 bool isGroupNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
873 OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
874 OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
876 view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
878 OSL_ASSERT( !aNode.isValid() ||
879 aView.isGroupNode(aNode) ||
880 aView.isSetNode(aNode) ||
881 (aView.isValueNode(aNode) && isRootNode(aNode)) );
883 return aNode.isValid() && aView.isGroupNode(aNode);
885 //-----------------------------------------------------------------------------
887 bool isSetNode(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
889 OSL_PRECOND( !aNode.isValid() || !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
890 OSL_PRECOND( !aNode.isValid() || aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
892 view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
894 OSL_ASSERT( !aNode.isValid() ||
895 aView.isGroupNode(aNode) ||
896 aView.isSetNode(aNode) ||
897 (aView.isValueNode(aNode) && isRootNode(aNode)) );
899 return aNode.isValid() && aView.isSetNode(aNode);
901 //-----------------------------------------------------------------------------
903 com::sun::star::uno::Any getSimpleElementValue(rtl::Reference< Tree > const& aTree, NodeRef const& aNode)
905 OSL_PRECOND( !isEmpty(aTree.get()), "ERROR: Configuration: Tree operation requires a valid Tree");
906 OSL_PRECOND( aNode.isValid(), "ERROR: Configuration: Node operation requires a valid Node");
907 OSL_PRECOND( aTree->isValidNode(aNode.getOffset()), "WARNING: Configuration: NodeRef does not match Tree");
909 if (!aNode.isValid()) return com::sun::star::uno::Any();
911 OSL_PRECOND( isSimpleValueElement(aTree, aNode), "ERROR: Configuration: Getting value is supported only for value nodes");
913 view::ViewTreeAccess aView = view::ViewTreeAccess(aTree.get());
915 return aView.getValue(aView.toValueNode(aNode));
918 //-----------------------------------------------------------------------------
919 } // namespace configuration
920 } // namespace configmgr