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