1*6d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*6d739b60SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*6d739b60SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*6d739b60SAndrew Rist  * distributed with this work for additional information
6*6d739b60SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*6d739b60SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*6d739b60SAndrew Rist  * "License"); you may not use this file except in compliance
9*6d739b60SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*6d739b60SAndrew Rist  *
11*6d739b60SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*6d739b60SAndrew Rist  *
13*6d739b60SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*6d739b60SAndrew Rist  * software distributed under the License is distributed on an
15*6d739b60SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*6d739b60SAndrew Rist  * KIND, either express or implied.  See the License for the
17*6d739b60SAndrew Rist  * specific language governing permissions and limitations
18*6d739b60SAndrew Rist  * under the License.
19*6d739b60SAndrew Rist  *
20*6d739b60SAndrew Rist  *************************************************************/
21*6d739b60SAndrew Rist 
22*6d739b60SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //________________________________
28cdf0e10cSrcweir //	my own includes
29cdf0e10cSrcweir #include <jobs/configaccess.hxx>
30cdf0e10cSrcweir #include <threadhelp/readguard.hxx>
31cdf0e10cSrcweir #include <threadhelp/writeguard.hxx>
32cdf0e10cSrcweir #include <threadhelp/resetableguard.hxx>
33cdf0e10cSrcweir #include <general.h>
34cdf0e10cSrcweir #include <services.h>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir //________________________________
37cdf0e10cSrcweir //	interface includes
38cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
39cdf0e10cSrcweir #include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
40cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
41cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
42cdf0e10cSrcweir #include <com/sun/star/util/XChangesBatch.hpp>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir //________________________________
45cdf0e10cSrcweir //	includes of other projects
46cdf0e10cSrcweir #include <unotools/configpathes.hxx>
47cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //________________________________
50cdf0e10cSrcweir //	namespace
51cdf0e10cSrcweir 
52cdf0e10cSrcweir namespace framework{
53cdf0e10cSrcweir 
54cdf0e10cSrcweir //________________________________
55cdf0e10cSrcweir //	non exported const
56cdf0e10cSrcweir 
57cdf0e10cSrcweir //________________________________
58cdf0e10cSrcweir //	non exported definitions
59cdf0e10cSrcweir 
60cdf0e10cSrcweir //________________________________
61cdf0e10cSrcweir //	declarations
62cdf0e10cSrcweir 
63cdf0e10cSrcweir //________________________________
64cdf0e10cSrcweir /**
65cdf0e10cSrcweir     @short  open the configuration of this job
66cdf0e10cSrcweir     @descr  We open the configuration of this job only. Not the whole package or the whole
67cdf0e10cSrcweir             job set. We are interested on our own properties only.
68cdf0e10cSrcweir             We set the opened configuration access as our member. So any following method,
69cdf0e10cSrcweir             which needs cfg access, can use it. That prevent us against multiple open/close requests.
70cdf0e10cSrcweir             But you can use this method to upgrade an already opened configuration too.
71cdf0e10cSrcweir 
72cdf0e10cSrcweir     @param  eMode
73cdf0e10cSrcweir                 force opening of the configuration access in readonly or in read/write mode
74cdf0e10cSrcweir  */
ConfigAccess(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR,const::rtl::OUString & sRoot)75cdf0e10cSrcweir ConfigAccess::ConfigAccess( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ,
76cdf0e10cSrcweir                             /*IN*/ const ::rtl::OUString&                                        sRoot )
77cdf0e10cSrcweir     : ThreadHelpBase(          )
78cdf0e10cSrcweir     , m_xSMGR       ( xSMGR    )
79cdf0e10cSrcweir     , m_sRoot       ( sRoot    )
80cdf0e10cSrcweir     , m_eMode       ( E_CLOSED )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir }
83cdf0e10cSrcweir 
84cdf0e10cSrcweir //________________________________
85cdf0e10cSrcweir /**
86cdf0e10cSrcweir     @short  last chance to close an open configuration access point
87cdf0e10cSrcweir     @descr  In case our user forgot to close this configuration point
88cdf0e10cSrcweir             in the right way, normaly he will run into some trouble -
89cdf0e10cSrcweir             e.g. losing data.
90cdf0e10cSrcweir  */
~ConfigAccess()91cdf0e10cSrcweir ConfigAccess::~ConfigAccess()
92cdf0e10cSrcweir {
93cdf0e10cSrcweir     close();
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir //________________________________
97cdf0e10cSrcweir /**
98cdf0e10cSrcweir     @short  return the internal mode of this instance
99cdf0e10cSrcweir     @descr  May be the outside user need any information about successfully opened
100cdf0e10cSrcweir             or closed config access point objects. He can control the internal mode to do so.
101cdf0e10cSrcweir 
102cdf0e10cSrcweir     @return The internal open state of this object.
103cdf0e10cSrcweir  */
getMode() const104cdf0e10cSrcweir ConfigAccess::EOpenMode ConfigAccess::getMode() const
105cdf0e10cSrcweir {
106cdf0e10cSrcweir     /* SAFE { */
107cdf0e10cSrcweir     ReadGuard aReadLock(m_aLock);
108cdf0e10cSrcweir     return m_eMode;
109cdf0e10cSrcweir     /* } SAFE */
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir //________________________________
113cdf0e10cSrcweir /**
114cdf0e10cSrcweir     @short  open the configuration access in the specified mode
115cdf0e10cSrcweir     @descr  We set the opened configuration access as our member. So any following method,
116cdf0e10cSrcweir             which needs cfg access, can use it. That prevent us against multiple open/close requests.
117cdf0e10cSrcweir             But you can use this method to upgrade an already opened configuration too.
118cdf0e10cSrcweir             It's possible to open a config access in READONLY mode first and "open" it at a second
119cdf0e10cSrcweir             time within the mode READWRITE. Then we will upgrade it. Dowgrade will be possible too.
120cdf0e10cSrcweir 
121cdf0e10cSrcweir             But note: closing will be done explicitly by calling method close() ... not by
122cdf0e10cSrcweir             downgrading with mode CLOSED!
123cdf0e10cSrcweir 
124cdf0e10cSrcweir     @param  eMode
125cdf0e10cSrcweir                 force (re)opening of the configuration access in readonly or in read/write mode
126cdf0e10cSrcweir  */
open(EOpenMode eMode)127cdf0e10cSrcweir void ConfigAccess::open( /*IN*/ EOpenMode eMode )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir     /* SAFE { */
130cdf0e10cSrcweir     // We must lock the whole method to be shure, that nobody
131cdf0e10cSrcweir     // outside uses our internal member m_xAccess!
132cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
133cdf0e10cSrcweir 
134cdf0e10cSrcweir     // check if configuration is already open in the right mode.
135cdf0e10cSrcweir     // By the way: Don't allow closing by using this method!
136cdf0e10cSrcweir     if (
137cdf0e10cSrcweir         (eMode  !=E_CLOSED) &&
138cdf0e10cSrcweir         (m_eMode!=eMode   )
139cdf0e10cSrcweir        )
140cdf0e10cSrcweir     {
141cdf0e10cSrcweir         // We have to close the old access point without any question here.
142cdf0e10cSrcweir         // It will be open again using the new mode.
143cdf0e10cSrcweir         // can be called without checks! It does the checks by itself ...
144cdf0e10cSrcweir         // e.g. for already closed or not opened configuration.
145cdf0e10cSrcweir         // Flushing of all made changes will be done here too.
146cdf0e10cSrcweir         close();
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         // create the configuration provider, which provides sub access points
149cdf0e10cSrcweir         css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(m_xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY);
150cdf0e10cSrcweir         if (xConfigProvider.is())
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             css::beans::PropertyValue aParam;
153cdf0e10cSrcweir             aParam.Name    = DECLARE_ASCII("nodepath");
154cdf0e10cSrcweir             aParam.Value <<= m_sRoot;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             css::uno::Sequence< css::uno::Any > lParams(1);
157cdf0e10cSrcweir             lParams[0] <<= aParam;
158cdf0e10cSrcweir 
159cdf0e10cSrcweir             // open it
160cdf0e10cSrcweir             try
161cdf0e10cSrcweir             {
162cdf0e10cSrcweir                 if (eMode==E_READONLY)
163cdf0e10cSrcweir                     m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS  , lParams);
164cdf0e10cSrcweir                 else
165cdf0e10cSrcweir                 if (eMode==E_READWRITE)
166cdf0e10cSrcweir                     m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams);
167cdf0e10cSrcweir             }
168cdf0e10cSrcweir             catch(css::uno::Exception& ex)
169cdf0e10cSrcweir             {
170cdf0e10cSrcweir                 (void) ex; // avoid warning
171cdf0e10cSrcweir                 LOG_WARNING("open config ...", U2B(ex.Message))
172cdf0e10cSrcweir             }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir             m_eMode = E_CLOSED;
175cdf0e10cSrcweir             if (m_xConfig.is())
176cdf0e10cSrcweir                 m_eMode = eMode;
177cdf0e10cSrcweir         }
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     aWriteLock.unlock();
181cdf0e10cSrcweir     /* } SAFE */
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir //________________________________
185cdf0e10cSrcweir /**
186cdf0e10cSrcweir     @short  close the internal opened configuration access and flush all changes
187cdf0e10cSrcweir     @descr  It checks, if the given access is valid and react in the right way.
188cdf0e10cSrcweir             It flushes all changes ... so nobody else must know this state.
189cdf0e10cSrcweir  */
close()190cdf0e10cSrcweir void ConfigAccess::close()
191cdf0e10cSrcweir {
192cdf0e10cSrcweir     /* SAFE { */
193cdf0e10cSrcweir     // Lock the whole method, to be shure that nobody else uses our internal members
194cdf0e10cSrcweir     // during this time.
195cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     // check already closed configuration
198cdf0e10cSrcweir     if (m_xConfig.is())
199cdf0e10cSrcweir     {
200cdf0e10cSrcweir         css::uno::Reference< css::util::XChangesBatch > xFlush(m_xConfig, css::uno::UNO_QUERY);
201cdf0e10cSrcweir         if (xFlush.is())
202cdf0e10cSrcweir             xFlush->commitChanges();
203cdf0e10cSrcweir         m_xConfig = css::uno::Reference< css::uno::XInterface >();
204cdf0e10cSrcweir         m_eMode   = E_CLOSED;
205cdf0e10cSrcweir     }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     aWriteLock.unlock();
208cdf0e10cSrcweir     /* } SAFE */
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir //________________________________
212cdf0e10cSrcweir /**
213cdf0e10cSrcweir     @short  provides an access to the internal wrapped configuration access
214cdf0e10cSrcweir     @descr  It's not allowed to safe this c++ (!) reference outside. You have
215cdf0e10cSrcweir             to use it directly. Further you must use our public lock member m_aLock
216cdf0e10cSrcweir             to synchronize your code with our internal structures and our interface
217cdf0e10cSrcweir             methods. Acquire it before you call cfg() and release it afterwards immediatly.
218cdf0e10cSrcweir 
219cdf0e10cSrcweir             E.g.:   ConfigAccess aAccess(...);
220cdf0e10cSrcweir                     ReadGuard aReadLock(aAccess.m_aLock);
221cdf0e10cSrcweir                     Reference< XPropertySet > xSet(aAccess.cfg(), UNO_QUERY);
222cdf0e10cSrcweir                     Any aProp = xSet->getPropertyValue("...");
223cdf0e10cSrcweir                     aReadLock.unlock();
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     @attention  During this time it's not allowed to call the methods open() or close()!
226cdf0e10cSrcweir                 Otherwhise you will change your own referenced config access. Anything will
227cdf0e10cSrcweir                 be possible then.
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     @return A c++(!) reference to the uno instance of the configuration access point.
230cdf0e10cSrcweir  */
cfg()231cdf0e10cSrcweir const css::uno::Reference< css::uno::XInterface >& ConfigAccess::cfg()
232cdf0e10cSrcweir {
233cdf0e10cSrcweir     // must be synchronized from outside!
234cdf0e10cSrcweir     // => no lock here ...
235cdf0e10cSrcweir     return m_xConfig;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir } // namespace framework
239