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

Java tutorial

Introduction

Here is the source code for com.bstek.dorado.idesupport.RuleSetBuilder.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.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.PropertyUtils;
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.io.InputStreamResource;
import com.bstek.dorado.core.pkgs.PackageInfo;
import com.bstek.dorado.core.xml.XmlDocumentBuilder;
import com.bstek.dorado.idesupport.model.Child;
import com.bstek.dorado.idesupport.model.ClientEvent;
import com.bstek.dorado.idesupport.model.CompositeType;
import com.bstek.dorado.idesupport.model.Property;
import com.bstek.dorado.idesupport.model.Reference;
import com.bstek.dorado.idesupport.model.Rule;
import com.bstek.dorado.idesupport.model.RuleSet;
import com.bstek.dorado.idesupport.parse.ConfigRuleParseContext;
import com.bstek.dorado.idesupport.template.ChildTemplate;
import com.bstek.dorado.idesupport.template.PropertyTemplate;
import com.bstek.dorado.idesupport.template.ReferenceTemplate;
import com.bstek.dorado.idesupport.template.RuleTemplate;

/**
 * @author Benny Bao (mailto:benny.bao@bstek.com)
 * @since 2009-11-22
 */
public class RuleSetBuilder {
    private XmlDocumentBuilder xmlDocumentBuilder;
    private XmlParser preloadParser;
    private XmlParser ruleTemplateParser;

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

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

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

