Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <jobs/configaccess.hxx>
30 : : #include <threadhelp/readguard.hxx>
31 : : #include <threadhelp/writeguard.hxx>
32 : : #include <threadhelp/resetableguard.hxx>
33 : : #include <general.h>
34 : : #include <services.h>
35 : :
36 : : #include <com/sun/star/beans/XPropertySet.hpp>
37 : : #include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
38 : : #include <com/sun/star/container/XNameAccess.hpp>
39 : : #include <com/sun/star/beans/PropertyValue.hpp>
40 : : #include <com/sun/star/util/XChangesBatch.hpp>
41 : :
42 : : #include <unotools/configpaths.hxx>
43 : : #include <rtl/ustrbuf.hxx>
44 : :
45 : : namespace framework{
46 : :
47 : : /**
48 : : @short open the configuration of this job
49 : : @descr We open the configuration of this job only. Not the whole package or the whole
50 : : job set. We are interested on our own properties only.
51 : : We set the opened configuration access as our member. So any following method,
52 : : which needs cfg access, can use it. That prevent us against multiple open/close requests.
53 : : But you can use this method to upgrade an already opened configuration too.
54 : :
55 : : @param eMode
56 : : force opening of the configuration access in readonly or in read/write mode
57 : : */
58 : 2480 : ConfigAccess::ConfigAccess( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
59 : : /*IN*/ const ::rtl::OUString& sRoot )
60 : : : ThreadHelpBase( )
61 : : , m_xSMGR ( xSMGR )
62 : : , m_sRoot ( sRoot )
63 : 2480 : , m_eMode ( E_CLOSED )
64 : : {
65 : 2480 : }
66 : :
67 : : //________________________________
68 : : /**
69 : : @short last chance to close an open configuration access point
70 : : @descr In case our user forgot to close this configuration point
71 : : in the right way, normaly he will run into some trouble -
72 : : e.g. losing data.
73 : : */
74 : 2480 : ConfigAccess::~ConfigAccess()
75 : : {
76 [ + - ]: 2480 : close();
77 [ - + ]: 2480 : }
78 : :
79 : : //________________________________
80 : : /**
81 : : @short return the internal mode of this instance
82 : : @descr May be the outside user need any information about successfully opened
83 : : or closed config access point objects. He can control the internal mode to do so.
84 : :
85 : : @return The internal open state of this object.
86 : : */
87 : 2480 : ConfigAccess::EOpenMode ConfigAccess::getMode() const
88 : : {
89 : : /* SAFE { */
90 [ + - ]: 2480 : ReadGuard aReadLock(m_aLock);
91 [ + - ]: 2480 : return m_eMode;
92 : : /* } SAFE */
93 : : }
94 : :
95 : : //________________________________
96 : : /**
97 : : @short open the configuration access in the specified mode
98 : : @descr We set the opened configuration access as our member. So any following method,
99 : : which needs cfg access, can use it. That prevent us against multiple open/close requests.
100 : : But you can use this method to upgrade an already opened configuration too.
101 : : It's possible to open a config access in READONLY mode first and "open" it at a second
102 : : time within the mode READWRITE. Then we will upgrade it. Dowgrade will be possible too.
103 : :
104 : : But note: closing will be done explicitly by calling method close() ... not by
105 : : downgrading with mode CLOSED!
106 : :
107 : : @param eMode
108 : : force (re)opening of the configuration access in readonly or in read/write mode
109 : : */
110 : 2480 : void ConfigAccess::open( /*IN*/ EOpenMode eMode )
111 : : {
112 : : /* SAFE { */
113 : : // We must lock the whole method to be shure, that nobody
114 : : // outside uses our internal member m_xAccess!
115 [ + - ]: 2480 : WriteGuard aWriteLock(m_aLock);
116 : :
117 : : // check if configuration is already open in the right mode.
118 : : // By the way: Don't allow closing by using this method!
119 [ + - ][ + - ]: 2480 : if (
120 : : (eMode !=E_CLOSED) &&
121 : : (m_eMode!=eMode )
122 : : )
123 : : {
124 : : // We have to close the old access point without any question here.
125 : : // It will be open again using the new mode.
126 : : // can be called without checks! It does the checks by itself ...
127 : : // e.g. for already closed or not opened configuration.
128 : : // Flushing of all made changes will be done here too.
129 [ + - ]: 2480 : close();
130 : :
131 : : // create the configuration provider, which provides sub access points
132 [ + - ][ + - ]: 2480 : css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(m_xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY);
[ + - ][ + - ]
133 [ + - ]: 2480 : if (xConfigProvider.is())
134 : : {
135 : 2480 : css::beans::PropertyValue aParam;
136 [ + - ]: 2480 : aParam.Name = DECLARE_ASCII("nodepath");
137 [ + - ]: 2480 : aParam.Value <<= m_sRoot;
138 : :
139 [ + - ]: 2480 : css::uno::Sequence< css::uno::Any > lParams(1);
140 [ + - ][ + - ]: 2480 : lParams[0] <<= aParam;
141 : :
142 : : // open it
143 : : try
144 : : {
145 [ + - ]: 2480 : if (eMode==E_READONLY)
146 [ + - ][ + - ]: 2480 : m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS , lParams);
[ + - ][ + - ]
147 : : else
148 [ # # ]: 0 : if (eMode==E_READWRITE)
149 [ # # ][ # # ]: 0 : m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams);
[ # # ][ # # ]
[ # # ]
150 : : }
151 [ # # ]: 0 : catch(const css::uno::Exception& ex)
152 : : {
153 : : (void) ex; // avoid warning
154 : : LOG_WARNING("open config ...", U2B(ex.Message))
155 : : }
156 : :
157 : 2480 : m_eMode = E_CLOSED;
158 [ + - ]: 2480 : if (m_xConfig.is())
159 [ + - ]: 2480 : m_eMode = eMode;
160 : 2480 : }
161 : : }
162 : :
163 [ + - ][ + - ]: 2480 : aWriteLock.unlock();
164 : : /* } SAFE */
165 : 2480 : }
166 : :
167 : : //________________________________
168 : : /**
169 : : @short close the internal opened configuration access and flush all changes
170 : : @descr It checks, if the given access is valid and react in the right way.
171 : : It flushes all changes ... so nobody else must know this state.
172 : : */
173 : 7210 : void ConfigAccess::close()
174 : : {
175 : : /* SAFE { */
176 : : // Lock the whole method, to be shure that nobody else uses our internal members
177 : : // during this time.
178 [ + - ]: 7210 : WriteGuard aWriteLock(m_aLock);
179 : :
180 : : // check already closed configuration
181 [ + + ]: 7210 : if (m_xConfig.is())
182 : : {
183 [ + - ]: 2480 : css::uno::Reference< css::util::XChangesBatch > xFlush(m_xConfig, css::uno::UNO_QUERY);
184 [ - + ]: 2480 : if (xFlush.is())
185 [ # # ][ # # ]: 0 : xFlush->commitChanges();
186 [ + - ]: 2480 : m_xConfig = css::uno::Reference< css::uno::XInterface >();
187 : 2480 : m_eMode = E_CLOSED;
188 : : }
189 : :
190 [ + - ][ + - ]: 7210 : aWriteLock.unlock();
191 : : /* } SAFE */
192 : 7210 : }
193 : :
194 : : //________________________________
195 : : /**
196 : : @short provides an access to the internal wrapped configuration access
197 : : @descr It's not allowed to safe this c++ (!) reference outside. You have
198 : : to use it directly. Further you must use our public lock member m_aLock
199 : : to synchronize your code with our internal structures and our interface
200 : : methods. Acquire it before you call cfg() and release it afterwards immediatly.
201 : :
202 : : E.g.: ConfigAccess aAccess(...);
203 : : ReadGuard aReadLock(aAccess.m_aLock);
204 : : Reference< XPropertySet > xSet(aAccess.cfg(), UNO_QUERY);
205 : : Any aProp = xSet->getPropertyValue("...");
206 : : aReadLock.unlock();
207 : :
208 : : @attention During this time it's not allowed to call the methods open() or close()!
209 : : Otherwhise you will change your own referenced config access. Anything will
210 : : be possible then.
211 : :
212 : : @return A c++(!) reference to the uno instance of the configuration access point.
213 : : */
214 : 2940 : const css::uno::Reference< css::uno::XInterface >& ConfigAccess::cfg()
215 : : {
216 : : // must be synchronized from outside!
217 : : // => no lock here ...
218 : 2940 : return m_xConfig;
219 : : }
220 : :
221 : : } // namespace framework
222 : :
223 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|