001    package com.hammurapi.review.util;
002    
003    import java.lang.annotation.Annotation;
004    import java.lang.reflect.Method;
005    import java.util.LinkedList;
006    
007    import org.eclipse.emf.ecore.util.EcoreUtil;
008    
009    import com.hammurapi.config.bootstrap.ConfigurationException;
010    import com.hammurapi.config.runtime.FactoryConfig;
011    import com.hammurapi.config.util.ConfigUtil;
012    import com.hammurapi.flow.Flow;
013    import com.hammurapi.flow.Node;
014    import com.hammurapi.reasoning.impl.RuleSetToFlowCompiler;
015    import com.hammurapi.reasoning.spi.Infer;
016    import com.hammurapi.reasoning.spi.model.ModelFactory;
017    import com.hammurapi.reasoning.spi.model.Rule;
018    import com.hammurapi.reasoning.spi.model.RuleSet;
019    import com.hammurapi.review.Inspect;
020    import com.hammurapi.review.Inspector;
021    import com.hammurapi.review.InspectorCategory;
022    import com.hammurapi.review.InspectorSet;
023    
024    /**
025     * This class compiles inspector set definition to a flow definition to be used by
026     * Hammurapi Rules engine for inferring observations from model elements.
027     * @author Pavel Vlasov
028     *
029     */
030    public class InspectorSetCompiler  extends RuleSetToFlowCompiler {
031            
032            /**
033             * Compiles inspector set to flow.
034             * @param source
035             * @param contextClassLoader
036             * @param contextUrl
037             * @param tokens
038             * @param profilePath
039             * @return
040             * @throws ConfigurationException
041             */
042            public Flow compile(InspectorSet source, FactoryConfig factoryConfig) throws ConfigurationException {
043                    return compile(compile(source), factoryConfig);
044            }
045            
046            private RuleSet compile(InspectorSet source) throws ConfigurationException {
047                    RuleSet ret = ModelFactory.eINSTANCE.createRuleSet();
048                    InspectorSet inspectorSet = (InspectorSet) EcoreUtil.copy(source);
049                    
050                    // Bases
051                    for (InspectorSet base: inspectorSet.getBase()) {
052                            ret.getBase().add(compile(base));
053                    }
054                    
055                    ConfigUtil.pump(inspectorSet, ret);
056    
057                    // Inspectors
058                    for (Inspector inspector: inspectorSet.getInspectors()) {
059                            if (inspector.isEnabled() && inspector.isRuntime()) {
060                                    Rule rule = ModelFactory.eINSTANCE.createRule();
061                                    ret.getRule().add(rule);
062                                    ConfigUtil.pump(inspector, rule);
063                                    ConfigUtil.addScalarProperty(rule, "severity", inspector.getSeverity(), false);
064                                    LinkedList<String> cl = new LinkedList<String>();
065                                    for (InspectorCategory c = inspector.getCategory(); c!=null; c = c.getParentCategory()) {
066                                            cl.addFirst(c.getName());
067                                    }
068                                    for (String cn: cl) {
069                                            ConfigUtil.addScalarProperty(rule, "category", cn, false);
070                                    }
071                            }
072                    }
073                    
074                    return ret;
075            }
076            
077            @Override
078            protected Node createInferenceMethodNode(
079                            RuleSet ruleSet, 
080                            Rule rule,
081                            Method method, Flow owner) {
082                    Node ret = createNode(owner, InspectorMethodNode.class);
083                    ConfigUtil.addScalarProperty(ret, "inspectorName", rule.getName(), true);
084                    return ret;
085            }
086            
087            @Override
088            protected Infer getInferAnnotation(Method method) {
089                    final Inspect inspect = method.getAnnotation(Inspect.class);
090                    if (inspect==null) {
091                            return null;
092                    }
093                    
094                    return new Infer() {
095    
096                            @Override
097                            public int priority() {
098                                    return 0;
099                            }
100    
101                            @Override
102                            public Class<?>[] value() {
103                                    return inspect.value();
104                            }
105    
106                            @Override
107                            public Class<? extends Annotation> annotationType() {
108                                    return Infer.class;
109                            }
110                            
111                    };
112            }
113    
114    }