KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_ejb > lib > EjbqlVariableVisitor


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 1999-2004 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: EjbqlVariableVisitor.java,v 1.25 2005/01/22 01:42:53 rhs Exp $
23  * --------------------------------------------------------------------------
24  */

25 package org.objectweb.jonas_ejb.lib;
26
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Stack JavaDoc;
32
33 import org.objectweb.jonas_ejb.container.TraceEjb;
34 import org.objectweb.jonas_ejb.deployment.api.DeploymentDescEjb2;
35 import org.objectweb.jonas_ejb.deployment.ejbql.ASTAbstractSchemaName;
36 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCollectionMemberDeclaration;
37 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCollectionValuedPathExpression;
38 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEJBQL;
39 import org.objectweb.jonas_ejb.deployment.ejbql.ASTFromClause;
40 import org.objectweb.jonas_ejb.deployment.ejbql.ASTIdentifier;
41 import org.objectweb.jonas_ejb.deployment.ejbql.ASTPath;
42 import org.objectweb.jonas_ejb.deployment.ejbql.ASTRangeVariableDeclaration;
43 import org.objectweb.jonas_ejb.deployment.ejbql.ParseException;
44 import org.objectweb.jonas_ejb.deployment.ejbql.SimpleNode;
45 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSelectClause;
46 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSelectExpression;
47 import org.objectweb.jonas_ejb.deployment.ejbql.ASTAggregateSelectExpression;
48 import org.objectweb.jonas_ejb.deployment.ejbql.ASTIdentificationVariable;
49 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCmpPathExpression;
50 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSingleValuedCmrPathExpression;
51 import org.objectweb.jonas_ejb.deployment.ejbql.ASTSingleValuedPathExpression;
52 import org.objectweb.jonas_ejb.deployment.ejbql.ASTWhereClause;
53 import org.objectweb.jonas_ejb.deployment.ejbql.ASTConditionalExpression;
54 import org.objectweb.jonas_ejb.deployment.ejbql.ASTConditionalTerm;
55 import org.objectweb.jonas_ejb.deployment.ejbql.ASTConditionalFactor;
56 import org.objectweb.jonas_ejb.deployment.ejbql.ASTBetweenExpression;
57 import org.objectweb.jonas_ejb.deployment.ejbql.ASTInExpression;
58 import org.objectweb.jonas_ejb.deployment.ejbql.ASTLikeExpression;
59 import org.objectweb.jonas_ejb.deployment.ejbql.ASTNullComparisonExpression;
60 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEmptyCollectionComparisonExpression;
61 import org.objectweb.jonas_ejb.deployment.ejbql.ASTCollectionMemberExpression;
62 import org.objectweb.jonas_ejb.deployment.ejbql.ASTComparisonExpression;
63 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticExpression;
64 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticTerm;
65 import org.objectweb.jonas_ejb.deployment.ejbql.ASTArithmeticFactor;
66 import org.objectweb.jonas_ejb.deployment.ejbql.ASTStringExpression;
67 import org.objectweb.jonas_ejb.deployment.ejbql.ASTDatetimeExpression;
68 import org.objectweb.jonas_ejb.deployment.ejbql.ASTBooleanExpression;
69 import org.objectweb.jonas_ejb.deployment.ejbql.ASTEntityBeanExpression;
70 import org.objectweb.jonas_ejb.deployment.ejbql.ASTFunctionsReturningStrings;
71 import org.objectweb.jonas_ejb.deployment.ejbql.ASTFunctionsReturningNumerics;
72 import org.objectweb.jonas_ejb.deployment.ejbql.ASTOrderByClause;
73 import org.objectweb.jonas_ejb.deployment.ejbql.ASTOrderByItem;
74 import org.objectweb.jorm.metainfo.api.Class;
75 import org.objectweb.jorm.metainfo.api.Manager;
76 import org.objectweb.medor.api.Field;
77 import org.objectweb.medor.api.MedorException;
78 import org.objectweb.medor.query.api.QueryTree;
79 import org.objectweb.medor.query.api.QueryTreeField;
80 import org.objectweb.medor.query.jorm.lib.ClassExtent;
81 import org.objectweb.medor.query.jorm.lib.PNameField;
82 import org.objectweb.medor.query.jorm.lib.QueryBuilder;
83 import org.objectweb.medor.query.lib.QueryTreePrinter;
84 import org.objectweb.medor.filter.lib.BasicFieldOperand;
85 import org.objectweb.util.monolog.api.BasicLevel;
86
87 /**
88  * Implementation of a visitor that creates a map of pairs [name,QueryTreeField]
89  * for all defined identifiers of the query.
90  * @author Christophe Ney [cney@batisseurs.com] Initial developper
91  * @author Helene Joanin:
92  * <ul>
93  * <li>In the visit of the SELECT clause, do not forget to add the id
94  * in the ids structure if its not present. Indeed, the definition of
95  * this id is done in the FROM clause which is visited later. This is
96  * needed for ejbSelect query which allows path_expression in the SELECT
97  * clause.</li>
98  * <li>Use of the NavigatorNodeFactory.getIn() for IN in the FROM part
99  * instead of NavigatorNodeFactory.getNavigatorNode()</li>
100  * <li>Some modifications needed to take into account CollectionValuedPathExpression
101  * for the member of and is empty operators.</li>
102  * <li>For the MemberOf implementation, do not more build an unique
103  * QueryTree, but a Map of pairs [name,QueryTreeField]</li>
104  * <li>Add the ORDER BY clause.</li>
105  * <li>Take into account the new interface of NavigatorNodeFactory.</li>
106  * <li>IS EMPTY / IS NOT EMPTY</li>
107  * <li>Take into account the EJBQL version 2.1 syntax.</li>
108  * </ul>
109  */