    public RuleSet buildRuleSet(InputStream in) throws Exception {
        Document document = xmlDocumentBuilder.loadDocument(new InputStreamResource(in));

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

        Element documentElement = document.getDocumentElement();
        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);
        }

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

        return buildRuleSet(ruleTemplateManager);
    }

    public RuleSet buildRuleSet(RuleTemplateManager ruleTemplateManager) throws Exception {
        RuleSet ruleSet = new RuleSet();
        ruleSet.setVersion(ruleTemplateManager.getVersion());

        List<PackageInfo> packageInfos = ruleTemplateManager.getPackageInfos();
        if (packageInfos != null) {
            ruleSet.getPackageInfos().addAll(packageInfos);
        }

        for (RuleTemplate ruleTemplate : ruleTemplateManager.getRuleTemplates()) {
            if (ruleSet.getRule(ruleTemplate.getName()) == null) {
                exportRule(ruleTemplate, ruleSet);
            }
        }
        return ruleSet;
    }

    protected Rule exportRule(RuleTemplate ruleTemplate, RuleSet ruleSet) throws Exception {
        Rule rule;
        String name = ruleTemplate.getName();
        if (StringUtils.isNotEmpty(name)) {
            rule = ruleSet.getRule(name);
            if (rule != null)
                return rule;
        }

        rule = new Rule(name);
        if (ruleTemplate.isGlobal()) {
            ruleSet.addRule(rule);
        }

        RuleTemplate[] parentTemplates = ruleTemplate.getParents();
        if (parentTemplates != null && parentTemplates.length > 0) {
            Rule[] parents = new Rule[parentTemplates.length];
            for (int i = 0; i < parentTemplates.length; i++) {
                RuleTemplate parentTemplate = parentTemplates[i];
                parents[i] = exportRule(parentTemplate, ruleSet);
            }
            rule.setParents(parents);
        }
        ruleTemplate.processInheritance();

        applyTemplateToRule(ruleTemplate, rule, ruleSet);
        return rule;
    }

    protected void applyTemplateToRule(RuleTemplate ruleTemplate, Rule rule, RuleSet ruleSet) throws Exception {
        applyProperties(ruleTemplate, rule,
                "label,abstract,nodeName,type,category,robots,icon,labelProperty,autoGenerateId,clientTypes,reserve,deprecated,visible");

        if (StringUtils.isEmpty(rule.getNodeName())) {
            if (StringUtils.isNotEmpty(rule.getType())) {
                String type = rule.getType();
                rule.setNodeName(StringUtils.substringAfterLast(type, "."));
            } else {
                rule.setNodeName(rule.getName());
            }
        }

        if (StringUtils.isEmpty(rule.getLabel())) {
            rule.setLabel(rule.getNodeName());
        }

        if (ruleTemplate.getSortFactor() > 0) {
            rule.setSortFactor(ruleTemplate.getSortFactor());
        }

        Map<String, PropertyTemplate> primitiveProperties = ruleTemplate.getFinalPrimitiveProperties();
        if (!primitiveProperties.isEmpty()) {
            for (PropertyTemplate propertyTemplate : primitiveProperties.values()) {
                Property property = new Property();
                applyTemplateToProperty(propertyTemplate, property, ruleSet);
                rule.addPrimitiveProperty(property);
            }
        }

        Map<String, PropertyTemplate> properties = ruleTemplate.getFinalProperties();
        if (!properties.isEmpty()) {
            for (PropertyTemplate propertyTemplate : properties.values()) {
                Property property = new Property();
                applyTemplateToProperty(propertyTemplate, property, ruleSet);
                rule.addProperty(property);
            }
        }

        Map<String, ClientEvent> clientEvents = ruleTemplate.getFinalClientEvents();
        if (!clientEvents.isEmpty()) {
            rule.addClientEvents(clientEvents.values());
        }

        Collection<ChildTemplate> children = ruleTemplate.getFinalChildren().values();
        if (!children.isEmpty()) {
            for (ChildTemplate childTemplate : children) {
                addChildrenByChildTemplate(rule, childTemplate, ruleSet);
            }
        }
    }

    protected void applyTemplateToProperty(PropertyTemplate propertyTemplate, Property property, RuleSet ruleSet)
            throws Exception {
        applyProperties(propertyTemplate, property,
                "name,type,defaultValue,fixed,enumValues,editor,highlight,visible,compositeType,clientTypes,reserve,deprecated");

        ReferenceTemplate referenceTemplate = propertyTemplate.getReference();
        if (referenceTemplate != null) {
            Rule rule = exportRule(referenceTemplate.getRuleTemplate(), ruleSet);
            property.setReference(new Reference(rule, referenceTemplate.getProperty()));
        }

        if (property.getCompositeType() == CompositeType.Fixed
                || property.getCompositeType() == CompositeType.Open) {
            Map<String, PropertyTemplate> properties = propertyTemplate.getProperties();
            for (Map.Entry<String, PropertyTemplate> entry : properties.entrySet()) {
                PropertyTemplate subPopertyTemplate = entry.getValue();
                if (!subPopertyTemplate.isVisible()) {
                    continue;
                }

                Property subPoperty = new Property();
                applyTemplateToProperty(subPopertyTemplate, subPoperty, ruleSet);
                property.addProperty(subPoperty);
            }
        }
    }

    private void findConcreteRules(RuleTemplate ruleTemplate, Set<Rule> concreteRules, RuleSet ruleSet,
            boolean validateScope) throws Exception {
        RuleTemplate[] subRuleTemplates = ruleTemplate.getSubRuleTemplates();
        if (subRuleTemplates != null && subRuleTemplates.length > 0) {
            for (RuleTemplate subRuleTemplate : subRuleTemplates) {
                String scope = subRuleTemplate.getScope();
                if (validateScope && "private".equals(scope)) {
                    continue;
                }

                if (!subRuleTemplate.isAbstract()
                        && (!validateScope || StringUtils.isEmpty(scope) || "public".equals(scope))) {
                    concreteRules.add(exportRule(subRuleTemplate, ruleSet));
                }

                findConcreteRules(subRuleTemplate, concreteRules, ruleSet, validateScope);
            }
        }
    }

    protected void addChildrenByChildTemplate(Rule rule, ChildTemplate childTemplate, RuleSet ruleSet)
            throws Exception {
        RuleTemplate childRuleTemplate = childTemplate.getRuleTemplate();
        // if (!childTemplate.isVisible() || !childRuleTemplate.isVisible()) {
        // return;
        // }

        Child child = new Child(childTemplate.getName());
        applyTemplateToChild(childTemplate, child, ruleSet);
        rule.addChild(child);

        Set<Rule> concreteRules = child.getConcreteRules();
        if (!childRuleTemplate.isAbstract()) {
            concreteRules.add(exportRule(childRuleTemplate, ruleSet));
        }
        findConcreteRules(childRuleTemplate, concreteRules, ruleSet, true);
    }

    protected void applyTemplateToChild(ChildTemplate childTemplate, Child child, RuleSet ruleSet)
            throws Exception {
        Rule rule = exportRule(childTemplate.getRuleTemplate(), ruleSet);
        child.setRule(rule);
        applyProperties(childTemplate, child, "fixed,aggregated,clientTypes,deprecated,reserve");
        if (childTemplate.isDeprecated()) {
            child.setDeprecated(true);
        }
    }

    private void applyProperties(Object source, Object target, String propertyNames) throws Exception {
        if (StringUtils.isNotEmpty(propertyNames)) {
            for (String propertyName : StringUtils.split(propertyNames, ',')) {
                applyProperty(source, target, propertyName);
            }
        }
    }

    private void applyProperty(Object source, Object target, String propertyName) throws Exception {
        Object value = PropertyUtils.getProperty(source, propertyName);
        if (value != null) {
            PropertyUtils.setProperty(target, propertyName, value);
        }
    }

}