Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef _UNOTOOLS_CONFIGNODE_HXX_
20 : #define _UNOTOOLS_CONFIGNODE_HXX_
21 :
22 : #include "unotools/unotoolsdllapi.h"
23 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
24 : #include <com/sun/star/container/XNameAccess.hpp>
25 : #include <com/sun/star/container/XNameContainer.hpp>
26 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 : #include <com/sun/star/util/XChangesBatch.hpp>
28 : #include <com/sun/star/uno/XComponentContext.hpp>
29 : #include <unotools/eventlisteneradapter.hxx>
30 :
31 : namespace comphelper
32 : {
33 : class ComponentContext;
34 : }
35 :
36 : //........................................................................
37 : namespace utl
38 : {
39 : //........................................................................
40 :
41 : //========================================================================
42 : //= OConfigurationNode
43 : //========================================================================
44 : class OConfigurationTreeRoot;
45 : /** a small wrapper around a configuration node.<p/>
46 : Nodes in the terminology used herein are <em>inner</em> nodes of a configuration
47 : tree, which means <em>no leafs</em>.
48 : */
49 : class UNOTOOLS_DLLPUBLIC OConfigurationNode : public ::utl::OEventListenerAdapter
50 : {
51 : private:
52 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess >
53 : m_xHierarchyAccess; /// accessing children grandchildren (mandatory interface of our UNO object)
54 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
55 : m_xDirectAccess; /// accessing children (mandatory interface of our UNO object)
56 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameReplace >
57 : m_xReplaceAccess; /// replacing child values
58 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
59 : m_xContainerAccess; /// modifying set nodes (optional interface of our UNO object)
60 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
61 : m_xDummy;
62 : sal_Bool m_bEscapeNames; /// escape names before accessing children ?
63 :
64 : OUString
65 : m_sCompletePath;
66 :
67 : OConfigurationNode insertNode(const OUString& _rName,const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xNode) const throw();
68 :
69 : protected:
70 : /// constructs a node object with an interface representing a node
71 : OConfigurationNode(
72 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxNode
73 : );
74 :
75 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >&
76 19 : getUNONode() const { return m_xDirectAccess; }
77 :
78 : public:
79 : /// constructs an empty and invalid node object
80 204 : OConfigurationNode() :m_bEscapeNames(sal_False) { }
81 : /// copy ctor
82 : OConfigurationNode(const OConfigurationNode& _rSource);
83 :
84 : /// assigment
85 : const OConfigurationNode& operator=(const OConfigurationNode& _rSource);
86 :
87 : /// dtor
88 3738 : ~OConfigurationNode() {}
89 :
90 : /// returns the local name of the node
91 : OUString getLocalName() const;
92 :
93 : /// returns the fully qualified path of the node
94 : OUString getNodePath() const;
95 :
96 : /** open a sub node
97 : @param _rPath access path of the to-be-opened sub node. May be a hierarchical path.
98 : */
99 : OConfigurationNode openNode(const OUString& _rPath) const throw();
100 :
101 0 : OConfigurationNode openNode( const sal_Char* _pAsciiPath ) const
102 : {
103 0 : return openNode( OUString::createFromAscii( _pAsciiPath ) );
104 : }
105 :
106 : /** create a new child node
107 :
108 : If the object represents a set node, this method may be used to create a new child. For non-set-nodes, the
109 : method will fail.<br/>
110 : Unless the respective operations on the pure configuration API, the to-be-created node immediately
111 : becomes a part of it's hierarchy, no explicit insertion is necessary.
112 : @param _rName name for the new child. Must be level-1-depth.
113 : */
114 : OConfigurationNode createNode(const OUString& _rName) const throw();
115 :
116 : OConfigurationNode createNode( const sal_Char* _pAsciiName ) const
117 : {
118 : return createNode( OUString::createFromAscii( _pAsciiName ) );
119 : }
120 :
121 : /** remove an existent child nod
122 :
123 : If the object represents a set node, this method may be used to delete an existent child. For non-set-nodes,
124 : the method will fail.
125 : */
126 : sal_Bool removeNode(const OUString& _rName) const throw();
127 :
128 : sal_Bool removeNode( const sal_Char* _pAsciiName ) const
129 : {
130 : return removeNode( OUString::createFromAscii( _pAsciiName ) );
131 : }
132 :
133 : /** retrieves the content of a descendant
134 :
135 : the returned value may contain anything from an interface (if <arg>_rPath</arg> refers to inner node of
136 : the configuration tree) to any explicit value (e.g. string, integer) or even void.<br/>
137 : Unfortunately, this implies that if a void value is returned, you won't have a clue if this means
138 : "the path does not exist" (besides the assertion made :), or if the value is really void.
139 : */
140 : ::com::sun::star::uno::Any
141 : getNodeValue(const OUString& _rPath) const throw();
142 :
143 : ::com::sun::star::uno::Any
144 908 : getNodeValue( const sal_Char* _pAsciiPath ) const
145 : {
146 908 : return getNodeValue( OUString::createFromAscii( _pAsciiPath ) );
147 : }
148 :
149 : /** write a node value<p/>
150 : The value given is written into the node specified by the given relative path.<br/>
151 : In opposite to <method>getNodeValue</method>, _rName must refer to a leaf in the configuration tree, not an inner
152 : node.
153 : @return sal_True if and only if the write was successful.
154 : */
155 : sal_Bool setNodeValue(const OUString& _rPath, const ::com::sun::star::uno::Any& _rValue) const throw();
156 :
157 19 : sal_Bool setNodeValue( const sal_Char* _pAsciiPath, const ::com::sun::star::uno::Any& _rValue ) const
158 : {
159 19 : return setNodeValue( OUString::createFromAscii( _pAsciiPath ), _rValue );
160 : }
161 :
162 : /// return the names of the existing children
163 : ::com::sun::star::uno::Sequence< OUString >
164 : getNodeNames() const throw();
165 :
166 : /** enables or disables name escaping when accessing direct children<p/>
167 : Escaping is disabled by default, usually you enable it for set nodes (e.g. with calling setEscape(isSetNode)).
168 : Once escaping is enabled, you should not access indirect children (e.g. openNode("child/grandchild"), 'cause
169 : escaping for such names may not be supported by the underlying API objects.
170 : @see getEscape
171 : */
172 : void setEscape(sal_Bool _bEnable = sal_True);
173 : /** get the flag specifying the current escape behaviour
174 : @see setEscape
175 : */
176 13373 : sal_Bool getEscape() const { return m_bEscapeNames; }
177 :
178 : /// invalidate the object
179 : virtual void clear() throw();
180 :
181 : // -----------------------
182 : // meta information about the node
183 :
184 : /// checks whether or not the object represents a set node.
185 : sal_Bool isSetNode() const;
186 :
187 : /// checks whether or not a direct child with a given name exists
188 : sal_Bool hasByName(const OUString& _rName) const throw();
189 0 : sal_Bool hasByName( const sal_Char* _pAsciiName ) const { return hasByName( OUString::createFromAscii( _pAsciiName ) ); }
190 :
191 : /// checks whether or not a descendent (no matter if direct or indirect) with the given name exists
192 : sal_Bool hasByHierarchicalName( const OUString& _rName ) const throw();
193 : sal_Bool hasByHierarchicalName( const sal_Char* _pAsciiName ) const { return hasByHierarchicalName( OUString::createFromAscii( _pAsciiName ) ); }
194 :
195 : /// check if the objects represents a valid configuration node
196 4718 : sal_Bool isValid() const { return m_xHierarchyAccess.is(); }
197 :
198 : /// check whether the object is read-only of updatable
199 86 : sal_Bool isReadonly() const { return !m_xReplaceAccess.is(); }
200 :
201 : protected:
202 : // OEventListenerAdapter
203 : virtual void _disposing( const ::com::sun::star::lang::EventObject& _rSource );
204 :
205 : protected:
206 : enum NAMEORIGIN
207 : {
208 : NO_CONFIGURATION, /// the name came from a configuration node
209 : NO_CALLER /// the name came from a client of this class
210 : };
211 : OUString normalizeName(const OUString& _rName, NAMEORIGIN _eOrigin) const;
212 : };
213 :
214 : //========================================================================
215 : //= OConfigurationTreeRoot
216 : //========================================================================
217 : /** a specialized version of a OConfigurationNode, representing the root
218 : of a configuration sub tree<p/>
219 : Only this class is able to commit any changes made any any OConfigurationNode
220 : objects.
221 : */
222 769 : class UNOTOOLS_DLLPUBLIC OConfigurationTreeRoot : public OConfigurationNode
223 : {
224 : ::com::sun::star::uno::Reference< ::com::sun::star::util::XChangesBatch >
225 : m_xCommitter;
226 : protected:
227 : /** ctor for a readonly node
228 : */
229 : OConfigurationTreeRoot(
230 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxRootNode
231 : );
232 :
233 : public:
234 : /// modes to use when creating a top-level node object
235 : enum CREATION_MODE
236 : {
237 : /// open the node (i.e. sub tree) for read access only
238 : CM_READONLY,
239 : /// open the node (i.e. sub tree) for read and write access, fall back to read-only if write access is not possible
240 : CM_UPDATABLE
241 : };
242 :
243 : public:
244 : /** default ctor<p/>
245 : The object constructed here is invalid (i.e. <method>isValid</method> will return sal_False).
246 : */
247 25 : OConfigurationTreeRoot() :OConfigurationNode() { }
248 :
249 : /** creates a configuration tree for the given path in the given mode
250 : */
251 : OConfigurationTreeRoot(
252 : const css::uno::Reference<css::uno::XComponentContext> & i_rContext,
253 : const OUString& i_rNodePath,
254 : const bool i_bUpdatable
255 : );
256 :
257 : /// copy ctor
258 0 : OConfigurationTreeRoot(const OConfigurationTreeRoot& _rSource)
259 0 : :OConfigurationNode(_rSource), m_xCommitter(_rSource.m_xCommitter) { }
260 :
261 : /** open a new top-level configuration node
262 :
263 : opens a new node which is the root if an own configuration sub tree. This is what "top level" means: The
264 : node does not have a parent. It does not mean that the node represents a module tree (like org.openoffice.Office.Writer
265 : or such).<br/>
266 : In opposite to <method>createWithServiceFactory</method>, createWithProvider expects a configuration provider
267 : to work with.
268 :
269 : @param _rxConfProvider configuration provider to use when retrieving the node.
270 : @param _rPath path to the node the object should represent
271 : @param _nDepth depth for node retrieval
272 : @param _eMode specifies which privileges should be applied when retrieving the node
273 :
274 : @see createWithServiceFactory
275 : */
276 : static OConfigurationTreeRoot createWithProvider(
277 : const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxConfProvider,
278 : const OUString& _rPath,
279 : sal_Int32 _nDepth = -1,
280 : CREATION_MODE _eMode = CM_UPDATABLE,
281 : sal_Bool _bLazyWrite = sal_True
282 : );
283 :
284 : /** open a new top-level configuration node<p/>
285 : opens a new node which is the root if an own configuration sub tree. This is what "top level" means: The
286 : node does not have a parent. It does not mean that the node represents a module tree (like org.openoffice.Office.Writer
287 : or such).<br/>
288 : In opposite to <method>createWithProvider</method>, createWithProvider expects a service factory. This factory
289 : is used to create a configuration provider, and this provider is used to retrieve the node
290 : @see createWithProvider
291 : @param _rxContext service factory to use to create the configuration provider.
292 : @param _rPath path to the node the object should represent
293 : @param _nDepth depth for node retrieval
294 : @param _eMode specifies which privileges should be applied when retrieving the node
295 : */
296 : static OConfigurationTreeRoot createWithComponentContext(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
297 : const OUString& _rPath, sal_Int32 _nDepth = -1, CREATION_MODE _eMode = CM_UPDATABLE, sal_Bool _bLazyWrite = sal_True);
298 :
299 : /** tolerant version of the <member>createWithServiceFactory</member>
300 :
301 : <p>No assertions are thrown in case of an failure to initialize the configuration service, but once
302 : the configuration could be initialized, errors in the creation of the specific node (e.g. because the
303 : given node path does not exist) are still asserted.</p>
304 : */
305 : static OConfigurationTreeRoot tryCreateWithComponentContext( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
306 : const OUString& _rPath, sal_Int32 _nDepth = -1, CREATION_MODE _eMode = CM_UPDATABLE, sal_Bool _bLazyWrite = sal_True );
307 :
308 : /** commit all changes made on the subtree the object is the root for<p/>
309 : All changes made on any OConfigurationNode object retrieved (maybe indirect) from this root
310 : object are committed when calling this method.
311 : @return sal_True if and only if the commit was successful
312 : */
313 : sal_Bool commit() const throw();
314 :
315 : /// invalidate the object
316 : virtual void clear() throw();
317 : };
318 :
319 : //........................................................................
320 : } // namespace utl
321 : //........................................................................
322 :
323 : #endif // _UNOTOOLS_CONFIGNODE_HXX_
324 :
325 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|