カスタムバリデーター2

先日作成したカスタムバリデータを国際化対応した。

ExRegExprValidator.java

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 = "Message";

	//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 mId = bundle.getString(messageId);
		
		Object[] mArgs = new Object[messageArgs.length];
		for(int i=0; i<messageArgs.length; i++){
			mArgs[i] = bundle.getString(messageArgs[i].toString());
		}
		
		return MessageFormat.format(mId, mArgs);
	}

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

}

Validator.dicon

<component 
  name="numericCharactorValidator" 
  class="examples.jsf.validator.ExRegExprValidator">
  <property name="pattern">"[0-9]*"</property>
  <property name="messageId">"examples.jsf.numericValidator"</property>
  <property name="messageArgs">new String[] {"user.id"}</property>
</component>

Message_ja.properties

user.id=ユーザー番号
examples.jsf.numericValidator="{0}": 入力が正しくありません。半角の数値を入力して下さい。

もう少し楽に書けるようになりたいけど、こんなもんか。

TODO:

  • 任意のBUNDLE_NAM。faces-config.xmlをそのまま利用してもいいかも。ない場合のデフォルトはExRegExprValidator.propertiesとか。
  • 良く使うパターンを書き溜める。