xref: /AOO41X/main/unotools/inc/unotools/configvaluecontainer.hxx (revision bae3752ec30c258ca902793e4eea3c818b0bcaad)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include "unotools/unotoolsdllapi.h"
24 
25 #ifndef UNOTOOLS_CONFIGVALUECONTAINER_HXX
26 #define UNOTOOLS_CONFIGVALUECONTAINER_HXX
27 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
28 #include <osl/mutex.hxx>
29 
30 //.........................................................................
31 namespace utl
32 {
33 //.........................................................................
34 
35 #define CVC_READONLY_ACCESS     0x0000
36 #define CVC_UPDATE_ACCESS       0x0001
37 
38 #define CVC_LAZY_UPDATE         0x0000
39 #define CVC_IMMEDIATE_UPDATE    0x0002
40 
41     struct OConfigurationValueContainerImpl;
42     struct NodeValueAccessor;
43     //=====================================================================
44     //= OConfigurationValueContainer
45     //=====================================================================
46     /** allows simple access to static configuration structures.
47 
48         <p>The basic idea of this class is that it's clients (usually derived classes) simply register an
49         address in memory and a node path, and upon explicit request, the configuration value and the memory
50         are syncronized.<br/>
51         This means that when calling <method>read</method>, the current configuration values are copied into
52         the memory registered for them, and upon calling <method>write</method> the current values in memory
53         are set in the configuration nodes.</p>
54 
55         <p>This way, the usage of this class is pretty straight forward: derive your own class, spend some members
56         to it, and bind these members to configuration node (usually done in the ctor of the derived class).<br/>
57         In the dtor, simply call <method>write</method> and <method>commit</method>.</p>
58 
59         <p>There is no auto-commit mechanism in the dtor: In the usual scenario, when you derive from this class
60         and bind some members of your derived class to config nodes, this means that your members will be destroyed
61         before your base class' dtor is called, so accessing the memory during such a theoretical auto-commit would
62         yield undefined behaviour.</p>
63     */
64     class UNOTOOLS_DLLPUBLIC OConfigurationValueContainer
65     {
66     private:
67         OConfigurationValueContainerImpl*
68                     m_pImpl;
69 
70     protected:
71         const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&
72                     getServiceFactory( ) const;
73 
74     protected:
75         //-----------------------------------------------------------------
76         // construction/destruction
77 
78         /** constructs the object
79 
80             @param _rxORB
81                 specifies the service factory which should be used to access the configuration
82             @param _rAccessSafety
83                 As this class is intented to manipulate objects it does not hold itself (see the various
84                 registerXXX methods), it needs to guard these access for muti threading safety.<br/>
85                 The mutex given here is locked whenever such an access occurs.
86             @param _pConfigLocation
87                 is an ASCII string describing the configurations node path
88             @param _nAccessFlags
89                 specifies different aspects of the configuration aspect to be created, e.g. it's update mode etc.<br/>
90                 See the CVC_xxx constants for what you can use here.
91             @param _nLevels
92                 specifies the number of levels to access under the node given by <arg>_pConfigLocation</arg>
93         */
94         OConfigurationValueContainer(
95             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
96             ::osl::Mutex& _rAccessSafety,
97             const sal_Char* _pConfigLocation,
98             const sal_uInt16 _nAccessFlags = CVC_UPDATE_ACCESS | CVC_LAZY_UPDATE,
99             const sal_Int32 _nLevels = -1
100         );
101 
102         /** constructs the object
103 
104             @param _rxORB
105                 specifies the service factory which should be used to access the configuration
106             @param _rAccessSafety
107                 As this class is intented to manipulate objects it does not hold itself (see the various
108                 registerXXX methods), it needs to guard these access for muti threading safety.<br/>
109                 The mutex given here is locked whenever such an access occurs.
110             @param _rConfigLocation
111                 describes the configurations node path
112             @param _nAccessFlags
113                 specifies different aspects of the configuration aspect to be created, e.g. it's update mode etc.<br/>
114                 See the CVC_xxx constants for what you can use here.
115             @param _nLevels
116                 specifies the number of levels to access under the node given by <arg>_pConfigLocation</arg>
117         */
118         OConfigurationValueContainer(
119             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
120             ::osl::Mutex& _rAccessSafety,
121             const ::rtl::OUString& _rConfigLocation,
122             const sal_uInt16 _nAccessFlags = CVC_UPDATE_ACCESS | CVC_LAZY_UPDATE,
123             const sal_Int32 _nLevels = -1
124         );
125 
126         /// dtor
127         ~OConfigurationValueContainer();
128 
129         //-----------------------------------------------------------------
130         // registering data containers
131 
132         /** registers a data accessor of an arbitrary type.
133 
134             <p>Usually, in your derived class you simply add a member of the correct type of the configuration
135             value, and then call this method with the address of this member.</p>
136 
137             <p>If the value you want to access may be <NULL/> at runtime, and if you want to recognize such
138             <NULL/> values, you may consider using <method>registerNullValueExchangeLocation</method>.</p>
139 
140             @param _pRelativePathAscii
141                 is a relative (ASCII) path of the node which should be "mirrored" into the accessor.
142             @param _pContainer
143                 points to the accessors location in memory. Usually, this is simply an address of your derived class
144             @param _rValueType
145                 is the type of your accessort. This type must be supported by the configuration.
146         */
147         void    registerExchangeLocation(
148             const sal_Char* _pRelativePathAscii,
149             void* _pContainer,
150             const ::com::sun::star::uno::Type& _rValueType
151         );
152 
153         /** registers a data accessor of an arbitrary type.
154 
155             <p>Usually, in your derived class you simply add a member of type <type scope="com.sun.star.uno">Any</type>,
156             and then call this method with the address of this member.</p>
157 
158             @param _pRelativePathAscii
159                 is a relative (ASCII) path of the node which should be "mirrored" into the accessor.
160             @param _pContainer
161                 points to the Any you want to hold the value
162         */
163         void    registerNullValueExchangeLocation(
164             const sal_Char* _pRelativePathAscii,
165             ::com::sun::star::uno::Any* _pContainer
166         );
167 
168     public:
169         /** reads the configuration data
170 
171             <p>The current values of the nodes bound (using the registerXXX methods) is copied into their
172             respective exchange locations.</p>
173 
174             <p>Please note that any changes done to your exchange locations are overridden with the current config
175             values.</p>
176 
177             @see write
178         */
179         void    read( );
180 
181         /** updates the configuration data
182 
183             <p>The current values in memory (your exchange locations registered using the registerXXX methods) is
184             forwarded to their respective configuration nodes.</p>
185 
186             <p>Note that calling <method>write</method>(<sal_True/) is the same as calling <method>commit</method>(<TRUE/>).</p>
187 
188             @precond
189                 The access must have been created for update access
190 
191             @param _bCommit
192                 If set to <TRUE/>, an automatic commit is done after the values have been synchronized.<br/>
193                 If set to <FALSE/>, you must explicitly call <method>commit</method> to make your changes persistent.
194 
195             @see read
196             @see commit
197         */
198         void    write( sal_Bool _bCommit = sal_True );
199 
200         /** commits any changes done
201 
202             <p>Note that calling <method>write</method>(<sal_True/) is the same as calling <method>commit</method>(<TRUE/>).</p>
203 
204             @precond
205                 The access must have been created for update access
206 
207             @param _bWrite
208                 If <TRUE/>, the current values in the exchange locations are written to the configuration nodes
209                 before the changes are committed.<br/>
210                 If <FALSE/>, only the current values in the config nodes (as present since the last call to
211                 <method>write</method>) are committed.
212         */
213         void    commit( sal_Bool _bWrite = sal_True );
214 
215     private:
216         /// implements the ctors
217         void implConstruct(
218             const ::rtl::OUString& _rConfigLocation,
219             const sal_uInt16 _nAccessFlags,
220             const sal_Int32 _nLevels
221         );
222 
223         /// registers a value container
224         void    implRegisterExchangeLocation( const NodeValueAccessor& _rAccessor );
225     };
226 
227 //.........................................................................
228 }   // namespace utl
229 //.........................................................................
230 
231 #endif // UNOTOOLS_CONFIGVALUECONTAINER_HXX
232 
233