package hep.aida.ref.plotter.style.registry;

import gnu.jel.CompiledExpression;
import gnu.jel.DVMap;
import gnu.jel.Evaluator;
import gnu.jel.Library;
import hep.aida.ICloud1D;
import hep.aida.ICloud2D;
import hep.aida.ICloud3D;
import hep.aida.IDataPointSet;
import hep.aida.IFunction;
import hep.aida.IHistogram1D;
import hep.aida.IHistogram2D;
import hep.aida.IHistogram3D;
import hep.aida.IManagedObject;
import hep.aida.IProfile1D;
import hep.aida.IProfile2D;
import hep.aida.ITupleColumn;

import java.util.Vector;


public class JELRuleCompiledExpression {
    private String  expression;
    private String  parsedExpression;
    private CompiledExpression compExpression;
    private Library lib;
    private ValueProvider pro;
    private Object[] context;
    private Resolver res;
    private Vector attributes;
    
    public JELRuleCompiledExpression(String expression) {
        this.expression = expression;
        attributes = new Vector();
        
        // Create a compiled expression
        parse();
        compile();
    }
    
    private int getAttributeIndex(String key) {
        return pro.getAttributeIndex(key);
    }
    
    public void parse() {
        parsedExpression = expression;

        //System.out.println("parse :: parsedExpression="+parsedExpression);
    }
    
    private void compile() {
        Class[] staticLib  = new Class[1];
        
        Class[] dynamicLib = new Class[1];
        context = new Object[1];
        Class[] dotLib     =  { Object.class, String.class, Class.class, java.util.Date.class };
        try {
            staticLib[0]  = java.lang.Class.forName("java.lang.Math");
            
            pro = new ValueProvider();
            dynamicLib[0] = pro.getClass();
            context[0] = pro;
            
            res = new Resolver();
            
        } catch(ClassNotFoundException e) {
            throw new RuntimeException("Can not find class for JEL!", e);
        }
        
        try {
            lib = new Library(staticLib, dynamicLib, dotLib, res, null);
            lib.markStateDependent("random", null);
        } catch (gnu.jel.CompilationException ec1) {
            throw new RuntimeException("Can not compile JEL Library!", ec1);
        }
        
        try {
            compExpression = Evaluator.compile(parsedExpression, lib, Boolean.TYPE);
        } catch (gnu.jel.CompilationException ec2) {
            throw new RuntimeException("Can not compile JEL Expression: "+expression, ec2);
        }
    }
    
    public boolean evaluate(IPlotterState state) {
        boolean ruleApplies = false;
        pro.setState(state);
        try {
            ruleApplies =  compExpression.evaluate_boolean(context);
        } catch (Throwable t) {
            throw new RuntimeException("Runtime JEL Evaluation Problems!", t);
        }
        
        return ruleApplies;
    }
    
    
    public class Resolver extends DVMap {
        
        public Resolver() {}
        public String getTypeName(String name) {
            //System.out.println("Resolver.getTypeName :: name = "+name);
            
            if (name.trim().equalsIgnoreCase(IStyleRule.PATH)) return "String";
            else if (name.trim().equalsIgnoreCase(IStyleRule.OBJECT)) return "Object";
            else if (name.trim().equalsIgnoreCase(IStyleRule.OBJECT_TYPE)) return "String";
            else if (name.trim().equalsIgnoreCase(IStyleRule.NULL)) return "Object";
            //else if (name.trim().equalsIgnoreCase(IStyleRule.ATTRIBUTE)) return "String";
            else if (name.trim().equalsIgnoreCase(IStyleRule.OVERLAY_INDEX)) return "Integer";
            else if (name.trim().equalsIgnoreCase(IStyleRule.OVERLAY_TOTAL)) return "Integer";
            else if (name.trim().equalsIgnoreCase(IStyleRule.REGION_INDEX)) return "Integer";
            else if (name.trim().equalsIgnoreCase(IStyleRule.REGION_TOTAL)) return "Integer";
            else return null;
        }
        
