View Javadoc

1   /*
2    * Copyright 2004-2009 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springmodules.validation.valang.predicates;
18  
19  import java.math.BigDecimal;
20  import java.util.Date;
21  
22  import org.springmodules.validation.valang.ValangException;
23  import org.springmodules.validation.valang.functions.EnumLiteralFunction;
24  import org.springmodules.validation.valang.functions.Function;
25  
26  /**
27   * Tests if a value is equal to another.
28   *
29   * @author David Winterfeldt
30   */
31  public class EqualsTestPredicate extends AbstractPropertyPredicate {
32  
33      /**
34       * <p>Constructor taking two functions and an operator.
35       *
36       * @param leftFunction the left function
37       * @param operator the operator.
38       */
39      public EqualsTestPredicate(Function leftFunction, Operator operator, Function rightFunction, int line, int column) {
40          super(leftFunction, operator, rightFunction, line, column);
41      }
42  
43      /**
44       * <p>The evaluate method takes the result of both functions and tests with the operator.
45       *
46       * @param   target      The target bean.
47       * @return  boolean      Whether or not the test passed.
48       */
49      public boolean evaluate(Object target) {
50          // constructor checks that left function is never null
51          Object leftValue = getLeftFunction().getResult(target);
52          Object rightValue = (getRightFunction() != null ? getRightFunction().getResult(target) : null);
53          
54          if (leftValue instanceof Number && rightValue instanceof Number) {
55              if (!(leftValue instanceof BigDecimal)) {
56                  leftValue = new BigDecimal(leftValue.toString());
57              }
58              if (!(rightValue instanceof BigDecimal)) {
59                  rightValue = new BigDecimal(rightValue.toString());
60              }
61  
62              return ((BigDecimal) leftValue).compareTo((BigDecimal) rightValue) == 0;
63          } else if (leftValue instanceof Date && rightValue instanceof Date) {
64              return ((Date) leftValue).getTime() == ((Date) rightValue).getTime();
65          // if one variable is an enum, convert other to a string and try to match
66          } else if (getLeftFunction() instanceof EnumLiteralFunction || getRightFunction() instanceof EnumLiteralFunction) {
67              Enum<?> enumValue = null;
68              Enum<?> convertedEnumValue = null;
69              String value = null;
70              
71              try {
72                  if (getRightFunction() instanceof EnumLiteralFunction) {
73                      enumValue = (Enum<?>) leftValue;
74                      value = rightValue.toString().trim();                       
75                  } else if (getLeftFunction() instanceof EnumLiteralFunction) {
76                      enumValue = (Enum<?>) rightValue;
77                      value = leftValue.toString().trim();
78                  }
79  
80                  // tried generating bytecode, but was twice as slow
81                  Class<?> enumClass = enumValue.getClass();
82                  convertedEnumValue = (Enum<?>) enumClass.getField(value).get(null);
83  
84                  return enumValue.equals(convertedEnumValue);
85              } catch (Throwable e) {
86                  throw new ValangException("Field [" + value + "] isn't an enum value on " + enumValue.getClass().getName() + ".", 
87                                            getLine(), getColumn());
88              }
89          } else {
90              return leftValue.equals(rightValue);
91          }
92      }
93  
94  }