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