Update ooo320-m1
[ooovba.git] / configmgr / source / inc / configpath.hxx
blob05b09337f86864d2e73406eaec129c27e3cc4a13
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: configpath.hxx,v $
10 * $Revision: 1.17 $
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_CONFIGPATH_HXX_
32 #define CONFIGMGR_CONFIGPATH_HXX_
34 #include <rtl/ustring.hxx>
36 #ifndef INCLUDED_VECTOR
37 #include <vector>
38 #define INCLUDED_VECTOR
39 #endif // INCLUDED_VECTOR
41 namespace configmgr
43 namespace configuration
45 //--------------------------------------------------------------------
47 /** check if this is a well-formed name for a
48 config Node (excluding set elements)
50 bool isSimpleName(rtl::OUString const& sName) SAL_THROW(());
52 /** make a name out of <var>sName</var>,
53 validating that it can be used for a config Node (excluding set elements)
54 or template name.
55 @throws InvalidName
56 if the name is not valid for that purpose
58 rtl::OUString validateNodeName(rtl::OUString const& sName);
60 /** make a name out of <var>sName</var>
61 validating that it can be used for a config set element
62 @throws InvalidName
63 if the name is not valid for that purpose
65 rtl::OUString validateElementName(rtl::OUString const& sName);
66 //------------------------------------------------------------------------
68 //------------------------------------------------------------------------
69 namespace Path
71 //------------------------------------------------------------------------
73 class Component
75 /// holds the contents of this path component
76 rtl::OUString m_aName;
77 public:
78 /// construct a path component from a string, without any validation
79 Component(rtl::OUString const& _sName) SAL_THROW(());
81 /// is this component an empty name ?
82 bool isEmpty() const SAL_THROW(()) { return m_aName.getLength() == 0; }
83 /// is this component a simple name ?
84 bool isSimpleName() const SAL_THROW(());
85 /// get the inner name for this component
86 rtl::OUString getName() const SAL_THROW(());
87 /// get the embedded type name for this component (if any)
88 rtl::OUString getTypeName() const SAL_THROW(());
90 /// get the contents of this as string (unparsed).
91 rtl::OUString toPathString() const SAL_THROW(()) { return m_aName; }
93 // hashing - for hash maps. compatible to equiv or matches
94 size_t hashCode() const SAL_THROW(())
95 { return this->getName().hashCode(); }
97 /// get the contents of this as a name (unparsed). Use with care !
98 rtl::OUString const& getInternalName() const SAL_THROW(()) { return m_aName; }
102 //-------------------------------------------------------------------------
104 /// compare taking type wildcards into account
105 bool matches(Component const& lhs,Component const& rhs) SAL_THROW(());
107 /// compare by inner names only
108 bool before(Component const& lhs,Component const& rhs) SAL_THROW(());
110 /// compare by inner names only
111 bool equiv(Component const& lhs,Component const& rhs) SAL_THROW(());
112 //-------------------------------------------------------------------------
114 /// construct a empty path component
115 Component makeEmptyComponent() SAL_THROW(());
117 //-------------------------------------------------------------------------
118 /// construct a path component from a name, validating it as simple name
119 Component wrapSimpleName(rtl::OUString const& _aName);
121 /// construct a path component from a type and element name, using a wildcard if no type is available
122 Component makeCompositeName(rtl::OUString const& _aElementName, rtl::OUString const& _aTypeName);
124 //-----------------------------------------------------------------------------
125 /// construct a composite path component from a element name or string, using a wildcard type
126 template <class NameRep>
127 Component wrapElementName(NameRep const& _aElementName) SAL_THROW(())
129 return makeCompositeName(_aElementName, NameRep());
132 //-------------------------------------------------------------------------
133 /// construct a path component from an arbitrary na,e or string
134 template <class NameRep>
135 Component wrapSafeName(NameRep const& _aName) SAL_THROW(())
137 return isSimpleName(_aName) ? wrapSimpleName(_aName) : wrapElementName(_aName);
140 //-----------------------------------------------------------------------------
141 /** lower-level representation of a path within the configuration
142 <p>Keeps the data in a vector of names in reverse order! </P>
144 class Rep
146 public:
147 /// construct an empty path
148 Rep() SAL_THROW(()) : m_aComponents() {}
150 /// construct a path consisting of a single component <var>_aName</var>
151 explicit Rep(Component const& _aName) SAL_THROW(()) : m_aComponents(1,_aName) {}
153 /// construct a path consisting of a path subrange
154 explicit Rep(std::vector<Component>::const_reverse_iterator const& _first, std::vector<Component>::const_reverse_iterator const& _last)
155 : m_aComponents(_last.base(), _first.base()) {}
157 /// swap contents with another instance
158 void swap(Rep& _aOther) SAL_THROW(()) { m_aComponents.swap(_aOther.m_aComponents); }
160 /// modify a path by prepending <var>aName</var>
161 void prepend(Component const& _aName) SAL_THROW(()) { m_aComponents.push_back(_aName); }
163 /// modify a path by prepending <var>aName</var>
164 void prepend(Rep const& _aOther) SAL_THROW(());
166 /// get the local name (the last component of this path)
167 Component const& getLocalName() const { check_not_empty(); return m_aComponents.front(); }
169 /// get the next name (the first component of this path)
170 Component const& getFirstName() const { check_not_empty(); return m_aComponents.back(); }
172 /// set this to the remainder after the first name (drop the first component of this path)
173 void dropFirstName() { check_not_empty(); m_aComponents.pop_back(); }
175 /// get a /-separated string representation of this
176 rtl::OUString toString(bool _bAbsolute) const SAL_THROW(());
178 public:
179 /// check if this is an empty path
180 bool isEmpty() const SAL_THROW(()) { return m_aComponents.empty(); }
182 /// Count the components of this
183 std::vector<Component>::size_type countComponents() const SAL_THROW(()) { return m_aComponents.size(); }
185 /// Insert a component into this path
186 void insertComponent(std::vector<Component>::reverse_iterator _it, Component _aName)
187 { m_aComponents.insert(_it.base(),_aName); }
189 /// Remove a component from this path
190 void removeComponent(std::vector<Component>::reverse_iterator _it) { m_aComponents.erase(_it.base()); }
192 /// Remove all components from this path
193 void clearComponents() SAL_THROW(()) { m_aComponents.clear(); }
195 /// get a STL style iterator to the first component
196 std::vector<Component>::const_reverse_iterator begin() const SAL_THROW(()) { return m_aComponents.rbegin(); }
197 /// get a STL style iterator to after the last component
198 std::vector<Component>::const_reverse_iterator end() const SAL_THROW(()) { return m_aComponents.rend(); }
200 /// get a STL style iterator to the first component
201 std::vector<Component>::reverse_iterator begin_mutate() SAL_THROW(()) { return m_aComponents.rbegin(); }
202 /// get a STL style iterator to after the last component
203 std::vector<Component>::reverse_iterator end_mutate() SAL_THROW(()) { return m_aComponents.rend(); }
205 // hashing - for hash maps
206 size_t hashCode() const SAL_THROW(());
208 /// preflight check for operations that require a non-empty path
209 void check_not_empty() const;
211 private:
212 std::vector<Component> m_aComponents;
214 //------------------------------------------------------------------------
216 /// compare taking type wildcards into account
217 bool matches(Rep const& lhs,Rep const& rhs) SAL_THROW(());
219 /// compare by inner names only
220 bool before(Rep const& lhs,Rep const& rhs) SAL_THROW(());
222 /// compare by inner names only
223 bool equiv(Rep const& lhs,Rep const& rhs) SAL_THROW(());
224 //------------------------------------------------------------------------
226 /// check a path for a prefix
227 bool hasMatchingPrefix(Rep const& _aPath,Rep const& _aPrefix) SAL_THROW(());
229 /// remove a prefix from a path. Throws InvalidName if it isn't a prefix
230 Rep stripMatchingPrefix(Rep const& _aPath,Rep const& _aPrefix);
231 //------------------------------------------------------------------------
233 /// distinguishes which kind of path is present in a string
234 bool isAbsolutePath(rtl::OUString const& _sPath);
235 //------------------------------------------------------------------------
237 //------------------------------------------------------------------------
239 class RelativePath
241 Path::Rep m_aRep;
242 public:
243 // Construction
244 /// construct a relative path from <var>aString</var> throwing InvalidName for parse errors
245 static RelativePath parse(rtl::OUString const& _aString);
247 /// construct an empty relative path
248 RelativePath() SAL_THROW(()) : m_aRep() { init(); }
250 /// construct a relative path having <var>aRep</var> as representation
251 explicit RelativePath(Path::Rep const& _aRep)
252 : m_aRep(_aRep) { init(); }
254 /// CONVERSION: construct a relative path having <var>aName</var> as single component
255 RelativePath(Path::Component const& _aName) SAL_THROW(());
257 /// build the Path that results from appending <var>aPath</var> to this
258 RelativePath compose(RelativePath const& _aPath) const SAL_THROW(());
260 /// check if this is an empty path
261 bool isEmpty() const SAL_THROW(()) { return m_aRep.isEmpty(); }
263 /// Count the components of this
264 std::vector<Path::Component>::size_type getDepth() const SAL_THROW(()) { return m_aRep.countComponents(); }
266 /// get the local name (the last component of this path)
267 Path::Component const& getLocalName() const { return m_aRep.getLocalName(); }
269 /// get the local name (the first component of this path)
270 Path::Component const& getFirstName() const { return m_aRep.getFirstName(); }
272 /// set this to the remainder of this path after the first name (drop the first component of this path)
273 void dropFirstName() { m_aRep.dropFirstName(); }
275 /// get a /-separated string representation of this
276 rtl::OUString toString() const SAL_THROW(());
277 public:
278 // Iteration support
279 /// get a STL style iterator to the first component
280 std::vector<Path::Component>::const_reverse_iterator begin() const SAL_THROW(()) { return m_aRep.begin(); }
281 /// get a STL style iterator to after the last component
282 std::vector<Path::Component>::const_reverse_iterator end() const SAL_THROW(()) { return m_aRep.end(); }
284 /// get a STL style iterator to the first component
285 std::vector<Path::Component>::reverse_iterator begin_mutate() SAL_THROW(()) { return m_aRep.begin_mutate(); }
286 /// get a STL style iterator to after the last component
287 std::vector<Path::Component>::reverse_iterator end_mutate() SAL_THROW(()) { return m_aRep.end_mutate(); }
289 // Direct access - 'package' visible
290 /// Get a reference to (or copy of) the internal PathRep of this
291 Path::Rep const& rep() const SAL_THROW(()) { return m_aRep; }
293 private:
294 void init();
297 /// compare taking type wildcards into account
298 inline bool matches(RelativePath const& lhs,RelativePath const& rhs) SAL_THROW(())
299 { return Path::matches(lhs.rep(),rhs.rep()); }
301 //------------------------------------------------------------------------
303 class AbsolutePath
305 Path::Rep m_aRep;
306 public:
307 // Construction
308 /// construct a absolute path from <var>aString</var> throwing InvalidName for parse errors
309 static AbsolutePath parse(rtl::OUString const& _aString);
311 /// construct a absolute path to a whole module (toplevel) without error checking
312 static AbsolutePath makeModulePath(rtl::OUString const& _aString) SAL_THROW(());
314 /// construct an absolute path to the (virtual) hierarchy root
315 static AbsolutePath root() SAL_THROW(());
317 /// construct an (otherwise invalid) substitute path for the root of a free-floating node
318 static AbsolutePath detachedRoot() SAL_THROW(());
320 /// construct a absolute path having <var>aRep</var> as representation
321 explicit AbsolutePath(Path::Rep const& _aRep) SAL_THROW(())
322 : m_aRep(_aRep) { init(); }
324 /// build the absolute path that results from appending <var>aPath</var> to this
325 AbsolutePath compose(RelativePath const& _aPath) const SAL_THROW(());
327 /// build the absolute path that results from removing the last component of this
328 AbsolutePath getParentPath() const;
330 /// check if this is the path to the (imaginary) root node
331 bool isRoot() const SAL_THROW(()) { return m_aRep.isEmpty(); }
332 #if OSL_DEBUG_LEVEL > 0
333 /// check if this is a path to a detached node
334 bool isDetached() const SAL_THROW(());
335 #endif
336 /// get the local name (the last component of this path)
337 Path::Component const& getLocalName() const { return m_aRep.getLocalName(); }
339 rtl::OUString const & getModuleName() const { return m_aRep.getFirstName().getInternalName(); }
341 /// get a /-separated string representation of this
342 rtl::OUString toString() const SAL_THROW(());
344 /// Count the components of this
345 std::vector<Path::Component>::size_type getDepth() const SAL_THROW(()) { return m_aRep.countComponents(); }
346 public:
347 // Iteration support
348 /// get a STL style iterator to the first component
349 std::vector<Path::Component>::const_reverse_iterator begin() const SAL_THROW(()) { return m_aRep.begin(); }
350 /// get a STL style iterator to after the last component
351 std::vector<Path::Component>::const_reverse_iterator end() const SAL_THROW(()) { return m_aRep.end(); }
353 /// get a STL style iterator to the first component
354 std::vector<Path::Component>::reverse_iterator begin_mutate() SAL_THROW(()) { return m_aRep.begin_mutate(); }
355 /// get a STL style iterator to after the last component
356 std::vector<Path::Component>::reverse_iterator end_mutate() SAL_THROW(()) { return m_aRep.end_mutate(); }
358 // Direct access - 'package' visible
359 /// Get a reference to (or copy of) the internal PathRep of this
360 Path::Rep const& rep() const SAL_THROW(()) { return m_aRep; }
361 private:
362 void init() SAL_THROW(());
365 /// compare taking type wildcards into account
366 inline bool matches(AbsolutePath const& lhs,AbsolutePath const& rhs) SAL_THROW(())
367 { return Path::matches(lhs.rep(),rhs.rep()); }
369 namespace Path
371 //------------------------------------------------------------------------
372 template <class PathClass>
373 bool hasPrefix(PathClass const& _aPath, PathClass const& _aPrefix) SAL_THROW(())
375 return hasMatchingPrefix(_aPath.rep(),_aPrefix.rep() );
377 //------------------------------------------------------------------------
379 template <class PathClass>
380 RelativePath stripPrefix(PathClass const& _aPath, PathClass const& _aPrefix)
382 return RelativePath( stripMatchingPrefix(_aPath.rep(),_aPrefix.rep()) );
384 //------------------------------------------------------------------------
386 // STL Helpers
387 //------------------------------------------------------------------------
389 /// a weak strict ordering considering only the name part
390 struct Before
392 bool operator()(Component const& lhs, Component const& rhs) const SAL_THROW(())
393 { return before(lhs,rhs); }
394 bool operator()(Rep const& lhs, Rep const& rhs) const SAL_THROW(())
395 { return before(lhs,rhs); }
396 bool operator()(AbsolutePath const& lhs, AbsolutePath const& rhs) const SAL_THROW(())
397 { return before(lhs.rep(),rhs.rep()); }
398 bool operator()(RelativePath const& lhs, RelativePath const& rhs) const SAL_THROW(())
399 { return before(lhs.rep(),rhs.rep()); }
401 //------------------------------------------------------------------------
403 /// an equality relation considering only the name part (compatible to Before)
404 struct Equiv
406 bool operator()(Component const& lhs, Component const& rhs) const SAL_THROW(())
407 { return equiv(lhs,rhs); }
408 bool operator()(Rep const& lhs, Rep const& rhs) const SAL_THROW(())
409 { return equiv(lhs,rhs); }
410 bool operator()(AbsolutePath const& lhs, AbsolutePath const& rhs) const SAL_THROW(())
411 { return equiv(lhs.rep(),rhs.rep()); }
412 bool operator()(RelativePath const& lhs, RelativePath const& rhs) const SAL_THROW(())
413 { return equiv(lhs.rep(),rhs.rep()); }
415 //------------------------------------------------------------------------
417 /// a hash generator (compatible to Equiv and Before)
418 struct Hash
420 size_t operator()(Component const& _aObject) const SAL_THROW(())
421 { return _aObject.hashCode(); }
422 size_t operator()(Rep const& _aObject) const SAL_THROW(())
423 { return _aObject.hashCode(); }
424 size_t operator()(AbsolutePath const& _aObject) const SAL_THROW(())
425 { return _aObject.rep().hashCode(); }
426 size_t operator()(RelativePath const& _aObject) const SAL_THROW(())
427 { return _aObject.rep().hashCode(); }
429 //------------------------------------------------------------------------
430 /// a binary predicate that is not (!) an equivalence relation
432 struct Matches
434 bool operator()(Component const& lhs, Component const& rhs) const SAL_THROW(())
435 { return matches(lhs,rhs); }
436 bool operator()(Rep const& lhs, Rep const& rhs) const SAL_THROW(())
437 { return matches(lhs,rhs); }
438 bool operator()(AbsolutePath const& lhs, AbsolutePath const& rhs) const SAL_THROW(())
439 { return matches(lhs.rep(),rhs.rep()); }
440 bool operator()(RelativePath const& lhs, RelativePath const& rhs) const SAL_THROW(())
441 { return matches(lhs.rep(),rhs.rep()); }
443 //------------------------------------------------------------------------
445 //------------------------------------------------------------------------
449 #endif // CONFIGMGR_CONFIGNAME_HXX_