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 { 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 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 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 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 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