001: /**
002: *
003: * Copyright 2004 Hiram Chirino
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: **/package org.activemq.filter.mockrunner;
018:
019: import java.math.BigDecimal;
020: import java.util.Collection;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import javax.jms.JMSException;
026: import javax.jms.Message;
027:
028: /**
029: * Alwin Ibba: Changed package
030: * Alwin Ibba: Removed create XPath methods
031: *
032: * An expression which performs an operation on two expression values
033: *
034: * @version $Revision: 1.3 $
035: */
036: public abstract class UnaryExpression implements Expression {
037:
038: private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal
039: .valueOf(Long.MIN_VALUE);
040: protected Expression right;
041:
042: public static Expression createNegate(Expression left) {
043: return new UnaryExpression(left) {
044: public Object evaluate(Message message) throws JMSException {
045: Object rvalue = right.evaluate(message);
046: if (rvalue == null) {
047: return null;
048: }
049: if (rvalue instanceof Number) {
050: return negate((Number) rvalue);
051: }
052: return null;
053: }
054:
055: public String getExpressionSymbol() {
056: return "-";
057: }
058: };
059: }
060:
061: public static BooleanExpression createInExpression(
062: PropertyExpression right, List elements, final boolean not) {
063:
064: // Use a HashSet if there are many elements.
065: Collection t;
066: if (elements.size() == 0)
067: t = null;
068: else if (elements.size() < 5)
069: t = elements;
070: else {
071: t = new HashSet(elements);
072: }
073: final Collection inList = t;
074:
075: return new BooleanUnaryExpression(right) {
076: public Object evaluate(Message message) throws JMSException {
077:
078: Object rvalue = this .right.evaluate(message);
079: if (rvalue == null) {
080: return null;
081: }
082: if (rvalue.getClass() != String.class)
083: return null;
084:
085: if ((inList != null && inList.contains(rvalue)) ^ not) {
086: return Boolean.TRUE;
087: } else {
088: return Boolean.FALSE;
089: }
090:
091: }
092:
093: public String toString() {
094: StringBuffer answer = new StringBuffer();
095: answer.append(this .right);
096: answer.append(" ");
097: answer.append(getExpressionSymbol());
098: answer.append(" ( ");
099:
100: int count = 0;
101: for (Iterator i = inList.iterator(); i.hasNext();) {
102: Object o = (Object) i.next();
103: if (count != 0) {
104: answer.append(", ");
105: }
106: answer.append(o);
107: count++;
108: }
109:
110: answer.append(" )");
111: return answer.toString();
112: }
113:
114: public String getExpressionSymbol() {
115: if (not)
116: return "NOT IN";
117: else
118: return "IN";
119: }
120: };
121: }
122:
123: abstract static class BooleanUnaryExpression extends
124: UnaryExpression implements BooleanExpression {
125: public BooleanUnaryExpression(Expression left) {
126: super (left);
127: }
128: };
129:
130: public static BooleanExpression createNOT(BooleanExpression left) {
131: return new BooleanUnaryExpression(left) {
132: public Object evaluate(Message message) throws JMSException {
133: Boolean lvalue = (Boolean) right.evaluate(message);
134: if (lvalue == null) {
135: return null;
136: }
137: return lvalue.booleanValue() ? Boolean.FALSE
138: : Boolean.TRUE;
139: }
140:
141: public String getExpressionSymbol() {
142: return "NOT";
143: }
144: };
145: }
146:
147: public static BooleanExpression createBooleanCast(Expression left) {
148: return new BooleanUnaryExpression(left) {
149: public Object evaluate(Message message) throws JMSException {
150: Object lvalue = right.evaluate(message);
151: if (lvalue == null)
152: return null;
153: if (!lvalue.getClass().equals(Boolean.class))
154: return Boolean.FALSE;
155:
156: return lvalue;
157: }
158:
159: public String getExpressionSymbol() {
160: return "NOT";
161: }
162: };
163: }
164:
165: private static Number negate(Number left) {
166: Class clazz = left.getClass();
167: if (clazz == Integer.class) {
168: return new Integer(-left.intValue());
169: } else if (clazz == Long.class) {
170: return new Long(-left.longValue());
171: } else if (clazz == Float.class) {
172: return new Float(-left.floatValue());
173: } else if (clazz == Double.class) {
174: return new Double(-left.doubleValue());
175: } else if (clazz == BigDecimal.class) {
176: // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the
177: // Selector. Long.MIN_VALUE is too big to store in a Long as a positive so we store it
178: // as a Big decimal. But it gets Negated right away.. to here we try to covert it back
179: // to a Long.
180: BigDecimal bd = (BigDecimal) left;
181: bd = bd.negate();
182:
183: if (BD_LONG_MIN_VALUE.compareTo(bd) == 0) {
184: return new Long(Long.MIN_VALUE);
185: }
186: return bd;
187: } else {
188: throw new RuntimeException("Don't know how to negate: "
189: + left);
190: }
191: }
192:
193: public UnaryExpression(Expression left) {
194: this .right = left;
195: }
196:
197: public Expression getRight() {
198: return right;
199: }
200:
201: public void setRight(Expression expression) {
202: right = expression;
203: }
204:
205: /**
206: * @see java.lang.Object#toString()
207: */
208: public String toString() {
209: return "(" + getExpressionSymbol() + " " + right.toString()
210: + ")";
211: }
212:
213: /**
214: * TODO: more efficient hashCode()
215: *
216: * @see java.lang.Object#hashCode()
217: */
218: public int hashCode() {
219: return toString().hashCode();
220: }
221:
222: /**
223: * TODO: more efficient hashCode()
224: *
225: * @see java.lang.Object#equals(java.lang.Object)
226: */
227: public boolean equals(Object o) {
228:
229: if (o == null || !this .getClass().equals(o.getClass())) {
230: return false;
231: }
232: return toString().equals(o.toString());
233:
234: }
235:
236: /**
237: * Returns the symbol that represents this binary expression. For example, addition is
238: * represented by "+"
239: *
240: * @return
241: */
242: abstract public String getExpressionSymbol();
243:
244: }
|