カスタムバリデータ

カスタムバリデータを作ってみた。

MyFacesのRegExprValidatorはエラーメッセージが固定(使い方を知らないだけ?)だったのでExRegExprValidatorというクラスをバリデータクラス作成の練習を兼ねて作ってみた。

package examples.jsf.validator;

import java.text.MessageFormat;
import java.util.ResourceBundle;

import javax.faces.application.FacesMessage;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

public class ExRegExprValidator implements Validator, StateHolder {

	private static final String BUNDLE_NAME = "Messages";

	//properties

	private String messageId;

	private Object[] messageArgs;

	private String pattern;

	private boolean _transient = false;

	//getter setter

	public String getMessageId() {
		return messageId;
	}

	public void setMessageId(String messageId) {
		this.messageId = messageId;
	}

	public Object[] getMessageArgs() {
		return messageArgs;
	}

	public void setMessageArgs(Object[] messageArgs) {
		this.messageArgs = messageArgs;
	}

	public String getPattern() {
		return pattern;
	}
	
	public void setPattern(String pattern) {
		this.pattern = pattern;
	}
	
	public boolean isTransient() {
		return _transient;
	}

	public void setTransient(boolean newTransientValue) {
		_transient = newTransientValue;
	}

	//method

	public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
		if (context == null) throw new NullPointerException("FacesContext");
		if (component == null) throw new NullPointerException("UIComponent");
		if (value == null) return;
		String text = value.toString();
		if (!text.matches(pattern)) {
			throw new ValidatorException(new FacesMessage(getResourceMessage()));
		}
	}

	private String getResourceMessage() {
		ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME);
		String mess = bundle.getString(messageId);
		return MessageFormat.format(mess, messageArgs);
	}

	public Object saveState(FacesContext context) {
		Object values[] = new Object[3];
		values[0] = pattern;
		values[1] = messageId;
		values[2] = messageArgs;
		return values;

	}

	public void restoreState(FacesContext context, Object state) {
		Object values[] = (Object[]) state;
		pattern = values[0].toString();
		messageId = values[1].toString();
		messageArgs = (Object[]) values[2];
	}

}

faces-config.xmlはこんな感じ。

<validator>
    <validator-id>examples.jsf.validator.ExRegExpr</validator-id>
    <validator-class>examples.jsf.validator.ExRegExprValidator</validator-class>
</validator>

Validator.diconと言うdiconファイルを作成。

<component name="userNameCharactorValidator" class="examples.jsf.validator.ExRegExprValidator">
	<property name="pattern">"[0-9A-Za-z]*"</property>
	<property name="messageId">"examples.jsf.userNameValidator"</property>
	<property name="messageArgs">new Object[0]</property>
</component>

一応、半角英数文字の入力書式チェックが出来た。messageArgsの書き方がわからない・・・(苦笑)

String型のmatchesを使っているからJDK1.4以上の対応。これだけ出来ればなんかもう二度とバリデータクラスは書かない気が。

カスタムタグは要らなさそうだから今は作らない。