KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > presumo > jms > selector > JmsOperand


1 /**
2  * This file is part of Presumo.
3  *
4  * Presumo is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * Presumo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Presumo; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  *
19  * Copyright 2001 Dan Greff
20  */

21 package com.presumo.jms.selector;
22
23 import java.util.Hashtable JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import javax.jms.Message JavaDoc;
27
28 /**
29  * Base class for all nodes in the JMS parse tree. All functionality is
30  * package protected, and calling code should use the access point
31  * represented by <code>Parser</code>.
32  *
33  * @see com.presumo.jms.selector.Parser
34  * @author Dan Greff
35  */

36 public abstract class JmsOperand
37 {
38
39   protected static short evalNumber = Short.MIN_VALUE + 1;
40   protected short myEvalNumber = Short.MIN_VALUE;
41
42   protected JmsOperand lastEval = null;
43   private final boolean tracked;
44   protected int refcount;
45
46
47   /**
48    * keeps track of what children belong to which parent.
49    */

50   protected Hashtable JavaDoc parents = null;
51
52   static private ArrayList JavaDoc allInstances = new ArrayList JavaDoc();
53
54   // used for debugging only
55
static ArrayList JavaDoc getAllInstances() { return allInstances; };
56
57   static final void resetStoredEvals()
58   {
59     ++evalNumber;
60     // We have to reset everybodys myEvalNumber to a known state that won't
61
// have any conflicts. This is a very heavyweight operation but will
62
// only happen after aprox. Short.MAX_Value * 2 evaluations.
63
if (evalNumber == Short.MAX_VALUE) {
64
65       for (int i=0; i < allInstances.size(); i++) {
66         ( (JmsOperand) allInstances.get(i)).myEvalNumber = Short.MIN_VALUE;
67       }
68       evalNumber = Short.MIN_VALUE+1;
69     }
70   }
71
72   /**
73    * All subclasses of JmsOperand will be a modified version of a singleton
74    * which only allows one instance for every logical expression within
75    * the JVM.
76    */

77   protected JmsOperand()
78   {
79     this(true);
80   }
81
82   /**
83    * JmsOperands that represent data types have constant evaluation times
84    * and don't need to be tracked for the reset functionality. This makes
85    * the reset functionality more effecient. Furthermore, JmsDataType(s)
86    * can be created during the evaulation phase (i.e. through an identifier)
87    * If these instances were tracked there would be a memory leak.
88    */

89   protected JmsOperand(boolean tracked)
90   {
91     if (tracked) {
92       allInstances.add(this);
93     }
94     refcount = 1;
95     this.tracked = tracked;
96
97   }
98   
99   void incrementRefCount()
100   {
101     refcount++;
102   }
103   
104   /**
105    * Increments all reference counts in this tree
106    */

107   void incrementAllRefCounts()
108   {
109     refcount++;
110   }
111
112   /**
113    * Returns an enumeration of all nodes that point to this instance
114    * as a child.
115    */

116   protected final Enumeration JavaDoc allParents()
117   {
118     return parents.keys();
119   }
120
121   protected final int numberOfParents()
122   {
123     if (parents == null)
124       return 0;
125     else
126       return parents.size();
127   }
128
129   protected final boolean hasParent(JmsOperand parent) {
130     if (parents == null)
131       return false;
132     else
133       return (parents.get(parent) != null);
134   }
135
136   protected final void addParent(JmsOperand parent) {
137     if (parents == null) {
138       parents = new Hashtable JavaDoc(10);
139     }
140     parents.put(parent, new Integer JavaDoc(1));
141       
142   }
143
144   protected final void addParentRef(JmsOperand parent) {
145     if (parents == null)
146       throw new IllegalStateException JavaDoc("Filter error: addParentRef called with no parents");
147     Integer JavaDoc parentRefCount = (Integer JavaDoc) parents.get(parent);
148     
149     if (parentRefCount == null)
150       throw new IllegalStateException JavaDoc("Filter error: addParentRef called on non-existant parent: " + parent + " this: " + this);
151     
152     parentRefCount = new Integer JavaDoc(parentRefCount.intValue() + 1);
153     parents.remove(parent);
154     parents.put(parent, parentRefCount);
155   }
156
157   protected final void removeParent(JmsOperand parent) {
158     if (parents == null || parent == null) return;
159     
160     Integer JavaDoc references = (Integer JavaDoc) parents.get(parent);
161     if (references == null) return;
162
163     int temp = references.intValue() - 1;
164     if (temp == 0) {
165       parents.remove(parent);
166       if (parents.size() == 0)
167         parents = null;
168     }
169     else {
170       parents.remove(parent);
171       parents.put(parent, references);
172       references = new Integer JavaDoc(references.intValue() - 1);
173     }
174
175   }
176
177
178   /**
179    * Evaluates the expression tree represented by this node.
180    *
181    * @param Hashtable property values for all variables.
182    * @exception SelectorFalseException If the selector attempts to perform an
183    * illegal operation that could not be discovered at parse time, such as
184    * add two string properties.
185    */

186   abstract JmsOperand evaluate(Message JavaDoc msg) throws SelectorFalseException;
187
188   /**
189    * Method used to evaluate all logically equivelant espressions within
190    * a JVM only once.
191    *
192    * @param Hashtable property values for all variables.
193    * @exception SelectorFalseException If the selector attempts to perform an
194    * illegal operation that could not be discovered at parse time, such as
195    * add two string properties.
196    */

197   JmsOperand evaluateOnce(Message JavaDoc msg) throws SelectorFalseException
198   {
199     if (myEvalNumber != evalNumber) {
200                                      // Order is important here due to the
201
lastEval = evaluate(msg); // possible exception thrown by
202
myEvalNumber = evalNumber; // evaluate.
203
//System.out.println("Calculated first evaluation: " + lastEval + " for [" + this.toString() + "]");
204
} else {
205       //System.out.println("Using previous evaluation: " + lastEval + " for [" + this.toString() + "]");
206
}
207     return lastEval;
208   }
209
210   /**
211    * Returns a String representing the SQL form of the filter which is logically
212    * equivilant.
213    */

214   abstract String JavaDoc unParse();
215
216   /**
217    * Because of the singleton optimizations, code using this parser has to manually
218    * free up parse trees. This operation should only be called on the root node
219    * of a parse tree.
220    */

221   void delete()
222   {
223     delete(null);
224   }
225
226   protected void delete(JmsOperand fromParent)
227   {
228     // System.out.println("Deleting: "+this+ " from parent: " + fromParent + " Refcount=" + refcount);
229
if (refcount == 0) return;
230     refcount--;
231     
232     //
233
// removeParent keeps track of references per parent and will not
234
// do the actual removal if this parent/child relationship still
235
// exists in other expression trees that have not been deleted
236
// yet
237
//
238
removeParent(fromParent);
239     
240     if (refcount == 0) {
241
242       if (tracked)
243         allInstances.remove(this);
244     }
245   }
246
247
248   void printTree(int level) {
249     for (int i=0; i < level * 2; i++) System.out.print(" ");
250     System.out.print(this);
251     System.out.println(" Refcount[" + refcount +"]");
252   }
253   
254   abstract short getType();
255
256   static final short JMS_EQUALS = 0;
257   static final short JMS_INTEGER_LITERAL = 1;
258   static final short JMS_IDENTIFIER = 2;
259   static final short JMS_BOOLEAN_LITERAL = 3;
260   static final short JMS_STRING_LITERAL = 4;
261   static final short JMS_FLOAT_LITERAL = 5;
262   static final short JMS_LESS = 6;
263   static final short JMS_GREATER = 7;
264   static final short JMS_NOT = 8;
265   static final short JMS_BINARY_OR = 9;
266   static final short JMS_BINARY_AND = 10;
267   static final short JMS_IS = 11;
268   static final short JMS_BINARY_MULT = 12;
269   static final short JMS_BINARY_DIV = 13;
270   static final short JMS_BINARY_ADD = 14;
271   static final short JMS_BINARY_SUB = 15;
272   static final short JMS_LIKE = 16;
273
274 }
275
276
277
278
279
280
281
282
Popular Tags