/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo 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 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.antar.expr; import org.openflexo.antar.expr.Constant.ArithmeticConstant; import org.openflexo.antar.expr.Constant.BooleanConstant; import org.openflexo.antar.expr.Constant.DateConstant; import org.openflexo.antar.expr.Constant.DurationConstant; import org.openflexo.antar.expr.Constant.EnumConstant; import org.openflexo.antar.expr.Constant.ObjectSymbolicConstant; import org.openflexo.antar.expr.Constant.StringConstant; public abstract class BooleanBinaryOperator extends BinaryOperator { public static final BooleanBinaryOperator AND = new LogicalBinaryOperator() { @Override public int getPriority() { return 6; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { if (leftArg instanceof BooleanConstant && rightArg instanceof BooleanConstant) { return BooleanConstant.get(((BooleanConstant) leftArg).getValue() && ((BooleanConstant) rightArg).getValue()); } throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.BOOLEAN); } @Override public String getName() { return "logical_and"; } @Override public Expression evaluate(Expression leftArg, Constant rightArg) throws TypeMismatchException { if (rightArg == BooleanConstant.FALSE) { return BooleanConstant.FALSE; } if (rightArg == BooleanConstant.TRUE) { return leftArg; } return super.evaluate(leftArg, rightArg); } @Override public Expression evaluate(Constant leftArg, Expression rightArg) throws TypeMismatchException { if (leftArg == BooleanConstant.FALSE) { return BooleanConstant.FALSE; } if (leftArg == BooleanConstant.TRUE) { return rightArg; } return super.evaluate(leftArg, rightArg); } }; public static final BooleanBinaryOperator OR = new LogicalBinaryOperator() { @Override public int getPriority() { return 7; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { if (leftArg instanceof BooleanConstant && rightArg instanceof BooleanConstant) { return BooleanConstant.get(((BooleanConstant) leftArg).getValue() || ((BooleanConstant) rightArg).getValue()); } throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.BOOLEAN); } @Override public String getName() { return "logical_or"; } @Override public Expression evaluate(Expression leftArg, Constant rightArg) throws TypeMismatchException { if (rightArg == BooleanConstant.FALSE) { return leftArg; } if (rightArg == BooleanConstant.TRUE) { return BooleanConstant.TRUE; } return super.evaluate(leftArg, rightArg); } @Override public Expression evaluate(Constant leftArg, Expression rightArg) throws TypeMismatchException { if (leftArg == BooleanConstant.FALSE) { return rightArg; } if (leftArg == BooleanConstant.TRUE) { return BooleanConstant.TRUE; } return super.evaluate(leftArg, rightArg); } }; public static final BooleanBinaryOperator EQUALS = new ComparisonBinaryOperator() { @Override public int getPriority() { return 5; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { // System.out.println("leftArg="+leftArg+" of "+leftArg.getEvaluationType()); // System.out.println("rightArg="+rightArg+" of "+rightArg.getEvaluationType()); if (leftArg instanceof BooleanConstant && rightArg instanceof BooleanConstant) { return ((BooleanConstant) leftArg).getValue() == ((BooleanConstant) rightArg).getValue() ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof ArithmeticConstant && rightArg instanceof ArithmeticConstant) { return ((ArithmeticConstant) leftArg).getArithmeticValue() == ((ArithmeticConstant) rightArg).getArithmeticValue() ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DateConstant && rightArg instanceof DateConstant) { return ((DateConstant) leftArg).getDate().equals(((DateConstant) rightArg).getDate()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DurationConstant && rightArg instanceof DurationConstant) { return ((DurationConstant) leftArg).getDuration().equals(((DurationConstant) rightArg).getDuration()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof StringConstant && rightArg instanceof StringConstant) { return ((StringConstant) leftArg).getValue().equals(((StringConstant) rightArg).getValue()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof EnumConstant && rightArg instanceof EnumConstant) { return ((EnumConstant) leftArg).getName().equals(((EnumConstant) rightArg).getName()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof EnumConstant && rightArg instanceof StringConstant) { return ((EnumConstant) leftArg).getName().equals(((StringConstant) rightArg).getValue()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } // System.out.println("leftArg="+leftArg+" of "+leftArg.getEvaluationType()); // System.out.println("rightArg="+rightArg+" of "+rightArg.getEvaluationType()); if (rightArg == ObjectSymbolicConstant.NULL) { if (leftArg == ObjectSymbolicConstant.NULL) { return Constant.BooleanConstant.TRUE; } if (leftArg instanceof StringConstant && ((StringConstant) leftArg).getValue().equals("null")) { return Constant.BooleanConstant.TRUE; } return Constant.BooleanConstant.FALSE; } if (leftArg == ObjectSymbolicConstant.NULL) { if (rightArg == ObjectSymbolicConstant.NULL) { return Constant.BooleanConstant.TRUE; } if (rightArg instanceof StringConstant && ((StringConstant) rightArg).getValue().equals("null")) { return Constant.BooleanConstant.TRUE; } return Constant.BooleanConstant.FALSE; } throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.values()); } @Override public String getName() { return "equals_operator"; } @Override public EvaluationType getEvaluationType(EvaluationType leftOperandType, EvaluationType rightOperandType) throws TypeMismatchException { if (leftOperandType.isStringOrLiteral() && rightOperandType.isStringOrLiteral()) { return EvaluationType.BOOLEAN; } if (leftOperandType.isBooleanOrLiteral() && rightOperandType.isBooleanOrLiteral()) { return EvaluationType.BOOLEAN; } if (leftOperandType.isEnumOrLiteral() && rightOperandType.isEnumOrLiteral()) { return EvaluationType.BOOLEAN; } return super.getEvaluationType(leftOperandType, rightOperandType); } }; public static final BooleanBinaryOperator NOT_EQUALS = new ComparisonBinaryOperator() { @Override public int getPriority() { return 5; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException, NullReferenceException { // TODO catch exception and replace EQUALS by NOT_EQUALS (not very important but who knows) return EQUALS.evaluate(leftArg, rightArg) == Constant.BooleanConstant.FALSE ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } @Override public String getName() { return "not_equals_operator"; } @Override public EvaluationType getEvaluationType(EvaluationType leftOperandType, EvaluationType rightOperandType) throws TypeMismatchException { if (leftOperandType.isStringOrLiteral() && rightOperandType.isStringOrLiteral()) { return EvaluationType.BOOLEAN; } if (leftOperandType.isBooleanOrLiteral() && rightOperandType.isBooleanOrLiteral()) { return EvaluationType.BOOLEAN; } if (leftOperandType.isEnumOrLiteral() && rightOperandType.isEnumOrLiteral()) { return EvaluationType.BOOLEAN; } return super.getEvaluationType(leftOperandType, rightOperandType); } }; public static final BooleanBinaryOperator LESS_THAN = new ComparisonBinaryOperator() { @Override public int getPriority() { return 5; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { if (leftArg instanceof ArithmeticConstant && rightArg instanceof ArithmeticConstant) { return ((ArithmeticConstant) leftArg).getArithmeticValue() < ((ArithmeticConstant) rightArg).getArithmeticValue() ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DateConstant && rightArg instanceof DateConstant) { return ((DateConstant) leftArg).getDate().before(((DateConstant) rightArg).getDate()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DurationConstant && rightArg instanceof DurationConstant) { return ((DurationConstant) leftArg).getDuration().lessThan(((DurationConstant) rightArg).getDuration()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.ARITHMETIC_FLOAT, EvaluationType.ARITHMETIC_INTEGER, EvaluationType.DATE, EvaluationType.DURATION); } @Override public String getName() { return "less_than_operator"; } }; public static final BooleanBinaryOperator LESS_THAN_OR_EQUALS = new ComparisonBinaryOperator() { @Override public int getPriority() { return 5; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { if (leftArg instanceof ArithmeticConstant && rightArg instanceof ArithmeticConstant) { return ((ArithmeticConstant) leftArg).getArithmeticValue() <= ((ArithmeticConstant) rightArg).getArithmeticValue() ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DateConstant && rightArg instanceof DateConstant) { return ((DateConstant) leftArg).getDate().before(((DateConstant) rightArg).getDate()) || ((DateConstant) leftArg).getDate().equals(((DateConstant) rightArg).getDate()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DurationConstant && rightArg instanceof DurationConstant) { return ((DurationConstant) leftArg).getDuration().lessOrEqualsThan(((DurationConstant) rightArg).getDuration()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.ARITHMETIC_FLOAT, EvaluationType.ARITHMETIC_INTEGER, EvaluationType.DATE, EvaluationType.DURATION); } @Override public String getName() { return "less_than_or_equals_operator"; } }; public static final BooleanBinaryOperator GREATER_THAN = new ComparisonBinaryOperator() { @Override public int getPriority() { return 5; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { if (leftArg instanceof ArithmeticConstant && rightArg instanceof ArithmeticConstant) { return ((ArithmeticConstant) leftArg).getArithmeticValue() > ((ArithmeticConstant) rightArg).getArithmeticValue() ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DateConstant && rightArg instanceof DateConstant) { return ((DateConstant) leftArg).getDate().after(((DateConstant) rightArg).getDate()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DurationConstant && rightArg instanceof DurationConstant) { return ((DurationConstant) leftArg).getDuration().greaterThan(((DurationConstant) rightArg).getDuration()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } // System.out.println("leftArg="+leftArg); // System.out.println("rightArg="+rightArg); throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.ARITHMETIC_FLOAT, EvaluationType.ARITHMETIC_INTEGER, EvaluationType.DATE, EvaluationType.DURATION); } @Override public String getName() { return "greater_than_operator"; } }; public static final BooleanBinaryOperator GREATER_THAN_OR_EQUALS = new ComparisonBinaryOperator() { @Override public int getPriority() { return 5; } @Override public Constant evaluate(Constant leftArg, Constant rightArg) throws TypeMismatchException { if (leftArg instanceof ArithmeticConstant && rightArg instanceof ArithmeticConstant) { return ((ArithmeticConstant) leftArg).getArithmeticValue() >= ((ArithmeticConstant) rightArg).getArithmeticValue() ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DateConstant && rightArg instanceof DateConstant) { return ((DateConstant) leftArg).getDate().after(((DateConstant) rightArg).getDate()) || ((DateConstant) leftArg).getDate().equals(((DateConstant) rightArg).getDate()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } if (leftArg instanceof DurationConstant && rightArg instanceof DurationConstant) { return ((DurationConstant) leftArg).getDuration().greaterOrEqualsThan(((DurationConstant) rightArg).getDuration()) ? Constant.BooleanConstant.TRUE : Constant.BooleanConstant.FALSE; } throw new TypeMismatchException(this, leftArg.getEvaluationType(), rightArg.getEvaluationType(), EvaluationType.ARITHMETIC_FLOAT, EvaluationType.ARITHMETIC_INTEGER, EvaluationType.DATE, EvaluationType.DURATION); } @Override public String getName() { return "greater_than_or_equals_operator"; } }; public static abstract class LogicalBinaryOperator extends BooleanBinaryOperator { @Override public EvaluationType getEvaluationType(EvaluationType leftOperandType, EvaluationType rightOperandType) throws TypeMismatchException { if (leftOperandType.isBooleanOrLiteral() && rightOperandType.isBooleanOrLiteral()) { return EvaluationType.BOOLEAN; } throw new TypeMismatchException(this, leftOperandType, rightOperandType, EvaluationType.BOOLEAN, EvaluationType.LITERAL); } } public static abstract class ComparisonBinaryOperator extends BooleanBinaryOperator { @Override public EvaluationType getEvaluationType(EvaluationType leftOperandType, EvaluationType rightOperandType) throws TypeMismatchException { if (leftOperandType.isArithmeticOrLiteral() && rightOperandType.isArithmeticOrLiteral()) { return EvaluationType.BOOLEAN; } if (leftOperandType.isDateOrLiteral() && rightOperandType.isDateOrLiteral()) { return EvaluationType.BOOLEAN; } if (leftOperandType.isDurationOrLiteral() && rightOperandType.isDurationOrLiteral()) { return EvaluationType.BOOLEAN; } throw new TypeMismatchException(this, leftOperandType, rightOperandType, EvaluationType.ARITHMETIC_INTEGER, EvaluationType.ARITHMETIC_FLOAT, EvaluationType.DATE, EvaluationType.DURATION, EvaluationType.LITERAL); } } }