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: configpath.hxx,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 #ifndef CONFIGMGR_CONFIGPATH_HXX_
32 #define CONFIGMGR_CONFIGPATH_HXX_
34 #include <rtl/ustring.hxx>
36 #ifndef INCLUDED_VECTOR
38 #define INCLUDED_VECTOR
39 #endif // INCLUDED_VECTOR
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)
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
63 if the name is not valid for that purpose
65 rtl::OUString
validateElementName(rtl::OUString
const& sName
);
66 //------------------------------------------------------------------------
68 //------------------------------------------------------------------------
71 //------------------------------------------------------------------------
75 /// holds the contents of this path component
76 rtl::OUString m_aName
;
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>
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(());
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;
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 //------------------------------------------------------------------------
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(());
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
; }
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 //------------------------------------------------------------------------
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(());
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(); }
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
; }
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()); }
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 //------------------------------------------------------------------------
387 //------------------------------------------------------------------------
389 /// a weak strict ordering considering only the name part
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)
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)
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
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_