1 19 package org.java.plugin.registry.xml; 20 21 import java.net.URL ; 22 import java.util.Collection ; 23 import java.util.Collections ; 24 import java.util.HashMap ; 25 import java.util.HashSet ; 26 import java.util.Iterator ; 27 import java.util.LinkedList ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import java.util.Map.Entry; 32 33 import org.apache.commons.logging.Log; 34 import org.apache.commons.logging.LogFactory; 35 import org.java.plugin.PathResolver; 36 import org.java.plugin.registry.Extension; 37 import org.java.plugin.registry.ExtensionPoint; 38 import org.java.plugin.registry.IntegrityCheckReport; 39 import org.java.plugin.registry.ManifestProcessingException; 40 import org.java.plugin.registry.PluginDescriptor; 41 import org.java.plugin.registry.PluginFragment; 42 import org.java.plugin.registry.PluginPrerequisite; 43 import org.java.plugin.registry.PluginRegistry; 44 import org.java.plugin.registry.Version; 45 import org.java.plugin.registry.IntegrityCheckReport.ReportItem; 46 import org.java.plugin.registry.xml.IntegrityChecker.ReportItemImpl; 47 import org.java.plugin.util.ExtendedProperties; 48 49 75 public final class PluginRegistryImpl implements PluginRegistry { 76 static final String PACKAGE_NAME = "org.java.plugin.registry.xml"; private static final char UNIQUE_SEPARATOR = '@'; 78 private static final Log log = LogFactory.getLog(PluginRegistryImpl.class); 79 80 private final List registrationReport = new LinkedList (); private final Map registeredPlugins = new HashMap (); private final Map registeredFragments = new HashMap (); private final List listeners = Collections.synchronizedList(new LinkedList ()); private ManifestParser manifestParser; 85 private boolean stopOnError = false; 86 87 90 public PluginRegistryImpl() { 91 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 92 null, ReportItem.ERROR_NO_ERROR, "registryStart", null)); } 94 95 99 public void configure(final ExtendedProperties config) { 100 stopOnError = "true".equalsIgnoreCase( config.getProperty("stopOnError", "false")); boolean isValidating = !"false".equalsIgnoreCase( config.getProperty("isValidating", "true")); manifestParser = new ManifestParser(isValidating); 105 log.info("configured, stopOnError=" + stopOnError + ", isValidating=" + isValidating); } 108 109 113 public ManifestInfo readManifestInfo(final URL url) 114 throws ManifestProcessingException { 115 try { 116 return new ManifestInfoImpl(manifestParser.parseManifestInfo(url)); 117 } catch (Exception e) { 118 throw new ManifestProcessingException(PACKAGE_NAME, 119 "manifestParsingError", url, e); } 121 } 122 123 154 public Map register(final URL [] manifests) 155 throws ManifestProcessingException { 156 List registeredPoints = new LinkedList (); Map registeredExtensions = new HashMap (); for (Iterator it = registeredPlugins.values().iterator(); 160 it.hasNext();) { 161 for (Iterator it2 = ((PluginDescriptor) it.next()) 162 .getExtensionPoints().iterator(); 163 it2.hasNext();) { 164 ExtensionPoint point = (ExtensionPoint) it2.next(); 165 registeredPoints.add(point); 166 for (Iterator it3 = point.getConnectedExtensions().iterator(); 167 it3.hasNext();) { 168 Extension ext = (Extension) it3.next(); 169 registeredExtensions.put(ext.getUniqueId(), ext); 170 } 171 } 172 } 173 Map result = new HashMap (manifests.length); Map plugins = new HashMap (); Map fragments = new HashMap (); registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 178 null, ReportItem.ERROR_NO_ERROR, "manifestsParsingStart", null)); for (int i = 0; i < manifests.length; i++) { 180 URL url = manifests[i]; 181 ModelPluginManifest model; 182 try { 183 model = manifestParser.parseManifest(url); 184 } catch (Exception e) { 185 log.error("can't parse manifest file " + url, e); if (stopOnError) { 187 throw new ManifestProcessingException(PACKAGE_NAME, 188 "manifestParsingError", url, e); } 190 registrationReport.add(new ReportItemImpl( 191 ReportItem.SEVERITY_ERROR, null, 192 ReportItem.ERROR_MANIFEST_PROCESSING_FAILED, 193 "manifestParsingError", new Object [] {url, e})); continue; 195 } 196 if (model instanceof ModelPluginFragment) { 197 fragments.put(url, model); 198 continue; 199 } 200 if (!(model instanceof ModelPluginDescriptor)) { 201 log.warn("URL " + url + " points to XML document of unknown type"); continue; 204 } 205 plugins.put(url, model); 206 } 207 if (log.isDebugEnabled()) { 208 log.debug("manifest files parsed, plugins.size=" + plugins.size() + ", fragments.size=" + fragments.size()); } 211 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 212 null, ReportItem.ERROR_NO_ERROR, "manifestsParsingFinish", new Object [] {new Integer (plugins.size()), 214 new Integer (fragments.size())})); 215 checkVersions(plugins); 216 if (log.isDebugEnabled()) { 217 log.debug("plug-ins versions checked, plugins.size=" + plugins.size()); 219 } 220 checkVersions(fragments); 221 if (log.isDebugEnabled()) { 222 log.debug("plug-in fragments versions checked, fragments.size=" + fragments.size()); 224 } 225 RegistryChangeDataImpl registryChangeData = 226 new RegistryChangeDataImpl(); 227 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 229 null, ReportItem.ERROR_NO_ERROR, 230 "registeringPluginsStart", null)); for (Iterator it = plugins.entrySet().iterator(); it.hasNext();) { 232 Map.Entry entry = (Entry) it.next(); 233 URL url = (URL ) entry.getKey(); 234 PluginDescriptor descr = registerPlugin(url, 235 (ModelPluginDescriptor) entry.getValue(), 236 registryChangeData); 237 if (descr != null) { 238 result.put(url, descr); 239 } 240 } 241 plugins.clear(); 242 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 244 null, ReportItem.ERROR_NO_ERROR, 245 "registeringFragmentsStart", null)); for (Iterator it = fragments.entrySet().iterator(); it.hasNext();) { 247 Map.Entry entry = (Entry) it.next(); 248 URL url = (URL ) entry.getKey(); 249 PluginFragment fragment = 250 registerFragment(url, (ModelPluginFragment) entry.getValue(), 251 registryChangeData); 252 if (fragment != null) { 253 result.put(url, fragment); 254 } 255 } 256 fragments.clear(); 257 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 258 null, ReportItem.ERROR_NO_ERROR, 259 "registeringPluginsFinish", new Integer (registeredPlugins.size()))); 261 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 262 null, ReportItem.ERROR_NO_ERROR, 263 "registeringFragmentsFinish", new Integer (registeredFragments.size()))); 265 log.info("plug-in and fragment descriptors registered - " + result.size()); 267 dump(); 268 if (result.isEmpty()) { 269 return result; 270 } 271 for (Iterator it = registeredPoints.iterator(); it.hasNext();) { 273 ((ExtensionPointImpl) it.next()).registryChanged(); 274 } 275 for (Iterator it = registeredExtensions.values().iterator(); 276 it.hasNext();) { 277 ((ExtensionImpl) it.next()).registryChanged(); 278 } 279 if (!listeners.isEmpty() || log.isDebugEnabled()) { 280 for (Iterator it = registeredPlugins.values().iterator(); 282 it.hasNext();) { 283 for (Iterator it2 = ((PluginDescriptor) it.next()) 284 .getExtensionPoints().iterator(); 285 it2.hasNext();) { 286 for (Iterator it3 = ((ExtensionPoint) it2.next()) 287 .getConnectedExtensions().iterator(); 288 it3.hasNext();) { 289 Extension ext = (Extension) it3.next(); 290 if (!registeredExtensions.containsKey( 291 ext.getUniqueId())) { 292 registryChangeData.putAddedExtension( 293 ext.getUniqueId(), 294 makeUniqueId(ext.getExtendedPluginId(), 295 ext.getExtendedPointId())); 296 } else { 297 registeredExtensions.remove(ext.getUniqueId()); 298 if (registryChangeData.modifiedPlugins().contains( 299 ext.getDeclaringPluginDescriptor().getId()) 300 || registryChangeData.modifiedPlugins() 301 .contains(ext.getExtendedPluginId())) { 302 registryChangeData.putModifiedExtension( 303 ext.getUniqueId(), 304 makeUniqueId(ext.getExtendedPluginId(), 305 ext.getExtendedPointId())); 306 } 307 } 308 } 309 } 310 } 311 for (Iterator it = registeredExtensions.values().iterator(); 312 it.hasNext();) { 313 Extension ext = (Extension) it.next(); 314 registryChangeData.putRemovedExtension(ext.getUniqueId(), 315 makeUniqueId(ext.getExtendedPluginId(), 316 ext.getExtendedPointId())); 317 } 318 fireEvent(registryChangeData); 320 } 321 return result; 322 } 323 324 private void checkVersions(final Map plugins) 325 throws ManifestProcessingException { 326 Map versions = new HashMap (); Set toBeRemovedUrls = new HashSet (); for (Iterator it = plugins.entrySet().iterator(); it.hasNext();) { 329 Map.Entry entry = (Map.Entry ) it.next(); 330 URL url = (URL ) entry.getKey(); 331 ModelPluginManifest model = (ModelPluginManifest) entry.getValue(); 332 if (registeredPlugins.containsKey(model.getId())) { 333 if (stopOnError) { 334 throw new ManifestProcessingException(PACKAGE_NAME, 335 "duplicatePlugin", model.getId()); 337 } 338 it.remove(); 339 registrationReport.add(new ReportItemImpl( 340 ReportItem.SEVERITY_ERROR, null, 341 ReportItem.ERROR_MANIFEST_PROCESSING_FAILED, 342 "duplicatedPluginId", model.getId())); continue; 344 } 345 if (registeredFragments.containsKey(model.getId())) { 346 if (stopOnError) { 347 throw new ManifestProcessingException(PACKAGE_NAME, 348 "duplicatePluginFragment", model.getId()); 350 } 351 it.remove(); 352 registrationReport.add(new ReportItemImpl( 353 ReportItem.SEVERITY_ERROR, null, 354 ReportItem.ERROR_MANIFEST_PROCESSING_FAILED, 355 "duplicatedFragmentId", model.getId())); continue; 357 } 358 Object [] version = (Object []) versions.get(model.getId()); 359 if (version == null) { 360 versions.put(model.getId(), 361 new Object [] {model.getVersion(), url}); 362 continue; 363 } 364 if (((Version) version[0]).compareTo(model.getVersion()) < 0) { 365 toBeRemovedUrls.add(version[1]); 366 versions.put(model.getId(), 367 new Object [] {model.getVersion(), url}); 368 } else { 369 toBeRemovedUrls.add(url); 370 } 371 } 372 versions.clear(); 373 for (Iterator it = toBeRemovedUrls.iterator(); it.hasNext();) { 374 URL url = (URL ) it.next(); 375 plugins.remove(url); 376 log.warn("ignoring duplicated manifest " + url); } 378 toBeRemovedUrls.clear(); 379 } 380 381 private PluginDescriptor registerPlugin(final URL url, 382 final ModelPluginDescriptor model, 383 final RegistryChangeDataImpl registryChangeData) 384 throws ManifestProcessingException { 385 if (log.isDebugEnabled()) { 386 log.debug("registering plug-in, URL - " + url); } 388 PluginDescriptorImpl result = null; 389 try { 390 result = new PluginDescriptorImpl(this, model, url); 391 registryChangeData.addedPlugins().add(result.getId()); 392 for (Iterator it = registeredFragments.values().iterator(); 394 it.hasNext();) { 395 PluginFragmentImpl fragment = (PluginFragmentImpl) it.next(); 396 if (fragment.matches(result)) { 397 result.registerFragment(fragment); 398 } 399 } 400 registrationReport.add(new ReportItemImpl( 401 ReportItem.SEVERITY_INFO, null, 402 ReportItem.ERROR_NO_ERROR, 403 "pluginRegistered", result.getUniqueId())); } catch (ManifestProcessingException mpe) { 405 log.error("failed registering plug-in, URL - " + url, mpe); if (stopOnError) { 407 throw mpe; 408 } 409 registrationReport.add(new ReportItemImpl( 410 ReportItem.SEVERITY_ERROR, null, 411 ReportItem.ERROR_MANIFEST_PROCESSING_FAILED, 412 "pluginRegistrationFailed", new Object [] {url, mpe})); return null; 414 } 415 registeredPlugins.put(result.getId(), result); 416 return result; 417 } 418 419 private PluginFragment registerFragment(final URL url, 420 final ModelPluginFragment model, 421 final RegistryChangeDataImpl registryChangeData) 422 throws ManifestProcessingException { 423 if (log.isDebugEnabled()) { 424 log.debug("registering plug-in fragment descriptor, URL - " + url); } 426 PluginFragmentImpl result = null; 427 try { 428 result = new PluginFragmentImpl(this, model, url); 429 boolean isRegistered = false; 431 PluginDescriptorImpl descr = 432 (PluginDescriptorImpl) getPluginDescriptor( 433 result.getPluginId()); 434 if (result.matches(descr)) { 435 descr.registerFragment(result); 436 if (!registryChangeData.addedPlugins().contains( 437 descr.getId())) { 438 registryChangeData.modifiedPlugins().add(descr.getId()); 439 } 440 isRegistered = true; 441 } 442 if (!isRegistered) { 443 log.warn("no matching plug-ins found for fragment " + result.getUniqueId()); 445 registrationReport.add(new ReportItemImpl( 446 ReportItem.SEVERITY_WARNING, null, 447 ReportItem.ERROR_NO_ERROR, 448 "noMatchingPluginFound", result.getUniqueId())); } 450 registrationReport.add(new ReportItemImpl( 451 ReportItem.SEVERITY_INFO, null, 452 ReportItem.ERROR_NO_ERROR, 453 "fragmentRegistered", result.getUniqueId())); } catch (ManifestProcessingException mpe) { 455 log.error("failed registering plug-in fragment descriptor, URL - " + url, mpe); 457 if (stopOnError) { 458 throw mpe; 459 } 460 registrationReport.add(new ReportItemImpl( 461 ReportItem.SEVERITY_ERROR, null, 462 ReportItem.ERROR_MANIFEST_PROCESSING_FAILED, 463 "fragmentRegistrationFailed", new Object [] {url, mpe})); return null; 465 } 466 registeredFragments.put(result.getId(), result); 467 return result; 468 } 469 470 473 public Collection unregister(final String [] ids) { 474 List registeredPoints = new LinkedList (); Map registeredExtensions = new HashMap (); for (Iterator it = registeredPlugins.values().iterator(); 478 it.hasNext();) { 479 for (Iterator it2 = ((PluginDescriptor) it.next()) 480 .getExtensionPoints().iterator(); 481 it2.hasNext();) { 482 ExtensionPoint point = (ExtensionPoint) it2.next(); 483 registeredPoints.add(point); 484 for (Iterator it3 = point.getConnectedExtensions().iterator(); 485 it3.hasNext();) { 486 Extension ext = (Extension) it3.next(); 487 registeredExtensions.put(ext.getUniqueId(), ext); 488 } 489 } 490 } 491 Set result = new HashSet (); 492 RegistryChangeDataImpl registryChangeData = 493 new RegistryChangeDataImpl(); 494 registrationReport.add(new ReportItemImpl( 496 ReportItem.SEVERITY_INFO, null, 497 ReportItem.ERROR_NO_ERROR, "unregisteringPrepare", null)); Map removingPlugins = new HashMap (); 499 Map removingFragments = new HashMap (); 500 for (int i = 0; i < ids.length; i++) { 501 PluginDescriptor descr = 502 (PluginDescriptor) registeredPlugins.get(ids[i]); 503 if (descr != null) { 504 for (Iterator it = getDependingPlugins(descr).iterator(); 505 it.hasNext();) { 506 PluginDescriptor depDescr = (PluginDescriptor) it.next(); 507 removingPlugins.put(depDescr.getId(), depDescr); 508 registryChangeData.removedPlugins().add(depDescr.getId()); 509 } 510 removingPlugins.put(descr.getId(), descr); 511 registryChangeData.removedPlugins().add(descr.getId()); 512 continue; 513 } 514 PluginFragment fragment = 515 (PluginFragment) registeredFragments.get(ids[i]); 516 if (fragment != null) { 517 removingFragments.put(fragment.getId(), fragment); 518 continue; 519 } 520 registrationReport.add(new ReportItemImpl( 521 ReportItem.SEVERITY_WARNING, null, 522 ReportItem.ERROR_NO_ERROR, 523 "pluginToUngregisterNotFound", ids[i])); } 525 for (Iterator it = removingPlugins.values().iterator(); it.hasNext();) { 527 PluginDescriptor descr = (PluginDescriptor) it.next(); 528 for (Iterator it2 = descr.getFragments().iterator(); 529 it2.hasNext();) { 530 PluginFragment fragment = (PluginFragment) it2.next(); 531 if (removingFragments.containsKey(fragment.getId())) { 532 continue; 533 } 534 removingFragments.put(fragment.getId(), fragment); 535 } 536 } 537 fireEvent(registryChangeData); 539 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 540 null, ReportItem.ERROR_NO_ERROR, 541 "unregisteringFragmentsStart", null)); for (Iterator it = removingFragments.values().iterator(); 543 it.hasNext();) { 544 PluginFragmentImpl fragment = (PluginFragmentImpl) it.next(); 545 unregisterFragment(fragment); 546 if (!removingPlugins.containsKey(fragment.getPluginId())) { 547 registryChangeData.modifiedPlugins().add( 548 fragment.getPluginId()); 549 } 550 result.add(fragment.getUniqueId()); 551 } 552 removingFragments.clear(); 553 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 554 null, ReportItem.ERROR_NO_ERROR, 555 "unregisteringPluginsStart", null)); for (Iterator it = removingPlugins.values().iterator(); it.hasNext();) { 557 PluginDescriptorImpl descr = (PluginDescriptorImpl) it.next(); 558 unregisterPlugin(descr); 559 result.add(descr.getUniqueId()); 560 } 561 removingPlugins.clear(); 562 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 563 null, ReportItem.ERROR_NO_ERROR, 564 "unregisteringPluginsFinish", new Integer (registeredPlugins.size()))); 566 registrationReport.add(new ReportItemImpl(ReportItem.SEVERITY_INFO, 567 null, ReportItem.ERROR_NO_ERROR, 568 "unregisteringFragmentsFinish", new Integer (registeredFragments.size()))); 570 log.info("plug-in and fragment descriptors unregistered - " + result.size()); 572 dump(); 573 if (result.isEmpty()) { 574 return result; 575 } 576 for (Iterator it = registeredPoints.iterator(); it.hasNext();) { 578 ((ExtensionPointImpl) it.next()).registryChanged(); 579 } 580 for (Iterator it = registeredExtensions.values().iterator(); 581 it.hasNext();) { 582 ((ExtensionImpl) it.next()).registryChanged(); 583 } 584 if (!listeners.isEmpty() || log.isDebugEnabled()) { 585 for (Iterator it = registeredPlugins.values().iterator(); 587 it.hasNext();) { 588 for (Iterator it2 = ((PluginDescriptor) it.next()) 589 .getExtensionPoints().iterator(); 590 it2.hasNext();) { 591 for (Iterator it3 = ((ExtensionPoint) it2.next()) 592 .getConnectedExtensions().iterator(); 593 it3.hasNext();) { 594 Extension ext = (Extension) it3.next(); 595 if (!registeredExtensions.containsKey( 596 ext.getUniqueId())) { 597 registryChangeData.putAddedExtension( 598 ext.getUniqueId(), 599 makeUniqueId(ext.getExtendedPluginId(), 600 ext.getExtendedPointId())); 601 } else { 602 registeredExtensions.remove(ext.getUniqueId()); 603 if (registryChangeData.modifiedPlugins().contains( 604 ext.getDeclaringPluginDescriptor().getId()) 605 || registryChangeData.modifiedPlugins() 606 .contains(ext.getExtendedPluginId())) { 607 registryChangeData.putModifiedExtension( 608 ext.getUniqueId(), 609 makeUniqueId(ext.getExtendedPluginId(), 610 ext.getExtendedPointId())); 611 } 612 } 613 } 614 } 615 } 616 for (Iterator it = registeredExtensions.values().iterator(); 617 it.hasNext();) { 618 Extension ext = (Extension) it.next(); 619 registryChangeData.putRemovedExtension(ext.getUniqueId(), 620 makeUniqueId(ext.getExtendedPluginId(), 621 ext.getExtendedPointId())); 622 } 623 fireEvent(registryChangeData); 625 } 626 return result; 627 } 628 629 private void unregisterPlugin(final PluginDescriptorImpl descr) { 630 registeredPlugins.remove(descr.getId()); 631 registrationReport.add(new ReportItemImpl( 632 ReportItem.SEVERITY_INFO, null, 633 ReportItem.ERROR_NO_ERROR, 634 "pluginUnregistered", descr.getUniqueId())); } 636 637 private void unregisterFragment(final PluginFragmentImpl fragment) { 638 PluginDescriptorImpl descr = 639 (PluginDescriptorImpl) registeredPlugins.get( 640 fragment.getPluginId()); 641 if (descr != null) { 642 descr.unregisterFragment(fragment); 643 } 644 registeredFragments.remove(fragment.getId()); 645 registrationReport.add(new ReportItemImpl( 646 ReportItem.SEVERITY_INFO, null, 647 ReportItem.ERROR_NO_ERROR, 648 "fragmentUnregistered", fragment.getUniqueId())); } 650 651 private void dump() { 652 if (!log.isDebugEnabled()) { 653 return; 654 } 655 StringBuffer buf = new StringBuffer (); 656 buf.append("PLUG-IN REGISTRY DUMP:\r\n") .append("-------------- DUMP BEGIN -----------------\r\n") .append("\tPlug-ins: " + registeredPlugins.size() + "\r\n"); for (Iterator it = registeredPlugins.values().iterator(); 661 it.hasNext();) { 662 buf.append("\t\t") .append(it.next()) 664 .append("\r\n"); } 666 buf.append("\tFragments: " + registeredFragments.size() + "\r\n"); for (Iterator it = registeredFragments.values().iterator(); 669 it.hasNext();) { 670 buf.append("\t\t") .append(it.next()) 672 .append("\r\n"); } 674 buf.append("Memory TOTAL/FREE/MAX: ") .append(Runtime.getRuntime().totalMemory()) 676 .append("/") .append(Runtime.getRuntime().freeMemory()) 678 .append("/") .append(Runtime.getRuntime().maxMemory()) 680 .append("\r\n"); buf.append("-------------- DUMP END -----------------\r\n"); log.debug(buf.toString()); 683 } 684 685 689 public ExtensionPoint getExtensionPoint(final String pluginId, 690 final String pointId) { 691 PluginDescriptor descriptor = 692 (PluginDescriptor) registeredPlugins.get(pluginId); 693 if (descriptor == null) { 694 throw new IllegalArgumentException ("unknown plug-in ID " + pluginId + " provided for extension point " + pointId); } 697 for (Iterator it = descriptor.getExtensionPoints().iterator(); 698 it.hasNext();) { 699 ExtensionPoint point = (ExtensionPoint) it.next(); 700 if (point.getId().equals(pointId)) { 701 if (point.isValid()) { 702 return point; 703 } 704 log.warn("extension point " + point.getUniqueId() + " is invalid and ignored by registry"); break; 707 } 708 } 709 throw new IllegalArgumentException ("unknown extension point ID - " + makeUniqueId(pluginId, pointId)); 711 } 712 713 716 public ExtensionPoint getExtensionPoint(final String uniqueId) { 717 return getExtensionPoint(extractPluginId(uniqueId), 718 extractId(uniqueId)); 719 } 720 721 725 public boolean isExtensionPointAvailable(final String pluginId, 726 final String pointId) { 727 PluginDescriptor descriptor = 728 (PluginDescriptor) registeredPlugins.get(pluginId); 729 if (descriptor == null) { 730 return false; 731 } 732 for (Iterator it = descriptor.getExtensionPoints().iterator(); 733 it.hasNext();) { 734 ExtensionPoint point = (ExtensionPoint) it.next(); 735 if (point.getId().equals(pointId)) { 736 return point.isValid(); 737 } 738 } 739 return false; 740 } 741 742 746 public boolean isExtensionPointAvailable(final String uniqueId) { 747 return isExtensionPointAvailable(extractPluginId(uniqueId), 748 extractId(uniqueId)); 749 } 750 751 754 public PluginDescriptor getPluginDescriptor(final String pluginId) { 755 PluginDescriptor result = 756 (PluginDescriptor) registeredPlugins.get(pluginId); 757 if (result == null) { 758 throw new IllegalArgumentException ("unknown plug-in ID - " + pluginId); 760 } 761 return result; 762 } 763 764 767 public boolean isPluginDescriptorAvailable(final String pluginId) { 768 return registeredPlugins.containsKey(pluginId); 769 } 770 771 774 public Collection getPluginDescriptors() { 775 return registeredPlugins.isEmpty() ? Collections.EMPTY_LIST 776 : Collections.unmodifiableCollection( 777 registeredPlugins.values()); 778 } 779 780 783 public Collection getPluginFragments() { 784 return registeredFragments.isEmpty() ? Collections.EMPTY_LIST 785 : Collections.unmodifiableCollection( 786 registeredFragments.values()); 787 } 788 789 793 public Collection getDependingPlugins(final PluginDescriptor descr) { 794 Map result = new HashMap (); 795 for (Iterator it = getPluginDescriptors().iterator(); 796 it.hasNext();) { 797 PluginDescriptor dependedDescr = (PluginDescriptor) it.next(); 798 if (dependedDescr.getId().equals(descr.getId())) { 799 continue; 800 } 801 for (Iterator it2 = dependedDescr.getPrerequisites().iterator(); 802 it2.hasNext();) { 803 PluginPrerequisite pre = (PluginPrerequisite) it2.next(); 804 if (!pre.getPluginId().equals(descr.getId()) 805 || !pre.matches()) { 806 continue; 807 } 808 if (!result.containsKey(dependedDescr.getId())) { 809 result.put(dependedDescr.getId(), dependedDescr); 810 for (Iterator it3 = 811 getDependingPlugins(dependedDescr).iterator(); 812 it3.hasNext();) { 813 PluginDescriptor descriptor = 814 (PluginDescriptor) it3.next(); 815 if (!result.containsKey(descriptor.getId())) { 816 result.put(descriptor.getId(), descriptor); 817 } 818 } 819 } 820 break; 821 } 822 } 823 return result.values(); 824 } 825 826 830 public IntegrityCheckReport checkIntegrity( 831 final PathResolver pathResolver) { 832 return checkIntegrity(pathResolver, false); 833 } 834 835 839 public IntegrityCheckReport checkIntegrity(final PathResolver pathResolver, 840 final boolean includeRegistrationReport) { 841 IntegrityChecker intergityCheckReport = new IntegrityChecker(this, 842 includeRegistrationReport ? registrationReport 843 : Collections.EMPTY_LIST); 844 intergityCheckReport.doCheck(pathResolver); 845 return intergityCheckReport; 846 } 847 848 851 public IntegrityCheckReport getRegistrationReport() { 852 return new IntegrityChecker(this, registrationReport); 853 } 854 855 859 public String makeUniqueId(final String pluginId, final String id) { 860 return pluginId + UNIQUE_SEPARATOR + id; 861 } 862 863 867 public String makeUniqueId(final String pluginId, final Version version) { 868 return pluginId + UNIQUE_SEPARATOR + version; 869 } 870 871 874 public String extractPluginId(final String uniqueId) { 875 int p = uniqueId.indexOf(UNIQUE_SEPARATOR); 876 if ((p <= 0) || (p >= (uniqueId.length() - 1))) { 877 throw new IllegalArgumentException ("invalid unique ID - " + uniqueId); 879 } 880 return uniqueId.substring(0, p); 881 } 882 883 886 public String extractId(final String uniqueId) { 887 int p = uniqueId.indexOf(UNIQUE_SEPARATOR); 888 if ((p <= 0) || (p >= (uniqueId.length() - 1))) { 889 throw new IllegalArgumentException ("invalid unique ID - " + uniqueId); 891 } 892 return uniqueId.substring(p + 1); 893 } 894 895 898 public Version extractVersion(final String uniqueId) { 899 int p = uniqueId.indexOf(UNIQUE_SEPARATOR); 900 if ((p <= 0) || (p >= (uniqueId.length() - 1))) { 901 throw new IllegalArgumentException ("invalid unique ID - " + uniqueId); 903 } 904 return Version.parse(uniqueId.substring(p + 1)); 905 } 906 907 911 public void registerListener(final RegistryChangeListener listener) { 912 if (listeners.contains(listener)) { 913 throw new IllegalArgumentException ("listener " + listener + " already registered"); } 916 listeners.add(listener); 917 } 918 919 923 public void unregisterListener(final RegistryChangeListener listener) { 924 if (!listeners.remove(listener)) { 925 log.warn("unknown listener " + listener); } 927 } 928 929 void fireEvent(final RegistryChangeDataImpl data) { 930 data.dump(); 931 if (listeners.isEmpty()) { 932 return; 933 } 934 RegistryChangeListener[] arr = 936 (RegistryChangeListener[]) listeners.toArray( 937 new RegistryChangeListener[listeners.size()]); 938 data.beforeEventFire(); 939 if (log.isDebugEnabled()) { 940 log.debug("propagating registry change event"); } 942 for (int i = 0; i < arr.length; i++) { 943 arr[i].registryChanged(data); 944 } 945 if (log.isDebugEnabled()) { 946 log.debug("registry change event propagated"); } 948 data.afterEventFire(); 949 } 950 951 private static final class RegistryChangeDataImpl 952 implements RegistryChangeData { 953 private Set addedPlugins; 954 private Set removedPlugins; 955 private Set modifiedPlugins; 956 private Map addedExtensions; 957 private Map removedExtensions; 958 private Map modifiedExtensions; 959 960 protected RegistryChangeDataImpl() { 961 reset(); 962 } 963 964 private void reset() { 965 addedPlugins = new HashSet (); 966 removedPlugins = new HashSet (); 967 modifiedPlugins = new HashSet (); 968 addedExtensions = new HashMap (); 969 removedExtensions = new HashMap (); 970 modifiedExtensions = new HashMap (); 971 } 972 973 protected void beforeEventFire() { 974 addedPlugins = Collections.unmodifiableSet(addedPlugins); 975 removedPlugins = Collections.unmodifiableSet(removedPlugins); 976 modifiedPlugins = Collections.unmodifiableSet(modifiedPlugins); 977 addedExtensions = Collections.unmodifiableMap(addedExtensions); 978 removedExtensions = Collections.unmodifiableMap(removedExtensions); 979 modifiedExtensions = 980 Collections.unmodifiableMap(modifiedExtensions); 981 } 982 983 protected void afterEventFire() { 984 reset(); 985 } 986 987 protected void dump() { 988 Log logger = LogFactory.getLog(getClass()); 989 if (!logger.isDebugEnabled()) { 990 return; 991 } 992 StringBuffer buf = new StringBuffer (); 993 buf.append("PLUG-IN REGISTRY CHANGES DUMP:\r\n") .append("-------------- DUMP BEGIN -----------------\r\n") .append("\tAdded plug-ins: " + addedPlugins.size() + "\r\n"); for (Iterator it = addedPlugins.iterator(); 998 it.hasNext();) { 999 buf.append("\t\t") .append(it.next()) 1001 .append("\r\n"); } 1003 buf.append("\tRemoved plug-ins: " + removedPlugins.size() + "\r\n"); for (Iterator it = removedPlugins.iterator(); 1006 it.hasNext();) { 1007 buf.append("\t\t") .append(it.next()) 1009 .append("\r\n"); } 1011 buf.append("\tModified plug-ins: " + modifiedPlugins.size() + "\r\n"); for (Iterator it = modifiedPlugins.iterator(); 1014 it.hasNext();) { 1015 buf.append("\t\t") .append(it.next()) 1017 .append("\r\n"); } 1019 buf.append("\tAdded extensions: " + addedExtensions.size() + "\r\n"); for (Iterator it = addedExtensions.entrySet().iterator(); 1022 it.hasNext();) { 1023 buf.append("\t\t") .append(it.next()) 1025 .append("\r\n"); } 1027 buf.append("\tRemoved extensions: " + removedExtensions.size() + "\r\n"); for (Iterator it = removedExtensions.entrySet().iterator(); 1030 it.hasNext();) { 1031 buf.append("\t\t") .append(it.next()) 1033 .append("\r\n"); } 1035 buf.append("\tModified extensions: " + modifiedExtensions.size() + "\r\n"); for (Iterator it = modifiedExtensions.entrySet().iterator(); 1038 it.hasNext();) { 1039 buf.append("\t\t") .append(it.next()) 1041 .append("\r\n"); } 1043 buf.append("Memory TOTAL/FREE/MAX: ") .append(Runtime.getRuntime().totalMemory()) 1045 .append("/") .append(Runtime.getRuntime().freeMemory()) 1047 .append("/") .append(Runtime.getRuntime().maxMemory()) 1049 .append("\r\n"); buf.append("-------------- DUMP END -----------------\r\n"); logger.debug(buf.toString()); 1052 } 1053 1054 1057 public Set addedPlugins() { 1058 return addedPlugins; 1059 } 1060 1061 1065 public Set removedPlugins() { 1066 return removedPlugins; 1067 } 1068 1069 1073 public Set modifiedPlugins() { 1074 return modifiedPlugins; 1075 } 1076 1077 void putAddedExtension(final String extensionUid, 1078 final String extensionPointUid) { 1079 addedExtensions.put(extensionUid, extensionPointUid); 1080 } 1081 1082 1086 public Set addedExtensions() { 1087 return addedExtensions.keySet(); 1088 } 1089 1090 1094 public Set addedExtensions(final String extensionPointUid) { 1095 Set result = new HashSet (); 1096 for (Iterator it = addedExtensions.entrySet().iterator(); 1097 it.hasNext();) { 1098 Map.Entry entry = (Map.Entry ) it.next(); 1099 if (entry.getValue().equals(extensionPointUid)) { 1100 result.add(entry.getKey()); 1101 } 1102 } 1103 return Collections.unmodifiableSet(result); 1104 } 1105 1106 void putRemovedExtension(final String extensionUid, 1107 final String extensionPointUid) { 1108 removedExtensions.put(extensionUid, extensionPointUid); 1109 } 1110 1111 1115 public Set removedExtensions() { 1116 return removedExtensions.keySet(); 1117 } 1118 1119 1123 public Set removedExtensions(final String extensionPointUid) { 1124 Set result = new HashSet (); 1125 for (Iterator it = removedExtensions.entrySet().iterator(); 1126 it.hasNext();) { 1127 Map.Entry entry = (Map.Entry ) it.next(); 1128 if (entry.getValue().equals(extensionPointUid)) { 1129 result.add(entry.getKey()); 1130 } 1131 } 1132 return Collections.unmodifiableSet(result); 1133 } 1134 1135 void putModifiedExtension(final String extensionUid, 1136 final String extensionPointUid) { 1137 modifiedExtensions.put(extensionUid, extensionPointUid); 1138 } 1139 1140 1144 public Set modifiedExtensions() { 1145 return modifiedExtensions.keySet(); 1146 } 1147 1148 1152 public Set modifiedExtensions(final String extensionPointUid) { 1153 Set result = new HashSet (); 1154 for (Iterator it = modifiedExtensions.entrySet().iterator(); 1155 it.hasNext();) { 1156 Map.Entry entry = (Map.Entry ) it.next(); 1157 if (entry.getValue().equals(extensionPointUid)) { 1158 result.add(entry.getKey()); 1159 } 1160 } 1161 return Collections.unmodifiableSet(result); 1162 } 1163 } 1164 1165 private static final class ManifestInfoImpl implements ManifestInfo { 1166 private final ModelManifestInfo model; 1167 1168 ManifestInfoImpl(final ModelManifestInfo aModel) { 1169 model = aModel; 1170 } 1171 1172 1175 public String getId() { 1176 return model.getId(); 1177 } 1178 1179 1183 public Version getVersion() { 1184 return model.getVersion(); 1185 } 1186 1187 1191 public String getVendor() { 1192 return model.getVendor(); 1193 } 1194 1195 1199 public String getPluginId() { 1200 return model.getPluginId(); 1201 } 1202 1203 1207 public Version getPluginVersion() { 1208 return model.getPluginVersion(); 1209 } 1210 1211 1215 public String getMatchingRule() { 1216 return model.getMatch(); 1217 } 1218 } 1219} 1220 | Popular Tags |