/* * OpenClinica is distributed under the * GNU Lesser General Public License (GNU LGPL). * For details see: http://www.openclinica.org/license * * Copyright 2003-2008 Akaza Research */ package org.akaza.openclinica.logic.expressionTree; import org.akaza.openclinica.exception.OpenClinicaSystemException; /** * @author Krikor Krumlian * */ public class RelationalOpNode extends ExpressionNode { Operator op; // The operator. ExpressionNode left; // The expression for its left operand. ExpressionNode right; // The expression for its right operand. RelationalOpNode(Operator op, ExpressionNode left, ExpressionNode right) { // Construct a BinOpNode containing the specified data. assert op == Operator.GREATER_THAN || op == Operator.GREATER_THAN_EQUAL || op == Operator.LESS_THAN || op == Operator.LESS_THAN_EQUAL; assert left != null && right != null; this.op = op; this.left = left; this.right = right; } @Override String testCalculate() throws OpenClinicaSystemException { double x, y; String l = String.valueOf(left.testValue()); String r = String.valueOf(right.testValue()); if(blankAgainstDateyyyyMMdd(l,r)) { return "blankAgainstDateyyyyMMdd"; } validate(l, r, left.getNumber(), right.getNumber()); if (ExpressionTreeHelper.isDateyyyyMMdd(l) && ExpressionTreeHelper.isDateyyyyMMdd(r)) { x = ExpressionTreeHelper.getDate(l).getTime(); y = ExpressionTreeHelper.getDate(r).getTime(); } else { x = Double.valueOf(l); y = Double.valueOf(r); } return calc(x, y); } @Override Object calculate() throws OpenClinicaSystemException { double x, y; String l = String.valueOf(left.value()); String r = String.valueOf(right.value()); if(blankAgainstDateyyyyMMdd(l,r)) { return "blankAgainstDateyyyyMMdd"; } validate(l, r); if (ExpressionTreeHelper.isDateyyyyMMdd(l) && ExpressionTreeHelper.isDateyyyyMMdd(r)) { x = ExpressionTreeHelper.getDate(l).getTime(); y = ExpressionTreeHelper.getDate(r).getTime(); } else { x = Double.valueOf(l); y = Double.valueOf(r); } return calc(x, y); } private String calc(double x, double y) throws OpenClinicaSystemException { switch (op) { case GREATER_THAN: return String.valueOf(x > y); case GREATER_THAN_EQUAL: return String.valueOf(x >= y); case LESS_THAN: return String.valueOf(x < y); case LESS_THAN_EQUAL: return String.valueOf(x <= y); default: return null; // Bad operator! } } private boolean isDouble(String x, String y) { try { Double.valueOf(x); Double.valueOf(y); return true; } catch (NumberFormatException nfe) { return false; } } void validate(String l, String r) throws OpenClinicaSystemException { if (!(ExpressionTreeHelper.isDateyyyyMMdd(l) && ExpressionTreeHelper.isDateyyyyMMdd(r)) && !isDouble(l, r)) { //throw new OpenClinicaSystemException(l + " and " + r + " cannot be used with the " + op.toString() + " operator"); throw new OpenClinicaSystemException("OCRERR_0001", new Object[] { l, r, op.toString() }); } } void validate(String l, String r, String ltext, String rtext) throws OpenClinicaSystemException { if (!(ExpressionTreeHelper.isDateyyyyMMdd(l) && ExpressionTreeHelper.isDateyyyyMMdd(r)) && !isDouble(l, r)) { //throw new OpenClinicaSystemException(l + " and " + r + " cannot be used with the " + op.toString() + " operator"); throw new OpenClinicaSystemException("OCRERR_0001", new Object[] { ltext, rtext, op.toString() }); } } /* * Precondition: both l and r are not empty. * Return true only if one is dd-MMM-yyyy format, another is ExpressionTreeHelper.isDateyyyyMMdd */ private boolean preValidateOnddMMMyyyyDashes(String l, String r) { if(ExpressionTreeHelper.isDateddMMMyyyyDashes(l)&&ExpressionTreeHelper.isDateyyyyMMdd(r) ||ExpressionTreeHelper.isDateddMMMyyyyDashes(r)&&ExpressionTreeHelper.isDateyyyyMMdd(l)) { return true; } return false; } private boolean blankAgainstDateyyyyMMdd(String l, String r) { return l.isEmpty() && ExpressionTreeHelper.isDateyyyyMMdd(r) || r.isEmpty() && ExpressionTreeHelper.isDateyyyyMMdd(l); } @Override void printStackCommands() { // To evalute the expression on a stack machine, first do // whatever is necessary to evaluate the left operand, leaving // the answer on the stack. Then do the same thing for the // second operand. Then apply the operator (which means popping // the operands, applying the operator, and pushing the result). left.printStackCommands(); right.printStackCommands(); logger.info(" Operator " + op); } }