Package com.alibaba.citrus.service.form.impl

Source Code of com.alibaba.citrus.service.form.impl.FormImpl

/*
* 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.impl;

import static com.alibaba.citrus.service.form.FormConstant.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.ObjectUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;

import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;

import com.alibaba.citrus.service.form.Form;
import com.alibaba.citrus.service.form.Group;
import com.alibaba.citrus.service.form.MessageContext;
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.service.form.impl.FormParameters.FormParameter;
import com.alibaba.citrus.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.TypeConverter;

/**
* 代表一个用户提交的form信息。
* <p>
* 注意:form对象不是线程安全的,不能被多线程共享。
* </p>
*
* @author Michael Zhou
*/
public class FormImpl implements Form {
    protected static final Logger log = LoggerFactory.getLogger(Form.class);
    private final FormConfig formConfig;
    private final String     formKey;
    private final boolean    forcePostOnly;
    private final Map<String, Group> groups    = createLinkedHashMap();
    private final Collection<Group>  groupList = Collections.unmodifiableCollection(groups.values());
    private final MessageContext      messageContext;
    private       boolean             valid;
    private       SimpleTypeConverter typeConverter;

    /** 创建一个新form。 */
    public FormImpl(FormConfig formConfig, String formKey, boolean forcePostOnly) {
        this.formConfig = formConfig;
        this.formKey = formKey;
        this.messageContext = MessageContextFactory.newInstance(this);
        this.forcePostOnly = forcePostOnly;
    }

    /** 取得form的配置信息。 */
    public FormConfig getFormConfig() {
        return formConfig;
    }

    /** 取得用于转换类型的converter。 */
    public TypeConverter getTypeConverter() {
        if (typeConverter == null) {
            typeConverter = new SimpleTypeConverter();
            getFormConfig().getPropertyEditorRegistrar().registerCustomEditors(typeConverter);
        }

        return typeConverter;
    }

    /** 是否强制为只接受post表单。 */
    public boolean isForcePostOnly() {
        return forcePostOnly;
    }

    /** 判定form是否通过验证。 */
    public boolean isValid() {
        return valid;
    }

    /** 设置form的合法性。该值将被叠加到当前的状态中:<code>this.valid &= valid</code> */
    protected void setValid(boolean valid) {
        this.valid &= valid;
    }

    /** 初始化form,将form恢复成“未验证”状态。随后,调用者可以重新设置值并手工验证表单。 */
    public void init() {
        init(null);
    }

    /** 用request初始化form。假如request为<code>null</code>,则将form设置成“未验证”状态,否则,验证表单。 */
    public void init(HttpServletRequest request) {
        valid = true;

        // 清除所有group
        groups.clear();

        if (request != null) {
            Set<String> ignoredGroups = createHashSet();
            boolean logStarted = false;

            // 扫描用户submit过来的所有form参数,找到符合格式的key:formKey.groupKey.instanceKey.fieldKey
            @SuppressWarnings("unchecked")
            Enumeration<String> e = request.getParameterNames();
            FormParameters params = new FormParameters(request);

            while (e.hasMoreElements()) {
                String key = e.nextElement();
                FormParameter param = parseParameterKey(key);

                // param为null表示该参数不是从form service生成的,忽略之
                if (param != null) {
                    if (!logStarted) {
                        logStarted = true;
                        log.debug("Initializing user-submitted form for validating");
                    }

                    params.addFormParameter(param);

                    String groupKey = param.groupKey;
                    String instanceKey = param.instanceKey;
                    String groupInstanceKey = getGroupInstanceKey(groupKey, instanceKey);

                    // 下面从request中初始化所有group instance,
                    // 并确保不会重复初始化同一个group instance。
                    if (!groups.containsKey(groupInstanceKey) && !ignoredGroups.contains(groupInstanceKey)) {
                        GroupConfig groupConfig = getFormConfig().getGroupConfigByKey(groupKey);

                        if (groupConfig == null) {
                            log.debug("No group associated with parameter: {}", key);
                            continue;
                        } else if ((forcePostOnly || groupConfig.isPostOnly())
                                   && !"post".equalsIgnoreCase(request.getMethod())) {
                            log.warn("Group {} can only read from POST request: {}", groupConfig.getName(), key);
                            ignoredGroups.add(groupInstanceKey);
                            setValid(false);
                            continue;
                        } else {
                            groups.put(groupInstanceKey, new GroupImpl(groupConfig, this, instanceKey));
                        }
                    }
                }
            }

            for (Group group : groups.values()) {
                if (log.isDebugEnabled()) {
                    if (DEFAULT_GROUP_INSTANCE_KEY.equals(group.getInstanceKey())) {
                        log.debug("Initializing form group: {}", group.getName());
                    } else {
                        log.debug("Initializing form group: {}[{}]", group.getName(), group.getInstanceKey());
                    }
                }

                if (group instanceof GroupImpl) {
                    ((GroupImpl) group).init(params);
                }
            }
        }
    }

