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 : #include "framework/ModuleController.hxx"
21 :
22 : #include "tools/ConfigurationAccess.hxx"
23 : #include <comphelper/processfactory.hxx>
24 : #include <boost/bind.hpp>
25 : #include <boost/unordered_map.hpp>
26 :
27 : #include <tools/diagnose_ex.h>
28 :
29 : #include <facreg.hxx>
30 :
31 : using namespace ::com::sun::star;
32 : using namespace ::com::sun::star::uno;
33 : using namespace ::com::sun::star::drawing::framework;
34 : using ::sd::tools::ConfigurationAccess;
35 :
36 : namespace sd { namespace framework {
37 :
38 : static const sal_uInt32 snFactoryPropertyCount (2);
39 : static const sal_uInt32 snStartupPropertyCount (1);
40 :
41 212 : class ModuleController::ResourceToFactoryMap
42 : : public ::boost::unordered_map<
43 : OUString,
44 : OUString,
45 : OUStringHash>
46 : {
47 : public:
48 212 : ResourceToFactoryMap (void) {}
49 : };
50 :
51 212 : class ModuleController::LoadedFactoryContainer
52 : : public ::boost::unordered_map<
53 : OUString,
54 : WeakReference<XInterface>,
55 : OUStringHash>
56 : {
57 : public:
58 212 : LoadedFactoryContainer (void) {}
59 : };
60 :
61 212 : Reference<XInterface> SAL_CALL ModuleController_createInstance (
62 : const Reference<XComponentContext>& rxContext)
63 : throw (css::uno::Exception, std::exception)
64 : {
65 212 : return Reference<XInterface>(ModuleController::CreateInstance(rxContext), UNO_QUERY);
66 : }
67 :
68 56 : OUString ModuleController_getImplementationName (void) throw(RuntimeException)
69 : {
70 56 : return OUString("com.sun.star.comp.Draw.framework.module.ModuleController");
71 : }
72 :
73 22 : Sequence<OUString> SAL_CALL ModuleController_getSupportedServiceNames (void)
74 : throw (RuntimeException)
75 : {
76 22 : static const OUString sServiceName("com.sun.star.drawing.framework.ModuleController");
77 22 : return Sequence<OUString>(&sServiceName, 1);
78 : }
79 :
80 : //===== ModuleController ======================================================
81 212 : Reference<XModuleController> ModuleController::CreateInstance (
82 : const Reference<XComponentContext>& rxContext)
83 : {
84 212 : return new ModuleController(rxContext);
85 : }
86 :
87 212 : ModuleController::ModuleController (const Reference<XComponentContext>& rxContext)
88 : throw (std::exception)
89 : : ModuleControllerInterfaceBase(MutexOwner::maMutex),
90 : mxController(),
91 0 : mpResourceToFactoryMap(new ResourceToFactoryMap()),
92 212 : mpLoadedFactories(new LoadedFactoryContainer())
93 : {
94 : (void)rxContext;
95 212 : LoadFactories(rxContext);
96 212 : }
97 :
98 284 : ModuleController::~ModuleController (void) throw()
99 : {
100 284 : }
101 :
102 212 : void SAL_CALL ModuleController::disposing (void)
103 : {
104 : // Break the cyclic reference back to DrawController object
105 212 : mpLoadedFactories.reset();
106 212 : mpResourceToFactoryMap.reset();
107 212 : mxController.clear();
108 212 : }
109 :
110 212 : void ModuleController::LoadFactories (const Reference<XComponentContext>& rxContext)
111 : {
112 : try
113 : {
114 : ConfigurationAccess aConfiguration (
115 : rxContext,
116 : "/org.openoffice.Office.Impress/",
117 212 : ConfigurationAccess::READ_ONLY);
118 : Reference<container::XNameAccess> xFactories (
119 : aConfiguration.GetConfigurationNode("MultiPaneGUI/Framework/ResourceFactories"),
120 424 : UNO_QUERY);
121 424 : ::std::vector<OUString> aProperties (snFactoryPropertyCount);
122 212 : aProperties[0] = "ServiceName";
123 212 : aProperties[1] = "ResourceList";
124 : ConfigurationAccess::ForAll(
125 : xFactories,
126 : aProperties,
127 424 : ::boost::bind(&ModuleController::ProcessFactory, this, _2));
128 : }
129 0 : catch (Exception&)
130 : {
131 : DBG_UNHANDLED_EXCEPTION();
132 : }
133 212 : }
134 :
135 848 : void ModuleController::ProcessFactory (const ::std::vector<Any>& rValues)
136 : {
137 : OSL_ASSERT(rValues.size() == snFactoryPropertyCount);
138 :
139 : // Get the service name of the factory.
140 848 : OUString sServiceName;
141 848 : rValues[0] >>= sServiceName;
142 :
143 : // Get all resource URLs that are created by the factory.
144 1696 : Reference<container::XNameAccess> xResources (rValues[1], UNO_QUERY);
145 1696 : ::std::vector<OUString> aURLs;
146 : tools::ConfigurationAccess::FillList(
147 : xResources,
148 : "URL",
149 848 : aURLs);
150 :
151 : SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": ModuleController::adding factory " <<
152 : OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr());
153 :
154 : // Add the resource URLs to the map.
155 848 : ::std::vector<OUString>::const_iterator iResource;
156 4664 : for (iResource=aURLs.begin(); iResource!=aURLs.end(); ++iResource)
157 : {
158 3816 : (*mpResourceToFactoryMap)[*iResource] = sServiceName;
159 : SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": " <<
160 : OUStringToOString(*iResource, RTL_TEXTENCODING_UTF8).getStr());
161 848 : }
162 848 : }
163 :
164 212 : void ModuleController::InstantiateStartupServices (void)
165 : {
166 : try
167 : {
168 : tools::ConfigurationAccess aConfiguration (
169 : "/org.openoffice.Office.Impress/",
170 212 : tools::ConfigurationAccess::READ_ONLY);
171 : Reference<container::XNameAccess> xFactories (
172 : aConfiguration.GetConfigurationNode("MultiPaneGUI/Framework/StartupServices"),
173 424 : UNO_QUERY);
174 424 : ::std::vector<OUString> aProperties (snStartupPropertyCount);
175 212 : aProperties[0] = "ServiceName";
176 : tools::ConfigurationAccess::ForAll(
177 : xFactories,
178 : aProperties,
179 424 : ::boost::bind(&ModuleController::ProcessStartupService, this, _2));
180 : }
181 0 : catch (Exception&)
182 : {
183 : OSL_TRACE("ERROR in ModuleController::InstantiateStartupServices");
184 : }
185 212 : }
186 :
187 212 : void ModuleController::ProcessStartupService (const ::std::vector<Any>& rValues)
188 : {
189 : OSL_ASSERT(rValues.size() == snStartupPropertyCount);
190 :
191 : try
192 : {
193 : // Get the service name of the startup service.
194 212 : OUString sServiceName;
195 212 : rValues[0] >>= sServiceName;
196 :
197 : // Instantiate service.
198 : Reference<uno::XComponentContext> xContext =
199 424 : ::comphelper::getProcessComponentContext();
200 :
201 : // Create the startup service.
202 424 : Sequence<Any> aArguments(1);
203 212 : aArguments[0] <<= mxController;
204 : // Note that when the new object will be destroyed at the end of
205 : // this scope when it does not register itself anywhere.
206 : // Typically it will add itself as ConfigurationChangeListener
207 : // at the configuration controller.
208 212 : xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sServiceName, aArguments, xContext);
209 :
210 : SAL_INFO("sd.fwk", OSL_THIS_FUNC << ": ModuleController::created startup service " <<
211 212 : OUStringToOString(sServiceName, RTL_TEXTENCODING_UTF8).getStr());
212 : }
213 0 : catch (Exception&)
214 : {
215 : OSL_TRACE("ERROR in ModuleController::ProcessStartupServices");
216 : }
217 212 : }
218 :
219 : //----- XModuleController -----------------------------------------------------
220 :
221 696 : void SAL_CALL ModuleController::requestResource (const OUString& rsResourceURL)
222 : throw (RuntimeException, std::exception)
223 : {
224 696 : ResourceToFactoryMap::const_iterator iFactory (mpResourceToFactoryMap->find(rsResourceURL));
225 696 : if (iFactory != mpResourceToFactoryMap->end())
226 : {
227 : // Check that the factory has already been loaded and not been
228 : // destroyed in the meantime.
229 476 : Reference<XInterface> xFactory;
230 : LoadedFactoryContainer::const_iterator iLoadedFactory (
231 476 : mpLoadedFactories->find(iFactory->second));
232 476 : if (iLoadedFactory != mpLoadedFactories->end())
233 0 : xFactory = Reference<XInterface>(iLoadedFactory->second, UNO_QUERY);
234 476 : if ( ! xFactory.is())
235 : {
236 : // Create a new instance of the factory.
237 : Reference<uno::XComponentContext> xContext =
238 476 : ::comphelper::getProcessComponentContext();
239 :
240 : // Create the factory service.
241 952 : Sequence<Any> aArguments(1);
242 476 : aArguments[0] <<= mxController;
243 : OSL_TRACE("creating resource %s",
244 : OUStringToOString(iFactory->second, RTL_TEXTENCODING_ASCII_US).getStr());
245 : try
246 : {
247 1428 : xFactory = xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
248 476 : iFactory->second,
249 : aArguments,
250 952 : xContext);
251 : }
252 0 : catch (const Exception&)
253 : {
254 : OSL_TRACE("caught exception while creating factory.");
255 : }
256 :
257 : // Remember that this factory has been instanced.
258 952 : (*mpLoadedFactories)[iFactory->second] = xFactory;
259 476 : }
260 : }
261 696 : }
262 :
263 : //----- XInitialization -------------------------------------------------------
264 :
265 212 : void SAL_CALL ModuleController::initialize (const Sequence<Any>& aArguments)
266 : throw (Exception, RuntimeException, std::exception)
267 : {
268 212 : if (aArguments.getLength() > 0)
269 : {
270 : try
271 : {
272 : // Get the XController from the first argument.
273 212 : mxController = Reference<frame::XController>(aArguments[0], UNO_QUERY_THROW);
274 :
275 212 : InstantiateStartupServices();
276 : }
277 0 : catch (RuntimeException&)
278 : {}
279 : }
280 212 : }
281 :
282 114 : } } // end of namespace sd::framework
283 :
284 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|