Package com.alibaba.citrus.turbine.dataresolver.impl

Source Code of com.alibaba.citrus.turbine.dataresolver.impl.FormResolverFactory$FieldResolver

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

import static com.alibaba.citrus.generictype.TypeInfoUtil.*;
import static com.alibaba.citrus.springext.util.SpringExtUtil.*;
import static com.alibaba.citrus.turbine.dataresolver.impl.DataResolverUtil.*;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.StringUtil.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.alibaba.citrus.service.dataresolver.DataResolver;
import com.alibaba.citrus.service.dataresolver.DataResolverContext;
import com.alibaba.citrus.service.dataresolver.DataResolverFactory;
import com.alibaba.citrus.service.form.Field;
import com.alibaba.citrus.service.form.Form;
import com.alibaba.citrus.service.form.FormService;
import com.alibaba.citrus.service.form.Group;
import com.alibaba.citrus.service.form.configuration.FieldConfig;
import com.alibaba.citrus.service.form.configuration.GroupConfig;
import com.alibaba.citrus.service.moduleloader.SkipModuleExecutionException;
import com.alibaba.citrus.springext.support.parser.AbstractSingleBeanDefinitionParser;
import com.alibaba.citrus.turbine.dataresolver.FormData;
import com.alibaba.citrus.turbine.dataresolver.FormField;
import com.alibaba.citrus.turbine.dataresolver.FormFields;
import com.alibaba.citrus.turbine.dataresolver.FormGroup;
import com.alibaba.citrus.turbine.dataresolver.FormGroups;
import net.sf.cglib.reflect.FastConstructor;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.MethodParameter;
import org.w3c.dom.Element;

public class FormResolverFactory implements DataResolverFactory {
    private final FormService formService;

    public FormResolverFactory(FormService formService) {
        this.formService = formService;
    }

    public DataResolver getDataResolver(DataResolverContext context) {
        // 当所需要的对象未定义时,resolver factory仍可以创建,但在取得resolver时报错。
        // 这样使得同一套配置可用于所有环境,仅当你需要注入特定对象时,才报错。
        assertNotNull(formService, "no FormService defined");

        Class<?> paramType = context.getTypeInfo().getRawType();

        // Form对象
        FormData formAnnotation = context.getAnnotation(FormData.class);

        if (formAnnotation != null || paramType.isAssignableFrom(Form.class)) {
            return new FormResolver(context, paramType, formAnnotation);
        }

        // Group对象:annotation @FormGroup,参数类型可为Group或任意POJO
        FormGroup groupAnnotation = context.getAnnotation(FormGroup.class);

        if (groupAnnotation != null) {
            return new GroupResolver(context, paramType, groupAnnotation);
        }

        // Field对象:annotation @FormField,参数类型可为Field或任意类型
        FormField fieldAnnotation = context.getAnnotation(FormField.class);

        if (fieldAnnotation != null) {
            return new FieldResolver(context, paramType, fieldAnnotation);
        }

        // Groups对象:annotation @FormGroups,参数类型可为Group[],List<Group>或任意可转换的类型
        FormGroups groupsAnnotation = context.getAnnotation(FormGroups.class);

        if (groupsAnnotation != null) {
            return new GroupsResolver(context, paramType, groupsAnnotation);
        }

        // Fields对象:annotation @FormFields,参数类型可为Field[],List<Field>或任意可转换的类型
        FormFields fieldsAnnotation = context.getAnnotation(FormFields.class);

        if (fieldsAnnotation != null) {
            return new FieldsResolver(context, paramType, fieldsAnnotation);
        }

        return null;
    }

    private boolean isConverterQuiet(Form form) {
        return form.getFormConfig().isConverterQuiet();
    }

    /** 检验form中的所有groups均被检验,并通过所有验证。 */
    private boolean isValidatedAndValid(Form form) {
        if (!form.isValid() || form.getGroups().isEmpty()) {
            return false;
        }

        for (Group group : form.getGroups()) {
            if (!group.isValidated()) {
                return false;
            }
        }

        return true;
    }

    private class FormResolver extends AbstractFormResolver {
        public FormResolver(DataResolverContext context, Class<?> paramType, FormData formAnnotation) {
            super("FormResolver", context);

            // 参数类型必须为Form
            assertTrue(paramType.isAssignableFrom(Form.class), "Parameter type annotated with @FormData should be Form");

            this.skipIfInvalid = true;

            // @FormData可选
            if (formAnnotation != null) {
                this.skipIfInvalid = formAnnotation.skipIfInvalid();
            }
        }

        public Object resolve() {
            Form form = formService.getForm();
            skipModuleExecutionIfNecessary(isValidatedAndValid(form), form);
            return form;
        }
    }

