KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > StatementTree


1 /**
2  * com.mckoi.database.StatementTree 08 Sep 2001
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database;
26
27 import java.util.HashMap JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.ListIterator JavaDoc;
32 import java.math.BigDecimal JavaDoc;
33
34 /**
35  * A serializable container class for a parsed query language statement. The
36  * structure of the tree is entirely dependant on the grammar that was used
37  * to create the tree. This object is a convenient form that can be cached and
38  * serialized to be stored.
39  * <p>
40  * Think of this as the model of a query after the grammar has been parsed
41  * and before it is evaluated.
42  *
43  * @author Tobias Downer
44  */

45
46 public final class StatementTree implements java.io.Serializable JavaDoc, Cloneable JavaDoc {
47
48   static final long serialVersionUID = -5907058730080713004L;
49
50   /**
51    * The class of statement this is. This is set to one of the query objects
52    * from the com.mckoi.database.interpret package. For example, if this is
53    * a select statement then it points to
54    * 'com.mckoi.database.interpret.Select'.
55    */

56   private String JavaDoc statement_class;
57
58   /**
59    * A map that maps from the name of the tree element to the object
60    * that contains information about. For example, if this is an SQL
61    * SELECT statement then entries in this map may be;
62    * <pre>
63    * "columns" -> sql.SelectColumn[]
64    * "distinct" -> new Boolean(true)
65    * </pre>
66    */

67   private HashMap JavaDoc map;
68
69   /**
70    * Constructs the StatementTree.
71    *
72    * @param statement_class the name of the class that interpretes this
73    * statement (eg. com.mckoi.database.interpret.Select).
74    */

75   public StatementTree(String JavaDoc statement_class) {
76     if (!statement_class.startsWith("com.mckoi.database.interpret.")) {
77       throw new Error JavaDoc("statement_class must be in the " +
78                       "com.mckoi.database.interpret package.");
79     }
80     this.statement_class = statement_class;
81     map = new HashMap JavaDoc();
82   }
83
84   /**
85    * Puts a new entry into the statement tree map.
86    */

87   public void putObject(String JavaDoc entry_name, Object JavaDoc ob) {
88     if (entry_name == null) {
89       throw new NullPointerException JavaDoc("entry_name is null.");
90     }
91     // Check on is derived from a known class
92
if (ob == null ||
93         ob instanceof Boolean JavaDoc ||
94         ob instanceof String JavaDoc ||
95         ob instanceof BigDecimal JavaDoc ||
96         ob instanceof Variable ||
97         ob instanceof Integer JavaDoc ||
98         ob instanceof TObject ||
99         ob instanceof TType ||
100         ob instanceof Expression ||
101         ob instanceof Expression[] ||
102         ob instanceof List JavaDoc ||
103         ob instanceof StatementTree ||
104         ob instanceof StatementTreeObject) {
105
106       Object JavaDoc v = map.put(entry_name, ob);
107       if (v != null) {
108         throw new Error JavaDoc("Entry '" + entry_name +
109                         "' is already present in this tree.");
110       }
111
112     }
113     else {
114       throw new Error JavaDoc("ob of entry '" + entry_name +
115                       "' is not derived from a recognised class");
116     }
117
118   }
119
120   /**
121    * Puts a boolean into the statement tree map.
122    */

123   public void putBoolean(String JavaDoc entry_name, boolean b) {
124     putObject(entry_name, b ? Boolean.TRUE : Boolean.FALSE);
125   }
126
127   /**
128    * Puts an integer into the statement tree map.
129    */

130   public void putInt(String JavaDoc entry_name, int v) {
131     putObject(entry_name, new Integer JavaDoc(v));
132   }
133
134
135   /**
136    * Gets an object entry from the statement tree.
137    */

138   public Object JavaDoc getObject(String JavaDoc entry_name) {
139     return map.get(entry_name);
140   }
141
142   /**
143    * Gets a boolean entry from the statement tree.
144    */

145   public boolean getBoolean(String JavaDoc entry_name) {
146     Object JavaDoc ob = map.get(entry_name);
147     return ((Boolean JavaDoc) ob).booleanValue();
148   }
149
150   /**
151    * Gets an integer entry from the statement tree.
152    */

153   public int getInt(String JavaDoc entry_name) {
154     Object JavaDoc ob = map.get(entry_name);
155     return ((Integer JavaDoc) ob).intValue();
156   }
157
158
159
160
161   /**
162    * Gets the interpreter class that services this tree.
163    */

164   public String JavaDoc getClassName() {
165     return statement_class;
166   }
167
168   /**
169    * For each expression in this StatementTree this method will call the
170    * 'prepare' method in each expression. The prepare method is intended to
171    * mutate each expression so that references can be qualified, sub-queries
172    * can be resolved, and variable substitutions can be substituted.
173    */

174   public void prepareAllExpressions(ExpressionPreparer preparer)
175                                                  throws DatabaseException {
176     Iterator JavaDoc i = map.values().iterator();
177
178     while (i.hasNext()) {
179       Object JavaDoc v = i.next();
180       if (v != null) {
181         prepareExpressionsInObject(v, preparer);
182       }
183     }
184
185   }
186
187   private void prepareExpressionsInObject(Object JavaDoc v,
188                      ExpressionPreparer preparer) throws DatabaseException {
189     // If expression
190
if (v instanceof Expression) {
191       ((Expression) v).prepare(preparer);
192     }
193     // If an array of expression
194
else if (v instanceof Expression[]) {
195       Expression[] exp_list = (Expression[]) v;
196       for (int n = 0; n < exp_list.length; ++n) {
197         exp_list[n].prepare(preparer);
198       }
199     }
200     // If a StatementTreeObject then can use the 'prepareExpressions' method.
201
else if (v instanceof StatementTreeObject) {
202       StatementTreeObject stob = (StatementTreeObject) v;
203       stob.prepareExpressions(preparer);
204     }
205     // If a StatementTree then can use the prepareAllExpressions method.
206
else if (v instanceof StatementTree) {
207       StatementTree st = (StatementTree) v;
208       st.prepareAllExpressions(preparer);
209     }
210     // If a list of objects,
211
else if (v instanceof List JavaDoc) {
212       List JavaDoc list = (List JavaDoc) v;
213       for (int n = 0; n < list.size(); ++n) {
214         Object JavaDoc ob = list.get(n);
215         prepareExpressionsInObject(ob, preparer);
216       }
217     }
218   }
219
220   /**
221    * Clones a single object.
222    */

223   public static Object JavaDoc cloneSingleObject(Object JavaDoc entry)
224                                          throws CloneNotSupportedException JavaDoc {
225
226     // Immutable entries,
227
if (entry == null ||
228         entry instanceof TObject ||
229         entry instanceof TType ||
230         entry instanceof Boolean JavaDoc ||
231         entry instanceof String JavaDoc ||
232         entry instanceof BigDecimal JavaDoc ||
233         entry instanceof Integer JavaDoc) {
234       // Immutable entries
235
}
236     else if (entry instanceof Expression) {
237       entry = ((Expression) entry).clone();
238     }
239     else if (entry instanceof Expression[]) {
240       Expression[] exps = (Expression[]) ((Expression[]) entry).clone();
241       // Clone each element of the array
242
for (int n = 0; n < exps.length; ++n) {
243         exps[n] = (Expression) exps[n].clone();
244       }
245       entry = exps;
246     }
247     else if (entry instanceof Variable) {
248       entry = ((Variable) entry).clone();
249     }
250     else if (entry instanceof StatementTreeObject) {
251       entry = ((StatementTreeObject) entry).clone();
252     }
253     else if (entry instanceof StatementTree) {
254       entry = ((StatementTree) entry).clone();
255     }
256     else if (entry instanceof List JavaDoc) {
257       // Clone the list by making a new ArrayList and adding a cloned version
258
// of each element into it.
259
List JavaDoc list = (List JavaDoc) entry;
260       ArrayList JavaDoc cloned_list = new ArrayList JavaDoc(list.size());
261       Iterator JavaDoc i = list.iterator();
262       while (i.hasNext()) {
263         cloned_list.add(cloneSingleObject(i.next()));
264       }
265       entry = cloned_list;
266     }
267     else {
268       throw new CloneNotSupportedException JavaDoc(entry.getClass().toString());
269     }
270
271     return entry;
272   }
273
274   /**
275    * Performs a deep clone of this object, calling 'clone' on any elements
276    * that are mutable or shallow copying immutable members.
277    */

278   public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
279     // Shallow clone first
280
StatementTree v = (StatementTree) super.clone();
281     // Clone the map
282
HashMap JavaDoc cloned_map = new HashMap JavaDoc();
283     v.map = cloned_map;
284
285     // For each key, clone the entry
286
Iterator JavaDoc i = map.keySet().iterator();
287     while (i.hasNext()) {
288       Object JavaDoc key = i.next();
289       Object JavaDoc entry = map.get(key);
290
291       entry = cloneSingleObject(entry);
292
293       cloned_map.put(key, entry);
294     }
295
296     return v;
297   }
298
299   /**
300    * For diagnostic.
301    */

302   public String JavaDoc toString() {
303     return "[ " + getClassName() + " [ " + map + " ] ]";
304   }
305
306 }
307
Popular Tags