1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: noderef.cxx,v $
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"
38 #include "viewaccess.hxx"
39 #include "configpath.hxx"
40 #include "nodechange.hxx"
41 #include "configexcept.hxx"
42 #include "configset.hxx"
45 #ifndef INCLUDED_ALGORITHM
46 #include <algorithm> // for swap
47 #define INCLUDED_ALGORITHM
49 #ifndef INCLUDED_FUNCTIONAL
50 #include <functional> // for less
51 #define INCLUDED_FUNCTIONAL
56 namespace configuration
58 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
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
);
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
));
89 //-----------------------------------------------------------------------------
92 //-----------------------------------------------------------------------------
94 //-----------------------------------------------------------------------------
101 //-----------------------------------------------------------------------------
103 NodeRef::NodeRef(unsigned int nPos
, unsigned int 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);
121 //-----------------------------------------------------------------------------
123 void NodeRef::swap(NodeRef
& rOther
)
125 std::swap(m_nPos
, rOther
.m_nPos
);
126 std::swap(m_nDepth
, rOther
.m_nDepth
);
128 //-----------------------------------------------------------------------------
134 //-----------------------------------------------------------------------------
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;
147 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
156 ValueRef::ValueRef(rtl::OUString
const& aName
, unsigned int nParentPos
)
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);
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 //-----------------------------------------------------------------------------
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
206 //-----------------------------------------------------------------------------
208 AnyNodeRef::AnyNodeRef()
214 //-----------------------------------------------------------------------------
216 AnyNodeRef::AnyNodeRef(unsigned int nPos
, unsigned int nDepth
)
221 //-----------------------------------------------------------------------------
223 AnyNodeRef::AnyNodeRef(rtl::OUString
const& aName
, unsigned int nParentPos
)
225 , m_nUsedPos(nParentPos
)
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
)
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
)
250 //-----------------------------------------------------------------------------
252 AnyNodeRef
& AnyNodeRef::operator=(AnyNodeRef
const& rOther
)
254 AnyNodeRef(rOther
).swap(*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 //-----------------------------------------------------------------------------
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)
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 //-----------------------------------------------------------------------------
315 // should move this to a more public place sometime
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
);
324 //-----------------------------------------------------------------------------
326 //-----------------------------------------------------------------------------
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
)
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 //-----------------------------------------------------------------------------
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
;
369 OSL_ENSURE(m_pTree
->isValidNode(n
),"Cannot produce valid Index for NodeID");
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
;
386 return std::less
<Tree
*>()(lhs
.m_pTree
,rhs
.m_pTree
);
389 //-----------------------------------------------------------------------------
391 //-----------------------------------------------------------------------------
393 SubNodeID::SubNodeID()
398 //-----------------------------------------------------------------------------
400 SubNodeID::SubNodeID(rtl::Reference
< Tree
> const& rTree
, NodeRef
const& rParentNode
, rtl::OUString
const& aName
)
402 , m_aParentID(rTree
,rParentNode
)
405 //-----------------------------------------------------------------------------
407 SubNodeID::SubNodeID(NodeID
const& rParentNodeID
, rtl::OUString
const& 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
);
430 return lhs
.m_aParentID
< rhs
.m_aParentID
;
433 //-----------------------------------------------------------------------------
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
);
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
);
486 return Path::makeCompositeName( aElementName
, aTemplate
->getName() );
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
);
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
);
570 aTree
= aElement
.get();
571 aNode
= aTree
->getRootNode();
577 NodeRef aChild
= aTree
->getChildNode(aNode
,aName
);
579 if ( aChild
.isValid() )
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
);
602 aTree
= aElement
.get();
603 return AnyNodeRef(aTree
->getRootNode());
609 NodeRef aChild
= aTree
->getChildNode(aParentNode
,aName
);
611 if ( aChild
.isValid() )
613 return AnyNodeRef(aChild
);
619 //-----------------------------------------------------------------------------
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;
636 //-----------------------------------------------------------------------------
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;
652 aNode
= aTree
->getRootNode();
656 //-----------------------------------------------------------------------------
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();
672 //-----------------------------------------------------------------------------
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;
685 if ( ! findLocalInnerChild(aTree
,aNode
,rPath
.getFirstName()) ) return false;
688 rPath
.dropFirstName();
693 //-----------------------------------------------------------------------------
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())
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
) )
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
);
737 //-----------------------------------------------------------------------------
739 AnyNodeRef
getDeepDescendant(rtl::Reference
< Tree
> & aTree
, NodeRef
& aNode
, RelativePath
& rPath
)
741 if ( findDeepInnerDescendant(aTree
,aNode
,rPath
) )
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
);
757 //-----------------------------------------------------------------------------
759 void getAllContainedNodes(rtl::Reference
< Tree
> const& aTree
, std::vector
<NodeID
>& aList
)
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
;
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
)
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();
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
);
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
);
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