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 :
20 : #include <jobs/configaccess.hxx>
21 : #include <threadhelp/readguard.hxx>
22 : #include <threadhelp/writeguard.hxx>
23 : #include <threadhelp/resetableguard.hxx>
24 : #include <general.h>
25 : #include <services.h>
26 :
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
29 : #include <com/sun/star/configuration/theDefaultProvider.hpp>
30 : #include <com/sun/star/container/XNameAccess.hpp>
31 : #include <com/sun/star/beans/PropertyValue.hpp>
32 : #include <com/sun/star/util/XChangesBatch.hpp>
33 :
34 : #include <unotools/configpaths.hxx>
35 : #include <rtl/ustrbuf.hxx>
36 :
37 : namespace framework{
38 :
39 : /**
40 : @short open the configuration of this job
41 : @descr We open the configuration of this job only. Not the whole package or the whole
42 : job set. We are interested on our own properties only.
43 : We set the opened configuration access as our member. So any following method,
44 : which needs cfg access, can use it. That prevent us against multiple open/close requests.
45 : But you can use this method to upgrade an already opened configuration too.
46 :
47 : @param eMode
48 : force opening of the configuration access in readonly or in read/write mode
49 : */
50 266 : ConfigAccess::ConfigAccess( /*IN*/ const css::uno::Reference< css::uno::XComponentContext >& rxContext,
51 : /*IN*/ const ::rtl::OUString& sRoot )
52 : : ThreadHelpBase( )
53 : , m_xContext ( rxContext)
54 : , m_sRoot ( sRoot )
55 266 : , m_eMode ( E_CLOSED )
56 : {
57 266 : }
58 :
59 : //________________________________
60 : /**
61 : @short last chance to close an open configuration access point
62 : @descr In case our user forgot to close this configuration point
63 : in the right way, normaly he will run into some trouble -
64 : e.g. losing data.
65 : */
66 500 : ConfigAccess::~ConfigAccess()
67 : {
68 250 : close();
69 250 : }
70 :
71 : //________________________________
72 : /**
73 : @short return the internal mode of this instance
74 : @descr May be the outside user need any information about successfully opened
75 : or closed config access point objects. He can control the internal mode to do so.
76 :
77 : @return The internal open state of this object.
78 : */
79 266 : ConfigAccess::EOpenMode ConfigAccess::getMode() const
80 : {
81 : /* SAFE { */
82 266 : ReadGuard aReadLock(m_aLock);
83 266 : return m_eMode;
84 : /* } SAFE */
85 : }
86 :
87 : //________________________________
88 : /**
89 : @short open the configuration access in the specified mode
90 : @descr We set the opened configuration access as our member. So any following method,
91 : which needs cfg access, can use it. That prevent us against multiple open/close requests.
92 : But you can use this method to upgrade an already opened configuration too.
93 : It's possible to open a config access in READONLY mode first and "open" it at a second
94 : time within the mode READWRITE. Then we will upgrade it. Dowgrade will be possible too.
95 :
96 : But note: closing will be done explicitly by calling method close() ... not by
97 : downgrading with mode CLOSED!
98 :
99 : @param eMode
100 : force (re)opening of the configuration access in readonly or in read/write mode
101 : */
102 266 : void ConfigAccess::open( /*IN*/ EOpenMode eMode )
103 : {
104 : /* SAFE { */
105 : // We must lock the whole method to be shure, that nobody
106 : // outside uses our internal member m_xAccess!
107 266 : WriteGuard aWriteLock(m_aLock);
108 :
109 : // check if configuration is already open in the right mode.
110 : // By the way: Don't allow closing by using this method!
111 266 : if (
112 : (eMode !=E_CLOSED) &&
113 : (m_eMode!=eMode )
114 : )
115 : {
116 : // We have to close the old access point without any question here.
117 : // It will be open again using the new mode.
118 : // can be called without checks! It does the checks by itself ...
119 : // e.g. for already closed or not opened configuration.
120 : // Flushing of all made changes will be done here too.
121 266 : close();
122 :
123 : // create the configuration provider, which provides sub access points
124 266 : css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider = css::configuration::theDefaultProvider::get(m_xContext);
125 266 : css::beans::PropertyValue aParam;
126 266 : aParam.Name = DECLARE_ASCII("nodepath");
127 266 : aParam.Value <<= m_sRoot;
128 :
129 266 : css::uno::Sequence< css::uno::Any > lParams(1);
130 266 : lParams[0] <<= aParam;
131 :
132 : // open it
133 : try
134 : {
135 266 : if (eMode==E_READONLY)
136 266 : m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS , lParams);
137 : else
138 0 : if (eMode==E_READWRITE)
139 0 : m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams);
140 : }
141 0 : catch(const css::uno::Exception& ex)
142 : {
143 : (void) ex; // avoid warning
144 : LOG_WARNING("open config ...", U2B(ex.Message))
145 : }
146 :
147 266 : m_eMode = E_CLOSED;
148 266 : if (m_xConfig.is())
149 266 : m_eMode = eMode;
150 : }
151 :
152 266 : aWriteLock.unlock();
153 : /* } SAFE */
154 266 : }
155 :
156 : //________________________________
157 : /**
158 : @short close the internal opened configuration access and flush all changes
159 : @descr It checks, if the given access is valid and react in the right way.
160 : It flushes all changes ... so nobody else must know this state.
161 : */
162 764 : void ConfigAccess::close()
163 : {
164 : /* SAFE { */
165 : // Lock the whole method, to be shure that nobody else uses our internal members
166 : // during this time.
167 764 : WriteGuard aWriteLock(m_aLock);
168 :
169 : // check already closed configuration
170 764 : if (m_xConfig.is())
171 : {
172 250 : css::uno::Reference< css::util::XChangesBatch > xFlush(m_xConfig, css::uno::UNO_QUERY);
173 250 : if (xFlush.is())
174 0 : xFlush->commitChanges();
175 250 : m_xConfig = css::uno::Reference< css::uno::XInterface >();
176 250 : m_eMode = E_CLOSED;
177 : }
178 :
179 764 : aWriteLock.unlock();
180 : /* } SAFE */
181 764 : }
182 :
183 : //________________________________
184 : /**
185 : @short provides an access to the internal wrapped configuration access
186 : @descr It's not allowed to safe this c++ (!) reference outside. You have
187 : to use it directly. Further you must use our public lock member m_aLock
188 : to synchronize your code with our internal structures and our interface
189 : methods. Acquire it before you call cfg() and release it afterwards immediatly.
190 :
191 : E.g.: ConfigAccess aAccess(...);
192 : ReadGuard aReadLock(aAccess.m_aLock);
193 : Reference< XPropertySet > xSet(aAccess.cfg(), UNO_QUERY);
194 : Any aProp = xSet->getPropertyValue("...");
195 : aReadLock.unlock();
196 :
197 : @attention During this time it's not allowed to call the methods open() or close()!
198 : Otherwhise you will change your own referenced config access. Anything will
199 : be possible then.
200 :
201 : @return A c++(!) reference to the uno instance of the configuration access point.
202 : */
203 286 : const css::uno::Reference< css::uno::XInterface >& ConfigAccess::cfg()
204 : {
205 : // must be synchronized from outside!
206 : // => no lock here ...
207 286 : return m_xConfig;
208 : }
209 :
210 : } // namespace framework
211 :
212 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|