1 11 package org.eclipse.pde.internal.builders; 12 13 import java.util.HashMap ; 14 import java.util.Map ; 15 16 import org.eclipse.core.resources.IFile; 17 import org.eclipse.core.resources.IProject; 18 import org.eclipse.core.resources.IResource; 19 import org.eclipse.core.runtime.CoreException; 20 import org.eclipse.core.runtime.IProgressMonitor; 21 import org.eclipse.core.runtime.IStatus; 22 import org.eclipse.core.runtime.PluginVersionIdentifier; 23 import org.eclipse.core.runtime.Status; 24 import org.eclipse.jdt.core.IJavaElement; 25 import org.eclipse.jdt.core.IJavaProject; 26 import org.eclipse.jdt.core.IPackageFragment; 27 import org.eclipse.jdt.core.IPackageFragmentRoot; 28 import org.eclipse.jdt.core.IType; 29 import org.eclipse.jdt.core.JavaCore; 30 import org.eclipse.jdt.core.JavaModelException; 31 import org.eclipse.jface.text.BadLocationException; 32 import org.eclipse.jface.text.IRegion; 33 import org.eclipse.osgi.service.resolver.BundleDescription; 34 import org.eclipse.osgi.service.resolver.ExportPackageDescription; 35 import org.eclipse.osgi.service.resolver.VersionRange; 36 import org.eclipse.osgi.util.ManifestElement; 37 import org.eclipse.osgi.util.NLS; 38 import org.eclipse.pde.core.plugin.IFragmentModel; 39 import org.eclipse.pde.core.plugin.IPluginBase; 40 import org.eclipse.pde.core.plugin.IPluginModel; 41 import org.eclipse.pde.core.plugin.IPluginModelBase; 42 import org.eclipse.pde.internal.PDE; 43 import org.eclipse.pde.internal.PDEMessages; 44 import org.eclipse.pde.internal.core.ICoreConstants; 45 import org.eclipse.pde.internal.core.PDECore; 46 import org.eclipse.pde.internal.core.search.PluginJavaSearchUtil; 47 import org.eclipse.pde.internal.core.util.IdUtil; 48 import org.osgi.framework.Constants; 49 import org.osgi.framework.InvalidSyntaxException; 50 import org.osgi.framework.Version; 51 52 public class BundleErrorReporter extends JarManifestErrorReporter { 53 private static final String COMPATIBILITY_PLUGIN = "org.eclipse.core.runtime.compatibility"; 55 private static final String COMPATIBILITY_ACTIVATOR = "org.eclipse.core.internal.compatibility.PluginActivator"; 57 63 protected static IStatus validateVersionString(String versionString) { 64 if (versionString == null) 65 return Status.OK_STATUS; 66 return PluginVersionIdentifier.validateVersion(versionString); 67 } 68 69 protected static IStatus validateVersionRange(String versionRangeString) { 70 try { 71 new VersionRange(versionRangeString); 72 } catch (IllegalArgumentException e) { 73 return new Status(IStatus.ERROR, PDE.PLUGIN_ID, IStatus.ERROR, 74 PDEMessages.BundleErrorReporter_invalidVersionRangeFormat, e); } 76 77 int comma = versionRangeString.indexOf(','); 79 if (comma < 0) { 80 return validateVersionString(versionRangeString); 81 } 82 83 IStatus status = validateVersionString(versionRangeString.substring(1, comma)); 84 if(!status.isOK()){ 85 return status; 86 } 87 return validateVersionString(versionRangeString 88 .substring(comma + 1, versionRangeString.length() - 1)); 89 } 90 91 private boolean fEclipse3_1; 92 93 private boolean fHasExtensibleApi = false; 94 95 private boolean fFragment; 96 97 private Map fFragmentsPackagesMap = null; 98 99 private Map fHostPackagesMap = null; 100 101 private boolean fHasFragment_Xml; 102 103 private boolean fHasExtensions; 104 105 private String fHostBundleId; 106 107 private String fPluginId = ""; 111 private Map fProjectPackagesMap = null; 112 113 private boolean fCompatibility = false; 114 115 private boolean fCompatibilityActivator = false; 116 117 public BundleErrorReporter(IFile file) { 118 super(file); 119 } 120 121 124 private void addProjectPackages(Map map, IProject proj) { 125 try { 126 if (!proj.hasNature(JavaCore.NATURE_ID)) { 127 return; 128 } 129 } catch (CoreException ce) { 130 return; 131 } 132 IJavaProject jp = JavaCore.create(proj); 133 try { 134 IPackageFragmentRoot[] roots = jp.getPackageFragmentRoots(); 135 for (int i = 0; i < roots.length; i++) { 136 if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE 137 || (roots[i].getKind() == IPackageFragmentRoot.K_BINARY && !roots[i] 138 .isExternal())) { 139 IJavaElement[] children = roots[i].getChildren(); 140 for (int j = 0; j < children.length; j++) { 141 IPackageFragment f = (IPackageFragment) children[j]; 142 map.put(f.getElementName(), f); 143 } 144 } 145 } 146 } catch (JavaModelException e) { 147 } 148 } 149 150 153 private HashMap getAvailableBundles() { 154 HashMap map = new HashMap (); 155 IPluginModelBase[] plugins = PDECore.getDefault().getModelManager() 156 .getPlugins(); 157 158 for (int i = 0; i < plugins.length; i++) { 159 IPluginBase element = plugins[i].getPluginBase(); 160 if ((element.getId() != null) && !element.getId().equals(fPluginId)) { 161 map.put(element.getId(), plugins[i]); 163 } 164 } 165 return map; 166 } 167 168 171 private HashMap getAvailableExportedPackages() { 172 IPluginModelBase[] plugins = PDECore.getDefault().getModelManager() 173 .getPlugins(); 174 175 HashMap map = new HashMap (); 176 for (int i = 0; i < plugins.length; i++) { 177 if ((plugins[i].getPluginBase().getId() != null)) { 178 BundleDescription bd = plugins[i].getBundleDescription(); 179 if (bd != null) { 180 ExportPackageDescription[] elements = bd 181 .getExportPackages(); 182 if (elements != null) { 183 for (int j = 0; j < elements.length; j++) { 184 map.put(elements[j].getName(), elements[j]); 185 } 186 } 187 } 188 } 189 } 190 return map; 191 } 192 193 196 private Map getFragmentsPackages() { 197 if (fFragmentsPackagesMap == null) { 198 Map map = new HashMap (); 199 IFragmentModel[] models = PDECore.getDefault().getModelManager() 200 .getFragments(); 201 for (int i = 0; i < models.length; i++) { 202 String hostId = models[i].getFragment().getPluginId(); 203 if (!fPluginId.equals(hostId)) { 204 continue; 205 } 206 IResource resource = models[i].getUnderlyingResource(); 207 if (resource != null) { 208 addProjectPackages(map, resource.getProject()); 209 210 } 211 } 212 fFragmentsPackagesMap = map; 213 } 214 return fFragmentsPackagesMap; 215 } 216 217 220 private Map getHostPackages() { 221 if (fHostPackagesMap == null) { 222 Map map = new HashMap (); 223 if (fHostBundleId != null) { 224 IPluginModel model = PDECore.getDefault().getModelManager() 225 .findPluginModel(fHostBundleId); 226 if (model == null) { 227 return map; 228 } 229 IResource resource = model.getUnderlyingResource(); 230 if (resource != null) { 231 addProjectPackages(map, resource.getProject()); 232 } else { 233 try { 234 if (fProject.hasNature(JavaCore.NATURE_ID)) { 235 IPackageFragment[] packages = PluginJavaSearchUtil 236 .collectPackageFragments( 237 new IPluginBase[] { model 238 .getPluginBase() }, 239 JavaCore.create(fProject), false); 240 for (int i = 0; i < packages.length; i++) 241 map.put(packages[i].getElementName(), 242 packages[i]); 243 } 244 } catch (JavaModelException jme) { 245 PDE.log(jme); 246 } catch (CoreException ce) { 247 } 248 } 249 } 250 fHostPackagesMap = map; 251 } 252 return fHostPackagesMap; 253 } 254 255 private int getPackageLine(IHeader header, ManifestElement element) { 256 String packageName = element.getValue(); 257 if (element.getDirectiveKeys() != null || element.getKeys() != null) 258 return getLine(header, packageName + ";"); 260 try { 262 IRegion lineRegion = fTextDocument.getLineInformation(header 263 .getLineNumber() 264 + header.getLinesSpan() - 1); 265 String lineStr = fTextDocument.get(lineRegion.getOffset(), 266 lineRegion.getLength()); 267 if (lineStr.endsWith(packageName)) { 268 return header.getLineNumber() + header.getLinesSpan(); 269 } 270 } catch (BadLocationException ble) { 271 PDECore.logException(ble); 272 } 273 274 return getLine(header, packageName + ","); } 277 278 281 private Map getProjectPackages() { 282 if (fProjectPackagesMap == null) { 283 Map map = new HashMap (); 284 addProjectPackages(map, fProject); 285 fProjectPackagesMap = map; 286 } 287 return fProjectPackagesMap; 288 } 289 290 protected boolean isCheckDeprecated() { 291 return CompilerFlags.getFlag(fProject, CompilerFlags.P_DEPRECATED) != CompilerFlags.IGNORE; 292 } 293 294 protected boolean isCheckNoRequiredAttr() { 295 return CompilerFlags.getFlag(fProject, CompilerFlags.P_NO_REQUIRED_ATT) != CompilerFlags.IGNORE; 296 } 297 298 protected boolean isCheckUnknownAttr() { 299 return CompilerFlags.getFlag(fProject, 300 CompilerFlags.P_UNKNOWN_ATTRIBUTE) != CompilerFlags.IGNORE; 301 } 302 303 protected boolean isCheckUnknownClass() { 304 return CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_CLASS) != CompilerFlags.IGNORE; 305 } 306 307 protected boolean isCheckUnresolvedImports() { 308 return CompilerFlags.getFlag(fProject, 309 CompilerFlags.P_UNRESOLVED_IMPORTS) != CompilerFlags.IGNORE; 310 } 311 312 325 private void readBundleManifestVersion() { 326 IHeader header = (IHeader) fHeaders 327 .get(Constants.BUNDLE_MANIFESTVERSION); 328 if (header == null) { 329 return; 330 } 331 try { 332 Version v = new Version(header.getValue()); 333 if (v.getMajor() >= 2) { 334 fEclipse3_1 = true; 335 } 336 } catch (NumberFormatException nfe) { 337 } 338 } 339 340 private void validateBundleActivator() { 341 IHeader header = (IHeader) fHeaders.get(Constants.BUNDLE_ACTIVATOR); 342 if (header == null) { 343 return; 344 } 345 String activator = header.getValue(); 346 fCompatibilityActivator = COMPATIBILITY_ACTIVATOR.equals(activator); 347 String message; 348 if (fFragment) { 349 350 message = PDEMessages.BundleErrorReporter_fragmentActivator; report(message, header.getLineNumber() + 1, CompilerFlags.ERROR); 352 return; 353 } 354 if (isCheckUnknownClass()) { 355 try { 356 if (!fProject.hasNature(JavaCore.NATURE_ID)) { 357 return; 358 } 359 } catch (CoreException ce) { 360 return; 361 } 362 IJavaProject javaProject = JavaCore.create(fProject); 363 try { 364 IType type = javaProject.findType(activator); 366 367 if (!fCompatibilityActivator) { 368 369 if (type == null || !type.exists()) { 370 message = NLS.bind( 371 PDEMessages.BundleErrorReporter_NoExist, 372 activator); report(message, getLine(header, activator), 374 CompilerFlags.P_UNKNOWN_CLASS); 375 return; 376 } 377 378 IPackageFragmentRoot pfroot = (IPackageFragmentRoot) type 380 .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); 381 if (pfroot != null && pfroot.isExternal()) { 382 message = NLS 383 .bind( 384 PDEMessages.BundleErrorReporter_externalClass, 385 activator); report(message, getLine(header, activator), 387 CompilerFlags.P_UNKNOWN_CLASS); 388 return; 389 } 390 } else { 391 if (!fCompatibility) { 392 message = NLS 393 .bind( 394 PDEMessages.BundleErrorReporter_unresolvedCompatibilityActivator, 395 activator); report(message, getLine(header, activator), 397 CompilerFlags.P_UNKNOWN_CLASS); 398 return; 399 } 400 } 401 } catch (JavaModelException e) { 402 PDECore.logException(e); 403 } 404 } 405 } 406 407 private void validatePluginClass() { 408 IHeader header = (IHeader) fHeaders.get(ICoreConstants.PLUGIN_CLASS); 409 if (header == null) { 410 return; 411 } 412 String pluginClass = header.getValue(); 413 String message; 414 if (fFragment) { 415 416 message = PDEMessages.BundleErrorReporter_fragmentActivator; report(message, header.getLineNumber() + 1, CompilerFlags.ERROR); 418 return; 419 } 420 if (!fCompatibilityActivator) { 421 if (!fCompatibility) { 422 message = PDEMessages.BundleErrorReporter_unusedPluginClass; report(message, header.getLineNumber() + 1, CompilerFlags.WARNING); 425 } 426 } 427 428 if (isCheckUnknownClass()) { 429 try { 430 if (!fProject.hasNature(JavaCore.NATURE_ID)) { 431 return; 432 } 433 } catch (CoreException ce) { 434 return; 435 } 436 IJavaProject javaProject = JavaCore.create(fProject); 437 try { 438 IType type = javaProject.findType(pluginClass); 440 441 442 if (type == null || !type.exists()) { 443 message = NLS.bind(PDEMessages.BundleErrorReporter_NoExist, 444 pluginClass); report(message, getLine(header, pluginClass), 446 CompilerFlags.P_UNKNOWN_CLASS); 447 return; 448 } 449 450 IPackageFragmentRoot pfroot = (IPackageFragmentRoot) type 452 .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); 453 if (pfroot != null && pfroot.isExternal()) { 454 message = NLS.bind( 455 PDEMessages.BundleErrorReporter_externalClass, 456 pluginClass); report(message, getLine(header, pluginClass), 458 CompilerFlags.P_UNKNOWN_CLASS); 459 return; 460 } 461 } catch (JavaModelException e) { 462 PDECore.logException(e); 463 } 464 } 465 } 466 467 private void validateBundleClasspath() { 468 IHeader header = (IHeader) fHeaders.get(Constants.BUNDLE_CLASSPATH); 469 if (header == null) { 470 return; 471 } 472 String classpath = header.getValue(); 473 474 String message = null; 475 if (classpath.trim().length() == 0) { 476 477 message = PDEMessages.BundleErrorReporter_ClasspathNotEmpty; report(message, header.getLineNumber() + 1, CompilerFlags.ERROR); 479 return; 480 } 481 482 ManifestElement[] elements = header.getElements(); 483 if (elements.length == 0) { 484 return; 485 } 486 } 487 488 491 private boolean validateBundleSymbolicName() { 492 IHeader header = (IHeader) fHeaders.get(Constants.BUNDLE_SYMBOLICNAME); 493 String message; 494 if (header == null) { 495 report( 496 NLS.bind(PDEMessages.BundleErrorReporter_headerMissing, Constants.BUNDLE_SYMBOLICNAME), 1, CompilerFlags.ERROR); 498 return false; 499 } 500 String symbolicName = header.getValue(); 501 if ((symbolicName.trim()).length() == 0) { 502 message = PDEMessages.BundleErrorReporter_NoSymbolicName; report(message, header.getLineNumber() + 1, CompilerFlags.ERROR); 504 return false; 505 } 506 ManifestElement[] elements = header.getElements(); 507 if (elements.length == 0) { 508 return false; 509 } 510 fPluginId = elements[0].getValue(); 511 512 validatePluginId(header, fPluginId); 513 514 validateSingletonAttribute(header, elements[0]); 515 validateSingletonDirective(header, elements[0]); 516 517 return true; 518 } 519 520 private void validateBundleVersion() { 521 IHeader header = (IHeader) fHeaders.get(Constants.BUNDLE_VERSION); 522 if (header == null) { 523 report( 524 NLS.bind(PDEMessages.BundleErrorReporter_headerMissing, Constants.BUNDLE_VERSION), 1, CompilerFlags.ERROR); 526 return; 527 } 528 String version = header.getValue(); 529 IStatus status = validateVersionString(version); 530 if(!status.isOK()){ 531 int line = getLine(header, version); 532 report(status.getMessage(), line, CompilerFlags.ERROR); 533 } 534 } 535 536 private void validateBundleVersionAttribute(IHeader header, 537 ManifestElement element) { 538 String versionRange = element 539 .getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE); 540 if (versionRange != null && !validateVersionRange(versionRange).isOK()) { 541 String message = NLS.bind(PDEMessages.BundleErrorReporter_InvalidFormatInBundleVersion, element.getValue()); report(message, getPackageLine(header, element), 543 CompilerFlags.ERROR); } 545 } 546 547 public void validateContent(IProgressMonitor monitor) { 548 super.validateContent(monitor); 549 if (fHeaders == null || getErrorCount() > 0) { 550 return; 551 } 552 553 readBundleManifestVersion(); 554 fHasFragment_Xml = fProject.getFile("fragment.xml").exists(); 556 IPluginModelBase modelBase = PDECore.getDefault().getModelManager() 557 .findModel(fProject); 558 if (modelBase != null) { 559 fHasExtensions = modelBase.getPluginBase().getExtensionPoints().length > 0 560 || modelBase.getPluginBase().getExtensions().length > 0; 561 } 562 563 if (!validateBundleSymbolicName()) { 565 return; 566 } 567 validateBundleVersion(); 568 validateExtensibleAPI(); 570 validateFragmentHost(); 572 validateBundleClasspath(); 573 validateRequireBundle(monitor); 574 validateBundleActivator(); 577 validatePluginClass(); 578 validateExportPackage(monitor); 579 validateProvidePackage(monitor); 580 validateImportPackage(monitor); 581 validateEclipsePlatformFilter(); 582 } 584 585 private void validateExportPackage(IProgressMonitor monitor) { 586 IHeader header = (IHeader) fHeaders.get(Constants.EXPORT_PACKAGE); 587 if (header == null) { 588 return; 589 } 590 String message = null; 591 ManifestElement[] exportPackageElements = header.getElements(); 592 593 for (int i = 0; i < exportPackageElements.length; i++) { 594 checkCanceled(monitor); 595 596 String exportPackageStmt = exportPackageElements[i].getValue(); 597 if (".".equals(exportPackageStmt.trim())) { continue; 600 } 601 602 validateVersionAttribute(header, exportPackageElements[i], false); 603 604 validateSpecificationVersionAttribute(header, 605 exportPackageElements[i]); 606 607 validateX_InternalDirective(header, exportPackageElements[i]); 608 609 validateX_FriendsDirective(header, exportPackageElements[i]); 610 611 if (!isCheckUnresolvedImports()) { 612 continue; 613 } 614 IPackageFragment f = (IPackageFragment) getProjectPackages().get( 615 exportPackageStmt); 616 617 if (f != null && f.isDefaultPackage()) { 618 message = PDEMessages.BundleErrorReporter_CannotExportDefaultPackage; report(message, getPackageLine(header, exportPackageElements[i]), 620 CompilerFlags.P_UNRESOLVED_IMPORTS); continue; 622 } 623 624 625 if (!getProjectPackages().containsKey(exportPackageStmt)) { 626 if (!(getHostPackages().containsKey(exportPackageStmt) || fHasExtensibleApi 627 && getFragmentsPackages() 628 .containsKey(exportPackageStmt))) { 629 message = NLS.bind(PDEMessages.BundleErrorReporter_NotExistInProject, exportPackageStmt); report(message, getPackageLine(header, exportPackageElements[i]), 631 CompilerFlags.P_UNRESOLVED_IMPORTS); continue; 633 } 634 } 635 636 } 637 } 638 639 private void validateExtensibleAPI(){ 640 IHeader header = (IHeader) fHeaders.get(ICoreConstants.EXTENSIBLE_API); 641 if(header==null){ 642 return; 643 } 644 validateBooleanValue(header); 645 646 fHasExtensibleApi = "true".equals(header.getValue()); } 648 649 private void validateFragmentHost() { 650 IHeader header = (IHeader) fHeaders.get(Constants.FRAGMENT_HOST); 651 String message; 652 if (header == null) { 653 if (isCheckNoRequiredAttr() && fHasFragment_Xml) { message = PDEMessages.BundleErrorReporter_HostNeeded; report(message, 1, CompilerFlags.P_NO_REQUIRED_ATT); 656 } 657 return; 658 } 659 660 fFragment = true; 661 ManifestElement[] fragmentHostElements = header.getElements(); 662 if (isCheckNoRequiredAttr() && fragmentHostElements.length == 0) { 663 message = PDEMessages.BundleErrorReporter_HostNeeded; report(message, 1, CompilerFlags.P_NO_REQUIRED_ATT); 665 return; 666 } 667 668 String fragmentHostStmt = fragmentHostElements[0].getValue(); 669 if (!validatePluginId(header, fragmentHostStmt)) { 670 return; 671 } 672 673 validateBundleVersionAttribute(header, fragmentHostElements[0]); 674 675 if (isCheckUnresolvedImports()) { 676 HashMap availableBundlesMap = getAvailableBundles(); 677 IPluginModelBase availableModel = (IPluginModelBase) availableBundlesMap 678 .get(fragmentHostStmt); 679 if (availableModel == null || !availableModel.isEnabled()) { 680 683 message = NLS.bind(PDEMessages.BundleErrorReporter_HostNotExistPDE, fragmentHostStmt); report(message, getLine(header, fragmentHostStmt), 685 CompilerFlags.P_UNRESOLVED_IMPORTS); 686 return; 687 } 688 if (availableModel instanceof IFragmentModel) { 689 690 message = NLS.bind(PDEMessages.BundleErrorReporter_HostIsFragment, fragmentHostStmt); report(message, getLine(header, fragmentHostStmt), 692 CompilerFlags.P_UNRESOLVED_IMPORTS); 693 return; 694 } 695 String availableVersion = availableModel.getPluginBase() 696 .getVersion(); 697 String requiredVersionRange = fragmentHostElements[0] 698 .getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE); 699 if (requiredVersionRange != null 700 && validateVersionRange(requiredVersionRange).isOK()) { 701 VersionRange versionRange = new VersionRange( 702 requiredVersionRange); 703 if (!versionRange.isIncluded(new Version(availableVersion))) { 704 message = NLS.bind(PDEMessages.BundleErrorReporter_BundleRangeInvalidInBundleVersion, fragmentHostStmt); report(message, getLine(header, requiredVersionRange), 706 CompilerFlags.P_UNRESOLVED_IMPORTS); 707 } 708 } 709 fHostBundleId = fragmentHostStmt; 711 712 } 713 } 714 715 private void validateImportPackage(IProgressMonitor monitor) { 716 IHeader header = (IHeader) fHeaders.get(Constants.IMPORT_PACKAGE); 717 if (header == null) { 718 return; 719 } 720 String message = null; 721 HashMap availableExportedPackagesMap = getAvailableExportedPackages(); 722 723 ManifestElement[] importPackageElements = header.getElements(); 724 for (int i = 0; i < importPackageElements.length; i++) { 725 checkCanceled(monitor); 726 727 validateSpecificationVersionAttribute(header, 728 importPackageElements[i]); 729 validateVersionAttribute(header, importPackageElements[i], true); 730 731 validateResolutionDirective(header, importPackageElements[i]); 732 733 String importPackageStmt = importPackageElements[i].getValue(); 734 735 if (!isCheckUnresolvedImports()) { 736 continue; 737 } 738 if (!availableExportedPackagesMap.containsKey(importPackageStmt)) { 739 740 message = NLS.bind(PDEMessages.BundleErrorReporter_PackageNotExported, importPackageStmt); report(message, getPackageLine(header, importPackageElements[i]), 742 CompilerFlags.P_UNRESOLVED_IMPORTS); 743 continue; 744 } 745 746 String requiredVersion = importPackageElements[i] 747 .getAttribute(Constants.VERSION_ATTRIBUTE); 748 if (requiredVersion != null && validateVersionRange(requiredVersion).isOK()) { 749 VersionRange range = new VersionRange(requiredVersion); 750 ExportPackageDescription epd = (ExportPackageDescription) availableExportedPackagesMap 751 .get(importPackageStmt); 752 if (epd.getVersion() != null 753 && !range.isIncluded(epd.getVersion())) { 754 message = NLS.bind(PDEMessages.BundleErrorReporter_VersionNotInRange, (new String [] { importPackageStmt, requiredVersion })); report(message, getPackageLine(header, importPackageElements[i]), 756 CompilerFlags.P_UNRESOLVED_IMPORTS); 757 continue; 758 } 759 } 760 } 761 } 762 763 900 private void validateOptionalAttribute(IHeader header, 901 ManifestElement requireBundleElements) { 902 String message; 903 String rexport = requireBundleElements 904 .getAttribute(ICoreConstants.OPTIONAL_ATTRIBUTE); 905 if (rexport != null) { 906 validateBooleanAttributeValue(header, requireBundleElements, 907 ICoreConstants.OPTIONAL_ATTRIBUTE); 908 if (fEclipse3_1 && isCheckDeprecated()) { 909 message = NLS 910 .bind( 911 PDEMessages.BundleErrorReporter_deprecated_attribute_optional, 912 ICoreConstants.OPTIONAL_ATTRIBUTE); report( 914 message, 915 getLine(header, ICoreConstants.OPTIONAL_ATTRIBUTE + "="), CompilerFlags.P_DEPRECATED); } 917 } 918 } 919 920 private boolean validatePluginId(IHeader header, String value) { 921 String message; 922 if (!IdUtil.isValidPluginId(value)) { 923 message = PDEMessages.BundleErrorReporter_InvalidSymbolicName; report(message, header.getLineNumber() + 1, CompilerFlags.WARNING); 925 return false; 926 } 927 return true; 928 } 929 930 private void validateProvidePackage(IProgressMonitor monitor) { 931 IHeader header = (IHeader) fHeaders.get(ICoreConstants.PROVIDE_PACKAGE); 932 if (header == null) { 933 return; 934 } 935 String message = null; 936 if (fEclipse3_1 && isCheckDeprecated()) { 937 message = NLS 938 .bind( 939 PDEMessages.BundleErrorReporter_deprecated_header_Provide_Package, 940 ICoreConstants.PROVIDE_PACKAGE); report(message, header.getLineNumber() + 1, 942 CompilerFlags.P_DEPRECATED); 943 } 944 ManifestElement[] exportPackageElements = header.getElements(); 945 946 for (int i = 0; i < exportPackageElements.length; i++) { 947 checkCanceled(monitor); 948 949 String exportPackageStmt = exportPackageElements[i].getValue(); 950 if (".".equals(exportPackageStmt.trim())) { continue; 953 } 954 955 validateSpecificationVersionAttribute(header, 956 exportPackageElements[i]); 957 958 if (!isCheckUnresolvedImports()) { 959 continue; 960 } 961 IPackageFragment f = (IPackageFragment) getProjectPackages().get( 962 exportPackageStmt); 963 964 if (f != null && f.isDefaultPackage()) { 965 message = PDEMessages.BundleErrorReporter_CannotExportDefaultPackage; report(message, getPackageLine(header, exportPackageElements[i]), 967 CompilerFlags.P_UNRESOLVED_IMPORTS); continue; 969 } 970 971 972 if (!getProjectPackages().containsKey(exportPackageStmt)) { 973 if (!(getHostPackages().containsKey(exportPackageStmt) || fHasExtensibleApi 974 && getFragmentsPackages() 975 .containsKey(exportPackageStmt))) { 976 message = NLS.bind(PDEMessages.BundleErrorReporter_NotExistInProject, exportPackageStmt); report(message, getPackageLine(header, exportPackageElements[i]), 978 CompilerFlags.P_UNRESOLVED_IMPORTS); continue; 980 } 981 } 982 983 } 984 } 985 986 private void validateReprovideAttribute(IHeader header, 987 ManifestElement requireBundleElements) { 988 String message; 989 String rexport = requireBundleElements 990 .getAttribute(ICoreConstants.REPROVIDE_ATTRIBUTE); 991 if (rexport != null) { 992 validateBooleanAttributeValue(header, requireBundleElements, 993 ICoreConstants.REPROVIDE_ATTRIBUTE); 994 if (fEclipse3_1 && isCheckDeprecated()) { 995 message = NLS 996 .bind( 997 PDEMessages.BundleErrorReporter_deprecated_attribute_reprovide, 998 ICoreConstants.REPROVIDE_ATTRIBUTE); report(message, 1000 getLine(header, ICoreConstants.REPROVIDE_ATTRIBUTE 1001 + "="), CompilerFlags.P_DEPRECATED); } 1003 } 1004 } 1005 1006 private void validateRequireBundle(IProgressMonitor monitor) { 1007 IHeader header = (IHeader) fHeaders.get(Constants.REQUIRE_BUNDLE); 1008 if (header == null) { 1009 return; 1010 } 1011 String message = null; 1012 HashMap availableBundlesMap = getAvailableBundles(); 1013 1014 ManifestElement[] requireBundleElements = header.getElements(); 1015 for (int i = 0; i < requireBundleElements.length; i++) { 1016 checkCanceled(monitor); 1017 1018 String requireBundleStmt = requireBundleElements[i].getValue(); 1019 if (COMPATIBILITY_PLUGIN.equals(requireBundleStmt)) { 1020 fCompatibility = true; 1021 } 1022 1023 validateBundleVersionAttribute(header, requireBundleElements[i]); 1024 1025 validateVisibilityDirective(header, requireBundleElements[i]); 1026 1027 validateReprovideAttribute(header, requireBundleElements[i]); 1028 1029 validateResolutionDirective(header, requireBundleElements[i]); 1030 1031 validateOptionalAttribute(header, requireBundleElements[i]); 1032 1033 if (!isCheckUnresolvedImports()) { 1034 return; 1035 } 1036 1037 int severity = getRequireBundleSeverity(requireBundleElements[i]); 1038 1039 1040 if (!availableBundlesMap.containsKey(requireBundleStmt)) { 1041 message = NLS.bind(PDEMessages.BundleErrorReporter_NotExistPDE, requireBundleStmt); report(message, getPackageLine(header, requireBundleElements[i]), 1043 severity); 1044 continue; 1045 } 1046 IPluginModelBase availableModel = (IPluginModelBase) availableBundlesMap 1047 .get(requireBundleStmt); 1048 if (!(availableModel instanceof IPluginModel)) { 1049 1050 message = NLS.bind(PDEMessages.BundleErrorReporter_IsFragment, requireBundleStmt); report(message, getPackageLine(header, requireBundleElements[i]), 1052 severity); 1053 continue; 1054 } 1055 String requiredVersionRange = requireBundleElements[i] 1056 .getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE); 1057 if (requiredVersionRange != null 1058 && validateVersionRange(requiredVersionRange).isOK()) { 1059 VersionRange versionRange = new VersionRange( 1060 requiredVersionRange); 1061 String availableVersion = availableModel.getPluginBase() 1062 .getVersion(); 1063 if (!versionRange.isIncluded(new Version(availableVersion))) { 1064 message = NLS.bind(PDEMessages.BundleErrorReporter_BundleRangeInvalidInBundleVersion, requireBundleStmt); report(message, getPackageLine(header, requireBundleElements[i]), 1066 severity); 1067 } 1068 1069 } 1070 } 1071 } 1072 1073 private int getRequireBundleSeverity(ManifestElement requireBundleElement) { 1074 boolean optional = Constants.RESOLUTION_OPTIONAL 1075 .equals(requireBundleElement 1076 .getDirective(Constants.RESOLUTION_DIRECTIVE)) 1077 || "true".equals(requireBundleElement .getAttribute(ICoreConstants.OPTIONAL_ATTRIBUTE)); 1079 int severity = CompilerFlags.getFlag(fProject, 1080 CompilerFlags.P_UNRESOLVED_IMPORTS); 1081 if (optional && severity == CompilerFlags.ERROR) severity = CompilerFlags.WARNING; 1083 return severity; 1084 } 1085 1086 private void validateResolutionDirective(IHeader header, 1087 ManifestElement requireBundleElement) { 1088 String resolution = requireBundleElement 1089 .getDirective(Constants.RESOLUTION_DIRECTIVE); 1090 if (resolution != null) { 1091 validateDirectiveValue(header, requireBundleElement, 1092 Constants.RESOLUTION_DIRECTIVE, new String [] { 1093 Constants.RESOLUTION_MANDATORY, 1094 Constants.RESOLUTION_OPTIONAL }); 1095 } 1096 } 1097 1098 private void validateSingletonAttribute(IHeader header, 1099 ManifestElement element) { 1100 String message; 1101 String singletonAttr = element 1102 .getAttribute(ICoreConstants.SINGLETON_ATTRIBUTE); 1103 if (fHasExtensions) { 1104 if (!fEclipse3_1) { 1105 if (!"true".equals(singletonAttr)) { message = NLS.bind(PDEMessages.BundleErrorReporter_singletonAttrRequired, ICoreConstants.SINGLETON_ATTRIBUTE); report(message, header.getLineNumber() + 1, 1108 CompilerFlags.ERROR); 1109 } 1110 } 1111 } 1112 if (isCheckDeprecated()) { 1113 if (fEclipse3_1 && singletonAttr != null) { 1114 message = NLS 1115 .bind( 1116 PDEMessages.BundleErrorReporter_deprecated_attribute_singleton, 1117 ICoreConstants.SINGLETON_ATTRIBUTE); report(message, 1119 getLine(header, ICoreConstants.SINGLETON_ATTRIBUTE 1120 + "="), CompilerFlags.P_DEPRECATED); } 1122 } 1123 validateBooleanAttributeValue(header, element, 1124 ICoreConstants.SINGLETON_ATTRIBUTE); 1125 } 1126 1127 private void validateSingletonDirective(IHeader header, 1128 ManifestElement element) { 1129 String singletonDir = element 1130 .getDirective(Constants.SINGLETON_DIRECTIVE); 1131 if (fHasExtensions) { 1132 if (fEclipse3_1) { 1133 if (!"true".equals(singletonDir)) { String message = NLS.bind(PDEMessages.BundleErrorReporter_singletonRequired, Constants.SINGLETON_DIRECTIVE); report(message, header.getLineNumber() + 1, 1136 CompilerFlags.ERROR); 1137 } 1138 1139 } 1140 } 1141 if (isCheckUnknownAttr()) { 1142 if (!fEclipse3_1 && singletonDir != null) { 1143 String message = NLS.bind(PDEMessages.BundleErrorReporter_UnknownDirective, Constants.SINGLETON_DIRECTIVE); report(message, getLine(header, Constants.SINGLETON_DIRECTIVE 1145 + ":="), CompilerFlags.P_UNKNOWN_ATTRIBUTE); 1147 } 1148 } 1149 validateBooleanDirectiveValue(header, element, 1150 Constants.SINGLETON_DIRECTIVE); 1151 } 1152 1153 private void validateSpecificationVersionAttribute(IHeader header, 1154 ManifestElement element) { 1155 String version = element 1156 .getAttribute(ICoreConstants.PACKAGE_SPECIFICATION_VERSION); 1157 IStatus status = validateVersionString(version); 1158 if(!status.isOK()){ 1159 report(status.getMessage(), getPackageLine(header, element), 1160 CompilerFlags.ERROR); } 1162 if (isCheckDeprecated()) { 1163 if (fEclipse3_1 && version != null) { 1164 String message = NLS 1165 .bind( 1166 PDEMessages.BundleErrorReporter_deprecated_attribute_specification_version, 1167 ICoreConstants.PACKAGE_SPECIFICATION_VERSION); report(message, 1169 getPackageLine(header, 1170 element), CompilerFlags.P_DEPRECATED); } 1172 } 1173 } 1174 1175 private void validateVersionAttribute(IHeader header, 1176 ManifestElement element, boolean range) { 1177 String version = element.getAttribute(Constants.VERSION_ATTRIBUTE); 1178 if (version == null) 1179 return; 1180 IStatus status = range ? validateVersionRange(version) 1181 : validateVersionString(version); 1182 if(!status.isOK()) { 1183 report(status.getMessage(), getPackageLine(header, element), 1184 CompilerFlags.ERROR); } 1186 } 1187 1188 private void validateVisibilityDirective(IHeader header, 1189 ManifestElement requireBundleElement) { 1190 String visibility = requireBundleElement 1191 .getDirective(Constants.VISIBILITY_DIRECTIVE); 1192 if (visibility != null) { 1193 validateDirectiveValue(header, requireBundleElement, 1194 Constants.VISIBILITY_DIRECTIVE, new String [] { 1195 Constants.VISIBILITY_PRIVATE, 1196 Constants.VISIBILITY_REEXPORT }); 1197 } 1198 } 1199 1200 private void validateX_InternalDirective(IHeader header, 1201 ManifestElement element) { 1202 String internal = element 1203 .getDirective(ICoreConstants.INTERNAL_DIRECTIVE); 1204 if (internal == null) { 1205 return; 1206 } 1207 for (int i = 0; i < BOOLEAN_VALUES.length; i++) { 1208 if (BOOLEAN_VALUES[i].equals(internal)) { 1209 return; 1210 } 1211 } 1212 String message = NLS.bind(PDEMessages.BundleErrorReporter_dir_value, 1213 (new String [] { internal, ICoreConstants.INTERNAL_DIRECTIVE })); report(message, getPackageLine(header, element), 1215 CompilerFlags.ERROR); } 1217 1218 private void validateX_FriendsDirective(IHeader header, 1219 ManifestElement element) { 1220 String friends = element.getDirective(ICoreConstants.FRIENDS_DIRECTIVE); 1221 String internal = element 1222 .getDirective(ICoreConstants.INTERNAL_DIRECTIVE); 1223 if (friends != null && internal != null) { 1224 String message = NLS.bind( 1225 PDEMessages.BundleErrorReporter_directive_hasNoEffectWith_, 1226 new String [] { ICoreConstants.FRIENDS_DIRECTIVE, 1227 ICoreConstants.INTERNAL_DIRECTIVE }); report(message, getPackageLine(header, element), 1229 CompilerFlags.WARNING); } 1231 } 1232 1233 private void validateEclipsePlatformFilter() { 1234 IHeader header = (IHeader) fHeaders.get(ICoreConstants.PLATFORM_FILTER); 1235 if (header == null) { 1236 return; 1237 } 1238 String filter = header.getValue(); 1239 try { 1240 PDE.getDefault().getBundleContext().createFilter(filter); 1241 } catch (InvalidSyntaxException ise) { 1242 report(PDEMessages.BundleErrorReporter_invalidFilterSyntax, header 1243 .getLineNumber() + 1, CompilerFlags.ERROR); 1244 } 1245 } 1246 1247} 1248 | Popular Tags |