xref: /AOO41X/main/configmgr/source/rootaccess.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir *
3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir *
5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir *
7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir *
9*cdf0e10cSrcweir * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir *
11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir *
15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir *
21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir *
26*cdf0e10cSrcweir ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "precompiled_configmgr.hxx"
29*cdf0e10cSrcweir #include "sal/config.h"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <vector>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp"
34*cdf0e10cSrcweir #include "com/sun/star/lang/EventObject.hpp"
35*cdf0e10cSrcweir #include "com/sun/star/lang/WrappedTargetException.hpp"
36*cdf0e10cSrcweir #include "com/sun/star/uno/Any.hxx"
37*cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
38*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
39*cdf0e10cSrcweir #include "com/sun/star/uno/Type.hxx"
40*cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
41*cdf0e10cSrcweir #include "com/sun/star/util/ChangesEvent.hpp"
42*cdf0e10cSrcweir #include "com/sun/star/util/ChangesSet.hpp"
43*cdf0e10cSrcweir #include "com/sun/star/util/ElementChange.hpp"
44*cdf0e10cSrcweir #include "com/sun/star/util/XChangesBatch.hpp"
45*cdf0e10cSrcweir #include "com/sun/star/util/XChangesListener.hpp"
46*cdf0e10cSrcweir #include "com/sun/star/util/XChangesNotifier.hpp"
47*cdf0e10cSrcweir #include "comphelper/sequenceasvector.hxx"
48*cdf0e10cSrcweir #include "cppu/unotype.hxx"
49*cdf0e10cSrcweir #include "cppuhelper/queryinterface.hxx"
50*cdf0e10cSrcweir #include "cppuhelper/weak.hxx"
51*cdf0e10cSrcweir #include "osl/diagnose.h"
52*cdf0e10cSrcweir #include "osl/mutex.hxx"
53*cdf0e10cSrcweir #include "rtl/ref.hxx"
54*cdf0e10cSrcweir #include "rtl/ustring.h"
55*cdf0e10cSrcweir #include "rtl/ustring.hxx"
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include "broadcaster.hxx"
58*cdf0e10cSrcweir #include "childaccess.hxx"
59*cdf0e10cSrcweir #include "components.hxx"
60*cdf0e10cSrcweir #include "data.hxx"
61*cdf0e10cSrcweir #include "lock.hxx"
62*cdf0e10cSrcweir #include "modifications.hxx"
63*cdf0e10cSrcweir #include "node.hxx"
64*cdf0e10cSrcweir #include "path.hxx"
65*cdf0e10cSrcweir #include "rootaccess.hxx"
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir namespace configmgr {
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir namespace {
70*cdf0e10cSrcweir 
71*cdf0e10cSrcweir namespace css = com::sun::star;
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir }
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir RootAccess::RootAccess(
76*cdf0e10cSrcweir     Components & components, rtl::OUString const & pathRepresentation,
77*cdf0e10cSrcweir     rtl::OUString const & locale, bool update):
78*cdf0e10cSrcweir     Access(components), pathRepresentation_(pathRepresentation),
79*cdf0e10cSrcweir     locale_(locale), update_(update)
80*cdf0e10cSrcweir {}
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir Path RootAccess::getAbsolutePath() {
83*cdf0e10cSrcweir     getNode();
84*cdf0e10cSrcweir     return path_;
85*cdf0e10cSrcweir }
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir void RootAccess::initBroadcaster(
88*cdf0e10cSrcweir     Modifications::Node const & modifications, Broadcaster * broadcaster)
89*cdf0e10cSrcweir {
90*cdf0e10cSrcweir     OSL_ASSERT(broadcaster != 0);
91*cdf0e10cSrcweir     comphelper::SequenceAsVector< css::util::ElementChange > changes;
92*cdf0e10cSrcweir     initBroadcasterAndChanges(
93*cdf0e10cSrcweir         modifications, broadcaster, changesListeners_.empty() ? 0 : &changes);
94*cdf0e10cSrcweir     if (!changes.empty()) {
95*cdf0e10cSrcweir         css::util::ChangesSet set(changes.getAsConstList());
96*cdf0e10cSrcweir         for (ChangesListeners::iterator i(changesListeners_.begin());
97*cdf0e10cSrcweir              i != changesListeners_.end(); ++i)
98*cdf0e10cSrcweir         {
99*cdf0e10cSrcweir             cppu::OWeakObject* pSource = static_cast< cppu::OWeakObject * >(this);
100*cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface > xBase( pSource, css::uno::UNO_QUERY );
101*cdf0e10cSrcweir             broadcaster->addChangesNotification(
102*cdf0e10cSrcweir                 *i,
103*cdf0e10cSrcweir                 css::util::ChangesEvent(
104*cdf0e10cSrcweir                     pSource, makeAny( xBase ), set));
105*cdf0e10cSrcweir         }
106*cdf0e10cSrcweir     }
107*cdf0e10cSrcweir }
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir void RootAccess::acquire() throw () {
110*cdf0e10cSrcweir     Access::acquire();
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir void RootAccess::release() throw () {
114*cdf0e10cSrcweir     Access::release();
115*cdf0e10cSrcweir }
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir rtl::OUString RootAccess::getAbsolutePathRepresentation() {
118*cdf0e10cSrcweir     getNode(); // turn pathRepresentation_ into canonic form
119*cdf0e10cSrcweir     return pathRepresentation_;
120*cdf0e10cSrcweir }
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir rtl::OUString RootAccess::getLocale() const {
123*cdf0e10cSrcweir     return locale_;
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir bool RootAccess::isUpdate() const {
127*cdf0e10cSrcweir     return update_;
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir RootAccess::~RootAccess() {
131*cdf0e10cSrcweir     osl::MutexGuard g(lock);
132*cdf0e10cSrcweir     getComponents().removeRootAccess(this);
133*cdf0e10cSrcweir }
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir Path RootAccess::getRelativePath() {
136*cdf0e10cSrcweir     return Path();
137*cdf0e10cSrcweir }
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir rtl::OUString RootAccess::getRelativePathRepresentation() {
140*cdf0e10cSrcweir     return rtl::OUString();
141*cdf0e10cSrcweir }
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir rtl::Reference< Node > RootAccess::getNode() {
144*cdf0e10cSrcweir     if (!node_.is()) {
145*cdf0e10cSrcweir         rtl::OUString canonic;
146*cdf0e10cSrcweir         int finalizedLayer;
147*cdf0e10cSrcweir         node_ = getComponents().resolvePathRepresentation(
148*cdf0e10cSrcweir             pathRepresentation_, &canonic, &path_, &finalizedLayer);
149*cdf0e10cSrcweir         if (!node_.is()) {
150*cdf0e10cSrcweir             throw css::uno::RuntimeException(
151*cdf0e10cSrcweir                 (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("cannot find ")) +
152*cdf0e10cSrcweir                  pathRepresentation_),
153*cdf0e10cSrcweir                 0);
154*cdf0e10cSrcweir                 // RootAccess::queryInterface indirectly calls
155*cdf0e10cSrcweir                 // RootAccess::getNode, so if this RootAccess were passed out in
156*cdf0e10cSrcweir                 // RuntimeException.Context, client code that called
157*cdf0e10cSrcweir                 // queryInterface on it would cause trouble; therefore,
158*cdf0e10cSrcweir                 // RuntimeException.Context is left null here
159*cdf0e10cSrcweir         }
160*cdf0e10cSrcweir         pathRepresentation_ = canonic;
161*cdf0e10cSrcweir         OSL_ASSERT(!path_.empty());
162*cdf0e10cSrcweir         name_ = path_.back();
163*cdf0e10cSrcweir         finalized_ = finalizedLayer != Data::NO_LAYER;
164*cdf0e10cSrcweir     }
165*cdf0e10cSrcweir     return node_;
166*cdf0e10cSrcweir }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir bool RootAccess::isFinalized() {
169*cdf0e10cSrcweir     getNode();
170*cdf0e10cSrcweir     return finalized_;
171*cdf0e10cSrcweir }
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir rtl::OUString RootAccess::getNameInternal() {
174*cdf0e10cSrcweir     getNode();
175*cdf0e10cSrcweir     return name_;
176*cdf0e10cSrcweir }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir rtl::Reference< RootAccess > RootAccess::getRootAccess() {
179*cdf0e10cSrcweir     return this;
180*cdf0e10cSrcweir }
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir rtl::Reference< Access > RootAccess::getParentAccess() {
183*cdf0e10cSrcweir     return rtl::Reference< Access >();
184*cdf0e10cSrcweir }
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir void RootAccess::addTypes(std::vector< css::uno::Type > * types) const {
187*cdf0e10cSrcweir     OSL_ASSERT(types != 0);
188*cdf0e10cSrcweir     types->push_back(cppu::UnoType< css::util::XChangesNotifier >::get());
189*cdf0e10cSrcweir     types->push_back(cppu::UnoType< css::util::XChangesBatch >::get());
190*cdf0e10cSrcweir }
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir void RootAccess::addSupportedServiceNames(
193*cdf0e10cSrcweir     std::vector< rtl::OUString > * services)
194*cdf0e10cSrcweir {
195*cdf0e10cSrcweir     OSL_ASSERT(services != 0);
196*cdf0e10cSrcweir     services->push_back(
197*cdf0e10cSrcweir         rtl::OUString(
198*cdf0e10cSrcweir             RTL_CONSTASCII_USTRINGPARAM(
199*cdf0e10cSrcweir                 "com.sun.star.configuration.AccessRootElement")));
200*cdf0e10cSrcweir     if (update_) {
201*cdf0e10cSrcweir         services->push_back(
202*cdf0e10cSrcweir             rtl::OUString(
203*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
204*cdf0e10cSrcweir                     "com.sun.star.configuration.UpdateRootElement")));
205*cdf0e10cSrcweir     }
206*cdf0e10cSrcweir }
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir void RootAccess::initDisposeBroadcaster(Broadcaster * broadcaster) {
209*cdf0e10cSrcweir     OSL_ASSERT(broadcaster != 0);
210*cdf0e10cSrcweir     for (ChangesListeners::iterator i(changesListeners_.begin());
211*cdf0e10cSrcweir          i != changesListeners_.end(); ++i)
212*cdf0e10cSrcweir     {
213*cdf0e10cSrcweir         broadcaster->addDisposeNotification(
214*cdf0e10cSrcweir             i->get(),
215*cdf0e10cSrcweir             css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
216*cdf0e10cSrcweir     }
217*cdf0e10cSrcweir     Access::initDisposeBroadcaster(broadcaster);
218*cdf0e10cSrcweir }
219*cdf0e10cSrcweir 
220*cdf0e10cSrcweir void RootAccess::clearListeners() throw() {
221*cdf0e10cSrcweir     changesListeners_.clear();
222*cdf0e10cSrcweir     Access::clearListeners();
223*cdf0e10cSrcweir }
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir css::uno::Any RootAccess::queryInterface(css::uno::Type const & aType)
226*cdf0e10cSrcweir     throw (css::uno::RuntimeException)
227*cdf0e10cSrcweir {
228*cdf0e10cSrcweir     OSL_ASSERT(thisIs(IS_ANY));
229*cdf0e10cSrcweir     osl::MutexGuard g(lock);
230*cdf0e10cSrcweir     checkLocalizedPropertyAccess();
231*cdf0e10cSrcweir     css::uno::Any res(Access::queryInterface(aType));
232*cdf0e10cSrcweir     if (res.hasValue()) {
233*cdf0e10cSrcweir         return res;
234*cdf0e10cSrcweir     }
235*cdf0e10cSrcweir     res = cppu::queryInterface(
236*cdf0e10cSrcweir         aType, static_cast< css::util::XChangesNotifier * >(this));
237*cdf0e10cSrcweir     if (res.hasValue()) {
238*cdf0e10cSrcweir         return res;
239*cdf0e10cSrcweir     }
240*cdf0e10cSrcweir     if (!res.hasValue() && update_) {
241*cdf0e10cSrcweir         res = cppu::queryInterface(
242*cdf0e10cSrcweir             aType, static_cast< css::util::XChangesBatch * >(this));
243*cdf0e10cSrcweir     }
244*cdf0e10cSrcweir     return res;
245*cdf0e10cSrcweir }
246*cdf0e10cSrcweir 
247*cdf0e10cSrcweir void RootAccess::addChangesListener(
248*cdf0e10cSrcweir     css::uno::Reference< css::util::XChangesListener > const & aListener)
249*cdf0e10cSrcweir     throw (css::uno::RuntimeException)
250*cdf0e10cSrcweir {
251*cdf0e10cSrcweir     OSL_ASSERT(thisIs(IS_ANY));
252*cdf0e10cSrcweir     {
253*cdf0e10cSrcweir         osl::MutexGuard g(lock);
254*cdf0e10cSrcweir         checkLocalizedPropertyAccess();
255*cdf0e10cSrcweir         if (!aListener.is()) {
256*cdf0e10cSrcweir             throw css::uno::RuntimeException(
257*cdf0e10cSrcweir                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("null listener")),
258*cdf0e10cSrcweir                 static_cast< cppu::OWeakObject * >(this));
259*cdf0e10cSrcweir         }
260*cdf0e10cSrcweir         if (!isDisposed()) {
261*cdf0e10cSrcweir             changesListeners_.insert(aListener);
262*cdf0e10cSrcweir             return;
263*cdf0e10cSrcweir         }
264*cdf0e10cSrcweir     }
265*cdf0e10cSrcweir     try {
266*cdf0e10cSrcweir         aListener->disposing(
267*cdf0e10cSrcweir             css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
268*cdf0e10cSrcweir     } catch (css::lang::DisposedException &) {}
269*cdf0e10cSrcweir }
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir void RootAccess::removeChangesListener(
272*cdf0e10cSrcweir     css::uno::Reference< css::util::XChangesListener > const & aListener)
273*cdf0e10cSrcweir     throw (css::uno::RuntimeException)
274*cdf0e10cSrcweir {
275*cdf0e10cSrcweir     OSL_ASSERT(thisIs(IS_ANY));
276*cdf0e10cSrcweir     osl::MutexGuard g(lock);
277*cdf0e10cSrcweir     checkLocalizedPropertyAccess();
278*cdf0e10cSrcweir     ChangesListeners::iterator i(changesListeners_.find(aListener));
279*cdf0e10cSrcweir     if (i != changesListeners_.end()) {
280*cdf0e10cSrcweir         changesListeners_.erase(i);
281*cdf0e10cSrcweir     }
282*cdf0e10cSrcweir }
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir void RootAccess::commitChanges()
285*cdf0e10cSrcweir     throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
286*cdf0e10cSrcweir {
287*cdf0e10cSrcweir     OSL_ASSERT(thisIs(IS_UPDATE));
288*cdf0e10cSrcweir     Broadcaster bc;
289*cdf0e10cSrcweir     {
290*cdf0e10cSrcweir         osl::MutexGuard g(lock);
291*cdf0e10cSrcweir         checkLocalizedPropertyAccess();
292*cdf0e10cSrcweir         int finalizedLayer;
293*cdf0e10cSrcweir         Modifications globalMods;
294*cdf0e10cSrcweir         commitChildChanges(
295*cdf0e10cSrcweir             ((getComponents().resolvePathRepresentation(
296*cdf0e10cSrcweir                   pathRepresentation_, 0, 0, &finalizedLayer)
297*cdf0e10cSrcweir               == node_) &&
298*cdf0e10cSrcweir              finalizedLayer == Data::NO_LAYER),
299*cdf0e10cSrcweir             &globalMods);
300*cdf0e10cSrcweir         getComponents().writeModifications();
301*cdf0e10cSrcweir         getComponents().initGlobalBroadcaster(globalMods, this, &bc);
302*cdf0e10cSrcweir     }
303*cdf0e10cSrcweir     bc.send();
304*cdf0e10cSrcweir }
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir sal_Bool RootAccess::hasPendingChanges() throw (css::uno::RuntimeException) {
307*cdf0e10cSrcweir     OSL_ASSERT(thisIs(IS_UPDATE));
308*cdf0e10cSrcweir     osl::MutexGuard g(lock);
309*cdf0e10cSrcweir     checkLocalizedPropertyAccess();
310*cdf0e10cSrcweir     //TODO: Optimize:
311*cdf0e10cSrcweir     std::vector< css::util::ElementChange > changes;
312*cdf0e10cSrcweir     reportChildChanges(&changes);
313*cdf0e10cSrcweir     return !changes.empty();
314*cdf0e10cSrcweir }
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir css::util::ChangesSet RootAccess::getPendingChanges()
317*cdf0e10cSrcweir     throw (css::uno::RuntimeException)
318*cdf0e10cSrcweir {
319*cdf0e10cSrcweir     OSL_ASSERT(thisIs(IS_UPDATE));
320*cdf0e10cSrcweir     osl::MutexGuard g(lock);
321*cdf0e10cSrcweir     checkLocalizedPropertyAccess();
322*cdf0e10cSrcweir     comphelper::SequenceAsVector< css::util::ElementChange > changes;
323*cdf0e10cSrcweir     reportChildChanges(&changes);
324*cdf0e10cSrcweir     return changes.getAsConstList();
325*cdf0e10cSrcweir }
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir }
328