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 "ResourceFactoryManager.hxx"
22 : #include <tools/wldcrd.hxx>
23 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 : #include <com/sun/star/lang/XComponent.hpp>
25 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 : #include <com/sun/star/util/URLTransformer.hpp>
27 : #include <comphelper/processfactory.hxx>
28 : #include <boost/bind.hpp>
29 : #include <algorithm>
30 :
31 : using namespace ::com::sun::star;
32 : using namespace ::com::sun::star::uno;
33 : using namespace ::com::sun::star::drawing::framework;
34 :
35 : #undef VERBOSE
36 : //#define VERBOSE 1
37 :
38 : namespace sd { namespace framework {
39 :
40 0 : ResourceFactoryManager::ResourceFactoryManager (const Reference<XControllerManager>& rxManager)
41 : : maMutex(),
42 : maFactoryMap(),
43 : maFactoryPatternList(),
44 : mxControllerManager(rxManager),
45 0 : mxURLTransformer()
46 : {
47 : // Create the URL transformer.
48 0 : Reference<uno::XComponentContext> xContext(::comphelper::getProcessComponentContext());
49 0 : mxURLTransformer = util::URLTransformer::create(xContext);
50 0 : }
51 :
52 :
53 :
54 :
55 0 : ResourceFactoryManager::~ResourceFactoryManager (void)
56 : {
57 0 : Reference<lang::XComponent> xComponent (mxURLTransformer, UNO_QUERY);
58 0 : if (xComponent.is())
59 0 : xComponent->dispose();
60 0 : }
61 :
62 :
63 :
64 :
65 0 : void ResourceFactoryManager::AddFactory (
66 : const OUString& rsURL,
67 : const Reference<XResourceFactory>& rxFactory)
68 : throw (RuntimeException)
69 : {
70 0 : if ( ! rxFactory.is())
71 0 : throw lang::IllegalArgumentException();
72 0 : if (rsURL.isEmpty())
73 0 : throw lang::IllegalArgumentException();
74 :
75 0 : ::osl::MutexGuard aGuard (maMutex);
76 :
77 0 : if (rsURL.indexOf('*') >= 0 || rsURL.indexOf('?') >= 0)
78 : {
79 : // The URL is a URL pattern not an single URL.
80 0 : maFactoryPatternList.push_back(FactoryPatternList::value_type(rsURL, rxFactory));
81 :
82 : #if defined VERBOSE && VERBOSE>=1
83 : OSL_TRACE("ResourceFactoryManager::AddFactory pattern %s %x\n",
84 : OUStringToOString(rsURL, RTL_TEXTENCODING_UTF8).getStr(),
85 : rxFactory.get());
86 : #endif
87 : }
88 : else
89 : {
90 0 : maFactoryMap[rsURL] = rxFactory;
91 :
92 : #if defined VERBOSE && VERBOSE>=1
93 : OSL_TRACE("ResourceFactoryManager::AddFactory fixed %s %x\n",
94 : OUStringToOString(rsURL, RTL_TEXTENCODING_UTF8).getStr(),
95 : rxFactory.get());
96 : #endif
97 0 : }
98 0 : }
99 :
100 :
101 :
102 :
103 0 : void ResourceFactoryManager::RemoveFactoryForURL (
104 : const OUString& rsURL)
105 : throw (RuntimeException)
106 : {
107 0 : if (rsURL.isEmpty())
108 0 : throw lang::IllegalArgumentException();
109 :
110 0 : ::osl::MutexGuard aGuard (maMutex);
111 :
112 0 : FactoryMap::iterator iFactory (maFactoryMap.find(rsURL));
113 0 : if (iFactory != maFactoryMap.end())
114 : {
115 0 : maFactoryMap.erase(iFactory);
116 : }
117 : else
118 : {
119 : // The URL may be a pattern. Look that up.
120 0 : FactoryPatternList::iterator iPattern;
121 0 : for (iPattern=maFactoryPatternList.begin();
122 0 : iPattern!=maFactoryPatternList.end();
123 : ++iPattern)
124 : {
125 0 : if (iPattern->first == rsURL)
126 : {
127 : // Found the pattern. Remove it.
128 0 : maFactoryPatternList.erase(iPattern);
129 0 : break;
130 : }
131 : }
132 0 : }
133 0 : }
134 :
135 :
136 :
137 :
138 :
139 0 : void ResourceFactoryManager::RemoveFactoryForReference(
140 : const Reference<XResourceFactory>& rxFactory)
141 : throw (RuntimeException)
142 : {
143 0 : ::osl::MutexGuard aGuard (maMutex);
144 :
145 : // Collect a list with all keys that map to the given factory.
146 0 : ::std::vector<OUString> aKeys;
147 0 : FactoryMap::const_iterator iFactory;
148 0 : for (iFactory=maFactoryMap.begin(); iFactory!=maFactoryMap.end(); ++iFactory)
149 0 : if (iFactory->second == rxFactory)
150 0 : aKeys.push_back(iFactory->first);
151 :
152 : // Remove the entries whose keys we just have collected.
153 0 : ::std::vector<OUString>::const_iterator iKey;
154 0 : for (iKey=aKeys.begin(); iKey!=aKeys.end(); ++iKey)
155 0 : maFactoryMap.erase(maFactoryMap.find(*iKey));
156 :
157 : // Remove the pattern entries whose factories are identical to the given
158 : // factory.
159 : FactoryPatternList::iterator iNewEnd (
160 : std::remove_if(
161 : maFactoryPatternList.begin(),
162 : maFactoryPatternList.end(),
163 : ::boost::bind(
164 : std::equal_to<Reference<XResourceFactory> >(),
165 : ::boost::bind(&FactoryPatternList::value_type::second, _1),
166 0 : rxFactory)));
167 0 : if (iNewEnd != maFactoryPatternList.end())
168 0 : maFactoryPatternList.erase(iNewEnd, maFactoryPatternList.end());
169 0 : }
170 :
171 :
172 :
173 :
174 0 : Reference<XResourceFactory> ResourceFactoryManager::GetFactory (
175 : const OUString& rsCompleteURL)
176 : throw (RuntimeException)
177 : {
178 0 : OUString sURLBase (rsCompleteURL);
179 0 : if (mxURLTransformer.is())
180 : {
181 0 : util::URL aURL;
182 0 : aURL.Complete = rsCompleteURL;
183 0 : if (mxURLTransformer->parseStrict(aURL))
184 0 : sURLBase = aURL.Main;
185 : }
186 :
187 0 : Reference<XResourceFactory> xFactory = FindFactory(sURLBase);
188 :
189 0 : if ( ! xFactory.is() && mxControllerManager.is())
190 : {
191 0 : Reference<XModuleController> xModuleController(mxControllerManager->getModuleController());
192 0 : if (xModuleController.is())
193 : {
194 : // Ask the module controller to provide a factory of the
195 : // requested view type. Note that this can (and should) cause
196 : // intermediate calls to AddFactory().
197 0 : xModuleController->requestResource(sURLBase);
198 :
199 0 : xFactory = FindFactory(sURLBase);
200 0 : }
201 : }
202 :
203 0 : return xFactory;
204 : }
205 :
206 :
207 :
208 :
209 0 : Reference<XResourceFactory> ResourceFactoryManager::FindFactory (const OUString& rsURLBase)
210 : throw (RuntimeException)
211 : {
212 0 : ::osl::MutexGuard aGuard (maMutex);
213 0 : FactoryMap::const_iterator iFactory (maFactoryMap.find(rsURLBase));
214 0 : if (iFactory != maFactoryMap.end())
215 0 : return iFactory->second;
216 : else
217 : {
218 : // Check the URL patterns.
219 0 : FactoryPatternList::const_iterator iPattern;
220 0 : for (iPattern=maFactoryPatternList.begin();
221 0 : iPattern!=maFactoryPatternList.end();
222 : ++iPattern)
223 : {
224 0 : WildCard aWildCard (iPattern->first);
225 0 : if (aWildCard.Matches(rsURLBase))
226 0 : return iPattern->second;
227 0 : }
228 : }
229 0 : return NULL;
230 : }
231 :
232 0 : } } // end of namespace sd::framework
233 :
234 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|