15b190011SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
35b190011SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
45b190011SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
55b190011SAndrew Rist  * distributed with this work for additional information
65b190011SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
75b190011SAndrew Rist  * to you under the Apache License, Version 2.0 (the
85b190011SAndrew Rist  * "License"); you may not use this file except in compliance
95b190011SAndrew Rist  * with the License.  You may obtain a copy of the License at
105b190011SAndrew Rist  *
115b190011SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
125b190011SAndrew Rist  *
135b190011SAndrew Rist  * Unless required by applicable law or agreed to in writing,
145b190011SAndrew Rist  * software distributed under the License is distributed on an
155b190011SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
165b190011SAndrew Rist  * KIND, either express or implied.  See the License for the
175b190011SAndrew Rist  * specific language governing permissions and limitations
185b190011SAndrew Rist  * under the License.
195b190011SAndrew Rist  *
205b190011SAndrew Rist  *************************************************************/
215b190011SAndrew Rist 
225b190011SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_sd.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "ConfigurationControllerResourceManager.hxx"
27cdf0e10cSrcweir #include "ConfigurationControllerBroadcaster.hxx"
28cdf0e10cSrcweir #include "ResourceFactoryManager.hxx"
29cdf0e10cSrcweir #include "framework/FrameworkHelper.hxx"
30cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
31cdf0e10cSrcweir #include <tools/diagnose_ex.h>
32cdf0e10cSrcweir #include <algorithm>
33cdf0e10cSrcweir #include <boost/bind.hpp>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir using namespace ::com::sun::star;
36cdf0e10cSrcweir using namespace ::com::sun::star::uno;
37cdf0e10cSrcweir using namespace ::com::sun::star::drawing::framework;
38cdf0e10cSrcweir using ::rtl::OUString;
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #undef VERBOSE
41cdf0e10cSrcweir //#define VERBOSE 1
42cdf0e10cSrcweir 
43cdf0e10cSrcweir namespace sd { namespace framework {
44cdf0e10cSrcweir 
45cdf0e10cSrcweir //===== ConfigurationControllerResourceManager ================================
46cdf0e10cSrcweir 
ConfigurationControllerResourceManager(const::boost::shared_ptr<ResourceFactoryManager> & rpResourceFactoryContainer,const::boost::shared_ptr<ConfigurationControllerBroadcaster> & rpBroadcaster)47cdf0e10cSrcweir ConfigurationControllerResourceManager::ConfigurationControllerResourceManager (
48cdf0e10cSrcweir     const ::boost::shared_ptr<ResourceFactoryManager>& rpResourceFactoryContainer,
49cdf0e10cSrcweir     const ::boost::shared_ptr<ConfigurationControllerBroadcaster>& rpBroadcaster)
50cdf0e10cSrcweir     : maResourceMap(ResourceComparator()),
51cdf0e10cSrcweir       mpResourceFactoryContainer(rpResourceFactoryContainer),
52cdf0e10cSrcweir       mpBroadcaster(rpBroadcaster)
53cdf0e10cSrcweir {
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 
~ConfigurationControllerResourceManager(void)59cdf0e10cSrcweir ConfigurationControllerResourceManager::~ConfigurationControllerResourceManager (void)
60cdf0e10cSrcweir {
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir 
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 
66cdf0e10cSrcweir ConfigurationControllerResourceManager::ResourceDescriptor
GetResource(const Reference<XResourceId> & rxResourceId)67cdf0e10cSrcweir     ConfigurationControllerResourceManager::GetResource (
68cdf0e10cSrcweir         const Reference<XResourceId>& rxResourceId)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
71cdf0e10cSrcweir     ResourceMap::const_iterator iResource (maResourceMap.find(rxResourceId));
72cdf0e10cSrcweir     if (iResource != maResourceMap.end())
73cdf0e10cSrcweir         return iResource->second;
74cdf0e10cSrcweir     else
75cdf0e10cSrcweir         return ResourceDescriptor();
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 
ActivateResources(const::std::vector<Reference<XResourceId>> & rResources,const Reference<XConfiguration> & rxConfiguration)81cdf0e10cSrcweir void ConfigurationControllerResourceManager::ActivateResources (
82cdf0e10cSrcweir     const ::std::vector<Reference<XResourceId> >& rResources,
83cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration)
84cdf0e10cSrcweir {
85cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
86cdf0e10cSrcweir     // Iterate in normal order over the resources that are to be
87cdf0e10cSrcweir     // activated so that resources on which others depend are activated
88cdf0e10cSrcweir     // beforet the depending resources are activated.
89cdf0e10cSrcweir     ::std::for_each(
90cdf0e10cSrcweir         rResources.begin(),
91cdf0e10cSrcweir         rResources.end(),
92cdf0e10cSrcweir         ::boost::bind(&ConfigurationControllerResourceManager::ActivateResource,
93cdf0e10cSrcweir             this, _1, rxConfiguration));
94cdf0e10cSrcweir }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 
DeactivateResources(const::std::vector<Reference<XResourceId>> & rResources,const Reference<XConfiguration> & rxConfiguration)99cdf0e10cSrcweir void ConfigurationControllerResourceManager::DeactivateResources (
100cdf0e10cSrcweir     const ::std::vector<Reference<XResourceId> >& rResources,
101cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration)
102cdf0e10cSrcweir {
103cdf0e10cSrcweir     ::osl::MutexGuard aGuard (maMutex);
104cdf0e10cSrcweir     // Iterate in reverese order over the resources that are to be
105cdf0e10cSrcweir     // deactivated so that resources on which others depend are deactivated
106cdf0e10cSrcweir     // only when the depending resources have already been deactivated.
107cdf0e10cSrcweir     ::std::for_each(
108cdf0e10cSrcweir         rResources.rbegin(),
109cdf0e10cSrcweir         rResources.rend(),
110cdf0e10cSrcweir         ::boost::bind(&ConfigurationControllerResourceManager::DeactivateResource,
111cdf0e10cSrcweir             this, _1, rxConfiguration));
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 
117cdf0e10cSrcweir /* In this method we do following steps.
118cdf0e10cSrcweir     1. Get the factory with which the resource will be created.
119cdf0e10cSrcweir     2. Create the resource.
120cdf0e10cSrcweir     3. Add the resource to the URL->Object map of the configuration
121cdf0e10cSrcweir     controller.
122cdf0e10cSrcweir     4. Add the resource id to the current configuration.
123cdf0e10cSrcweir     5. Notify listeners.
124cdf0e10cSrcweir */
ActivateResource(const Reference<XResourceId> & rxResourceId,const Reference<XConfiguration> & rxConfiguration)125cdf0e10cSrcweir void ConfigurationControllerResourceManager::ActivateResource (
126cdf0e10cSrcweir     const Reference<XResourceId>& rxResourceId,
127cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration)
128cdf0e10cSrcweir {
129cdf0e10cSrcweir    if ( ! rxResourceId.is())
130cdf0e10cSrcweir    {
131cdf0e10cSrcweir        OSL_ASSERT(rxResourceId.is());
132cdf0e10cSrcweir        return;
133cdf0e10cSrcweir    }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
136cdf0e10cSrcweir     OSL_TRACE("activating resource %s\n", OUStringToOString(
137cdf0e10cSrcweir         FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
138cdf0e10cSrcweir #endif
139cdf0e10cSrcweir 
140cdf0e10cSrcweir     // 1. Get the factory.
141cdf0e10cSrcweir     const OUString sResourceURL (rxResourceId->getResourceURL());
142cdf0e10cSrcweir     Reference<XResourceFactory> xFactory (mpResourceFactoryContainer->GetFactory(sResourceURL));
143cdf0e10cSrcweir     if ( ! xFactory.is())
144cdf0e10cSrcweir     {
145cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
146*7a32b0c8SAndre Fischer         OSL_TRACE("    no factory found for %s\n",
147cdf0e10cSrcweir             OUStringToOString(sResourceURL, RTL_TEXTENCODING_UTF8).getStr());
148cdf0e10cSrcweir #endif
149cdf0e10cSrcweir         return;
150cdf0e10cSrcweir     }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir     try
153cdf0e10cSrcweir     {
154cdf0e10cSrcweir         // 2. Create the resource.
155cdf0e10cSrcweir         Reference<XResource> xResource;
156cdf0e10cSrcweir         try
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             xResource = xFactory->createResource(rxResourceId);
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir         catch (lang::DisposedException&)
161cdf0e10cSrcweir         {
162cdf0e10cSrcweir             // The factory is disposed and can be removed from the list
163cdf0e10cSrcweir             // of registered factories.
164cdf0e10cSrcweir             mpResourceFactoryContainer->RemoveFactoryForReference(xFactory);
165cdf0e10cSrcweir         }
166*7a32b0c8SAndre Fischer         catch (Exception& e)
167cdf0e10cSrcweir         {
168*7a32b0c8SAndre Fischer             (void)e;
169cdf0e10cSrcweir         }
170cdf0e10cSrcweir 
171cdf0e10cSrcweir         if (xResource.is())
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
174cdf0e10cSrcweir             OSL_TRACE("    successfully created\n");
175cdf0e10cSrcweir #endif
176cdf0e10cSrcweir             // 3. Add resource to URL->Object map.
177cdf0e10cSrcweir             AddResource(xResource, xFactory);
178cdf0e10cSrcweir 
179cdf0e10cSrcweir             // 4. Add resource id to current configuration.
180cdf0e10cSrcweir             rxConfiguration->addResource(rxResourceId);
181cdf0e10cSrcweir 
182cdf0e10cSrcweir             // 5. Notify the new resource to listeners of the ConfigurationController.
183cdf0e10cSrcweir             mpBroadcaster->NotifyListeners(
184cdf0e10cSrcweir                 FrameworkHelper::msResourceActivationEvent,
185cdf0e10cSrcweir                 rxResourceId,
186cdf0e10cSrcweir                 xResource);
187cdf0e10cSrcweir         }
188cdf0e10cSrcweir         else
189cdf0e10cSrcweir         {
190cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
191cdf0e10cSrcweir             OSL_TRACE("    resource creation failed\n");
192cdf0e10cSrcweir #endif
193cdf0e10cSrcweir         }
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir     catch (RuntimeException&)
196cdf0e10cSrcweir     {
197cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 
203cdf0e10cSrcweir 
204cdf0e10cSrcweir /* In this method we do following steps.
205cdf0e10cSrcweir     1. Remove the resource from the URL->Object map of the configuration
206cdf0e10cSrcweir     controller.
207*7a32b0c8SAndre Fischer     2. Notify listeners that deactivation has started.
208cdf0e10cSrcweir     3. Remove the resource id from the current configuration.
209cdf0e10cSrcweir     4. Release the resource.
210*7a32b0c8SAndre Fischer     5. Notify listeners about that deactivation is completed.
211cdf0e10cSrcweir */
DeactivateResource(const Reference<XResourceId> & rxResourceId,const Reference<XConfiguration> & rxConfiguration)212cdf0e10cSrcweir void ConfigurationControllerResourceManager::DeactivateResource (
213cdf0e10cSrcweir     const Reference<XResourceId>& rxResourceId,
214cdf0e10cSrcweir     const Reference<XConfiguration>& rxConfiguration)
215cdf0e10cSrcweir {
216cdf0e10cSrcweir     if ( ! rxResourceId.is())
217cdf0e10cSrcweir         return;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir     bool bSuccess (false);
220cdf0e10cSrcweir     try
221cdf0e10cSrcweir     {
222cdf0e10cSrcweir         // 1. Remove resource from URL->Object map.
223cdf0e10cSrcweir         ResourceDescriptor aDescriptor (RemoveResource(rxResourceId));
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         if (aDescriptor.mxResource.is() && aDescriptor.mxResourceFactory.is())
226cdf0e10cSrcweir         {
227cdf0e10cSrcweir             // 2.  Notifiy listeners that the resource is being deactivated.
228cdf0e10cSrcweir             mpBroadcaster->NotifyListeners(
229cdf0e10cSrcweir                 FrameworkHelper::msResourceDeactivationEvent,
230cdf0e10cSrcweir                 rxResourceId,
231cdf0e10cSrcweir                 aDescriptor.mxResource);
232cdf0e10cSrcweir 
233cdf0e10cSrcweir             // 3. Remove resource id from current configuration.
234cdf0e10cSrcweir             rxConfiguration->removeResource(rxResourceId);
235cdf0e10cSrcweir 
236cdf0e10cSrcweir             // 4. Release the resource.
237cdf0e10cSrcweir             try
238cdf0e10cSrcweir             {
239cdf0e10cSrcweir                 aDescriptor.mxResourceFactory->releaseResource(aDescriptor.mxResource);
240cdf0e10cSrcweir             }
241cdf0e10cSrcweir             catch (lang::DisposedException& rException)
242cdf0e10cSrcweir             {
243cdf0e10cSrcweir                 if ( ! rException.Context.is()
244cdf0e10cSrcweir                     || rException.Context == aDescriptor.mxResourceFactory)
245cdf0e10cSrcweir                 {
246cdf0e10cSrcweir                     // The factory is disposed and can be removed from the
247cdf0e10cSrcweir                     // list of registered factories.
248cdf0e10cSrcweir                     mpResourceFactoryContainer->RemoveFactoryForReference(
249cdf0e10cSrcweir                         aDescriptor.mxResourceFactory);
250cdf0e10cSrcweir                 }
251cdf0e10cSrcweir             }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir             bSuccess = true;
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir     }
256cdf0e10cSrcweir     catch (RuntimeException&)
257cdf0e10cSrcweir     {
258cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
259cdf0e10cSrcweir     }
260*7a32b0c8SAndre Fischer 
261*7a32b0c8SAndre Fischer     // 5.  Notifiy listeners that the resource is being deactivated.
262*7a32b0c8SAndre Fischer     mpBroadcaster->NotifyListeners(
263*7a32b0c8SAndre Fischer         FrameworkHelper::msResourceDeactivationEndEvent,
264*7a32b0c8SAndre Fischer         rxResourceId,
265*7a32b0c8SAndre Fischer         NULL);
266cdf0e10cSrcweir 
267cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=1
268cdf0e10cSrcweir     if (bSuccess)
269cdf0e10cSrcweir         OSL_TRACE("successfully deactivated %s\n", OUStringToOString(
270cdf0e10cSrcweir             FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
271cdf0e10cSrcweir     else
272cdf0e10cSrcweir         OSL_TRACE("activating resource %s failed\n", OUStringToOString(
273cdf0e10cSrcweir             FrameworkHelper::ResourceIdToString(rxResourceId), RTL_TEXTENCODING_UTF8).getStr());
274cdf0e10cSrcweir #endif
275cdf0e10cSrcweir }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 
AddResource(const Reference<XResource> & rxResource,const Reference<XResourceFactory> & rxFactory)280cdf0e10cSrcweir void ConfigurationControllerResourceManager::AddResource (
281cdf0e10cSrcweir     const Reference<XResource>& rxResource,
282cdf0e10cSrcweir     const Reference<XResourceFactory>& rxFactory)
283cdf0e10cSrcweir {
284cdf0e10cSrcweir     if ( ! rxResource.is())
285cdf0e10cSrcweir     {
286cdf0e10cSrcweir         OSL_ASSERT(rxResource.is());
287cdf0e10cSrcweir         return;
288cdf0e10cSrcweir     }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir     // Add the resource to the resource container.
291cdf0e10cSrcweir     ResourceDescriptor aDescriptor;
292cdf0e10cSrcweir     aDescriptor.mxResource = rxResource;
293cdf0e10cSrcweir     aDescriptor.mxResourceFactory = rxFactory;
294cdf0e10cSrcweir     maResourceMap[rxResource->getResourceId()] = aDescriptor;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
297cdf0e10cSrcweir     OSL_TRACE("ConfigurationControllerResourceManager::AddResource(): added %s -> %x\n",
298cdf0e10cSrcweir         OUStringToOString(
299cdf0e10cSrcweir             FrameworkHelper::ResourceIdToString(rxResource->getResourceId()),
300cdf0e10cSrcweir             RTL_TEXTENCODING_UTF8).getStr(),
301cdf0e10cSrcweir         rxResource.get());
302cdf0e10cSrcweir #endif
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 
307cdf0e10cSrcweir 
308cdf0e10cSrcweir ConfigurationControllerResourceManager::ResourceDescriptor
RemoveResource(const Reference<XResourceId> & rxResourceId)309cdf0e10cSrcweir     ConfigurationControllerResourceManager::RemoveResource (
310cdf0e10cSrcweir         const Reference<XResourceId>& rxResourceId)
311cdf0e10cSrcweir {
312cdf0e10cSrcweir     ResourceDescriptor aDescriptor;
313cdf0e10cSrcweir 
314cdf0e10cSrcweir     ResourceMap::iterator iResource (maResourceMap.find(rxResourceId));
315cdf0e10cSrcweir     if (iResource != maResourceMap.end())
316cdf0e10cSrcweir     {
317cdf0e10cSrcweir #if defined VERBOSE && VERBOSE>=2
318cdf0e10cSrcweir         OSL_TRACE("ConfigurationControllerResourceManager::RemoveResource(): removing %s -> %x\n",
319cdf0e10cSrcweir             OUStringToOString(
320cdf0e10cSrcweir                 FrameworkHelper::ResourceIdToString(rxResourceId),
321cdf0e10cSrcweir                 RTL_TEXTENCODING_UTF8).getStr(),
322cdf0e10cSrcweir             *iResource);
323cdf0e10cSrcweir #endif
324cdf0e10cSrcweir 
325cdf0e10cSrcweir         aDescriptor = iResource->second;
326cdf0e10cSrcweir         maResourceMap.erase(rxResourceId);
327cdf0e10cSrcweir     }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir     return aDescriptor;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 
335cdf0e10cSrcweir //===== ConfigurationControllerResourceManager::ResourceComparator ============
336cdf0e10cSrcweir 
operator ()(const Reference<XResourceId> & rxId1,const Reference<XResourceId> & rxId2) const337cdf0e10cSrcweir bool ConfigurationControllerResourceManager::ResourceComparator::operator() (
338cdf0e10cSrcweir     const Reference<XResourceId>& rxId1,
339cdf0e10cSrcweir     const Reference<XResourceId>& rxId2) const
340cdf0e10cSrcweir {
341cdf0e10cSrcweir     if (rxId1.is() && rxId2.is())
342cdf0e10cSrcweir         return rxId1->compareTo(rxId2)<0;
343cdf0e10cSrcweir     else if (rxId1.is())
344cdf0e10cSrcweir         return true;
345cdf0e10cSrcweir     else if (rxId2.is())
346cdf0e10cSrcweir         return false;
347cdf0e10cSrcweir     else
348cdf0e10cSrcweir         return false;
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 
352cdf0e10cSrcweir 
353cdf0e10cSrcweir 
354cdf0e10cSrcweir } } // end of namespace sd::framework
355cdf0e10cSrcweir 
356