You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by Apache Wiki <wi...@apache.org> on 2009/05/31 16:14:46 UTC

[Myfaces Wiki] Update of "Extensions/Validator/Getting Started/Constraint Aspects" by GerhardPetracek

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Myfaces Wiki" for change notification.

The following page has been changed by GerhardPetracek:
http://wiki.apache.org/myfaces/Extensions/Validator/Getting_Started/Constraint_Aspects

New page:
= Constraint Aspects/Parameters =

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

Before you continue reading - constraint aspects don't replace "domain-attributes".[[BR]]
E.g. the values of min and max of @Length are attributes of the constraint which might be different at every usage.[[BR]]
Furthermore, they aren't interesting for other constraints like @Equals.[[BR]]
So it doesn't make sense to use a generic concept to replace such attributes.[[BR]]

Anyway, there are use-cases for shared features. ExtVal uses this mechanism e.g. for severities. Constraint aspects are interesting for features which allow a small set of possible values and which are interesting for different constraints of the whole application.[[BR]]
'''Without''' a generic solution you have to introduce one attribute per feature for every use-case at every constraint. And the implementation which uses these information have to be aware of all types of constraints (esp.: if you don't have a fix attribute name for it).

Constraint aspects allow you to extend the functionality of existing constraints.[[BR]]
Furthermore, they allow to introduce shared features. The implementations to process the information provided by the aspects/parameters aren't aware of the attribute name of the parameter nor of the concrete type of the constraint, parameter,... That means you provide a generic aspect attribute mechanism once and use it for different constraints and features.

== Examples ==

Example usage of an ExtVal constraint + validation parameters:
{{{
@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.)

Example for a custom constraint:
{{{
public @interface MyConstraint {
  Class<? extends ValidationParameter>[] params() default ViolationSeverity.Error.class;
}
}}}
The important part is: Class< ? extends ValidationParameter >[[BR]]
You can choose any attribute-name! (An array isn't required)[[BR]]
A parameter implementation has to implement this marker interface. The values within the implementation are marked via '''@ParameterValue'''. Optionally you can provide '''@ParameterKey'''. If you don't specify an explicit key, the interface extending the ValidationParameter interface is the key.

== Examples for possible parameter implementation styles ==

=== Parameter implementation - style 1 ===
Direct implementation (just an interface - no concrete class) + grouped values

{{{
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 ...
}
}}}

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

{{{
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;
}
}}}

=== Parameter implementation - style 3 ===
Class with implicit key + mixed value types + multiple values with the same type

{{{
public interface Priority extends ValidationParameter {
  @ParameterValue
  Integer getValue();

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

  @ParameterValue(id = LongDescription)
  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 int getValue() {
    return 3;
  }

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

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

=== Using the constraint and these parameter implementations ===

{{{
@MyConstraint(params = {ViolationSeverity.Warn.class, AllowClientSideValidation.class, HighPriority.class})
}}}

=== Query the information ===
{{{
ValidationParameterExtractor extractor = ExtValUtils.getValidationParameterExtractor();

//extract all available parameters
extractor().extract(myConstraint)

//query the severity
extractor().extract(myConstraint, ViolationSeverity.class, FacesMessage.Severity.class)

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

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

//query all descriptions of the priority:
extractor().extract(myConstraint, Priority.class, String.class)

//query a specific description:
extractor().extract(myConstraint, Priority.class, String.class, Priority.ShortDescription.class)
}}}

As you see the extractor is a generic impl. which allows an easier usage of the constraint aspects.[[BR]]
You can see the signatures of the methods at: [http://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractor.java ValidationParameterExtractor.java]

This concept isn't bound to ExtVal. ExtVal just provides one possible implementation which allows different parameter styles which are quite flexible in view of key/value aggregation and much more...