    private class GroupResolver extends AbstractFormResolver {
        private final String          groupName;
        private final String          groupInstanceKey;
        private final FastConstructor fc;

        public GroupResolver(DataResolverContext context, Class<?> paramType, FormGroup groupAnnotation) {
            super("GroupResolver", context);

            groupInstanceKey = trimToNull(groupAnnotation.instanceKey());
            skipIfInvalid = groupAnnotation.skipIfInvalid();

            // name()或value() - 确保group存在
            groupName = getGroupConfig(
                    getAnnotationNameOrValue(FormGroup.class, groupAnnotation, context, groupInstanceKey != null
                                                                                        || skipIfInvalid == false)).getName();

            // 假如是pojo,则取得constructor。
            if (!paramType.isAssignableFrom(Group.class)) {
                fc = getFastConstructor(paramType);
            } else {
                fc = null;
            }
        }

        public Object resolve() {
            Form form = formService.getForm();
            Group group = form.getGroup(groupName, groupInstanceKey);

            boolean valid = isValidatedAndValid(form);

            if (fc == null) {
                skipModuleExecutionIfNecessary(valid, group);
                return group;
            } else {
                skipModuleExecutionIfNecessary(valid, null);

                if (valid) {
                    Object object = newInstance(fc);
                    group.setProperties(object);
                    return object;
                } else {
                    return null;
                }
            }
        }
    }

    private class FieldResolver extends AbstractFormResolver {
        private final String groupName;
        private final String groupInstanceKey;
        private final String fieldName;

        public FieldResolver(DataResolverContext context, Class<?> paramType, FormField fieldAnnotation) {
            super("FieldResolver", context);

            // 确保group存在
            groupName = getGroupConfig(fieldAnnotation.group()).getName();

            // 确保field存在
            fieldName = getFieldConfig(groupName, fieldAnnotation.name()).getName();

            groupInstanceKey = trimToNull(fieldAnnotation.groupInstanceKey());
            skipIfInvalid = fieldAnnotation.skipIfInvalid();
        }

        public Object resolve() {
            Form form = formService.getForm();
            Group group = form.getGroup(groupName, groupInstanceKey);
            Field field = group.getField(fieldName);

            boolean valid = isValidatedAndValid(form);

            if (context.getTypeInfo().getRawType().isAssignableFrom(Field.class)) {
                skipModuleExecutionIfNecessary(valid, field);
                return field;
            } else {
                skipModuleExecutionIfNecessary(valid, null);

                if (valid) {
                    try {
                        return field.getValueOfType(context.getTypeInfo().getRawType(),
                                                    context.getExtraObject(MethodParameter.class), null);
                    } catch (TypeMismatchException e) {
                        if (!isConverterQuiet(form)) {
                            throw e;
                        }
                    }
                }

                return null;
            }
        }
    }

    private class GroupsResolver extends AbstractFormResolver {
        private final String          groupName;
        private final Class<?>        componentType;
        private final FastConstructor fc;

        public GroupsResolver(DataResolverContext context, Class<?> paramType, FormGroups groupsAnnotation) {
            super("GroupResolver", context);

            skipIfInvalid = groupsAnnotation.skipIfInvalid();

            // name()或value() - 确保group存在
            groupName = getGroupConfig(
                    getAnnotationNameOrValue(FormGroups.class, groupsAnnotation, context, skipIfInvalid == false))
                    .getName();

            // param类型:数组、Collection
            if (paramType.isArray()) {
                componentType = paramType.getComponentType();
            } else if (Collection.class.isAssignableFrom(paramType)) {
                componentType = resolveIterableElement(context.getTypeInfo()).getRawType();
            } else {
                componentType = null;
            }

            // component类型可以是Group或任意类,但不能是Object。
            assertTrue(componentType != null && !Object.class.equals(componentType), "Invalid paramType: %s",
                       context.getTypeInfo());

            if (!componentType.isAssignableFrom(Group.class)) {
                fc = getFastConstructor(componentType);
            } else {
                fc = null;
            }
        }

        public Object resolve() {
            Form form = formService.getForm();
            Collection<Group> groups = form.getGroups(groupName);

            boolean valid = isValidatedAndValid(form);

            if (fc == null) {
                Object result = null;

                try {
                    result = form.getTypeConverter().convertIfNecessary(groups, context.getTypeInfo().getRawType(),
                                                                        context.getExtraObject(MethodParameter.class));
                } catch (TypeMismatchException e) {
                    if (!isConverterQuiet(form)) {
                        throw e;
                    }

                    return null;
                }

                skipModuleExecutionIfNecessary(valid, result);
                return result;
            } else {
                skipModuleExecutionIfNecessary(valid, null);

                if (!valid) {
                    return null;
                }

                Object[] results = new Object[groups.size()];

                int i = 0;
                for (Group group : groups) {
                    Object object = newInstance(fc);
                    group.setProperties(object);
                    results[i++] = object;
                }

                try {
                    return form.getTypeConverter().convertIfNecessary(results, context.getTypeInfo().getRawType(),
                                                                      context.getExtraObject(MethodParameter.class));
                } catch (TypeMismatchException e) {
                    if (!isConverterQuiet(form)) {
                        throw e;
                    }

                    return null;
                }
            }
        }
    }

