Package com.alibaba.citrus.service.moduleloader.impl.factory

Source Code of com.alibaba.citrus.service.moduleloader.impl.factory.AbstractModuleFactoryDefinitionParser$ParsingModuleInfo

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

import static com.alibaba.citrus.springext.util.DomUtil.*;
import static com.alibaba.citrus.springext.util.SpringExtUtil.*;
import static com.alibaba.citrus.util.Assert.*;
import static com.alibaba.citrus.util.CollectionUtil.*;
import static com.alibaba.citrus.util.StringUtil.*;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.citrus.service.moduleloader.impl.ModuleKey;
import com.alibaba.citrus.springext.support.parser.AbstractNamedBeanDefinitionParser;
import com.alibaba.citrus.springext.util.SpringExtUtil;
import com.alibaba.citrus.util.regex.MatchResultSubstitution;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionDefaults;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.w3c.dom.Element;

public abstract class AbstractModuleFactoryDefinitionParser<T> extends AbstractNamedBeanDefinitionParser<T> {
    protected final Logger log = LoggerFactory.getLogger(getBeanClass(null));

    /** 解析明确定义的beans,这些beans将覆盖自动搜索而得的module脚本。 */
    protected final Map<String, ParsingModuleInfo> parseSpecificBeans(Element element, ParserContext parserContext,
                                                                      AbstractBeanDefinition containingBd,
                                                                      ElementSelector beanSelector) {
        Map<String, ParsingModuleInfo> specificBeans = createHashMap();

        for (Element subElement : subElements(element, beanSelector)) {
            BeanDefinitionHolder bdh = (BeanDefinitionHolder) parserContext.getDelegate().parsePropertySubElement(
                    subElement, containingBd);

            String itemName = parseItemName(parserContext, subElement, bdh.getBeanDefinition());

            specificBeans.put(itemName, new ParsingModuleInfo(bdh.getBeanDefinition(), itemName));
        }

        log.debug("Found {} specificly defined modules", specificBeans.size());

        return specificBeans;
    }

    protected abstract String parseItemName(ParserContext parserContext, Element element, BeanDefinition bd);

    protected BeanDefinitionDefaults getBeanDefinitionDefaults(Element element, ParserContext parserContext) {
        BeanDefinitionDefaults defaults = new BeanDefinitionDefaults();
        String defaultLazyInit = trimToNull(element.getAttribute("defaultLazyInit"));
        String defaultAutowireMode = trimToNull(element.getAttribute("defaultAutowireMode"));

        if (defaultLazyInit == null) {
            defaults.setLazyInit(getDefaultLazyInit());
        } else {
            defaults.setLazyInit(Boolean.parseBoolean(defaultLazyInit));
        }

        if (defaultAutowireMode == null) {
            defaultAutowireMode = getDefaultAutowireMode();
        }

        defaults.setAutowireMode(parserContext.getDelegate().getAutowireMode(defaultAutowireMode));

        return defaults;
    }

    protected boolean getDefaultLazyInit() {
        return false;
    }

    protected String getDefaultAutowireMode() {
        return "no";
    }

    protected void postProcessItems(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
                                    Map<String, ParsingModuleInfo> items, String tags) {
        // 注册所有明确定义的beans
        for (ParsingModuleInfo item : items.values()) {
            if (item.bd != null) {
                assertNotNull(item.key, "Specificly-defined module could not be found in %s: %s", tags, item.itemName);

                item.beanName = SpringExtUtil.generateBeanName(item.getBaseBeanName(), parserContext.getRegistry());
                parserContext.getRegistry().registerBeanDefinition(item.beanName, item.bd);
            }
        }

        // 设置ModuleFactory.setModules()
        List<Object> moduleList = createManagedList(element, parserContext);

        log.debug("Defined {} modules with {}", items.size(), getBeanClass(null).getSimpleName());

        for (ParsingModuleInfo item : items.values()) {
            if (item.beanName != null) {
                BeanDefinitionBuilder bdb = BeanDefinitionBuilder.genericBeanDefinition(ModuleInfo.class);

                bdb.addConstructorArgValue(item.key);
                bdb.addConstructorArgValue(item.beanName);
                bdb.addConstructorArgValue(item.itemName); // className or script resourceName

                moduleList.add(bdb.getBeanDefinition());

                log.debug("Defined module {} with {}", new Object[] { item.key, item.itemName });
            }
        }

        builder.addPropertyValue("modules", moduleList);
    }

