1 11 package org.eclipse.core.runtime.adaptor; 12 13 import java.io.*; 14 import java.net.URL ; 15 import java.util.*; 16 import org.eclipse.core.runtime.internal.adaptor.*; 17 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; 18 import org.eclipse.osgi.framework.adaptor.core.*; 19 import org.eclipse.osgi.framework.internal.core.Constants; 20 import org.eclipse.osgi.framework.log.FrameworkLogEntry; 21 import org.eclipse.osgi.framework.util.Headers; 22 import org.eclipse.osgi.service.datalocation.Location; 23 import org.eclipse.osgi.service.pluginconversion.PluginConversionException; 24 import org.eclipse.osgi.util.ManifestElement; 25 import org.eclipse.osgi.util.NLS; 26 import org.osgi.framework.BundleException; 27 import org.osgi.framework.Version; 28 29 36 public class EclipseBundleData extends AbstractBundleData { 38 39 static public final byte MANIFEST_TYPE_UNKNOWN = 0x00; 40 41 static public final byte MANIFEST_TYPE_BUNDLE = 0x01; 42 43 static public final byte MANIFEST_TYPE_PLUGIN = 0x02; 44 45 static public final byte MANIFEST_TYPE_FRAGMENT = 0x04; 46 47 static public final byte MANIFEST_TYPE_JAR = 0x08; 48 49 private static String [] libraryVariants = null; 50 51 52 private long manifestTimeStamp = 0; 53 private byte manifestType = MANIFEST_TYPE_UNKNOWN; 54 55 57 public static final String PROTOCOL = "platform"; 59 public static final String FILE = "file"; 61 private static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; 63 protected String pluginClass = null; 64 65 private boolean autoStart; 66 private String [] autoStartExceptions; 67 68 protected String buddyList; 69 70 protected String registeredBuddyList; 71 72 protected boolean hasPackageInfo; 73 74 private static String [] buildLibraryVariants() { 75 ArrayList result = new ArrayList(); 76 EclipseEnvironmentInfo info = EclipseEnvironmentInfo.getDefault(); 77 result.add("ws/" + info.getWS() + "/"); result.add("os/" + info.getOS() + "/" + info.getOSArch() + "/"); result.add("os/" + info.getOS() + "/"); String nl = info.getNL(); 81 nl = nl.replace('_', '/'); 82 while (nl.length() > 0) { 83 result.add("nl/" + nl + "/"); int i = nl.lastIndexOf('/'); 85 nl = (i < 0) ? "" : nl.substring(0, i); } 87 result.add(""); return (String []) result.toArray(new String [result.size()]); 89 } 90 91 96 public EclipseBundleData(AbstractFrameworkAdaptor adaptor, long id) { 97 super(adaptor, id); 98 } 99 100 104 public void initializeExistingBundle() throws IOException { 105 createBaseBundleFile(); 106 if (!checkManifestTimeStamp()) { 107 if (getBundleStoreDir().exists()) { 108 109 FileOutputStream out = new FileOutputStream(new File(getBundleStoreDir(), ".delete")); 110 out.close(); 111 } 112 throw new IOException(); 113 } 114 } 115 116 private boolean checkManifestTimeStamp() { 117 if (!"true".equalsIgnoreCase(System.getProperty(PROP_CHECK_CONFIG))) return true; 119 120 if (PluginConverterImpl.getTimeStamp(getBaseFile(), getManifestType()) == getManifestTimeStamp()) { 121 if ((getManifestType() & (MANIFEST_TYPE_JAR | MANIFEST_TYPE_BUNDLE)) != 0) 122 return true; 123 String cacheLocation = System.getProperty(LocationManager.PROP_MANIFEST_CACHE); 124 Location parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation(); 125 if (parentConfiguration != null) { 126 try { 127 return checkManifestAndParent(cacheLocation, getSymbolicName(), getVersion().toString(), getManifestType()) != null; 128 } catch (BundleException e) { 129 return false; 130 } 131 } 132 File cacheFile = new File(cacheLocation, getSymbolicName() + '_' + getVersion() + ".MF"); if (cacheFile.isFile()) 134 return true; 135 } 136 return false; 137 } 138 139 150 public String findLibrary(String libName) { 151 String result = super.findLibrary(libName); 154 if (result != null) 155 return result; 156 if (libraryVariants == null) 157 libraryVariants = buildLibraryVariants(); 158 if (libName.length() == 0) 159 return null; 160 if (libName.charAt(0) == '/' || libName.charAt(0) == '\\') 161 libName = libName.substring(1); 162 libName = System.mapLibraryName(libName); 163 164 167 return searchVariants(libraryVariants, libName); 168 169 } 170 171 private String searchVariants(String [] variants, String path) { 172 for (int i = 0; i < variants.length; i++) { 173 BundleEntry libEntry = baseBundleFile.getEntry(variants[i] + path); 174 if (libEntry == null) { 175 } else { 179 File libFile = baseBundleFile.getFile(variants[i] + path); 183 if (libFile == null) 184 return null; 185 if (org.eclipse.osgi.service.environment.Constants.OS_HPUX.equals(EclipseEnvironmentInfo.getDefault().getOS())) { 187 try { 188 Runtime.getRuntime().exec(new String [] {"chmod", "755", libFile.getAbsolutePath()}).waitFor(); } catch (Exception e) { 191 e.printStackTrace(); 192 } 193 } 194 return libFile.getAbsolutePath(); 195 } 196 } 197 return null; 198 } 199 200 private URL [] getSearchURLs(URL target) { 202 return new URL [] {target}; 203 } 204 205 public synchronized Dictionary getManifest() throws BundleException { 206 return getManifest(false); 207 } 208 209 218 public synchronized Dictionary getManifest(boolean first) throws BundleException { 219 if (manifest == null) 220 manifest = first ? loadManifest() : new CachedManifest(this); 221 return manifest; 222 } 223 224 private boolean isComplete(Dictionary manifest) { 225 if (manifest.get(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME) != null) 227 return true; 228 return getEntry(PluginConverterImpl.PLUGIN_MANIFEST) == null && getEntry(PluginConverterImpl.FRAGMENT_MANIFEST) == null; 230 } 231 232 237 public synchronized Dictionary loadManifest() throws BundleException { 238 URL url = getEntry(Constants.OSGI_BUNDLE_MANIFEST); 239 if (url != null) { 240 Dictionary builtIn = loadManifestFrom(url); 242 if (!isComplete(builtIn)) { 244 Dictionary generatedManifest = generateManifest(builtIn); 245 if (generatedManifest != null) 246 return generatedManifest; 247 } 248 manifestType = MANIFEST_TYPE_BUNDLE; 250 if (getBaseFile().isFile()) { 251 manifestTimeStamp = getBaseFile().lastModified(); 252 manifestType |= MANIFEST_TYPE_JAR; 253 } else 254 manifestTimeStamp = getBaseBundleFile().getEntry(Constants.OSGI_BUNDLE_MANIFEST).getTime(); 255 return builtIn; 256 } 257 Dictionary result = generateManifest(null); 258 if (result == null) 259 throw new BundleException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_DATA_MANIFEST_NOT_FOUND, getLocation())); 260 return result; 261 } 262 263 private Headers basicCheckManifest(String cacheLocation, String symbolicName, String version, byte inputType) throws BundleException { 264 File currentFile = new File(cacheLocation, symbolicName + '_' + version + ".MF"); if (PluginConverterImpl.upToDate(currentFile, getBaseFile(), inputType)) { 266 try { 267 return Headers.parseManifest(new FileInputStream(currentFile)); 268 } catch (FileNotFoundException e) { 269 } 271 } 272 return null; 273 } 274 275 private Headers checkManifestAndParent(String cacheLocation, String symbolicName, String version, byte inputType) throws BundleException { 276 Headers result = basicCheckManifest(cacheLocation, symbolicName, version, inputType); 277 if (result != null) 278 return result; 279 280 Location parentConfiguration = null; 281 if ((parentConfiguration = LocationManager.getConfigurationLocation().getParentLocation()) != null) { 282 result = basicCheckManifest(new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.MANIFESTS_DIR).toString(), symbolicName, version, inputType); 283 } 284 return result; 285 } 286 287 private Dictionary generateManifest(Dictionary originalManifest) throws BundleException { 288 String cacheLocation = System.getProperty(LocationManager.PROP_MANIFEST_CACHE); 289 if (getSymbolicName() != null) { 290 Headers existingHeaders = checkManifestAndParent(cacheLocation, getSymbolicName(), getVersion().toString(), manifestType); 291 if (existingHeaders != null) 292 return existingHeaders; 293 } 294 295 PluginConverterImpl converter = PluginConverterImpl.getDefault(); 296 297 Dictionary generatedManifest; 298 try { 299 generatedManifest = converter.convertManifest(getBaseFile(), true, null, true, null); 300 } catch (PluginConversionException pce) { 301 String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_ERROR_CONVERTING, getBaseFile()); throw new BundleException(message, pce); } 304 305 Version version = Version.parseVersion((String ) generatedManifest.get(Constants.BUNDLE_VERSION)); 307 String symbolicName = ManifestElement.parseHeader(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME, (String ) generatedManifest.get(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME))[0].getValue(); 308 ManifestElement generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, (String ) generatedManifest.get(PluginConverterImpl.GENERATED_FROM))[0]; 309 Headers existingHeaders = checkManifestAndParent(cacheLocation, symbolicName, version.toString(), Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE))); 310 setManifestTimeStamp(Long.parseLong(generatedFrom.getValue())); 312 setManifestType(Byte.parseByte(generatedFrom.getAttribute(PluginConverterImpl.MANIFEST_TYPE_ATTRIBUTE))); 313 if (!adaptor.canWrite() || existingHeaders != null) 314 return existingHeaders; 315 316 if (originalManifest != null) { 318 Enumeration keysEnum = originalManifest.keys(); 319 while (keysEnum.hasMoreElements()) { 320 Object key = keysEnum.nextElement(); 321 generatedManifest.put(key, originalManifest.get(key)); 322 } 323 } 324 325 File bundleManifestLocation = new File(cacheLocation, symbolicName + '_' + version.toString() + ".MF"); try { 328 converter.writeManifest(bundleManifestLocation, generatedManifest, true); 329 } catch (Exception e) { 330 } 332 return generatedManifest; 333 334 } 335 336 private Dictionary loadManifestFrom(URL manifestURL) throws BundleException { 337 try { 338 return Headers.parseManifest(manifestURL.openStream()); 339 } catch (IOException e) { 340 throw new BundleException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_DATA_ERROR_READING_MANIFEST, getLocation()), e); 341 } 342 } 343 344 protected void loadFromManifest() throws BundleException { 345 getManifest(true); 346 super.loadFromManifest(); 347 if (manifest instanceof CachedManifest) 349 throw new IllegalStateException (); 350 pluginClass = (String ) manifest.get(EclipseAdaptor.PLUGIN_CLASS); 351 parseAutoStart((String ) manifest.get(EclipseAdaptor.ECLIPSE_AUTOSTART)); 352 buddyList = (String ) manifest.get(Constants.BUDDY_LOADER); 353 registeredBuddyList = (String ) manifest.get(Constants.REGISTERED_POLICY); 354 hasPackageInfo = hasPackageInfo(getEntry(Constants.OSGI_BUNDLE_MANIFEST)); 355 } 356 357 private boolean hasPackageInfo(URL url) { 361 if (url == null) 362 return false; 363 BufferedReader br = null; 364 try { 365 br = new BufferedReader(new InputStreamReader(url.openStream())); 366 String line; 367 while ((line = br.readLine()) != null) { 368 if (line.startsWith("Specification-Title: ") || line.startsWith("Specification-Version: ") || line.startsWith("Specification-Vendor: ") || line.startsWith("Implementation-Title: ") || line.startsWith("Implementation-Version: ") || line.startsWith("Implementation-Vendor: ")) return true; 370 } 371 } catch (IOException ioe) { 372 } finally { 374 if (br != null) 375 try { 376 br.close(); 377 } catch (IOException e) { 378 } 380 } 381 return false; 382 } 383 384 388 public String getPluginClass() { 389 return pluginClass; 390 } 391 392 396 public String getBuddyList() { 397 return buddyList; 398 } 399 400 404 public String getRegisteredBuddyList() { 405 return registeredBuddyList; 406 } 407 408 412 public void setPluginClass(String value) { 413 pluginClass = value; 414 } 415 416 420 public long getManifestTimeStamp() { 421 return manifestTimeStamp; 422 } 423 424 428 public void setManifestTimeStamp(long stamp) { 429 manifestTimeStamp = stamp; 430 } 431 432 436 public byte getManifestType() { 437 return manifestType; 438 } 439 440 444 public void setManifestType(byte manifestType) { 445 this.manifestType = manifestType; 446 } 447 448 452 public void setAutoStart(boolean value) { 453 autoStart = value; 454 } 455 456 460 public boolean isAutoStart() { 461 return autoStart; 462 } 463 464 470 public int getPersistentStatus() { 471 return isAutoStartable() ? (~Constants.BUNDLE_STARTED) & getStatus() : getStatus(); 473 } 474 475 479 public void setAutoStartExceptions(String [] autoStartExceptions) { 480 this.autoStartExceptions = autoStartExceptions; 481 } 482 483 487 public String [] getAutoStartExceptions() { 488 return autoStartExceptions; 489 } 490 491 private void parseAutoStart(String headerValue) { 492 autoStart = false; 493 autoStartExceptions = null; 494 ManifestElement[] allElements = null; 495 try { 496 allElements = ManifestElement.parseHeader(EclipseAdaptor.ECLIPSE_AUTOSTART, headerValue); 497 } catch (BundleException e) { 498 String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_CANNOT_GET_HEADERS, getLocation()); 500 EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, message, 0, e, null)); 501 } 502 if (allElements == null) 504 return; 505 autoStart = "true".equalsIgnoreCase(allElements[0].getValue()); String exceptionsValue = allElements[0].getAttribute(EclipseAdaptor.ECLIPSE_AUTOSTART_EXCEPTIONS); 509 if (exceptionsValue == null) 510 return; 511 StringTokenizer tokenizer = new StringTokenizer(exceptionsValue, ","); int numberOfTokens = tokenizer.countTokens(); 513 autoStartExceptions = new String [numberOfTokens]; 514 for (int i = 0; i < numberOfTokens; i++) 515 autoStartExceptions[i] = tokenizer.nextToken().trim(); 516 } 517 518 523 public boolean isAutoStartable() { 524 return autoStart || (autoStartExceptions != null && autoStartExceptions.length > 0); 525 } 526 527 532 public synchronized void save() throws IOException { 533 if (adaptor.canWrite()) 534 ((EclipseAdaptor) adaptor).saveMetaDataFor(this); 535 } 536 537 public String toString() { 538 return "BundleData for " + getSymbolicName() + " (" + id + ")"; } 540 541 public File getParentGenerationDir() { 542 Location parentConfiguration = null; 543 Location currentConfiguration = LocationManager.getConfigurationLocation(); 544 if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null) 545 return new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.BUNDLES_DIR + '/' + getBundleID() + '/' + getGeneration()); 546 return null; 547 } 548 } 549 | Popular Tags |