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