Source Code Cross Referenced for SpeedoQLQueryFilterVisitor.java in  » Database-ORM » Speedo_1.4.5 » org » objectweb » speedo » query » jdo » parser » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database ORM » Speedo_1.4.5 » org.objectweb.speedo.query.jdo.parser 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * Speedo: an implementation of JDO compliant personality on top of JORM generic
003:         * I/O sub-system.
004:         * Copyright (C) 2001-2004 France Telecom R&D
005:         *
006:         * This library is free software; you can redistribute it and/or
007:         * modify it under the terms of the GNU Lesser General Public
008:         * License as published by the Free Software Foundation; either
009:         * version 2 of the License, or (at your option) any later version.
010:         *
011:         * This library is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         * Lesser General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU Lesser General Public
017:         * License along with this library; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
019:         *
020:         *
021:         *
022:         * Contact: speedo@objectweb.org
023:         *
024:         * Authors: S. Chassande-Barrioz
025:         *
026:         */package org.objectweb.speedo.query.jdo.parser;
027:
028:        import org.objectweb.jorm.naming.api.PName;
029:        import org.objectweb.jorm.type.api.PType;
030:        import org.objectweb.medor.api.Field;
031:        import org.objectweb.medor.expression.api.Expression;
032:        import org.objectweb.medor.expression.api.Operator;
033:        import org.objectweb.medor.expression.api.ParameterOperand;
034:        import org.objectweb.medor.expression.api.TypingException;
035:        import org.objectweb.medor.expression.lib.And;
036:        import org.objectweb.medor.expression.lib.BasicOperand;
037:        import org.objectweb.medor.expression.lib.BasicParameterOperand;
038:        import org.objectweb.medor.expression.lib.Bitwize;
039:        import org.objectweb.medor.expression.lib.ConditionalAnd;
040:        import org.objectweb.medor.expression.lib.ConditionalOr;
041:        import org.objectweb.medor.expression.lib.DivideBy;
042:        import org.objectweb.medor.expression.lib.Equal;
043:        import org.objectweb.medor.expression.lib.Greater;
044:        import org.objectweb.medor.expression.lib.GreaterEqual;
045:        import org.objectweb.medor.expression.lib.Length;
046:        import org.objectweb.medor.expression.lib.Like;
047:        import org.objectweb.medor.expression.lib.Lower;
048:        import org.objectweb.medor.expression.lib.LowerEqual;
049:        import org.objectweb.medor.expression.lib.Minus;
050:        import org.objectweb.medor.expression.lib.Mult;
051:        import org.objectweb.medor.expression.lib.Not;
052:        import org.objectweb.medor.expression.lib.NotEqual;
053:        import org.objectweb.medor.expression.lib.Or;
054:        import org.objectweb.medor.expression.lib.Plus;
055:        import org.objectweb.medor.expression.lib.StringComparatorParameterOperand;
056:        import org.objectweb.medor.expression.lib.StringLower;
057:        import org.objectweb.medor.expression.lib.StringUpper;
058:        import org.objectweb.medor.expression.lib.UMinus;
059:        import org.objectweb.medor.expression.lib.Substring;
060:        import org.objectweb.medor.filter.lib.BasicFieldOperand;
061:        import org.objectweb.medor.filter.lib.ExpressionPrinter;
062:        import org.objectweb.medor.filter.lib.InCollection;
063:        import org.objectweb.medor.filter.lib.IsEmpty;
064:        import org.objectweb.medor.filter.lib.IsNull;
065:        import org.objectweb.medor.filter.lib.MemberOf;
066:        import org.objectweb.medor.query.api.QueryTree;
067:        import org.objectweb.medor.query.api.QueryTreeField;
068:        import org.objectweb.medor.query.jorm.lib.QueryBuilder;
069:        import org.objectweb.medor.query.lib.SelectProject;
070:        import org.objectweb.speedo.api.SpeedoException;
071:        import org.objectweb.speedo.mapper.api.JormFactory;
072:        import org.objectweb.util.monolog.api.BasicLevel;
073:        import org.objectweb.util.monolog.api.Logger;
074:
075:        import javax.jdo.JDOException;
076:        import java.util.Collections;
077:        import java.util.Map;
078:        import java.util.Stack;
079:
080:        /**
081:         * Implementation of a visitor that creates the filter
082:         */
083:        public class SpeedoQLQueryFilterVisitor extends SpeedoQLAbstractVisitor {
084:
085:            private final static String CONTAINS_PATH_SET = "Next element is the contain path set";
086:            private final static String REMOVER = "Remover";
087:
088:            /**
089:             * qf is the transformation of the filter into a MEDOR expression
090:             */
091:            private Expression qf = null;
092:
093:            /**
094:             * qt is built by the SpeedoQLVariableVisitor and is just used here
095:             */
096:            private QueryTree qt = null;
097:
098:            private SelectProject root;
099:
100:            /**
101:             * speedoql is the result of the filter parsing
102:             */
103:            private ASTSpeedoQL speedoql = null;
104:
105:            Map fields;
106:
107:            QueryBuilder qb;
108:
109:            private int nbNot = 0;
110:
111:            private String tab = "";
112:
113:            private JormFactory jf = null;
114:
115:            private Class clazz = null;
116:
117:            public SpeedoQLQueryFilterVisitor(Map _fields, SelectProject _root,
118:                    ASTSpeedoQL speedoql, Logger logger, Map hparam,
119:                    Map vparam, Class clazz, QueryBuilder _qb, JormFactory jf)
120:                    throws SpeedoException {
121:                //qt = qtree;
122:                this .fields = _fields;
123:                this .speedoql = speedoql;
124:                this .qt = _root;
125:                this .root = _root;
126:                this .qb = _qb;
127:                this .jf = jf;
128:                setLogger(logger);
129:                setParams(hparam);
130:                setVars(vparam);
131:                setCurrentClass(clazz.getName());
132:                this .clazz = clazz;
133:                startVisiting();
134:            }
135:
136:            /**
137:             * the visit starts here, please before sets a list of variables.
138:             * @throws java.lang.Exception
139:             */
140:            public void startVisiting() throws SpeedoException {
141:                debug = logger.isLoggable(BasicLevel.DEBUG);
142:                nbNot = 0;
143:                try {
144:                    visit(speedoql);
145:                } catch (Exception e) {
146:                    if (e instanceof  SpeedoQLAbstractVisitor.VisitorException) {
147:                        e = ((SpeedoQLAbstractVisitor.VisitorException) e)
148:                                .getNestedException();
149:                    }
150:                    throw new SpeedoException(
151:                            "Impossible to built the queryTree during the filter visit",
152:                            e);
153:                }
154:                // this expression is the filter of the SelectProject
155:                Expression exprFilter = getQueryFilter();
156:                if (exprFilter != null) {
157:                    ME me = replaceNullNode(exprFilter);
158:                    if (me != null && me.modified) {
159:                        qf = me.e;
160:                        exprFilter = getQueryFilter();
161:                    }
162:                    if (debug) {
163:                        logger.log(BasicLevel.DEBUG, "filter = "
164:                                + exprFilter.getClass().getName());
165:                    }
166:                    root.setQueryFilter(exprFilter);
167:                }
168:
169:            }
170:
171:            private static class ME {
172:                public Expression e;
173:                public boolean modified;
174:
175:                public ME(Expression _e) {
176:                    this .e = _e;
177:                    this .modified = true;
178:                }
179:            }
180:
181:            /**
182:             * Replace null node.
183:             * @param exprFilter
184:             */
185:            private ME replaceNullNode(Expression exprFilter)
186:                    throws SpeedoException {
187:                ME me = null;
188:                if ((exprFilter instanceof  Equal)
189:                        || (exprFilter instanceof  NotEqual)) {
190:                    Operator op = (Operator) exprFilter;
191:                    for (int i = 0; i < op.getOperandNumber(); i++) {
192:                        if (op.getExpression(i) instanceof  DummyOperand) {
193:                            //get the other child operand
194:                            int j = (i + 1) % 2;
195:                            Expression other = op.getExpression(j);
196:                            PType ptype = other.getType();
197:                            if (ptype.getTypeCode() == PType.TYPECODE_REFERENCE) {
198:                                PName val = null;
199:                                try {
200:                                    val = jf.getPClassMapping(
201:                                            ptype.getJormName(),
202:                                            clazz.getClassLoader())
203:                                            .getPBinder().getNull();
204:                                } catch (Exception e) {
205:                                    throw new SpeedoException(
206:                                            "Try to replace null node. Impossible to find the null PName for the type "
207:                                                    + ptype.getJormName(), e);
208:                                }
209:                                //replace the null node with null PName
210:                                op.setExpression(i,
211:                                        new BasicOperand(val, ptype));
212:                            } else {
213:                                //Transform the null [not]equality into a IsNull operator
214:                                me = new ME(new IsNull(other,
215:                                        exprFilter instanceof  NotEqual));
216:                                //recursion is done on the other operand
217:                                exprFilter = me.e;
218:                            }
219:                        }
220:                    }
221:                }
222:                if (exprFilter instanceof  Operator) {
223:                    Operator op = (Operator) exprFilter;
224:                    for (int i = 0; i < op.getOperandNumber(); i++) {
225:                        //recursivity
226:                        ME ime = replaceNullNode(op.getExpression(i));
227:                        if (ime != null && ime.modified) {
228:                            //replace the child
229:                            op.setExpression(i, ime.e);
230:                            //mark the result as modified
231:                            if (me == null) {//create if not already done
232:                                me = new ME(exprFilter);
233:                            }
234:                            me.modified = true;
235:                        }
236:                    }
237:                }
238:                return me; //can be null
239:            }
240:
241:            /**
242:             * get the query filter that was built from visiting the syntaxic tree
243:             */
244:            public Expression getQueryFilter() {
245:                return qf;
246:            }
247:
248:            public Object visit(ASTPrimary node, Object data) {
249:                Stack stack = (Stack) data;
250:                boolean hasMethod = node.value != null;
251:                if (hasMethod) {
252:                    stack.push(node.value);
253:                }
254:                visit((SimpleNode) node, data);
255:                if (hasMethod) {
256:                    Expression e2 = (Expression) stack.pop();
257:                    Expression e1 = (Expression) stack.pop();
258:                    String methodName = (String) stack.pop();
259:                    if (methodName.startsWith("null.")) {
260:                        methodName = methodName.substring("null.".length());
261:                    }
262:                    stack.push(e1);
263:                    stack.push(methodName);
264:                    e1 = treatMethodOperator(methodName, stack, e2);
265:                    if (e1 != null) {
266:                        stack.push(e1);
267:                    }
268:                }
269:                return null;
270:            }
271:
272:            public Object visit(ASTSpeedoPrimary node, Object data) {
273:                visit((SimpleNode) node, data);
274:                Stack stack = (Stack) data;
275:                while (stack.size() > 0 && REMOVER.equals(stack.peek())) {
276:                    stack.pop();
277:                }
278:                if (stack.size() > 0) {
279:                    qf = (Expression) stack.pop();
280:                } // else there is no filter
281:                return null;
282:            }
283:
284:            /**
285:             *
286:             */
287:            public Object visit(ASTRelationalExpression node, Object data) {
288:                if (debug) {
289:                    logger.log(BasicLevel.DEBUG, tab
290:                            + "Visit RelationalExpression: " + node);
291:                }
292:                tab += '\t';
293:                visit((SimpleNode) node, data);
294:                tab = tab.substring(1);
295:                Stack stack = (Stack) data;
296:                if (stack.size() > 0) {
297:                    if (CONTAINS_PATH_SET.equals(stack.peek())) {
298:                        if (debug) {
299:                            logger.log(BasicLevel.ERROR,
300:                                    "remove the element of the stack");
301:                        }
302:                    } else {
303:                        if (debug) {
304:                            logger.log(BasicLevel.DEBUG,
305:                                    "manage relational expression: "
306:                                            + "(children: "
307:                                            + node.jjtGetNumChildren()
308:                                            + ", stack: " + stack.size()
309:                                            + ", peek:" + stack.peek() + ")");
310:                        }
311:                        for (int i = 0; (i < (node.jjtGetNumChildren() - 1) && stack
312:                                .size() > 0); i++) {
313:                            int op = ((Integer) node.ops.get(node
314:                                    .jjtGetNumChildren()
315:                                    - 2 - i)).intValue();
316:                            if (usedInRelationalExpresssion(op)) {
317:                                Object child2 = stack.pop();
318:                                Object child1 = stack.pop();
319:
320:                                if (debug) {
321:                                    logger.log(BasicLevel.DEBUG, "pop child1: "
322:                                            + child1);
323:                                    logger.log(BasicLevel.DEBUG, "pop child2: "
324:                                            + child2);
325:                                }
326:                                if (REMOVER.equals(child1)) {
327:                                    if (REMOVER.equals(child2)) {
328:                                        //nothin
329:                                    } else {
330:                                        stack.push(child2);
331:                                        if (debug) {
332:                                            logger.log(BasicLevel.DEBUG,
333:                                                    "push(" + child2 + ")");
334:                                        }
335:                                    }
336:                                } else {
337:                                    if (REMOVER.equals(child2)) {
338:                                        stack.push(child1);
339:                                        if (debug) {
340:                                            logger.log(BasicLevel.DEBUG,
341:                                                    "push(" + child1 + ")");
342:                                        }
343:                                    } else {
344:                                        Expression ret = null;
345:                                        switch (op) {
346:                                        case SpeedoQLConstants.OR:
347:                                            ret = new ConditionalOr(
348:                                                    (Expression) child1,
349:                                                    (Expression) child2);
350:                                            break;
351:                                        case SpeedoQLConstants.AND:
352:                                            ret = new ConditionalAnd(
353:                                                    (Expression) child1,
354:                                                    (Expression) child2);
355:                                            break;
356:                                        case SpeedoQLConstants.BITWISEOR:
357:                                            ret = new Or((Expression) child1,
358:                                                    (Expression) child2);
359:                                            break;
360:                                        case SpeedoQLConstants.BITWISEXOR:
361:                                            ret = null;
362:                                            break;
363:                                        case SpeedoQLConstants.BITWISEAND:
364:                                            ret = new And((Expression) child1,
365:                                                    (Expression) child2);
366:                                            break;
367:                                        case SpeedoQLConstants.EQ:
368:                                            ret = new Equal(
369:                                                    (Expression) child1,
370:                                                    (Expression) child2);
371:                                            break;
372:                                        case SpeedoQLConstants.NEQ:
373:                                            ret = new NotEqual(
374:                                                    (Expression) child1,
375:                                                    (Expression) child2);
376:                                            break;
377:                                        case SpeedoQLConstants.LT:
378:                                            ret = new Lower(
379:                                                    (Expression) child1,
380:                                                    (Expression) child2);
381:                                            break;
382:                                        case SpeedoQLConstants.GT:
383:                                            ret = new Greater(
384:                                                    (Expression) child1,
385:                                                    (Expression) child2);
386:                                            break;
387:                                        case SpeedoQLConstants.GTE:
388:                                            ret = new GreaterEqual(
389:                                                    (Expression) child1,
390:                                                    (Expression) child2);
391:                                            break;
392:                                        case SpeedoQLConstants.LTE:
393:                                            ret = new LowerEqual(
394:                                                    (Expression) child1,
395:                                                    (Expression) child2);
396:                                            break;
397:                                        }
398:                                        if (debug) {
399:                                            logger.log(BasicLevel.DEBUG,
400:                                                    "push(" + ret + ")");
401:                                        }
402:                                        stack.push(ret);
403:                                    }
404:                                }
405:                            }
406:                        }
407:                    }
408:                }
409:                if (debug) {
410:                    logger.log(BasicLevel.DEBUG, "children:"
411:                            + node.jjtGetNumChildren() + " / stack: "
412:                            + stack.size());
413:                    logger.log(BasicLevel.DEBUG, tab
414:                            + "End of Visit RelationalExpression: " + node);
415:                }
416:                return null;
417:            }
418:
419:            private boolean usedInRelationalExpresssion(int op) {
420:                switch (op) {
421:                case SpeedoQLConstants.OR:
422:                case SpeedoQLConstants.AND:
423:                case SpeedoQLConstants.BITWISEOR:
424:                case SpeedoQLConstants.BITWISEXOR:
425:                case SpeedoQLConstants.BITWISEAND:
426:                case SpeedoQLConstants.EQ:
427:                case SpeedoQLConstants.NEQ:
428:                case SpeedoQLConstants.LT:
429:                case SpeedoQLConstants.GT:
430:                case SpeedoQLConstants.GTE:
431:                case SpeedoQLConstants.LTE:
432:                    if (debug) {
433:                        logger.log(BasicLevel.DEBUG, "node useful");
434:                    }
435:                    return true;
436:                default:
437:                    if (debug) {
438:                        logger.log(BasicLevel.DEBUG, "node useless");
439:                    }
440:                    return false;
441:                }
442:            }
443:
444:            public Object visit(ASTAdditiveExpression node, Object data) {
445:                if (debug) {
446:                    logger.log(BasicLevel.DEBUG, tab
447:                            + "Visit AdditiveExpression: " + node);
448:                }
449:                tab += '\t';
450:                visit((SimpleNode) node, data);
451:                tab = tab.substring(1);
452:                Stack stack = (Stack) data;
453:                if (stack.size() > 0 && !CONTAINS_PATH_SET.equals(stack.peek())
454:                        && !REMOVER.equals(stack.peek())) {
455:                    Expression ret = (Expression) stack.pop();
456:                    for (int i = 0; i < node.jjtGetNumChildren() - 1; i++) {
457:                        if (debug) {
458:                            logger.log(BasicLevel.DEBUG,
459:                                    "Visit ConditionalExpression... children...["
460:                                            + i + "]");
461:                        }
462:
463:                        switch (((Integer) node.ops.get(node
464:                                .jjtGetNumChildren()
465:                                - 2 - i)).intValue()) {
466:
467:                        case SpeedoQLConstants.PLUS:
468:                            ret = new Plus((Expression) stack.pop(), ret);
469:                            break;
470:                        case SpeedoQLConstants.MINUS:
471:                            ret = new Minus((Expression) stack.pop(), ret);
472:                            break;
473:                        case SpeedoQLConstants.MULT:
474:                            ret = new Mult((Expression) stack.pop(), ret);
475:                            break;
476:                        case SpeedoQLConstants.DIV:
477:                            ret = new DivideBy((Expression) stack.pop(), ret);
478:                            break;
479:                        default:
480:
481:                        }
482:                    }
483:                    ((Stack) data).push(ret);
484:                }
485:                if (debug) {
486:                    logger.log(BasicLevel.DEBUG, tab
487:                            + "End of Visit AdditiveExpression: " + node);
488:                }
489:                return null;
490:            }
491:
492:            public Object visit(ASTUnaryExpression node, Object data) {
493:                if (debug) {
494:                    logger.log(BasicLevel.DEBUG, tab + "Visit UnaryExpression"
495:                            + node);
496:                }
497:                tab += '\t';
498:                boolean hasNot = node.ops.size() > 0
499:                        && ((Integer) node.ops.get(0)).intValue() == SpeedoQLConstants.NOT;
500:                if (hasNot) {
501:                    nbNot++;
502:                    if (debug) {
503:                        logger
504:                                .log(BasicLevel.DEBUG, "remember a Not: "
505:                                        + nbNot);
506:                    }
507:                }
508:                visit((SimpleNode) node, data);
509:                if (hasNot && nbNot > 0) {
510:                    nbNot--;
511:                    if (debug) {
512:                        logger.log(BasicLevel.DEBUG, "forget a Not: " + nbNot);
513:                    }
514:                }
515:                tab = tab.substring(1);
516:                Stack stack = (Stack) data;
517:                if (debug && stack.size() > 0) {
518:                    logger.log(BasicLevel.DEBUG, tab + "stack.peek:"
519:                            + stack.peek());
520:                }
521:                if (stack.size() > 0 && !CONTAINS_PATH_SET.equals(stack.peek())
522:                        && !REMOVER.equals(stack.peek())) {
523:                    Object o = stack.pop();
524:                    if (node.ops.size() > 0) {
525:                        switch (((Integer) node.ops.get(0)).intValue()) {
526:                        case SpeedoQLConstants.MINUS:
527:                            o = new UMinus((Expression) o);
528:                            break;
529:                        case SpeedoQLConstants.BITWISECOMPL:
530:                            o = new Bitwize((Expression) o);
531:                            break;
532:                        case SpeedoQLConstants.NOT:
533:                            logger.log(BasicLevel.DEBUG, "NOT(" + o + "): "
534:                                    + node);
535:                            o = new Not((Expression) o);
536:                            break;
537:                        }
538:                    }
539:                    ((Stack) data).push(o);
540:                }
541:                if (debug) {
542:                    logger.log(BasicLevel.DEBUG, tab
543:                            + "End of Visit UnaryExpression: " + node);
544:                }
545:                return null;
546:            }
547:
548:            // to be done
549:            public Object visit(ASTCastExpression node, Object data) {
550:                ((Stack) data).push(node);
551:                return null;
552:            }
553:
554:            /**
555:             * 4 cases to manage: (en cours par equipe MEDOR)
556:             * - Collection.contains(Object o)
557:             * - Collection.isEmpty()
558:             * - String.startsWith(String s)
559:             * - String.endsWith(String s)
560:             */
561:            public Object visit(ASTArgumentList node, Object data) {
562:                visit((SimpleNode) node, data);
563:                return null;
564:            }
565:
566:            public Object visit(ASTLiteral node, Object data) {
567:                Stack stack = (Stack) data;
568:                Expression e = null;
569:                if (node.value == null) {
570:                    //special case for null: will be replaced later
571:                    e = new DummyOperand();
572:                } else if (node.value instanceof  Integer) {
573:                    e = new BasicOperand(((Integer) node.value).intValue());
574:                } else if (node.value instanceof  Float) {
575:                    e = new BasicOperand(((Float) node.value).floatValue());
576:                } else if (node.value instanceof  Character) {
577:                    e = new BasicOperand(((Character) node.value).charValue());
578:                } else if (node.value instanceof  String) {
579:                    String s = (String) (node.value);
580:                    s = s.substring(1, s.length() - 1);
581:                    e = new BasicOperand(s);
582:                } else if (node.value instanceof  Boolean) {
583:                    e = new BasicOperand(((Boolean) node.value).booleanValue());
584:                }
585:                if (stack.size() > 0) {
586:                    Object top = stack.peek();
587:                    if (CONTAINS_PATH_SET.equals(top)) {
588:                        //TODO: Support the path.contains(path) operator
589:                        logger
590:                                .log(BasicLevel.ERROR,
591:                                        "The path.contains(path) operator is not yet implemented");
592:                        return null;
593:                    } else if (top instanceof  String) {
594:                        e = treatMethodOperator((String) top, stack, e);
595:                    }
596:                }
597:                if (e != null) {
598:                    if (debug) {
599:                        logger.log(BasicLevel.DEBUG, "push("
600:                                + ExpressionPrinter.e2str(e) + ")");
601:                    }
602:                    stack.push(e);
603:                }
604:                return null;
605:            }
606:
607:            private Expression treatMethodOperator(String opName, Stack stack,
608:                    Expression e) {
609:                int op = isMethodOperator(opName);
610:                if (op == -1) {
611:                    return e;
612:                }
613:                switch (op) {
614:                case STARTS_WITH_OPERATOR: {
615:                    stack.pop();
616:                    Object oe = stack.pop();
617:                    if (debug) {
618:                        logger.log(BasicLevel.DEBUG, "pop expression: " + oe);
619:                    }
620:                    Expression str = (Expression) oe;
621:                    if (e instanceof  BasicParameterOperand) {
622:                        e = new StringComparatorParameterOperand(
623:                                (BasicParameterOperand) e, null, ".*");
624:                    } else if (e instanceof  BasicOperand) {
625:                        try {
626:                            e = new BasicOperand(((BasicOperand) e).getString()
627:                                    + ".*");
628:                        } catch (TypingException e1) {
629:                            throw new JDOException(
630:                                    "Bad parameter type for the 'startsWith' method",
631:                                    e1);
632:                        }
633:                    }
634:                    e = new Like(str, e);
635:                    break;
636:                }
637:                case ENDS_WITH_OPERATOR: {
638:                    stack.pop();
639:                    Object oe = stack.pop();
640:                    if (debug) {
641:                        logger.log(BasicLevel.DEBUG, "pop expression: " + oe);
642:                    }
643:                    Expression str = (Expression) oe;
644:                    if (e instanceof  BasicParameterOperand) {
645:                        e = new StringComparatorParameterOperand(
646:                                (BasicParameterOperand) e, ".*", null);
647:                    } else if (e instanceof  BasicOperand) {
648:                        try {
649:                            e = new BasicOperand("%"
650:                                    + ((BasicOperand) e).getString());
651:                        } catch (TypingException e1) {
652:                            throw new JDOException(
653:                                    "Bad parameter type for the 'startsWith' method",
654:                                    e1);
655:                        }
656:                    }
657:                    e = new Like(str, e);
658:                    break;
659:                }
660:                case EQUALS_OPERATOR:
661:                    //TODO: Support the equals operator
662:                    break;
663:                case MATCHES_OPERATOR: {
664:                    stack.pop();
665:                    Object oe = stack.pop();
666:                    if (debug) {
667:                        logger.log(BasicLevel.DEBUG, "pop expression: " + oe);
668:                    }
669:                    Expression str = (Expression) oe;
670:                    if (e instanceof  BasicParameterOperand) {
671:                        //e = new StringComparatorParameterOperand((BasicParameterOperand) e, "%", "%");
672:                    } else if (e instanceof  BasicOperand) {
673:                        try {
674:                            e = new BasicOperand(((BasicOperand) e).getString());
675:                        } catch (TypingException e1) {
676:                            throw new JDOException(
677:                                    "Bad parameter type for the 'startsWith' method",
678:                                    e1);
679:                        }
680:                    }
681:                    e = new Like(str, e);
682:                    break;
683:                }
684:                case SUBSTRING_OPERATOR: {
685:                    stack.pop();
686:                    Object o = stack.pop();
687:                    if (o == STR_OPERAND_SUBSTRING) {
688:                        if (debug) {
689:                            logger.log(BasicLevel.DEBUG, "push("
690:                                    + ExpressionPrinter.e2str(e) + ")");
691:                        }
692:                        stack.push(e);
693:                        if (debug) {
694:                            logger.log(BasicLevel.DEBUG,
695:                                    "push(BEGIN_OPERAND_SUBSTRING)");
696:                        }
697:                        stack.push(BEGIN_OPERAND_SUBSTRING);
698:                        if (debug) {
699:                            logger
700:                                    .log(BasicLevel.DEBUG, "push(" + opName
701:                                            + ")");
702:                        }
703:                        stack.push(opName);
704:                        return null;
705:                    } else if (o == BEGIN_OPERAND_SUBSTRING) {
706:                        Expression begin = (Expression) stack.pop();
707:                        Expression str = (Expression) stack.pop();
708:                        e = new Substring(str, begin, e);
709:                    } else {
710:                        throw new JDOException("Protocol error: " + o);
711:                    }
712:                    break;
713:                }
714:                }
715:                return e;
716:            }
717:
718:            public Object visit(ASTType node, Object data) {
719:                if (debug) {
720:                    logger.log(BasicLevel.DEBUG, "Visit Type: " + node);
721:                }
722:
723:                ((Stack) data).push(node);
724:
725:                if (debug) {
726:                    logger.log(BasicLevel.DEBUG, "End of Visit Type");
727:                }
728:                return null;
729:            }
730:
731:            /**
732:             * qualifiedname could be:
733:             * - a class field (salary from Employee)
734:             * - a parameter
735:             * - a variable
736:             *
737:             */
738:            public Object visit(ASTQualifiedName node, Object data) {
739:                String name = (String) node.value;
740:                String[] splitted = splitPath(name);
741:                Stack stack = (Stack) data;
742:                if (debug) {
743:                    logger.log(BasicLevel.DEBUG, tab
744:                            + "Visit QualifiedName value=[" + node.value
745:                            + "] stack size=" + stack.size());
746:                }
747:                try {
748:                    if (params != null && params.get(splitted[0]) != null) {
749:                        visitParameter(stack, splitted, name);
750:                    } else {
751:                        if (!"this".equals(splitted[0])
752:                                && (vars == null || vars.get(splitted[0]) == null)) {
753:                            //It is not a variable, but a navigation from the current 
754:                            // class without 'this' at the begin. then add the 
755:                            // class name in first
756:                            name = "this." + name;
757:                            String[] newsplitted = new String[splitted.length + 1];
758:                            newsplitted[0] = "this";
759:                            System.arraycopy(splitted, 0, newsplitted, 1,
760:                                    splitted.length);
761:                            splitted = newsplitted;
762:                        }
763:                        visitFieldAccess(stack, splitted, name);
764:                    }
765:                } catch (Exception e) {
766:                    throw new SpeedoQLAbstractVisitor.VisitorException(e);
767:                }
768:                return null;
769:            }
770:
771:            private void visitParameter(Stack stack, String[] splitted,
772:                    String name) throws Exception {
773:                if (stack.size() > 0 && CONTAINS_PATH_SET.equals(stack.peek())) {
774:                    //x.y.bs.contains(myParam)
775:                    stack.pop(); // forget the CONTAINS_PATH_SET
776:                    Object o = stack.pop(); // pop the pathset
777:                    String pathset = (String) o;
778:                    if (debug) {
779:                        logger.log(BasicLevel.DEBUG, tab + "parameter(" + name
780:                                + ") MemberOf " + pathset);
781:                    }
782:                    String[] spli = splitPath(pathset);
783:                    String rest = mergePath(spli, 1, spli.length - 1);
784:                    QueryBuilder subquery = new QueryBuilder(qb);
785:                    subquery.define("", qb.navigate(spli[0]));
786:                    QueryTreeField setField = subquery.project(subquery
787:                            .navigate(rest));
788:                    Expression e = new MemberOf(Collections
789:                            .singletonList(((Object[]) params.get(name))[1]),
790:                            Collections.singletonList(new BasicFieldOperand(
791:                                    setField)));
792:                    if (debug) {
793:                        logger.log(BasicLevel.DEBUG, tab + "push("
794:                                + ExpressionPrinter.e2str(e) + ")");
795:                    }
796:                    stack.push(e);
797:                } else if (splitted.length == 1) {
798:                    if (debug) {
799:                        logger.log(BasicLevel.DEBUG, tab
800:                                + "Push the parameterOperand " + name);
801:                    }
802:                    Expression e = (Expression) ((Object[]) params.get(name))[1];
803:                    if (stack.size() > 0 && stack.peek() instanceof  String) {
804:                        e = treatMethodOperator((String) stack.peek(), stack, e);
805:                    }
806:                    stack.push(e);
807:                } else if (splitted.length == 2
808:                        && "contains".equals(splitted[1])) {
809:                    if (debug) {
810:                        logger.log(BasicLevel.DEBUG, tab
811:                                + "Push the parameterOperand " + splitted[0]);
812:                    }
813:                    ParameterOperand po = (ParameterOperand) ((Object[]) params
814:                            .get(splitted[0]))[1];
815:
816:                    stack.push(po);
817:                    stack.push(CONTAINS_PATH_SET);
818:                } else {
819:                    throw new Exception(
820:                            "Does not support the naviation over a parameter: "
821:                                    + name);
822:                }
823:            }
824:
825:            private void visitFieldAccess(Stack stack, String[] splitted,
826:                    String name) throws Exception {
827:                int operatorId = -1;
828:                if (stack.size() > 0 && CONTAINS_PATH_SET.equals(stack.peek())) {
829:                    stack.pop(); // forget the CONTAINS_PATH_SET
830:                    Object o = stack.pop(); // pop the pathset
831:                    if (o instanceof  ParameterOperand) {
832:                        //myParam.contains(...)
833:                        if (debug) {
834:                            logger.log(BasicLevel.DEBUG, tab + "(" + name
835:                                    + ") InCollection (" + o + ")");
836:                        }
837:                        Field qtf = (Field) fields.get(name);
838:                        Expression e = new InCollection(new BasicFieldOperand(
839:                                qtf), (ParameterOperand) o, qtf.getType());
840:                        stack.push(e);
841:
842:                    } else if (o instanceof  String) {
843:                        String pathset = (String) o;
844:                        String[] spli = splitPath(pathset);
845:                        if (vars.containsKey(splitted[0])) {
846:                            //x.y.bs.contains(b)
847:                            //The variable definition is managed by the Variable visitor
848:                            //thus forget the expression
849:                            if ((nbNot % 2) == 0) {
850:                                stack.push(REMOVER);
851:                            } else {
852:                                QueryTreeField f = (QueryTreeField) fields
853:                                        .get(name);
854:                                stack.push(new Not(new IsEmpty(
855:                                        new BasicFieldOperand(f))));
856:                            }
857:                        } else {
858:                            //x.y.bs.contains(u.v.b)
859:                            String rest = mergePath(spli, 1, spli.length - 2);
860:                            QueryBuilder subquery = new QueryBuilder(qb);
861:                            subquery.define("", qb.navigate(spli[0]));
862:                            QueryTreeField setField = subquery.project(subquery
863:                                    .navigate(rest));
864:                            QueryTreeField f = (QueryTreeField) fields
865:                                    .get(name);
866:
867:                            stack
868:                                    .push(new MemberOf(
869:                                            Collections
870:                                                    .singletonList(new BasicFieldOperand(
871:                                                            f)),
872:                                            Collections
873:                                                    .singletonList(new BasicFieldOperand(
874:                                                            setField))));
875:                        }
876:                    } else {
877:                        if (debug) {
878:                            logger
879:                                    .log(
880:                                            BasicLevel.DEBUG,
881:                                            tab
882:                                                    + "Do not use the pathset of the contain operator");
883:                        }
884:                        stack.push(REMOVER);
885:                    }
886:                    return;
887:                }
888:
889:                //maybe there is an operator
890:                String last = splitted[splitted.length - 1];
891:                operatorId = isMethodOperator(last);
892:                if (operatorId == -1) {
893:                    //No operator found ==> default case
894:                    if (debug) {
895:                        logger.log(BasicLevel.DEBUG, tab
896:                                + "create a fieldOperand with:" + name);
897:                    }
898:                    Field f = (Field) fields.get(name);
899:                    if (f == null) {
900:                        throw new SpeedoException("Internal error: No field '"
901:                                + name + "' found during filter parsing");
902:                    }
903:                    stack.push(new BasicFieldOperand(f));
904:                    return;
905:                }
906:                //There is an operator
907:                String begin = buildStringwithout(splitted,
908:                        splitted.length - 1, ".");
909:                if (operatorId == CONTAINS_OPERATOR) {
910:                    //The contains contraint is managed during the QueryTree creation
911:                    //see the variable vistor
912:                    //However push some stuff in the stack in order to known that 
913:                    // the next qualifiedName is used in a contain constraint.
914:                    if (debug) {
915:                        logger.log(BasicLevel.DEBUG, tab
916:                                + "contains operator: set=" + begin);
917:                    }
918:                    stack.push(begin);
919:                    stack.push(CONTAINS_PATH_SET);
920:                    return;
921:                } else if (operatorId == IS_EMPTY_OPERATOR) {
922:                    if (debug) {
923:                        logger.log(BasicLevel.DEBUG, tab + "Visit IsEmpty: "
924:                                + begin);
925:                    }
926:                    String rest = mergePath(splitted, 1, splitted.length - 2);
927:                    QueryBuilder subquery = new QueryBuilder(qb);
928:                    subquery.define("", qb.navigate(splitted[0]));
929:                    Field f = subquery.project(subquery.navigate(rest));
930:                    stack.push(new IsEmpty(new BasicFieldOperand(f)));
931:                    return;
932:                }
933:
934:                if (debug) {
935:                    logger.log(BasicLevel.DEBUG, tab
936:                            + "create a fieldOperand with:" + begin);
937:                }
938:                Field f = (Field) fields.get(begin);
939:                Expression e = new BasicFieldOperand(f);
940:                switch (operatorId) {
941:                case TO_LOWER_OPERATOR:
942:                    e = new StringLower(e);
943:                    stack.push(e);
944:                    break;
945:                case TO_UPPER_OPERATOR:
946:                    e = new StringUpper(e);
947:                    stack.push(e);
948:                    break;
949:                case LENGTH_OPERATOR:
950:                    e = new Length(e);
951:                    stack.push(e);
952:                    break;
953:                case SUBSTRING_OPERATOR:
954:                    stack.push(e);
955:                    stack.push(STR_OPERAND_SUBSTRING);
956:                    stack.push(last);
957:                    break;
958:                default:
959:                    stack.push(e);
960:                    stack.push(last);
961:                    break;
962:                }
963:            }
964:
965:            static class DummyOperand extends BasicOperand {
966:
967:                public DummyOperand() {
968:                    super();
969:                }
970:            }
971:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.