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