        public Object translate(String name) {
            //System.out.println("Resolver.translate :: name = "+name);
            if (name.trim().equalsIgnoreCase(IStyleRule.PATH)) return new Integer(-1);
            else if (name.trim().equalsIgnoreCase(IStyleRule.OBJECT)) return new Integer(1);
            else if (name.trim().equalsIgnoreCase(IStyleRule.OBJECT_TYPE)) return new Integer(-2);
            else if (name.trim().equalsIgnoreCase(IStyleRule.NULL)) return new Integer(-10);
            //else if (name.trim().equalsIgnoreCase(IStyleRule.ATTRIBUTE)) return new Integer(10);
            else if (name.trim().equalsIgnoreCase(IStyleRule.OVERLAY_INDEX)) return new Integer(0);
            else if (name.trim().equalsIgnoreCase(IStyleRule.OVERLAY_TOTAL)) return new Integer(1);
            else if (name.trim().equalsIgnoreCase(IStyleRule.REGION_INDEX)) return new Integer(2);
            else if (name.trim().equalsIgnoreCase(IStyleRule.REGION_TOTAL)) return new Integer(3);
            return new Integer(100);
        }
    }
    
    public class ValueProvider {
        private IPlotterState state;
        
        public ValueProvider() {
            this(null);
        }
        public ValueProvider(IPlotterState state) {
            this.state = state;
        }
        
        int getAttributeIndex(String key) {
            return (state == null) ? 0 : ((PlotterState) state).getAttributeIndex(key);
        }
        
        public void setState(IPlotterState state) {
            this.state = state;
        }
        
        public String getStringProperty(int index) {
            String value = null;
            if (index == -10) value = null;
            else if (index == -2) value = objectAIDAType();
            else if (index == -1) value = state.getObjectPath();
            else if (index >= 0) value = state.getAttribute((String) attributes.get(index));
            //System.out.println("ValueProvider.getStringProperty :: index="+index+", value="+value);
            return value;
        }
        public Object getObjectProperty(int index) {
            Object value = null;
            if (index == 0) value = null;
            else if (index == 1) value = state.getObject();
            //System.out.println("ValueProvider.getObjectProperty :: index="+index+", value="+value);
            return value;
        }
	public int getIntegerProperty(int index) { 
            int value = -1;
            if (index == 0) return state.getOverlayIndex();
            else if (index == 1) value = state.getOverlayTotal();
            else if (index == 2) value = state.getRegionIndex();
            else if (index == 3) value = state.getRegionTotal();
            //System.out.println("ValueProvider.getIntegerProperty :: index="+index+", value="+value);
            return value;
        }
        
        public String attribute(String key) { 
            String value = state.getAttribute(key);
            if (value == null) value = "";
            return value;
        }
        
        public String objectAIDAType() { 
            Object obj = state.getObject();
            String value = null;
            if (obj == null) value = "null";
            else if (obj instanceof IDataPointSet)  value = "IDataPointSet";
            else if (obj instanceof IHistogram1D)  value = "IHistogram1D";
            else if (obj instanceof IHistogram2D)  value = "IHistogram2D";
            else if (obj instanceof IHistogram3D)  value = "IHistogram3D";
            else if (obj instanceof ICloud1D)  value = "ICloud1D";
            else if (obj instanceof ICloud2D)  value = "ICloud2D";
            else if (obj instanceof ICloud3D)  value = "ICloud3D";
            else if (obj instanceof IProfile1D)  value = "IProfile1D";
            else if (obj instanceof IProfile2D)  value = "IProfile2D";
            else if (obj instanceof IFunction)  value = "IFunction";
            else if (obj instanceof ITupleColumn)  value = "ITupleColumn";
            else if (obj instanceof IManagedObject) value = ((IManagedObject) obj).type();
            else value = obj.getClass().getName();
            return value;
        }
        
        public boolean isObjectInstanceOf(String className) {
            boolean ok = false;
            try {
                Class cl = Class.forName(className);
                //ok = (state.getObject() instanceof cl);
            } catch (Exception e) { e.printStackTrace(); }
            
            return ok;
        }
    }
    
    
    public static void main(String[] args) throws Exception {
        //String expr = "(OBJECT.getClass().toString().equals(\"JELRule.class\")) && PATH.equalsIgnoreCase(\"MC\")";
        String expr = "overlayCount == 3";
        JELRuleCompiledExpression ce = new JELRuleCompiledExpression(expr);
        
        PlotterState state = new PlotterState();
        state.setObjectPath("mc");
        state.setAttribute("printing", "true");
        state.setAttribute("experiment", "BaBar");
        state.setOverlayIndex(3);
        state.setObject(new JELRule());
        
        boolean ok = ce.evaluate(state);
        System.out.println("ok="+ok);
        
    }
}

 

Ads help maintain this website.