1 52 53 package freemarker.core; 54 55 import java.util.Date ; 56 import freemarker.template.*; 57 58 63 64 final class ComparisonExpression extends BooleanExpression { 65 66 static final int EQUALS=1; 67 static final int NOT_EQUALS=2; 68 static final int LESS_THAN=3; 69 static final int GREATER_THAN=4; 70 static final int LESS_THAN_EQUALS=5; 71 static final int GREATER_THAN_EQUALS=6; 72 73 private final Expression left; 74 private final Expression right; 75 private final int operation; 76 private final String opString; 77 78 ComparisonExpression(Expression left, Expression right, String opString) { 79 this.left = left; 80 this.right = right; 81 opString = opString.intern(); 82 this.opString = opString; 83 if (opString == "==" || opString == "=") { 84 operation = EQUALS; 85 } 86 else if (opString == "!=") { 87 operation = NOT_EQUALS; 88 } 89 else if (opString == "gt" || opString == "\\gt" || opString == ">" || opString == ">") { 90 operation = GREATER_THAN; 91 } 92 else if (opString == "gte" || opString == "\\gte" || opString == ">=" || opString == ">=") { 93 operation = GREATER_THAN_EQUALS; 94 } 95 else if (opString== "lt" || opString == "\\lt" || opString == "<" || opString == "<") { 96 operation = LESS_THAN; 97 } 98 else if (opString == "lte" || opString == "\\lte" || opString == "<=" || opString == "<=") { 99 operation = LESS_THAN_EQUALS; 100 } 101 else { 102 throw new RuntimeException ("Unknown comparison operator " + opString); 103 } 104 } 105 106 110 boolean isTrue(Environment env) throws TemplateException { 111 TemplateModel ltm = left.getAsTemplateModel(env); 112 TemplateModel rtm = right.getAsTemplateModel(env); 113 if (env != null && env.isClassicCompatible()) { 114 if (ltm == null) { 115 ltm = TemplateScalarModel.EMPTY_STRING; 116 } 117 if (rtm == null) { 118 rtm = TemplateScalarModel.EMPTY_STRING; 119 } 120 } 121 assertNonNull(ltm, left, env); 122 assertNonNull(rtm, right, env); 123 int comp = 0; 124 if(ltm instanceof TemplateNumberModel && rtm instanceof TemplateNumberModel) { 125 Number first = EvaluationUtil.getNumber((TemplateNumberModel)ltm, left, env); 126 Number second = EvaluationUtil.getNumber((TemplateNumberModel)rtm, right, env); 127 ArithmeticEngine ae = 128 env != null 129 ? env.getArithmeticEngine() 130 : getTemplate().getArithmeticEngine(); 131 comp = ae.compareNumbers(first, second); 132 } 133 else if(ltm instanceof TemplateDateModel && rtm instanceof TemplateDateModel) { 134 TemplateDateModel ltdm = (TemplateDateModel)ltm; 135 TemplateDateModel rtdm = (TemplateDateModel)rtm; 136 int ltype = ltdm.getDateType(); 137 int rtype = rtdm.getDateType(); 138 if(ltype != rtype) { 139 throw new TemplateException( 140 "Can not compare dates of different type. Left date is of " 141 + TemplateDateModel.TYPE_NAMES.get(ltype) 142 + " type, right date is of " 143 + TemplateDateModel.TYPE_NAMES.get(rtype) + " type.", 144 env); 145 } 146 if(ltype == TemplateDateModel.UNKNOWN) { 147 throw new TemplateException( 148 "Left date is of UNKNOWN type, and can not be compared.", env); 149 } 150 if(rtype == TemplateDateModel.UNKNOWN) { 151 throw new TemplateException( 152 "Right date is of UNKNOWN type, and can not be compared.", env); 153 } 154 155 Date first = EvaluationUtil.getDate(ltdm, left, env); 156 Date second = EvaluationUtil.getDate(rtdm, right, env); 157 comp = first.compareTo(second); 158 } 159 else if(ltm instanceof TemplateScalarModel && rtm instanceof TemplateScalarModel) { 160 if(operation != EQUALS && operation != NOT_EQUALS) { 161 throw new TemplateException("Can not use operator " + opString + " on string values.", env); 162 } 163 String first = EvaluationUtil.getString((TemplateScalarModel)ltm, left, env); 164 String second = EvaluationUtil.getString((TemplateScalarModel)rtm, right, env); 165 comp = env.getCollator().compare(first, second); 166 } 167 else if(ltm instanceof TemplateBooleanModel && rtm instanceof TemplateBooleanModel) { 168 if(operation != EQUALS && operation != NOT_EQUALS) { 169 throw new TemplateException("Can not use operator " + opString + " on boolean values.", env); 170 } 171 boolean first = ((TemplateBooleanModel)ltm).getAsBoolean(); 172 boolean second = ((TemplateBooleanModel)rtm).getAsBoolean(); 173 comp = (first ? 1 : 0) - (second ? 1 : 0); 174 } 175 else if(env.isClassicCompatible()) { 177 String first = left.getStringValue(env); 178 String second = right.getStringValue(env); 179 comp = env.getCollator().compare(first, second); 180 } 181 else { 182 throw new TemplateException( 183 "The only legal comparisons are between two numbers, two strings, or two dates.\n" 184 + "Left hand operand is a " + ltm.getClass().getName() + "\n" 185 + "Right hand operand is a " + rtm.getClass().getName() + "\n" 186 , env); 187 } 188 switch (operation) { 189 case EQUALS: 190 return comp == 0; 191 case NOT_EQUALS: 192 return comp != 0; 193 case LESS_THAN : 194 return comp < 0; 195 case GREATER_THAN : 196 return comp > 0; 197 case LESS_THAN_EQUALS : 198 return comp <= 0; 199 case GREATER_THAN_EQUALS : 200 return comp >= 0; 201 default : 202 throw new TemplateException("unknown operation", env); 203 } 204 } 205 206 public String getCanonicalForm() { 207 return left.getCanonicalForm() + ' ' + opString + ' ' + right.getCanonicalForm(); 208 } 209 210 boolean isLiteral() { 211 return constantValue != null || (left.isLiteral() && right.isLiteral()); 212 } 213 214 Expression _deepClone(String name, Expression subst) { 215 return new ComparisonExpression(left.deepClone(name, subst), right.deepClone(name, subst), opString); 216 } 217 } 218 | Popular Tags |