1 19 package org.java.plugin.registry.xml; 20 21 import java.net.URL ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.Collections ; 25 import java.util.Date ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import org.java.plugin.PathResolver; 33 import org.java.plugin.registry.Extension; 34 import org.java.plugin.registry.ExtensionPoint; 35 import org.java.plugin.registry.Identity; 36 import org.java.plugin.registry.ManifestProcessingException; 37 import org.java.plugin.registry.PluginDescriptor; 38 import org.java.plugin.registry.PluginFragment; 39 import org.java.plugin.registry.PluginRegistry; 40 import org.java.plugin.registry.ExtensionPoint.ParameterDefinition; 41 import org.java.plugin.registry.IntegrityCheckReport.ReportItem; 42 import org.java.plugin.registry.xml.ExtensionPointImpl.ParameterDefinitionImpl; 43 44 47 final class ExtensionImpl extends PluginElementImpl implements Extension { 48 private final ModelExtension model; 49 private List parameters; 50 private Boolean isValid; 51 52 ExtensionImpl(final PluginDescriptorImpl descr, 53 final PluginFragmentImpl aFragment, final ModelExtension aModel) 54 throws ManifestProcessingException { 55 super(descr, aFragment, aModel.getId(), aModel.getDocumentation()); 56 model = aModel; 57 if ((model.getPluginId() == null) 58 || (model.getPluginId().trim().length() == 0)) { 59 throw new ManifestProcessingException( 60 PluginRegistryImpl.PACKAGE_NAME, 61 "extensionIdIsBlank", descr.getId()); } 63 if ((model.getPointId() == null) 64 || (model.getPointId().trim().length() == 0)) { 65 throw new ManifestProcessingException( 66 PluginRegistryImpl.PACKAGE_NAME, 67 "extendedPointIdIsBlank", descr.getId()); } 69 parameters = new ArrayList (model.getParams().size()); 70 for (Iterator it = model.getParams().iterator(); it.hasNext();) { 71 parameters.add(new ParameterImpl(null, (ModelParameter) it.next())); 72 } 73 parameters = Collections.unmodifiableList(parameters); 74 if (log.isDebugEnabled()) { 75 log.debug("object instantiated: " + this); } 77 } 78 79 82 public String getUniqueId() { 83 return getDeclaringPluginDescriptor().getRegistry().makeUniqueId( 84 getDeclaringPluginDescriptor().getId(), getId()); 85 } 86 87 90 public Collection getParameters() { 91 return parameters; 92 } 93 94 97 public Parameter getParameter(final String id) { 98 ParameterImpl result = null; 99 for (Iterator it = parameters.iterator(); it.hasNext();) { 100 ParameterImpl param = (ParameterImpl) it.next(); 101 if (param.getId().equals(id)) { 102 if (result == null) { 103 result = param; 104 } else { 105 throw new IllegalArgumentException ( 106 "more than one parameter with ID " + id + " defined in extension " + getUniqueId()); } 109 } 110 } 111 return result; 112 } 113 114 117 public Collection getParameters(final String id) { 118 List result = new LinkedList (); 119 for (Iterator it = parameters.iterator(); it.hasNext();) { 120 ParameterImpl param = (ParameterImpl) it.next(); 121 if (param.getId().equals(id)) { 122 result.add(param); 123 } 124 } 125 return Collections.unmodifiableList(result); 126 } 127 128 131 public String getExtendedPluginId() { 132 return model.getPluginId(); 133 } 134 135 138 public String getExtendedPointId() { 139 return model.getPointId(); 140 } 141 142 145 public boolean isValid() { 146 if (isValid == null) { 147 validate(); 148 } 149 return isValid.booleanValue(); 150 } 151 152 Collection validate() { 153 ExtensionPoint point = 154 getExtensionPoint(getExtendedPluginId(), getExtendedPointId()); 155 if (point == null) { 156 isValid = Boolean.FALSE; 157 return Collections.singletonList( 158 new IntegrityChecker.ReportItemImpl( 159 ReportItem.SEVERITY_ERROR, this, 160 ReportItem.ERROR_INVALID_EXTENSION, 161 "extPointNotAvailable", new Object [] { getDeclaringPluginDescriptor().getRegistry() 163 .makeUniqueId(getExtendedPluginId(), 164 getExtendedPointId()), getUniqueId()})); 165 } 166 Collection result = 167 validateParameters(point.getParameterDefinitions(), parameters); 168 isValid = result.isEmpty() ? Boolean.TRUE : Boolean.FALSE; 169 return result; 170 } 171 172 ExtensionPoint getExtensionPoint(final String uniqueId) { 173 PluginRegistry registry = getDeclaringPluginDescriptor().getRegistry(); 174 return getExtensionPoint(registry.extractPluginId(uniqueId), 175 registry.extractId(uniqueId)); 176 } 177 178 ExtensionPoint getExtensionPoint(final String pluginId, 179 final String pointId) { 180 PluginRegistry registry = getDeclaringPluginDescriptor().getRegistry(); 181 if (!registry.isPluginDescriptorAvailable(pluginId)) { 182 return null; 183 } 184 for (Iterator it = registry.getPluginDescriptor(pluginId) 185 .getExtensionPoints().iterator(); it.hasNext();) { 186 ExtensionPoint point = (ExtensionPoint) it.next(); 187 if (point.getId().equals(pointId)) { 188 return point; 189 } 190 } 191 return null; 192 } 193 194 private Collection validateParameters(final Collection allDefinitions, 195 final Collection allParams) { 196 List result = new LinkedList (); 197 Map groups = new HashMap (); 198 for (Iterator it = allParams.iterator(); it.hasNext();) { 199 Parameter param = (Parameter) it.next(); 200 ParameterDefinition def = param.getDefinition(); 201 if (def == null) { 202 result.add(new IntegrityChecker.ReportItemImpl( 203 ReportItem.SEVERITY_ERROR, this, 204 ReportItem.ERROR_INVALID_EXTENSION, 205 "cantDetectParameterDef", new Object [] { param.getId(), getUniqueId()})); 207 continue; 208 } 209 if (groups.containsKey(param.getId())) { 210 ((Collection ) groups.get(param.getId())).add(param); 211 } else { 212 Collection paramGroup = new LinkedList (); 213 paramGroup.add(param); 214 groups.put(param.getId(), paramGroup); 215 } 216 } 217 if (!result.isEmpty()) { 218 return result; 219 } 220 for (Iterator it = allDefinitions.iterator(); it.hasNext();) { 221 ParameterDefinition def = (ParameterDefinition) it.next(); 222 Collection paramGroup = (Collection ) groups.get(def.getId()); 223 result.addAll(validateParameters(def, 224 (paramGroup != null) ? paramGroup 225 : Collections.EMPTY_LIST)); 226 } 227 return result; 228 } 229 230 private Collection validateParameters(final ParameterDefinition def, 231 final Collection params) { 232 if (log.isDebugEnabled()) { 233 log.debug("validating parameters for definition " + def); } 235 if (ParameterDefinition.MULT_ONE.equals(def.getMultiplicity()) 236 && (params.size() != 1)) { 237 return Collections.singletonList( 238 new IntegrityChecker.ReportItemImpl( 239 ReportItem.SEVERITY_ERROR, this, 240 ReportItem.ERROR_INVALID_EXTENSION, 241 "tooManyOrFewParams", new Object [] { def.getId(), getUniqueId()})); 243 } else if (ParameterDefinition.MULT_NONE_OR_ONE.equals( 244 def.getMultiplicity()) && (params.size() > 1)) { 245 return Collections.singletonList( 246 new IntegrityChecker.ReportItemImpl( 247 ReportItem.SEVERITY_ERROR, this, 248 ReportItem.ERROR_INVALID_EXTENSION, 249 "tooManyParams", new Object [] { def.getId(), getUniqueId()})); 251 } else if (ParameterDefinition.MULT_ONE_OR_MORE.equals( 252 def.getMultiplicity()) && params.isEmpty()) { 253 return Collections.singletonList( 254 new IntegrityChecker.ReportItemImpl( 255 ReportItem.SEVERITY_ERROR, this, 256 ReportItem.ERROR_INVALID_EXTENSION, 257 "tooFewParams", new Object [] { def.getId(), getUniqueId()})); 259 } 260 if (params.isEmpty()) { 261 return Collections.EMPTY_LIST; 262 } 263 List result = new LinkedList (); 264 int count = 1; 265 for (Iterator it = params.iterator(); it.hasNext(); count++) { 266 ParameterImpl param = (ParameterImpl) it.next(); 267 if (!param.isValid()) { 268 result.add(new IntegrityChecker.ReportItemImpl( 269 ReportItem.SEVERITY_ERROR, this, 270 ReportItem.ERROR_INVALID_EXTENSION, 271 "invalidParameterValue", new Object [] { def.getId(), new Integer (count), getUniqueId()})); 273 } 274 if (!ParameterDefinition.TYPE_ANY.equals(def.getType()) 275 && result.isEmpty()) { 276 result.addAll(validateParameters( 277 param.getDefinition().getSubDefinitions(), 278 param.getSubParameters())); 279 } 280 } 281 return result; 282 } 283 284 287 public String toString() { 288 return "{PluginExtension: uid=" + getUniqueId() + "}"; } 290 291 void registryChanged() { 292 isValid = null; 293 } 294 295 private class ParameterImpl extends PluginElementImpl implements Parameter { 296 private final ModelParameter modelParam; 297 private ParameterValueParser valueParser; 298 private List subParameters; 299 private ParameterDefinition definition = null; 300 private boolean definitionDetected = false; 301 private final ParameterImpl superParameter; 302 303 ParameterImpl(final ParameterImpl aSuperParameter, 304 final ModelParameter aModel) 305 throws ManifestProcessingException { 306 super(ExtensionImpl.this.getDeclaringPluginDescriptor(), 307 ExtensionImpl.this.getDeclaringPluginFragment(), 308 aModel.getId(), aModel.getDocumentation()); 309 this.superParameter = aSuperParameter; 310 modelParam = aModel; 311 subParameters = new ArrayList (modelParam.getParams().size()); 312 for (Iterator it = modelParam.getParams().iterator(); 313 it.hasNext();) { 314 subParameters.add(new ParameterImpl(this, 315 (ModelParameter) it.next())); 316 } 317 subParameters = Collections.unmodifiableList(subParameters); 318 if (log.isDebugEnabled()) { 319 log.debug("object instantiated: " + this); } 321 } 322 323 326 public Extension getDeclaringExtension() { 327 return ExtensionImpl.this; 328 } 329 330 333 public PluginDescriptor getDeclaringPluginDescriptor() { 334 return ExtensionImpl.this.getDeclaringPluginDescriptor(); 335 } 336 337 340 public PluginFragment getDeclaringPluginFragment() { 341 return ExtensionImpl.this.getDeclaringPluginFragment(); 342 } 343 344 347 public ParameterDefinition getDefinition() { 348 if (definitionDetected) { 349 return definition; 350 } 351 definitionDetected = true; 352 if (log.isDebugEnabled()) { 353 log.debug("detecting definition for parameter " + this); } 355 Collection definitions; 356 if (superParameter != null) { 357 if (superParameter.getDefinition() == null) { 358 return null; 359 } 360 if (ParameterDefinition.TYPE_ANY.equals( 361 superParameter.getDefinition().getType())) { 362 definition = superParameter.getDefinition(); 363 if (log.isDebugEnabled()) { 364 log.debug("definition detected - " + definition); } 366 return definition; 367 } 368 definitions = 369 superParameter.getDefinition().getSubDefinitions(); 370 } else { 371 definitions = getExtensionPoint( 372 getDeclaringExtension().getExtendedPluginId(), 373 getDeclaringExtension().getExtendedPointId()). 374 getParameterDefinitions(); 375 } 376 for (Iterator it = definitions.iterator(); it.hasNext();) { 377 ParameterDefinition def = (ParameterDefinition) it.next(); 378 if (def.getId().equals(getId())) { 379 definition = def; 380 break; 381 } 382 } 383 if (log.isDebugEnabled()) { 384 log.debug("definition detected - " + definition); } 386 return definition; 387 } 388 389 392 public Parameter getSuperParameter() { 393 return superParameter; 394 } 395 396 399 public Collection getSubParameters() { 400 return subParameters; 401 } 402 403 407 public Parameter getSubParameter(final String id) { 408 ParameterImpl result = null; 409 for (Iterator it = subParameters.iterator(); it.hasNext();) { 410 ParameterImpl param = (ParameterImpl) it.next(); 411 if (param.getId().equals(id)) { 412 if (result == null) { 413 result = param; 414 } else { 415 throw new IllegalArgumentException ( 416 "more than one parameter with ID " + id + " defined in extension " + getUniqueId()); } 419 } 420 } 421 return result; 422 } 423 424 428 public Collection getSubParameters(final String id) { 429 List result = new LinkedList (); 430 for (Iterator it = subParameters.iterator(); it.hasNext();) { 431 ParameterImpl param = (ParameterImpl) it.next(); 432 if (param.getId().equals(id)) { 433 result.add(param); 434 } 435 } 436 return Collections.unmodifiableList(result); 437 } 438 439 442 public String rawValue() { 443 return (modelParam.getValue() != null) ? modelParam.getValue() : ""; } 445 446 boolean isValid() { 447 if (valueParser != null) { 448 return valueParser.isParsingSucceeds(); 449 } 450 if (log.isDebugEnabled()) { 451 log.debug("validating parameter " + this); } 453 valueParser = new ParameterValueParser( 454 getDeclaringPluginDescriptor().getRegistry(), 455 getDefinition(), modelParam.getValue()); 456 if (!valueParser.isParsingSucceeds()) { 457 log.warn("parsing value for parameter " + this + " failed, message is: " + valueParser.getParsingMessage()); 460 } 461 return valueParser.isParsingSucceeds(); 462 } 463 464 467 public Boolean valueAsBoolean() { 468 if (!isValid()) { 469 throw new UnsupportedOperationException ( 470 "parameter value is invalid"); } 472 if (!ParameterDefinition.TYPE_BOOLEAN.equals( 473 definition.getType())) { 474 throw new UnsupportedOperationException ("parameter type is not " + ParameterDefinition.TYPE_BOOLEAN); 476 } 477 if (valueParser.getValue() == null) { 478 return (Boolean ) ((ParameterDefinitionImpl) getDefinition()) 479 .getValueParser().getValue(); 480 } 481 return (Boolean ) valueParser.getValue(); 482 } 483 484 487 public Date valueAsDate() { 488 if (!isValid()) { 489 throw new UnsupportedOperationException ( 490 "parameter value is invalid"); } 492 if (!ParameterDefinition.TYPE_DATE.equals(definition.getType()) 493 && !ParameterDefinition.TYPE_DATETIME.equals( 494 definition.getType()) 495 && !ParameterDefinition.TYPE_TIME.equals( 496 definition.getType())) { 497 throw new UnsupportedOperationException ("parameter type is not " + ParameterDefinition.TYPE_DATE + " nor " + ParameterDefinition.TYPE_DATETIME + " nor" + ParameterDefinition.TYPE_TIME); 501 } 502 if (valueParser.getValue() == null) { 503 return (Date ) ((ParameterDefinitionImpl) getDefinition()) 504 .getValueParser().getValue(); 505 } 506 return (Date ) valueParser.getValue(); 507 } 508 509 512 public Number valueAsNumber() { 513 if (!isValid()) { 514 throw new UnsupportedOperationException ( 515 "parameter value is invalid"); } 517 if (!ParameterDefinition.TYPE_NUMBER.equals(definition.getType())) { 518 throw new UnsupportedOperationException ("parameter type is not " + ParameterDefinition.TYPE_NUMBER); 520 } 521 if (valueParser.getValue() == null) { 522 return (Number ) ((ParameterDefinitionImpl) getDefinition()) 523 .getValueParser().getValue(); 524 } 525 return (Number ) valueParser.getValue(); 526 } 527 528 531 public String valueAsString() { 532 if (!isValid()) { 533 throw new UnsupportedOperationException ( 534 "parameter value is invalid"); } 536 if (!ParameterDefinition.TYPE_STRING.equals(definition.getType()) 537 && !ParameterDefinition.TYPE_FIXED.equals( 538 definition.getType())) { 539 throw new UnsupportedOperationException ("parameter type is not " + ParameterDefinition.TYPE_STRING); 541 } 542 if (valueParser.getValue() == null) { 543 return (String ) ((ParameterDefinitionImpl) getDefinition()) 544 .getValueParser().getValue(); 545 } 546 return (String ) valueParser.getValue(); 547 } 548 549 552 public Extension valueAsExtension() { 553 if (!isValid()) { 554 throw new UnsupportedOperationException ( 555 "parameter value is invalid"); } 557 if (!ParameterDefinition.TYPE_EXTENSION_ID.equals( 558 definition.getType())) { 559 throw new UnsupportedOperationException ( 560 "parameter type is not " + ParameterDefinition.TYPE_EXTENSION_ID); 562 } 563 if (valueParser.getValue() == null) { 564 return (Extension) ((ParameterDefinitionImpl) getDefinition()) 565 .getValueParser().getValue(); 566 } 567 return (Extension) valueParser.getValue(); 568 } 569 570 573 public ExtensionPoint valueAsExtensionPoint() { 574 if (!isValid()) { 575 throw new UnsupportedOperationException ( 576 "parameter value is invalid"); } 578 if (!ParameterDefinition.TYPE_EXTENSION_POINT_ID.equals( 579 definition.getType())) { 580 throw new UnsupportedOperationException ( 581 "parameter type is not " + ParameterDefinition.TYPE_EXTENSION_POINT_ID); 583 } 584 if (valueParser.getValue() == null) { 585 return (ExtensionPoint) ((ParameterDefinitionImpl) getDefinition()) 586 .getValueParser().getValue(); 587 } 588 return (ExtensionPoint) valueParser.getValue(); 589 } 590 591 594 public PluginDescriptor valueAsPluginDescriptor() { 595 if (!isValid()) { 596 throw new UnsupportedOperationException ( 597 "parameter value is invalid"); } 599 if (!ParameterDefinition.TYPE_PLUGIN_ID.equals( 600 definition.getType())) { 601 throw new UnsupportedOperationException ("parameter type is not " + ParameterDefinition.TYPE_PLUGIN_ID); 603 } 604 if (valueParser.getValue() == null) { 605 return (PluginDescriptor) ((ParameterDefinitionImpl) getDefinition()) 606 .getValueParser().getValue(); 607 } 608 return (PluginDescriptor) valueParser.getValue(); 609 } 610 611 614 public URL valueAsUrl() { 615 return valueAsUrl(null); 616 } 617 618 622 public URL valueAsUrl(final PathResolver pathResolver) { 623 if (!isValid()) { 624 throw new UnsupportedOperationException ( 625 "parameter value is invalid"); } 627 if (!ParameterDefinition.TYPE_RESOURCE.equals( 628 definition.getType())) { 629 throw new UnsupportedOperationException ( 630 "parameter type is not " + ParameterDefinition.TYPE_RESOURCE); 632 } 633 if ((valueParser.getValue() == null) && (rawValue() == null)) { 634 return valueAsUrl(pathResolver, 635 getDefinition().getDeclaringExtensionPoint(), 636 (URL ) ((ParameterDefinitionImpl) getDefinition()) 637 .getValueParser().getValue(), 638 getDefinition().getDefaultValue()); 639 } 640 return valueAsUrl(pathResolver, getDeclaringPluginDescriptor(), 641 (URL ) valueParser.getValue(), rawValue()); 642 } 643 644 private URL valueAsUrl(final PathResolver pathResolver, 645 final Identity idt, final URL absoluteUrl, 646 final String relativeUrl) { 647 if ((pathResolver == null) || (absoluteUrl != null)) { 648 return absoluteUrl; 649 } 650 if (relativeUrl == null) { 651 return null; 652 } 653 return pathResolver.resolvePath(idt, relativeUrl); 654 } 655 656 659 public String toString() { 660 return "{PluginExtension.Parameter: extUid=" + getDeclaringExtension().getUniqueId() + "; id=" + getId() + "}"; } 664 665 669 protected boolean isEqualTo(final Identity idt) { 670 if (!super.isEqualTo(idt)) { 671 return false; 672 } 673 ParameterImpl other = (ParameterImpl) idt; 674 if ((getSuperParameter() == null) 675 && (other.getSuperParameter() == null)) { 676 return true; 677 } 678 if ((getSuperParameter() == null) 679 || (other.getSuperParameter() == null)) { 680 return false; 681 } 682 return getSuperParameter().equals(other.getSuperParameter()); 683 } 684 } 685 } 686 | Popular Tags |