001: /**
002: * Copyright 2007 Jens Dietrich Licensed under the Apache License, Version 2.0 (the "License");
003: * you may not use this file except in compliance with the License.
004: * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
005: * Unless required by applicable law or agreed to in writing, software distributed under the
006: * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
007: * either express or implied. See the License for the specific language governing permissions
008: * and limitations under the License.
009: */package nz.org.take;
010:
011: import java.util.Arrays;
012:
013: /**
014: * Predicates to compare numbers (==,!=, < etc).
015: * @author <a href="http://www-ist.massey.ac.nz/JBDietrich/">Jens Dietrich</a>
016: */
017:
018: public class Comparison extends AbstractPredicate {
019:
020: private String symbol = null;
021: private Class[] types = new Class[] { Double.class, Double.class };
022: private String name = null;
023:
024: public Comparison(String symbol) throws TakeException {
025: super ();
026: this .symbol = symbol;
027: String n = createName();
028: if (n != null)
029: name = n;
030: else
031: throw new TakeException(
032: "This comparison operator is unknown: " + symbol);
033: }
034:
035: private String createName() {
036: if ("<".equals(symbol))
037: return "less_than";
038: else if ("<=".equals(symbol))
039: return "less_than_or_equal";
040: else if (">".equals(symbol))
041: return "greater_than";
042: else if (">=".equals(symbol))
043: return "greater_than_or_equal";
044: else if ("==".equals(symbol))
045: return "equal";
046: else if ("!=".equals(symbol))
047: return "not_equal";
048: else
049: return null;
050: }
051:
052: public String getName() {
053: return name;
054: }
055:
056: public Class[] getSlotTypes() {
057: return types;
058: }
059:
060: public String toString() {
061: return (negated ? "!" : "") + getName();
062: }
063:
064: public String getSymbol() {
065: return symbol;
066: }
067:
068: public void setSymbol(String symbol) {
069: this .symbol = symbol;
070: }
071:
072: public void setTypes(Class[] types) {
073: if (types.length != 2)
074: throw new IllegalArgumentException(
075: "Comparisons are compare exactly two terms, but the number of arguments is "
076: + types.length);
077: checkType(types[0]);
078: checkType(types[1]);
079: this .types = types;
080: this .name = createName() + "_" + computeTypeTag();
081: }
082:
083: private void checkType(Class c) {
084: if (c.isPrimitive())
085: return;
086: if ((c == Boolean.class || c == String.class)
087: && (symbol.equals("==") || symbol.equals("!=")))
088: return;
089: if (!Number.class.isAssignableFrom(c))
090: throw new IllegalArgumentException(
091: "Comparisons are for numeric data types only and in case of String and Boolean, if the symbol is == or !=.");
092:
093: }
094:
095: @Override
096: public int hashCode() {
097: final int PRIME = 31;
098: int result = 1;
099: result = PRIME * result
100: + ((symbol == null) ? 0 : symbol.hashCode());
101: result = PRIME * result + Arrays.hashCode(types);
102: return result;
103: }
104:
105: @Override
106: public boolean equals(Object obj) {
107: if (this == obj)
108: return true;
109: if (obj == null)
110: return false;
111: if (getClass() != obj.getClass())
112: return false;
113: final Comparison other = (Comparison) obj;
114: if (symbol == null) {
115: if (other.symbol != null)
116: return false;
117: } else if (!symbol.equals(other.symbol))
118: return false;
119: if (!Arrays.equals(types, other.types))
120: return false;
121: return true;
122: }
123:
124: /**
125: * compute a short string representing the associated types
126: * used as part of the name in order to make names unique if overloading
127: * occurs.
128: * @return a string
129: */
130: private String computeTypeTag() {
131: return "" + computeTypeTag(this .types[0])
132: + computeTypeTag(this .types[1]);
133: }
134:
135: private char computeTypeTag(Class clazz) {
136: if (clazz.isPrimitive())
137: return clazz.getName().charAt(0);
138: else if (clazz.getName().startsWith("java.lang."))
139: return Character.toLowerCase(clazz.getName().charAt(
140: "java.lang.".length()));
141: else
142: throw new IllegalArgumentException(
143: "Illegal primitive class name: " + clazz.getName());
144:
145: }
146:
147: }
|