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 "ConfigurationUpdater.hxx"
27cdf0e10cSrcweir #include "ConfigurationTracer.hxx"
28cdf0e10cSrcweir #include "ConfigurationClassifier.hxx"
29cdf0e10cSrcweir #include "ConfigurationControllerBroadcaster.hxx"
30cdf0e10cSrcweir #include "framework/Configuration.hxx"
31cdf0e10cSrcweir #include "framework/FrameworkHelper.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <comphelper/scopeguard.hxx>
34cdf0e10cSrcweir #include <tools/diagnose_ex.h>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <boost/bind.hpp>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir using namespace ::com::sun::star;
39cdf0e10cSrcweir using namespace ::com::sun::star::uno;
40cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
41cdf0e10cSrcweir using ::sd::framework::FrameworkHelper;
42cdf0e10cSrcweir using ::rtl::OUString;
43cdf0e10cSrcweir using ::std::vector;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #undef VERBOSE
46cdf0e10cSrcweir //#define VERBOSE 2
47cdf0e10cSrcweir 
48cdf0e10cSrcweir namespace {
49cdf0e10cSrcweir static const sal_Int32 snShortTimeout (100);
50cdf0e10cSrcweir static const sal_Int32 snNormalTimeout (1000);
51cdf0e10cSrcweir static const sal_Int32 snLongTimeout (10000);
52cdf0e10cSrcweir static const sal_Int32 snShortTimeoutCountThreshold (1);
53cdf0e10cSrcweir static const sal_Int32 snNormalTimeoutCountThreshold (5);
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
56cdf0e10cSrcweir namespace sd { namespace framework {
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 
59cdf0e10cSrcweir //===== ConfigurationUpdaterLock ==============================================
60cdf0e10cSrcweir 
61cdf0e10cSrcweir class ConfigurationUpdaterLock
62cdf0e10cSrcweir {
63cdf0e10cSrcweir public:
ConfigurationUpdaterLock(ConfigurationUpdater & rUpdater)64cdf0e10cSrcweir     ConfigurationUpdaterLock (ConfigurationUpdater& rUpdater)
65cdf0e10cSrcweir         : mrUpdater(rUpdater) { mrUpdater.LockUpdates(); }
~ConfigurationUpdaterLock(void)66cdf0e10cSrcweir     ~ConfigurationUpdaterLock(void) { mrUpdater.UnlockUpdates(); }
67cdf0e10cSrcweir private:
68cdf0e10cSrcweir     ConfigurationUpdater& mrUpdater;
69cdf0e10cSrcweir };
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 
74cdf0e10cSrcweir //===== ConfigurationUpdater ==================================================
75cdf0e10cSrcweir 
ConfigurationUpdater(const::boost::shared_ptr<ConfigurationControllerBroadcaster> & rpBroadcaster,const::boost::shared_ptr<ConfigurationControllerResourceManager> & rpResourceManager,const Reference<XControllerManager> & rxControllerManager)76cdf0e10cSrcweir ConfigurationUpdater::ConfigurationUpdater (
77cdf0e10cSrcweir     const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster,
78cdf0e10cSrcweir     const ::boost::shared_ptr<ConfigurationControllerResourceManager>& rpResourceManager,
79cdf0e10cSrcweir     const Reference<XControllerManager>& rxControllerManager)
80cdf0e10cSrcweir     : mxControllerManager(),
81cdf0e10cSrcweir       mpBroadcaster(rpBroadcaster),
82cdf0e10cSrcweir       mxCurrentConfiguration(Reference<XConfiguration>(new Configuration(NULL, false))),
83cdf0e10cSrcweir       mxRequestedConfiguration(),
84cdf0e10cSrcweir       mbUpdatePending(false),
85cdf0e10cSrcweir       mbUpdateBeingProcessed(false),
86cdf0e10cSrcweir       mnLockCount(0),
87cdf0e10cSrcweir       maUpdateTimer(),
88cdf0e10cSrcweir       mnFailedUpdateCount(0),
89cdf0e10cSrcweir       mpResourceManager(rpResourceManager)
90cdf0e10cSrcweir {
91cdf0e10cSrcweir     // Prepare the timer that is started when after an update the current
92cdf0e10cSrcweir     // and the requested configuration differ.  With the timer we try
93cdf0e10cSrcweir     // updates until the two configurations are the same.
94cdf0e10cSrcweir     maUpdateTimer.SetTimeout(snNormalTimeout);
95cdf0e10cSrcweir     maUpdateTimer.SetTimeoutHdl(LINK(this,ConfigurationUpdater,TimeoutHandler));
96cdf0e10cSrcweir     SetControllerManager(rxControllerManager);
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 
~ConfigurationUpdater(void)102cdf0e10cSrcweir ConfigurationUpdater::~ConfigurationUpdater (void)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir     maUpdateTimer.Stop();
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
107cdf0e10cSrcweir 
108cdf0e10cSrcweir 
109cdf0e10cSrcweir 
SetControllerManager(const Reference<XControllerManager> & rxControllerManager)110cdf0e10cSrcweir void ConfigurationUpdater::SetControllerManager(
111cdf0e10cSrcweir     const Reference<XControllerManager>& rxControllerManager)
112cdf0e10cSrcweir {
113cdf0e10cSrcweir     mxControllerManager = rxControllerManager;
114cdf0e10cSrcweir }
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 
118cdf0e10cSrcweir 
RequestUpdate(const Reference<XConfiguration> & rxRequestedConfiguration)119cdf0e10cSrcweir void ConfigurationUpdater::RequestUpdate (
120cdf0e10cSrcweir     const Reference<XConfiguration>& rxRequestedConfiguration)
121cdf0e10cSrcweir {
122cdf0e10cSrcweir     mxRequestedConfiguration = rxRequestedConfiguration;
123cdf0e10cSrcweir 
124cdf0e10cSrcweir     // Find out whether we really can update the configuration.
125cdf0e10cSrcweir     if (IsUpdatePossible())
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
128cdf0e10cSrcweir         OSL_TRACE("UpdateConfiguration start");
129cdf0e10cSrcweir #endif
130cdf0e10cSrcweir 
131cdf0e10cSrcweir         // Call UpdateConfiguration while that is possible and while someone
132cdf0e10cSrcweir         // set mbUpdatePending to true in the middle of it.
133cdf0e10cSrcweir         do
134cdf0e10cSrcweir         {
135cdf0e10cSrcweir             UpdateConfiguration();
136cdf0e10cSrcweir 
137cdf0e10cSrcweir             if (mbUpdatePending && IsUpdatePossible())
138cdf0e10cSrcweir                 continue;
139cdf0e10cSrcweir         }
140cdf0e10cSrcweir         while (false);
141cdf0e10cSrcweir     }
142cdf0e10cSrcweir     else
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         mbUpdatePending = true;
145cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
146cdf0e10cSrcweir         OSL_TRACE("scheduling update for later");
147cdf0e10cSrcweir #endif
148cdf0e10cSrcweir     }
149cdf0e10cSrcweir }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 
GetCurrentConfiguration(void) const154cdf0e10cSrcweir Reference<XConfiguration> ConfigurationUpdater::GetCurrentConfiguration (void) const
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     return mxCurrentConfiguration;
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 
IsUpdatePossible(void)162cdf0e10cSrcweir bool ConfigurationUpdater::IsUpdatePossible (void)
163cdf0e10cSrcweir {
164cdf0e10cSrcweir     return ! mbUpdateBeingProcessed
165cdf0e10cSrcweir         && mxControllerManager.is()
166cdf0e10cSrcweir         && mnLockCount==0
167cdf0e10cSrcweir         && mxRequestedConfiguration.is()
168cdf0e10cSrcweir         && mxCurrentConfiguration.is();
169cdf0e10cSrcweir }
170cdf0e10cSrcweir 
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 
UpdateConfiguration(void)174cdf0e10cSrcweir void ConfigurationUpdater::UpdateConfiguration (void)
175cdf0e10cSrcweir {
176cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
177cdf0e10cSrcweir         OSL_TRACE("UpdateConfiguration update");
178cdf0e10cSrcweir #endif
179cdf0e10cSrcweir     SetUpdateBeingProcessed(true);
180cdf0e10cSrcweir     comphelper::ScopeGuard aScopeGuard (
181cdf0e10cSrcweir         ::boost::bind(&ConfigurationUpdater::SetUpdateBeingProcessed, this, false));
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     try
184cdf0e10cSrcweir     {
185cdf0e10cSrcweir         mbUpdatePending = false;
186cdf0e10cSrcweir 
187cdf0e10cSrcweir         CleanRequestedConfiguration();
188cdf0e10cSrcweir         ConfigurationClassifier aClassifier(mxRequestedConfiguration, mxCurrentConfiguration);
189cdf0e10cSrcweir         if (aClassifier.Partition())
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
192cdf0e10cSrcweir             OSL_TRACE("ConfigurationUpdater::UpdateConfiguration(");
193cdf0e10cSrcweir             ConfigurationTracer::TraceConfiguration(
194cdf0e10cSrcweir                 mxRequestedConfiguration, "requested configuration");
195cdf0e10cSrcweir             ConfigurationTracer::TraceConfiguration(
196cdf0e10cSrcweir                 mxCurrentConfiguration, "current configuration");
197cdf0e10cSrcweir #endif
198cdf0e10cSrcweir             // Notify the begining of the update.
199cdf0e10cSrcweir             ConfigurationChangeEvent aEvent;
200cdf0e10cSrcweir             aEvent.Type = FrameworkHelper::msConfigurationUpdateStartEvent;
201cdf0e10cSrcweir             aEvent.Configuration = mxRequestedConfiguration;
202cdf0e10cSrcweir             mpBroadcaster->NotifyListeners(aEvent);
203cdf0e10cSrcweir 
204cdf0e10cSrcweir             // Do the actual update.  All exceptions are caught and ignored,
205cdf0e10cSrcweir             // so that the the end of the update is notified always.
206cdf0e10cSrcweir             try
207cdf0e10cSrcweir             {
208cdf0e10cSrcweir                 if (mnLockCount == 0)
209cdf0e10cSrcweir                     UpdateCore(aClassifier);
210cdf0e10cSrcweir             }
211cdf0e10cSrcweir             catch(RuntimeException)
212cdf0e10cSrcweir             {
213cdf0e10cSrcweir             }
214cdf0e10cSrcweir 
215cdf0e10cSrcweir             // Notify the end of the update.
216cdf0e10cSrcweir             aEvent.Type = FrameworkHelper::msConfigurationUpdateEndEvent;
217cdf0e10cSrcweir             mpBroadcaster->NotifyListeners(aEvent);
218cdf0e10cSrcweir 
219cdf0e10cSrcweir             CheckUpdateSuccess();
220cdf0e10cSrcweir         }
221cdf0e10cSrcweir         else
222cdf0e10cSrcweir         {
223cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>0
224cdf0e10cSrcweir             OSL_TRACE("nothing to do");
225cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
226cdf0e10cSrcweir             ConfigurationTracer::TraceConfiguration(
227cdf0e10cSrcweir                 mxRequestedConfiguration, "requested configuration");
228cdf0e10cSrcweir             ConfigurationTracer::TraceConfiguration(
229cdf0e10cSrcweir                 mxCurrentConfiguration, "current configuration");
230cdf0e10cSrcweir #endif
231cdf0e10cSrcweir #endif
232cdf0e10cSrcweir         }
233cdf0e10cSrcweir     }
234cdf0e10cSrcweir     catch (RuntimeException e)
235cdf0e10cSrcweir     {
236cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
237cdf0e10cSrcweir     }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>0
240cdf0e10cSrcweir     OSL_TRACE("ConfigurationUpdater::UpdateConfiguration)");
241cdf0e10cSrcweir     OSL_TRACE("UpdateConfiguration end");
242cdf0e10cSrcweir #endif
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 
CleanRequestedConfiguration(void)248cdf0e10cSrcweir void ConfigurationUpdater::CleanRequestedConfiguration (void)
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     if (mxControllerManager.is())
251cdf0e10cSrcweir     {
252cdf0e10cSrcweir         // Request the deactivation of pure anchors that have no child.
253cdf0e10cSrcweir         vector<Reference<XResourceId> > aResourcesToDeactivate;
254cdf0e10cSrcweir         CheckPureAnchors(mxRequestedConfiguration, aResourcesToDeactivate);
255cdf0e10cSrcweir         if (!aResourcesToDeactivate.empty() )
256cdf0e10cSrcweir         {
257cdf0e10cSrcweir             Reference<XConfigurationController> xCC (
258cdf0e10cSrcweir                 mxControllerManager->getConfigurationController());
259cdf0e10cSrcweir             vector<Reference<XResourceId> >::iterator iId;
260cdf0e10cSrcweir             for (iId=aResourcesToDeactivate.begin(); iId!=aResourcesToDeactivate.end(); ++iId)
261cdf0e10cSrcweir                 if (iId->is())
262cdf0e10cSrcweir                     xCC->requestResourceDeactivation(*iId);
263cdf0e10cSrcweir         }
264cdf0e10cSrcweir     }
265cdf0e10cSrcweir }
266cdf0e10cSrcweir 
267cdf0e10cSrcweir 
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 
CheckUpdateSuccess(void)270cdf0e10cSrcweir void ConfigurationUpdater::CheckUpdateSuccess (void)
271cdf0e10cSrcweir {
272cdf0e10cSrcweir     // When the two configurations differ then start the timer to call
273cdf0e10cSrcweir     // another update later.
274cdf0e10cSrcweir     if ( ! AreConfigurationsEquivalent(mxCurrentConfiguration, mxRequestedConfiguration))
275cdf0e10cSrcweir     {
276cdf0e10cSrcweir         if (mnFailedUpdateCount <= snShortTimeoutCountThreshold)
277cdf0e10cSrcweir             maUpdateTimer.SetTimeout(snShortTimeout);
278cdf0e10cSrcweir         else if (mnFailedUpdateCount < snNormalTimeoutCountThreshold)
279cdf0e10cSrcweir             maUpdateTimer.SetTimeout(snNormalTimeout);
280cdf0e10cSrcweir         else
281cdf0e10cSrcweir             maUpdateTimer.SetTimeout(snLongTimeout);
282cdf0e10cSrcweir         ++mnFailedUpdateCount;
283cdf0e10cSrcweir         maUpdateTimer.Start();
284cdf0e10cSrcweir     }
285cdf0e10cSrcweir     else
286cdf0e10cSrcweir     {
287cdf0e10cSrcweir         // Update was successfull.  Reset the failed update count.
288cdf0e10cSrcweir         mnFailedUpdateCount = 0;
289cdf0e10cSrcweir     }
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir 
293cdf0e10cSrcweir 
294cdf0e10cSrcweir 
UpdateCore(const ConfigurationClassifier & rClassifier)295cdf0e10cSrcweir void ConfigurationUpdater::UpdateCore (const ConfigurationClassifier& rClassifier)
296cdf0e10cSrcweir {
297cdf0e10cSrcweir     try
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
300cdf0e10cSrcweir         rClassifier.TraceResourceIdVector(
301cdf0e10cSrcweir             "requested but not current resources:", rClassifier.GetC1minusC2());
302cdf0e10cSrcweir         rClassifier.TraceResourceIdVector(
303cdf0e10cSrcweir             "current but not requested resources:", rClassifier.GetC2minusC1());
304cdf0e10cSrcweir         rClassifier.TraceResourceIdVector(
305cdf0e10cSrcweir             "requested and current resources:", rClassifier.GetC1andC2());
306cdf0e10cSrcweir #endif
307cdf0e10cSrcweir 
308cdf0e10cSrcweir         // Updating of the sub controllers is done in two steps.  In the
309cdf0e10cSrcweir         // first the sub controllers typically shut down resources that are
310cdf0e10cSrcweir         // not requested anymore.  In the second the sub controllers
311cdf0e10cSrcweir         // typically set up resources that have been newly requested.
312cdf0e10cSrcweir         mpResourceManager->DeactivateResources(rClassifier.GetC2minusC1(), mxCurrentConfiguration);
313cdf0e10cSrcweir         mpResourceManager->ActivateResources(rClassifier.GetC1minusC2(), mxCurrentConfiguration);
314cdf0e10cSrcweir 
315cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
316cdf0e10cSrcweir         OSL_TRACE("ConfigurationController::UpdateConfiguration)");
317cdf0e10cSrcweir         ConfigurationTracer::TraceConfiguration(
318cdf0e10cSrcweir             mxRequestedConfiguration, "requested configuration");
319cdf0e10cSrcweir         ConfigurationTracer::TraceConfiguration(
320cdf0e10cSrcweir             mxCurrentConfiguration, "current configuration");
321cdf0e10cSrcweir #endif
322cdf0e10cSrcweir 
323cdf0e10cSrcweir         // Deactivate pure anchors that have no child.
324cdf0e10cSrcweir         vector<Reference<XResourceId> > aResourcesToDeactivate;
325cdf0e10cSrcweir         CheckPureAnchors(mxCurrentConfiguration, aResourcesToDeactivate);
326cdf0e10cSrcweir         if (!aResourcesToDeactivate.empty() )
327cdf0e10cSrcweir             mpResourceManager->DeactivateResources(aResourcesToDeactivate, mxCurrentConfiguration);
328cdf0e10cSrcweir     }
329cdf0e10cSrcweir     catch(RuntimeException)
330cdf0e10cSrcweir     {
331cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 
CheckPureAnchors(const Reference<XConfiguration> & rxConfiguration,vector<Reference<XResourceId>> & rResourcesToDeactivate)338cdf0e10cSrcweir void ConfigurationUpdater::CheckPureAnchors (
339cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration,
340cdf0e10cSrcweir     vector<Reference<XResourceId> >& rResourcesToDeactivate)
341cdf0e10cSrcweir {
342cdf0e10cSrcweir     if ( ! rxConfiguration.is())
343cdf0e10cSrcweir         return;
344cdf0e10cSrcweir 
345cdf0e10cSrcweir     // Get a list of all resources in the configuration.
346cdf0e10cSrcweir     Sequence<Reference<XResourceId> > aResources(
347cdf0e10cSrcweir         rxConfiguration->getResources(
348cdf0e10cSrcweir             NULL, OUString(), AnchorBindingMode_INDIRECT));
349cdf0e10cSrcweir     sal_Int32 nCount (aResources.getLength());
350cdf0e10cSrcweir 
351cdf0e10cSrcweir     // Prepare the list of pure anchors that have to be deactivated.
352cdf0e10cSrcweir     rResourcesToDeactivate.clear();
353cdf0e10cSrcweir 
354cdf0e10cSrcweir     // Iterate over the list in reverse order because when there is a chain
355cdf0e10cSrcweir     // of pure anchors with only the last one having no child then the whole
356cdf0e10cSrcweir     // list has to be deactivated.
357cdf0e10cSrcweir     sal_Int32 nIndex (nCount-1);
358cdf0e10cSrcweir     while (nIndex >= 0)
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         const Reference<XResourceId> xResourceId (aResources[nIndex]);
361cdf0e10cSrcweir         const Reference<XResource> xResource (
362cdf0e10cSrcweir             mpResourceManager->GetResource(xResourceId).mxResource);
363cdf0e10cSrcweir         bool bDeactiveCurrentResource (false);
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         // Skip all resources that are no pure anchors.
366cdf0e10cSrcweir         if (xResource.is() && xResource->isAnchorOnly())
367cdf0e10cSrcweir         {
368cdf0e10cSrcweir             // When xResource is not an anchor of the the next resource in
369cdf0e10cSrcweir             // the list then it is the anchor of no resource at all.
370cdf0e10cSrcweir             if (nIndex == nCount-1)
371cdf0e10cSrcweir             {
372cdf0e10cSrcweir                 // No following anchors, deactivate this one, then remove it
373cdf0e10cSrcweir                 // from the list.
374cdf0e10cSrcweir                 bDeactiveCurrentResource = true;
375cdf0e10cSrcweir             }
376cdf0e10cSrcweir             else
377cdf0e10cSrcweir             {
378cdf0e10cSrcweir                 const Reference<XResourceId> xPrevResourceId (aResources[nIndex+1]);
379cdf0e10cSrcweir                 if ( ! xPrevResourceId.is()
380cdf0e10cSrcweir                     || ! xPrevResourceId->isBoundTo(xResourceId, AnchorBindingMode_DIRECT))
381cdf0e10cSrcweir                 {
382cdf0e10cSrcweir                     // The previous resource (id) does not exist or is not bound to
383cdf0e10cSrcweir                     // the current anchor.
384cdf0e10cSrcweir                     bDeactiveCurrentResource = true;
385cdf0e10cSrcweir                 }
386cdf0e10cSrcweir             }
387cdf0e10cSrcweir         }
388cdf0e10cSrcweir 
389cdf0e10cSrcweir         if (bDeactiveCurrentResource)
390cdf0e10cSrcweir         {
391cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
392cdf0e10cSrcweir             OSL_TRACE("deactiving pure anchor %s because it has no children",
393cdf0e10cSrcweir                 OUStringToOString(
394cdf0e10cSrcweir                     FrameworkHelper::ResourceIdToString(xResourceId),
395cdf0e10cSrcweir                     RTL_TEXTENCODING_UTF8).getStr());
396cdf0e10cSrcweir #endif
397cdf0e10cSrcweir             // Erase element from current configuration.
398cdf0e10cSrcweir             for (sal_Int32 nI=nIndex; nI<nCount-2; ++nI)
399cdf0e10cSrcweir                 aResources[nI] = aResources[nI+1];
400cdf0e10cSrcweir             nCount -= 1;
401cdf0e10cSrcweir 
402cdf0e10cSrcweir             rResourcesToDeactivate.push_back(xResourceId);
403cdf0e10cSrcweir         }
404cdf0e10cSrcweir         nIndex -= 1;
405cdf0e10cSrcweir     }
406cdf0e10cSrcweir }
407cdf0e10cSrcweir 
408cdf0e10cSrcweir 
409cdf0e10cSrcweir 
410cdf0e10cSrcweir 
LockUpdates(void)411cdf0e10cSrcweir void ConfigurationUpdater::LockUpdates (void)
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     ++mnLockCount;
414cdf0e10cSrcweir }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 
UnlockUpdates(void)419cdf0e10cSrcweir void ConfigurationUpdater::UnlockUpdates (void)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir     --mnLockCount;
422cdf0e10cSrcweir     if (mnLockCount == 0 && mbUpdatePending)
423cdf0e10cSrcweir     {
424cdf0e10cSrcweir         RequestUpdate(mxRequestedConfiguration);
425cdf0e10cSrcweir     }
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 
GetLock(void)431cdf0e10cSrcweir ::boost::shared_ptr<ConfigurationUpdaterLock> ConfigurationUpdater::GetLock (void)
432cdf0e10cSrcweir {
433cdf0e10cSrcweir     return ::boost::shared_ptr<ConfigurationUpdaterLock>(new ConfigurationUpdaterLock(*this));
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 
SetUpdateBeingProcessed(bool bValue)439cdf0e10cSrcweir void ConfigurationUpdater::SetUpdateBeingProcessed (bool bValue)
440cdf0e10cSrcweir {
441cdf0e10cSrcweir     mbUpdateBeingProcessed = bValue;
442cdf0e10cSrcweir }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir 
445cdf0e10cSrcweir 
446cdf0e10cSrcweir 
IMPL_LINK(ConfigurationUpdater,TimeoutHandler,Timer *,EMPTYARG)447cdf0e10cSrcweir IMPL_LINK(ConfigurationUpdater, TimeoutHandler, Timer*, EMPTYARG)
448cdf0e10cSrcweir {
449cdf0e10cSrcweir     OSL_TRACE("configuration update timer");
450cdf0e10cSrcweir     if ( ! mbUpdateBeingProcessed
451cdf0e10cSrcweir         && mxCurrentConfiguration.is()
452cdf0e10cSrcweir         && mxRequestedConfiguration.is())
453cdf0e10cSrcweir     {
454cdf0e10cSrcweir         if ( ! AreConfigurationsEquivalent(mxCurrentConfiguration, mxRequestedConfiguration))
455cdf0e10cSrcweir         {
456cdf0e10cSrcweir             OSL_TRACE("configurations differ, requesting update");
457cdf0e10cSrcweir             RequestUpdate(mxRequestedConfiguration);
458cdf0e10cSrcweir         }
459cdf0e10cSrcweir     }
460cdf0e10cSrcweir     return 0;
461cdf0e10cSrcweir }
462cdf0e10cSrcweir 
463cdf0e10cSrcweir 
464cdf0e10cSrcweir } } // end of namespace sd::framework
465