com.bstek.dorado.idesupport.RuleTemplateBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.bstek.dorado.idesupport.RuleTemplateBuilder.java

Source

/*
 * This file is part of Dorado 7.x (http://dorado7.bsdn.org).
 * 
 * Copyright (c) 2002-2012 BSTEK Corp. All rights reserved.
 * 
 * This file is dual-licensed under the AGPLv3 (http://www.gnu.org/licenses/agpl-3.0.html) 
 * and BSDN commercial (http://www.bsdn.org/licenses) licenses.
 * 
 * If you are unsure which license is appropriate for your use, please contact the sales department
 * at http://www.bstek.com/contact.
 */

package com.bstek.dorado.idesupport;

import java.io.FileNotFoundException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.bstek.dorado.config.xml.XmlParser;
import com.bstek.dorado.core.Context;
import com.bstek.dorado.core.io.Resource;
import com.bstek.dorado.core.pkgs.PackageInfo;
import com.bstek.dorado.core.xml.XmlDocumentBuilder;
import com.bstek.dorado.idesupport.initializer.InitializerContext;
import com.bstek.dorado.idesupport.initializer.RuleTemplateInitializer;
import com.bstek.dorado.idesupport.parse.ConfigRuleParseContext;
import com.bstek.dorado.idesupport.template.ChildTemplate;
import com.bstek.dorado.idesupport.template.RuleTemplate;
import com.bstek.dorado.util.PathUtils;
import com.bstek.dorado.util.clazz.ClassUtils;

/**
 * @author Benny Bao (mailto:benny.bao@bstek.com)
 * @since 2009-11-18
 */
public class RuleTemplateBuilder implements RuleTemplateManagerListener {
    private XmlDocumentBuilder xmlDocumentBuilder;
    private XmlParser preloadParser;
    private XmlParser ruleTemplateParser;
    private Map<String, RuleTemplateInitializer> initializerNameMap = new LinkedHashMap<String, RuleTemplateInitializer>();
    private Map<Class<?>, RuleTemplateInitializer> initializerTypeMap = new LinkedHashMap<Class<?>, RuleTemplateInitializer>();

    private List<String> configTemplateFiles;

    private int initializingRuleTemplate = 0;
    private InitializerContext initializerContext;

    public void setXmlDocumentBuilder(XmlDocumentBuilder xmlDocumentBuilder) {
        this.xmlDocumentBuilder = xmlDocumentBuilder;
    }

    public void setConfigTemplateFiles(List<String> configTemplateFiles) {
        this.configTemplateFiles = configTemplateFiles;
    }

    public void setPreloadParser(XmlParser preloadParser) {
        this.preloadParser = preloadParser;
    }

    public void setRuleTemplateParser(XmlParser ruleTemplateParser) {
        this.ruleTemplateParser = ruleTemplateParser;
    }

    public void setInitializerMap(Map<String, RuleTemplateInitializer> initializerMap)
            throws ClassNotFoundException, LinkageError {
        this.initializerNameMap = new LinkedHashMap<String, RuleTemplateInitializer>();
        this.initializerTypeMap = new LinkedHashMap<Class<?>, RuleTemplateInitializer>();

        appendInitializerMap(initializerMap);
    }

