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