View Javadoc

1   /**
2    * Copyright 2005-2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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  package org.kuali.rice.krms.framework.engine.expression;
17  
18  import org.apache.commons.lang.ObjectUtils;
19  import org.kuali.rice.core.api.mo.common.Coded;
20  import org.kuali.rice.krms.api.engine.IncompatibleTypeException;
21  
22  public enum ComparisonOperator implements Coded {
23  
24  	EQUALS("="),
25  	NOT_EQUALS("!="),
26  	GREATER_THAN(">"),
27  	GREATER_THAN_EQUAL(">="),
28  	LESS_THAN("<"),
29  	LESS_THAN_EQUAL("<=");
30  	
31  	private final String code;
32  	
33  	private ComparisonOperator(String code) {
34  		this.code = code;
35  	}
36  	
37  	public String getCode() {
38  		return code;
39  	}
40  	
41  	public static ComparisonOperator fromCode(String code) {
42  		if (code == null) {
43  			return null;
44  		}
45  		for (ComparisonOperator comparisonOperator : values()) {
46  			if (comparisonOperator.code.equals(code)) {
47  				return comparisonOperator;
48  			}
49  		}
50  		throw new IllegalArgumentException("Failed to locate the ComparisionOperator with the given code: " + code);
51  	}
52  	
53  	public boolean compare(Object lhs, Object rhs) {
54  		
55  		// TODO this implementation seems largely incomplete, it seems we are need to have some kind of engine
56  		// or utility which can coerce types to possible forms for comparision purposes?  For now, let's verify
57  		// they are of the same type
58  		
59  		if (lhs != null && rhs != null && !lhs.getClass().equals(rhs.getClass())) {
60  			throw new IncompatibleTypeException("Could not compare values for operator " + this, lhs, rhs.getClass());
61  		}
62  		
63  		if (this == EQUALS) {
64  			return ObjectUtils.equals(lhs, rhs);
65  		} else if (this == NOT_EQUALS) {
66  			return ObjectUtils.notEqual(lhs, rhs);
67  		} else if (lhs == null || rhs == null) {
68  			// any other operation besides equals and not equals will evaluate to false in the case of null
69  			return false;
70  		}
71  		if (lhs instanceof Comparable && rhs instanceof Comparable) {
72  			
73  			// TODO not sure what to do about this cast and whether or not it will safe,
74  			// be sure to hit this in unit testing!
75  			
76  			int result = ((Comparable)lhs).compareTo(rhs);
77  			if (this == GREATER_THAN) {
78  				return result > 0;
79  			}
80  			if (this == GREATER_THAN_EQUAL) {
81  				return result >= 0;
82  			}
83  			if (this == LESS_THAN) {
84  				return result < 0;
85  			}
86  			if (this == LESS_THAN_EQUAL) {
87  				return result <= 0;
88  			}			
89  		} else {
90  			throw new IncompatibleTypeException("Could not compare values, they are not comparable for operator " + this, lhs, rhs.getClass());
91  		}
92  		throw new IllegalStateException("Invalid operator detected: " + this);
93  	}
94  	
95  }