- commonsValidator
- validatorVar
- validatorScript
For example:
<h:form onsubmit="return validateForm(this);">
...
<label for="firstName"
value="#{bundle['person.firstName']}*" /><br />
<h:inputText id="firstName" value="#{person.firstName}"
size="22" maxlength="20">
<val:commonsValidator type="required"
arg="#{textBundle['person.firstName']}" client="true" server="true" />
<val:commonsValidator type="maxlength" maxlength="20"
arg="#{textBundle['person.firstName']}" client="true" server="true" />
<val:commonsValidator type="mask"
arg="#{textBundle['person.firstName']}" client="true" server="true">
<val:validatorVar name="mask" value="#{validationBundle['regexp.personName']}" />
</val:commonsValidator>
</h:inputText>
...
<val:validatorScript functionName="validateForm" />
</h:form>
...
First, you must create a facelets taglib file to tell facelets how to interpret these tags. Within the taglib file, you will refer to specific facelet TagHandler implementation classes that you will provide.
shale-validator-taglib.xml
<!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/validator</namespace>
<tag>
<tag-name>validatorScript</tag-name>
<component>
<component-type>org.apache.shale.ValidatorScript</component-type>
</component>
</tag>
<tag>
<tag-name>commonsValidator</tag-name>
<handler-class>net.genschaw.jsf.facelets.CommonsValidatorHandler</handler-class>
</tag>
<tag>
<tag-name>validatorVar</tag-name>
<handler-class>net.genschaw.jsf.facelets.CommonsValidatorVarHandler</handler-class>
</tag>
</facelet-taglib>
Save this file in your webapp, commonly under /WEB-INF. The <namespace>
element is defining the namespace you will use for prefixing in your facelets templates.
For example:
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:val="http://shale.apache.org/validator">
...
...
</html>
The first <tag>
element tells facelets to create a ValidatorScript
component when it encounters a validatorScript
tag. This component is defined in Shale's faces-config.xml.
The second <tag>
element tells facelets to invoke a TagHandler when it encounters a commonsValidator
tag. The tag handler is a class you need to implement (see below) to create a CommonsValidator instance and attach it to the associated component.
Finally, the third <tag>
element tells facelets to also invoke a TagHandler when it encounters a validatorVar
tag. This handler needs to expose the name/value pair in the current FaceletContext
. The CommonsValidatorHandler
will subsequently apply the variable(s) to the CommonsValidator it creates.
CommonsValidatorHandler
import java.io.IOException;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.component.EditableValueHolder;
import javax.faces.component.UIComponent;
import javax.faces.validator.Validator;
import org.apache.shale.validator.CommonsValidator;
import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.MetaRuleset;
import com.sun.facelets.tag.MetaTagHandler;
import com.sun.facelets.tag.Metadata;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;
import com.sun.facelets.tag.TagException;
/**
* Facelets TagHandler for "commonsValidator" tag.
*
* @author Shane Genschaw
*/
public class CommonsValidatorHandler extends MetaTagHandler {
/**
* Set validatorVar tag variables on commons validator.
*
* @see com.sun.facelets.tag.Metadata
*/
public static class ValidatorVarMetadata extends Metadata {
/**
* @see com.sun.facelets.tag.Metadata#applyMetadata(com.sun.facelets.FaceletContext, java.lang.Object)
*/
@SuppressWarnings("unchecked")
public void applyMetadata(FaceletContext ctx, Object instance) {
Map validatorVars = (Map) ctx.getAttribute(CommonsValidatorVarHandler.KEY);
if (null != validatorVars) {
CommonsValidator v = (CommonsValidator) instance;
v.getVars().putAll(validatorVars);
ctx.setAttribute(CommonsValidatorVarHandler.KEY, null);
}
}
}
private final TagAttribute binding;
private String validatorId = "org.apache.shale.CommonsValidator";
/**
* @param config
*/
public CommonsValidatorHandler(TagConfig config) {
super(config);
this.binding = this.getAttribute("binding");
}
/**
* @see com.sun.facelets.FaceletHandler#apply(com.sun.facelets.FaceletContext,
* javax.faces.component.UIComponent)
*/
public void apply(FaceletContext ctx, UIComponent parent)
throws IOException {
if (parent == null || !(parent instanceof EditableValueHolder)) {
throw new TagException(this.tag,
"Parent not an instance of EditableValueHolder: " + parent);
}
// process validatorVar tag(s), if present
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);
}
// alias the minlength and maxlength attributes
@SuppressWarnings("unchecked")
protected MetaRuleset createMetaRuleset(Class type) {
MetaRuleset metaRuleset = super.createMetaRuleset(type).ignore(
"binding").alias("minlength", "minLength").alias("maxlength",
"maxLength").add(new ValidatorVarMetadata());
return metaRuleset;
}
}
CommonsValidatorVarHandler
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.TagConfig;
import com.sun.facelets.tag.TagHandler;
/**
* Facelets TagHandler for "validatorVar" tag.
*
* @author Shane Genschaw
*/
public class CommonsValidatorVarHandler extends TagHandler {
/** Key under which variable map is stored in FaceletContext. */
public static final String KEY = "validatorVars";
// possible attributes
private final TagAttribute name;
private final TagAttribute value;
/**
* @param config
*/
public CommonsValidatorVarHandler(TagConfig config) {
super(config);
this.name = getRequiredAttribute("name");
this.value = getRequiredAttribute("value");
}
/**
* @see com.sun.facelets.FaceletHandler#apply(com.sun.facelets.FaceletContext,
* javax.faces.component.UIComponent)
*/
@SuppressWarnings("unchecked")
public void apply(FaceletContext ctx, UIComponent parent)
throws IOException {
String nameStr = this.name.getValue(ctx);
ValueExpression veObj = this.value
.getValueExpression(ctx, Object.class);
if (null != veObj) {
Map validatorVars = (Map) ctx.getAttribute(KEY);
if (null == validatorVars) {
validatorVars = new HashMap();
ctx.setAttribute(KEY, validatorVars);
}
validatorVars.put(nameStr, veObj.getExpressionString());
}
}
}
The last step is to add a configuration parameter in your web.xml file to tell facelets to load you're new taglib.
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/shale-validator.taglib.xml</param-value>
</context-param>
Additional Resources
No comments:
Post a Comment