Cet article décrit comment intégrer les tags du framework Shale Validator avec Facelets. Il s’agit notamment d’indiquer à Facelets comment interpréter les tags <s:commonsValidator>, <s:validatorVar> et <s:validatorScript>. Par exemple:
<s:commonsValidator type="minlength" arg="#{bundle['login.login']}" server="true" client="true" minlength="4"/>
<s:commonsValidator type="mask" arg="#{bundle['login.login']}" server="true" client="true">
<s:validatorVar name="mask" value="^[a-zA-Z0-9]*$"/>
</s:commonsValidator>
<s:validatorScript functionName="validateForm"/>
Handler pour CommonsValidator
Un handler spécifique facelets doit être redéfini afin de pouvoir prendre en compte les variables de commons validator renseignées avec le tag <s:validatorVar>. L’exemple ci-dessous permet de traiter uniquement le cas de la variable "mask", mais la classe handler peut être facilement étendue afin de prendre en compte d’autres variables. A noter que ce handler n’hérite pas de ValidatorHandler, car précisément, la méthode apply() (méthode finale) de ValidatorHandler ne propage pas le traitement aux handlers fils. Le code ci-dessous est donc une copie de la classe ValidatorHandler qui permet de propager le traitement au handler du tag <s:validatorVar>.
package fr.icodem.facelets.shale;
public class CommonsValidatorHandler extends MetaTagHandler {
// validatorVar tag
// set mask variable on commons validator
public static class MaskMetadata extends Metadata {
public void applyMetadata(FaceletContext ctx, Object instance) {
ValueExpression var = ctx.getVariableMapper().resolveVariable("mask");
if (var != null) {
String expression = var.getExpressionString();
CommonsValidator v = (CommonsValidator)instance;
v.setMask(expression);
}
}
}
private final TagAttribute binding;
private String validatorId = "org.apache.shale.CommonsValidator";
public CommonsValidatorHandler(TagConfig config) {
super(config);
this.binding = this.getAttribute("binding");
}
public final void apply(FaceletContext ctx, UIComponent parent)
throws IOException, FacesException, FaceletException, ELException {
if (parent == null || !(parent instanceof EditableValueHolder)) {
throw new TagException(this.tag,
"Parent not an instance of EditableValueHolder: " + parent);
}
// validatorVar tag
// get validator vars
if (nextHandler != null) nextHandler.apply(ctx, parent);
// only process if it's been created
if (parent.getParent() == null) {
// cast to a ValueHolder
EditableValueHolder evh = (EditableValueHolder) parent;
ValueExpression ve = null;
Validator v = null;
if (this.binding != null) {
ve = this.binding.getValueExpression(ctx, Validator.class);
v = (Validator) ve.getValue(ctx);
}
if (v == null) {
v = this.createValidator(ctx);
if (ve != null) {
ve.setValue(ctx, v);
}
}
if (v == null) {
throw new TagException(this.tag, "No Validator was created");
}
this.setAttributes(ctx, v);
evh.addValidator(v);
}
}
protected Validator createValidator(FaceletContext ctx) {
if (this.validatorId == null) {
throw new TagException(
this.tag,
"Default behavior invoked of requiring a validator-id " +
"passed in the constructor, must override ValidateHandler(ValidatorConfig)");
}
return ctx.getFacesContext().getApplication().createValidator(
this.validatorId);
}
// commons validator tag
// create specific rule set
@SuppressWarnings("unchecked")
protected MetaRuleset createMetaRuleset(Class type) {
MetaRuleset metaRuleset = super.createMetaRuleset(type)
.ignore("binding")
.alias("minlength", "minLength")
.alias("maxlength", "maxLength")
.add(new MaskMetadata());
return metaRuleset;
}
}
Handler pour ValidatorVar
Ce handler permet de placer dans le context de Facelets les variables renseignées avec le tag <s:validatorVar>.
public class ValidatorVarHandler extends TagHandler {
// possible attributes
private final TagAttribute name;
private final TagAttribute value;
public ValidatorVarHandler(TagConfig config) {
super(config);
this.name = getRequiredAttribute("name");
this.value = getRequiredAttribute("value");
}
@Override
public void apply(FaceletContext ctx, UIComponent parent)
throws IOException, FacesException, ELException {
String nameStr = this.name.getValue(ctx);
ValueExpression veObj = this.value.getValueExpression(ctx, Object.class);
ctx.getVariableMapper().setVariable(nameStr, veObj);
}
}
Fichier taglib Facelets pour Shale
Les handlers définis précédemment sont utilisés dans le fichier shale.taglib.xml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://shale.apache.org/core</namespace>
<tag>
<tag-name>commonsValidator</tag-name>
<handler-class>org.librairie.web.CommonsValidatorHandler</handler-class>
</tag>
<tag>
<tag-name>validatorScript</tag-name>
<component>
<component-type>org.apache.shale.ValidatorScript</component-type>
</component>
</tag>
<tag>
<tag-name>validatorVar</tag-name>
<handler-class>org.librairie.web.ValidatorVarHandler</handler-class>
</tag>
</facelet-taglib>