1 11 package org.eclipse.help.internal.util; 12 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.net.URL ; 16 import java.net.URLConnection ; 17 import java.util.ArrayList ; 18 import java.util.Enumeration ; 19 import java.util.HashMap ; 20 import java.util.HashSet ; 21 import java.util.Hashtable ; 22 import java.util.Iterator ; 23 import java.util.Locale ; 24 import java.util.Map ; 25 import java.util.Set ; 26 27 import org.eclipse.core.runtime.CoreException; 28 import org.eclipse.core.runtime.FileLocator; 29 import org.eclipse.core.runtime.IConfigurationElement; 30 import org.eclipse.core.runtime.IExtension; 31 import org.eclipse.core.runtime.IExtensionDelta; 32 import org.eclipse.core.runtime.IPath; 33 import org.eclipse.core.runtime.IRegistryChangeEvent; 34 import org.eclipse.core.runtime.IRegistryChangeListener; 35 import org.eclipse.core.runtime.Path; 36 import org.eclipse.core.runtime.Platform; 37 import org.eclipse.help.IHelpContentProducer; 38 import org.eclipse.help.internal.HelpPlugin; 39 import org.osgi.framework.Bundle; 40 41 public class ResourceLocator { 42 43 public static final String CONTENTPRODUCER_XP_NAME = "contentProducer"; public static final String BINDING = "binding"; 46 public static final String CONTENTPRODUCER_XP_FULLNAME = HelpPlugin.PLUGIN_ID 47 + "." + CONTENTPRODUCER_XP_NAME; 49 private static Hashtable zipCache = new Hashtable (); 50 51 private static final Object ZIP_NOT_FOUND = new Object (); 52 53 private static final Object STATIC_DOCS_ONLY = ZIP_NOT_FOUND; 55 56 private static Map contentProducers = new HashMap (2, 0.5f); 58 59 static class ProducerDescriptor { 60 61 private IHelpContentProducer producer; 62 private IConfigurationElement config; 63 64 public ProducerDescriptor(IConfigurationElement config) { 65 this.config = config; 66 } 67 68 public boolean matches(String refId) { 69 IExtension ex = config.getDeclaringExtension(); 70 String id = ex.getUniqueIdentifier(); 71 return id != null && id.equals(refId); 72 } 73 74 public void reset() { 75 producer = null; 76 } 77 78 public IHelpContentProducer getProducer() { 79 if (producer == null) { 80 try { 81 Object o = config.createExecutableExtension("producer"); if (o instanceof IHelpContentProducer) 83 producer = (IHelpContentProducer) o; 84 } catch (CoreException ce) { 85 HelpPlugin 86 .logError( 87 "Exception occurred creating help content producer for plug-in " + config.getContributor().getName() + ".", ce); } 89 } 90 return producer; 91 } 92 } 93 static { 94 Platform.getExtensionRegistry().addRegistryChangeListener(new IRegistryChangeListener() { 95 96 101 public void registryChanged(IRegistryChangeEvent event) { 102 IExtensionDelta[] deltas = event.getExtensionDeltas(HelpPlugin.PLUGIN_ID, 103 CONTENTPRODUCER_XP_NAME); 104 for (int i = 0; i < deltas.length; i++) { 105 IExtension extension = deltas[i].getExtension(); 106 String affectedPlugin = extension.getContributor().getName(); 107 synchronized (contentProducers) { 110 Object obj = contentProducers.get(affectedPlugin); 111 if (obj instanceof ProducerDescriptor) { 112 ProducerDescriptor desc = (ProducerDescriptor) obj; 113 desc.reset(); 114 } 115 } 116 } 117 } 118 }); 119 } 120 121 127 private static IHelpContentProducer getContentProducer(String pluginId) { 128 synchronized (contentProducers) { 129 Object obj = getProducerDescriptor(pluginId); 130 if (obj == null || obj == STATIC_DOCS_ONLY) 131 return null; 132 return ((ProducerDescriptor) obj).getProducer(); 133 } 134 } 135 136 private static Object getProducerDescriptor(String pluginId) { 137 Object descriptor = contentProducers.get(pluginId); 138 if (descriptor == null) { 139 descriptor = createContentProducer(pluginId); 142 if (descriptor == null) { 143 descriptor = STATIC_DOCS_ONLY; 144 } 145 contentProducers.put(pluginId, descriptor); 146 } 147 return descriptor; 148 } 149 150 156 private static ProducerDescriptor createContentProducer(String pluginId) { 157 IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor( 158 CONTENTPRODUCER_XP_FULLNAME); 159 if (elements.length == 0) { 160 return null; 161 } 162 163 for (int i = 0; i < elements.length; i++) { 164 IConfigurationElement element = elements[i]; 165 if (!elements[i].getContributor().getName().equals(pluginId)) { 166 continue; 167 } 168 if (BINDING.equals(element.getName())) { 169 String refId = element.getAttribute("producerId"); if (refId != null) { 173 return findContentProducer(elements, refId); 174 } 175 } else if (CONTENTPRODUCER_XP_NAME.equals(element.getName())) { 176 return new ProducerDescriptor(element); 177 } 178 } 179 return null; 180 } 181 182 private static ProducerDescriptor findContentProducer(IConfigurationElement [] elements, String refId) { 183 for (Iterator iter = contentProducers.values().iterator(); iter.hasNext();) { 185 Object obj = iter.next(); 186 if (obj instanceof ProducerDescriptor) { 187 ProducerDescriptor desc = (ProducerDescriptor) obj; 188 if (desc.matches(refId)) 189 return desc; 190 } 191 } 192 for (int i=0; i<elements.length; i++) { 196 if (CONTENTPRODUCER_XP_NAME.equals(elements[i].getName())) { 197 String id = elements[i].getDeclaringExtension().getUniqueIdentifier(); 198 if (refId.equals(id)) { 199 Object obj = getProducerDescriptor(elements[i].getContributor().getName()); 200 if (obj instanceof ProducerDescriptor) 201 return (ProducerDescriptor)obj; 202 } 203 } 204 } 205 return null; 206 } 207 208 211 public static InputStream openFromProducer(Bundle pluginDesc, String file, String locale) { 212 IHelpContentProducer producer = getContentProducer(pluginDesc.getSymbolicName()); 213 if (producer == null) { 214 return null; 215 } 216 if (locale == null || locale.length() <= 0) { 217 locale = Platform.getNL(); 218 } 219 Locale l; 220 if (locale.length() >= 5) { 221 l = new Locale (locale.substring(0, 2), locale.substring(3, 5)); 222 } else if (locale.length() >= 2) { 223 l = new Locale (locale.substring(0, 2), ""); } else { 225 l = Locale.getDefault(); 226 } 227 return producer.getInputStream(pluginDesc.getSymbolicName(), file, l); 228 } 229 230 243 public static InputStream openFromPlugin(String pluginId, String file, String locale) { 244 Bundle bundle = Platform.getBundle(pluginId); 245 if (bundle != null) 246 return openFromPlugin(bundle, file, locale); 247 return null; 248 } 249 250 263 public static InputStream openFromZip(Bundle pluginDesc, String zip, String file, String locale) { 264 265 String pluginID = pluginDesc.getSymbolicName(); 266 Map cache = zipCache; 267 ArrayList pathPrefix = getPathPrefix(locale); 268 269 for (int i = 0; i < pathPrefix.size(); i++) { 270 271 Object cached = cache.get(pluginID + '/' + pathPrefix.get(i) + zip); 274 if (cached == null) { 275 try { 276 URL url = FileLocator.find(pluginDesc, new Path(pathPrefix.get(i) + zip), null); 277 if (url != null) { 278 URL realZipURL = FileLocator.toFileURL(FileLocator.resolve(url)); 279 cached = realZipURL.toExternalForm(); 280 } else { 281 cached = ZIP_NOT_FOUND; 282 } 283 } catch (IOException ioe) { 284 cached = ZIP_NOT_FOUND; 285 } 286 cache.put(pluginID + '/' + pathPrefix.get(i) + zip, cached); 288 } 289 290 if (cached == ZIP_NOT_FOUND || cached.toString().startsWith("jar:")) continue; 292 293 try { 296 URL jurl = new URL ("jar", "", (String ) cached + "!/" + file); URLConnection jconnection = jurl.openConnection(); 298 jconnection.setDefaultUseCaches(false); 299 jconnection.setUseCaches(false); 300 return jconnection.getInputStream(); 301 } catch (IOException ioe) { 302 continue; 304 } 305 306 } 308 return null; 310 } 311 312 325 public static InputStream openFromPlugin(Bundle pluginDesc, String file, String locale) { 326 327 ArrayList pathPrefix = getPathPrefix(locale); 328 URL flatFileURL = find(pluginDesc, new Path(file), pathPrefix); 329 if (flatFileURL != null) 330 try { 331 return flatFileURL.openStream(); 332 } catch (IOException e) { 333 return null; 334 } 335 return null; 336 } 337 338 339 340 344 public static URL find(Bundle pluginDesc, IPath flatFilePath, ArrayList pathPrefix) { 345 346 for (int i = 0; i < pathPrefix.size(); i++) { 348 URL url = FileLocator.find(pluginDesc, new Path((String ) pathPrefix.get(i) + flatFilePath), null); 349 if (url != null) 350 return url; 351 } 352 return null; 353 } 354 355 public static void clearZipCache() { 356 zipCache = new Hashtable (); 357 } 358 359 366 public static ArrayList getPathPrefix(String locale) { 367 ArrayList pathPrefix = new ArrayList (5); 368 String ws = Platform.getWS(); 371 String os = Platform.getOS(); 372 if (locale == null) 373 locale = Platform.getNL(); 374 375 if (ws != null) 376 pathPrefix.add("ws/" + ws + '/'); 378 if (os != null && !os.equals("OS_UNKNOWN")) pathPrefix.add("os/" + os + '/'); 381 if (locale != null && locale.length() >= 5) 382 pathPrefix.add("nl/" + locale.substring(0, 2) + '/' + locale.substring(3, 5) + '/'); 384 if (locale != null && locale.length() >= 2) 385 pathPrefix.add("nl/" + locale.substring(0, 2) + '/'); 387 pathPrefix.add(""); 390 return pathPrefix; 391 } 392 393 406 public static Set findTopicPaths(Bundle pluginDesc, String directory, String locale) { 407 Set ret = new HashSet (); 408 findTopicPaths(pluginDesc, directory, locale, ret); 409 return ret; 410 } 411 412 418 private static void findTopicPaths(Bundle pluginDesc, String directory, String locale, Set paths) { 419 if (directory.endsWith("/")) directory = directory.substring(0, directory.length() - 1); 421 ArrayList pathPrefix = getPathPrefix(locale); 422 for (int i = 0; i < pathPrefix.size(); i++) { 423 String path = pathPrefix.get(i) + directory; 424 if (path.length() == 0) 425 path = "/"; Enumeration entries = pluginDesc.getEntryPaths(path); 427 if (entries != null) { 428 while (entries.hasMoreElements()) { 429 String topicPath = (String ) entries.nextElement(); 430 if (topicPath.endsWith("/")) { findTopicPaths(pluginDesc, topicPath, locale, paths); 432 } else { 433 paths.add(topicPath); 434 } 435 } 436 } 437 } 438 } 439 } 440 | Popular Tags |