/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.service.form.support; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.StringUtil.*; import com.alibaba.citrus.expr.Expression; import com.alibaba.citrus.expr.ExpressionContext; import com.alibaba.citrus.expr.ExpressionFactory; import com.alibaba.citrus.expr.ExpressionParseException; import com.alibaba.citrus.expr.composite.CompositeExpressionFactory; import com.alibaba.citrus.service.form.Validator; import com.alibaba.citrus.service.form.configuration.FieldConfig; import com.alibaba.citrus.service.form.configuration.FormConfig; import com.alibaba.citrus.service.form.configuration.GroupConfig; import com.alibaba.citrus.springext.support.BeanSupport; import com.alibaba.citrus.util.ObjectUtil; import com.alibaba.citrus.util.StringEscapeUtil; import com.alibaba.citrus.util.i18n.LocaleUtil; import org.springframework.context.MessageSource; import org.springframework.context.MessageSourceAware; import org.springframework.context.NoSuchMessageException; /** * 抽象的<code>Validator</code>实现。 * * @author Michael Zhou */ public abstract class AbstractValidator extends BeanSupport implements Validator, MessageSourceAware { protected static final ExpressionFactory EXPRESSION_FACTORY = new CompositeExpressionFactory(); private String id; private String messageCode; private Message message; private MessageSource messageSource; public void setMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } /** * 是否需要检查message值? * <p> * 如果是,则message未指定时将报错。 * </p> */ protected boolean requiresMessage() { return true; } /** 当GroupConfig被初始化完成以后被调用,此时可取得同组中其它的fields。 */ public void init(FieldConfig fieldConfig) throws Exception { if (requiresMessage()) { boolean hasMessage = false; // 1. 从messageSource中查找 if (id != null && messageSource != null) { GroupConfig groupConfig = fieldConfig.getGroupConfig(); FormConfig formConfig = groupConfig.getFormConfig(); // form.groupName.fieldName.validatorId messageCode = formConfig.getMessageCodePrefix() + groupConfig.getName() + "." + fieldConfig.getName() + "." + id; hasMessage = getMessageFromMessageSource() != null; } // 2. 如果messageSource中找不到,则validator必须设置message if (!hasMessage) { assertNotNull(message, "no message"); message.compile(); } } } private String getMessageFromMessageSource() { try { return messageSource.getMessage(messageCode, null, LocaleUtil.getContext().getLocale()); } catch (NoSuchMessageException e) { return null; } } /** 取得validator的ID,通过该ID可以找到指定的validator。 */ public String getId() { return id == null ? getBeanName() : id; } /** 设置validator的ID,通过该ID可以找到指定的validator。 */ public void setId(String id) { this.id = trimToNull(id); } /** 取得出错信息。 */ public final String getMessage(Context context) { // 首先,假如message已经被设置,则直接返回。 // 例如all-of-validator就会设置这个message。 String result = trimToNull(context.getMessage()); if (result == null) { // 然后,试着查找message source(仅当id存在) Message message = this.message; if (messageCode != null && messageSource != null) { String messageFromMessageSource = getMessageFromMessageSource(); if (messageFromMessageSource != null) { message = new Message(messageFromMessageSource); message.compile(); } } // 渲染message if (message != null) { result = message.getMessageString(context.getMessageContext()); } } return result; } /** 设置出错信息。 */ public void setMessage(String message) { this.message = new Message(message); } /** 生成副本。 */ @Override public Validator clone() { try { return (Validator) super.clone(); } catch (CloneNotSupportedException e) { return null; // 不可能发生! } } /** 代表一个message表达式。 */ protected static class Message implements Cloneable { private String message; private Expression messageExpression; public Message(String message) { this.message = trimToNull(message); } /** 编译表达式。 */ public void compile() { assertNotNull(message, "message"); try { messageExpression = EXPRESSION_FACTORY.createExpression(message); } catch (ExpressionParseException e) { throw new IllegalArgumentException("Invalid message for validator " + getClass().getSimpleName() + ": \"" + StringEscapeUtil.escapeJava(message) + "\""); } } /** 取得出错信息。 */ public String getMessageString(ExpressionContext context) { return ObjectUtil.toString(messageExpression.evaluate(context), ""); } @Override public String toString() { return "ValidatorMessage[" + message + "]"; } } }