1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "precompiled_sd.hxx" 29 30 #include "ResourceFactoryManager.hxx" 31 #include <tools/wldcrd.hxx> 32 #include <com/sun/star/lang/IllegalArgumentException.hpp> 33 #include <com/sun/star/lang/XComponent.hpp> 34 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 35 #include <comphelper/processfactory.hxx> 36 #include <boost/bind.hpp> 37 #include <algorithm> 38 39 using namespace ::com::sun::star; 40 using namespace ::com::sun::star::uno; 41 using namespace ::com::sun::star::drawing::framework; 42 using ::rtl::OUString; 43 44 namespace sd { namespace framework { 45 46 ResourceFactoryManager::ResourceFactoryManager (const Reference<XControllerManager>& rxManager) 47 : maMutex(), 48 maFactoryMap(), 49 maFactoryPatternList(), 50 mxControllerManager(rxManager), 51 mxURLTransformer() 52 { 53 // Create the URL transformer. 54 Reference<lang::XMultiServiceFactory> xServiceManager ( 55 ::comphelper::getProcessServiceFactory()); 56 mxURLTransformer = Reference<util::XURLTransformer>( 57 xServiceManager->createInstance( 58 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))), 59 UNO_QUERY); 60 } 61 62 63 64 65 ResourceFactoryManager::~ResourceFactoryManager (void) 66 { 67 Reference<lang::XComponent> xComponent (mxURLTransformer, UNO_QUERY); 68 if (xComponent.is()) 69 xComponent->dispose(); 70 } 71 72 73 74 75 void ResourceFactoryManager::AddFactory ( 76 const OUString& rsURL, 77 const Reference<XResourceFactory>& rxFactory) 78 throw (RuntimeException) 79 { 80 if ( ! rxFactory.is()) 81 throw lang::IllegalArgumentException(); 82 if (rsURL.getLength() == 0) 83 throw lang::IllegalArgumentException(); 84 85 ::osl::MutexGuard aGuard (maMutex); 86 87 if (rsURL.indexOf('*') >= 0 || rsURL.indexOf('?') >= 0) 88 { 89 // The URL is a URL pattern not an single URL. 90 maFactoryPatternList.push_back(FactoryPatternList::value_type(rsURL, rxFactory)); 91 } 92 else 93 { 94 maFactoryMap[rsURL] = rxFactory; 95 } 96 } 97 98 99 100 101 void ResourceFactoryManager::RemoveFactoryForURL ( 102 const OUString& rsURL) 103 throw (RuntimeException) 104 { 105 if (rsURL.getLength() == 0) 106 throw lang::IllegalArgumentException(); 107 108 ::osl::MutexGuard aGuard (maMutex); 109 110 FactoryMap::iterator iFactory (maFactoryMap.find(rsURL)); 111 if (iFactory != maFactoryMap.end()) 112 { 113 maFactoryMap.erase(iFactory); 114 } 115 else 116 { 117 // The URL may be a pattern. Look that up. 118 FactoryPatternList::iterator iPattern; 119 for (iPattern=maFactoryPatternList.begin(); 120 iPattern!=maFactoryPatternList.end(); 121 ++iPattern) 122 { 123 if (iPattern->first == rsURL) 124 { 125 // Found the pattern. Remove it. 126 maFactoryPatternList.erase(iPattern); 127 break; 128 } 129 } 130 } 131 } 132 133 134 135 136 137 void ResourceFactoryManager::RemoveFactoryForReference( 138 const Reference<XResourceFactory>& rxFactory) 139 throw (RuntimeException) 140 { 141 ::osl::MutexGuard aGuard (maMutex); 142 143 // Collect a list with all keys that map to the given factory. 144 ::std::vector<OUString> aKeys; 145 FactoryMap::const_iterator iFactory; 146 for (iFactory=maFactoryMap.begin(); iFactory!=maFactoryMap.end(); ++iFactory) 147 if (iFactory->second == rxFactory) 148 aKeys.push_back(iFactory->first); 149 150 // Remove the entries whose keys we just have collected. 151 ::std::vector<OUString>::const_iterator iKey; 152 for (iKey=aKeys.begin(); iKey!=aKeys.end(); ++iKey) 153 maFactoryMap.erase(maFactoryMap.find(*iKey)); 154 155 // Remove the pattern entries whose factories are identical to the given 156 // factory. 157 FactoryPatternList::iterator iNewEnd ( 158 std::remove_if( 159 maFactoryPatternList.begin(), 160 maFactoryPatternList.end(), 161 ::boost::bind( 162 std::equal_to<Reference<XResourceFactory> >(), 163 ::boost::bind(&FactoryPatternList::value_type::second, _1), 164 rxFactory))); 165 if (iNewEnd != maFactoryPatternList.end()) 166 maFactoryPatternList.erase(iNewEnd, maFactoryPatternList.end()); 167 } 168 169 170 171 172 Reference<XResourceFactory> ResourceFactoryManager::GetFactory ( 173 const OUString& rsCompleteURL) 174 throw (RuntimeException) 175 { 176 OUString sURLBase (rsCompleteURL); 177 if (mxURLTransformer.is()) 178 { 179 util::URL aURL; 180 aURL.Complete = rsCompleteURL; 181 if (mxURLTransformer->parseStrict(aURL)) 182 sURLBase = aURL.Main; 183 } 184 185 Reference<XResourceFactory> xFactory = FindFactory(sURLBase); 186 187 if ( ! xFactory.is() && mxControllerManager.is()) 188 { 189 Reference<XModuleController> xModuleController(mxControllerManager->getModuleController()); 190 if (xModuleController.is()) 191 { 192 // Ask the module controller to provide a factory of the 193 // requested view type. Note that this can (and should) cause 194 // intermediate calls to AddFactory(). 195 xModuleController->requestResource(sURLBase); 196 197 xFactory = FindFactory(sURLBase); 198 } 199 } 200 201 return xFactory; 202 } 203 204 205 206 207 Reference<XResourceFactory> ResourceFactoryManager::FindFactory (const OUString& rsURLBase) 208 throw (RuntimeException) 209 { 210 ::osl::MutexGuard aGuard (maMutex); 211 FactoryMap::const_iterator iFactory (maFactoryMap.find(rsURLBase)); 212 if (iFactory != maFactoryMap.end()) 213 return iFactory->second; 214 else 215 { 216 // Check the URL patterns. 217 FactoryPatternList::const_iterator iPattern; 218 for (iPattern=maFactoryPatternList.begin(); 219 iPattern!=maFactoryPatternList.end(); 220 ++iPattern) 221 { 222 WildCard aWildCard (iPattern->first); 223 if (aWildCard.Matches(rsURLBase)) 224 return iPattern->second; 225 } 226 } 227 return NULL; 228 } 229 230 } } // end of namespace sd::framework 231