summaryrefslogtreecommitdiff
path: root/qpid/java/common/src/main/java/org/apache/qpid/filter/UnaryExpression.java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/common/src/main/java/org/apache/qpid/filter/UnaryExpression.java')
-rw-r--r--qpid/java/common/src/main/java/org/apache/qpid/filter/UnaryExpression.java340
1 files changed, 340 insertions, 0 deletions
diff --git a/qpid/java/common/src/main/java/org/apache/qpid/filter/UnaryExpression.java b/qpid/java/common/src/main/java/org/apache/qpid/filter/UnaryExpression.java
new file mode 100644
index 0000000000..b80b89840c
--- /dev/null
+++ b/qpid/java/common/src/main/java/org/apache/qpid/filter/UnaryExpression.java
@@ -0,0 +1,340 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.filter;
+//
+// Based on like named file from r450141 of the Apache ActiveMQ project <http://www.activemq.org/site/home.html>
+//
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * An expression which performs an operation on two expression values
+ */
+public abstract class UnaryExpression implements Expression
+{
+
+ private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE);
+ private Expression right;
+
+ public static Expression createNegate(Expression left)
+ {
+ return new NegativeExpression(left);
+ }
+
+ public static BooleanExpression createInExpression(PropertyExpression right, List elements, final boolean not)
+ {
+
+ // Use a HashSet if there are many elements.
+ Collection t;
+ if (elements.size() == 0)
+ {
+ t = null;
+ }
+ else if (elements.size() < 5)
+ {
+ t = elements;
+ }
+ else
+ {
+ t = new HashSet(elements);
+ }
+
+ final Collection inList = t;
+
+ return new InExpression(right, inList, not);
+ }
+
+ abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression
+ {
+ public BooleanUnaryExpression(Expression left)
+ {
+ super(left);
+ }
+
+ public boolean matches(FilterableMessage message)
+ {
+ Object object = evaluate(message);
+
+ return (object != null) && (object == Boolean.TRUE);
+ }
+ }
+
+ public static BooleanExpression createNOT(BooleanExpression left)
+ {
+ return new NotExpression(left);
+ }
+
+ public static BooleanExpression createBooleanCast(Expression left)
+ {
+ return new BooleanCastExpression(left);
+ }
+
+ private static Number negate(Number left)
+ {
+ Class clazz = left.getClass();
+ if (clazz == Integer.class)
+ {
+ return -left.intValue();
+ }
+ else if (clazz == Long.class)
+ {
+ return -left.longValue();
+ }
+ else if (clazz == Float.class)
+ {
+ return -left.floatValue();
+ }
+ else if (clazz == Double.class)
+ {
+ return -left.doubleValue();
+ }
+ else if (clazz == BigDecimal.class)
+ {
+ // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the
+ // Selector. Long.MIN_VALUE is too big to store in a Long as a positive so we store it
+ // as a Big decimal. But it gets Negated right away.. to here we try to covert it back
+ // to a Long.
+ BigDecimal bd = (BigDecimal) left;
+ bd = bd.negate();
+
+ if (BD_LONG_MIN_VALUE.compareTo(bd) == 0)
+ {
+ return Long.MIN_VALUE;
+ }
+
+ return bd;
+ }
+ else
+ {
+ throw new SelectorParsingException("Don't know how to negate: " + left);
+ }
+ }
+
+ public UnaryExpression(Expression left)
+ {
+ this.right = left;
+ }
+
+ public Expression getRight()
+ {
+ return right;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ return "(" + getExpressionSymbol() + " " + right.toString() + ")";
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode()
+ {
+ return toString().hashCode();
+ }
+
+ /**
+ * TODO: more efficient hashCode()
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o)
+ {
+ return ((o != null) && this.getClass().equals(o.getClass())) && toString().equals(o.toString());
+ }
+
+ /**
+ * Returns the symbol that represents this binary expression. For example, addition is
+ * represented by "+"
+ *
+ * @return symbol
+ */
+ public abstract String getExpressionSymbol();
+
+ private static class NegativeExpression extends UnaryExpression
+ {
+ public NegativeExpression(final Expression left)
+ {
+ super(left);
+ }
+
+ public Object evaluate(FilterableMessage message)
+ {
+ Object rvalue = getRight().evaluate(message);
+ if (rvalue == null)
+ {
+ return null;
+ }
+
+ if (rvalue instanceof Number)
+ {
+ return negate((Number) rvalue);
+ }
+
+ return null;
+ }
+
+ public String getExpressionSymbol()
+ {
+ return "-";
+ }
+ }
+
+ private static class InExpression extends BooleanUnaryExpression
+ {
+ private final Collection _inList;
+ private final boolean _not;
+
+ public InExpression(final PropertyExpression right, final Collection inList, final boolean not)
+ {
+ super(right);
+ _inList = inList;
+ _not = not;
+ }
+
+ public Object evaluate(FilterableMessage message)
+ {
+
+ Object rvalue = getRight().evaluate(message);
+ if (rvalue == null)
+ {
+ return null;
+ }
+
+ if (rvalue.getClass() != String.class)
+ {
+ return null;
+ }
+
+ if (((_inList != null) && _inList.contains(rvalue)) ^ _not)
+ {
+ return Boolean.TRUE;
+ }
+ else
+ {
+ return Boolean.FALSE;
+ }
+
+ }
+
+ public String toString()
+ {
+ StringBuilder answer = new StringBuilder(String.valueOf(getRight()));
+ answer.append(" ");
+ answer.append(getExpressionSymbol());
+ answer.append(" ( ");
+
+ int count = 0;
+ for (Object o : _inList)
+ {
+ if (count != 0)
+ {
+ answer.append(", ");
+ }
+
+ answer.append(o);
+ count++;
+ }
+
+ answer.append(" )");
+
+ return answer.toString();
+ }
+
+ public String getExpressionSymbol()
+ {
+ if (_not)
+ {
+ return "NOT IN";
+ }
+ else
+ {
+ return "IN";
+ }
+ }
+ }
+
+ private static class NotExpression extends BooleanUnaryExpression
+ {
+ public NotExpression(final BooleanExpression left)
+ {
+ super(left);
+ }
+
+ public Object evaluate(FilterableMessage message)
+ {
+ Boolean lvalue = (Boolean) getRight().evaluate(message);
+ if (lvalue == null)
+ {
+ return null;
+ }
+
+ return lvalue ? Boolean.FALSE : Boolean.TRUE;
+ }
+
+ public String getExpressionSymbol()
+ {
+ return "NOT";
+ }
+ }
+
+ private static class BooleanCastExpression extends BooleanUnaryExpression
+ {
+ public BooleanCastExpression(final Expression left)
+ {
+ super(left);
+ }
+
+ public Object evaluate(FilterableMessage message)
+ {
+ Object rvalue = getRight().evaluate(message);
+ if (rvalue == null)
+ {
+ return null;
+ }
+
+ if (!rvalue.getClass().equals(Boolean.class))
+ {
+ return Boolean.FALSE;
+ }
+
+ return ((Boolean) rvalue) ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public String toString()
+ {
+ return getRight().toString();
+ }
+
+ public String getExpressionSymbol()
+ {
+ return "";
+ }
+ }
+}