    private class FieldsResolver extends AbstractFormResolver {
        private final String   groupName;
        private final String   fieldName;
        private final Class<?> componentType;

        public FieldsResolver(DataResolverContext context, Class<?> paramType, FormFields fieldsAnnotation) {
            super("FieldsResolver", context);

            skipIfInvalid = fieldsAnnotation.skipIfInvalid();

            // 确保group存在
            groupName = getGroupConfig(fieldsAnnotation.group()).getName();

            // 确保field存在
            fieldName = getFieldConfig(groupName, fieldsAnnotation.name()).getName();

            // param类型:数组、Collection
            if (paramType.isArray()) {
                componentType = paramType.getComponentType();
            } else if (Collection.class.isAssignableFrom(paramType)) {
                componentType = resolveIterableElement(context.getTypeInfo()).getRawType();
            } else {
                componentType = null;
            }

            // component类型可以是Field或任意类,但不能是Object。
            assertTrue(componentType != null && !Object.class.equals(componentType), "Invalid paramType: %s",
                       context.getTypeInfo());
        }

        public Object resolve() {
            Form form = formService.getForm();

            // 取得同名group instances中的指定field。
            Collection<Group> groups = form.getGroups(groupName);
            List<Field> fields = new ArrayList<Field>(groups.size());

            for (Group group : groups) {
                fields.add(group.getField(fieldName));
            }

            boolean valid = isValidatedAndValid(form);

            if (componentType.isAssignableFrom(Field.class)) {
                Object result = null;

                try {
                    result = form.getTypeConverter().convertIfNecessary(fields, context.getTypeInfo().getRawType(),
                                                                        context.getExtraObject(MethodParameter.class));
                } catch (TypeMismatchException e) {
                    if (!isConverterQuiet(form)) {
                        throw e;
                    }

                    return null;
                }

                skipModuleExecutionIfNecessary(valid, result);
                return result;
            } else {
                skipModuleExecutionIfNecessary(valid, null);

                if (!valid) {
                    return null;
                }

                Object[] results = new Object[fields.size()];

                for (int i = 0; i < results.length; i++) {
                    try {
                        results[i] = fields.get(i).getValueOfType(componentType,
                                                                  context.getExtraObject(MethodParameter.class), null);
                    } catch (TypeMismatchException e) {
                        if (!isConverterQuiet(form)) {
                            throw e;
                        }

                        results[i] = null;
                    }
                }

                try {
                    return form.getTypeConverter().convertIfNecessary(results, context.getTypeInfo().getRawType(),
                                                                      context.getExtraObject(MethodParameter.class));
                } catch (TypeMismatchException e) {
                    if (!isConverterQuiet(form)) {
                        throw e;
                    }

                    return null;
                }
            }
        }
    }

    private abstract class AbstractFormResolver extends AbstractDataResolver {
        protected boolean skipIfInvalid;

        private AbstractFormResolver(String desc, DataResolverContext context) {
            super(desc, context);
        }

        protected final void skipModuleExecutionIfNecessary(boolean valid, Object valueForNonSkippable)
                throws SkipModuleExecutionException {
            if (skipIfInvalid && !valid) {
                throw new SkipModuleExecutionException("Form data is not valid", valueForNonSkippable);
            }
        }

        protected final GroupConfig getGroupConfig(String groupName) {
            groupName = assertNotNull(trimToNull(groupName), "group name is empty");
            return assertNotNull(formService.getFormConfig().getGroupConfig(groupName),
                                 "group \"%s\" does not defined", groupName);
        }

        protected final FieldConfig getFieldConfig(String groupName, String fieldName) {
            GroupConfig groupConfig = getGroupConfig(groupName);
            fieldName = assertNotNull(trimToNull(fieldName), "field name is empty");
            return assertNotNull(groupConfig.getFieldConfig(fieldName), "field \"%s.%s\" does not defined",
                                 groupConfig.getName(), fieldName);
        }
    }

    public static class DefinitionParser extends AbstractSingleBeanDefinitionParser<FormResolverFactory> {
        @Override
        protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
            addConstructorArg(builder, false, FormService.class);
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.turbine.dataresolver.impl.FormResolverFactory$FieldResolver

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.