Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

This feature is available in MyFaces ExtVal in the 3rd release.
Before the official release you can use it via the snapshot version.

Code Block
java
java
titleThe problemjava
//not typesafe:
@Required(parameters = {@Param(key= "severity", value = "warn"), @Param(key= "display", value = "global")})

...

Example usage of an ExtVal constraint + validation parameters:

Code Block
java
java
titleThe solutionjava
@Required(parameters = {ViolationSeverity.Warn.class, DisplayGlobal.class})

...

You can query the parameters of a constraint at any time. (You just need access to the constraint.)

Code Block
java
java
titleExample for a custom constraintjava
public @interface MyConstraint {
  Class<? extends ValidationParameter>[] params() default ViolationSeverity.Error.class;
}

...

Direct implementation (just an interface - no concrete class) + grouped values

Code Block
java
java
titleStyle 1java
public interface ViolationSeverity {
  interface Warn extends ValidationParameter {
    @ParameterKey
    public Class KEY = ViolationSeverity.class;

    @ParameterValue
    FacesMessage.Severity SEVERITY = FacesMessage.SEVERITY_WARN;
  }

  interface Error extends ValidationParameter {
    @ParameterKey
    public Class KEY = ViolationSeverity.class;

    @ParameterValue
    FacesMessage.Severity SEVERITY = FacesMessage.SEVERITY_ERROR;
  }
  // the other severities ...
}

...

Direct implementation (just an interface - no concrete class) + key that doesn't introduce a class dependency

Code Block
java
java
titleStyle 1java
public interface AllowClientSideValidation extends ValidationParameter {
  @ParameterKey
  public String key = "client_side_validation_support";

  @ParameterValue
  boolean value = true;
}

public interface RestrictClientSideValidation extends ValidationParameter {
  @ParameterKey
  public String key = "client_side_validation_support";

  @ParameterValue
  boolean value = false;
}

...

Class with implicit key + mixed value types + multiple values with the same type

Code Block
java
java
titleStyle 3java
public interface Priority extends ValidationParameter {
  @ParameterValue
  Integer getValue();

  @ParameterValue(id = ShortDescription.class)
  String getShortDescription();

  @ParameterValue(id = LongDescription.class)
  String getLongDescription();

  interface ShortDescription{}
  interface LongDescription{}
}

public class HighPriority implements Priority {
  public Integer getValue() {
    return 1;
  }

  public String getShortDescription() {
    return "do it asap";
  }

  public String getLongDescription() {
    return "do it immediately";
  }
}

public class LowPriority implements Priority {
  public Integer getValue() {
    return 3;
  }

  public String getShortDescription() {
    return "not that important";
  }

  public String getLongDescription() {
    return "the topic is not that important";
  }
}

...

Class with implicit key + the implementation provides the final value (the method isn't given by the interface) (PropertyValidationInterceptor extends ValidationParameter)

Code Block
java
java
titleStyle 4java
public class CustomValidationInterceptor implements PropertyValidationInterceptor
{
    private static PropertyValidationInterceptor propertyValidationInterceptor;

    //called at every parameter query
    @ParameterValue
    public PropertyValidationInterceptor getInstance()
    {
        if(propertyValidationInterceptor == null)
        {
            propertyValidationInterceptor = new CustomValidationInterceptor();
        }
        return propertyValidationInterceptor;
    }

    public boolean beforeValidation(
            FacesContext facesContext, UIComponent uiComponent, Object convertedObject, Map<String, Object> properties)
    {
        //your implementation
        return true;
    }

    public void afterValidation(
            FacesContext facesContext, UIComponent uiComponent, Object convertedObject, Map<String, Object> properties)
    {
        //your implementation
    }
}

...

Class with implicit key + implicit value -> a simple marker

Code Block
java
java
titleStyle 5java
public interface ShowGlobalViolationMessageOnly extends ValidationParameter
{
}

...

An use-case is available at os890.

Code Block
java
java
titleStyle 6 and 7java
public class TestPerson
{
    //...

    @Required(parameters = {
            LoginValidator.class,
            AdditionalValidator.class})
    private String name;

    public class LoginValidator extends TestValidatorProvider
    {
        @ParameterValue
        public TestValidationStrategyProvider getValue()
        {
            return this;
        }

        @Override
        public ValidationStrategy getValidationStrategy()
        {
            return new ValidationStrategy() {

                public void validate(FacesContext facesContext, UIComponent uiComponent, MetaDataEntry metaDataEntry, Object convertedObject)
                {
                        //...
                }
            };
        }
    }
}

public class AdditionalValidator extends TestValidatorProvider
{
    //...
}

Using the constraint and these parameter implementations

Code Block
java
java
titleUsing constraint aspectsjava
@MyConstraint(params = {
    ViolationSeverity.Warn.class,
    AllowClientSideValidation.class,
    HighPriority.class,
    CustomValidationInterceptor.class,
    ShowGlobalViolationMessageOnly.class,
    LoginValidator.class,
    AdditionalValidator.class})

Query the information

Code Block
java
java
titleExtract constraint aspectsjava
ValidationParameterExtractor extractor = ExtValUtils.getValidationParameterExtractor();

//extract all available parameters - returns a list
extractor().extract(myConstraint)

//query the severity - returns a list
extractor().extract(myConstraint, ViolationSeverity.class, FacesMessage.Severity.class)

//query all information of the priority (independent of the type) - returns a list
extractor().extract(myConstraint, Priority.class)

//query information of the priority - the result is filtered by type - returns a list
extractor().extract(myConstraint, Priority.class, Integer.class)

//query all descriptions of the priority - returns a list
extractor().extract(myConstraint, Priority.class, String.class)

//query a specific description - returns a single result
extractor().extract(myConstraint, Priority.class, String.class, Priority.ShortDescription.class)

...