KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > parser > NativeQueryParser


1 package com.jofti.parser;
2
3 import java.io.IOException JavaDoc;
4 import java.io.Reader JavaDoc;
5 import java.io.StringReader JavaDoc;
6 import java.util.ArrayList JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.LinkedHashMap JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Stack JavaDoc;
13
14 import org.apache.commons.logging.Log;
15 import org.apache.commons.logging.LogFactory;
16
17 import antlr.collections.AST;
18
19 import com.jofti.api.IndexQuery;
20 import com.jofti.core.INameSpaceAware;
21 import com.jofti.core.IParsedQuery;
22 import com.jofti.core.IPredicate;
23 import com.jofti.exception.JoftiException;
24 import com.jofti.introspect.ClassIntrospector;
25 import com.jofti.parser.sql.SQLQueryParser;
26 import com.jofti.query.EJBQuery;
27 import com.jofti.query.SQLQuery;
28 import com.jofti.util.ReflectionUtil;
29
30 public class NativeQueryParser extends AbstractParser implements IQueryParser {
31
32     
33      private static Log log = LogFactory.getLog(ParserManager.class);
34      
35
36      
37     public NativeQueryParser(final int cachedQueries,ClassIntrospector introspector){
38         super(cachedQueries,introspector);
39      }
40      
41    public NativeQueryParser(ClassIntrospector introspector){
42             this(100, introspector);
43          }
44     
45    public IParsedQuery parseQuery(IndexQuery originalQuery)
46     throws JoftiException {
47        try{
48         return parseQuery(((SQLQuery)originalQuery).getQuery(),originalQuery);
49        } catch (ClassCastException JavaDoc ce){
50            throw new JoftiException("Class Query is no longer supported - use SQLQuery");
51        }
52    }
53    
54    
55    public IParsedQuery getQuery(String JavaDoc name){
56
57     ParsedQuery query = null;
58     synchronized (lockObject) {
59         query = (ParsedQuery) compiledQueries.get(name);
60     }
61     if (query != null){
62         SQLQueryWrapper wrapper = new SQLQueryWrapper(query);
63
64
65         return wrapper;
66     }
67     return query;
68
69 }
70         
71    public IParsedQuery parseQuery(String JavaDoc name, IndexQuery originalQuery)
72     throws JoftiException {
73
74 // get text string
75
SQLQuery tempQuery = (SQLQuery) originalQuery;
76
77
78 ParsedQuery parsedQuery = null;
79
80 //see if query is already cached - this ignores parameters - and only checks the String format
81
synchronized (lockObject) {
82     parsedQuery = (ParsedQuery) compiledQueries.get(name);
83 }
84
85 // we have a cached query here
86
if (parsedQuery == null) {
87     // we have to parse the query
88
if (log.isDebugEnabled()) {
89         log.debug("parsing new query " + ((SQLQuery) originalQuery).getQuery());
90     }
91     // parse the query
92

93     parsedQuery = parseQuery(new ParsedQuery(), tempQuery);
94     
95     //add returned query into cache
96
synchronized (lockObject) {
97         compiledQueries.put(name, parsedQuery);
98     }
99 }
100
101 SQLQueryWrapper wrapper = new SQLQueryWrapper(parsedQuery);
102
103 //add in the name parameters if we have any
104

105 return wrapper;
106
107
108 }
109
110
111      public ParsedQuery parseQuery(ParsedQuery parsedQuery, IndexQuery originalQuery) throws JoftiException{
112             
113             
114         
115             String JavaDoc query =((SQLQuery) originalQuery).getQuery();
116             // first get an input Steam
117
Reader JavaDoc input =null;
118             try {
119             input = new StringReader JavaDoc(query);
120             
121             CommonLexer lexer = new CommonLexer(input);
122             
123             SQLQueryParser parser = new SQLQueryParser(lexer);
124             parser.statement();
125             
126             
127             // get the AST
128
AST orderStatement =null;
129             AST ast = parser.getAST();
130             AST selectStatement = null;
131
132         
133             if ( ast == null || ast.getFirstChild() == null){
134                 
135                 throw new JoftiException("SQLQuery statement '" + formatQueryForError(query) + "' is not of format 'select <classname(s)> [from <namespace>] where <condition(s)>'");
136             }
137             if (log.isDebugEnabled()){
138                 log.debug(ast.toStringTree());
139              }
140             AST expression =null;
141             // first try and process order
142
if (ast.getType() == CommonLexerTokenTypes.ORDER){
143                 orderStatement =ast;
144                 //mark for later
145
ast = ast.getFirstChild();
146             }
147             
148             
149             if (ast.getFirstChild().getType() == CommonLexerTokenTypes.FROM){
150                 String JavaDoc nameSpace = parseNameSpace(ast.getFirstChild().getFirstChild().getNextSibling());
151                 
152                 if (originalQuery instanceof INameSpaceAware){
153                     ((INameSpaceAware)originalQuery).setNameSpace(nameSpace);
154                 }
155                 parsedQuery.setNameSpace(nameSpace);
156                 selectStatement = ast.getFirstChild().getFirstChild();
157                 expression = ast.getFirstChild().getNextSibling();
158             }else{
159                 selectStatement = ast.getFirstChild();
160                 // now get the stuff out of the where clause
161

162                  expression = selectStatement.getNextSibling();
163             }
164             
165             // get the classes from here
166
AST classes= selectStatement.getFirstChild();
167             if (classes == null){
168                 throw new JoftiException("SQLQuery must contain a single className with no alias or every className must have an alias in query:"+ formatQueryForError(query));
169
170             }
171             
172             parsedQuery = parseClasses(classes, parsedQuery);
173             
174
175             // we have classes and aliases
176

177             // set a number of return classes
178
if(parsedQuery.getAliasMap() != null && parsedQuery.getAliasMap().size()>0){
179                 Iterator JavaDoc it = parsedQuery.getAliasMap().values().iterator();
180                 int size =parsedQuery.getAliasMap().size();
181                 for (int i = 0;i<size;i++){
182                     Object JavaDoc obj = it.next();
183                     parsedQuery.getFieldReturnMap().put(obj,null);
184                 }
185             }
186
187             
188             if (log.isDebugEnabled()){
189
190             log.debug(expression.getText());
191             }
192             
193             Stack JavaDoc stack = new Stack JavaDoc();
194             
195             stack = parseWherePredicates(expression,stack,parsedQuery);
196             
197              if (log.isDebugEnabled()){
198                  log.debug(stack);
199              }
200             
201             // we need to reverse the stack here
202
Stack JavaDoc temp = new Stack JavaDoc();
203             
204             boolean predicateElement =false;
205             
206             while (stack.size() !=0){
207                 Object JavaDoc obj = stack.pop();
208                 if (predicateElement){
209                     if (obj instanceof IPredicate){
210                         throw new JoftiException("SQLQuery not formatted correctly a join operator must seperate two predicates");
211                     }
212                     predicateElement =false;
213                 } else{
214                     if (obj instanceof Operator){
215                         throw new JoftiException("SQLQuery not formatted correctly a join operator must seperate two predicates");
216                     }
217                     predicateElement =true;
218                 }
219                 temp.push(obj);
220             }
221
222             
223             parsedQuery.setPredicates(temp);
224             
225             if (orderStatement != null){
226                 parsedQuery = parseOrder(orderStatement, parsedQuery);
227             }
228             } catch (Throwable JavaDoc t){
229                 if (t instanceof JoftiException){
230                     throw (JoftiException)t;
231                 }else{
232                     throw new JoftiException("SQLQuery statement '" + formatQueryForError(query) + "' is not of format 'select <classname(s)> where <condition(s)>'",t);
233                 }
234                 
235             }finally {
236                 try {
237                     if (input != null){
238                         input.close();
239                     }
240                 } catch (IOException JavaDoc e){
241                     // we do not care here
242
}
243             }
244             
245             
246             return parsedQuery;
247             
248             
249         }
250
251        
252     
253         
254         private String JavaDoc parseNameSpace(AST expression) throws JoftiException{
255             
256             String JavaDoc nameSpace ="";
257             while (expression != null){
258
259                     nameSpace = nameSpace + expression.getText();
260                 expression = expression.getNextSibling();
261                 
262             }
263             if (log.isDebugEnabled()){
264                 log.debug("name space:" + nameSpace);
265             }
266             return nameSpace;
267         }
268
269     
270
271         
272         private ParsedQuery parseClasses(AST classes, ParsedQuery query) throws JoftiException{
273             //first check if classes has any children as this tells us if as has been used
274
AST node = classes;
275             if (node.getType() != CommonLexerTokenTypes.ALIAS_IDENTIFIER){
276                 Class JavaDoc clazz = null;
277                 try{
278                     clazz = ReflectionUtil.classForName(node.getText());
279                 }catch (Exception JavaDoc e){
280                     throw new JoftiException("Class "+ node.getText() + " cannot be constructed in query",e);
281                 }
282                 query.setClassName(clazz);
283             }else{
284                 do{
285                     // we have some alias
286
if (log.isDebugEnabled()){
287                     log.debug("alias found for class " + node.getFirstChild().toStringTree() + " of " +node.getFirstChild().getNextSibling().toStringTree());
288                     }
289                     Class JavaDoc clazz =null;
290                     try {
291                         clazz = ReflectionUtil.classForName(node.getFirstChild().getText());
292                     } catch (Exception JavaDoc e){
293                         throw new JoftiException("Class "+ node.getFirstChild().getText() + " cannot be parsed in query",e);
294                     }
295                     query.getAliasMap().put(node.getFirstChild().getNextSibling().getText(),clazz );
296                     node = node.getNextSibling();
297                 }while (node != null);
298             }
299             return query;
300             
301             
302         }
303         
304         private String JavaDoc formatQueryForError(String JavaDoc query){
305             if (query.lastIndexOf(";") != query.length()){
306                 return query.substring(0,query.length()-1);
307             }else{
308                 return query;
309             }
310         }
311
312 }
313
Popular Tags