    /** 处理每一个匹配。 */
    protected static class ParsingModuleMatcher {
        private final Map<String, ParsingModuleInfo> items;
        private final Pattern                        itemPattern;
        private final String                         typeName;
        private final String                         moduleName;
        private       List<TypeFilter>               includeFilters;

        public ParsingModuleMatcher(Map<String, ParsingModuleInfo> items, Pattern itemPattern, String typeName,
                                    String moduleName) {
            this(items, itemPattern, typeName, moduleName, null);
        }

        public ParsingModuleMatcher(Map<String, ParsingModuleInfo> items, Pattern itemPattern, String typeName,
                                    String moduleName, List<TypeFilter> includeFilters) {
            this.items = items;
            this.itemPattern = itemPattern;
            this.typeName = typeName;
            this.moduleName = moduleName;
            this.includeFilters = includeFilters;
        }

        protected boolean doMatch(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
                throws IOException {
            String itemName = metadataReader.getAnnotationMetadata().getClassName();

            Matcher matcher = itemPattern.matcher(itemName);

            if (!matcher.find()) {
                return false;
            }

            //根据用户提供的Filter来过滤当前扫瞄的元信息(属于二次过滤)
            boolean matched = true;
            if (this.includeFilters != null) {
                matched = this.includeFilters.size() < 1;

                for (TypeFilter filter : this.includeFilters) {

                    if (matched) {
                        break;
                    }

                    try {
                        matched = filter.match(metadataReader, metadataReaderFactory);
                    } catch (Exception e) {
                        matched = false;
                    }
                }
            }

            if (!matched) {
                return false;
            }

            return this.match(itemName, matcher);
        }

        protected final boolean doMatch(String itemName) {
            Matcher matcher = itemPattern.matcher(itemName);

            if (!matcher.find()) {
                return false;
            }

            return match(itemName, matcher);
        }

        private boolean match(String itemName, Matcher matcher) {
            MatchResultSubstitution subs = new MatchResultSubstitution(matcher);

            String type = trimToNull(subs.substitute(typeName));
            String name;

            if (type == null) {
                return false;
            }

            if (moduleName == null) {
                int startIndex = subs.getMatch().end() + 1;

                if (itemName.length() > startIndex) {
                    name = itemName.substring(startIndex);
                } else {
                    return false;
                }
            } else {
                name = subs.substitute(moduleName);
            }

            name = getName(name, itemName);

            if (items.containsKey(itemName)) {
                ParsingModuleInfo item = items.get(itemName);

                // 对于特别创建的bean,补充其type和name信息。
                if (item.bd != null && item.key == null) {
                    item.key = new ModuleKey(type, name);
                }

                // 忽略重复匹配的类
                return false;
            } else {
                items.put(itemName, new ParsingModuleInfo(type, name, itemName));
                return true;
            }
        }

        protected String getName(String name, String itemName) {
            return name;
        }

        protected final String generateBeanName(String itemName, BeanDefinitionRegistry registry) {
            ParsingModuleInfo item = assertNotNull(items.get(itemName), "missing %s", itemName);

            item.beanName = SpringExtUtil.generateBeanName(item.getBaseBeanName(), registry);

            return item.beanName;
        }
    }

    /** 代表一个module的解析时信息。 */
    protected static class ParsingModuleInfo {
        final BeanDefinition bd;
        final String         itemName;
        String    beanName;
        ModuleKey key;

        public ParsingModuleInfo(String moduleType, String moduleName, String itemName) {
            this.bd = null;
            this.key = new ModuleKey(moduleType, moduleName);
            this.itemName = itemName;
        }

        public ParsingModuleInfo(BeanDefinition bd, String itemName) {
            this.bd = bd;
            this.itemName = itemName;
        }

        public String getBaseBeanName() {
            return "module." + key.getModuleType() + "." + key.getModuleName();
        }
    }
}
TOP

Related Classes of com.alibaba.citrus.service.moduleloader.impl.factory.AbstractModuleFactoryDefinitionParser$ParsingModuleInfo

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.