Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/activemq/filter/UnaryExpression.java


1   /** 
2    * 
3    * Copyright 2004 Hiram Chirino
4    * 
5    * Licensed under the Apache License, Version 2.0 (the "License"); 
6    * you may not use this file except in compliance with the License. 
7    * You may obtain a copy of the License at 
8    * 
9    * http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS, 
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
14   * See the License for the specific language governing permissions and 
15   * limitations under the License. 
16   * 
17   **/
18  package org.activemq.filter;
19  
20  import java.math.BigDecimal;
21  import java.util.Collection;
22  import java.util.HashSet;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import javax.jms.JMSException;
27  import javax.jms.Message;
28  
29  /**
30   * An expression which performs an operation on two expression values
31   * 
32   * @version $Revision: 1.1.1.1 $
33   */
34  public abstract class UnaryExpression implements Expression {
35  
36      private static final BigDecimal BD_LONG_MIN_VALUE = BigDecimal.valueOf(Long.MIN_VALUE);
37      protected Expression right;
38  
39      public static Expression createNegate(Expression left) {
40          return new UnaryExpression(left) {
41              public Object evaluate(Message message) throws JMSException {
42                  Object rvalue = right.evaluate(message);
43                  if (rvalue == null) {
44                      return null;
45                  }
46                  if (rvalue instanceof Number) {
47                      return negate((Number) rvalue);
48                  }
49                  return null;
50              }
51  
52              public String getExpressionSymbol() {
53                  return "-";
54              }
55          };
56      }
57  
58      public static BooleanExpression createInExpression(PropertyExpression right, List elements, final boolean not) {
59        
60        // Use a HashSet if there are many elements.
61        Collection t;
62      if( elements.size()==0 )
63          t=null;
64        else if( elements.size() < 5 )
65          t = elements;
66        else {
67          t = new HashSet(elements);
68        }
69        final Collection inList = t;
70        
71          return new BooleanUnaryExpression(right) {
72              public Object evaluate(Message message) throws JMSException {
73                
74                  Object rvalue = right.evaluate(message);
75                  if (rvalue == null) {
76                      return null;
77                  }
78                  if( rvalue.getClass()!=String.class )
79                    return null;
80                  
81                  if( (inList!=null && inList.contains(rvalue)) ^ not ) {
82                    return Boolean.TRUE;
83                  } else {
84                    return Boolean.FALSE;                  
85                  }
86                  
87              }
88  
89              public String toString() {
90                StringBuffer answer = new StringBuffer();
91                answer.append(right);
92                answer.append(" ");
93                answer.append(getExpressionSymbol());
94                answer.append(" ( ");
95  
96                int count=0;
97                for (Iterator i = inList.iterator(); i.hasNext();) {
98            Object o = (Object) i.next();
99            if( count!=0 ) {
100                   answer.append(", ");        
101           }
102                 answer.append(o);        
103                 count++;
104         }
105               
106               answer.append(" )");        
107                 return answer.toString();
108       }
109       
110             public String getExpressionSymbol() {
111               if( not )
112                 return "NOT IN";
113               else 
114                 return "IN";
115             }
116         };
117     }
118 
119     abstract static class BooleanUnaryExpression extends UnaryExpression implements BooleanExpression {
120         public BooleanUnaryExpression(Expression left) {          
121             super(left);
122         }
123     };
124 
125         
126     public static BooleanExpression createNOT(BooleanExpression left) {
127         return new BooleanUnaryExpression(left) {
128             public Object evaluate(Message message) throws JMSException {
129                 Boolean lvalue = (Boolean) right.evaluate(message);
130                 if (lvalue == null) {
131                     return null;
132                 }
133                 return lvalue.booleanValue() ? Boolean.FALSE : Boolean.TRUE;
134             }
135 
136             public String getExpressionSymbol() {
137                 return "NOT";
138             }
139         };
140     }
141     
142     public static BooleanExpression createXPath(final String xpath) {
143         return new XPathExpression(xpath);
144     }
145 
146     public static BooleanExpression createXQuery(final String xpath) {
147         return new XQueryExpression(xpath);
148     }
149 
150     public static BooleanExpression createBooleanCast(Expression left) {
151         return new BooleanUnaryExpression(left) {
152             public Object evaluate(Message message) throws JMSException {
153                 Object lvalue = right.evaluate(message);
154                 if (lvalue == null) 
155                     return null;
156                 if (!lvalue.getClass().equals(Boolean.class)) 
157                     return Boolean.FALSE;
158                                
159                 return lvalue;
160             }
161 
162             public String getExpressionSymbol() {
163                 return "NOT";
164             }
165         };
166     }
167 
168     private static Number negate(Number left) {
169       Class clazz = left.getClass();
170         if (clazz == Integer.class) {
171             return new Integer(-left.intValue());
172         }
173         else if (clazz == Long.class) {
174             return new Long(-left.longValue());
175         }
176         else if (clazz ==  Float.class) {
177             return new Float(-left.floatValue());
178         }
179         else if (clazz == Double.class) {
180             return new Double(-left.doubleValue());
181         }
182         else if (clazz == BigDecimal.class) {
183           // We ussually get a big deciamal when we have Long.MIN_VALUE constant in the 
184           // Selector.  Long.MIN_VALUE is too big to store in a Long as a positive so we store it 
185           // as a Big decimal.  But it gets Negated right away.. to here we try to covert it back
186           // to a Long.          
187           BigDecimal bd = (BigDecimal)left;
188           bd = bd.negate();
189           
190           if( BD_LONG_MIN_VALUE.compareTo(bd)==0  ) {
191             return new Long(Long.MIN_VALUE);
192           }
193             return bd;
194         }
195         else {
196             throw new RuntimeException("Don't know how to negate: "+left);
197         }
198     }
199 
200     public UnaryExpression(Expression left) {
201         this.right = left;
202     }
203 
204     public Expression getRight() {
205         return right;
206     }
207 
208     public void setRight(Expression expression) {
209         right = expression;
210     }
211 
212     /**
213      * @see java.lang.Object#toString()
214      */
215     public String toString() {
216         return "(" + getExpressionSymbol() + " " + right.toString() + ")";
217     }
218 
219     /**
220      * TODO: more efficient hashCode()
221      *
222      * @see java.lang.Object#hashCode()
223      */
224     public int hashCode() {
225         return toString().hashCode();
226     }
227 
228     /**
229      * TODO: more efficient hashCode()
230      *
231      * @see java.lang.Object#equals(java.lang.Object)
232      */
233     public boolean equals(Object o) {
234 
235         if (o == null || !this.getClass().equals(o.getClass())) {
236             return false;
237         }
238         return toString().equals(o.toString());
239 
240     }
241 
242     /**
243      * Returns the symbol that represents this binary expression.  For example, addition is
244      * represented by "+"
245      *
246      * @return
247      */
248     abstract public String getExpressionSymbol();
249 
250 }