1 19 package org.java.plugin.registry.xml; 20 21 import java.util.ArrayList ; 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 32 import org.java.plugin.registry.Extension; 33 import org.java.plugin.registry.ExtensionPoint; 34 import org.java.plugin.registry.Identity; 35 import org.java.plugin.registry.ManifestProcessingException; 36 import org.java.plugin.registry.PluginDescriptor; 37 import org.java.plugin.registry.PluginRegistry; 38 import org.java.plugin.registry.IntegrityCheckReport.ReportItem; 39 40 43 class ExtensionPointImpl extends PluginElementImpl implements ExtensionPoint { 44 private final ModelExtensionPoint model; 45 private Map connectedExtensions; 46 private Map availableExtensions; 47 private List parameterDefinitions; 48 private Boolean isValid; 49 private boolean paramDefsMerged = false; 50 private List descendants; 51 52 ExtensionPointImpl(final PluginDescriptorImpl descr, 53 final PluginFragmentImpl aFragment, 54 final ModelExtensionPoint aModel) 55 throws ManifestProcessingException { 56 super(descr, aFragment, aModel.getId(), aModel.getDocumentation()); 57 model = aModel; 58 if ((model.getParentPointId() != null) 59 && (model.getParentPluginId() == null)) { 60 log.warn("parent plug-in ID not specified together with parent" + " extension point ID, using declaring plug-in ID," + " extension point is " + getUniqueId()); model.setParentPluginId(descr.getId()); 64 } 65 parameterDefinitions = new ArrayList (model.getParamDefs().size()); 66 Set names = new HashSet (); 67 for (Iterator it = model.getParamDefs().iterator(); it.hasNext();) { 68 ParameterDefinitionImpl def = new ParameterDefinitionImpl(null, 69 (ModelParameterDef) it.next()); 70 if (names.contains(def.getId())) { 71 throw new ManifestProcessingException( 72 PluginRegistryImpl.PACKAGE_NAME, 73 "duplicateParameterDefinition", new Object [] {def.getId(), getId(), descr.getId()}); 75 } 76 names.add(def.getId()); 77 parameterDefinitions.add(def); 78 } 79 parameterDefinitions = 80 Collections.unmodifiableList(parameterDefinitions); 81 if (log.isDebugEnabled()) { 82 log.debug("object instantiated: " + this); } 84 } 85 86 89 public String getUniqueId() { 90 return getDeclaringPluginDescriptor().getRegistry().makeUniqueId( 91 getDeclaringPluginDescriptor().getId(), getId()); 92 } 93 94 97 public String getMultiplicity() { 98 return model.getExtensionMultiplicity(); 99 } 100 101 private void updateExtensionsLists() { 102 connectedExtensions = new HashMap (); 103 availableExtensions = new HashMap (); 104 for (Iterator it = getDeclaringPluginDescriptor().getRegistry() 105 .getPluginDescriptors().iterator(); it.hasNext();) { 106 PluginDescriptor descr = (PluginDescriptor) it.next(); 107 for (Iterator it2 = descr.getExtensions().iterator(); 108 it2.hasNext();) { 109 Extension ext = (Extension) it2.next(); 110 if (getDeclaringPluginDescriptor().getId().equals( 111 ext.getExtendedPluginId()) 112 && getId().equals(ext.getExtendedPointId())) { 113 availableExtensions.put(ext.getUniqueId(), ext); 114 if (ext.isValid()) { 115 if (log.isDebugEnabled()) { 116 log.debug("extension " + ext + " connected to point " + this); } 119 connectedExtensions.put(ext.getUniqueId(), ext); 120 } else { 121 log.warn("extension " + ext.getUniqueId() + " is invalid and doesn't connected to" + " extension point " + getUniqueId()); } 125 } 126 } 127 } 128 } 129 130 133 public Collection getAvailableExtensions() { 134 if (availableExtensions == null) { 135 updateExtensionsLists(); 136 } 137 return Collections.unmodifiableCollection(availableExtensions.values()); 138 } 139 140 144 public Extension getAvailableExtension(final String uniqueId) { 145 if (availableExtensions == null) { 146 updateExtensionsLists(); 147 } 148 Extension result = (Extension) availableExtensions.get(uniqueId); 149 if (result == null) { 150 throw new IllegalArgumentException ("extension " + uniqueId + " not available in point " + getUniqueId()); } 153 return result; 154 } 155 156 160 public boolean isExtensionAvailable(final String uniqueId) { 161 if (availableExtensions == null) { 162 updateExtensionsLists(); 163 } 164 return availableExtensions.containsKey(uniqueId); 165 } 166 167 170 public Collection getConnectedExtensions() { 171 if (connectedExtensions == null) { 172 updateExtensionsLists(); 173 } 174 return Collections.unmodifiableCollection(connectedExtensions.values()); 175 } 176 177 181 public Extension getConnectedExtension(final String uniqueId) { 182 if (connectedExtensions == null) { 183 updateExtensionsLists(); 184 } 185 Extension result = (Extension) connectedExtensions.get(uniqueId); 186 if (result == null) { 187 throw new IllegalArgumentException ("extension " + uniqueId + " not connected to point " + getUniqueId()); } 190 return result; 191 } 192 193 197 public boolean isExtensionConnected(final String uniqueId) { 198 if (connectedExtensions == null) { 199 updateExtensionsLists(); 200 } 201 return connectedExtensions.containsKey(uniqueId); 202 } 203 204 207 public boolean isValid() { 208 if (isValid == null) { 209 validate(); 210 } 211 return isValid.booleanValue(); 212 } 213 214 Collection validate() { 215 if ((model.getParentPluginId() != null) 216 && (model.getParentPointId() != null)) { 217 try { 218 if (!isExtensionPointAvailable(model.getParentPluginId(), 219 model.getParentPointId())) { 220 isValid = Boolean.FALSE; 221 return Collections.singletonList( 222 new IntegrityChecker.ReportItemImpl( 223 ReportItem.SEVERITY_ERROR, this, 224 ReportItem.ERROR_INVALID_EXTENSION_POINT, 225 "parentExtPointNotAvailable", new Object [] { getDeclaringPluginDescriptor().getRegistry() 227 .makeUniqueId(model.getParentPluginId(), 228 model.getParentPointId()), 229 getUniqueId()})); 230 } 231 } catch (Throwable t) { 232 isValid = Boolean.FALSE; 233 if (log.isDebugEnabled()) { 234 log.debug("failed checking availability of extension point " + getDeclaringPluginDescriptor().getRegistry() 236 .makeUniqueId(model.getParentPluginId(), 237 model.getParentPointId()), t); 238 } 239 return Collections.singletonList( 240 new IntegrityChecker.ReportItemImpl( 241 ReportItem.SEVERITY_ERROR, this, 242 ReportItem.ERROR_INVALID_EXTENSION_POINT, 243 "parentExtPointAvailabilityCheckFailed", new Object [] { getDeclaringPluginDescriptor().getRegistry() 245 .makeUniqueId(model.getParentPluginId(), 246 model.getParentPointId()), 247 getUniqueId(), t})); 248 } 249 } 250 if (EXT_MULT_ANY.equals(getMultiplicity())) { 251 isValid = Boolean.TRUE; 252 return Collections.EMPTY_LIST; 253 } else if (EXT_MULT_ONE.equals(getMultiplicity())) { 254 isValid = Boolean.valueOf(getAvailableExtensions().size() == 1); 255 if (!isValid.booleanValue()) { 256 return Collections.singletonList( 257 new IntegrityChecker.ReportItemImpl( 258 ReportItem.SEVERITY_ERROR, this, 259 ReportItem.ERROR_INVALID_EXTENSION_POINT, 260 "toManyOrFewExtsConnected", getUniqueId())); } 262 } else if (EXT_MULT_NONE.equals(getMultiplicity())) { 263 isValid = Boolean.valueOf(getAvailableExtensions().size() == 0); 264 if (!isValid.booleanValue()) { 265 return Collections.singletonList( 266 new IntegrityChecker.ReportItemImpl( 267 ReportItem.SEVERITY_ERROR, this, 268 ReportItem.ERROR_INVALID_EXTENSION_POINT, 269 "extsConnectedToAbstractExtPoint", getUniqueId())); } 271 } else { 272 isValid = Boolean.TRUE; 274 Set foundPlugins = new HashSet (); 275 for (Iterator it = getAvailableExtensions().iterator(); 276 it.hasNext();) { 277 String pluginId = ((Extension) it.next()) 278 .getDeclaringPluginDescriptor().getId(); 279 if (!foundPlugins.add(pluginId)) { 280 isValid = Boolean.FALSE; 281 return Collections.singletonList( 282 new IntegrityChecker.ReportItemImpl( 283 ReportItem.SEVERITY_ERROR, this, 284 ReportItem.ERROR_INVALID_EXTENSION_POINT, 285 "toManyExtsConnected", getUniqueId())); } 287 } 288 } 289 return Collections.EMPTY_LIST; 290 } 291 292 private boolean isExtensionPointAvailable(final String pluginId, 293 final String pointId) { 294 PluginRegistry registry = getDeclaringPluginDescriptor().getRegistry(); 295 if (!registry.isPluginDescriptorAvailable(pluginId)) { 296 return false; 297 } 298 for (Iterator it = registry.getPluginDescriptor(pluginId) 299 .getExtensionPoints().iterator(); it.hasNext();) { 300 if (((ExtensionPoint) it.next()).getId().equals(pointId)) { 301 return true; 302 } 303 } 304 return false; 305 } 306 307 310 public Collection getParameterDefinitions() { 311 if ((model.getParentPluginId() == null) 312 || (model.getParentPointId() == null) || paramDefsMerged) { 313 return parameterDefinitions; 314 } 315 Set names = new HashSet (); 316 Collection parentParamDefs = 317 getDeclaringPluginDescriptor().getRegistry().getExtensionPoint( 318 model.getParentPluginId(), model.getParentPointId()) 319 .getParameterDefinitions(); 320 List newParamDefs = new ArrayList (parameterDefinitions.size() 321 + parentParamDefs.size()); 322 for (Iterator it = parameterDefinitions.iterator(); it.hasNext();) { 323 ParameterDefinition def = (ParameterDefinition) it.next(); 324 names.add(def.getId()); 325 newParamDefs.add(def); 326 } 327 for (Iterator it = parentParamDefs.iterator(); it.hasNext();) { 328 ParameterDefinition def = (ParameterDefinition) it.next(); 329 if (names.contains(def.getId())) { 330 continue; 331 } 332 newParamDefs.add(def); 333 } 334 paramDefsMerged = true; 335 parameterDefinitions = Collections.unmodifiableList(newParamDefs); 336 return parameterDefinitions; 337 } 338 339 343 public ParameterDefinition getParameterDefinition(final String id) { 344 for (Iterator it = getParameterDefinitions().iterator(); 345 it.hasNext();) { 346 ParameterDefinitionImpl def = (ParameterDefinitionImpl) it.next(); 347 if (def.getId().equals(id)) { 348 return def; 349 } 350 } 351 throw new IllegalArgumentException ("parameter definition with ID " + id + " not found in extension point " + getUniqueId() + " and all it parents"); } 355 356 359 public String getParentPluginId() { 360 return model.getParentPluginId(); 361 } 362 363 366 public String getParentExtensionPointId() { 367 return model.getParentPointId(); 368 } 369 370 374 public boolean isSuccessorOf(final ExtensionPoint extensionPoint) { 375 if ((model.getParentPluginId() == null) 376 || (model.getParentPointId() == null)) { 377 return false; 378 } 379 if (model.getParentPluginId().equals( 380 extensionPoint.getDeclaringPluginDescriptor().getId()) 381 && model.getParentPointId().equals(extensionPoint.getId())) { 382 return true; 383 } 384 try { 385 return getDeclaringPluginDescriptor().getRegistry() 386 .getExtensionPoint(model.getParentPluginId(), 387 model.getParentPointId()).isSuccessorOf(extensionPoint); 388 } catch (IllegalArgumentException iae) { 389 return false; 390 } 391 } 392 393 private void collectDescendants() { 394 descendants = new LinkedList (); 395 for (Iterator it = getDeclaringPluginDescriptor().getRegistry() 396 .getPluginDescriptors().iterator(); it.hasNext();) { 397 PluginDescriptor descr = (PluginDescriptor) it.next(); 398 for (Iterator it2 = descr.getExtensionPoints().iterator(); 399 it2.hasNext();) { 400 ExtensionPoint extp = (ExtensionPoint) it2.next(); 401 if (extp.isSuccessorOf(this)) { 402 if (log.isDebugEnabled()) { 403 log.debug("extension point " + extp + " is descendant of point " + this); } 406 descendants.add(extp); 407 } 408 } 409 } 410 descendants = Collections.unmodifiableList(descendants); 411 } 412 413 416 public Collection getDescendants() { 417 if (descendants == null) { 418 collectDescendants(); 419 } 420 return descendants; 421 } 422 423 426 public String toString() { 427 return "{ExtensionPoint: uid=" + getUniqueId() + "}"; } 429 430 void registryChanged() { 431 isValid = null; 432 connectedExtensions = null; 433 availableExtensions = null; 434 descendants = null; 435 } 436 437 class ParameterDefinitionImpl extends PluginElementImpl 438 implements ParameterDefinition { 439 private List subDefinitions; 440 private final ParameterDefinitionImpl superDefinition; 441 private final ModelParameterDef modelParamDef; 442 private final ParameterValueParser valueParser; 443 444 ParameterDefinitionImpl(final ParameterDefinitionImpl aSuperDefinition, 445 final ModelParameterDef aModel) 446 throws ManifestProcessingException { 447 super(ExtensionPointImpl.this.getDeclaringPluginDescriptor(), 448 ExtensionPointImpl.this.getDeclaringPluginFragment(), 449 aModel.getId(), aModel.getDocumentation()); 450 superDefinition = aSuperDefinition; 451 modelParamDef = aModel; 452 checkType(); 453 checkMultiplicity(); 454 valueParser = new ParameterValueParser( 455 getDeclaringPluginDescriptor().getRegistry(), this, 456 modelParamDef.getDefaultValue()); 457 if (!valueParser.isParsingSucceeds()) { 458 log.warn("parsing default value for parameter definition " + this + " failed, message is: " + valueParser.getParsingMessage()); 461 throw new ManifestProcessingException( 462 PluginRegistryImpl.PACKAGE_NAME, 463 "invalidDefaultValueAttribute", new Object [] {modelParamDef.getDefaultValue(), 465 ExtensionPointImpl.this.getId(), 466 ExtensionPointImpl.this 467 .getDeclaringPluginDescriptor().getId()}); 468 } 469 if (TYPE_ANY.equals(modelParamDef.getType())) { 470 subDefinitions = Collections.EMPTY_LIST; 471 } else { 472 subDefinitions = new ArrayList ( 473 modelParamDef.getParamDefs().size()); 474 Set names = new HashSet (); 475 for (Iterator it = modelParamDef.getParamDefs().iterator(); 476 it.hasNext();) { 477 ParameterDefinitionImpl def = new ParameterDefinitionImpl( 478 this, (ModelParameterDef) it.next()); 479 if (names.contains(def.getId())) { 480 throw new ManifestProcessingException( 481 PluginRegistryImpl.PACKAGE_NAME, 482 "duplicateParameterDefinition", new Object [] {def.getId(), 484 ExtensionPointImpl.this.getId(), 485 ExtensionPointImpl.this. 486 getDeclaringPluginDescriptor().getId()}); 487 } 488 names.add(def.getId()); 489 subDefinitions.add(def); 490 } 491 subDefinitions = Collections.unmodifiableList(subDefinitions); 492 } 493 if (log.isDebugEnabled()) { 494 log.debug("object instantiated: " + this); } 496 } 497 498 private void checkType() throws ManifestProcessingException { 499 String type = modelParamDef.getType(); 500 if (!TYPE_STRING.equals(type) 501 && !TYPE_BOOLEAN.endsWith(type) 502 && !TYPE_NUMBER.equals(type) 503 && !TYPE_DATE.equals(type) 504 && !TYPE_TIME.equals(type) 505 && !TYPE_DATETIME.equals(type) 506 && !TYPE_NULL.equals(type) 507 && !TYPE_ANY.equals(type) 508 && !TYPE_PLUGIN_ID.equals(type) 509 && !TYPE_EXTENSION_POINT_ID.equals(type) 510 && !TYPE_EXTENSION_ID.equals(type) 511 && !TYPE_FIXED.equals(type) 512 && !TYPE_RESOURCE.equals(type)) { 513 throw new ManifestProcessingException( 514 PluginRegistryImpl.PACKAGE_NAME, 515 "invalidTypeAttribute", new Object [] {type, ExtensionPointImpl.this.getId(), 517 ExtensionPointImpl.this 518 .getDeclaringPluginDescriptor().getId()}); 519 } 520 } 521 522 private void checkMultiplicity() throws ManifestProcessingException { 523 String multiplicity = modelParamDef.getMultiplicity(); 524 if (!MULT_ONE.equals(multiplicity) 525 && !MULT_ANY.equals(multiplicity) 526 && !MULT_NONE_OR_ONE.equals(multiplicity) 527 && !MULT_ONE_OR_MORE.equals(multiplicity)) { 528 throw new ManifestProcessingException( 529 PluginRegistryImpl.PACKAGE_NAME, 530 "invalidMultiplicityAttribute", new Object [] {multiplicity, 532 ExtensionPointImpl.this.getId(), 533 ExtensionPointImpl.this 534 .getDeclaringPluginDescriptor().getId()}); 535 } 536 } 537 538 ParameterValueParser getValueParser() { 539 return valueParser; 540 } 541 542 546 public ExtensionPoint getDeclaringExtensionPoint() { 547 return ExtensionPointImpl.this; 548 } 549 550 554 public String getMultiplicity() { 555 return modelParamDef.getMultiplicity(); 556 } 557 558 562 public Collection getSubDefinitions() { 563 return subDefinitions; 564 } 565 566 570 public ParameterDefinition getSuperDefinition() { 571 return superDefinition; 572 } 573 574 578 public ParameterDefinition getSubDefinition(final String id) { 579 for (Iterator it = subDefinitions.iterator(); it.hasNext();) { 580 ParameterDefinitionImpl def = 581 (ParameterDefinitionImpl) it.next(); 582 if (def.getId().equals(id)) { 583 return def; 584 } 585 } 586 throw new IllegalArgumentException ( 587 "parameter definition with ID " + id + " not found in extension point " + getUniqueId()); } 590 591 594 public String getType() { 595 return modelParamDef.getType(); 596 } 597 598 602 public String getCustomData() { 603 return modelParamDef.getCustomData(); 604 } 605 606 610 public String getDefaultValue() { 611 return modelParamDef.getDefaultValue(); 612 } 613 614 617 public String toString() { 618 return "{PluginExtensionPoint.ParameterDefinition: extPointUid=" + getDeclaringExtensionPoint().getUniqueId() + "; id=" + getId() + "}"; } 622 623 627 protected boolean isEqualTo(final Identity idt) { 628 if (!super.isEqualTo(idt)) { 629 return false; 630 } 631 ParameterDefinitionImpl other = (ParameterDefinitionImpl) idt; 632 if ((getSuperDefinition() == null) 633 && (other.getSuperDefinition() == null)) { 634 return true; 635 } 636 if ((getSuperDefinition() == null) 637 || (other.getSuperDefinition() == null)) { 638 return false; 639 } 640 return getSuperDefinition().equals(other.getSuperDefinition()); 641 } 642 } 643 } 644 | Popular Tags |