KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > sqls > impl > StatementMetaData


1 /*
2  * Copyright 2003, 2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15
16  */

17 package org.apache.ws.jaxme.sqls.impl;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.ws.jaxme.sqls.BooleanConstraint;
26 import org.apache.ws.jaxme.sqls.Case;
27 import org.apache.ws.jaxme.sqls.Column;
28 import org.apache.ws.jaxme.sqls.ColumnReference;
29 import org.apache.ws.jaxme.sqls.CombinedConstraint;
30 import org.apache.ws.jaxme.sqls.DeleteStatement;
31 import org.apache.ws.jaxme.sqls.Expression;
32 import org.apache.ws.jaxme.sqls.Function;
33 import org.apache.ws.jaxme.sqls.InsertStatement;
34 import org.apache.ws.jaxme.sqls.JoinReference;
35 import org.apache.ws.jaxme.sqls.Parts;
36 import org.apache.ws.jaxme.sqls.RawSQLCode;
37 import org.apache.ws.jaxme.sqls.SelectStatement;
38 import org.apache.ws.jaxme.sqls.SetStatement;
39 import org.apache.ws.jaxme.sqls.Table;
40 import org.apache.ws.jaxme.sqls.TableReference;
41 import org.apache.ws.jaxme.sqls.UpdateStatement;
42 import org.apache.ws.jaxme.sqls.Value;
43
44
45 public class StatementMetaData {
46     public static class LocalData {
47         private boolean hasWhereClause;
48         
49         public boolean hasWhereClause() {
50             return hasWhereClause;
51         }
52
53         public void setWhereClause(boolean pHasWhereClause) {
54             hasWhereClause = pHasWhereClause;
55         }
56     }
57
58     private final Map JavaDoc aliases = new HashMap JavaDoc();
59     private final Map JavaDoc columnNames = new HashMap JavaDoc();
60
61     private final List JavaDoc tables = new ArrayList JavaDoc();
62
63     public StatementMetaData(DeleteStatement pQuery) {
64         addTable(pQuery.getTableReference());
65         addCombinedConstraint(pQuery.getWhere());
66         createTableAliases();
67         createColumnNames();
68     }
69
70     public StatementMetaData(UpdateStatement pQuery, ColumnReference[] pColumns) {
71         addSetStatement(pQuery, pColumns);
72         addCombinedConstraint(pQuery.getWhere());
73         createTableAliases();
74         createColumnNames();
75     }
76
77     public StatementMetaData(InsertStatement pQuery, ColumnReference[] pColumns) {
78         addSetStatement(pQuery, pColumns);
79         SelectStatement subSelect = pQuery.getSubSelect();
80         if (subSelect != null) {
81             addSelectStatement(subSelect);
82         }
83         createTableAliases();
84         createColumnNames();
85     }
86
87     public StatementMetaData(SelectStatement pQuery) {
88       addSelectStatement(pQuery);
89       createTableAliases();
90       createColumnNames();
91     }
92
93     protected void addSetStatement(SetStatement pQuery, ColumnReference[] pColumns) {
94         addTable(pQuery.getTableReference());
95         for (int i = 0; i < pColumns.length; i++) {
96             addColumn(pColumns[i]);
97         }
98         for (Iterator JavaDoc iter = pQuery.getSetValues(); iter.hasNext(); ) {
99             SetStatement.SetValue setValue = (SetStatement.SetValue) iter.next();
100             addPart(setValue.getValue());
101             addPart(setValue.getColumnReference());
102         }
103     }
104
105     protected void addTable(TableReference pTableReference) {
106         Table t = pTableReference.getTable();
107         Table.Name alias = pTableReference.getAlias();
108         if (alias != null) {
109             if (aliases.containsKey(alias.getName())) {
110                 throw new IllegalStateException JavaDoc("The alias " + alias +
111                         " is used twice ");
112             }
113             aliases.put(alias.getName(), pTableReference);
114         }
115         tables.add(pTableReference);
116         if (t instanceof ViewImpl) {
117             ViewImpl v = (ViewImpl) t;
118             addSelectStatement(v.getViewStatement());
119         }
120             
121         if (pTableReference instanceof JoinReference) {
122             addCombinedConstraint(((JoinReference) pTableReference).getOn());
123         }
124     }
125
126     protected void addSelectStatement(SelectStatement pQuery) {
127         for (Iterator JavaDoc tableIter = pQuery.getSelectTableReferences(); tableIter.hasNext(); ) {
128             TableReference ref = (TableReference) tableIter.next();
129             addTable(ref);
130         }
131         addCombinedConstraint(pQuery.getWhere());
132         for (Iterator JavaDoc iter = pQuery.getResultColumns(); iter.hasNext(); ) {
133             addPart(iter.next());
134         }
135         for (Iterator JavaDoc iter = pQuery.getOrderColumns(); iter.hasNext(); ) {
136             SelectStatement.OrderColumn orderColumn = (SelectStatement.OrderColumn) iter.next();
137             addPart(orderColumn.getColumn());
138         }
139     }
140
141     protected void addColumn(ColumnReference pColumn) {
142         if (pColumn instanceof VirtualColumn) {
143             VirtualColumn vc = (VirtualColumn) pColumn;
144             Object JavaDoc o = vc.getValue();
145             if (o instanceof SelectStatement) {
146                 addSelectStatement((SelectStatement) o);
147             } else if (o instanceof Function) {
148                 addParts((Function) o);
149             } else if (o instanceof String JavaDoc) {
150                 // Do nothing
151
} else {
152                 throw new IllegalStateException JavaDoc("Invalid type of VirtualColumn: " + o);
153             }
154             addColumnName(vc.getName());
155         }
156     }
157
158     private void addColumnName(Column.Name pName) {
159         String JavaDoc key = pName.toString().toUpperCase();
160         Integer JavaDoc num = (Integer JavaDoc) columnNames.get(key);
161         if (num == null) {
162             num = new Integer JavaDoc(1);
163         } else {
164             num = new Integer JavaDoc(num.intValue() + 1);
165         }
166         columnNames.put(key, num);
167     }
168
169     protected void addCombinedConstraint(CombinedConstraint pConstraint) {
170       for (Iterator JavaDoc iter = pConstraint.getParts(); iter.hasNext(); ) {
171         Object JavaDoc o = iter.next();
172         if (o instanceof CombinedConstraint) {
173           addCombinedConstraint((CombinedConstraint) o);
174         } else if (o instanceof BooleanConstraint) {
175           addBooleanConstraint((BooleanConstraint) o);
176         } else {
177           throw new IllegalStateException JavaDoc("Invalid part type in CombinedConstraint: " + o);
178         }
179       }
180     }
181
182     protected void addPart(Object JavaDoc pPart) {
183         if (pPart instanceof SelectStatement) {
184             addSelectStatement((SelectStatement) pPart);
185         } else if (pPart instanceof CombinedConstraint) {
186             addCombinedConstraint((CombinedConstraint) pPart);
187         } else if (pPart instanceof Function) {
188             addParts((Function) pPart);
189         } else if (pPart instanceof Expression) {
190             addParts((Expression) pPart);
191         } else if (pPart instanceof ColumnReference
192                 || pPart instanceof Value
193                 || pPart instanceof RawSQLCode) {
194             // Ignore me
195
} else if (pPart instanceof Case) {
196             Case casePart = (Case) pPart;
197             addPart(casePart.getCheckedValue());
198             Object JavaDoc o = casePart.getElseValue();
199             if (o != null) {
200                 addPart(o);
201             }
202             Case.When[] whens = casePart.getWhens();
203             for (int i = 0; i < whens.length; i++) {
204                 Case.When when = whens[i];
205                 addPart(when.getCondition());
206                 addPart(when.getValue());
207             }
208         } else if (pPart.getClass().isArray()) {
209             Object JavaDoc[] o = (Object JavaDoc[]) pPart;
210             for (int i = 0; i < o.length; i++) {
211                 addPart(o[i]);
212             }
213         } else {
214             throw new IllegalStateException JavaDoc("Invalid part type: " + pPart);
215         }
216     }
217
218     protected void addParts(Parts pParts) {
219         for (Iterator JavaDoc iter = pParts.getParts(); iter.hasNext(); ) {
220             addPart(iter.next());
221         }
222     }
223
224     protected void addBooleanConstraint(BooleanConstraint pConstraint) {
225       BooleanConstraint.Type type = pConstraint.getType();
226       if (BooleanConstraint.Type.EQ.equals(type)
227           || BooleanConstraint.Type.EXISTS.equals(type)
228           || BooleanConstraint.Type.GE.equals(type)
229           || BooleanConstraint.Type.GT.equals(type)
230           || BooleanConstraint.Type.IN.equals(type)
231           || BooleanConstraint.Type.ISNULL.equals(type)
232           || BooleanConstraint.Type.LE.equals(type)
233           || BooleanConstraint.Type.LIKE.equals(type)
234           || BooleanConstraint.Type.LT.equals(type)
235           || BooleanConstraint.Type.NE.equals(type)
236           || BooleanConstraint.Type.BETWEEN.equals(type)) {
237         addParts(pConstraint);
238       } else {
239         throw new IllegalStateException JavaDoc("Invalid part type in BooleanConstraint: " + type);
240       }
241     }
242
243     protected String JavaDoc getUniqueAlias(String JavaDoc pSuggestion, Map JavaDoc pAliases) {
244         String JavaDoc prefix;
245         if (pSuggestion == null) {
246             prefix = "";
247         } else {
248             prefix = pSuggestion;
249         }
250         if (!pAliases.containsKey(prefix)) {
251             return prefix;
252         }
253         for (char c = '0'; c <= '9'; c++) {
254             String JavaDoc s = prefix + c;
255             if (!pAliases.containsKey(s)) {
256                 return s;
257             }
258         }
259         for (char c = 'A'; c <= 'Z'; c++) {
260             String JavaDoc s = prefix + c;
261             if (!pAliases.containsKey(s)) {
262                 return s;
263             }
264         }
265         return getUniqueAlias(prefix + '0', pAliases);
266     }
267
268     protected void createTableAliases() {
269         if (tables.size() > 1) {
270             // Make sure that all tables have an alias
271
for (Iterator JavaDoc iter = tables.iterator(); iter.hasNext(); ) {
272                 TableReference tableReference = (TableReference) iter.next();
273                 if (tableReference.getAlias() == null) {
274                     String JavaDoc alias = getUniqueAlias(tableReference.getTable().getName().getName(), aliases);
275                     aliases.put(alias, tableReference);
276                     if (!alias.equals(tableReference.getTable().getName().getName())) {
277                         tableReference.setAlias(alias);
278                     }
279                 }
280             }
281         }
282     }
283
284     protected void createColumnNames() {
285       // Create a Map of all column names, that may be referenced.
286
// maps key is the column name, and the maps value is the
287
// number of possible references. In other words: If an entry
288
// in the map has a value > 1, then its column name must be
289
// qualified, because it is used in multiple tables.
290
for (int i = 0; i < tables.size(); i++) {
291         TableReference table = (TableReference) tables.get(i);
292         for (Iterator JavaDoc iter = table.getTable().getColumns(); iter.hasNext(); ) {
293           Column col = (Column) iter.next();
294           addColumnName(col.getName());
295         }
296       }
297     }
298
299     public Map JavaDoc getColumnNames() {
300       return columnNames;
301     }
302   }
Popular Tags