1*5b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*5b190011SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*5b190011SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*5b190011SAndrew Rist * distributed with this work for additional information
6*5b190011SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*5b190011SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*5b190011SAndrew Rist * "License"); you may not use this file except in compliance
9*5b190011SAndrew Rist * with the License. You may obtain a copy of the License at
10*5b190011SAndrew Rist *
11*5b190011SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*5b190011SAndrew Rist *
13*5b190011SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*5b190011SAndrew Rist * software distributed under the License is distributed on an
15*5b190011SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5b190011SAndrew Rist * KIND, either express or implied. See the License for the
17*5b190011SAndrew Rist * specific language governing permissions and limitations
18*5b190011SAndrew Rist * under the License.
19*5b190011SAndrew Rist *
20*5b190011SAndrew Rist *************************************************************/
21*5b190011SAndrew Rist
22*5b190011SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include "precompiled_sd.hxx"
25cdf0e10cSrcweir
26cdf0e10cSrcweir #include "framework/ConfigurationController.hxx"
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include "framework/Configuration.hxx"
29cdf0e10cSrcweir #include "framework/FrameworkHelper.hxx"
30cdf0e10cSrcweir #include "ConfigurationUpdater.hxx"
31cdf0e10cSrcweir #include "ConfigurationControllerBroadcaster.hxx"
32cdf0e10cSrcweir #include "ConfigurationTracer.hxx"
33cdf0e10cSrcweir #include "GenericConfigurationChangeRequest.hxx"
34cdf0e10cSrcweir #include "ResourceFactoryManager.hxx"
35cdf0e10cSrcweir #include "UpdateRequest.hxx"
36cdf0e10cSrcweir #include "ChangeRequestQueueProcessor.hxx"
37cdf0e10cSrcweir #include "ConfigurationClassifier.hxx"
38cdf0e10cSrcweir #include "ViewShellBase.hxx"
39cdf0e10cSrcweir #include "UpdateLockManager.hxx"
40cdf0e10cSrcweir #include "DrawController.hxx"
41cdf0e10cSrcweir #include <com/sun/star/drawing/framework/XControllerManager.hpp>
42cdf0e10cSrcweir #include <com/sun/star/util/XURLTransformer.hpp>
43cdf0e10cSrcweir
44cdf0e10cSrcweir #include <comphelper/stl_types.hxx>
45cdf0e10cSrcweir #include <vos/mutex.hxx>
46cdf0e10cSrcweir #include <vcl/svapp.hxx>
47cdf0e10cSrcweir
48cdf0e10cSrcweir using namespace ::com::sun::star;
49cdf0e10cSrcweir using namespace ::com::sun::star::uno;
50cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
51cdf0e10cSrcweir using rtl::OUString;
52cdf0e10cSrcweir using ::sd::framework::FrameworkHelper;
53cdf0e10cSrcweir
54cdf0e10cSrcweir #undef VERBOSE
55cdf0e10cSrcweir //#define VERBOSE 3
56cdf0e10cSrcweir
57cdf0e10cSrcweir
58cdf0e10cSrcweir namespace sd { namespace framework {
59cdf0e10cSrcweir
ConfigurationController_createInstance(const Reference<XComponentContext> & rxContext)60cdf0e10cSrcweir Reference<XInterface> SAL_CALL ConfigurationController_createInstance (
61cdf0e10cSrcweir const Reference<XComponentContext>& rxContext)
62cdf0e10cSrcweir {
63cdf0e10cSrcweir (void)rxContext;
64cdf0e10cSrcweir return static_cast<XWeak*>(new ConfigurationController());
65cdf0e10cSrcweir }
66cdf0e10cSrcweir
67cdf0e10cSrcweir
68cdf0e10cSrcweir
69cdf0e10cSrcweir
ConfigurationController_getImplementationName(void)70cdf0e10cSrcweir OUString ConfigurationController_getImplementationName (void) throw(RuntimeException)
71cdf0e10cSrcweir {
72cdf0e10cSrcweir return OUString(RTL_CONSTASCII_USTRINGPARAM(
73cdf0e10cSrcweir "com.sun.star.comp.Draw.framework.configuration.ConfigurationController"));
74cdf0e10cSrcweir }
75cdf0e10cSrcweir
76cdf0e10cSrcweir
77cdf0e10cSrcweir
78cdf0e10cSrcweir
ConfigurationController_getSupportedServiceNames(void)79cdf0e10cSrcweir Sequence<rtl::OUString> SAL_CALL ConfigurationController_getSupportedServiceNames (void)
80cdf0e10cSrcweir throw (RuntimeException)
81cdf0e10cSrcweir {
82cdf0e10cSrcweir static const OUString sServiceName(OUString::createFromAscii(
83cdf0e10cSrcweir "com.sun.star.drawing.framework.ConfigurationController"));
84cdf0e10cSrcweir return Sequence<rtl::OUString>(&sServiceName, 1);
85cdf0e10cSrcweir }
86cdf0e10cSrcweir
87cdf0e10cSrcweir
88cdf0e10cSrcweir
89cdf0e10cSrcweir
90cdf0e10cSrcweir //----- ConfigurationController::Implementation -------------------------------
91cdf0e10cSrcweir
92cdf0e10cSrcweir class ConfigurationController::Implementation
93cdf0e10cSrcweir {
94cdf0e10cSrcweir public:
95cdf0e10cSrcweir Implementation (
96cdf0e10cSrcweir ConfigurationController& rController,
97cdf0e10cSrcweir const Reference<frame::XController>& rxController);
98cdf0e10cSrcweir ~Implementation (void);
99cdf0e10cSrcweir
100cdf0e10cSrcweir Reference<XControllerManager> mxControllerManager;
101cdf0e10cSrcweir
102cdf0e10cSrcweir /** The Broadcaster class implements storing and calling of listeners.
103cdf0e10cSrcweir */
104cdf0e10cSrcweir ::boost::shared_ptr<ConfigurationControllerBroadcaster> mpBroadcaster;
105cdf0e10cSrcweir
106cdf0e10cSrcweir /** The requested configuration which is modifed (asynchronously) by
107cdf0e10cSrcweir calls to requestResourceActivation() and
108cdf0e10cSrcweir requestResourceDeactivation(). The mpConfigurationUpdater makes the
109cdf0e10cSrcweir current configuration reflect the content of this one.
110cdf0e10cSrcweir */
111cdf0e10cSrcweir ::com::sun::star::uno::Reference<
112cdf0e10cSrcweir ::com::sun::star::drawing::framework::XConfiguration> mxRequestedConfiguration;
113cdf0e10cSrcweir
114cdf0e10cSrcweir ViewShellBase* mpBase;
115cdf0e10cSrcweir
116cdf0e10cSrcweir ::boost::shared_ptr<ResourceFactoryManager> mpResourceFactoryContainer;
117cdf0e10cSrcweir
118cdf0e10cSrcweir ::boost::shared_ptr<ConfigurationControllerResourceManager> mpResourceManager;
119cdf0e10cSrcweir
120cdf0e10cSrcweir ::boost::shared_ptr<ConfigurationUpdater> mpConfigurationUpdater;
121cdf0e10cSrcweir
122cdf0e10cSrcweir /** The queue processor ownes the queue of configuration change request
123cdf0e10cSrcweir objects and processes the objects.
124cdf0e10cSrcweir */
125cdf0e10cSrcweir ::boost::scoped_ptr<ChangeRequestQueueProcessor> mpQueueProcessor;
126cdf0e10cSrcweir
127cdf0e10cSrcweir ::boost::shared_ptr<ConfigurationUpdaterLock> mpConfigurationUpdaterLock;
128cdf0e10cSrcweir
129cdf0e10cSrcweir sal_Int32 mnLockCount;
130cdf0e10cSrcweir };
131cdf0e10cSrcweir
132cdf0e10cSrcweir
133cdf0e10cSrcweir
134cdf0e10cSrcweir
135cdf0e10cSrcweir //===== ConfigurationController::Lock =========================================
136cdf0e10cSrcweir
Lock(const Reference<XConfigurationController> & rxController)137cdf0e10cSrcweir ConfigurationController::Lock::Lock (const Reference<XConfigurationController>& rxController)
138cdf0e10cSrcweir : mxController(rxController)
139cdf0e10cSrcweir {
140cdf0e10cSrcweir OSL_ASSERT(mxController.is());
141cdf0e10cSrcweir
142cdf0e10cSrcweir if (mxController.is())
143cdf0e10cSrcweir mxController->lock();
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
146cdf0e10cSrcweir
147cdf0e10cSrcweir
148cdf0e10cSrcweir
~Lock(void)149cdf0e10cSrcweir ConfigurationController::Lock::~Lock (void)
150cdf0e10cSrcweir {
151cdf0e10cSrcweir if (mxController.is())
152cdf0e10cSrcweir mxController->unlock();
153cdf0e10cSrcweir }
154cdf0e10cSrcweir
155cdf0e10cSrcweir
156cdf0e10cSrcweir
157cdf0e10cSrcweir
158cdf0e10cSrcweir //===== ConfigurationController ===============================================
159cdf0e10cSrcweir
ConfigurationController(void)160cdf0e10cSrcweir ConfigurationController::ConfigurationController (void) throw()
161cdf0e10cSrcweir : ConfigurationControllerInterfaceBase(MutexOwner::maMutex),
162cdf0e10cSrcweir mpImplementation(),
163cdf0e10cSrcweir mbIsDisposed(false)
164cdf0e10cSrcweir {
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
167cdf0e10cSrcweir
168cdf0e10cSrcweir
169cdf0e10cSrcweir
~ConfigurationController(void)170cdf0e10cSrcweir ConfigurationController::~ConfigurationController (void) throw()
171cdf0e10cSrcweir {
172cdf0e10cSrcweir }
173cdf0e10cSrcweir
174cdf0e10cSrcweir
175cdf0e10cSrcweir
176cdf0e10cSrcweir
disposing(void)177cdf0e10cSrcweir void SAL_CALL ConfigurationController::disposing (void)
178cdf0e10cSrcweir {
179cdf0e10cSrcweir if (mpImplementation.get() == NULL)
180cdf0e10cSrcweir return;
181cdf0e10cSrcweir
182cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
183cdf0e10cSrcweir OSL_TRACE("ConfigurationController::disposing\n");
184cdf0e10cSrcweir OSL_TRACE(" requesting empty configuration\n");
185cdf0e10cSrcweir #endif
186cdf0e10cSrcweir // To destroy all resources an empty configuration is requested and then,
187cdf0e10cSrcweir // synchronously, all resulting requests are processed.
188cdf0e10cSrcweir mpImplementation->mpQueueProcessor->Clear();
189cdf0e10cSrcweir restoreConfiguration(new Configuration(this,false));
190cdf0e10cSrcweir mpImplementation->mpQueueProcessor->ProcessUntilEmpty();
191cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
192cdf0e10cSrcweir OSL_TRACE(" all requests processed\n");
193cdf0e10cSrcweir #endif
194cdf0e10cSrcweir
195cdf0e10cSrcweir // Now that all resources have been deactivated, mark the controller as
196cdf0e10cSrcweir // disposed.
197cdf0e10cSrcweir mbIsDisposed = true;
198cdf0e10cSrcweir
199cdf0e10cSrcweir // Release the listeners.
200cdf0e10cSrcweir lang::EventObject aEvent;
201cdf0e10cSrcweir aEvent.Source = uno::Reference<uno::XInterface>((cppu::OWeakObject*)this);
202cdf0e10cSrcweir
203cdf0e10cSrcweir {
204cdf0e10cSrcweir const ::vos::OGuard aSolarGuard (Application::GetSolarMutex());
205cdf0e10cSrcweir mpImplementation->mpBroadcaster->DisposeAndClear();
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
208cdf0e10cSrcweir mpImplementation->mpQueueProcessor.reset();
209cdf0e10cSrcweir mpImplementation->mxRequestedConfiguration = NULL;
210cdf0e10cSrcweir mpImplementation.reset();
211cdf0e10cSrcweir }
212cdf0e10cSrcweir
213cdf0e10cSrcweir
214cdf0e10cSrcweir
215cdf0e10cSrcweir
ProcessEvent(void)216cdf0e10cSrcweir void ConfigurationController::ProcessEvent (void)
217cdf0e10cSrcweir {
218cdf0e10cSrcweir if (mpImplementation.get() != NULL)
219cdf0e10cSrcweir {
220cdf0e10cSrcweir OSL_ASSERT(mpImplementation->mpQueueProcessor.get()!=NULL);
221cdf0e10cSrcweir
222cdf0e10cSrcweir mpImplementation->mpQueueProcessor->ProcessOneEvent();
223cdf0e10cSrcweir }
224cdf0e10cSrcweir }
225cdf0e10cSrcweir
226cdf0e10cSrcweir
227cdf0e10cSrcweir
228cdf0e10cSrcweir
RequestSynchronousUpdate(void)229cdf0e10cSrcweir void ConfigurationController::RequestSynchronousUpdate (void)
230cdf0e10cSrcweir {
231cdf0e10cSrcweir if (mpImplementation.get() == NULL)
232cdf0e10cSrcweir return;
233cdf0e10cSrcweir if (mpImplementation->mpQueueProcessor.get() == 0)
234cdf0e10cSrcweir return;
235cdf0e10cSrcweir mpImplementation->mpQueueProcessor->ProcessUntilEmpty();
236cdf0e10cSrcweir }
237cdf0e10cSrcweir
238cdf0e10cSrcweir
239cdf0e10cSrcweir
240cdf0e10cSrcweir
241cdf0e10cSrcweir //----- XConfigurationControllerBroadcaster -----------------------------------
242cdf0e10cSrcweir
addConfigurationChangeListener(const Reference<XConfigurationChangeListener> & rxListener,const::rtl::OUString & rsEventType,const Any & rUserData)243cdf0e10cSrcweir void SAL_CALL ConfigurationController::addConfigurationChangeListener (
244cdf0e10cSrcweir const Reference<XConfigurationChangeListener>& rxListener,
245cdf0e10cSrcweir const ::rtl::OUString& rsEventType,
246cdf0e10cSrcweir const Any& rUserData)
247cdf0e10cSrcweir throw (RuntimeException)
248cdf0e10cSrcweir {
249cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
250cdf0e10cSrcweir
251cdf0e10cSrcweir ThrowIfDisposed();
252cdf0e10cSrcweir OSL_ASSERT(mpImplementation.get()!=NULL);
253cdf0e10cSrcweir mpImplementation->mpBroadcaster->AddListener(rxListener, rsEventType, rUserData);
254cdf0e10cSrcweir }
255cdf0e10cSrcweir
256cdf0e10cSrcweir
257cdf0e10cSrcweir
258cdf0e10cSrcweir
removeConfigurationChangeListener(const Reference<XConfigurationChangeListener> & rxListener)259cdf0e10cSrcweir void SAL_CALL ConfigurationController::removeConfigurationChangeListener (
260cdf0e10cSrcweir const Reference<XConfigurationChangeListener>& rxListener)
261cdf0e10cSrcweir throw (RuntimeException)
262cdf0e10cSrcweir {
263cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
264cdf0e10cSrcweir
265cdf0e10cSrcweir ThrowIfDisposed();
266cdf0e10cSrcweir mpImplementation->mpBroadcaster->RemoveListener(rxListener);
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
269cdf0e10cSrcweir
270cdf0e10cSrcweir
271cdf0e10cSrcweir
notifyEvent(const ConfigurationChangeEvent & rEvent)272cdf0e10cSrcweir void SAL_CALL ConfigurationController::notifyEvent (
273cdf0e10cSrcweir const ConfigurationChangeEvent& rEvent)
274cdf0e10cSrcweir throw (RuntimeException)
275cdf0e10cSrcweir {
276cdf0e10cSrcweir ThrowIfDisposed();
277cdf0e10cSrcweir mpImplementation->mpBroadcaster->NotifyListeners(rEvent);
278cdf0e10cSrcweir }
279cdf0e10cSrcweir
280cdf0e10cSrcweir
281cdf0e10cSrcweir
282cdf0e10cSrcweir
283cdf0e10cSrcweir
284cdf0e10cSrcweir //----- XConfigurationController ----------------------------------------------
285cdf0e10cSrcweir
lock(void)286cdf0e10cSrcweir void SAL_CALL ConfigurationController::lock (void)
287cdf0e10cSrcweir throw (RuntimeException)
288cdf0e10cSrcweir {
289cdf0e10cSrcweir OSL_ASSERT(mpImplementation.get()!=NULL);
290cdf0e10cSrcweir OSL_ASSERT(mpImplementation->mpConfigurationUpdater.get()!=NULL);
291cdf0e10cSrcweir
292cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
293cdf0e10cSrcweir ThrowIfDisposed();
294cdf0e10cSrcweir
295cdf0e10cSrcweir
296cdf0e10cSrcweir ++mpImplementation->mnLockCount;
297cdf0e10cSrcweir if (mpImplementation->mpConfigurationUpdaterLock.get()==NULL)
298cdf0e10cSrcweir mpImplementation->mpConfigurationUpdaterLock
299cdf0e10cSrcweir = mpImplementation->mpConfigurationUpdater->GetLock();
300cdf0e10cSrcweir }
301cdf0e10cSrcweir
302cdf0e10cSrcweir
303cdf0e10cSrcweir
304cdf0e10cSrcweir
unlock(void)305cdf0e10cSrcweir void SAL_CALL ConfigurationController::unlock (void)
306cdf0e10cSrcweir throw (RuntimeException)
307cdf0e10cSrcweir {
308cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
309cdf0e10cSrcweir
310cdf0e10cSrcweir // Allow unlocking while the ConfigurationController is being disposed
311cdf0e10cSrcweir // (but not when that is done and the controller is disposed.)
312cdf0e10cSrcweir if (rBHelper.bDisposed)
313cdf0e10cSrcweir ThrowIfDisposed();
314cdf0e10cSrcweir
315cdf0e10cSrcweir OSL_ASSERT(mpImplementation->mnLockCount>0);
316cdf0e10cSrcweir --mpImplementation->mnLockCount;
317cdf0e10cSrcweir if (mpImplementation->mnLockCount == 0)
318cdf0e10cSrcweir mpImplementation->mpConfigurationUpdaterLock.reset();
319cdf0e10cSrcweir }
320cdf0e10cSrcweir
321cdf0e10cSrcweir
322cdf0e10cSrcweir
323cdf0e10cSrcweir
requestResourceActivation(const Reference<XResourceId> & rxResourceId,ResourceActivationMode eMode)324cdf0e10cSrcweir void SAL_CALL ConfigurationController::requestResourceActivation (
325cdf0e10cSrcweir const Reference<XResourceId>& rxResourceId,
326cdf0e10cSrcweir ResourceActivationMode eMode)
327cdf0e10cSrcweir throw (RuntimeException)
328cdf0e10cSrcweir {
329cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
330cdf0e10cSrcweir ThrowIfDisposed();
331cdf0e10cSrcweir
332cdf0e10cSrcweir // Check whether we are being disposed. This is handled differently
333cdf0e10cSrcweir // then being completely disposed because the first thing disposing()
334cdf0e10cSrcweir // does is to deactivate all remaining resources. This is done via
335cdf0e10cSrcweir // regular methods which must not throw DisposedExceptions. Therefore
336cdf0e10cSrcweir // we just return silently during that stage.
337cdf0e10cSrcweir if (rBHelper.bInDispose)
338cdf0e10cSrcweir {
339cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
340cdf0e10cSrcweir OSL_TRACE("ConfigurationController::requestResourceActivation(): ignoring %s\n",
341cdf0e10cSrcweir OUStringToOString(
342cdf0e10cSrcweir FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
343cdf0e10cSrcweir #endif
344cdf0e10cSrcweir return;
345cdf0e10cSrcweir }
346cdf0e10cSrcweir
347cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
348cdf0e10cSrcweir OSL_TRACE("ConfigurationController::requestResourceActivation() %s\n",
349cdf0e10cSrcweir OUStringToOString(
350cdf0e10cSrcweir FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
351cdf0e10cSrcweir #endif
352cdf0e10cSrcweir
353cdf0e10cSrcweir if (rxResourceId.is())
354cdf0e10cSrcweir {
355cdf0e10cSrcweir if (eMode == ResourceActivationMode_REPLACE)
356cdf0e10cSrcweir {
357cdf0e10cSrcweir // Get a list of the matching resources and create deactivation
358cdf0e10cSrcweir // requests for them.
359cdf0e10cSrcweir Sequence<Reference<XResourceId> > aResourceList (
360cdf0e10cSrcweir mpImplementation->mxRequestedConfiguration->getResources(
361cdf0e10cSrcweir rxResourceId->getAnchor(),
362cdf0e10cSrcweir rxResourceId->getResourceTypePrefix(),
363cdf0e10cSrcweir AnchorBindingMode_DIRECT));
364cdf0e10cSrcweir
365cdf0e10cSrcweir for (sal_Int32 nIndex=0; nIndex<aResourceList.getLength(); ++nIndex)
366cdf0e10cSrcweir {
367cdf0e10cSrcweir // Do not request the deactivation of the resource for which
368cdf0e10cSrcweir // this method was called. Doing it would not change the
369cdf0e10cSrcweir // outcome but would result in unnecessary work.
370cdf0e10cSrcweir if (rxResourceId->compareTo(aResourceList[nIndex]) == 0)
371cdf0e10cSrcweir continue;
372cdf0e10cSrcweir
373cdf0e10cSrcweir // Request the deactivation of a resource and all resources
374cdf0e10cSrcweir // linked to it.
375cdf0e10cSrcweir requestResourceDeactivation(aResourceList[nIndex]);
376cdf0e10cSrcweir }
377cdf0e10cSrcweir }
378cdf0e10cSrcweir
379cdf0e10cSrcweir Reference<XConfigurationChangeRequest> xRequest(
380cdf0e10cSrcweir new GenericConfigurationChangeRequest(
381cdf0e10cSrcweir rxResourceId,
382cdf0e10cSrcweir GenericConfigurationChangeRequest::Activation));
383cdf0e10cSrcweir postChangeRequest(xRequest);
384cdf0e10cSrcweir }
385cdf0e10cSrcweir }
386cdf0e10cSrcweir
387cdf0e10cSrcweir
388cdf0e10cSrcweir
389cdf0e10cSrcweir
requestResourceDeactivation(const Reference<XResourceId> & rxResourceId)390cdf0e10cSrcweir void SAL_CALL ConfigurationController::requestResourceDeactivation (
391cdf0e10cSrcweir const Reference<XResourceId>& rxResourceId)
392cdf0e10cSrcweir throw (RuntimeException)
393cdf0e10cSrcweir {
394cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
395cdf0e10cSrcweir ThrowIfDisposed();
396cdf0e10cSrcweir
397cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
398cdf0e10cSrcweir OSL_TRACE("ConfigurationController::requestResourceDeactivation() %s\n",
399cdf0e10cSrcweir OUStringToOString(
400cdf0e10cSrcweir FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
401cdf0e10cSrcweir #endif
402cdf0e10cSrcweir
403cdf0e10cSrcweir if (rxResourceId.is())
404cdf0e10cSrcweir {
405cdf0e10cSrcweir // Request deactivation of all resources linked to the specified one
406cdf0e10cSrcweir // as well.
407cdf0e10cSrcweir const Sequence<Reference<XResourceId> > aLinkedResources (
408cdf0e10cSrcweir mpImplementation->mxRequestedConfiguration->getResources(
409cdf0e10cSrcweir rxResourceId,
410cdf0e10cSrcweir OUString(),
411cdf0e10cSrcweir AnchorBindingMode_DIRECT));
412cdf0e10cSrcweir const sal_Int32 nCount (aLinkedResources.getLength());
413cdf0e10cSrcweir for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir // We do not add deactivation requests directly but call this
416cdf0e10cSrcweir // method recursively, so that when one time there are resources
417cdf0e10cSrcweir // linked to linked resources, these are handled correctly, too.
418cdf0e10cSrcweir requestResourceDeactivation(aLinkedResources[nIndex]);
419cdf0e10cSrcweir }
420cdf0e10cSrcweir
421cdf0e10cSrcweir // Add a deactivation request for the specified resource.
422cdf0e10cSrcweir Reference<XConfigurationChangeRequest> xRequest(
423cdf0e10cSrcweir new GenericConfigurationChangeRequest(
424cdf0e10cSrcweir rxResourceId,
425cdf0e10cSrcweir GenericConfigurationChangeRequest::Deactivation));
426cdf0e10cSrcweir postChangeRequest(xRequest);
427cdf0e10cSrcweir }
428cdf0e10cSrcweir }
429cdf0e10cSrcweir
430cdf0e10cSrcweir
431cdf0e10cSrcweir
432cdf0e10cSrcweir
getResource(const Reference<XResourceId> & rxResourceId)433cdf0e10cSrcweir Reference<XResource> SAL_CALL ConfigurationController::getResource (
434cdf0e10cSrcweir const Reference<XResourceId>& rxResourceId)
435cdf0e10cSrcweir throw (RuntimeException)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
438cdf0e10cSrcweir ThrowIfDisposed();
439cdf0e10cSrcweir
440cdf0e10cSrcweir ConfigurationControllerResourceManager::ResourceDescriptor aDescriptor (
441cdf0e10cSrcweir mpImplementation->mpResourceManager->GetResource(rxResourceId));
442cdf0e10cSrcweir return aDescriptor.mxResource;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir
445cdf0e10cSrcweir
446cdf0e10cSrcweir
447cdf0e10cSrcweir
update(void)448cdf0e10cSrcweir void SAL_CALL ConfigurationController::update (void)
449cdf0e10cSrcweir throw (RuntimeException)
450cdf0e10cSrcweir {
451cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
452cdf0e10cSrcweir ThrowIfDisposed();
453cdf0e10cSrcweir
454cdf0e10cSrcweir if (mpImplementation->mpQueueProcessor->IsEmpty())
455cdf0e10cSrcweir {
456cdf0e10cSrcweir // The queue is empty. Add another request that does nothing but
457cdf0e10cSrcweir // asynchronously trigger a request for an update.
458cdf0e10cSrcweir mpImplementation->mpQueueProcessor->AddRequest(new UpdateRequest());
459cdf0e10cSrcweir }
460cdf0e10cSrcweir else
461cdf0e10cSrcweir {
462cdf0e10cSrcweir // The queue is not empty, so we rely on the queue processor to
463cdf0e10cSrcweir // request an update automatically when the queue becomes empty.
464cdf0e10cSrcweir }
465cdf0e10cSrcweir }
466cdf0e10cSrcweir
467cdf0e10cSrcweir
468cdf0e10cSrcweir
469cdf0e10cSrcweir
hasPendingRequests(void)470cdf0e10cSrcweir sal_Bool SAL_CALL ConfigurationController::hasPendingRequests (void)
471cdf0e10cSrcweir throw (RuntimeException)
472cdf0e10cSrcweir {
473cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
474cdf0e10cSrcweir ThrowIfDisposed();
475cdf0e10cSrcweir
476cdf0e10cSrcweir return ! mpImplementation->mpQueueProcessor->IsEmpty();
477cdf0e10cSrcweir }
478cdf0e10cSrcweir
479cdf0e10cSrcweir
480cdf0e10cSrcweir
481cdf0e10cSrcweir
482cdf0e10cSrcweir
postChangeRequest(const Reference<XConfigurationChangeRequest> & rxRequest)483cdf0e10cSrcweir void SAL_CALL ConfigurationController::postChangeRequest (
484cdf0e10cSrcweir const Reference<XConfigurationChangeRequest>& rxRequest)
485cdf0e10cSrcweir throw (RuntimeException)
486cdf0e10cSrcweir {
487cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
488cdf0e10cSrcweir ThrowIfDisposed();
489cdf0e10cSrcweir
490cdf0e10cSrcweir mpImplementation->mpQueueProcessor->AddRequest(rxRequest);
491cdf0e10cSrcweir }
492cdf0e10cSrcweir
493cdf0e10cSrcweir
494cdf0e10cSrcweir
495cdf0e10cSrcweir
getRequestedConfiguration(void)496cdf0e10cSrcweir Reference<XConfiguration> SAL_CALL ConfigurationController::getRequestedConfiguration (void)
497cdf0e10cSrcweir throw (RuntimeException)
498cdf0e10cSrcweir {
499cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
500cdf0e10cSrcweir ThrowIfDisposed();
501cdf0e10cSrcweir
502cdf0e10cSrcweir if (mpImplementation->mxRequestedConfiguration.is())
503cdf0e10cSrcweir return Reference<XConfiguration>(
504cdf0e10cSrcweir mpImplementation->mxRequestedConfiguration->createClone(), UNO_QUERY);
505cdf0e10cSrcweir else
506cdf0e10cSrcweir return Reference<XConfiguration>();
507cdf0e10cSrcweir }
508cdf0e10cSrcweir
509cdf0e10cSrcweir
510cdf0e10cSrcweir
511cdf0e10cSrcweir
getCurrentConfiguration(void)512cdf0e10cSrcweir Reference<XConfiguration> SAL_CALL ConfigurationController::getCurrentConfiguration (void)
513cdf0e10cSrcweir throw (RuntimeException)
514cdf0e10cSrcweir {
515cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
516cdf0e10cSrcweir ThrowIfDisposed();
517cdf0e10cSrcweir
518cdf0e10cSrcweir Reference<XConfiguration> xCurrentConfiguration(
519cdf0e10cSrcweir mpImplementation->mpConfigurationUpdater->GetCurrentConfiguration());
520cdf0e10cSrcweir if (xCurrentConfiguration.is())
521cdf0e10cSrcweir return Reference<XConfiguration>(xCurrentConfiguration->createClone(), UNO_QUERY);
522cdf0e10cSrcweir else
523cdf0e10cSrcweir return Reference<XConfiguration>();
524cdf0e10cSrcweir }
525cdf0e10cSrcweir
526cdf0e10cSrcweir
527cdf0e10cSrcweir
528cdf0e10cSrcweir
529cdf0e10cSrcweir /** The given configuration is restored by generating the appropriate set of
530cdf0e10cSrcweir activation and deactivation requests.
531cdf0e10cSrcweir */
restoreConfiguration(const Reference<XConfiguration> & rxNewConfiguration)532cdf0e10cSrcweir void SAL_CALL ConfigurationController::restoreConfiguration (
533cdf0e10cSrcweir const Reference<XConfiguration>& rxNewConfiguration)
534cdf0e10cSrcweir throw (RuntimeException)
535cdf0e10cSrcweir {
536cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
537cdf0e10cSrcweir ThrowIfDisposed();
538cdf0e10cSrcweir
539cdf0e10cSrcweir // We will probably be making a couple of activation and deactivation
540cdf0e10cSrcweir // requests so lock the configuration controller and let it later update
541cdf0e10cSrcweir // all changes at once.
542cdf0e10cSrcweir ::boost::shared_ptr<ConfigurationUpdaterLock> pLock (
543cdf0e10cSrcweir mpImplementation->mpConfigurationUpdater->GetLock());
544cdf0e10cSrcweir
545cdf0e10cSrcweir // Get lists of resources that are to be activated or deactivated.
546cdf0e10cSrcweir Reference<XConfiguration> xCurrentConfiguration (mpImplementation->mxRequestedConfiguration);
547cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
548cdf0e10cSrcweir OSL_TRACE("ConfigurationController::restoreConfiguration(\n");
549cdf0e10cSrcweir ConfigurationTracer::TraceConfiguration(rxNewConfiguration, "requested configuration");
550cdf0e10cSrcweir ConfigurationTracer::TraceConfiguration(xCurrentConfiguration, "current configuration");
551cdf0e10cSrcweir #endif
552cdf0e10cSrcweir ConfigurationClassifier aClassifier (rxNewConfiguration, xCurrentConfiguration);
553cdf0e10cSrcweir aClassifier.Partition();
554cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=3
555cdf0e10cSrcweir aClassifier.TraceResourceIdVector(
556cdf0e10cSrcweir "requested but not current resources:\n", aClassifier.GetC1minusC2());
557cdf0e10cSrcweir aClassifier.TraceResourceIdVector(
558cdf0e10cSrcweir "current but not requested resources:\n", aClassifier.GetC2minusC1());
559cdf0e10cSrcweir aClassifier.TraceResourceIdVector(
560cdf0e10cSrcweir "requested and current resources:\n", aClassifier.GetC1andC2());
561cdf0e10cSrcweir #endif
562cdf0e10cSrcweir
563cdf0e10cSrcweir ConfigurationClassifier::ResourceIdVector::const_iterator iResource;
564cdf0e10cSrcweir
565cdf0e10cSrcweir // Request the deactivation of resources that are not requested in the
566cdf0e10cSrcweir // new configuration.
567cdf0e10cSrcweir const ConfigurationClassifier::ResourceIdVector& rResourcesToDeactivate (
568cdf0e10cSrcweir aClassifier.GetC2minusC1());
569cdf0e10cSrcweir for (iResource=rResourcesToDeactivate.begin();
570cdf0e10cSrcweir iResource!=rResourcesToDeactivate.end();
571cdf0e10cSrcweir ++iResource)
572cdf0e10cSrcweir {
573cdf0e10cSrcweir requestResourceDeactivation(*iResource);
574cdf0e10cSrcweir }
575cdf0e10cSrcweir
576cdf0e10cSrcweir // Request the activation of resources that are requested in the
577cdf0e10cSrcweir // new configuration but are not part of the current configuration.
578cdf0e10cSrcweir const ConfigurationClassifier::ResourceIdVector& rResourcesToActivate (
579cdf0e10cSrcweir aClassifier.GetC1minusC2());
580cdf0e10cSrcweir for (iResource=rResourcesToActivate.begin();
581cdf0e10cSrcweir iResource!=rResourcesToActivate.end();
582cdf0e10cSrcweir ++iResource)
583cdf0e10cSrcweir {
584cdf0e10cSrcweir requestResourceActivation(*iResource, ResourceActivationMode_ADD);
585cdf0e10cSrcweir }
586cdf0e10cSrcweir
587cdf0e10cSrcweir pLock.reset();
588cdf0e10cSrcweir }
589cdf0e10cSrcweir
590cdf0e10cSrcweir
591cdf0e10cSrcweir
592cdf0e10cSrcweir
593cdf0e10cSrcweir //----- XResourceFactoryManager -----------------------------------------------
594cdf0e10cSrcweir
addResourceFactory(const OUString & sResourceURL,const Reference<XResourceFactory> & rxResourceFactory)595cdf0e10cSrcweir void SAL_CALL ConfigurationController::addResourceFactory(
596cdf0e10cSrcweir const OUString& sResourceURL,
597cdf0e10cSrcweir const Reference<XResourceFactory>& rxResourceFactory)
598cdf0e10cSrcweir throw (RuntimeException)
599cdf0e10cSrcweir {
600cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
601cdf0e10cSrcweir ThrowIfDisposed();
602cdf0e10cSrcweir mpImplementation->mpResourceFactoryContainer->AddFactory(sResourceURL, rxResourceFactory);
603cdf0e10cSrcweir }
604cdf0e10cSrcweir
605cdf0e10cSrcweir
606cdf0e10cSrcweir
607cdf0e10cSrcweir
removeResourceFactoryForURL(const OUString & sResourceURL)608cdf0e10cSrcweir void SAL_CALL ConfigurationController::removeResourceFactoryForURL(
609cdf0e10cSrcweir const OUString& sResourceURL)
610cdf0e10cSrcweir throw (RuntimeException)
611cdf0e10cSrcweir {
612cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
613cdf0e10cSrcweir ThrowIfDisposed();
614cdf0e10cSrcweir mpImplementation->mpResourceFactoryContainer->RemoveFactoryForURL(sResourceURL);
615cdf0e10cSrcweir }
616cdf0e10cSrcweir
617cdf0e10cSrcweir
618cdf0e10cSrcweir
619cdf0e10cSrcweir
removeResourceFactoryForReference(const Reference<XResourceFactory> & rxResourceFactory)620cdf0e10cSrcweir void SAL_CALL ConfigurationController::removeResourceFactoryForReference(
621cdf0e10cSrcweir const Reference<XResourceFactory>& rxResourceFactory)
622cdf0e10cSrcweir throw (RuntimeException)
623cdf0e10cSrcweir {
624cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
625cdf0e10cSrcweir ThrowIfDisposed();
626cdf0e10cSrcweir mpImplementation->mpResourceFactoryContainer->RemoveFactoryForReference(rxResourceFactory);
627cdf0e10cSrcweir }
628cdf0e10cSrcweir
629cdf0e10cSrcweir
630cdf0e10cSrcweir
631cdf0e10cSrcweir
getResourceFactory(const OUString & sResourceURL)632cdf0e10cSrcweir Reference<XResourceFactory> SAL_CALL ConfigurationController::getResourceFactory (
633cdf0e10cSrcweir const OUString& sResourceURL)
634cdf0e10cSrcweir throw (RuntimeException)
635cdf0e10cSrcweir {
636cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
637cdf0e10cSrcweir ThrowIfDisposed();
638cdf0e10cSrcweir
639cdf0e10cSrcweir return mpImplementation->mpResourceFactoryContainer->GetFactory(sResourceURL);
640cdf0e10cSrcweir }
641cdf0e10cSrcweir
642cdf0e10cSrcweir
643cdf0e10cSrcweir
644cdf0e10cSrcweir
645cdf0e10cSrcweir //----- XInitialization -------------------------------------------------------
646cdf0e10cSrcweir
initialize(const Sequence<Any> & aArguments)647cdf0e10cSrcweir void SAL_CALL ConfigurationController::initialize (const Sequence<Any>& aArguments)
648cdf0e10cSrcweir throw (Exception, RuntimeException)
649cdf0e10cSrcweir {
650cdf0e10cSrcweir ::osl::MutexGuard aGuard (maMutex);
651cdf0e10cSrcweir
652cdf0e10cSrcweir if (aArguments.getLength() == 1)
653cdf0e10cSrcweir {
654cdf0e10cSrcweir const ::vos::OGuard aSolarGuard (Application::GetSolarMutex());
655cdf0e10cSrcweir
656cdf0e10cSrcweir mpImplementation.reset(new Implementation(
657cdf0e10cSrcweir *this,
658cdf0e10cSrcweir Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW)));
659cdf0e10cSrcweir }
660cdf0e10cSrcweir }
661cdf0e10cSrcweir
662cdf0e10cSrcweir
663cdf0e10cSrcweir
664cdf0e10cSrcweir
665cdf0e10cSrcweir //-----------------------------------------------------------------------------
666cdf0e10cSrcweir
ThrowIfDisposed(void) const667cdf0e10cSrcweir void ConfigurationController::ThrowIfDisposed (void) const
668cdf0e10cSrcweir throw (::com::sun::star::lang::DisposedException)
669cdf0e10cSrcweir {
670cdf0e10cSrcweir if (mbIsDisposed)
671cdf0e10cSrcweir {
672cdf0e10cSrcweir throw lang::DisposedException (
673cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM(
674cdf0e10cSrcweir "ConfigurationController object has already been disposed")),
675cdf0e10cSrcweir const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
676cdf0e10cSrcweir }
677cdf0e10cSrcweir
678cdf0e10cSrcweir if (mpImplementation.get() == NULL)
679cdf0e10cSrcweir {
680cdf0e10cSrcweir OSL_ASSERT(mpImplementation.get() != NULL);
681cdf0e10cSrcweir throw RuntimeException(
682cdf0e10cSrcweir OUString(RTL_CONSTASCII_USTRINGPARAM(
683cdf0e10cSrcweir "ConfigurationController not initialized")),
684cdf0e10cSrcweir const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
685cdf0e10cSrcweir }
686cdf0e10cSrcweir }
687cdf0e10cSrcweir
688cdf0e10cSrcweir
689cdf0e10cSrcweir
690cdf0e10cSrcweir
691cdf0e10cSrcweir //===== ConfigurationController::Implementation ===============================
692cdf0e10cSrcweir
Implementation(ConfigurationController & rController,const Reference<frame::XController> & rxController)693cdf0e10cSrcweir ConfigurationController::Implementation::Implementation (
694cdf0e10cSrcweir ConfigurationController& rController,
695cdf0e10cSrcweir const Reference<frame::XController>& rxController)
696cdf0e10cSrcweir : mxControllerManager(rxController, UNO_QUERY_THROW),
697cdf0e10cSrcweir mpBroadcaster(new ConfigurationControllerBroadcaster(&rController)),
698cdf0e10cSrcweir mxRequestedConfiguration(new Configuration(&rController, true)),
699cdf0e10cSrcweir mpBase(NULL),
700cdf0e10cSrcweir mpResourceFactoryContainer(new ResourceFactoryManager(mxControllerManager)),
701cdf0e10cSrcweir mpResourceManager(
702cdf0e10cSrcweir new ConfigurationControllerResourceManager(mpResourceFactoryContainer,mpBroadcaster)),
703cdf0e10cSrcweir mpConfigurationUpdater(
704cdf0e10cSrcweir new ConfigurationUpdater(mpBroadcaster, mpResourceManager,mxControllerManager)),
705cdf0e10cSrcweir mpQueueProcessor(new ChangeRequestQueueProcessor(&rController,mpConfigurationUpdater)),
706cdf0e10cSrcweir mpConfigurationUpdaterLock(),
707cdf0e10cSrcweir mnLockCount(0)
708cdf0e10cSrcweir {
709cdf0e10cSrcweir mpQueueProcessor->SetConfiguration(mxRequestedConfiguration);
710cdf0e10cSrcweir }
711cdf0e10cSrcweir
712cdf0e10cSrcweir
713cdf0e10cSrcweir
714cdf0e10cSrcweir
~Implementation(void)715cdf0e10cSrcweir ConfigurationController::Implementation::~Implementation (void)
716cdf0e10cSrcweir {
717cdf0e10cSrcweir }
718cdf0e10cSrcweir
719cdf0e10cSrcweir
720cdf0e10cSrcweir
721cdf0e10cSrcweir
722cdf0e10cSrcweir } } // end of namespace sd::framework
723