    /**
     * 解析从URL中传过来的key,如果解析成功,则返回相应的groupKey,instanceKey和fieldKey,否则返回
     * <code>null</code>
     */
    private FormParameter parseParameterKey(String paramKey) {
        if (!paramKey.startsWith(FORM_KEY_PREFIX)) {
            return null;
        }

        String[] parts = StringUtil.split(paramKey, FIELD_KEY_SEPARATOR, 5);

        if (parts.length < 4 || !isEquals(parts[0], this.formKey)) {
            return null;
        }

        String groupKey = toLowerCase(parts[1]);
        String instanceKey = parts[2];
        String fieldKey = toLowerCase(parts[3]);
        String additionalInfo = parts.length > 4 ? parts[4] : null;

        // 取得规格化的group/field key,即:
        // 如果fieldKeyFormat=compressed,则为压缩格式;
        // 如果fieldKeyFormat=uncompressed,则为非压缩格式;
        // 如果group或field不存在,则暂且保持key原值,后面会报警告。
        GroupConfig groupConfig = getFormConfig().getGroupConfigByKey(groupKey);

        if (groupConfig != null) {
            groupKey = groupConfig.getKey();

            FieldConfig fieldConfig = groupConfig.getFieldConfigByKey(fieldKey);

            if (fieldConfig != null) {
                fieldKey = fieldConfig.getKey();
            }
        }

        String normalizedKey = FORM_KEY_PREFIX + FIELD_KEY_SEPARATOR + groupKey + FIELD_KEY_SEPARATOR + instanceKey
                               + FIELD_KEY_SEPARATOR + fieldKey;

        if (additionalInfo != null) {
            normalizedKey += FIELD_KEY_SEPARATOR + additionalInfo;
        }

        return new FormParameter(groupKey, fieldKey, instanceKey, additionalInfo, paramKey, normalizedKey);
    }

    /** 取得group instance的key,用来索引所有group instance。 */
    private String getGroupInstanceKey(String groupKey, String instanceKey) {
        return groupKey + FIELD_KEY_SEPARATOR + instanceKey;
    }

    /** 验证(或重新验证)当前的所有group instance。 */
    public void validate() {
        valid = true;

        for (Group group : getGroups()) {
            group.validate();
        }
    }

    /** 取得代表form的key。 */
    public String getKey() {
        return formKey;
    }

    /** 取得所有group的列表。 */
    public Collection<Group> getGroups() {
        return groupList;
    }

    /** 取得所有指定名称的group的列表。group名称大小写不敏感。 */
    public Collection<Group> getGroups(String groupName) {
        List<Group> resultGroups = createArrayList(groups.size());

        for (Group group : groups.values()) {
            if (group.getName().equalsIgnoreCase(groupName)) {
                resultGroups.add(group);
            }
        }

        return resultGroups;
    }

    /** 取得默认的group instance。如果该group instance不存在,则创建之。Group名称大小写不敏感。 */
    public Group getGroup(String groupName) {
        return getGroup(groupName, null, true);
    }

    /** 取得group instance。如果该group instance不存在,则创建之。Group名称大小写不敏感。 */
    public Group getGroup(String groupName, String instanceKey) {
        return getGroup(groupName, instanceKey, true);
    }

    /**
     * 取得group instance。如果该group instance不存在,并且<code>create == true</code>
     * ,则创建之。Group名称大小写不敏感。
     */
    public Group getGroup(String groupName, String instanceKey, boolean create) {
        GroupConfig groupConfig = getFormConfig().getGroupConfig(groupName);

        if (groupConfig == null) {
            return null;
        }

        instanceKey = defaultIfNull(trimToNull(instanceKey), DEFAULT_GROUP_INSTANCE_KEY);

        String groupInstanceKey = getGroupInstanceKey(groupConfig.getKey(), instanceKey);
        Group group = groups.get(groupInstanceKey);

        if (group == null && create) {
            group = new GroupImpl(groupConfig, this, instanceKey);
            groups.put(groupInstanceKey, group);
            group.init();
        }

        return group;
    }

    /** 取得form级别的错误信息表达式的context,包含常用小工具和所有系统属性。 */
    protected MessageContext getMessageContext() {
        return messageContext;
    }

    /** 转换成易于阅读的字符串。 */
    @Override
    public String toString() {
        return "Form[groups: " + getFormConfig().getGroupConfigList().size() + ", group instances: "
               + getGroups().size() + ", valid: " + isValid() + "]";
    }
}
TOP

Related Classes of com.alibaba.citrus.service.form.impl.FormImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.