/* * 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.configuration; import static com.alibaba.citrus.util.Assert.ExceptionType.*; import static com.alibaba.citrus.util.Assert.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import static java.util.Collections.*; import java.util.List; import java.util.Map; 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; /** * 代表一个form group的定义信息。 * * @author Michael Zhou */ public class GroupConfigImpl extends AbstractConfig<GroupConfig> implements GroupConfig { private FormConfig formConfig; private String parentGroup; private String name; private String key; private Map<String, FieldConfigImpl> fields; // field name to fieldConfig private Map<String, FieldConfigImpl> fieldsByKey; // field key to fieldConfig private List<Import> imports; // imported groups private List<Import> importList; // unmodifiable imported groups private List<FieldConfig> fieldList; // unmodifiable field list private Boolean trimmingByDefault; private Boolean postOnly; /** 取得group所属的form config。 */ public FormConfig getFormConfig() { return formConfig; } /** 设置group所属的form config。 */ public void setFormConfig(FormConfig formConfig) { this.formConfig = formConfig; } /** 取得group name。 */ public String getName() { return name; } /** 设置group name。 */ public void setName(String name) { this.name = trimToNull(name); } /** 取得group key。 */ public String getKey() { return key; } /** 设置group key。 */ public void setKey(String key) { this.key = trimToNull(key); } /** 取得parent group。 */ public String getParentGroup() { return parentGroup; } /** 设置parent group,所有parent group中的内容都会被加入到当前group中。 */ public void setParentGroup(String parentGroup) { this.parentGroup = trimToNull(parentGroup); } /** 取得默认的trimming选项。 */ public boolean isTrimmingByDefault() { return trimmingByDefault == null ? true : trimmingByDefault.booleanValue(); } /** 设置默认的trimming选项。 */ public void setTrimmingByDefault(boolean trimmingByDefault) { this.trimmingByDefault = trimmingByDefault; } /** Group是否必须从post请求中取得数据。 */ public boolean isPostOnly() { if (postOnly == null) { return formConfig == null ? true : formConfig.isPostOnlyByDefault(); } else { return postOnly.booleanValue(); } } /** 设置group是否必须从post请求中取得数据。 */ public void setPostOnly(boolean postOnly) { this.postOnly = postOnly; } /** 取得所有field config的列表。 */ public List<FieldConfig> getFieldConfigList() { if (fieldList == null) { return emptyList(); } else { return fieldList; } } /** 取得指定名称的field config。名称大小写不敏感。 如果未找到,则返回<code>null</code>。 */ public FieldConfig getFieldConfig(String fieldName) { if (fields == null) { return null; } else { return fields.get(caseInsensitiveName(fieldName)); } } /** 取得指定key对应的field config。如果未找到,则返回<code>null</code>。 */ public FieldConfig getFieldConfigByKey(String fieldKey) { return assertNotNull(fieldsByKey, ILLEGAL_STATE, "fieldsByKey not inited").get(fieldKey); } /** 设置一组field configs。 */ public void setFieldConfigImplList(List<FieldConfigImpl> fieldConfigList) { if (fieldConfigList != null) { fields = createLinkedHashMap(); for (FieldConfigImpl fieldConfig : fieldConfigList) { addFieldConfig(fieldConfig, true); // 大小写不敏感! } } } /** 添加一个field config。 */ private void addFieldConfig(FieldConfigImpl fieldConfig, boolean checkDuplicate) { if (fields == null) { fields = createLinkedHashMap(); } String fieldName = caseInsensitiveName(fieldConfig.getName()); // 大小写不敏感! if (checkDuplicate) { assertTrue(!fields.containsKey(fieldName), "Duplicated field name: \"%s.%s\"", getName(), fieldConfig.getName()); } fields.put(fieldName, fieldConfig); } /** 取得所有的imports。 */ public List<Import> getImports() { if (importList == null) { return emptyList(); } else { return importList; } } /** 引进其它group的字段。如果fieldName为null,则引进整个group(同extends)。 */ public void setImports(List<Import> imports) { if (imports != null) { this.imports = createArrayList(imports); this.importList = unmodifiableList(this.imports); } } /** 扩展当前group,将指定group中的内容复制到当前group中。 */ void extendsFrom(GroupConfigImpl parentGroupConfig) { if (trimmingByDefault == null && parentGroupConfig.trimmingByDefault != null) { trimmingByDefault = parentGroupConfig.trimmingByDefault; } if (postOnly == null && parentGroupConfig.postOnly != null) { postOnly = parentGroupConfig.postOnly; } extendsOrImports(parentGroupConfig, null, false); } /** 将指定group中的内容复制到当前group中。 */ void importsFrom(GroupConfigImpl srcGroupConfig, String fieldName) { extendsOrImports(srcGroupConfig, fieldName, true); } /** 扩展或引入fields。 */ private void extendsOrImports(GroupConfigImpl srcGroupConfig, String fieldName, boolean checkDuplicate) { if (fieldName == null) { // merge/import all for (FieldConfig srcFieldConfig : srcGroupConfig.getFieldConfigList()) { mergeField((FieldConfigImpl) srcFieldConfig, checkDuplicate); } } else { // merge/import single field FieldConfig srcFieldConfig = srcGroupConfig.getFieldConfig(fieldName); assertNotNull(srcFieldConfig, "Field \"%s.%s\" not found", srcGroupConfig.getName(), fieldName); mergeField((FieldConfigImpl) srcFieldConfig, checkDuplicate); } } /** 合并field。 */ private void mergeField(FieldConfigImpl srcFieldConfig, boolean checkDuplicate) { FieldConfigImpl copy = (FieldConfigImpl) getFieldConfig(srcFieldConfig.getName()); if (copy == null) { // 如果当前group中未定义同名的field,则创建之 copy = new FieldConfigImpl(); copy.setGroupConfig(this); } copy.mergeWith(srcFieldConfig); // 如果当前group中已经定义了同名的field,那么, // 当checkDuplicate==false时,合并field(extends group的情形), // 当checkDuplicate==true时,报错(imports field的情形) addFieldConfig(copy, checkDuplicate); } /** * 初始化group config。 * <p> * 不同于<code>init()</code>方法,此方法是被<code>formConfig.init()</code>调用。 * </p> */ void init2() throws Exception { assertNotNull(fields, "no fields"); fieldsByKey = createHashMap(); fieldList = createArrayList(fields.size()); for (Map.Entry<String, FieldConfigImpl> entry : fields.entrySet()) { String caseInsensitiveName = entry.getKey(); FieldConfigImpl fieldConfig = entry.getValue(); switch (getFormConfig().getFieldKeyFormat()) { case uncompressed: fieldConfig.setKey(caseInsensitiveName); break; default: // 设置不重复的、压缩的key for (int i = 1; i <= caseInsensitiveName.length(); i++) { String key = caseInsensitiveName.substring(0, i); if (!fieldsByKey.containsKey(key)) { fieldConfig.setKey(key); fieldsByKey.put(key, fieldConfig); break; } } break; } // 设置不压缩的key - 不可能重复,因为前面已经判断过了 fieldsByKey.put(caseInsensitiveName, fieldConfig); // 设置field.group fieldConfig.setGroupConfig(this); // 设置fieldList fieldList.add(fieldConfig); } fieldList = unmodifiableList(fieldList); // 初始化所有validators for (FieldConfig fieldConfig : fieldList) { for (Validator validator : fieldConfig.getValidators()) { validator.init(fieldConfig); } } } /** 转换成易于阅读的字符串。 */ @Override public String toString() { return "GroupConfig[name: " + getName() + ", fields: " + getFieldConfigList().size() + "]"; } /** 代表import其它group中的field的信息。 */ public static final class ImportImpl implements Import { private final String groupName; private final String fieldName; public ImportImpl(String groupName, String fieldName) { this.groupName = trimToNull(groupName); this.fieldName = trimToNull(fieldName); } public String getGroupName() { return groupName; } public String getFieldName() { return fieldName; } @Override public String toString() { return fieldName == null ? groupName : groupName + "." + fieldName; } } }