110 public class EjbqlVariableVisitor extends EjbqlAbstractVisitor {
111
112     /**
113      * The JORM Manager
114      */

115     private Manager manager;
116
117     /**
118      * The Deployment Descriptors information
119      */

120     private DeploymentDescEjb2 dd;
121
122     /**
123      * ids structure for all the defined identifiers of the query,.
124      */

125     private HashMap JavaDoc ids = new HashMap JavaDoc();
126
127     /**
128      * field for each defined identifiers of the query.
129      */

130     private HashMap JavaDoc fields = new HashMap JavaDoc();
131
132     private QueryBuilder qb = new QueryBuilder();
133
134     /**
135      * track which paths are collections
136      */

137     private HashSet JavaDoc collections = new HashSet JavaDoc();
138
139     /**
140      * constructor
141      * @param ejbql root of the lexical tree
142      * @param dd Deployment Descriptor
143      * @param qb query builder used to navigate paths
144      * @throws Exception when error parsing
145      */

146
147     public EjbqlVariableVisitor(ASTEJBQL ejbql, DeploymentDescEjb2 dd, QueryBuilder qb) throws Exception JavaDoc {
148         this.dd = dd;
149         this.qb = qb;
150         manager = dd.getJormManager();
151
152         // parse the ejbql and build the ids structure
153
visit(ejbql);
154
155         for (Iterator JavaDoc it = ids.keySet().iterator(); it.hasNext(); ) {
156             String JavaDoc id = (String JavaDoc) it.next();
157             IdValue idv = (IdValue) ids.get(id);
158             fields.put(id + "." + Field.PNAMENAME, qb.project(define(id)));
159             for (int i = 0; i < idv.getDeclaredPathLength(); i++) {
160                 String JavaDoc path = idv.getMergedPath(i);
161                 if (!collections.contains(path)) {
162                     fields.put(path, qb.project(define(path)));
163                 }
164             }
165         }
166     }
167
168     private QueryTreeField define(String JavaDoc id) throws ParseException, MedorException {
169         String JavaDoc[] path = splitPath(id);
170
171         if (!qb.contains(path[0])) {
172             IdValue idv = (IdValue) ids.get(path[0]);
173             String JavaDoc[] name = idv.getName();
174
175             PNameField pnf;
176             if (name.length == 1) {
177                 pnf = extent(name[0], path[0]);
178             } else {
179                 pnf = (PNameField) define(mergePath(name));
180             }
181             qb.define(path[0], pnf);
182         }
183
184         return qb.navigate(path);
185     }
186
187     private PNameField extent(String JavaDoc schema, String JavaDoc alias) throws ParseException, MedorException {
188         if (schema == null) { throw new NullPointerException JavaDoc("schema"); }
189         String JavaDoc cn = dd.asn2BeanDesc(schema).getJormClassName();
190         Class JavaDoc theClass = manager.getClass(cn);
191         if (theClass == null) {
192             throw new ParseException
193                 ("Abstract schema name \"" + schema +
194                  "\" has not been declared in the jorm meta information");
195         }
196         ClassExtent ext = new ClassExtent(theClass, alias, Field.PNAMENAME, false);
197         return (PNameField) ext.getField(ext.getPNameFieldName());
198     }
199
200     /**
201      * get the Map that was built from visiting the lexical query tree This map
202      * allows to get the org.objectweb.medor.api.Field from its name (ident or
203      * path).
204      * @return the Fields map
205      */

206     public Map JavaDoc getFields() {
207         return fields;
208     }
209
210     /**
211      * Trace the given ids structure
212      * @param idsM identifiocators Map
213      */

214     public void traceIds(HashMap JavaDoc idsM) {
215         if (TraceEjb.isDebugQuery()) {
216             TraceEjb.query.log(BasicLevel.DEBUG, "Begin of IDS structure:");
217             // trace the ids structure
218
for (Iterator JavaDoc i = idsM.keySet().iterator(); i.hasNext();) {
219                 String JavaDoc id = (String JavaDoc) i.next();
220                 IdValue idv = (IdValue) idsM.get(id);
221                 TraceEjb.query.log(BasicLevel.DEBUG, "ids[" + id + "]=" + idv);
222                 if (idv.getQueryTree() != null) {
223                     QueryTreePrinter.printQueryTree(idv.getQueryTree(), TraceEjb.query, BasicLevel.DEBUG);
224                 }
225             }
226             TraceEjb.query.log(BasicLevel.DEBUG, "End of IDS structure:");
227         }
228     }
229
230     /**
231      * visit child nodes
232      * @param node the node to visit
233      * @param data the current stack
234      * @return the stack
235      */

236     public Object JavaDoc visit(ASTFromClause node, Object JavaDoc data) {
237         return visit((SimpleNode) node, data);
238     }
239
240     /**
241      * visit child nodes
242      * @param node the node to visit
243      * @param data the current stack
244      * @return the stack
245      */

246     public Object JavaDoc visit(ASTCollectionMemberDeclaration node, Object JavaDoc data) {
247         return visit((SimpleNode) node, data);
248     }
249
250     /**
251      * visit child nodes
252      * @param node the node to visit
253      * @param data the current stack
254      * @return the stack
255      */

256     public Object JavaDoc visit(ASTRangeVariableDeclaration node, Object JavaDoc data) {
257         return visit((SimpleNode) node, data);
258     }
259
260     /**
261      * visit child nodes
262      * @param node the node to visit
263      * @param data the current stack
264      * @return the stack
265      */

266     public Object JavaDoc visit(ASTCollectionValuedPathExpression node, Object JavaDoc data) {
267         return visit((SimpleNode) node, data);
268     }
269
270     /**
271      * Push the Node to the stack
272      * @param node the node to visit
273      * @param data the current stack
274      * @return the stack
275      */

276     public Object JavaDoc visit(ASTAbstractSchemaName node, Object JavaDoc data) {
277         ((Stack JavaDoc) data).push(node.value);
278         return null;
279     }
280
281     /**
282      * Store the pair identifier,Node from the Stack in HashMap
283      * @param node the node to visit
284      * @param data the current stack
285      * @return the stack
286      */

287     public Object JavaDoc visit(ASTIdentifier node, Object JavaDoc data) {
288         String JavaDoc id = (String JavaDoc) node.value;
289         String JavaDoc name = (String JavaDoc) ((Stack JavaDoc) data).pop();
290         IdValue iv = (IdValue) ids.get(id);
291         if (iv == null) {
292             iv = new IdValue(name);
293             ids.put(id, iv);
294         } else {
295             iv.setName(splitPath(name));
296         }
297         return null;
298     }
299
300     /**
301      * Push the Node to the stack
302      * @param node the node to visit
303      * @param data the current stack
304      * @return the stack
305      */

306     public Object JavaDoc visit(ASTPath node, Object JavaDoc data) {
307         ((Stack JavaDoc) data).push(node.value);
308         return null;
309     }
310
311     /**
312      * Process the variable ie create the IdValue if not already done and add the path
313      * @param path of the variable
314      */

315     private void processVariable(String JavaDoc path) {
316         // Common to select, where and orderby clauses
317
String JavaDoc id = splitPath(path)[0];
318         IdValue iv = (IdValue) ids.get(id);
319         if (iv == null) {
320             iv = new IdValue();
321             ids.put(id, iv);
322         }
323         iv.addPath(path);
324     }
325
326     // -------------- select ---------------//
327
/**
328      * visit child nodes
329      * @param node the node to visit
330      * @param data the current stack
331      * @return the stack
332      */

333     public Object JavaDoc visit(ASTSelectClause node, Object JavaDoc data) {
334         visit((SimpleNode) node, data);
335         Stack JavaDoc st = (Stack JavaDoc) data;
336         if (!st.empty()) {
337             processVariable((String JavaDoc) st.pop());
338         }
339         return null;
340     }
341
342     /**
343      * visit child nodes
344      * @param node the node to visit
345      * @param data the current stack
346      * @return the stack
347      */

348     public Object JavaDoc visit(ASTSelectExpression node, Object JavaDoc data) {
349         return visit((SimpleNode) node, data);
350     }
351
352     /**
353      * visit child nodes
354      * @param node the node to visit
355      * @param data the current stack
356      * @return the stack
357      */

358     public Object JavaDoc visit(ASTAggregateSelectExpression node, Object JavaDoc data) {
359         return visit((SimpleNode) node, data);
360     }
361
362     /**
363      * visit child nodes
364      * @param node the node to visit
365      * @param data the current stack
366      * @return the stack
367      */

368     public Object JavaDoc visit(ASTIdentificationVariable node, Object JavaDoc data) {
369         return visit((SimpleNode) node, data);
370     }
371
372     /**
373      * visit child nodes
374      * @param node the node to visit
375      * @param data the current stack
376      * @return the stack
377      */

378     public Object JavaDoc visit(ASTSingleValuedPathExpression node, Object JavaDoc data) {
379         return visit((SimpleNode) node, data);
380     }
381
382     /**
383      * visit child nodes
384      * @param node the node to visit
385      * @param data the current stack
386      * @return the stack
387      */

388     public Object JavaDoc visit(ASTSingleValuedCmrPathExpression node, Object JavaDoc data) {
389         return visit((SimpleNode) node, data);
390     }
391
392     /**
393      * visit child nodes
394      * @param node the node to visit
395      * @param data the current stack
396      * @return the stack
397      */

398     public Object JavaDoc visit(ASTCmpPathExpression node, Object JavaDoc data) {
399         return visit((SimpleNode) node, data);
400     }
401
402     // ----------- Where -----------------//
403
/**
404      * visit child nodes
405      * @param node the node to visit
406      * @param data the current stack
407      * @return the stack
408      */

409     public Object JavaDoc visit(ASTWhereClause node, Object JavaDoc data) {
410         visit((SimpleNode) node, data);
411         Stack JavaDoc st = (Stack JavaDoc) data;
412         while (!st.empty()) {
413             processVariable((String JavaDoc) st.pop());
414         }
415         return null;
416     }
417
418     /**
419      * visit child nodes
420      * @param node the node to visit
421      * @param data the current stack
422      * @return the stack
423      */

424     public Object JavaDoc visit(ASTConditionalExpression node, Object JavaDoc data) {
425         return visit((SimpleNode) node, data);
426     }
427
428     /**
429      * visit child nodes
430      * @param node the node to visit
431      * @param data the current stack
432      * @return the stack
433      */

434     public Object JavaDoc visit(ASTConditionalTerm node, Object JavaDoc data) {
435         return visit((SimpleNode) node, data);
436     }
437
438     /**
439      * Visit child nodes and count the number of the unary operator NOT.
440      * @param node the node to visit
441      * @param data the current stack
442      * @return the stack
443      */

444     public Object JavaDoc visit(ASTConditionalFactor node, Object JavaDoc data) {
445         return visit((SimpleNode) node, data);
446     }
447
448     /**
449      * visit child nodes
450      * @param node the node to visit
451      * @param data the current stack
452      * @return the stack
453      */

454     public Object JavaDoc visit(ASTBetweenExpression node, Object JavaDoc data) {
455         return visit((SimpleNode) node, data);
456     }
457
458     /**
459      * visit child nodes
460      * @param node the node to visit
461      * @param data the current stack
462      * @return the stack
463      */

464     public Object JavaDoc visit(ASTInExpression node, Object JavaDoc data) {
465         return visit((SimpleNode) node, data);
466     }
467
468     /**
469      * visit child nodes
470      * @param node the node to visit
471      * @param data the current stack
472      * @return the stack
473      */

474     public Object JavaDoc visit(ASTLikeExpression node, Object JavaDoc data) {
475         return visit((SimpleNode) node, data);
476     }
477
478     /**
479      * visit child nodes
480      * @param node the node to visit
481      * @param data the current stack
482      * @return the stack
483      */

484     public Object JavaDoc visit(ASTNullComparisonExpression node, Object JavaDoc data) {
485         return visit((SimpleNode) node, data);
486     }
487
488     /**
489      * visit child nodes and see if it's IS EMPTY or IS NOT EMPTY
490      * @param node the node to visit
491      * @param data the current stack
492      * @return the stack
493      */

494     public Object JavaDoc visit(ASTEmptyCollectionComparisonExpression node, Object JavaDoc data) {
495         visit((SimpleNode) node, data);
496         Stack JavaDoc st = (Stack JavaDoc) data;
497         String JavaDoc path = (String JavaDoc) st.peek();
498         collections.add(path);
499         return null;
500     }
501
502     /**
503      * visit child nodes
504      * @param node the node to visit
505      * @param data the current stack
506      * @return the stack
507      */

508     public Object JavaDoc visit(ASTCollectionMemberExpression node, Object JavaDoc data) {
509         visit((SimpleNode) node, data);
510         Stack JavaDoc st = (Stack JavaDoc) data;
511         String JavaDoc path = (String JavaDoc) st.peek();
512         collections.add(path);
513         return null;
514     }
515
516     /**
517      * visit child nodes
518      * @param node the node to visit
519      * @param data the current stack
520      * @return the stack
521      */

522     public Object JavaDoc visit(ASTComparisonExpression node, Object JavaDoc data) {
523         return visit((SimpleNode) node, data);
524     }
525
526     /**
527      * visit child nodes
528      * @param node the node to visit
529      * @param data the current stack
530      * @return the stack
531      */

532     public Object JavaDoc visit(ASTArithmeticExpression node, Object JavaDoc data) {
533         return visit((SimpleNode) node, data);
534     }
535
536     /**
537      * visit child nodes
538      * @param node the node to visit
539      * @param data the current stack
540      * @return the stack
541      */

542     public Object JavaDoc visit(ASTArithmeticTerm node, Object JavaDoc data) {
543         return visit((SimpleNode) node, data);
544     }
545
546     /**
547      * visit child nodes
548      * @param node the node to visit
549      * @param data the current stack
550      * @return the stack
551      */

552     public Object JavaDoc visit(ASTArithmeticFactor node, Object JavaDoc data) {
553         return visit((SimpleNode) node, data);
554     }
555
556     /**
557      * visit child nodes
558      * @param node the node to visit
559      * @param data the current stack
560      * @return the stack
561      */

562     public Object JavaDoc visit(ASTStringExpression node, Object JavaDoc data) {
563         return visit((SimpleNode) node, data);
564     }
565
566     /**
567      * visit child nodes
568      * @param node the node to visit
569      * @param data the current stack
570      * @return the stack
571      */

572     public Object JavaDoc visit(ASTDatetimeExpression node, Object JavaDoc data) {
573         return visit((SimpleNode) node, data);
574     }
575
576     /**
577      * visit child nodes
578      * @param node the node to visit
579      * @param data the current stack
580      * @return the stack
581      */

582     public Object JavaDoc visit(ASTBooleanExpression node, Object JavaDoc data) {
583         return visit((SimpleNode) node, data);
584     }
585
586     /**
587      * visit child nodes
588      * @param node the node to visit
589      * @param data the current stack
590      * @return the stack
591      */

592     public Object JavaDoc visit(ASTEntityBeanExpression node, Object JavaDoc data) {
593         return visit((SimpleNode) node, data);
594     }
595
596     /**
597      * visit child nodes
598      * @param node the node to visit
599      * @param data the current stack
600      * @return the stack
601      */

602     public Object JavaDoc visit(ASTFunctionsReturningStrings node, Object JavaDoc data) {
603         return visit((SimpleNode) node, data);
604     }
605
606     /**
607      * visit child nodes
608      * @param node the node to visit
609      * @param data the current stack
610      * @return the stack
611      */

612     public Object JavaDoc visit(ASTFunctionsReturningNumerics node, Object JavaDoc data) {
613         return visit((SimpleNode) node, data);
614     }
615
616     // ----------- Order by -----------------//
617
/**
618      * visit child nodes
619      * @param node the node to visit
620      * @param data the current stack
621      * @return the stack
622      */

623     public Object JavaDoc visit(ASTOrderByClause node, Object JavaDoc data) {
624         visit((SimpleNode) node, data);
625         Stack JavaDoc st = (Stack JavaDoc) data;
626         while (!st.empty()) {
627             processVariable((String JavaDoc) st.pop());
628         }
629         return null;
630     }
631
632     /**
633      * visit child nodes
634      * @param node the node to visit
635      * @param data the current stack
636      * @return the stack
637      */

638     public Object JavaDoc visit(ASTOrderByItem node, Object JavaDoc data) {
639         return visit((SimpleNode) node, data);
640     }
641
642 }
643
Popular Tags