Package fr.imag.adele.apam.maven.plugin.validation

Source Code of fr.imag.adele.apam.maven.plugin.validation.PropertyValidator

package fr.imag.adele.apam.maven.plugin.validation;

import fr.imag.adele.apam.declarations.PropertyDefinition;
import fr.imag.adele.apam.maven.plugin.validation.property.Type;
import fr.imag.adele.apam.maven.plugin.validation.property.TypeParser;
import fr.imag.adele.apam.util.Attribute;


/**
* The common validations for property definitions in abstract components
*
* NOTE this class is intended to be sub-classed to specialize the verification
* in specific kinds of components.
*
* @author vega
*
*/
public class PropertyValidator extends AbstractValidator<PropertyDefinition,Void> {

  /**
   * The parser used to validate all defined property types
   */
  private final TypeParser           typeParser;
 
  /**
   * The validator used to validate substitution expressions
   */
  private final ContextualExpressionValidator expressionValidator;
 
  public PropertyValidator(ComponentValidator<?> parent) {
    super(parent);
   
    this.typeParser        = new TypeParser();
    this.expressionValidator  = new ContextualExpressionValidator(this,typeParser);
  }

  /**
   * Parses the specified type
   */
  protected Type getType(PropertyDefinition property) {
    return typeParser.parse(property.getType());
  }

  /**
   * Validates the property definition
   */
  public final Void validate(PropertyDefinition property) {
   
    initializeState(property,typeParser.parse(property.getType()));

    validateName();
    validateType();
    validateDefaultValue();

    validateInstrumentation();
    validateRefinement();
   
    return null;
  }

  /**
   * validates the property values
   */
  public final void validate(String propertyName, String value) {

    PropertyDefinition property = getComponent().getEffectiveDeclaration(getGroup()).getPropertyDefinition(propertyName);
    Type propertyType       = property != null ? typeParser.parse(property.getType()) : null;
   
    initializeState(property,propertyType);

    if (Attribute.isFinalAttribute(propertyName)) {
      error("Property " + quoted(propertyName) + " is an internal property and cannot be redefined");
    }
   
    if (getProperty() == null) {
      error("Property " + quoted(propertyName) + " is not defined");
      return;
    }
   
    validateTypedValue(value);
    validateRefinement(value);
  }
 
  /**
   * Validate allowed property names
   */
  protected void validateName() {
    if (Attribute.isReservedAttributePrefix(getProperty().getName())) {
      error("Property " + quoted(getProperty().getName()) + " is reserved");
    }
   
  }

  /**
   * Validate the type is well defined
   */
  protected void validateType() {
    if (getType() == null) {
      error("Property " + quoted(getProperty().getName()) + " has invalid type "+getProperty().getType());
    }
  }

  /**
   * Validates the default value has a type compatible with the type of the property
   *
   */
  protected void validateDefaultValue() {
    validateTypedValue(getProperty().getDefaultValue());
  }
 
  /**
   * Validates that a value (that can have substitution expressions) is compatible with the type
   * of the property
   */
  private void validateTypedValue(String value) {
   
    if (value == null)
      return;
   
    /*
     * If the type could not be determined, we can not perform this validation
     */
    if (getType() == null)
      return;

     
    if (expressionValidator.isContextualExpression(value)) {
     
      /*
       * If the value is a substitution expression try to parse and type it.  Verify the type of the expression
       *  matches the type of the property
       */
      Type expressionType = validate(value,expressionValidator);
     
      if (expressionType != null && !expressionType.isAssignableTo(getType())) {
        error("Property " + quoted(getProperty().getName()) + " has invalid value "+value+", expected type is "+getType()+" but found "+expressionType);
      }
     
    }
    else {
     
      /*
       * For normal values, just validates the literal is accepted by the type
       */
      if (getType().value(value) == null) {
        error("Property " + quoted(getProperty().getName()) + " has invalid value "+value+" for type "+getType());
      }
    }
     
  }

  /**
   * Validates if a instrumentation of a property is valid
   *
   * In general, instrumentation is not allowed at all level of abstraction. This method must
   * be redefined in subclasses specialized for specific levels of abstraction that support it
   */
  protected void validateInstrumentation() {
    if (getProperty().getCallback() != null) {
      error("Property " + quoted(getProperty().getName()) + ", cannot specify a callback for an abstract component");
    }

    if (getProperty().getField() != null) {
      error("Property " + quoted(getProperty().getName()) + ", cannot specify an injection field for an abstract component");
    }
   
  }

  /**
   * Validates if a refinement of a property defined in the group is allowed
   *
   * In general, this is not allowed at all level of abstraction. This method must be redefined in subclasses
   * specialized for specific levels of abstraction  that support it
   */
  protected void validateRefinement() {

    PropertyDefinition groupDeclaration = getGroup() != null ? getGroup().getPropertyDefinition(getProperty().getName()) : null;

    if (Attribute.isFinalAttribute(getProperty().getName())) {
      error("Property " + quoted(getProperty().getName()) + " cannot be redefined");
    }
    else if (groupDeclaration != null && Attribute.isInheritedAttribute(getProperty().getName())) {
      error("Property " + quoted(getProperty().getName()) + " is already defined in component "+getGroup().getName());
    }
  }
 
  /**
   * Validates if a refinement of a property value in the group is allowed
   *
   */
  protected void validateRefinement(String value) {
    String groupvalue = getGroup() != null ? getGroup().getProperty(getProperty().getName()) : null;
    if (groupvalue != null && value != null && Attribute.isInheritedAttribute(getProperty().getName())) {
      error("Property " + quoted(getProperty().getName()) + " already valued in parent component "+getGroup().getName());
    }
  }

  /**
   * The property declaration currently validated
   */
  private PropertyDefinition   property;

  /**
   * The type of the property currently validated
   */
  private Type        propertyType;

  /**
   * Initializes the internal state of the validator
   */
  protected void initializeState(PropertyDefinition property, Type propertyType) {
    this.property    = property;
    this.propertyType  = propertyType;
 
 
  protected PropertyDefinition getProperty() {
    return property;
  }
 
  protected Type getType() {
    return propertyType;
  }

  /**
   * Frees all references to the state of validation
   */
  @Override
  public void resetState() {
   
    this.property     = null;
    this.propertyType   = null;
   
    super.resetState();
  }
 
}
TOP

Related Classes of fr.imag.adele.apam.maven.plugin.validation.PropertyValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.