merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / inc / tree.hxx
blobf9675be2b38c6b2741957d087266580533e4a52e
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$
10 * $Revision$
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 #ifndef CONFIGMGR_CONFIGNODEIMPL_HXX_
32 #define CONFIGMGR_CONFIGNODEIMPL_HXX_
34 #include "change.hxx"
35 #include "configpath.hxx"
36 #include "template.hxx"
37 #include "utility.hxx"
38 #include <rtl/ref.hxx>
39 #include <salhelper/simplereferenceobject.hxx>
40 #include <osl/diagnose.h>
42 #ifndef INCLUDED_VECTOR
43 #include <vector>
44 #define INCLUDED_VECTOR
45 #endif
46 #ifndef INCLUDED_MAP
47 #include <map>
48 #define INCLUDED_MAP
49 #endif
50 #ifndef INCLUDED_MEMORY
51 #include <memory>
52 #define INCLUDED_MEMORY
53 #endif
55 namespace configmgr
57 namespace node { struct Attributes; }
58 namespace sharable { union Node; }
59 namespace view { class ViewStrategy; }
60 namespace configuration
62 //-----------------------------------------------------------------------------
63 class AnyNodeRef;
64 class ElementTree;
65 class GroupNodeImpl;
66 class NodeChange;
67 class NodeChanges;
68 class NodeImpl;
69 class NodeRef;
70 class SetNodeImpl;
71 class TemplateProvider;
72 class Tree;
73 class ValueElementNodeImpl;
74 class ValueMemberNode;
75 class ValueRef;
76 //-----------------------------------------------------------------------------
77 // WARNING: a similar item is in noderef.hxx
78 const unsigned int c_TreeDepthAll = ~0u;
80 //-----------------------------------------------------------------------------
81 inline
82 unsigned int& incDepth(unsigned int& rDepth)
84 if (rDepth != c_TreeDepthAll) ++rDepth;
85 return rDepth;
88 inline
89 unsigned int& decDepth(unsigned int& rDepth)
91 OSL_ENSURE(rDepth != 0,"Cannot decrement zero depth");
92 if (rDepth != c_TreeDepthAll && rDepth != 0) --rDepth;
93 return rDepth;
96 inline
97 unsigned int childDepth(unsigned int nDepth)
98 { return decDepth(nDepth); }
100 inline
101 unsigned int parentDepth(unsigned int nDepth)
102 { return incDepth(nDepth); }
104 inline
105 unsigned int remainingDepth(unsigned int nOuterDepth, unsigned int nRelativeDepth)
107 OSL_ENSURE(nRelativeDepth != c_TreeDepthAll,"RelativeDepth can't be infinite");
108 OSL_ENSURE(nRelativeDepth <= nOuterDepth,"ERROR: RelativeDepth is larger than enclosing depth");
110 unsigned int nInnerDepth = (nOuterDepth == c_TreeDepthAll) ? nOuterDepth :
111 (nRelativeDepth < nOuterDepth) ? nOuterDepth-nRelativeDepth :
113 return nInnerDepth;
115 //-------------------------------------------------------------------------
117 /// interface for a class that can be used to do some operation on a set of <type>NodeRef</type>s and <type>ValueRef</type>s.
118 struct NodeVisitor
120 /// returned from <method>handle</method> to indicate whether the operation is complete or should continue
121 enum Result { DONE, CONTINUE };
122 /// do the operation on <var>aNode</var>. needs to be implemented by concrete visitor classes
123 virtual Result handle(rtl::Reference< Tree > const& aTree, NodeRef const& aNode) = 0;
124 /// do the operation on <var>aValue</var>. needs to be implemented by concrete visitor classes
125 virtual Result handle(rtl::Reference< Tree > const& aTree, ValueRef const& aValue) = 0;
126 protected:
127 virtual ~NodeVisitor() {}
129 //-----------------------------------------------------------------------------
131 // class Node Impl
132 //-----------------------------------------------------------------------------
134 /** is the Implementation class for class <type>Node</type>, held inside a <type>Tree</type>.
135 <p> Implements some functionality common to all node types.
136 </p>
137 <p> Otherwise it provides (not really typesafe) access to a
138 <type scope='configmgr::configuration::NodeType>NodeImpl</type> which implements
139 functionality for a node of a given type
140 (as given by a <type scope='configmgr::configuration::NodeType>Enum</type> value).
141 </p>
143 class NodeData
145 rtl::Reference<NodeImpl> m_pSpecificNode;
146 rtl::OUString m_aName_; // cached for better performance
147 unsigned int m_nParent;
148 public:
149 NodeData(rtl::Reference<NodeImpl> const& aSpecificNodeImpl, rtl::OUString const& aName, unsigned int nParent);
151 void rebuild(rtl::Reference<view::ViewStrategy> const& _xNewStrategy, sharable::Node * _aNewData);
152 // COMMON: information
153 rtl::OUString getName() const { return m_aName_; }
154 unsigned int getParent() const { return m_nParent; }
156 // change management
157 public:
158 // BASIC NODE: access to common attributes
159 NodeImpl & nodeImpl() { return implGetNodeImpl(); }
160 NodeImpl const & nodeImpl() const { return implGetNodeImpl(); }
162 // SET: access to child elements
163 bool isSetNode() const;
164 SetNodeImpl& setImpl() { return implGetSetImpl(); }
165 SetNodeImpl const& setImpl() const { return implGetSetImpl(); }
167 // VALUES: access to data
168 bool isValueElementNode() const;
169 ValueElementNodeImpl& valueElementImpl() { return implGetValueImpl(); }
170 ValueElementNodeImpl const& valueElementImpl() const { return implGetValueImpl(); }
172 // GROUP: access to children
173 bool isGroupNode() const;
174 GroupNodeImpl& groupImpl() { return implGetGroupImpl(); }
175 GroupNodeImpl const&groupImpl() const { return implGetGroupImpl(); }
177 // access helper
178 public:
179 sharable::Node * getOriginalNodeAccess() const;
181 private:
182 NodeImpl& implGetNodeImpl() const;
183 SetNodeImpl& implGetSetImpl() const;
184 GroupNodeImpl& implGetGroupImpl() const ;
185 ValueElementNodeImpl& implGetValueImpl() const ;
187 //-----------------------------------------------------------------------------
188 /** represents a hierarchy of config entries (identified by <type>NodeRef</type>s and <type>ValueRef</type>s)
190 <p>Examples for trees include</p>
191 <ulist>
192 <li>A module tree (for a specific set of parameters).</li>
193 <li>An updating tree (for a part of the whole).</li>
194 <li>A set element (updating or not), which could be detached.</li>
195 <ulist>
196 <p> Holds a list of <type>Node</type> which it allows to access by
197 <type>unsigned int</type> (which is basically a one-based index).
198 </p>
199 <p> Also provides for navigation to the context this tree is located in
200 </p>
202 class Tree : public salhelper::SimpleReferenceObject
204 friend class view::ViewStrategy;
205 protected:
206 // Construction
207 /// creates a Tree for a detached, virgin tree
208 Tree( );
210 /// creates a Tree with a parent tree
211 Tree(Tree& rParentTree, unsigned int nParentNode);
213 virtual ~Tree() = 0;
215 /// fills this Tree starting from _aRootNode, using the given factory and the tree's template provider
216 void build(rtl::Reference<view::ViewStrategy> const& _xStrategy, sharable::Node * _aRootNode, unsigned int nDepth, TemplateProvider const& aTemplateProvider);
218 void rebuild(rtl::Reference<view::ViewStrategy> const& _xNewStrategy, sharable::Node * _aNewData);
220 public:
221 // realeses the data this refers to
222 virtual void disposeData();
224 // Context Access
225 /// gets the path to the root node of this tree
226 AbsolutePath getRootPath() const;
227 /// gets the tree of parent node of this tree
228 Tree* getContextTree() { return m_pParentTree; }
229 /// gets the tree of parent node of this tree
230 Tree const *getContextTree() const { return m_pParentTree; }
231 /// gets the offset of parent node of this tree within its tree
232 unsigned int getContextNode() const { return m_nParentNode; }
234 // Node Collection information
235 /// checks whether <var>nNode</var> is a valid node offset in this tree
236 bool isValidNode(unsigned int nNode) const;
238 bool isRootNode(NodeRef const & node) const;
240 NodeRef getRootNode() const;
242 NodeRef getContextNodeRef() const;
244 bool isValidValueNode(ValueRef const & value);
246 #if OSL_DEBUG_LEVEL > 0
247 bool isValidAnyNode(AnyNodeRef const & node);
248 #endif
250 /// checks whether the node has any element nodes (of its own)
251 bool hasElements(NodeRef const & node);
253 bool hasElement(NodeRef const & node, rtl::OUString const & name);
255 bool hasElement(NodeRef const & node, Path::Component const & name);
257 /** gets the element with the given name of the given node
258 <p>PRE: <code>hasElement(node, name)</code></p>
259 <p>If there is no such element, may return an empty node or
260 raise an exception (?)</p>
262 @throws InvalidName
263 if name is not a valid child name for this node
265 rtl::Reference< ElementTree > getElement(
266 NodeRef const & node, rtl::OUString const & name);
268 /** gets the element with the given name of the given node, if it is
269 available
270 <p>PRE: <code>hasElement(node, name)</code></p>
271 <p>If there is no such element, may return an empty node or
272 raise an exception (?)</p>
273 <p>Caution: May miss existing children unless hasChild/getChild
274 has been called before.</p>
276 @throws InvalidName
277 if name is not a valid child name for this node
279 rtl::Reference< ElementTree > getAvailableElement(
280 NodeRef const & node, rtl::OUString const & name);
282 /// checks whether the node has any child nodes (in this tree)
283 bool hasChildren(NodeRef const & node);
285 bool hasChildValue(
286 NodeRef const & node, rtl::OUString const & name);
288 bool hasChildNode(NodeRef const & node, rtl::OUString const & name);
290 bool hasChild(NodeRef const & node, rtl::OUString const & name);
292 /** gets the child value (in this tree) with the given name of the
293 given node
294 <p>PRE: <code>hasChildValue(node, name)</code></p>
295 <P>If there is no such node, may return an empty node or raise
296 an exception (?)</p>
298 @throws InvalidName
299 if <var>aName</var> is not a valid child name for this node
301 ValueRef getChildValue(
302 NodeRef const & node, rtl::OUString const & name);
304 NodeRef getChildNode(
305 NodeRef const & node, rtl::OUString const & name);
307 AnyNodeRef getAnyChild(
308 NodeRef const& node, rtl::OUString const & name);
310 node::Attributes getAttributes(NodeRef const & node);
312 node::Attributes getAttributes(AnyNodeRef const & node);
314 node::Attributes getAttributes(ValueRef const & value);
316 com::sun::star::uno::Type getUnoType(ValueRef const & value);
318 /// return the parent of the given node (or an empty node, if it is
319 /// the tree root)
320 NodeRef getParent(NodeRef const & node);
322 /// return the parent of the given value (or an empty node, if it is
323 /// the tree root)
324 NodeRef getParent(ValueRef const & value);
326 AbsolutePath getAbsolutePath(NodeRef const & node);
328 /// retrieves the current value for the given node, provided there
329 /// is one and it is available (only works for value nodes)
330 com::sun::star::uno::Any getNodeValue(ValueRef const & value);
332 /// checks whether the given node has a default value (only works
333 /// for value nodes)
334 bool hasNodeDefault(ValueRef const & value);
336 /// checks whether the given node assumes its default value (only
337 /// works for value nodes)
338 bool isNodeDefault(ValueRef const & value);
340 /// checks whether the given node has a default state
341 bool hasNodeDefault(NodeRef const & node);
343 /// checks whether the given node assumes its default state
344 bool isNodeDefault(NodeRef const & node);
346 /// checks whether the given node has a default state
347 bool hasNodeDefault(AnyNodeRef const & node);
349 /// checks whether the given node assumes its default state
350 bool isNodeDefault(AnyNodeRef const & node);
352 /// checks whether the default values are available for the children
353 /// of the given node (if applicable)
354 bool areValueDefaultsAvailable(NodeRef const & node);
356 /// retrieves the default value for the given node, provided there
357 /// is one and it is available (only works for value nodes)
358 com::sun::star::uno::Any getNodeDefaultValue(
359 ValueRef const & value);
361 bool hasChanges();
363 /// lists any pending changes on this tree
364 bool collectChanges(NodeChanges & changes);
366 void integrate(
367 NodeChange & change, NodeRef const & node, bool local);
369 void integrate(
370 NodeChanges & changes, NodeRef const & node, bool local);
372 NodeVisitor::Result visit(
373 NodeRef const & node, NodeVisitor & visitor)
374 { return visitor.handle(this, node); }
376 NodeVisitor::Result visit(
377 ValueRef const & value, NodeVisitor & visitor)
378 { return visitor.handle(this, value); }
380 /** lets the given visitor visit the child nodes of the given node
382 The order in which nodes are visited is repeatable (but
383 currently unspecified). Visits nodes until NodeVisitor::DONE is
384 returned, then returns NodeVisitor::DONE. If all visits return
385 NodeVisitor::CONTINUE, returns NodeVisitor::CONTINUE. If no
386 children are present, returns NodeVisitor::CONTINUE.
388 NodeVisitor::Result dispatchToChildren(
389 NodeRef const & node, NodeVisitor & visitor);
391 NodeRef getNode(unsigned int offset) const;
393 rtl::Reference< Template > extractElementInfo(NodeRef const & node);
395 /// gets the depth that is available in this tree (due to the original request)
396 unsigned int getAvailableDepth() const { return m_nDepth; }
398 /// gets the depth that is available in this tree within the given node
399 unsigned int getRemainingDepth(unsigned int nNode) const
400 { return remainingDepth(getAvailableDepth(),depthTo(nNode)); }
402 // Node Collection navigation
403 /** gets the simple name of the node <var>nNode</var>
404 <p>PRE: <code>isValidNode(nNode)</code>
405 </p>
407 rtl::OUString getSimpleNodeName(unsigned int nNode) const;
409 /** gets the simple name of the root node (i.e. of the tree as a whole)
411 virtual rtl::OUString getSimpleRootName() const;
413 /** gets the full name of the root node
415 Path::Component getExtendedRootName() const;
417 /** gets the number of hierarchy levels from the root node to node <var>nNode</var>
418 in this tree
419 <p>In particular <code>depthTo(N) == 0</code> if <code>N == root()</code>
420 </p>
421 <p>PRE: <code>isValidNode(nNode)</code>
422 </p>
424 unsigned int depthTo(unsigned int nNode) const;
426 /// append the local path (relative to root) to a node to a collection of names
427 void prependLocalPathTo(unsigned int nNode, Path::Rep& rNames);
429 // check whether defaults are available
430 bool hasDefaults(unsigned int _nNode) const;
431 public:
432 enum { ROOT = 1 }; /// base of <type>unsigned int</type>s used in this class
434 /** gets the <type>unsigned int</type> of the parent node <var>nNode</var> in this tree
435 or 0 (zero) if it is the root node
436 <p>PRE: <code>isValidNode(nNode)</code>
437 </p>
439 unsigned int parent_(unsigned int nNode) const;
441 // Node iteration and access
442 /** gets the <type>unsigned int</type> of the first child node
443 of node <var>nParent</var> in this tree (in list order)
444 or 0 (zero) if it has no children in this tree
445 <p>PRE: <code>isValidNode(nParent)</code>
446 </p>
448 unsigned int firstChild_ (unsigned int nParent) const;
450 /** gets the <type>unsigned int</type> of the first child node
451 of node <var>nParent</var> that is after
452 node <var>nNode</var> in this tree (in list order)
453 or 0 (zero) if there is no such node
454 <p>if <code>nStartAfter == 0</code> searching starts at the beginning
455 </p>
456 <p>PRE: <code>isValidNode(nParent)</code>
457 </p>
458 <p>PRE: <code>isValidNode(nStartAfter) || nStartAfter == 0</code>
459 </p>
461 unsigned int findNextChild_(unsigned int nParent, unsigned int nStartAfter) const;
463 /** gets the <type>unsigned int</type> of the first (and only) child node
464 of node <var>nParent</var> in this tree (in list order)
465 where the name of the node is <var>aName</var>,
466 or 0 (zero) if there is no such node
467 <p>PRE: <code>isValidNode(nParent)</code>
468 </p>
470 unsigned int findChild_(unsigned int nParent, rtl::OUString const& aName) const;
472 // Node Collection access
473 /// get the number of nodes in this tree
474 unsigned int nodeCount() const;
476 /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
477 NodeData* nodeData(unsigned int nNode);
478 /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
479 NodeData const* nodeData(unsigned int nNode) const;
480 /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
481 NodeImpl& nodeImpl(unsigned int nNode) { return nodeData(nNode)->nodeImpl(); }
482 /// get the <type>NodeData</type> for node <var>nNode</var> in this tree
483 NodeImpl const& nodeImpl(unsigned int nNode) const { return nodeData(nNode)->nodeImpl(); }
485 unsigned int nodeOffset(NodeData const & rNodeData) const;
487 // Behavior
488 rtl::Reference< view::ViewStrategy > getViewBehavior() const;
489 protected:
490 // immediate commit
491 /* // implementation of commit protocol
492 void commitDirect();
494 void implCommitDirectFrom(unsigned int nNode);
496 void implRebuild(unsigned int nNode, sharable::Node * _aNewData);
498 protected:
499 /// set a new parent context for this tree
500 void setContext(Tree* pParentTree, unsigned int nParentNode);
501 /// set no-parent context for this tree
502 void clearContext();
504 inline // is protected and should be used only in the implementation
505 rtl::OUString implGetOriginalName(unsigned int nNode) const;
507 private:
508 /// get the full name of the root of this tree
509 virtual Path::Component doGetRootName() const = 0;
511 /// prepend the absolute path to the root of this tree (no context use)
512 virtual void doFinishRootPath(Path::Rep& rPath) const = 0;
514 ValueMemberNode getMemberNode(ValueRef const & value);
516 rtl::Reference<view::ViewStrategy> m_xStrategy;
517 std::vector<NodeData> m_aNodes;
518 Tree* m_pParentTree;
519 unsigned int m_nParentNode;
520 unsigned int m_nDepth;
522 /// prepend the absolute path to the root of this tree (using context if present)
523 void implPrependRootPath(Path::Rep& rPath) const;
525 friend class TreeImplBuilder;
528 /// checks, if tree represents a real tree
529 bool isEmpty(Tree * tree);
530 //-----------------------------------------------------------------------------
532 class ElementTree : public Tree
534 public:
536 /// creates a Tree for a detached, virgin instance of <var>aTemplate</var> (always will be direct)
537 ElementTree(rtl::Reference< data::TreeSegment > const& _aElementData, rtl::Reference<Template> aTemplate, TemplateProvider const& aTemplateProvider );
539 /** creates a Tree with a parent tree, that (supposedly)
540 is an instance of <var>aTemplateInfo</var>
542 ElementTree(rtl::Reference<view::ViewStrategy> const& _xStrategy,
543 Tree& rParentTree, unsigned int nParentNode,
544 sharable::TreeFragment * dataTree, unsigned int nDepth,
545 rtl::Reference<Template> aTemplateInfo,
546 TemplateProvider const& aTemplateProvider );
548 /** creates a Tree with no parent node, that (supposedly)
549 is an instance of <var>aTemplateInfo</var>
551 ElementTree(rtl::Reference<view::ViewStrategy> const& _xStrategy,
552 sharable::TreeFragment * dataTree, unsigned int nDepth,
553 rtl::Reference<Template> aTemplateInfo,
554 TemplateProvider const& aTemplateProvider );
556 ~ElementTree();
558 // realeses the data this refers to
559 virtual void disposeData();
561 // rebuilding
562 using Tree::rebuild;
563 void rebuild(rtl::Reference<view::ViewStrategy> const& _xNewStrategy, sharable::TreeFragment * newData);
565 // data access
566 sharable::TreeFragment * getOriginalTreeAccess() const { return m_aDataAddress; }
568 // Tree information
569 virtual rtl::OUString getSimpleRootName() const;
570 /// checks whether this is an instance of a known template
571 bool isTemplateInstance() const { return !!m_aInstanceInfo.is(); }
572 /// checks whether this is an instance of the given template
573 bool isInstanceOf(rtl::Reference<Template> const& aTemplateInfo) const
574 { return m_aInstanceInfo == aTemplateInfo && aTemplateInfo.is(); }
575 /// retrieves the template that this is an instance of
576 rtl::Reference<Template> getTemplate() const { return m_aInstanceInfo; }
577 /// makes a complete name from a simple name and template information
578 Path::Component makeExtendedName(rtl::OUString const& aSimpleName) const;
580 // node control operation
581 /// check if this is a free-floating tree
582 bool isFree() const { return m_aOwnData.is(); }
583 /// transfer ownership to the given set
584 void attachTo(sharable::SetNode * updatableSetNode, rtl::OUString const& aElementName);
585 /// tranfer ownership from the given set
586 void detachFrom(sharable::SetNode * updatableSetNode, rtl::OUString const& aElementName);
588 /// take ownership of the given tree (which must not already be the one in use)
589 void takeTreeAndRebuild(rtl::Reference< data::TreeSegment > const& _aElementData);
590 /// take ownership of the given tree (which must already be the one in use)
591 void takeTreeBack(rtl::Reference< data::TreeSegment > const& _aElementData);
593 /// release ownership
594 rtl::Reference< data::TreeSegment > releaseOwnedTree();
596 // context operation
597 /// set a new root name
598 void renameTree(rtl::OUString const& aNewName);
599 /// set a new parent context for this tree
600 void moveTree(Tree* pParentTree, unsigned int nParentNode);
601 /// set no-parent context for this tree
602 void detachTree();
604 private:
605 static bool isUpdatableSegment(Tree& _rTree);
607 virtual Path::Component doGetRootName() const;
609 virtual void doFinishRootPath(Path::Rep& rPath) const;
610 private:
611 rtl::Reference<Template> const m_aInstanceInfo;
612 rtl::OUString m_aElementName;
613 sharable::TreeFragment * m_aDataAddress;
614 rtl::Reference< data::TreeSegment > m_aOwnData;
616 //-----------------------------------------------------------------------------
617 inline
618 bool Tree::isValidNode(unsigned int nNode) const
620 return ROOT <= nNode && nNode < nodeCount() + ROOT;
622 //---------------------------------------------------------------------
623 inline
624 unsigned int Tree::nodeCount() const
626 return m_aNodes.size();
628 //---------------------------------------------------------------------
629 inline
630 NodeData* Tree::nodeData(unsigned int nNode)
632 if (nNode == 0) return NULL;
633 OSL_ASSERT(isValidNode(nNode));
634 return &m_aNodes[nNode - ROOT];
636 //---------------------------------------------------------------------
637 inline
638 NodeData const* Tree::nodeData(unsigned int nNode) const
640 if (nNode == 0) return NULL;
641 OSL_ASSERT(isValidNode(nNode));
642 return &m_aNodes[nNode - ROOT];
644 //---------------------------------------------------------------------
645 inline
646 unsigned int Tree::nodeOffset(NodeData const & rNode) const
648 unsigned int nOffset = ROOT + (&rNode - &m_aNodes[0]);
649 OSL_ASSERT(isValidNode(nOffset));
650 return nOffset;
653 //-----------------------------------------------------------------------------
654 // helper for other impl classes
655 //-----------------------------------------------------------------------------
656 #if OSL_DEBUG_LEVEL > 0
657 struct ElementHelper
659 static
660 com::sun::star::uno::Type getUnoType(rtl::Reference< ElementTree > const& aElement);
662 #endif
663 //-----------------------------------------------------------------------------
665 //-----------------------------------------------------------------------------
668 #endif // CONFIGMGR_CONFIGNODEIMPL_HXX_