1 11 package org.eclipse.pde.internal.build.builder; 12 13 import java.io.File ; 14 import java.io.IOException ; 15 import java.net.MalformedURLException ; 16 import java.net.URL ; 17 import java.util.*; 18 import org.eclipse.core.internal.boot.PlatformURLHandler; 19 import org.eclipse.core.internal.runtime.PlatformURLFragmentConnection; 20 import org.eclipse.core.internal.runtime.PlatformURLPluginConnection; 21 import org.eclipse.core.runtime.*; 22 import org.eclipse.osgi.service.resolver.*; 23 import org.eclipse.osgi.util.NLS; 24 import org.eclipse.pde.internal.build.*; 25 import org.eclipse.pde.internal.build.site.PDEState; 26 import org.eclipse.update.core.IPluginEntry; 27 import org.osgi.framework.Filter; 28 29 public class ClasspathComputer3_0 implements IClasspathComputer, IPDEBuildConstants, IXMLConstants, IBuildPropertiesConstants { 30 public static class ClasspathElement { 31 private String path; 32 private String accessRules; 33 34 40 public ClasspathElement(String path, String accessRules){ 41 this.path = path; 42 this.accessRules = accessRules; 43 } 44 public String toString() { 45 return path; 46 } 47 public String getPath() { 48 return path; 49 } 50 public String getAccessRules(){ 51 return accessRules; 52 } 53 public void addRules(String newRule){ 54 if (accessRules.equals("") || accessRules.equals(newRule)) return; 56 if (!newRule.equals("")) { String join = accessRules.substring(0, accessRules.length() - EXCLUDE_ALL_RULE.length() - 1); 58 newRule = join + newRule.substring(1); 59 } 60 accessRules = newRule; 61 return; 62 } 63 67 public boolean equals(Object obj) { 68 if (obj instanceof ClasspathElement) { 69 ClasspathElement element = (ClasspathElement) obj; 70 return (path != null && path.equals(element.getPath())); 71 } 72 return false; 73 } 74 public int hashCode() { 75 return path.hashCode(); 76 } 77 78 public static String normalize(String path) { 79 return path.replaceAll("\\\\", "/"); } 82 } 83 84 private static final String EXCLUDE_ALL_RULE = "?**/*"; 86 private ModelBuildScriptGenerator generator; 87 private Map visiblePackages = null; 88 private Map pathElements = null; 89 90 public ClasspathComputer3_0(ModelBuildScriptGenerator modelGenerator) { 91 this.generator = modelGenerator; 92 } 93 94 103 public List getClasspath(BundleDescription model, ModelBuildScriptGenerator.CompiledEntry jar) throws CoreException { 104 List classpath = new ArrayList(20); 105 List pluginChain = new ArrayList(10); String location = generator.getLocation(model); 107 Set addedPlugins = new HashSet(10); pathElements = new HashMap(); 109 visiblePackages = getVisiblePackages(model); 110 111 addPrerequisites(model, classpath, location, pluginChain, addedPlugins); 113 114 addSelf(model, jar, classpath, location, pluginChain, addedPlugins); 116 117 return classpath; 118 119 } 120 121 private Map getVisiblePackages(BundleDescription model) { 122 Map packages = new HashMap(20); 123 StateHelper helper = Platform.getPlatformAdmin().getStateHelper(); 124 addVisiblePackagesFromState(helper, model, packages); 125 if (model.getHost() != null) 126 addVisiblePackagesFromState(helper, (BundleDescription)model.getHost().getSupplier(), packages); 127 return packages; 128 } 129 130 private void addVisiblePackagesFromState(StateHelper helper, BundleDescription model, Map packages) { 131 ExportPackageDescription[] exports = helper.getVisiblePackages(model); 132 for (int i = 0; i < exports.length; i++) { 133 BundleDescription exporter = exports[i].getExporter(); 134 if (exporter == null) 135 continue; 136 137 boolean discouraged = helper.getAccessCode(model, exports[i]) == StateHelper.ACCESS_DISCOURAGED; 138 String pattern = exports[i].getName().replaceAll("\\.", "/") + "/*"; String rule = (discouraged ? '~' : '+') + pattern; 140 141 String rules = (String ) packages.get(exporter.getSymbolicName()); 142 if (rules != null) { 143 if (rules.indexOf(rule) == -1) 144 rules = (rules != null) ? rules + File.pathSeparator + rule : rule; 145 } else { 146 rules = rule; 147 } 148 149 packages.put(exporter.getSymbolicName(), rules); 150 } 151 } 152 159 private void addPlugin(BundleDescription plugin, List classpath, String location) throws CoreException { 160 boolean allFragments = true; 161 String patchInfo = (String ) generator.getSite(false).getRegistry().getPatchData().get(new Long (plugin.getBundleId())); 162 if (patchInfo != null && plugin != generator.getModel()) { 163 addFragmentsLibraries(plugin, classpath, location, false, false); 164 allFragments = false; 165 } 166 addRuntimeLibraries(plugin, classpath, location); 167 addFragmentsLibraries(plugin, classpath, location, true, allFragments); 168 } 169 170 177 private void addRuntimeLibraries(BundleDescription model, List classpath, String baseLocation) throws CoreException { 178 String [] libraries = getClasspathEntries(model); 179 String root = generator.getLocation(model); 180 IPath base = Utils.makeRelative(new Path(root), new Path(baseLocation)); 181 Properties modelProps = getBuildPropertiesFor(model); 182 ModelBuildScriptGenerator.specialDotProcessing(modelProps, libraries); 183 for (int i = 0; i < libraries.length; i++) { 184 addDevEntries(model, baseLocation, classpath, Utils.getArrayFromString(modelProps.getProperty(PROPERTY_OUTPUT_PREFIX + libraries[i]))); 185 addPathAndCheck(model, base, libraries[i], modelProps, classpath); 186 } 187 } 188 189 196 private void addFragmentsLibraries(BundleDescription plugin, List classpath, String baseLocation, boolean afterPlugin, boolean all) throws CoreException { 197 BundleDescription[] fragments = plugin.getFragments(); 199 if (fragments == null) 200 return; 201 202 for (int i = 0; i < fragments.length; i++) { 203 if (fragments[i] == generator.getModel()) 204 continue; 205 if (matchFilter(fragments[i]) == false) 206 continue; 207 if (! afterPlugin && isPatchFragment(fragments[i])) { 208 addPluginLibrariesToFragmentLocations(plugin, fragments[i], classpath, baseLocation); 209 addRuntimeLibraries(fragments[i], classpath, baseLocation); 210 continue; 211 } 212 if ( (afterPlugin && !isPatchFragment(fragments[i])) || all) { 213 addRuntimeLibraries(fragments[i], classpath, baseLocation); 214 addPluginLibrariesToFragmentLocations(plugin, fragments[i], classpath, baseLocation); 215 continue; 216 } 217 } 218 } 219 220 private boolean isPatchFragment(BundleDescription fragment) throws CoreException { 221 return generator.getSite(false).getRegistry().getPatchData().get(new Long (fragment.getBundleId())) != null; 222 } 223 224 235 private void addPluginLibrariesToFragmentLocations(BundleDescription plugin, BundleDescription fragment, List classpath, String baseLocation) throws CoreException { 236 String [] libraries = getClasspathEntries(plugin); 241 242 String root = generator.getLocation(fragment); 243 IPath base = Utils.makeRelative(new Path(root), new Path(baseLocation)); 244 Properties modelProps = getBuildPropertiesFor(fragment); 245 for (int i = 0; i < libraries.length; i++) { 246 addPathAndCheck(fragment, base, libraries[i], modelProps, classpath); 247 } 248 } 249 250 private Properties getBuildPropertiesFor(BundleDescription bundle) { 251 try { 252 Properties bundleProperties = AbstractScriptGenerator.readProperties(generator.getLocation(bundle), PROPERTIES_FILE, IStatus.OK); 253 if (Utils.isStringIn(generator.getClasspathEntries(bundle), ModelBuildScriptGenerator.DOT) != -1) { 254 String sourceFolder = bundleProperties.getProperty(PROPERTY_SOURCE_PREFIX + ModelBuildScriptGenerator.DOT); 255 if (sourceFolder != null) { 256 bundleProperties.setProperty(PROPERTY_SOURCE_PREFIX + ModelBuildScriptGenerator.EXPANDED_DOT, sourceFolder); 257 bundleProperties.remove(PROPERTY_SOURCE_PREFIX + ModelBuildScriptGenerator.DOT); 258 } 259 String outputValue = bundleProperties.getProperty(PROPERTY_OUTPUT_PREFIX + ModelBuildScriptGenerator.DOT); 260 if (outputValue != null) { 261 bundleProperties.setProperty(PROPERTY_OUTPUT_PREFIX + ModelBuildScriptGenerator.EXPANDED_DOT, outputValue); 262 bundleProperties.remove(PROPERTY_OUTPUT_PREFIX + ModelBuildScriptGenerator.DOT); 263 } 264 } 265 return bundleProperties; 266 } catch (CoreException e) { 267 } 269 return null; 270 } 271 272 private void addPathAndCheck(BundleDescription model, IPath basePath, String libraryName, Properties modelProperties, List classpath) { 277 String pluginId = model != null ? model.getSymbolicName() : null; 278 String rules = ""; BundleDescription currentBundle = generator.getModel(); 282 if (model != null && model != currentBundle && (currentBundle.getHost() == null || currentBundle.getHost().getSupplier() != model) ) { 283 String packageKey = pluginId; 284 if (model.isResolved() && model.getHost() != null) { 285 packageKey = ((BundleDescription) model.getHost().getSupplier()).getSymbolicName(); 286 } 287 if (visiblePackages.containsKey(packageKey)) { 288 rules = "[" + (String ) visiblePackages.get(packageKey) + File.pathSeparator + EXCLUDE_ALL_RULE + "]"; } else { 290 rules = "[" + EXCLUDE_ALL_RULE + "]"; } 292 } 293 294 String path = null; 295 if ("jar".equalsIgnoreCase(basePath.getFileExtension())) { path = basePath.toOSString(); 297 } else { 298 Path libraryPath = new Path(libraryName); 299 if (libraryPath.isAbsolute()) 300 path = libraryPath.toOSString(); 301 else 302 path = basePath.append(libraryPath).toOSString(); 303 } 304 path = generator.replaceVariables(path, pluginId == null ? false : generator.getCompiledElements().contains(pluginId)); 305 String secondaryPath = null; 306 if (generator.getCompiledElements().contains(pluginId)) { 307 if (modelProperties == null || modelProperties.getProperty(IBuildPropertiesConstants.PROPERTY_SOURCE_PREFIX + libraryName) != null) 308 path = Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + '/' + path; 309 secondaryPath = Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + "/../" + model.getSymbolicName() + '_' + model.getVersion() + '/' + libraryName; 311 } 312 313 addClasspathElementWithRule(classpath, path, rules); 314 if (secondaryPath != null) { 315 addClasspathElementWithRule(classpath, secondaryPath, rules); 316 } 317 } 318 319 private void addClasspathElementWithRule(List classpath, String path, String rules) { 320 String normalizedPath = ClasspathElement.normalize(path); 321 ClasspathElement existing = (ClasspathElement) pathElements.get(normalizedPath); 322 if (existing != null){ 323 existing.addRules( rules); 324 } else { 325 ClasspathElement element = new ClasspathElement(normalizedPath, rules); 326 classpath.add(element); 327 pathElements.put(normalizedPath, element); 328 } 329 } 330 331 private void addSelf(BundleDescription model, ModelBuildScriptGenerator.CompiledEntry jar, List classpath, String location, List pluginChain, Set addedPlugins) throws CoreException { 332 HostSpecification host = model.getHost(); 334 if (host != null) { 335 BundleDescription[] hosts = host.getHosts(); 336 for (int i = 0; i < hosts.length; i++) 337 addPluginAndPrerequisites(hosts[i], classpath, location, pluginChain, addedPlugins); 338 } 339 340 Properties modelProperties = generator.getBuildProperties(); 342 String jarOrder = (String ) modelProperties.get(PROPERTY_JAR_ORDER); 343 if (jarOrder == null) { 344 String [] libraries = getClasspathEntries(model); 347 if (libraries != null) { 348 for (int i = 0; i < libraries.length; i++) { 349 String libraryName = libraries[i]; 350 if (jar.getName(false).equals(libraryName)) 351 continue; 352 353 boolean isSource = (modelProperties.getProperty(PROPERTY_SOURCE_PREFIX + libraryName) != null); 354 if (isSource) { 355 addDevEntries(model, location, classpath, Utils.getArrayFromString(modelProperties.getProperty(PROPERTY_OUTPUT_PREFIX + libraryName))); 356 } 357 addPathAndCheck(model, Path.EMPTY, libraryName, modelProperties, classpath); 361 } 362 } 363 } else { 364 String [] order = Utils.getArrayFromString(jarOrder); 366 for (int i = 0; i < order.length; i++) { 367 if (order[i].equals(jar.getName(false))) 368 break; 369 addDevEntries(model, location, classpath, Utils.getArrayFromString((String ) modelProperties.get(PROPERTY_OUTPUT_PREFIX + order[i]))); 370 addPathAndCheck(model, Path.EMPTY, order[i], modelProperties, classpath); 371 } 372 String [] libraries = getClasspathEntries(model); 374 for (int i = 0; i < libraries.length; i++) { 375 String libraryName = libraries[i]; 376 if (modelProperties.get(PROPERTY_SOURCE_PREFIX + libraryName) == null) { 377 addPathAndCheck(model, Path.EMPTY, libraryName, modelProperties, classpath); 380 } 381 } 382 } 383 384 String extraClasspath = (String ) modelProperties.get(PROPERTY_JAR_EXTRA_CLASSPATH); 386 if (extraClasspath != null) { 387 String [] extra = Utils.getArrayFromString(extraClasspath, ";,"); 389 for (int i = 0; i < extra.length; i++) { 390 String toAdd = computeExtraPath(extra[i], classpath, location); 393 if (toAdd != null) 394 addPathAndCheck(null, new Path(toAdd), "", modelProperties, classpath); } 396 } 397 398 String [] jarSpecificExtraClasspath = jar.getExtraClasspath(); 400 for (int i = 0; i < jarSpecificExtraClasspath.length; i++) { 401 String toAdd = computeExtraPath(jarSpecificExtraClasspath[i], classpath, location); 404 if (toAdd != null) 405 addPathAndCheck(null, new Path(toAdd), "", modelProperties, classpath); } 407 } 408 409 416 private String computeExtraPath(String url, List classpath, String location) throws CoreException { 417 String relativePath = null; 418 419 String [] urlfragments = Utils.getArrayFromString(url, "/"); 421 if (urlfragments.length > 2 && urlfragments[0].equals(PlatformURLHandler.PROTOCOL + PlatformURLHandler.PROTOCOL_SEPARATOR)) { 423 String modelLocation = null; 424 BundleDescription bundle = null; 425 if (urlfragments[1].equalsIgnoreCase(PlatformURLPluginConnection.PLUGIN) || urlfragments[1].equalsIgnoreCase(PlatformURLFragmentConnection.FRAGMENT)) 426 bundle = generator.getSite(false).getRegistry().getResolvedBundle(urlfragments[2]); 427 428 if (urlfragments.length == 3) { 429 addPlugin(bundle, classpath, location); 430 return null; 431 } 432 433 modelLocation = generator.getLocation(bundle); 434 435 if (urlfragments[1].equalsIgnoreCase("resource")) { String message = NLS.bind(Messages.exception_url, generator.getPropertiesFileName() + "::" + url); throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_MALFORMED_URL, message, null)); 438 } 439 if (modelLocation != null) { 440 for (int i = 3; i < urlfragments.length; i++) { 441 modelLocation += '/' + urlfragments[i]; 442 } 443 return relativePath = Utils.makeRelative(new Path(modelLocation), new Path(location)).toOSString(); 444 } 445 } 446 447 try { 449 URL extraURL = new URL (url); 450 try { 451 relativePath = Utils.makeRelative(new Path(Platform.resolve(extraURL).getFile()), new Path(location)).toOSString(); 452 } catch (IOException e) { 453 String message = NLS.bind(Messages.exception_url, generator.getPropertiesFileName() + "::" + url); throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_MALFORMED_URL, message, e)); 455 } 456 } catch (MalformedURLException e) { 457 relativePath = url; 458 } 462 return relativePath; 463 } 464 465 private void addPrerequisites(BundleDescription target, List classpath, String baseLocation, List pluginChain, Set addedPlugins) throws CoreException { 467 if (pluginChain.contains(target)) { 468 String cycleString = ""; for (Iterator iter = pluginChain.iterator(); iter.hasNext();) 470 cycleString += iter.next().toString() + ", "; cycleString += target.toString(); 472 String message = NLS.bind(Messages.error_pluginCycle, cycleString); 473 throw new CoreException(new Status(IStatus.ERROR, IPDEBuildConstants.PI_PDEBUILD, EXCEPTION_CLASSPATH_CYCLE, message, null)); 474 } 475 if (addedPlugins.contains(target)) return; 477 478 BundleDescription[] requires = PDEState.getDependentBundles(target); 481 pluginChain.add(target); 482 for (int i = 0; i < requires.length; i++) { 483 addPluginAndPrerequisites(requires[i], classpath, baseLocation, pluginChain, addedPlugins); 484 } 485 pluginChain.remove(target); 486 addedPlugins.add(target); 487 } 488 489 500 private void addPluginAndPrerequisites(BundleDescription target, List classpath, String baseLocation, List pluginChain, Set addedPlugins) throws CoreException { 501 if (matchFilter(target) == false) 502 return; 503 504 addPlugin(target, classpath, baseLocation); 505 addPrerequisites(target, classpath, baseLocation, pluginChain, addedPlugins); 506 } 507 508 private boolean matchFilter(BundleDescription target) { 509 String filter = target.getPlatformFilter(); 510 if (filter == null) return true; 512 513 IPluginEntry associatedEntry = generator.getAssociatedEntry(); 514 if (associatedEntry == null) 515 return true; 516 517 String os = associatedEntry.getOS(); 518 String ws = associatedEntry.getWS(); 519 String arch = associatedEntry.getOSArch(); 520 String nl = associatedEntry.getNL(); 521 if (os == null && ws == null && arch == null && nl == null) return true; 523 524 Filter f = BundleHelper.getDefault().createFilter(filter); 526 if (f == null) 527 return true; 528 529 Dictionary properties = new Hashtable(3); 530 if (os != null) { 531 properties.put(OSGI_OS, os); 532 } else { 533 properties.put(OSGI_OS, CatchAllValue.singleton); 534 } 535 if (ws != null) 536 properties.put(OSGI_WS, ws); 537 else 538 properties.put(OSGI_WS, CatchAllValue.singleton); 539 540 if (arch != null) 541 properties.put(OSGI_ARCH, arch); 542 else 543 properties.put(OSGI_ARCH, CatchAllValue.singleton); 544 545 if (arch != null) 546 properties.put(OSGI_NL, arch); 547 else 548 properties.put(OSGI_NL, CatchAllValue.singleton); 549 550 return f.match(properties); 551 } 552 553 559 private void addDevEntries(BundleDescription model, String baseLocation, List classpath, String [] jarSpecificEntries) { 560 if (generator.devEntries == null && (jarSpecificEntries == null || jarSpecificEntries.length == 0)) 561 return; 562 563 String [] entries; 564 if (jarSpecificEntries != null && jarSpecificEntries.length > 0) 566 entries = jarSpecificEntries; 567 else 568 entries = generator.devEntries.getDevClassPath(model.getSymbolicName()); 569 570 IPath root = Utils.makeRelative(new Path(generator.getLocation(model)), new Path(baseLocation)); 571 for (int i = 0; i < entries.length; i++) { 572 addPathAndCheck(model, root, entries[i], null, classpath); 573 } 574 } 575 576 private String [] getClasspathEntries(BundleDescription bundle) throws CoreException { 578 return generator.getClasspathEntries(bundle); 579 } 580 } 581 | Popular Tags |