1 11 package org.eclipse.core.runtime.adaptor; 12 13 import java.io.BufferedInputStream; 14 import java.io.BufferedReader; 15 import java.io.BufferedWriter; 16 import java.io.File; 17 import java.io.FileInputStream; 18 import java.io.FileOutputStream; 19 import java.io.IOException; 20 import java.io.InputStream; 21 import java.io.InputStreamReader; 22 import java.io.OutputStreamWriter; 23 import java.net.MalformedURLException; 24 import java.net.URL; 25 import java.util.ArrayList; 26 import java.util.Collection; 27 import java.util.Dictionary; 28 import java.util.Enumeration; 29 import java.util.HashSet; 30 import java.util.Hashtable; 31 import java.util.Iterator; 32 import java.util.List; 33 import java.util.Map; 34 import java.util.Set; 35 import java.util.jar.JarEntry; 36 import java.util.jar.JarFile; 37 38 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; 39 import org.eclipse.osgi.framework.internal.core.Constants; 40 import org.eclipse.osgi.framework.internal.defaultadaptor.DevClassPathHelper; 41 import org.eclipse.osgi.framework.log.FrameworkLogEntry; 42 import org.eclipse.osgi.service.pluginconversion.PluginConversionException; 43 import org.eclipse.osgi.service.pluginconversion.PluginConverter; 44 import org.eclipse.osgi.service.resolver.Version; 45 import org.eclipse.osgi.service.resolver.VersionRange; 46 import org.eclipse.osgi.util.ManifestElement; 47 import org.osgi.framework.BundleContext; 48 import org.osgi.framework.BundleException; 49 50 53 public class PluginConverterImpl implements PluginConverter { 54 public static boolean DEBUG = false; 55 private static final String SEMICOLON = "; "; private static final String UTF_8 = "UTF-8"; private static final String LIST_SEPARATOR = ",\n "; private static final String DOT = "."; private BundleContext context; 60 private BufferedWriter out; 61 private IPluginInfo pluginInfo; 62 private File pluginManifestLocation; 63 private Dictionary generatedManifest; 64 private byte manifestType; 65 private String target; 66 private static final String MANIFEST_VERSION = "Manifest-Version"; private static final String PLUGIN_PROPERTIES_FILENAME = "plugin"; private static PluginConverterImpl instance; 69 private static final String[] ARCH_LIST = {org.eclipse.osgi.service.environment.Constants.ARCH_PA_RISC, org.eclipse.osgi.service.environment.Constants.ARCH_PPC, org.eclipse.osgi.service.environment.Constants.ARCH_SPARC, org.eclipse.osgi.service.environment.Constants.ARCH_X86, org.eclipse.osgi.service.environment.Constants.ARCH_AMD64, org.eclipse.osgi.service.environment.Constants.ARCH_IA64}; 70 protected static final String FRAGMENT_MANIFEST = "fragment.xml"; protected static final String GENERATED_FROM = "Generated-from"; protected static final String MANIFEST_TYPE_ATTRIBUTE = "type"; private static final String[] OS_LIST = {org.eclipse.osgi.service.environment.Constants.OS_AIX, org.eclipse.osgi.service.environment.Constants.OS_HPUX, org.eclipse.osgi.service.environment.Constants.OS_LINUX, org.eclipse.osgi.service.environment.Constants.OS_MACOSX, org.eclipse.osgi.service.environment.Constants.OS_QNX, org.eclipse.osgi.service.environment.Constants.OS_SOLARIS, org.eclipse.osgi.service.environment.Constants.OS_WIN32}; 74 protected static final String PI_RUNTIME = "org.eclipse.core.runtime"; protected static final String PI_BOOT = "org.eclipse.core.boot"; protected static final String PI_RUNTIME_COMPATIBILITY = "org.eclipse.core.runtime.compatibility"; protected static final String PLUGIN_MANIFEST = "plugin.xml"; private static final String COMPATIBILITY_ACTIVATOR = "org.eclipse.core.internal.compatibility.PluginActivator"; private static final String[] WS_LIST = {org.eclipse.osgi.service.environment.Constants.WS_CARBON, org.eclipse.osgi.service.environment.Constants.WS_GTK, org.eclipse.osgi.service.environment.Constants.WS_MOTIF, org.eclipse.osgi.service.environment.Constants.WS_PHOTON, org.eclipse.osgi.service.environment.Constants.WS_WIN32}; 80 81 public static PluginConverterImpl getDefault() { 82 return instance; 83 } 84 85 public PluginConverterImpl() { 86 this(null); 87 } 88 89 PluginConverterImpl(BundleContext context) { 90 this.context = context; 91 instance = this; 92 } 93 94 private void init() { 95 out = null; 97 pluginInfo = null; 98 pluginManifestLocation = null; 99 generatedManifest = new Hashtable(10); 100 manifestType = EclipseBundleData.MANIFEST_TYPE_UNKNOWN; 101 target = null; 102 } 103 104 private void fillPluginInfo(File pluginBaseLocation) throws PluginConversionException { 105 pluginManifestLocation = pluginBaseLocation; 106 if (pluginManifestLocation == null) 107 throw new IllegalArgumentException(); 108 URL pluginFile = findPluginManifest(pluginBaseLocation); 109 if (pluginFile == null) 110 throw new PluginConversionException(EclipseAdaptorMsg.formatter.getString("ECLIPSE_CONVERTER_FILENOTFOUND", pluginBaseLocation.getAbsolutePath())); pluginInfo = parsePluginInfo(pluginFile); 112 String validation = pluginInfo.validateForm(); 113 if (validation != null) 114 throw new PluginConversionException(validation); 115 } 116 117 private Set filterExport(Collection exportToFilter, Collection filter) { 118 if (filter == null || filter.contains("*")) return (Set) exportToFilter; 120 Set filteredExport = new HashSet(exportToFilter.size()); 121 for (Iterator iter = exportToFilter.iterator(); iter.hasNext();) { 122 String anExport = (String) iter.next(); 123 for (Iterator iter2 = filter.iterator(); iter2.hasNext();) { 124 String aFilter = (String) iter2.next(); 125 int dotStar = aFilter.indexOf(".*"); if (dotStar != -1) 127 aFilter = aFilter.substring(0, dotStar); 128 if (anExport.equals(aFilter)) { 129 filteredExport.add(anExport); 130 break; 131 } 132 } 133 } 134 return filteredExport; 135 } 136 137 private ArrayList findOSJars(File pluginRoot, String path, boolean filter) { 138 path = path.substring(4); 139 ArrayList found = new ArrayList(0); 140 for (int i = 0; i < OS_LIST.length; i++) { 141 String searchedPath = "os/" + OS_LIST[i] + "/" + path; if (new File(pluginRoot, searchedPath).exists()) 144 found.add(searchedPath + (filter ? ";(os=" + WS_LIST[i] + ")" : "")); for (int j = 0; j < ARCH_LIST.length; j++) { 147 searchedPath = "os/" + OS_LIST[i] + "/" + ARCH_LIST[j] + "/" + path; if (new File(pluginRoot, searchedPath).exists()) { 149 found.add(searchedPath + (filter ? ";(& (os=" + WS_LIST[i] + ") (arch=" + ARCH_LIST[j] + ")" : "")); } 151 } 152 } 153 return found; 154 } 155 156 private URL findPluginManifest(File baseLocation) { 157 URL xmlFileLocation; 159 InputStream stream = null; 160 URL baseURL = null; 161 try { 162 if (baseLocation.getName().endsWith(".jar")) { baseURL = new URL("jar:file:" + baseLocation.toString() + "!/"); manifestType |= EclipseBundleData.MANIFEST_TYPE_JAR; 165 } else { 166 baseURL = baseLocation.toURL(); 167 } 168 } catch (MalformedURLException e1) { 169 } 171 try { 172 xmlFileLocation = new URL(baseURL, PLUGIN_MANIFEST); 173 stream = xmlFileLocation.openStream(); 174 manifestType |= EclipseBundleData.MANIFEST_TYPE_PLUGIN; 175 return xmlFileLocation; 176 } catch (MalformedURLException e) { 177 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, e.getMessage(), 0, e, null); 178 EclipseAdaptor.getDefault().getFrameworkLog().log(entry); 179 return null; 180 } catch (IOException ioe) { 181 } finally { 183 try { 184 if (stream != null) 185 stream.close(); 186 } catch (IOException e) { 187 } 189 } 190 try { 191 xmlFileLocation = new URL(baseURL, FRAGMENT_MANIFEST); 192 xmlFileLocation.openStream(); 193 manifestType |= EclipseBundleData.MANIFEST_TYPE_FRAGMENT; 194 return xmlFileLocation; 195 } catch (MalformedURLException e) { 196 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, e.getMessage(), 0, e, null); 197 EclipseAdaptor.getDefault().getFrameworkLog().log(entry); 198 return null; 199 } catch (IOException ioe) { 200 } finally { 202 try { 203 if (stream != null) 204 stream.close(); 205 } catch (IOException e) { 206 } 208 } 209 return null; 210 } 211 212 private ArrayList findWSJars(File pluginRoot, String path, boolean filter) { 213 path = path.substring(4); 214 ArrayList found = new ArrayList(0); 215 for (int i = 0; i < WS_LIST.length; i++) { 216 String searchedPath = "ws/" + WS_LIST[i] + path; if (new File(pluginRoot, searchedPath).exists()) { 218 found.add(searchedPath + (filter ? ";(ws=" + WS_LIST[i] + ")" : "")); } 220 } 221 return found; 222 } 223 224 protected void fillManifest(boolean compatibilityManifest, boolean analyseJars) { 225 generateManifestVersion(); 226 generateHeaders(); 227 generateClasspath(); 228 generateActivator(); 229 generatePluginClass(); 230 if (analyseJars) 231 generateProvidePackage(); 232 generateRequireBundle(); 233 generateLocalizationEntry(); 234 generateEclipseHeaders(); 235 if (compatibilityManifest) { 236 generateTimestamp(); 237 } 238 } 239 240 public void writeManifest(File generationLocation, Dictionary manifestToWrite, boolean compatibilityManifest) throws PluginConversionException { 241 try { 242 File parentFile = new File(generationLocation.getParent()); 243 parentFile.mkdirs(); 244 generationLocation.createNewFile(); 245 if (!generationLocation.isFile()) { 246 String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CONVERTER_ERROR_CREATING_BUNDLE_MANIFEST", this.pluginInfo.getUniqueId(), generationLocation); throw new PluginConversionException(message); 248 } 249 manifestToWrite = new Hashtable((Map) manifestToWrite); 251 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(generationLocation), UTF_8)); 253 writeEntry(MANIFEST_VERSION, (String) manifestToWrite.remove(MANIFEST_VERSION)); 254 writeEntry(GENERATED_FROM, (String) manifestToWrite.remove(GENERATED_FROM)); writeEntry(Constants.BUNDLE_NAME, (String) manifestToWrite.remove(Constants.BUNDLE_NAME)); 256 writeEntry(Constants.BUNDLE_SYMBOLICNAME, (String) manifestToWrite.remove(Constants.BUNDLE_SYMBOLICNAME)); 257 writeEntry(Constants.BUNDLE_VERSION, (String) manifestToWrite.remove(Constants.BUNDLE_VERSION)); 258 writeEntry(Constants.BUNDLE_CLASSPATH, (String) manifestToWrite.remove(Constants.BUNDLE_CLASSPATH)); 259 writeEntry(Constants.BUNDLE_ACTIVATOR, (String) manifestToWrite.remove(Constants.BUNDLE_ACTIVATOR)); 260 writeEntry(Constants.BUNDLE_VENDOR, (String) manifestToWrite.remove(Constants.BUNDLE_VENDOR)); 261 writeEntry(Constants.FRAGMENT_HOST, (String) manifestToWrite.remove(Constants.FRAGMENT_HOST)); 262 writeEntry(Constants.BUNDLE_LOCALIZATION, (String) manifestToWrite.remove(Constants.BUNDLE_LOCALIZATION)); 263 writeEntry(Constants.PROVIDE_PACKAGE, (String) manifestToWrite.remove(Constants.PROVIDE_PACKAGE)); 264 writeEntry(Constants.REQUIRE_BUNDLE, (String) manifestToWrite.remove(Constants.REQUIRE_BUNDLE)); 265 Enumeration keys = manifestToWrite.keys(); 266 while (keys.hasMoreElements()) { 267 String key = (String) keys.nextElement(); 268 writeEntry(key, (String) manifestToWrite.get(key)); 269 } 270 out.flush(); 271 } catch (IOException e) { 272 String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CONVERTER_ERROR_CREATING_BUNDLE_MANIFEST", this.pluginInfo.getUniqueId(), generationLocation); throw new PluginConversionException(message, e); 274 } finally { 275 if (out != null) 276 try { 277 out.close(); 278 } catch (IOException e) { 279 } 281 } 282 } 283 284 private void generateLocalizationEntry() { 285 generatedManifest.put(Constants.BUNDLE_LOCALIZATION, PLUGIN_PROPERTIES_FILENAME); 286 } 287 288 private void generateManifestVersion() { 289 generatedManifest.put(MANIFEST_VERSION, "1.0"); } 291 292 private boolean requireRuntimeCompatibility() { 293 ArrayList requireList = pluginInfo.getRequires(); 294 for (Iterator iter = requireList.iterator(); iter.hasNext();) { 295 if (((PluginParser.Prerequisite) iter.next()).getName().equalsIgnoreCase(PI_RUNTIME_COMPATIBILITY)) 296 return true; 297 } 298 return false; 299 } 300 301 private void generateActivator() { 302 if (!pluginInfo.isFragment()) 303 if (!requireRuntimeCompatibility()) { 304 String pluginClass = pluginInfo.getPluginClass(); 305 if (pluginClass != null && !pluginClass.trim().equals("")) generatedManifest.put(Constants.BUNDLE_ACTIVATOR, pluginClass); 307 } else { 308 generatedManifest.put(Constants.BUNDLE_ACTIVATOR, COMPATIBILITY_ACTIVATOR); 309 } 310 } 311 312 private void generateClasspath() { 313 String[] classpath = pluginInfo.getLibrariesName(); 314 if (classpath.length != 0) 315 generatedManifest.put(Constants.BUNDLE_CLASSPATH, getStringFromArray(classpath, LIST_SEPARATOR)); 316 } 317 318 private void generateHeaders() { 319 generatedManifest.put(Constants.BUNDLE_NAME, pluginInfo.getPluginName()); 320 generatedManifest.put(Constants.BUNDLE_VERSION, pluginInfo.getVersion()); 321 generatedManifest.put(Constants.BUNDLE_SYMBOLICNAME, getSymbolicNameEntry()); 322 String provider = pluginInfo.getProviderName(); 323 if (provider != null) 324 generatedManifest.put(Constants.BUNDLE_VENDOR, provider); 325 if (pluginInfo.isFragment()) { 326 StringBuffer hostBundle = new StringBuffer(); 327 hostBundle.append(pluginInfo.getMasterId()); 328 String versionRange = getVersionRange(pluginInfo.getMasterVersion(), pluginInfo.getMasterMatch()); if (versionRange != null) 330 hostBundle.append(versionRange); 331 generatedManifest.put(Constants.FRAGMENT_HOST, hostBundle.toString()); 332 } 333 } 334 335 339 private String getSymbolicNameEntry() { 340 if (!pluginInfo.isSingleton()) 342 return pluginInfo.getUniqueId(); 343 StringBuffer result = new StringBuffer(pluginInfo.getUniqueId()); 344 result.append(SEMICOLON); result.append(Constants.SINGLETON_ATTRIBUTE); 346 result.append("=true"); return result.toString(); 348 } 349 350 private void generatePluginClass() { 351 if (requireRuntimeCompatibility()) { 352 String pluginClass = pluginInfo.getPluginClass(); 353 if (pluginClass != null) 354 generatedManifest.put(EclipseAdaptor.PLUGIN_CLASS, pluginClass); 355 } 356 } 357 358 private void generateProvidePackage() { 359 Set exports = getExports(); 360 if (exports != null && exports.size() != 0) { 361 generatedManifest.put(Constants.PROVIDE_PACKAGE, getStringFromCollection(exports, LIST_SEPARATOR)); 362 } 363 } 364 365 private void generateRequireBundle() { 366 ArrayList requiredBundles = pluginInfo.getRequires(); 367 if (requiredBundles.size() == 0) 368 return; 369 StringBuffer bundleRequire = new StringBuffer(); 370 for (Iterator iter = requiredBundles.iterator(); iter.hasNext();) { 371 PluginParser.Prerequisite element = (PluginParser.Prerequisite) iter.next(); 372 StringBuffer modImport = new StringBuffer(element.getName()); 373 String versionRange = getVersionRange(element.getVersion(), element.getMatch()); 374 if (versionRange != null) 375 modImport.append(versionRange); 376 if (element.isExported()) { 377 modImport.append(';').append(Constants.REPROVIDE_ATTRIBUTE).append("=true"); } 379 if (element.isOptional()) { 380 modImport.append(';').append(Constants.OPTIONAL_ATTRIBUTE).append("=true"); } 382 bundleRequire.append(modImport.toString()); 383 if (iter.hasNext()) 384 bundleRequire.append(LIST_SEPARATOR); 385 } 386 generatedManifest.put(Constants.REQUIRE_BUNDLE, bundleRequire.toString()); 387 } 388 389 private void generateTimestamp() { 390 generatedManifest.put(GENERATED_FROM, Long.toString(getTimeStamp(pluginManifestLocation, manifestType)) + ";" + MANIFEST_TYPE_ATTRIBUTE + "=" + manifestType); } 393 394 private void generateEclipseHeaders() { 395 if (!pluginInfo.isFragment()) 396 generatedManifest.put(EclipseAdaptor.ECLIPSE_AUTOSTART, "true"); } 398 399 private Set getExports() { 400 Map libs = pluginInfo.getLibraries(); 401 if (libs == null) 402 return null; 403 404 if (DevClassPathHelper.inDevelopmentMode()) { 406 String[] devClassPath = DevClassPathHelper.getDevClassPath(pluginInfo.getUniqueId()); 407 408 List allExportClauses = new ArrayList(libs.size()); 410 Set libEntries = libs.entrySet(); 411 for (Iterator iter = libEntries.iterator(); iter.hasNext();) { 412 Map.Entry element = (Map.Entry) iter.next(); 413 allExportClauses.addAll((List) element.getValue()); 414 } 415 if (devClassPath != null) { 416 for (int i = 0; i < devClassPath.length; i++) 417 libs.put(devClassPath[i], allExportClauses); 418 } 419 } 420 421 Set result = new HashSet(7); 422 Set libEntries = libs.entrySet(); 423 for (Iterator iter = libEntries.iterator(); iter.hasNext();) { 424 Map.Entry element = (Map.Entry) iter.next(); 425 List filter = (List) element.getValue(); 426 if (filter.size() == 0) continue; 428 File libraryLocation = new File(pluginManifestLocation, (String) element.getKey()); 429 Set exports = null; 430 if (libraryLocation.exists()) { 431 if (libraryLocation.isFile()) 432 exports = filterExport(getExportsFromJAR(libraryLocation), filter); else if (libraryLocation.isDirectory()) 434 exports = filterExport(getExportsFromDir(libraryLocation), filter); 435 } else { 436 ArrayList expandedLibs = getLibrariesExpandingVariables((String) element.getKey(), false); 437 exports = new HashSet(); 438 for (Iterator iterator = expandedLibs.iterator(); iterator.hasNext();) { 439 String libName = (String) iterator.next(); 440 File libFile = new File(pluginManifestLocation, libName); 441 if (libFile.isFile()) { 442 exports.addAll(filterExport(getExportsFromJAR(libFile), filter)); 443 } 444 } 445 } 446 if (exports != null) 447 result.addAll(exports); 448 } 449 return result; 450 } 451 452 private Set getExportsFromDir(File location) { 453 return getExportsFromDir(location, ""); } 455 456 private Set getExportsFromDir(File location, String packageName) { 457 String prefix = (packageName.length() > 0) ? (packageName + '.') : ""; String[] files = location.list(); 459 Set exportedPaths = new HashSet(); 460 boolean containsFile = false; 461 for (int i = 0; i < files.length; i++) { 462 if (!isValidPackageName(files[i])) 463 continue; 464 File pkgFile = new File(location, files[i]); 465 if (pkgFile.isDirectory()) 466 exportedPaths.addAll(getExportsFromDir(pkgFile, prefix + files[i])); 467 else 468 containsFile = true; 469 } 470 if (containsFile) 471 if (packageName.length() > 0) 474 exportedPaths.add(packageName); 475 else 476 exportedPaths.add(DOT); 477 return exportedPaths; 478 } 479 480 private Set getExportsFromJAR(File jarFile) { 481 Set names = new HashSet(); 482 JarFile file = null; 483 try { 484 file = new JarFile(jarFile); 485 } catch (IOException e) { 486 String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CONVERTER_PLUGIN_LIBRARY_IGNORED", jarFile, pluginInfo.getUniqueId()); EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, message, 0, e, null)); 488 return names; 489 } 490 for (Enumeration enum = file.entries(); enum.hasMoreElements();) { 492 JarEntry entry = (JarEntry) enum.nextElement(); 493 String name = entry.getName(); 494 if (!isValidPackageName(name)) 495 continue; 496 int lastSlash = name.lastIndexOf("/"); if (lastSlash != -1) { 499 if (lastSlash != name.length() - 1 && name.lastIndexOf(' ') == -1) 500 names.add(name.substring(0, lastSlash).replace('/', '.')); 501 } else { 502 names.add(DOT); 505 } 506 } 507 return names; 508 } 509 510 private ArrayList getLibrariesExpandingVariables(String libraryPath, boolean filter) { 511 String var = hasPrefix(libraryPath); 512 if (var == null) { 513 ArrayList returnValue = new ArrayList(1); 514 returnValue.add(libraryPath); 515 return returnValue; 516 } 517 if (var.equals("ws")) { return findWSJars(pluginManifestLocation, libraryPath, filter); 519 } 520 if (var.equals("os")) { return findOSJars(pluginManifestLocation, libraryPath, filter); 522 } 523 return new ArrayList(0); 524 } 525 526 private String hasPrefix(String libPath) { 528 if (libPath.startsWith("$ws$")) return "ws"; if (libPath.startsWith("$os$")) return "os"; if (libPath.startsWith("$nl$")) return "nl"; return null; 535 } 536 537 private boolean isValidPackageName(String name) { 538 if (name.indexOf(' ') > 0 || name.equalsIgnoreCase("META-INF") || name.startsWith("META-INF/")) return false; 540 return true; 541 } 542 543 548 private IPluginInfo parsePluginInfo(URL pluginLocation) throws PluginConversionException { 549 InputStream input = null; 550 try { 551 input = new BufferedInputStream(pluginLocation.openStream()); 552 return new PluginParser(context, target).parsePlugin(input); 553 } catch (Exception e) { 554 String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CONVERTER_ERROR_PARSING_PLUGIN_MANIFEST", pluginManifestLocation); throw new PluginConversionException(message, e); 556 } finally { 557 if (input != null) 558 try { 559 input.close(); 560 } catch (IOException e) { 561 } 563 } 564 } 565 566 public static boolean upToDate(File generationLocation, File pluginLocation, byte manifestType) { 567 if (!generationLocation.isFile()) 568 return false; 569 String secondLine = null; 570 BufferedReader reader = null; 571 try { 572 reader = new BufferedReader(new InputStreamReader(new FileInputStream(generationLocation))); 573 reader.readLine(); 574 secondLine = reader.readLine(); 575 } catch (IOException e) { 576 return false; 578 } finally { 579 if (reader != null) 580 try { 581 reader.close(); 582 } catch (IOException e) { 583 } 585 } 586 String tag = GENERATED_FROM + ": "; if (secondLine == null || !secondLine.startsWith(tag)) 588 return false; 589 590 secondLine = secondLine.substring(tag.length()); 591 ManifestElement generatedFrom; 592 try { 593 generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, secondLine)[0]; 594 } catch (BundleException be) { 595 return false; 596 } 597 String timestampStr = generatedFrom.getValue(); 598 try { 599 return Long.parseLong(timestampStr.trim()) == getTimeStamp(pluginLocation, manifestType); 600 } catch (NumberFormatException nfe) { 601 } 603 return false; 604 } 605 606 public static long getTimeStamp(File pluginLocation, byte manifestType) { 607 if ((manifestType & EclipseBundleData.MANIFEST_TYPE_JAR) != 0) 608 return pluginLocation.lastModified(); 609 else if ((manifestType & EclipseBundleData.MANIFEST_TYPE_PLUGIN) != 0) 610 return new File(pluginLocation, PLUGIN_MANIFEST).lastModified(); 611 else if ((manifestType & EclipseBundleData.MANIFEST_TYPE_FRAGMENT) != 0) 612 return new File(pluginLocation, FRAGMENT_MANIFEST).lastModified(); 613 else if ((manifestType & EclipseBundleData.MANIFEST_TYPE_BUNDLE) != 0) 614 return new File(pluginLocation, Constants.OSGI_BUNDLE_MANIFEST).lastModified(); 615 return -1; 616 } 617 618 private void writeEntry(String key, String value) throws IOException { 619 if (value != null && value.length() > 0) { 620 out.write(key + ": " + value); out.newLine(); 622 } 623 } 624 625 private String getStringFromArray(String[] values, String separator) { 626 if (values == null) 627 return ""; StringBuffer result = new StringBuffer(); 629 for (int i = 0; i < values.length; i++) { 630 if (i > 0) 631 result.append(separator); 632 result.append(values[i]); 633 } 634 return result.toString(); 635 } 636 637 private String getStringFromCollection(Collection collection, String separator) { 638 StringBuffer result = new StringBuffer(); 639 boolean first = true; 640 for (Iterator i = collection.iterator(); i.hasNext();) { 641 if (first) 642 first = false; 643 else 644 result.append(separator); 645 result.append(i.next()); 646 } 647 return result.toString(); 648 } 649 650 public synchronized Dictionary convertManifest(File pluginBaseLocation, boolean compatibility, String target, boolean analyseJars) throws PluginConversionException { 651 if (DEBUG) 652 System.out.println("Convert " + pluginBaseLocation); init(); 654 this.target = target; 655 fillPluginInfo(pluginBaseLocation); 656 fillManifest(compatibility, analyseJars); 657 return generatedManifest; 658 } 659 660 public synchronized File convertManifest(File pluginBaseLocation, File bundleManifestLocation, boolean compatibilityManifest, String target, boolean analyseJars) throws PluginConversionException { 661 if (DEBUG) 662 System.out.println("Convert " + pluginBaseLocation); init(); 664 this.target = target; 665 fillPluginInfo(pluginBaseLocation); 666 if (bundleManifestLocation == null) { 667 String cacheLocation = (String) System.getProperties().get(LocationManager.PROP_MANIFEST_CACHE); 668 bundleManifestLocation = new File(cacheLocation, pluginInfo.getUniqueId() + '_' + pluginInfo.getVersion() + ".MF"); } 670 fillManifest(compatibilityManifest, analyseJars); 671 if (upToDate(bundleManifestLocation, pluginManifestLocation, manifestType)) 672 return bundleManifestLocation; 673 writeManifest(bundleManifestLocation, generatedManifest, compatibilityManifest); 674 return bundleManifestLocation; 675 } 676 677 private String getVersionRange(String reqVersion, String matchRule) { 678 if (reqVersion == null) 679 return null; 680 681 Version minVersion = new Version(reqVersion); 682 String versionRange; 683 if (matchRule != null) { 684 if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_PERFECT)) { 685 versionRange = new VersionRange(minVersion, minVersion).toString(); 686 } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_EQUIVALENT)) { 687 versionRange = new VersionRange(minVersion, new Version(minVersion.getMajorComponent(), minVersion.getMinorComponent() + 1, 0, "", false)).toString(); } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_COMPATIBLE)) { 689 versionRange = new VersionRange(minVersion, new Version(minVersion.getMajorComponent() + 1, 0, 0, "", false)).toString(); } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_GREATER_OR_EQUAL)) { 691 versionRange = reqVersion; 693 } else { 694 versionRange = new VersionRange(minVersion, new Version(minVersion.getMajorComponent() + 1, 0, 0, "", false)).toString(); } 696 } else { 697 versionRange = new VersionRange(minVersion, new Version(minVersion.getMajorComponent() + 1, 0, 0, "", false)).toString(); } 699 700 StringBuffer result = new StringBuffer(); 701 result.append(';').append(Constants.BUNDLE_VERSION_ATTRIBUTE).append('='); 702 result.append('\"').append(versionRange).append('\"'); 703 return result.toString(); 704 } 705 } | Popular Tags |