1 11 package org.eclipse.core.runtime.internal.adaptor; 12 13 import java.io.*; 14 import java.net.MalformedURLException ; 15 import java.net.URL ; 16 import java.util.*; 17 import java.util.zip.ZipEntry ; 18 import java.util.zip.ZipFile ; 19 import org.eclipse.core.runtime.adaptor.*; 20 import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; 21 import org.eclipse.osgi.framework.internal.core.Constants; 22 import org.eclipse.osgi.framework.internal.core.FrameworkProperties; 23 import org.eclipse.osgi.framework.log.FrameworkLogEntry; 24 import org.eclipse.osgi.internal.baseadaptor.DevClassPathHelper; 25 import org.eclipse.osgi.service.pluginconversion.PluginConversionException; 26 import org.eclipse.osgi.service.pluginconversion.PluginConverter; 27 import org.eclipse.osgi.service.resolver.VersionRange; 28 import org.eclipse.osgi.util.ManifestElement; 29 import org.eclipse.osgi.util.NLS; 30 import org.osgi.framework.*; 31 32 35 public class PluginConverterImpl implements PluginConverter { 36 public static boolean DEBUG = false; 37 38 static public final byte MANIFEST_TYPE_UNKNOWN = 0x00; 39 40 static public final byte MANIFEST_TYPE_BUNDLE = 0x01; 41 42 static public final byte MANIFEST_TYPE_PLUGIN = 0x02; 43 44 static public final byte MANIFEST_TYPE_FRAGMENT = 0x04; 45 46 static public final byte MANIFEST_TYPE_JAR = 0x08; 47 private static final String SEMICOLON = "; "; private static final String UTF_8 = "UTF-8"; private static final String LIST_SEPARATOR = ",\n "; private static final String LINE_SEPARATOR = "\n "; private static final String DOT = "."; private static int MAXLINE = 511; 53 private BundleContext context; 54 private FrameworkAdaptor adaptor; 55 private BufferedWriter out; 56 private IPluginInfo pluginInfo; 57 private File pluginManifestLocation; 58 private Dictionary generatedManifest; 59 private byte manifestType; 60 private Version target; 61 private Dictionary devProperties; 62 static final Version TARGET31 = new Version(3, 1, 0); 63 static final Version TARGET32 = new Version(3, 2, 0); 64 private static final String MANIFEST_VERSION = "Manifest-Version"; private static final String PLUGIN_PROPERTIES_FILENAME = "plugin"; private static PluginConverterImpl instance; 67 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}; 68 static public final String FRAGMENT_MANIFEST = "fragment.xml"; static public final String GENERATED_FROM = "Generated-from"; static public 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}; 72 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"; static public 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}; 78 private static final String IGNORE_DOT = "@ignoredot@"; 80 public static PluginConverterImpl getDefault() { 81 return instance; 82 } 83 84 public PluginConverterImpl(FrameworkAdaptor adaptor, BundleContext context) { 85 this.context = context; 86 this.adaptor = adaptor; 87 instance = this; 88 } 89 90 private void init() { 91 out = null; 93 pluginInfo = null; 94 pluginManifestLocation = null; 95 generatedManifest = new Hashtable(10); 96 manifestType = MANIFEST_TYPE_UNKNOWN; 97 target = null; 98 devProperties = null; 99 } 100 101 private void fillPluginInfo(File pluginBaseLocation) throws PluginConversionException { 102 pluginManifestLocation = pluginBaseLocation; 103 if (pluginManifestLocation == null) 104 throw new IllegalArgumentException (); 105 URL pluginFile = findPluginManifest(pluginBaseLocation); 106 if (pluginFile == null) 107 throw new PluginConversionException(NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_FILENOTFOUND, pluginBaseLocation.getAbsolutePath())); 108 pluginInfo = parsePluginInfo(pluginFile); 109 String validation = pluginInfo.validateForm(); 110 if (validation != null) 111 throw new PluginConversionException(validation); 112 } 113 114 private Set filterExport(Collection exportToFilter, Collection filter) { 115 if (filter == null || filter.contains("*")) return (Set) exportToFilter; 117 Set filteredExport = new HashSet(exportToFilter.size()); 118 for (Iterator iter = exportToFilter.iterator(); iter.hasNext();) { 119 String anExport = (String ) iter.next(); 120 for (Iterator iter2 = filter.iterator(); iter2.hasNext();) { 121 String aFilter = (String ) iter2.next(); 122 int dotStar = aFilter.indexOf(".*"); if (dotStar != -1) 124 aFilter = aFilter.substring(0, dotStar); 125 if (anExport.equals(aFilter)) { 126 filteredExport.add(anExport); 127 break; 128 } 129 } 130 } 131 return filteredExport; 132 } 133 134 private ArrayList findOSJars(File pluginRoot, String path, boolean filter) { 135 path = path.substring(4); 136 ArrayList found = new ArrayList(0); 137 for (int i = 0; i < OS_LIST.length; i++) { 138 String searchedPath = "os/" + OS_LIST[i] + "/" + path; if (new File (pluginRoot, searchedPath).exists()) 141 found.add(searchedPath + (filter ? ";(os=" + WS_LIST[i] + ")" : "")); for (int j = 0; j < ARCH_LIST.length; j++) { 144 searchedPath = "os/" + OS_LIST[i] + "/" + ARCH_LIST[j] + "/" + path; if (new File (pluginRoot, searchedPath).exists()) { 146 found.add(searchedPath + (filter ? ";(& (os=" + WS_LIST[i] + ") (arch=" + ARCH_LIST[j] + ")" : "")); } 148 } 149 } 150 return found; 151 } 152 153 private URL findPluginManifest(File baseLocation) { 154 URL xmlFileLocation; 156 InputStream stream = null; 157 URL baseURL = null; 158 try { 159 if (!baseLocation.isDirectory()) { 160 baseURL = new URL ("jar:file:" + baseLocation.toString() + "!/"); manifestType |= MANIFEST_TYPE_JAR; 162 } else { 163 baseURL = baseLocation.toURL(); 164 } 165 } catch (MalformedURLException e1) { 166 } 168 try { 169 xmlFileLocation = new URL (baseURL, PLUGIN_MANIFEST); 170 stream = xmlFileLocation.openStream(); 171 manifestType |= MANIFEST_TYPE_PLUGIN; 172 return xmlFileLocation; 173 } catch (MalformedURLException e) { 174 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, e.getMessage(), 0, e, null); 175 adaptor.getFrameworkLog().log(entry); 176 return null; 177 } catch (IOException ioe) { 178 } finally { 180 try { 181 if (stream != null) 182 stream.close(); 183 } catch (IOException e) { 184 } 186 } 187 try { 188 xmlFileLocation = new URL (baseURL, FRAGMENT_MANIFEST); 189 stream = xmlFileLocation.openStream(); 190 manifestType |= MANIFEST_TYPE_FRAGMENT; 191 return xmlFileLocation; 192 } catch (MalformedURLException e) { 193 FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, e.getMessage(), 0, e, null); 194 adaptor.getFrameworkLog().log(entry); 195 return null; 196 } catch (IOException ioe) { 197 } finally { 199 try { 200 if (stream != null) 201 stream.close(); 202 } catch (IOException e) { 203 } 205 } 206 return null; 207 } 208 209 private ArrayList findWSJars(File pluginRoot, String path, boolean filter) { 210 path = path.substring(4); 211 ArrayList found = new ArrayList(0); 212 for (int i = 0; i < WS_LIST.length; i++) { 213 String searchedPath = "ws/" + WS_LIST[i] + path; if (new File (pluginRoot, searchedPath).exists()) { 215 found.add(searchedPath + (filter ? ";(ws=" + WS_LIST[i] + ")" : "")); } 217 } 218 return found; 219 } 220 221 protected void fillManifest(boolean compatibilityManifest, boolean analyseJars) { 222 generateManifestVersion(); 223 generateHeaders(); 224 generateClasspath(); 225 generateActivator(); 226 generatePluginClass(); 227 if (analyseJars) 228 generateProvidePackage(); 229 generateRequireBundle(); 230 generateLocalizationEntry(); 231 generateEclipseHeaders(); 232 if (compatibilityManifest) { 233 generateTimestamp(); 234 } 235 } 236 237 public void writeManifest(File generationLocation, Dictionary manifestToWrite, boolean compatibilityManifest) throws PluginConversionException { 238 long start = System.currentTimeMillis(); 239 try { 240 File parentFile = new File (generationLocation.getParent()); 241 parentFile.mkdirs(); 242 generationLocation.createNewFile(); 243 if (!generationLocation.isFile()) { 244 String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_ERROR_CREATING_BUNDLE_MANIFEST, this.pluginInfo.getUniqueId(), generationLocation); 245 throw new PluginConversionException(message); 246 } 247 manifestToWrite = new Hashtable((Map) manifestToWrite); 249 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(generationLocation), UTF_8)); 251 writeEntry(MANIFEST_VERSION, (String ) manifestToWrite.remove(MANIFEST_VERSION)); 252 writeEntry(GENERATED_FROM, (String ) manifestToWrite.remove(GENERATED_FROM)); writeEntry(Constants.BUNDLE_MANIFESTVERSION, (String ) manifestToWrite.remove(Constants.BUNDLE_MANIFESTVERSION)); 255 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.EXPORT_PACKAGE, (String ) manifestToWrite.remove(Constants.EXPORT_PACKAGE)); 265 writeEntry(Constants.PROVIDE_PACKAGE, (String ) manifestToWrite.remove(Constants.PROVIDE_PACKAGE)); 267 writeEntry(Constants.REQUIRE_BUNDLE, (String ) manifestToWrite.remove(Constants.REQUIRE_BUNDLE)); 268 Enumeration keys = manifestToWrite.keys(); 269 while (keys.hasMoreElements()) { 270 String key = (String ) keys.nextElement(); 271 writeEntry(key, (String ) manifestToWrite.get(key)); 272 } 273 out.flush(); 274 } catch (IOException e) { 275 String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_ERROR_CREATING_BUNDLE_MANIFEST, this.pluginInfo.getUniqueId(), generationLocation); 276 throw new PluginConversionException(message, e); 277 } finally { 278 if (out != null) 279 try { 280 out.close(); 281 } catch (IOException e) { 282 } 284 } 285 if (DEBUG) 286 System.out.println("Time to write out converted manifest to: " + generationLocation + ": "+ (System.currentTimeMillis() - start) + "ms."); } 288 289 private void generateLocalizationEntry() { 290 generatedManifest.put(Constants.BUNDLE_LOCALIZATION, PLUGIN_PROPERTIES_FILENAME); 291 } 292 293 private void generateManifestVersion() { 294 generatedManifest.put(MANIFEST_VERSION, "1.0"); } 296 297 private boolean requireRuntimeCompatibility() { 298 ArrayList requireList = pluginInfo.getRequires(); 299 for (Iterator iter = requireList.iterator(); iter.hasNext();) { 300 if (((PluginParser.Prerequisite) iter.next()).getName().equalsIgnoreCase(PI_RUNTIME_COMPATIBILITY)) 301 return true; 302 } 303 return false; 304 } 305 306 private void generateActivator() { 307 if (!pluginInfo.isFragment()) 308 if (!requireRuntimeCompatibility()) { 309 String pluginClass = pluginInfo.getPluginClass(); 310 if (pluginClass != null && !pluginClass.trim().equals("")) generatedManifest.put(Constants.BUNDLE_ACTIVATOR, pluginClass); 312 } else { 313 generatedManifest.put(Constants.BUNDLE_ACTIVATOR, COMPATIBILITY_ACTIVATOR); 314 } 315 } 316 317 private void generateClasspath() { 318 String [] classpath = pluginInfo.getLibrariesName(); 319 if (classpath.length != 0) 320 generatedManifest.put(Constants.BUNDLE_CLASSPATH, getStringFromArray(classpath, LIST_SEPARATOR)); 321 } 322 323 private void generateHeaders() { 324 if (TARGET31.compareTo(target) <= 0) 325 generatedManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); generatedManifest.put(Constants.BUNDLE_NAME, pluginInfo.getPluginName()); 327 generatedManifest.put(Constants.BUNDLE_VERSION, pluginInfo.getVersion()); 328 generatedManifest.put(Constants.BUNDLE_SYMBOLICNAME, getSymbolicNameEntry()); 329 String provider = pluginInfo.getProviderName(); 330 if (provider != null) 331 generatedManifest.put(Constants.BUNDLE_VENDOR, provider); 332 if (pluginInfo.isFragment()) { 333 StringBuffer hostBundle = new StringBuffer (); 334 hostBundle.append(pluginInfo.getMasterId()); 335 String versionRange = getVersionRange(pluginInfo.getMasterVersion(), pluginInfo.getMasterMatch()); if (versionRange != null) 337 hostBundle.append(versionRange); 338 generatedManifest.put(Constants.FRAGMENT_HOST, hostBundle.toString()); 339 } 340 } 341 342 346 private String getSymbolicNameEntry() { 347 if (!pluginInfo.isSingleton()) 349 return pluginInfo.getUniqueId(); 350 StringBuffer result = new StringBuffer (pluginInfo.getUniqueId()); 351 result.append(SEMICOLON); 352 result.append(Constants.SINGLETON_DIRECTIVE); 353 String assignment = TARGET31.compareTo(target) <= 0 ? ":=" : "="; result.append(assignment).append("true"); return result.toString(); 356 } 357 358 private void generatePluginClass() { 359 if (requireRuntimeCompatibility()) { 360 String pluginClass = pluginInfo.getPluginClass(); 361 if (pluginClass != null) 362 generatedManifest.put(Constants.PLUGIN_CLASS, pluginClass); 363 } 364 } 365 366 private void generateProvidePackage() { 367 Set exports = getExports(); 368 if (exports != null && exports.size() != 0) { 369 generatedManifest.put(TARGET31.compareTo(target) <= 0 ? Constants.EXPORT_PACKAGE : Constants.PROVIDE_PACKAGE, getStringFromCollection(exports, LIST_SEPARATOR)); 370 } 371 } 372 373 private void generateRequireBundle() { 374 ArrayList requiredBundles = pluginInfo.getRequires(); 375 if (requiredBundles.size() == 0) 376 return; 377 StringBuffer bundleRequire = new StringBuffer (); 378 for (Iterator iter = requiredBundles.iterator(); iter.hasNext();) { 379 PluginParser.Prerequisite element = (PluginParser.Prerequisite) iter.next(); 380 StringBuffer modImport = new StringBuffer (element.getName()); 381 String versionRange = getVersionRange(element.getVersion(), element.getMatch()); 382 if (versionRange != null) 383 modImport.append(versionRange); 384 if (element.isExported()) { 385 if (TARGET31.compareTo(target) <= 0) 386 modImport.append(';').append(Constants.VISIBILITY_DIRECTIVE).append(":=").append(Constants.VISIBILITY_REEXPORT); else 388 modImport.append(';').append(Constants.REPROVIDE_ATTRIBUTE).append("=true"); } 390 if (element.isOptional()) { 391 if (TARGET31.compareTo(target) <= 0) 392 modImport.append(';').append(Constants.RESOLUTION_DIRECTIVE).append(":=").append(Constants.RESOLUTION_OPTIONAL); else 394 modImport.append(';').append(Constants.OPTIONAL_ATTRIBUTE).append("=true"); } 396 bundleRequire.append(modImport.toString()); 397 if (iter.hasNext()) 398 bundleRequire.append(LIST_SEPARATOR); 399 } 400 generatedManifest.put(Constants.REQUIRE_BUNDLE, bundleRequire.toString()); 401 } 402 403 private void generateTimestamp() { 404 generatedManifest.put(GENERATED_FROM, Long.toString(getTimeStamp(pluginManifestLocation, manifestType)) + ";" + MANIFEST_TYPE_ATTRIBUTE + "=" + manifestType); } 407 408 private void generateEclipseHeaders() { 409 if (pluginInfo.isFragment()) 410 return; 411 412 String pluginClass = pluginInfo.getPluginClass(); 413 if (pluginInfo.hasExtensionExtensionPoints() || (pluginClass != null && !pluginClass.trim().equals(""))) generatedManifest.put(TARGET32.compareTo(target) <= 0 ? Constants.ECLIPSE_LAZYSTART : Constants.ECLIPSE_AUTOSTART, "true"); } 416 417 private Set getExports() { 418 Map libs = pluginInfo.getLibraries(); 419 if (libs == null) 420 return null; 421 422 if (devProperties != null || DevClassPathHelper.inDevelopmentMode()) { 424 String [] devClassPath = DevClassPathHelper.getDevClassPath(pluginInfo.getUniqueId(), devProperties); 425 List allExportClauses = new ArrayList(libs.size()); 427 Set libEntries = libs.entrySet(); 428 for (Iterator iter = libEntries.iterator(); iter.hasNext();) { 429 Map.Entry element = (Map.Entry) iter.next(); 430 allExportClauses.addAll((List) element.getValue()); 431 } 432 if (devClassPath != null) { 433 String [] ignoreDotProp = DevClassPathHelper.getDevClassPath(IGNORE_DOT, devProperties); 437 if (devClassPath.length > 0 && ignoreDotProp != null && ignoreDotProp.length > 0 && "true".equals(ignoreDotProp[0])) libs.remove(DOT); 439 for (int i = 0; i < devClassPath.length; i++) 440 libs.put(devClassPath[i], allExportClauses); 441 } 442 } 443 444 Set result = new TreeSet(); 445 Set libEntries = libs.entrySet(); 446 for (Iterator iter = libEntries.iterator(); iter.hasNext();) { 447 Map.Entry element = (Map.Entry) iter.next(); 448 List filter = (List) element.getValue(); 449 if (filter.size() == 0) continue; 451 String libEntryText = ((String ) element.getKey()).trim(); 452 File libraryLocation; 453 if (libEntryText.equals(DOT)) 454 libraryLocation = pluginManifestLocation; 455 else { 456 File libEntryAsPath = new File (libEntryText); 458 libraryLocation = libEntryAsPath.isAbsolute() ? libEntryAsPath : new File (pluginManifestLocation, libEntryText); 459 } 460 Set exports = null; 461 if (libraryLocation.exists()) { 462 if (libraryLocation.isFile()) 463 exports = filterExport(getExportsFromJAR(libraryLocation), filter); else if (libraryLocation.isDirectory()) 465 exports = filterExport(getExportsFromDir(libraryLocation), filter); 466 } else { 467 ArrayList expandedLibs = getLibrariesExpandingVariables((String ) element.getKey(), false); 468 exports = new HashSet(); 469 for (Iterator iterator = expandedLibs.iterator(); iterator.hasNext();) { 470 String libName = (String ) iterator.next(); 471 File libFile = new File (pluginManifestLocation, libName); 472 if (libFile.isFile()) { 473 exports.addAll(filterExport(getExportsFromJAR(libFile), filter)); 474 } 475 } 476 } 477 if (exports != null) 478 result.addAll(exports); 479 } 480 return result; 481 } 482 483 private Set getExportsFromDir(File location) { 484 return getExportsFromDir(location, ""); } 486 487 private Set getExportsFromDir(File location, String packageName) { 488 String prefix = (packageName.length() > 0) ? (packageName + '.') : ""; String [] files = location.list(); 490 Set exportedPaths = new HashSet(); 491 boolean containsFile = false; 492 if (files != null) 493 for (int i = 0; i < files.length; i++) { 494 if (!isValidPackageName(files[i])) 495 continue; 496 File pkgFile = new File (location, files[i]); 497 if (pkgFile.isDirectory()) 498 exportedPaths.addAll(getExportsFromDir(pkgFile, prefix + files[i])); 499 else 500 containsFile = true; 501 } 502 if (containsFile) 503 if (packageName.length() > 0) 506 exportedPaths.add(packageName); 507 else 508 exportedPaths.add(DOT); 509 return exportedPaths; 510 } 511 512 private Set getExportsFromJAR(File jarFile) { 513 Set names = new HashSet(); 514 ZipFile file = null; 515 try { 516 file = new ZipFile (jarFile); 517 } catch (IOException e) { 518 String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_PLUGIN_LIBRARY_IGNORED, jarFile, pluginInfo.getUniqueId()); 519 adaptor.getFrameworkLog().log(new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null)); 520 return names; 521 } 522 for (Enumeration entriesEnum = file.entries(); entriesEnum.hasMoreElements();) { 524 ZipEntry entry = (ZipEntry ) entriesEnum.nextElement(); 525 String name = entry.getName(); 526 if (!isValidPackageName(name)) 527 continue; 528 int lastSlash = name.lastIndexOf("/"); if (lastSlash != -1) { 531 if (lastSlash != name.length() - 1 && name.lastIndexOf(' ') == -1) 532 names.add(name.substring(0, lastSlash).replace('/', '.')); 533 } else { 534 names.add(DOT); 537 } 538 } 539 try { 540 file.close(); 541 } catch (IOException e) { 542 } 544 return names; 545 } 546 547 private ArrayList getLibrariesExpandingVariables(String libraryPath, boolean filter) { 548 String var = hasPrefix(libraryPath); 549 if (var == null) { 550 ArrayList returnValue = new ArrayList(1); 551 returnValue.add(libraryPath); 552 return returnValue; 553 } 554 if (var.equals("ws")) { return findWSJars(pluginManifestLocation, libraryPath, filter); 556 } 557 if (var.equals("os")) { return findOSJars(pluginManifestLocation, libraryPath, filter); 559 } 560 return new ArrayList(0); 561 } 562 563 private String hasPrefix(String libPath) { 565 if (libPath.startsWith("$ws$")) return "ws"; if (libPath.startsWith("$os$")) return "os"; if (libPath.startsWith("$nl$")) return "nl"; return null; 572 } 573 574 private boolean isValidPackageName(String name) { 575 if (name.indexOf(' ') > 0 || name.equalsIgnoreCase("META-INF") || name.startsWith("META-INF/")) return false; 577 return true; 578 } 579 580 585 private IPluginInfo parsePluginInfo(URL pluginLocation) throws PluginConversionException { 586 InputStream input = null; 587 try { 588 input = new BufferedInputStream(pluginLocation.openStream()); 589 return new PluginParser(adaptor, context, target).parsePlugin(input); 590 } catch (Exception e) { 591 String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CONVERTER_ERROR_PARSING_PLUGIN_MANIFEST, pluginManifestLocation); 592 throw new PluginConversionException(message, e); 593 } finally { 594 if (input != null) 595 try { 596 input.close(); 597 } catch (IOException e) { 598 } 600 } 601 } 602 603 public static boolean upToDate(File generationLocation, File pluginLocation, byte manifestType) { 604 if (!generationLocation.isFile()) 605 return false; 606 String secondLine = null; 607 BufferedReader reader = null; 608 try { 609 reader = new BufferedReader(new InputStreamReader(new FileInputStream(generationLocation))); 610 reader.readLine(); 611 secondLine = reader.readLine(); 612 } catch (IOException e) { 613 return false; 615 } finally { 616 if (reader != null) 617 try { 618 reader.close(); 619 } catch (IOException e) { 620 } 622 } 623 String tag = GENERATED_FROM + ": "; if (secondLine == null || !secondLine.startsWith(tag)) 625 return false; 626 627 secondLine = secondLine.substring(tag.length()); 628 ManifestElement generatedFrom; 629 try { 630 generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, secondLine)[0]; 631 } catch (BundleException be) { 632 return false; 633 } 634 String timestampStr = generatedFrom.getValue(); 635 try { 636 return Long.parseLong(timestampStr.trim()) == getTimeStamp(pluginLocation, manifestType); 637 } catch (NumberFormatException nfe) { 638 } 640 return false; 641 } 642 643 public static long getTimeStamp(File pluginLocation, byte manifestType) { 644 if ((manifestType & MANIFEST_TYPE_JAR) != 0) 645 return pluginLocation.lastModified(); 646 else if ((manifestType & MANIFEST_TYPE_PLUGIN) != 0) 647 return new File (pluginLocation, PLUGIN_MANIFEST).lastModified(); 648 else if ((manifestType & MANIFEST_TYPE_FRAGMENT) != 0) 649 return new File (pluginLocation, FRAGMENT_MANIFEST).lastModified(); 650 else if ((manifestType & MANIFEST_TYPE_BUNDLE) != 0) 651 return new File (pluginLocation, Constants.OSGI_BUNDLE_MANIFEST).lastModified(); 652 return -1; 653 } 654 655 private void writeEntry(String key, String value) throws IOException { 656 if (value != null && value.length() > 0) { 657 out.write(splitOnComma(key + ": " + value)); out.write('\n'); 659 } 660 } 661 662 private String splitOnComma(String value) { 663 if (value.length() < MAXLINE || value.indexOf(LINE_SEPARATOR) >= 0) 664 return value; String [] values = ManifestElement.getArrayFromList(value); 666 if (values == null || values.length == 0) 667 return value; 668 StringBuffer sb = new StringBuffer (value.length() + ((values.length - 1) * LIST_SEPARATOR.length())); 669 for (int i = 0; i < values.length - 1; i++) 670 sb.append(values[i]).append(LIST_SEPARATOR); 671 sb.append(values[values.length -1]); 672 return sb.toString(); 673 } 674 675 private String getStringFromArray(String [] values, String separator) { 676 if (values == null) 677 return ""; StringBuffer result = new StringBuffer (); 679 for (int i = 0; i < values.length; i++) { 680 if (i > 0) 681 result.append(separator); 682 result.append(values[i]); 683 } 684 return result.toString(); 685 } 686 687 private String getStringFromCollection(Collection collection, String separator) { 688 StringBuffer result = new StringBuffer (); 689 boolean first = true; 690 for (Iterator i = collection.iterator(); i.hasNext();) { 691 if (first) 692 first = false; 693 else 694 result.append(separator); 695 result.append(i.next()); 696 } 697 return result.toString(); 698 } 699 700 public synchronized Dictionary convertManifest(File pluginBaseLocation, boolean compatibility, String target, boolean analyseJars, Dictionary devProperties) throws PluginConversionException { 701 long start = System.currentTimeMillis(); 702 if (DEBUG) 703 System.out.println("Convert " + pluginBaseLocation); init(); 705 this.target = target == null ? TARGET32 : new Version(target); 706 this.devProperties = devProperties; 707 fillPluginInfo(pluginBaseLocation); 708 fillManifest(compatibility, analyseJars); 709 if (DEBUG) 710 System.out.println("Time to convert manifest for: " + pluginBaseLocation + ": " + (System.currentTimeMillis() - start) + "ms."); return generatedManifest; 712 } 713 714 public synchronized File convertManifest(File pluginBaseLocation, File bundleManifestLocation, boolean compatibilityManifest, String target, boolean analyseJars, Dictionary devProperties) throws PluginConversionException { 715 convertManifest(pluginBaseLocation, compatibilityManifest, target, analyseJars, devProperties); 716 if (bundleManifestLocation == null) { 717 String cacheLocation = FrameworkProperties.getProperty(LocationManager.PROP_MANIFEST_CACHE); 718 bundleManifestLocation = new File (cacheLocation, pluginInfo.getUniqueId() + '_' + pluginInfo.getVersion() + ".MF"); } 720 if (upToDate(bundleManifestLocation, pluginManifestLocation, manifestType)) 721 return bundleManifestLocation; 722 writeManifest(bundleManifestLocation, generatedManifest, compatibilityManifest); 723 return bundleManifestLocation; 724 } 725 726 private String getVersionRange(String reqVersion, String matchRule) { 727 if (reqVersion == null) 728 return null; 729 730 Version minVersion = Version.parseVersion(reqVersion); 731 String versionRange; 732 if (matchRule != null) { 733 if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_PERFECT)) { 734 versionRange = new VersionRange(minVersion, true, minVersion, true).toString(); 735 } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_EQUIVALENT)) { 736 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor(), minVersion.getMinor() + 1, 0, ""), false).toString(); } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_COMPATIBLE)) { 738 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor() + 1, 0, 0, ""), false).toString(); } else if (matchRule.equalsIgnoreCase(IModel.PLUGIN_REQUIRES_MATCH_GREATER_OR_EQUAL)) { 740 versionRange = reqVersion; 742 } else { 743 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor() + 1, 0, 0, ""), false).toString(); } 745 } else { 746 versionRange = new VersionRange(minVersion, true, new Version(minVersion.getMajor() + 1, 0, 0, ""), false).toString(); } 748 749 StringBuffer result = new StringBuffer (); 750 result.append(';').append(Constants.BUNDLE_VERSION_ATTRIBUTE).append('='); 751 result.append('\"').append(versionRange).append('\"'); 752 return result.toString(); 753 } 754 } 755 | Popular Tags |