Java tutorial
/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * You should have received a copy of the GNU General Public License * (for example /usr/src/linux/COPYING); if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.w20e.socrates.model; import java.util.Vector; import org.apache.commons.jxpath.ri.Compiler; import com.w20e.socrates.expression.And; import com.w20e.socrates.expression.Ceil; import com.w20e.socrates.expression.DateTime; import com.w20e.socrates.expression.Divide; import com.w20e.socrates.expression.Equals; import com.w20e.socrates.expression.Eval; import com.w20e.socrates.expression.Exp; import com.w20e.socrates.expression.Expression; import com.w20e.socrates.expression.Floor; import com.w20e.socrates.expression.Format; import com.w20e.socrates.expression.GT; import com.w20e.socrates.expression.GTE; import com.w20e.socrates.expression.Get; import com.w20e.socrates.expression.IfThenElse; import com.w20e.socrates.expression.In; import com.w20e.socrates.expression.LT; import com.w20e.socrates.expression.LTE; import com.w20e.socrates.expression.Map; import com.w20e.socrates.expression.Matches; import com.w20e.socrates.expression.Max; import com.w20e.socrates.expression.Min; import com.w20e.socrates.expression.Minus; import com.w20e.socrates.expression.Modulo; import com.w20e.socrates.expression.Multiply; import com.w20e.socrates.expression.Not; import com.w20e.socrates.expression.NotEquals; import com.w20e.socrates.expression.Num; import com.w20e.socrates.expression.Operation; import com.w20e.socrates.expression.Or; import com.w20e.socrates.expression.RandomInt; import com.w20e.socrates.expression.Round; import com.w20e.socrates.expression.Sample; import com.w20e.socrates.expression.Str; import com.w20e.socrates.expression.Substr; import com.w20e.socrates.expression.Sum; import com.w20e.socrates.expression.XBoolean; import com.w20e.socrates.expression.XNumber; import com.w20e.socrates.expression.XString; import com.w20e.socrates.expression.XVar; /** * @author dokter Implementation for JXPath compiler. */ public final class ExpressionCompiler implements Compiler { /** * Instance for compiler. */ private static ExpressionCompiler instance = null; /** * int value of parser for not function. */ private static final int NOT = 19; /** * int value of parser for true function. */ private static final int TRUE = 20; /** * int value of parser for rnd function. */ private static final int RND = 27; /** * Sum id. */ private static final int SUM = 24; /** * Floor id. */ private static final int FLOOR = 25; /** * Hide constructor. */ private ExpressionCompiler() { // Empty constructor. } /** * Get an instance of this compiler. * * @return the instance. */ public static synchronized ExpressionCompiler getInstance() { if (ExpressionCompiler.instance == null) { ExpressionCompiler.instance = new ExpressionCompiler(); } return ExpressionCompiler.instance; } /** * Implement number creation. * * @return an XNumber object * @param arg0 * numeric value */ @Override public Object number(final String arg0) { if (arg0.indexOf('.') == -1) { return new XNumber(Long.valueOf(arg0)); } return new XNumber(new Float(arg0)); } /** * Implement to literal for compiler. * * @return XString value * @param arg0 * string */ @Override public Object literal(final String arg0) { return new XString(arg0); } /** * Implement qname method. * * @param arg0 * name * @param arg1 * dunno * @return arg1 */ @Override public Object qname(final String arg0, final String arg1) { return arg1; } /** * Implement summation creation. * * @param arg0 * summation operands * @return summation operation */ @Override public Object sum(final Object[] arg0) { return sum(0, arg0); } /** * Enable multiple arguments to our two-operand summation. * * @param i * pointer in argument array * @param arg0 * operands * @return Sum expression */ private Expression sum(final int i, final Object[] arg0) { Sum op = new Sum(); Vector<Expression> args = new Vector<Expression>(); for (Object arg : arg0) { args.add((Expression) arg); } op.setOperands(args.toArray(new Expression[args.size()])); return op; } /** * Implement minus creation. * * @param arg0 * left operand * @param arg1 * right operand * @return new minus operation */ @Override public Object minus(final Object arg0, final Object arg1) { Operation op = new Minus(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Implement multiplication creation. * * @param arg0 * left operand * @param arg1 * right operand * @return multiply operation */ @Override public Object multiply(final Object arg0, final Object arg1) { Operation op = new Multiply(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Implement divide creation. * * @param arg0 * left operand * @param arg1 * right operand * @return division operation */ @Override public Object divide(final Object arg0, final Object arg1) { Operation op = new Divide(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new Module operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new module operation */ @Override public Object mod(final Object arg0, final Object arg1) { Operation op = new Modulo(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new LT operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new LT operation */ @Override public Object lessThan(final Object arg0, final Object arg1) { Operation op = new LT(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new LTE operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new LTE operation */ @Override public Object lessThanOrEqual(final Object arg0, final Object arg1) { Operation op = new LTE(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new GT operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new GT operation */ @Override public Object greaterThan(final Object arg0, final Object arg1) { Operation op = new GT(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new GTE operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new GTE operation */ @Override public Object greaterThanOrEqual(final Object arg0, final Object arg1) { Operation op = new GTE(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new Equals operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new Equals operation */ @Override public Object equal(final Object arg0, final Object arg1) { Operation op = new Equals(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create noteqals operation. * * @param arg0 * left operand * @param arg1 * right operand * @return new notequals operation */ @Override public Object notEqual(final Object arg0, final Object arg1) { Operation op = new NotEquals(); op.setLeftOperand((Expression) arg0); op.setRightOperand((Expression) arg1); return op; } /** * Create new Minus operation. * * @param arg0 * left operand for minus. * @return new Unary minus */ @Override public Object minus(final Object arg0) { Operation op = new Minus(); op.setLeftOperand(new XNumber(Integer.valueOf(0))); op.setRightOperand((Expression) arg0); return op; } /** * Unimplemented operation. * * @param arg0 * dunno * @return null */ @Override public Object variableReference(final Object arg0) { return null; } /** * Only implemented to return true/false functions. * * @param arg0 * numeric argument specifying function * @param arg1 * dunno * @return new XBoolean */ @Override public Object function(final int arg0, final Object[] arg1) { //System.out.print(arg0); if (arg0 == ExpressionCompiler.TRUE) { return new XBoolean(true); } else if (arg0 == ExpressionCompiler.RND) { Round rnd = new Round(); Vector<Expression> v = new Vector<Expression>(); if (arg1 != null) { for (Object arg : arg1) { v.add((Expression) arg); } } rnd.setOperands(v.toArray(new Expression[v.size()])); return rnd; } else if (arg0 == ExpressionCompiler.FLOOR) { Floor floor = new Floor(); floor.setLeftOperand((Expression) arg1[0]); return floor; } else if (arg0 == ExpressionCompiler.NOT) { Not not = new Not(); not.setLeftOperand((Expression) arg1[0]); return not; } else if (arg0 == ExpressionCompiler.SUM) { return this.sum(0, arg1); } else if (arg0 == Compiler.FUNCTION_STRING) { // only with mandatory parameter is implemented! return new XVar(arg1[0].toString()); // throws exception if args1 // == null } else { return new XBoolean(false); } } /** * Create the named function. * * @param arg0 * function name * @param arg1 * arguments * @return the function or false if unknown. */ @Override public Object function(final Object arg0, final Object[] arg1) { //System.out.println("2 " + arg0); //System.out.println(arg1); if (arg0.toString().equals("exp")) { Exp exp = new Exp(); exp.setLeftOperand((Expression) arg1[0]); return exp; } else if (arg0.toString().equals("max")) { Max exp = new Max(); exp.setLeftOperand((Expression) arg1[0]); exp.setRightOperand((Expression) arg1[1]); return exp; } else if (arg0.toString().equals("min")) { Min exp = new Min(); exp.setLeftOperand((Expression) arg1[0]); exp.setRightOperand((Expression) arg1[1]); return exp; } else if (arg0.toString().equals("eval")) { return new Eval(arg1[0].toString()); } else if (arg0.toString().equals("matches")) { Matches exp = new Matches(); exp.setLeftOperand((Expression) arg1[0]); exp.setRightOperand((Expression) arg1[1]); return exp; } else if (arg0.toString().equals("datetime")) { DateTime datetime = new DateTime(); Vector<Expression> v = new Vector<Expression>(); if (arg1 != null) { for (Object arg : arg1) { v.add((Expression) arg); } } datetime.setOperands(v.toArray(new Expression[v.size()])); return datetime; } else if (arg0.toString().equals("test") || arg0.toString().equals("if")) { IfThenElse exp = new IfThenElse(); exp.setLeftOperand((Expression) arg1[0]); exp.setMiddleOperand((Expression) arg1[1]); exp.setRightOperand((Expression) arg1[2]); return exp; } else if (arg0.toString().equals("map")) { Map map = new Map(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } map.setOperands(v.toArray(new Expression[v.size()])); return map; } else if (arg0.toString().equals("str")) { Str str = new Str(); str.setLeftOperand((Expression) arg1[0]); return str; } else if (arg0.toString().equals("num")) { Num num = new Num(); num.setLeftOperand((Expression) arg1[0]); return num; } else if (arg0.toString().equals("ceil")) { Ceil ceil = new Ceil(); ceil.setLeftOperand((Expression) arg1[0]); return ceil; } else if (arg0.toString().equals("format")) { Format fmt = new Format(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } fmt.setOperands(v.toArray(new Expression[v.size()])); return fmt; } else if (arg0.toString().equals("substr")) { Substr sstr = new Substr(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } sstr.setOperands(v.toArray(new Expression[v.size()])); return sstr; } else if (arg0.toString().equals("random")) { RandomInt r = new RandomInt(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } r.setOperands(v.toArray(new Expression[v.size()])); return r; } else if (arg0.toString().equals("sample")) { Sample s = new Sample(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } s.setOperands(v.toArray(new Expression[v.size()])); return s; } else if (arg0.toString().equals("in")) { In in = new In(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } in.setOperands(v.toArray(new Expression[v.size()])); return in; } else if (arg0.toString().equals("get")) { Get get = new Get(); Vector<Expression> v = new Vector<Expression>(); for (Object arg : arg1) { v.add((Expression) arg); } get.setOperands(v.toArray(new Expression[v.size()])); return get; } return new XBoolean(false); } /** * Create new and object. * * @param arg0 * left and right operands. * @return new and object. */ @Override public Object and(final Object[] arg0) { return and(0, arg0); } /** * Enable multiple arguments to our two-operand summation. * * @param i * pointer in argument array * @param arg0 * operands * @return Sum expression */ private Expression and(final int i, final Object[] arg0) { Operation op = new And(); if (arg0.length <= i) { return op; } op.setLeftOperand((Expression) arg0[i]); if (arg0.length == i + 1) { return op; } else if (arg0.length == i + 2) { op.setRightOperand((Expression) arg0[i + 1]); } else { op.setRightOperand(and(i + 1, arg0)); } return op; } /** * Create new or object. * * @param arg0 * left and right operands. * @return new or object. */ @Override public Object or(final Object[] arg0) { return or(0, arg0); } /** * Enable multiple arguments to our two-operand summation. * * @param i * pointer in argument array * @param arg0 * operands * @return Sum expression */ private Expression or(final int i, final Object[] arg0) { Operation op = new Or(); if (arg0.length <= i) { return op; } op.setLeftOperand((Expression) arg0[i]); if (arg0.length == i + 1) { return op; } else if (arg0.length == i + 2) { op.setRightOperand((Expression) arg0[i + 1]); } else { op.setRightOperand(or(i + 1, arg0)); } return op; } /** * Create new union object. * * @param arg0 * left and right operands. * @return new union object. */ @Override public Object union(final Object[] arg0) { return or(arg0); } /** * Create new node name test. Unimplemented! * * @param arg0 * dunno * @return atg0. */ @Override public Object nodeNameTest(final Object arg0) { return arg0; } /** * Create new nodetype test. Unimplemented! * * @param arg0 * dunno * @return null. */ @Override public Object nodeTypeTest(final int arg0) { return null; } /** * Create new processing instruction test. Unimplemented! * * @param arg0 * dunno * @return null */ @Override public Object processingInstructionTest(final String arg0) { return null; } /** * Create new step. Unimplemented! * * @param arg0 * dunno * @param arg1 * dunno * @param arg2 * dunno * @return step object */ @Override public Object step(final int arg0, final Object arg1, final Object[] arg2) { // System.out.println("Step " + arg1 + ", " + arg2.length); return arg1; } /** * Create a location path. Creates an XRef object. * * @param arg0 * starts at root? * @param arg1 * elements of the path * @return a new XRef object */ @Override public Object locationPath(final boolean arg0, final Object[] arg1) { String res = ""; for (int i = 0; i < arg1.length; i++) { res = res + "/" + arg1[i]; } return new XVar(res); } /** * Create a new expression path. For now unimplemented. * * @param arg0 * dunno * @param arg1 * dunno * @param arg2 * dunno * @return expressionpath object. */ @Override public Object expressionPath(final Object arg0, final Object[] arg1, final Object[] arg2) { // System.out.println("exp: " + arg0); return arg0; } }