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