    public void appendInitializerMap(Map<String, RuleTemplateInitializer> initializerMap)
            throws ClassNotFoundException {
        for (Map.Entry<String, RuleTemplateInitializer> entry : initializerMap.entrySet()) {
            String key = entry.getKey();
            RuleTemplateInitializer initialier = entry.getValue();
            if (initialier instanceof RuleTemplateBuilderAware) {
                ((RuleTemplateBuilderAware) initialier).setRuleTemplateBuilder(this);
            }

            if (key.startsWith("classType:")) {
                initializerTypeMap.put(ClassUtils.forName(key.substring(10)), initialier);
            } else {
                initializerNameMap.put(key, initialier);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public RuleTemplateManager getRuleTemplateManager() throws Exception {
        RuleTemplateManager ruleTemplateManager = new RuleTemplateManager();
        ruleTemplateManager.addListener(this);

        ConfigRuleParseContext parserContext = new ConfigRuleParseContext();
        parserContext.setRuleTemplateManager(ruleTemplateManager);

        for (String configTemplateFile : configTemplateFiles) {
            Document document = xmlDocumentBuilder.loadDocument(getResource(configTemplateFile));
            parseRuleConfigDocument(parserContext, document);
        }
        ruleTemplateManager.setVersion(Constants.RULE_CONFIG_VERSION);

        ruleTemplateManager.getPackageInfos().clear();
        List<PackageInfo> packageInfos = (List<PackageInfo>) parserContext.getAttributes().get("packageInfos");
        if (packageInfos != null) {
            ruleTemplateManager.getPackageInfos().addAll(packageInfos);
        }

        for (RuleTemplate ruleTemplate : parserContext.getRuleTemplateMap().values()) {
            ruleTemplateManager.addRuleTemplate(ruleTemplate);
        }

        initRuleTemplates(ruleTemplateManager);
        return ruleTemplateManager;
    }

    private Resource getResource(String file) throws FileNotFoundException {
        Resource resource = Context.getCurrent().getResource(file);
        if (!resource.exists()) {
            throw new FileNotFoundException("File not exists - [" + resource + "]");
        }
        return resource;
    }

    public void parseRuleConfigDocument(ConfigRuleParseContext parserContext, Document document) throws Exception {
        Element documentElement = document.getDocumentElement();
        parserContext.getRuleTemplateManager().setVersion(documentElement.getAttribute("version"));

        preloadParser.parse(documentElement, parserContext);

        Map<String, Element> ruleElementMap = parserContext.getRuleElementMap();
        for (String name : ruleElementMap.keySet().toArray(new String[0])) {
            Element element = ruleElementMap.get(name);
            ruleTemplateParser.parse(element, parserContext);
        }
    }

    protected void initRuleTemplates(RuleTemplateManager ruleTemplateManager) throws Exception {
        InitializerContext initializerContext = new InitializerContext(ruleTemplateManager);
        this.initializerContext = initializerContext;
        try {
            for (RuleTemplate ruleTemplate : ruleTemplateManager.getRuleTemplates().toArray(new RuleTemplate[0])) {
                initRuleTemplate(initializerContext, ruleTemplate);
            }
        } finally {
            this.initializerContext = null;
        }
    }

    public void initRuleTemplate(InitializerContext initializerContext, RuleTemplate ruleTemplate)
            throws Exception {
        if (ruleTemplate.isInitialized()) {
            return;
        }
        ruleTemplate.setInitialized(true);

        initializingRuleTemplate++;
        try {
            String parentName = null, parentNodeName = null;
            RuleTemplate[] parents = ruleTemplate.getParents();
            if (parents != null) {
                for (RuleTemplate parent : parents) {
                    initRuleTemplate(initializerContext, parent);
                    if (StringUtils.isNotEmpty(parent.getName())) {
                        parentName = parent.getName();
                    }
                    if (StringUtils.isNotEmpty(parent.getNodeName())) {
                        parentNodeName = parent.getNodeName();
                    }
                }
            }

            if (StringUtils.isEmpty(ruleTemplate.getName())) {
                if (StringUtils.isEmpty(ruleTemplate.getNodeName())) {
                    if (parentNodeName != null) {
                        ruleTemplate.setNodeName(parentNodeName);
                    } else if (parentName != null) {
                        ruleTemplate.setNodeName(parentName);
                    } else {
                        throw new IllegalArgumentException(
                                "Neither [name] nor [nodeName] is defined for the Rule.");
                    }
                }
            }

            processInitializer(ruleTemplate, initializerContext);

            Collection<ChildTemplate> children = ruleTemplate.getChildren().values();
            if (!children.isEmpty()) {
                for (ChildTemplate childTemplate : children) {
                    initRuleTemplate(initializerContext, childTemplate.getRuleTemplate());
                }
            }
        } finally {
            initializingRuleTemplate--;
        }
    }

    protected void processInitializer(RuleTemplate ruleTemplate, InitializerContext initializerContext)
            throws Exception {
        String ruleName = ruleTemplate.getName();
        for (Map.Entry<String, RuleTemplateInitializer> entry : initializerNameMap.entrySet()) {
            if (PathUtils.match(entry.getKey(), ruleName)) {
                RuleTemplateInitializer initializer = entry.getValue();
                initializer.initRuleTemplate(ruleTemplate, initializerContext);
            }
        }

        String typeName = ruleTemplate.getType();
        Class<?> type = null;
        if (StringUtils.isNotEmpty(typeName)) {
            type = ClassUtils.forName(typeName);
        }
        if (type != null) {
            for (Map.Entry<Class<?>, RuleTemplateInitializer> entry : initializerTypeMap.entrySet()) {
                if (entry.getKey().isAssignableFrom(type)) {
                    RuleTemplateInitializer initializer = entry.getValue();
                    initializer.initRuleTemplate(ruleTemplate, initializerContext);
                }
            }
        }
    }

    public void ruleTemplateAdded(RuleTemplateManager ruleTemplateManager, RuleTemplate ruleTemplate)
            throws Exception {
        if (initializingRuleTemplate > 0 && ruleTemplate.isAutoInitialize()) {
            initRuleTemplate(initializerContext, ruleTemplate);
        }
    }

    public List<String> getConfigTemplateFiles() {
        return configTemplateFiles;
    }

}