Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "framework/ModuleController.hxx"
22 :
23 : #include "tools/ConfigurationAccess.hxx"
24 : #include <comphelper/processfactory.hxx>
25 : #include <comphelper/stl_types.hxx>
26 : #include <boost/bind.hpp>
27 : #include <boost/unordered_map.hpp>
28 :
29 : #include <tools/diagnose_ex.h>
30 :
31 : using namespace ::com::sun::star;
32 : using namespace ::com::sun::star::uno;
33 : using namespace ::com::sun::star::drawing::framework;
34 : using ::rtl::OUString;
35 : using ::sd::tools::ConfigurationAccess;
36 :
37 : namespace sd { namespace framework {
38 :
39 : static const sal_uInt32 snFactoryPropertyCount (2);
40 : static const sal_uInt32 snStartupPropertyCount (1);
41 :
42 :
43 :
44 :
45 0 : class ModuleController::ResourceToFactoryMap
46 : : public ::boost::unordered_map<
47 : rtl::OUString,
48 : rtl::OUString,
49 : ::rtl::OUStringHash,
50 : ::comphelper::UStringEqual>
51 : {
52 : public:
53 0 : ResourceToFactoryMap (void) {}
54 : };
55 :
56 :
57 0 : class ModuleController::LoadedFactoryContainer
58 : : public ::boost::unordered_map<
59 : rtl::OUString,
60 : WeakReference<XInterface>,
61 : ::rtl::OUStringHash,
62 : ::comphelper::UStringEqual>
63 : {
64 : public:
65 0 : LoadedFactoryContainer (void) {}
66 : };
67 :
68 :
69 :
70 :
71 :
72 0 : Reference<XInterface> SAL_CALL ModuleController_createInstance (
73 : const Reference<XComponentContext>& rxContext)
74 : {
75 0 : return Reference<XInterface>(ModuleController::CreateInstance(rxContext), UNO_QUERY);
76 : }
77 :
78 :
79 :
80 :
81 2 : ::rtl::OUString ModuleController_getImplementationName (void) throw(RuntimeException)
82 : {
83 2 : return ::rtl::OUString("com.sun.star.comp.Draw.framework.module.ModuleController");
84 : }
85 :
86 :
87 :
88 :
89 0 : Sequence<rtl::OUString> SAL_CALL ModuleController_getSupportedServiceNames (void)
90 : throw (RuntimeException)
91 : {
92 0 : static const ::rtl::OUString sServiceName("com.sun.star.drawing.framework.ModuleController");
93 0 : return Sequence<rtl::OUString>(&sServiceName, 1);
94 : }
95 :
96 :
97 :
98 :
99 : //===== ModuleController ======================================================
100 :
101 0 : Reference<XModuleController> ModuleController::CreateInstance (
102 : const Reference<XComponentContext>& rxContext)
103 : {
104 0 : return new ModuleController(rxContext);
105 : }
106 :
107 :
108 :
109 :
110 0 : ModuleController::ModuleController (const Reference<XComponentContext>& rxContext) throw()
111 : : ModuleControllerInterfaceBase(MutexOwner::maMutex),
112 : mxController(),
113 0 : mpResourceToFactoryMap(new ResourceToFactoryMap()),
114 0 : mpLoadedFactories(new LoadedFactoryContainer())
115 : {
116 : (void)rxContext;
117 0 : LoadFactories(rxContext);
118 0 : }
119 :
120 :
121 :
122 :
123 0 : ModuleController::~ModuleController (void) throw()
124 : {
125 0 : }
126 :
127 :
128 :
129 :
130 0 : void SAL_CALL ModuleController::disposing (void)
131 : {
132 : // Break the cyclic reference back to DrawController object
133 0 : mpLoadedFactories.reset();
134 0 : mpResourceToFactoryMap.reset();
135 0 : mxController.clear();
136 0 : }
137 :
138 :
139 :
140 :
141 0 : void ModuleController::LoadFactories (const Reference<XComponentContext>& rxContext)
142 : {
143 : try
144 : {
145 : ConfigurationAccess aConfiguration (
146 : rxContext,
147 : "/org.openoffice.Office.Impress/",
148 0 : ConfigurationAccess::READ_ONLY);
149 : Reference<container::XNameAccess> xFactories (
150 : aConfiguration.GetConfigurationNode("MultiPaneGUI/Framework/ResourceFactories"),
151 0 : UNO_QUERY);
152 0 : ::std::vector<rtl::OUString> aProperties (snFactoryPropertyCount);
153 0 : aProperties[0] = "ServiceName";
154 0 : aProperties[1] = "ResourceList";
155 : ConfigurationAccess::ForAll(
156 : xFactories,
157 : aProperties,
158 0 : ::boost::bind(&ModuleController::ProcessFactory, this, _2));
159 : }
160 0 : catch (Exception&)
161 : {
162 : DBG_UNHANDLED_EXCEPTION();
163 : }
164 0 : }
165 :
166 :
167 :
168 :
169 0 : void ModuleController::ProcessFactory (const ::std::vector<Any>& rValues)
170 : {
171 : OSL_ASSERT(rValues.size() == snFactoryPropertyCount);
172 :
173 : // Get the service name of the factory.
174 0 : rtl::OUString sServiceName;
175 0 : rValues[0] >>= sServiceName;
176 :
177 : // Get all resource URLs that are created by the factory.
178 0 : Reference<container::XNameAccess> xResources (rValues[1], UNO_QUERY);
179 0 : ::std::vector<rtl::OUString> aURLs;
180 : tools::ConfigurationAccess::FillList(
181 : xResources,
182 : "URL",
183 0 : aURLs);
184 :
185 : SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": ModuleController::adding factory " <<
186 : OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr());
187 :
188 : // Add the resource URLs to the map.
189 0 : ::std::vector<rtl::OUString>::const_iterator iResource;
190 0 : for (iResource=aURLs.begin(); iResource!=aURLs.end(); ++iResource)
191 : {
192 0 : (*mpResourceToFactoryMap)[*iResource] = sServiceName;
193 : SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": " <<
194 : OUStringToOString(*iResource, RTL_TEXTENCODING_UTF8).getStr());
195 0 : }
196 0 : }
197 :
198 :
199 :
200 :
201 0 : void ModuleController::InstantiateStartupServices (void)
202 : {
203 : try
204 : {
205 : tools::ConfigurationAccess aConfiguration (
206 : "/org.openoffice.Office.Impress/",
207 0 : tools::ConfigurationAccess::READ_ONLY);
208 : Reference<container::XNameAccess> xFactories (
209 : aConfiguration.GetConfigurationNode("MultiPaneGUI/Framework/StartupServices"),
210 0 : UNO_QUERY);
211 0 : ::std::vector<rtl::OUString> aProperties (snStartupPropertyCount);
212 0 : aProperties[0] = "ServiceName";
213 : tools::ConfigurationAccess::ForAll(
214 : xFactories,
215 : aProperties,
216 0 : ::boost::bind(&ModuleController::ProcessStartupService, this, _2));
217 : }
218 0 : catch (Exception&)
219 : {
220 : OSL_TRACE("ERROR in ModuleController::InstantiateStartupServices");
221 : }
222 0 : }
223 :
224 :
225 :
226 :
227 0 : void ModuleController::ProcessStartupService (const ::std::vector<Any>& rValues)
228 : {
229 : OSL_ASSERT(rValues.size() == snStartupPropertyCount);
230 :
231 : try
232 : {
233 : // Get the service name of the startup service.
234 0 : rtl::OUString sServiceName;
235 0 : rValues[0] >>= sServiceName;
236 :
237 : // Instantiate service.
238 : Reference<lang::XMultiServiceFactory> xGlobalFactory (
239 0 : ::comphelper::getProcessServiceFactory(), UNO_QUERY);
240 0 : if (xGlobalFactory.is())
241 : {
242 : // Create the startup service.
243 0 : Sequence<Any> aArguments(1);
244 0 : aArguments[0] <<= mxController;
245 : // Note that when the new object will be destroyed at the end of
246 : // this scope when it does not register itself anywhere.
247 : // Typically it will add itself as ConfigurationChangeListener
248 : // at the configuration controller.
249 0 : xGlobalFactory->createInstanceWithArguments(sServiceName, aArguments);
250 :
251 : SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": ModuleController::created startup service " <<
252 0 : OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr());
253 0 : }
254 : }
255 0 : catch (Exception&)
256 : {
257 : OSL_TRACE("ERROR in ModuleController::ProcessStartupServices");
258 : }
259 0 : }
260 :
261 :
262 :
263 :
264 : //----- XModuleController -----------------------------------------------------
265 :
266 0 : void SAL_CALL ModuleController::requestResource (const OUString& rsResourceURL)
267 : throw (RuntimeException)
268 : {
269 0 : ResourceToFactoryMap::const_iterator iFactory (mpResourceToFactoryMap->find(rsResourceURL));
270 0 : if (iFactory != mpResourceToFactoryMap->end())
271 : {
272 : // Check that the factory has already been loaded and not been
273 : // destroyed in the meantime.
274 0 : Reference<XInterface> xFactory;
275 : LoadedFactoryContainer::const_iterator iLoadedFactory (
276 0 : mpLoadedFactories->find(iFactory->second));
277 0 : if (iLoadedFactory != mpLoadedFactories->end())
278 0 : xFactory = Reference<XInterface>(iLoadedFactory->second, UNO_QUERY);
279 0 : if ( ! xFactory.is())
280 : {
281 : // Create a new instance of the factory.
282 : Reference<lang::XMultiServiceFactory> xGlobalFactory (
283 0 : ::comphelper::getProcessServiceFactory(), UNO_QUERY);
284 0 : if (xGlobalFactory.is())
285 : {
286 : // Create the factory service.
287 0 : Sequence<Any> aArguments(1);
288 0 : aArguments[0] <<= mxController;
289 0 : xFactory = xGlobalFactory->createInstanceWithArguments(
290 0 : iFactory->second,
291 0 : aArguments);
292 :
293 : // Remember that this factory has been instanced.
294 0 : (*mpLoadedFactories)[iFactory->second] = xFactory;
295 0 : }
296 0 : }
297 : }
298 0 : }
299 :
300 :
301 :
302 :
303 : //----- XInitialization -------------------------------------------------------
304 :
305 0 : void SAL_CALL ModuleController::initialize (const Sequence<Any>& aArguments)
306 : throw (Exception, RuntimeException)
307 : {
308 0 : if (aArguments.getLength() > 0)
309 : {
310 : try
311 : {
312 : // Get the XController from the first argument.
313 0 : mxController = Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW);
314 :
315 0 : InstantiateStartupServices();
316 : }
317 0 : catch (RuntimeException&)
318 : {}
319 : }
320 0 : }
321 :
322 :
323 9 : } } // end of namespace sd::framework
324 :
325 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|