/**
* Copyright (c) 2011-2012, James Zhan 詹波 (jfinal@126.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jfinal.validate;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.jfinal.aop.Interceptor;
import com.jfinal.core.ActionInvocation;
import com.jfinal.core.Controller;
/**
* Validator.
*/
public abstract class Validator implements Interceptor {
private Controller controller;
private ActionInvocation invocation;
private boolean shortCircuit = false;
private boolean invalid = false;
private static final String emailAddressPattern = "\\b(^['_A-Za-z0-9-]+(\\.['_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b";
protected void setShortCircuit(boolean shortCircuit) {
this.shortCircuit = shortCircuit;
}
final public void intercept(ActionInvocation invocation) {
Validator validator = null;
try {validator = getClass().newInstance();}
catch (Exception e) {throw new RuntimeException(e);}
validator.controller = invocation.getController();
validator.invocation = invocation;
try {validator.validate(validator.controller);}
catch (ValidateException e) {/* should not be throw */} // short circuit validate need this
if (validator.invalid)
validator.handleError(validator.controller);
else
invocation.invoke();
}
/**
* Use validateXxx method to validate the parameters of this action.
*/
protected abstract void validate(Controller c);
/**
* Handle the validate error.
* Example:<br>
* controller.keepPara();<br>
* controller.render("register.html");
*/
protected abstract void handleError(Controller c);
/**
* Add message when validate failure.
*/
protected void addError(String errorKey, String errorMessage) {
invalid = true;
controller.setAttr(errorKey, errorMessage);
if (shortCircuit) {
throw new ValidateException();
}
}
/**
* Return the action key of this action.
*/
protected String getActionKey() {
return invocation.getActionKey();
}
/**
* Return the controller key of this action.
*/
protected String getControllerKey() {
return invocation.getControllerKey();
}
/**
* Validate Required.
*/
protected void validateRequired(String field, String errorKey, String errorMessage) {
String value = controller.getPara(field);
if (value == null || "".equals(value)) // 经测试,无输入时值为"",跳格键值为"\t",输入空格则为空格" "
addError(errorKey, errorMessage);
}
/**
* Validate required string.
*/
protected void validateRequiredString(String field, String errorKey, String errorMessage) {
String value = controller.getPara(field);
if (value == null || "".equals(value.trim()))
addError(errorKey, errorMessage);
}
/**
* Validate integer.
*/
protected void validateInteger(String field, int min, int max, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
int temp = Integer.parseInt(value);
if (temp < min || temp > max)
addError(errorKey, errorMessage);
}
catch (Exception e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate long.
*/
protected void validateLong(String field, long min, long max, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
long temp = Long.parseLong(value);
if (temp < min || temp > max)
addError(errorKey, errorMessage);
}
catch (Exception e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate long.
*/
protected void validateLong(String field, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
Long.parseLong(value);
}
catch (Exception e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate double.
*/
protected void validateDouble(String field, double min, double max, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
double temp = Double.parseDouble(value);
if (temp < min || temp > max)
addError(errorKey, errorMessage);
}
catch (Exception e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate double.
*/
protected void validateDouble(String field, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
Double.parseDouble(value);
}
catch (Exception e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate date.
*/
protected void validateDate(String field, Date min, Date max, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
Date temp = new SimpleDateFormat(datePattern).parse(value); // Date temp = Date.valueOf(value); 为了兼容 64位 JDK
if (temp.before(min) || temp.after(max))
addError(errorKey, errorMessage);
}
catch (Exception e) {
addError(errorKey, errorMessage);
}
}
// TODO set in Const and config it in Constants. TypeConverter do the same thing.
private static final String datePattern = "yyyy-MM-dd";
/**
* Validate date. Date formate: yyyy-MM-dd
*/
protected void validateDate(String field, String min, String max, String errorKey, String errorMessage) {
// validateDate(field, Date.valueOf(min), Date.valueOf(max), errorKey, errorMessage); 为了兼容 64位 JDK
try {
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
validateDate(field, sdf.parse(min), sdf.parse(max), errorKey, errorMessage);
} catch (ParseException e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate equal field. Usually validate password and password again
*/
protected void validateEqualField(String field_1, String field_2, String errorKey, String errorMessage) {
String value_1 = controller.getPara(field_1);
String value_2 = controller.getPara(field_2);
if (value_1 == null || value_2 == null || (! value_1.equals(value_2)))
addError(errorKey, errorMessage);
}
/**
* Validate equal string.
*/
protected void validateEqualString(String s1, String s2, String errorKey, String errorMessage) {
if (s1 == null || s2 == null || (! s1.equals(s2)))
addError(errorKey, errorMessage);
}
/**
* Validate equal integer.
*/
protected void validateEqualInteger(Integer i1, Integer i2, String errorKey, String errorMessage) {
if (i1 == null || i2 == null || (i1.intValue() != i2.intValue()))
addError(errorKey, errorMessage);
}
/**
* Validate email.
*/
protected void validateEmail(String field, String errorKey, String errorMessage) {
validateRegex(field, emailAddressPattern, false, errorKey, errorMessage);
}
/**
* Validate URL.
*/
protected void validateUrl(String field, String errorKey, String errorMessage) {
try {
String value = controller.getPara(field);
if (value.startsWith("https://"))
value = "http://" + value.substring(8); // URL doesn't understand the https protocol, hack it
new URL(value);
} catch (MalformedURLException e) {
addError(errorKey, errorMessage);
}
}
/**
* Validate regular expression.
*/
protected void validateRegex(String field, String regExpression, boolean isCaseSensitive, String errorKey, String errorMessage) {
Pattern pattern = isCaseSensitive ? Pattern.compile(regExpression) : Pattern.compile(regExpression, Pattern.CASE_INSENSITIVE);
String value = controller.getPara(field);
if (value == null) {
addError(errorKey, errorMessage);
return ;
}
Matcher matcher = pattern.matcher(value);
if (!matcher.matches())
addError(errorKey, errorMessage);
}
/**
* Validate regular expression and case sensitive.
*/
protected void validateRegex(String field, String regExpression, String errorKey, String errorMessage) {
validateRegex(field, regExpression, true, errorKey, errorMessage);
}
protected void validateString(String field, boolean notBlank, int minLen, int maxLen, String errorKey, String errorMessage) {
String value = controller.getPara(field);
if (value == null || value.length() < minLen || value.length() > maxLen)
addError(errorKey, errorMessage);
else if(notBlank && "".equals(value.trim()))
addError(errorKey, errorMessage);
}
/**
* Validate string.
*/
protected void validateString(String field, int minLen, int maxLen, String errorKey, String errorMessage) {
validateString(field, true, minLen, maxLen, errorKey, errorMessage);
}
/**
* Validate token created by Controller.createToken(String).
*/
protected void validateToken(String tokenName, String errorKey, String errorMessage) {
if (controller.validateToken(tokenName) == false)
addError(errorKey, errorMessage);
}
/**
* Validate token created by Controller.createToken().
*/
protected void validateToken(String errorKey, String errorMessage) {
if (controller.validateToken() == false)
addError(errorKey, errorMessage);
}
}