package gve.calc.formula;

import java.lang.reflect.*;
import gve.calc.logic.*;	// OperatorModel

The classes InfixBinaryOp, PrefixUnaryOp and PostfixUnaryOp maintain a list of (String,Factory) pairs, linking an operator name (e.g. "*") to a Factory (that contains a method returning for example OperatorMult objects).
public class StandardOperators { private StandardOperators() {} public static void registerStandardOps() { // pri 15000 registerInBin(OperatorDot.class); // pri 10000 registerInBin(OperatorSpace.class); // pri 2000 registerInBin(OperatorPow.class); // 1900 registerInBin(OperatorMult.class); registerInBin(Fraction.class); // 1800 registerInBin(OperatorPlus.class); registerInBin(OperatorMinus.class); // pri 1700 register("<",new OperatorCompareFactory()); register(">",new OperatorCompareFactory()); register("<=",new OperatorCompareFactory()); register(">=",new OperatorCompareFactory()); // pri 1600 register("=",new OperatorEqualityFactory()); register("!=",new OperatorEqualityFactory()); // pri 1500 register("union",new OperatorUnionFactory()); // pri 1400 register("in",new OperatorSetFactory()); register("subseteq",new OperatorSetFactory()); // pri 1300 registerpre("not",new OperatorNotFactory()); // pri 1200 register("&",new OperatorBooleanFactory()); // pri 1100 register("xor",new OperatorBooleanFactory()); // pri 1000 register("or",new OperatorBooleanFactory()); // pri 900 register("=>",new OperatorBooleanFactory()); register("<=>",new OperatorBooleanFactory()); // pri 800 register(":",new OperatorColonFactory()); // 810 registerpre("exists",new OperatorQuantorFactory()); registerpre("forall",new OperatorQuantorFactory()); // pri 600 register("union=",new OperatorAssignFactory()); register(":=",new OperatorAssignFactory()); register("+=",new OperatorAssignFactory()); // pri 500 register(",",new OperatorCommaFactory()); // pri 400 register("|-",new OperatorModelFactory()); register("|=",new OperatorModelFactory()); register("|>",new OperatorModelFactory()); // pri 300 registerpost(";",new OperatorSemicolonFactory()); } public static void registerInBin(Class clazz) { StandardInfixBinaryFactory factory = new StandardInfixBinaryFactory(clazz); register(factory.getName(),factory); } public static void register(String name,InfixBinaryOpFactory factory) { InfixBinaryOp.registerFactory(name,factory); } public static void registerpre(String name,UnaryOpFactory factory) { PrefixUnaryOp.registerFactory(name,factory); } public static void registerpost(String name,UnaryOpFactory factory) { PostfixUnaryOp.registerFactory(name,factory); } }
This Factory is more or less equivalent to manually creating classes like class OperatorMultFactory extends InfixBinaryOpFactory { public InfixBinaryOp createInfixBinaryOp(String name,Part l,Part r) { return new OperatorMult(l,r); } } except for the extra getName() method. We actually don't need the 'name' argument of createInfixBinaryOp() at all.
class StandardInfixBinaryFactory extends InfixBinaryOpFactory { private Constructor c; public StandardInfixBinaryFactory(Class clazz) { try { Class [] paramtypes = new Class[2]; paramtypes[0] = paramtypes[1] = Part.class; //System.out.println("paramtypes "+paramtypes[0]); c = clazz.getConstructor(paramtypes); //System.out.println("c "+c); } catch (Exception exc) { exc.printStackTrace(); } } public String getName() { try { // Create an instance to find out what the name of the operator is Object [] args = new Object[2]; args[0] = new Identifier(""); args[1] = new Identifier(""); //System.out.println("getname.c "+c); InfixBinaryOp op = (InfixBinaryOp)c.newInstance(args); return op.getName(); } catch (Exception exc) { exc.printStackTrace(); } return null; } public InfixBinaryOp createInfixBinaryOp(String name,Part l,Part r) { // "return new OperatorXxxx(l,r); Object [] args = new Object[2]; args[0] = l; args[1] = r; try { return (InfixBinaryOp)c.newInstance(args); } catch (Exception exc) { exc.printStackTrace(); } return null; } }