Source Code Cross Referenced for EJBQLToSQL92Compiler.java in  » EJB-Server-JBoss-4.2.1 » server » org » jboss » ejb » plugins » cmp » jdbc » 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 » EJB Server JBoss 4.2.1 » server » org.jboss.ejb.plugins.cmp.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * JBoss, Home of Professional Open Source.
0003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004:         * as indicated by the @author tags. See the copyright.txt file in the
0005:         * distribution for a full listing of individual contributors.
0006:         *
0007:         * This is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU Lesser General Public License as
0009:         * published by the Free Software Foundation; either version 2.1 of
0010:         * the License, or (at your option) any later version.
0011:         *
0012:         * This software is distributed in the hope that it will be useful,
0013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015:         * Lesser General Public License for more details.
0016:         *
0017:         * You should have received a copy of the GNU Lesser General Public
0018:         * License along with this software; if not, write to the Free
0019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021:         */
0022:        package org.jboss.ejb.plugins.cmp.jdbc;
0023:
0024:        import java.io.StringReader;
0025:        import java.util.ArrayList;
0026:        import java.util.List;
0027:        import java.util.Set;
0028:        import java.util.HashSet;
0029:        import java.util.Map;
0030:        import java.util.HashMap;
0031:        import java.util.Iterator;
0032:
0033:        import org.jboss.ejb.plugins.cmp.ejbql.*;
0034:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
0035:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge;
0036:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractCMRFieldBridge;
0037:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
0038:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
0039:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCTypeMappingMetaData;
0040:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData;
0041:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData;
0042:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData;
0043:        import org.jboss.ejb.plugins.cmp.bridge.CMPFieldBridge;
0044:        import org.jboss.ejb.EntityPersistenceStore;
0045:        import org.jboss.logging.Logger;
0046:
0047:        /**
0048:         * Compiles EJB-QL and JBossQL into SQL using OUTER and INNER joins.
0049:         *
0050:         * @author <a href="mailto:alex@jboss.org">Alex Loubyansky</a>
0051:         * @version $Revision: 63348 $
0052:         */
0053:        public final class EJBQLToSQL92Compiler implements  QLCompiler,
0054:                JBossQLParserVisitor {
0055:            private static final Logger log = Logger
0056:                    .getLogger(EJBQLToSQL92Compiler.class);
0057:
0058:            // input objects
0059:            private final Catalog catalog;
0060:            private Class returnType;
0061:            private Class[] parameterTypes;
0062:            private JDBCReadAheadMetaData readAhead;
0063:
0064:            // alias info
0065:            private AliasManager aliasManager;
0066:            private Map joinPaths = new HashMap();
0067:            private Map identifierToTable = new HashMap();
0068:            private Set joinedAliases = new HashSet();
0069:
0070:            // mapping metadata
0071:            private JDBCTypeMappingMetaData typeMapping;
0072:            private JDBCTypeFactory typeFactory;
0073:
0074:            // output objects
0075:            private boolean forceDistinct;
0076:            private String sql;
0077:            private int offsetParam;
0078:            private int offsetValue;
0079:            private int limitParam;
0080:            private int limitValue;
0081:            private JDBCEntityPersistenceStore selectManager;
0082:            private Object selectObject;
0083:            private List inputParameters = new ArrayList();
0084:
0085:            private List leftJoinCMRList = new ArrayList();
0086:            private StringBuffer onFindCMRJoin;
0087:
0088:            private boolean countCompositePk;
0089:            private boolean selectDistinct;
0090:
0091:            public EJBQLToSQL92Compiler(Catalog catalog) {
0092:                this .catalog = catalog;
0093:            }
0094:
0095:            public void compileEJBQL(String ejbql, Class returnType,
0096:                    Class[] parameterTypes, JDBCQueryMetaData metadata)
0097:                    throws Exception {
0098:                // reset all state variables
0099:                reset();
0100:
0101:                // set input arguemts
0102:                this .returnType = returnType;
0103:                this .parameterTypes = parameterTypes;
0104:                this .readAhead = metadata.getReadAhead();
0105:
0106:                // get the parser
0107:                EJBQLParser parser = new EJBQLParser(new StringReader(""));
0108:
0109:                try {
0110:                    // parse the ejbql into an abstract sytax tree
0111:                    ASTEJBQL ejbqlNode = parser.parse(catalog, parameterTypes,
0112:                            ejbql);
0113:
0114:                    // translate to sql
0115:                    sql = ejbqlNode.jjtAccept(this , new StringBuffer())
0116:                            .toString();
0117:                } catch (Exception e) {
0118:                    // if there is a problem reset the state before exiting
0119:                    reset();
0120:                    throw e;
0121:                } catch (Error e) {
0122:                    // lame javacc lexer throws Errors
0123:                    reset();
0124:                    throw e;
0125:                }
0126:            }
0127:
0128:            public void compileJBossQL(String ejbql, Class returnType,
0129:                    Class[] parameterTypes, JDBCQueryMetaData metadata)
0130:                    throws Exception {
0131:                // reset all state variables
0132:                reset();
0133:
0134:                // set input arguemts
0135:                this .returnType = returnType;
0136:                this .parameterTypes = parameterTypes;
0137:                this .readAhead = metadata.getReadAhead();
0138:
0139:                // get the parser
0140:                JBossQLParser parser = new JBossQLParser(new StringReader(""));
0141:
0142:                try {
0143:                    // parse the ejbql into an abstract sytax tree
0144:                    ASTEJBQL ejbqlNode = parser.parse(catalog, parameterTypes,
0145:                            ejbql);
0146:
0147:                    // translate to sql
0148:                    sql = ejbqlNode.jjtAccept(this , new StringBuffer())
0149:                            .toString();
0150:
0151:                    if (log.isTraceEnabled()) {
0152:                        log.trace("ejbql: " + ejbql);
0153:                        log.trace("sql: " + sql);
0154:                    }
0155:                } catch (Exception e) {
0156:                    // if there is a problem reset the state before exiting
0157:                    reset();
0158:                    throw e;
0159:                } catch (Error e) {
0160:                    // lame javacc lexer throws Errors
0161:                    reset();
0162:                    throw e;
0163:                }
0164:            }
0165:
0166:            public String getSQL() {
0167:                return sql;
0168:            }
0169:
0170:            public int getOffsetValue() {
0171:                return offsetValue;
0172:            }
0173:
0174:            public int getOffsetParam() {
0175:                return offsetParam;
0176:            }
0177:
0178:            public int getLimitValue() {
0179:                return limitValue;
0180:            }
0181:
0182:            public int getLimitParam() {
0183:                return limitParam;
0184:            }
0185:
0186:            public boolean isSelectEntity() {
0187:                return selectObject instanceof  JDBCAbstractEntityBridge;
0188:            }
0189:
0190:            public JDBCAbstractEntityBridge getSelectEntity() {
0191:                return (JDBCAbstractEntityBridge) selectObject;
0192:            }
0193:
0194:            public boolean isSelectField() {
0195:                boolean result;
0196:                if (selectObject instanceof  JDBCFieldBridge) {
0197:                    JDBCFieldBridge field = (JDBCFieldBridge) selectObject;
0198:                    result = field.isCMPField();
0199:                } else {
0200:                    result = false;
0201:                }
0202:                return result;
0203:            }
0204:
0205:            public JDBCFieldBridge getSelectField() {
0206:                return (JDBCFieldBridge) selectObject;
0207:            }
0208:
0209:            public SelectFunction getSelectFunction() {
0210:                return (SelectFunction) selectObject;
0211:            }
0212:
0213:            public EntityPersistenceStore getStoreManager() {
0214:                return selectManager;
0215:            }
0216:
0217:            public List getInputParameters() {
0218:                return inputParameters;
0219:            }
0220:
0221:            public List getLeftJoinCMRList() {
0222:                return leftJoinCMRList;
0223:            }
0224:
0225:            public boolean isSelectDistinct() {
0226:                return selectDistinct;
0227:            }
0228:
0229:            public Object visit(SimpleNode node, Object data) {
0230:                throw new RuntimeException(
0231:                        "Internal error: Found unknown node type in "
0232:                                + "EJB-QL abstract syntax tree: node=" + node);
0233:            }
0234:
0235:            public Object visit(ASTEJBQL node, Object data) {
0236:                Node selectNode = node.jjtGetChild(0);
0237:                Node fromNode = node.jjtGetChild(1);
0238:
0239:                // compile selectNode
0240:                StringBuffer selectClause = new StringBuffer(50);
0241:                selectNode.jjtAccept(this , selectClause);
0242:
0243:                StringBuffer whereClause = null;
0244:                StringBuffer orderByClause = null;
0245:                for (int i = 2; i < node.jjtGetNumChildren(); ++i) {
0246:                    Node childNode = node.jjtGetChild(i);
0247:                    if (childNode instanceof  ASTWhere) {
0248:                        whereClause = new StringBuffer(20);
0249:                        childNode.jjtAccept(this , whereClause);
0250:                    } else if (childNode instanceof  ASTOrderBy) {
0251:                        orderByClause = new StringBuffer();
0252:                        childNode.jjtAccept(this , orderByClause);
0253:                    } else if (childNode instanceof  ASTLimitOffset) {
0254:                        childNode.jjtAccept(this , null);
0255:                    }
0256:                }
0257:
0258:                // compile fromNode
0259:                StringBuffer fromClause = new StringBuffer(30);
0260:                fromNode.jjtAccept(this , fromClause);
0261:
0262:                // left-join
0263:                for (Iterator iter = identifierToTable.entrySet().iterator(); iter
0264:                        .hasNext();) {
0265:                    final Map.Entry entry = (Map.Entry) iter.next();
0266:                    final String identifier = (String) entry.getKey();
0267:                    final String table = (String) entry.getValue();
0268:                    final String alias = aliasManager.getAlias(identifier);
0269:
0270:                    fromClause.append(table).append(' ').append(alias);
0271:                    join(alias, fromClause);
0272:
0273:                    if (iter.hasNext()) {
0274:                        fromClause.append(SQLUtil.COMMA);
0275:                    }
0276:                }
0277:
0278:                selectDistinct = ((ASTSelect) selectNode).distinct
0279:                        || returnType == Set.class || forceDistinct;
0280:
0281:                // assemble sql
0282:                StringBuffer sql = (StringBuffer) data;
0283:                if (selectManager.getMetaData().hasRowLocking()
0284:                        && !(selectObject instanceof  SelectFunction)) {
0285:                    JDBCFunctionMappingMetaData rowLockingTemplate = typeMapping
0286:                            .getRowLockingTemplate();
0287:                    if (rowLockingTemplate == null) {
0288:                        throw new IllegalStateException(
0289:                                "Row locking template is not defined for given mapping: "
0290:                                        + typeMapping.getName());
0291:                    }
0292:
0293:                    boolean distinct = selectDistinct;
0294:
0295:                    Object args[] = new Object[] {
0296:                            distinct ? SQLUtil.DISTINCT + selectClause
0297:                                    : selectClause.toString(),
0298:                            fromClause,
0299:                            whereClause == null || whereClause.length() == 0 ? null
0300:                                    : whereClause,
0301:                            orderByClause == null
0302:                                    || orderByClause.length() == 0 ? null
0303:                                    : orderByClause };
0304:                    rowLockingTemplate.getFunctionSql(args, sql);
0305:                } else {
0306:                    sql.append(SQLUtil.SELECT);
0307:                    if (selectDistinct) {
0308:                        sql.append(SQLUtil.DISTINCT);
0309:                    }
0310:                    sql.append(selectClause).append(SQLUtil.FROM).append(
0311:                            fromClause);
0312:
0313:                    if (whereClause != null && whereClause.length() > 0) {
0314:                        sql.append(SQLUtil.WHERE).append(whereClause);
0315:                    }
0316:
0317:                    if (orderByClause != null && orderByClause.length() > 0) {
0318:                        sql.append(SQLUtil.ORDERBY).append(orderByClause);
0319:                    }
0320:                }
0321:
0322:                if (countCompositePk) {
0323:                    sql.insert(0, "SELECT COUNT(*) FROM (").append(") t_count");
0324:                }
0325:
0326:                return data;
0327:            }
0328:
0329:            public Object visit(ASTOrderBy node, Object data) {
0330:                StringBuffer buf = (StringBuffer) data;
0331:                node.jjtGetChild(0).jjtAccept(this , data);
0332:                for (int i = 1; i < node.jjtGetNumChildren(); i++) {
0333:                    buf.append(SQLUtil.COMMA);
0334:                    node.jjtGetChild(i).jjtAccept(this , data);
0335:                }
0336:                return data;
0337:            }
0338:
0339:            public Object visit(ASTOrderByPath node, Object data) {
0340:                StringBuffer buf = (StringBuffer) data;
0341:                node.jjtGetChild(0).jjtAccept(this , data);
0342:                if (node.ascending) {
0343:                    buf.append(SQLUtil.ASC);
0344:                } else {
0345:                    buf.append(SQLUtil.DESC);
0346:                }
0347:                return data;
0348:            }
0349:
0350:            public Object visit(ASTLimitOffset node, Object data) {
0351:                int child = 0;
0352:                if (node.hasOffset) {
0353:                    Node offsetNode = node.jjtGetChild(child++);
0354:                    if (offsetNode instanceof  ASTParameter) {
0355:                        ASTParameter param = (ASTParameter) offsetNode;
0356:                        Class parameterType = getParameterType(param.number);
0357:                        if (int.class != parameterType
0358:                                && Integer.class != parameterType) {
0359:                            throw new IllegalStateException(
0360:                                    "OFFSET parameter must be an int");
0361:                        }
0362:                        offsetParam = param.number;
0363:                    } else {
0364:                        ASTExactNumericLiteral param = (ASTExactNumericLiteral) offsetNode;
0365:                        offsetValue = (int) param.value;
0366:                    }
0367:                }
0368:
0369:                if (node.hasLimit) {
0370:                    Node limitNode = node.jjtGetChild(child);
0371:                    if (limitNode instanceof  ASTParameter) {
0372:                        ASTParameter param = (ASTParameter) limitNode;
0373:                        Class parameterType = getParameterType(param.number);
0374:                        if (int.class != parameterType
0375:                                && Integer.class != parameterType) {
0376:                            throw new IllegalStateException(
0377:                                    "LIMIT parameter must be an int");
0378:                        }
0379:                        limitParam = param.number;
0380:                    } else {
0381:                        ASTExactNumericLiteral param = (ASTExactNumericLiteral) limitNode;
0382:                        limitValue = (int) param.value;
0383:                    }
0384:                }
0385:                return data;
0386:            }
0387:
0388:            public Object visit(ASTSelect select, Object data) {
0389:                StringBuffer sql = (StringBuffer) data;
0390:
0391:                final Node child0 = select.jjtGetChild(0);
0392:                final ASTPath path;
0393:                if (child0 instanceof  ASTPath) {
0394:                    path = (ASTPath) child0;
0395:
0396:                    if (path.isCMPField()) {
0397:                        // set the select object
0398:                        JDBCFieldBridge selectField = (JDBCFieldBridge) path
0399:                                .getCMPField();
0400:                        selectManager = selectField.getManager();
0401:                        selectObject = selectField;
0402:                        setTypeFactory(selectManager.getJDBCTypeFactory());
0403:
0404:                        // todo inner or left?
0405:                        //addLeftJoinPath(path);
0406:                        addInnerJoinPath(path);
0407:
0408:                        String alias = aliasManager.getAlias(path.getPath(path
0409:                                .size() - 2));
0410:                        SQLUtil.getColumnNamesClause(selectField, alias, sql);
0411:                    } else {
0412:                        JDBCAbstractEntityBridge selectEntity = (JDBCAbstractEntityBridge) path
0413:                                .getEntity();
0414:                        selectManager = selectEntity.getManager();
0415:                        selectObject = selectEntity;
0416:                        setTypeFactory(selectEntity.getManager()
0417:                                .getJDBCTypeFactory());
0418:
0419:                        final String alias = aliasManager.getAlias(path
0420:                                .getPath());
0421:                        if (select.distinct) {
0422:                            SQLUtil.getSearchableColumnNamesClause(selectEntity
0423:                                    .getTableFields(), alias, sql);
0424:                        } else {
0425:                            SQLUtil.getColumnNamesClause(selectEntity
0426:                                    .getTableFields(), alias, sql);
0427:                        }
0428:
0429:                        /*
0430:                        if(readAhead.isOnFind())
0431:                        {
0432:                           String eagerLoadGroupName = readAhead.getEagerLoadGroup();
0433:                           boolean[] loadGroupMask = selectEntity.getLoadGroupMask(eagerLoadGroupName);
0434:                           SQLUtil.appendColumnNamesClause(
0435:                              selectEntity.getTableFields(),
0436:                              loadGroupMask,
0437:                              alias,
0438:                              sql
0439:                           );
0440:                        }
0441:                         */
0442:
0443:                        addLeftJoinPath(path);
0444:                    }
0445:                } else {
0446:                    // the function should take a path expresion as a parameter
0447:                    path = getPathFromChildren(child0);
0448:
0449:                    if (path == null) {
0450:                        throw new IllegalStateException(
0451:                                "The function in SELECT clause does not contain a path expression.");
0452:                    }
0453:
0454:                    if (path.isCMPField()) {
0455:                        JDBCFieldBridge selectField = (JDBCFieldBridge) path
0456:                                .getCMPField();
0457:                        selectManager = selectField.getManager();
0458:                        setTypeFactory(selectManager.getJDBCTypeFactory());
0459:                    } else if (path.isCMRField()) {
0460:                        JDBCFieldBridge cmrField = (JDBCFieldBridge) path
0461:                                .getCMRField();
0462:                        selectManager = cmrField.getManager();
0463:                        setTypeFactory(selectManager.getJDBCTypeFactory());
0464:                        addLeftJoinPath(path);
0465:                    } else {
0466:                        final JDBCAbstractEntityBridge entity = (JDBCAbstractEntityBridge) path
0467:                                .getEntity();
0468:                        selectManager = entity.getManager();
0469:                        setTypeFactory(selectManager.getJDBCTypeFactory());
0470:                        addLeftJoinPath(path);
0471:                    }
0472:
0473:                    selectObject = child0;
0474:                    child0.jjtAccept(this , data);
0475:                }
0476:
0477:                return data;
0478:            }
0479:
0480:            public Object visit(ASTWhere node, Object data) {
0481:                node.jjtGetChild(0).jjtAccept(this , data);
0482:                return data;
0483:            }
0484:
0485:            public Object visit(ASTOr node, Object data) {
0486:                StringBuffer buf = (StringBuffer) data;
0487:                node.jjtGetChild(0).jjtAccept(this , data);
0488:                for (int i = 1; i < node.jjtGetNumChildren(); ++i) {
0489:                    buf.append(SQLUtil.OR);
0490:                    node.jjtGetChild(i).jjtAccept(this , data);
0491:                }
0492:                return data;
0493:            }
0494:
0495:            public Object visit(ASTWhereConditionalTerm node, Object data) {
0496:                for (int i = 0; i < node.jjtGetNumChildren(); ++i) {
0497:                    node.jjtGetChild(i).jjtAccept(this , data);
0498:                }
0499:                return data;
0500:            }
0501:
0502:            public Object visit(ASTAnd node, Object data) {
0503:                StringBuffer buf = (StringBuffer) data;
0504:                node.jjtGetChild(0).jjtAccept(this , data);
0505:                for (int i = 1; i < node.jjtGetNumChildren(); i++) {
0506:                    buf.append(SQLUtil.AND);
0507:                    node.jjtGetChild(i).jjtAccept(this , data);
0508:                }
0509:                return data;
0510:            }
0511:
0512:            public Object visit(ASTNot node, Object data) {
0513:                StringBuffer buf = (StringBuffer) data;
0514:                buf.append(SQLUtil.NOT);
0515:                node.jjtGetChild(0).jjtAccept(this , data);
0516:                return data;
0517:            }
0518:
0519:            public Object visit(ASTConditionalParenthetical node, Object data) {
0520:                StringBuffer buf = (StringBuffer) data;
0521:                buf.append('(');
0522:                node.jjtGetChild(0).jjtAccept(this , data);
0523:                buf.append(')');
0524:                return data;
0525:            }
0526:
0527:            public Object visit(ASTBetween node, Object data) {
0528:                StringBuffer buf = (StringBuffer) data;
0529:                node.jjtGetChild(0).jjtAccept(this , data);
0530:                if (node.not) {
0531:                    buf.append(SQLUtil.NOT);
0532:                }
0533:                buf.append(SQLUtil.BETWEEN);
0534:                node.jjtGetChild(1).jjtAccept(this , data);
0535:                buf.append(SQLUtil.AND);
0536:                node.jjtGetChild(2).jjtAccept(this , data);
0537:                return data;
0538:            }
0539:
0540:            public Object visit(ASTIn node, Object data) {
0541:                StringBuffer buf = (StringBuffer) data;
0542:                node.jjtGetChild(0).jjtAccept(this , data);
0543:                if (node.not) {
0544:                    buf.append(SQLUtil.NOT);
0545:                }
0546:                buf.append(SQLUtil.IN).append('(');
0547:                node.jjtGetChild(1).jjtAccept(this , data);
0548:                for (int i = 2; i < node.jjtGetNumChildren(); i++) {
0549:                    buf.append(SQLUtil.COMMA);
0550:                    node.jjtGetChild(i).jjtAccept(this , data);
0551:                }
0552:                buf.append(')');
0553:                return data;
0554:            }
0555:
0556:            public Object visit(ASTLike node, Object data) {
0557:                StringBuffer buf = (StringBuffer) data;
0558:                node.jjtGetChild(0).jjtAccept(this , data);
0559:                if (node.not) {
0560:                    buf.append(SQLUtil.NOT);
0561:                }
0562:                buf.append(SQLUtil.LIKE);
0563:                node.jjtGetChild(1).jjtAccept(this , data);
0564:                if (node.jjtGetNumChildren() == 3) {
0565:                    buf.append(" {ESCAPE ");
0566:                    node.jjtGetChild(2).jjtAccept(this , data);
0567:                    buf.append('}');
0568:                }
0569:                return data;
0570:            }
0571:
0572:            public Object visit(ASTNullComparison node, Object data) {
0573:                StringBuffer sql = (StringBuffer) data;
0574:
0575:                final Node child0 = node.jjtGetChild(0);
0576:                if (child0 instanceof  ASTPath) {
0577:                    ASTPath path = (ASTPath) child0;
0578:                    addLeftJoinPath(path);
0579:
0580:                    JDBCFieldBridge field = (JDBCFieldBridge) path.getField();
0581:
0582:                    if (field instanceof  JDBCAbstractCMRFieldBridge) {
0583:                        JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) field;
0584:                        final String alias;
0585:                        final JDBCFieldBridge[] keyFields;
0586:
0587:                        if (cmrField.hasForeignKey()) {
0588:                            alias = aliasManager.getAlias(path.getPath(path
0589:                                    .size() - 2));
0590:                            keyFields = cmrField.getForeignKeyFields();
0591:                        } else {
0592:                            alias = aliasManager.getAlias(path.getPath());
0593:                            if (cmrField.getMetaData().getRelationMetaData()
0594:                                    .isTableMappingStyle()) {
0595:                                keyFields = cmrField.getRelatedCMRField()
0596:                                        .getEntity().getPrimaryKeyFields();
0597:                            } else {
0598:                                keyFields = cmrField.getRelatedCMRField()
0599:                                        .getForeignKeyFields();
0600:                            }
0601:                        }
0602:
0603:                        SQLUtil
0604:                                .getIsNullClause(node.not, keyFields, alias,
0605:                                        sql);
0606:                    } else {
0607:                        String alias = aliasManager.getAlias(path.getPath(path
0608:                                .size() - 2));
0609:                        SQLUtil.getIsNullClause(node.not, field, alias, sql);
0610:                    }
0611:                } else if (child0 instanceof  ASTParameter) {
0612:                    ASTParameter param = (ASTParameter) child0;
0613:                    Class type = getParameterType(param.number);
0614:
0615:                    QueryParameter queryParam = new QueryParameter(
0616:                            param.number - 1, typeFactory.getJDBCType(type));
0617:                    inputParameters.add(queryParam);
0618:
0619:                    sql.append("? IS ");
0620:                    if (node.not) {
0621:                        sql.append(SQLUtil.NOT);
0622:                    }
0623:                    sql.append(SQLUtil.NULL);
0624:                } else {
0625:                    throw new IllegalStateException(
0626:                            "Unexpected node in IS NULL clause: " + node);
0627:                }
0628:
0629:                return data;
0630:            }
0631:
0632:            public Object visit(ASTIsEmpty node, Object data) {
0633:                ASTPath path = (ASTPath) node.jjtGetChild(0);
0634:                if (!path.isCMRField()) {
0635:                    throw new IllegalStateException(
0636:                            "IS EMPTY can be applied only to collection valued CMR field.");
0637:                }
0638:
0639:                addLeftJoinPath(path);
0640:
0641:                StringBuffer sql = (StringBuffer) data;
0642:                JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) path
0643:                        .getCMRField();
0644:                JDBCAbstractEntityBridge relatedEntity = (JDBCAbstractEntityBridge) cmrField
0645:                        .getRelatedEntity();
0646:                String alias = aliasManager.getAlias(path.getPath());
0647:                SQLUtil.getIsNullClause(node.not, relatedEntity
0648:                        .getPrimaryKeyFields(), alias, sql);
0649:
0650:                return data;
0651:            }
0652:
0653:            public Object visit(ASTMemberOf node, Object data) {
0654:                Node member = node.jjtGetChild(0);
0655:                ASTPath colPath = (ASTPath) node.jjtGetChild(1);
0656:                JDBCAbstractEntityBridge colEntity = (JDBCAbstractEntityBridge) colPath
0657:                        .getEntity();
0658:
0659:                StringBuffer sql = (StringBuffer) data;
0660:
0661:                if (node.not) {
0662:                    sql.append(SQLUtil.NOT);
0663:                }
0664:
0665:                sql.append(SQLUtil.EXISTS).append('(').append(SQLUtil.SELECT);
0666:
0667:                if (member instanceof  ASTParameter) {
0668:                    ASTParameter toParam = (ASTParameter) member;
0669:                    verifyParameterEntityType(toParam.number, colEntity);
0670:                    inputParameters.addAll(QueryParameter.createParameters(
0671:                            toParam.number - 1, colEntity));
0672:
0673:                    String parentAlias = aliasManager.getAlias(colPath
0674:                            .getPath(0));
0675:                    String localParentAlias = aliasManager.getAlias(colPath
0676:                            .getPath(0)
0677:                            + "_local");
0678:                    JDBCAbstractEntityBridge parentEntity = (JDBCAbstractEntityBridge) colPath
0679:                            .getEntity(0);
0680:                    SQLUtil.getColumnNamesClause(parentEntity
0681:                            .getPrimaryKeyFields(), localParentAlias, sql);
0682:                    sql.append(SQLUtil.FROM).append(
0683:                            parentEntity.getQualifiedTableName()).append(' ')
0684:                            .append(localParentAlias);
0685:                    innerJoinPath(colPath, sql);
0686:
0687:                    sql.append(SQLUtil.WHERE);
0688:
0689:                    JDBCAbstractEntityBridge col0 = (JDBCAbstractEntityBridge) colPath
0690:                            .getEntity(0);
0691:                    SQLUtil.getSelfCompareWhereClause(col0
0692:                            .getPrimaryKeyFields(), parentAlias,
0693:                            localParentAlias, sql);
0694:                    sql.append(SQLUtil.AND);
0695:
0696:                    String localColAlias = aliasManager.getAlias(colPath
0697:                            .getPath()
0698:                            + "_local");
0699:                    SQLUtil.getWhereClause(colEntity.getPrimaryKeyFields(),
0700:                            localColAlias, sql);
0701:                } else {
0702:                    ASTPath memberPath = (ASTPath) member;
0703:                    JDBCAbstractEntityBridge memberEntity = (JDBCAbstractEntityBridge) memberPath
0704:                            .getEntity();
0705:
0706:                    if (!memberEntity.equals(colEntity)) {
0707:                        throw new IllegalStateException(
0708:                                "Member must be if the same type as the collection, got: member="
0709:                                        + memberEntity.getEntityName()
0710:                                        + ", collection="
0711:                                        + colEntity.getEntityName());
0712:                    }
0713:
0714:                    String memberAlias = aliasManager.getAlias(memberPath
0715:                            .getPath());
0716:
0717:                    if (memberPath.size() > 1) {
0718:                        String parentAlias = aliasManager.getAlias(memberPath
0719:                                .getPath(0)
0720:                                + "_local");
0721:                        JDBCAbstractEntityBridge parentEntity = (JDBCAbstractEntityBridge) memberPath
0722:                                .getEntity(0);
0723:                        SQLUtil.getColumnNamesClause(parentEntity
0724:                                .getPrimaryKeyFields(), parentAlias, sql);
0725:                        sql.append(SQLUtil.FROM).append(
0726:                                parentEntity.getQualifiedTableName()).append(
0727:                                ' ').append(parentAlias);
0728:                        innerJoinPath(memberPath, sql);
0729:                        innerJoinPath(colPath, sql);
0730:                    } else if (colPath.size() > 1) {
0731:                        String parentAlias = aliasManager.getAlias(colPath
0732:                                .getPath(0)
0733:                                + "_local");
0734:                        JDBCAbstractEntityBridge parentEntity = (JDBCAbstractEntityBridge) colPath
0735:                                .getEntity(0);
0736:                        SQLUtil.getColumnNamesClause(parentEntity
0737:                                .getPrimaryKeyFields(), parentAlias, sql);
0738:                        sql.append(SQLUtil.FROM).append(
0739:                                parentEntity.getQualifiedTableName()).append(
0740:                                ' ').append(parentAlias);
0741:                        innerJoinPath(colPath, sql);
0742:                    } else {
0743:                        throw new IllegalStateException(
0744:                                "There should be collection valued path expression, not identification variable.");
0745:                    }
0746:
0747:                    sql.append(SQLUtil.WHERE);
0748:
0749:                    JDBCAbstractEntityBridge member0 = (JDBCAbstractEntityBridge) memberPath
0750:                            .getEntity(0);
0751:                    String colAliasLocal = aliasManager.getAlias(colPath
0752:                            .getPath()
0753:                            + "_local");
0754:                    if (memberPath.size() > 1) {
0755:                        String memberAliasLocal = aliasManager
0756:                                .getAlias(memberPath.getPath() + "_local");
0757:                        SQLUtil.getSelfCompareWhereClause(colEntity
0758:                                .getPrimaryKeyFields(), memberAliasLocal,
0759:                                colAliasLocal, sql);
0760:
0761:                        sql.append(SQLUtil.AND);
0762:
0763:                        String member0Alias = aliasManager.getAlias(memberPath
0764:                                .getPath(0));
0765:                        String member0AliasLocal = aliasManager
0766:                                .getAlias(memberPath.getPath(0) + "_local");
0767:                        SQLUtil.getSelfCompareWhereClause(member0
0768:                                .getPrimaryKeyFields(), member0Alias,
0769:                                member0AliasLocal, sql);
0770:                    } else {
0771:                        SQLUtil.getSelfCompareWhereClause(member0
0772:                                .getPrimaryKeyFields(), memberAlias,
0773:                                colAliasLocal, sql);
0774:                    }
0775:                }
0776:
0777:                sql.append(')');
0778:
0779:                return data;
0780:            }
0781:
0782:            private void innerJoinPath(ASTPath path, StringBuffer sql) {
0783:                if (path.size() < 2) {
0784:                    return;
0785:                }
0786:
0787:                String parentAlias = aliasManager.getAlias(path.getPath(0)
0788:                        + "_local");
0789:                String leftAlias = parentAlias;
0790:                for (int i = 1; i < path.size(); ++i) {
0791:                    String curPath = path.getPath(i);
0792:                    final String joinAlias = aliasManager.getAlias(curPath
0793:                            + "_local");
0794:
0795:                    final JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) path
0796:                            .getCMRField(i);
0797:                    final JDBCAbstractEntityBridge joinEntity = (JDBCAbstractEntityBridge) cmrField
0798:                            .getRelatedEntity();
0799:
0800:                    JDBCRelationMetaData relation = cmrField.getMetaData()
0801:                            .getRelationMetaData();
0802:
0803:                    String join = " INNER JOIN ";
0804:
0805:                    if (relation.isTableMappingStyle()) {
0806:                        String relTableAlias = aliasManager
0807:                                .getRelationTableAlias(curPath + "_local");
0808:                        sql.append(join).append(
0809:                                cmrField.getQualifiedTableName()).append(' ')
0810:                                .append(relTableAlias).append(" ON ");
0811:                        SQLUtil.getRelationTableJoinClause(cmrField, leftAlias,
0812:                                relTableAlias, sql);
0813:
0814:                        sql.append(join).append(
0815:                                joinEntity.getQualifiedTableName()).append(' ')
0816:                                .append(joinAlias).append(" ON ");
0817:                        SQLUtil.getRelationTableJoinClause(cmrField
0818:                                .getRelatedCMRField(), joinAlias,
0819:                                relTableAlias, sql);
0820:                    } else {
0821:                        sql.append(join).append(
0822:                                joinEntity.getQualifiedTableName()).append(' ')
0823:                                .append(joinAlias).append(" ON ");
0824:
0825:                        SQLUtil.getJoinClause(cmrField, leftAlias, joinAlias,
0826:                                sql);
0827:                    }
0828:
0829:                    leftAlias = joinAlias;
0830:                }
0831:            }
0832:
0833:            public Object visit(ASTStringComparison node, Object data) {
0834:                StringBuffer buf = (StringBuffer) data;
0835:                node.jjtGetChild(0).jjtAccept(this , data);
0836:                buf.append(' ').append(node.opp).append(' ');
0837:                node.jjtGetChild(1).jjtAccept(this , data);
0838:                return data;
0839:            }
0840:
0841:            public Object visit(ASTBooleanComparison node, Object data) {
0842:                StringBuffer buf = (StringBuffer) data;
0843:                node.jjtGetChild(0).jjtAccept(this , data);
0844:                if (node.jjtGetNumChildren() == 2) {
0845:                    buf.append(' ').append(node.opp).append(' ');
0846:                    node.jjtGetChild(1).jjtAccept(this , data);
0847:                }
0848:                return data;
0849:            }
0850:
0851:            public Object visit(ASTDatetimeComparison node, Object data) {
0852:                StringBuffer buf = (StringBuffer) data;
0853:                node.jjtGetChild(0).jjtAccept(this , data);
0854:                buf.append(' ').append(node.opp).append(' ');
0855:                node.jjtGetChild(1).jjtAccept(this , data);
0856:                return data;
0857:            }
0858:
0859:            public Object visit(ASTValueClassComparison node, Object data) {
0860:                StringBuffer buf = (StringBuffer) data;
0861:
0862:                boolean not = (node.opp.equals(SQLUtil.NOT_EQUAL));
0863:                String comparison = node.opp;
0864:                buf.append('(');
0865:                if (not) {
0866:                    buf.append(SQLUtil.NOT).append('(');
0867:                    comparison = "=";
0868:                }
0869:
0870:                // setup the from path
0871:                ASTPath fromPath = (ASTPath) node.jjtGetChild(0);
0872:                addInnerJoinPath(fromPath);
0873:                String fromAlias = aliasManager.getAlias(fromPath
0874:                        .getPath(fromPath.size() - 2));
0875:                CMPFieldBridge fromCMPField = (CMPFieldBridge) fromPath
0876:                        .getCMPField();
0877:
0878:                Node toNode = node.jjtGetChild(1);
0879:                if (toNode instanceof  ASTParameter) {
0880:                    ASTParameter toParam = (ASTParameter) toNode;
0881:
0882:                    // can only compare like kind entities
0883:                    Class parameterType = getParameterType(toParam.number);
0884:                    if (!(fromCMPField.getFieldType().equals(parameterType))) {
0885:                        throw new IllegalStateException(
0886:                                "Only like types can be "
0887:                                        + "compared: from CMP field="
0888:                                        + fromCMPField.getFieldType()
0889:                                        + " to parameter=" + parameterType);
0890:                    }
0891:
0892:                    inputParameters.addAll(QueryParameter.createParameters(
0893:                            toParam.number - 1, fromCMPField));
0894:                    SQLUtil.getWhereClause(fromCMPField.getJDBCType(),
0895:                            fromAlias, comparison, buf);
0896:                } else {
0897:                    ASTPath toPath = (ASTPath) toNode;
0898:                    addInnerJoinPath(toPath);
0899:                    String toAlias = aliasManager.getAlias(toPath
0900:                            .getPath(toPath.size() - 2));
0901:                    JDBCCMPFieldBridge toCMPField = (JDBCCMPFieldBridge) toPath
0902:                            .getCMPField();
0903:
0904:                    // can only compare like kind entities
0905:                    if (!(fromCMPField.getFieldType().equals(toCMPField
0906:                            .getFieldType()))) {
0907:                        throw new IllegalStateException(
0908:                                "Only like types can be "
0909:                                        + "compared: from CMP field="
0910:                                        + fromCMPField.getFieldType()
0911:                                        + " to CMP field="
0912:                                        + toCMPField.getFieldType());
0913:                    }
0914:
0915:                    SQLUtil.getSelfCompareWhereClause(fromCMPField, toCMPField,
0916:                            fromAlias, toAlias, comparison, buf);
0917:                }
0918:
0919:                return (not ? buf.append(')') : buf).append(')');
0920:            }
0921:
0922:            public Object visit(ASTEntityComparison node, Object data) {
0923:                StringBuffer buf = (StringBuffer) data;
0924:                Node arg0 = node.jjtGetChild(0);
0925:                Node arg1 = node.jjtGetChild(1);
0926:                if (node.opp.equals(SQLUtil.NOT_EQUAL)) {
0927:                    compareEntity(true, arg0, arg1, buf);
0928:                } else {
0929:                    compareEntity(false, arg0, arg1, buf);
0930:                }
0931:                return data;
0932:            }
0933:
0934:            public Object visit(ASTArithmeticComparison node, Object data) {
0935:                StringBuffer buf = (StringBuffer) data;
0936:                node.jjtGetChild(0).jjtAccept(this , data);
0937:                buf.append(' ').append(node.opp).append(' ');
0938:                node.jjtGetChild(1).jjtAccept(this , data);
0939:                return data;
0940:            }
0941:
0942:            public Object visit(ASTPlusMinus node, Object data) {
0943:                StringBuffer buf = (StringBuffer) data;
0944:                node.jjtGetChild(0).jjtAccept(this , data);
0945:                for (int i = 1; i < node.jjtGetNumChildren(); i++) {
0946:                    buf.append(' ').append(node.opps.get(i - 1)).append(' ');
0947:                    node.jjtGetChild(i).jjtAccept(this , data);
0948:                }
0949:                return data;
0950:            }
0951:
0952:            public Object visit(ASTMultDiv node, Object data) {
0953:                StringBuffer buf = (StringBuffer) data;
0954:                node.jjtGetChild(0).jjtAccept(this , data);
0955:                for (int i = 1; i < node.jjtGetNumChildren(); i++) {
0956:                    buf.append(' ').append(node.opps.get(i - 1)).append(' ');
0957:                    node.jjtGetChild(i).jjtAccept(this , data);
0958:                }
0959:                return data;
0960:            }
0961:
0962:            public Object visit(ASTNegation node, Object data) {
0963:                StringBuffer buf = (StringBuffer) data;
0964:                buf.append('-');
0965:                node.jjtGetChild(0).jjtAccept(this , data);
0966:                return data;
0967:            }
0968:
0969:            public Object visit(ASTArithmeticParenthetical node, Object data) {
0970:                StringBuffer buf = (StringBuffer) data;
0971:                buf.append('(');
0972:                node.jjtGetChild(0).jjtAccept(this , data);
0973:                buf.append(')');
0974:                return data;
0975:            }
0976:
0977:            public Object visit(ASTStringParenthetical node, Object data) {
0978:                StringBuffer buf = (StringBuffer) data;
0979:                buf.append('(');
0980:                node.jjtGetChild(0).jjtAccept(this , data);
0981:                buf.append(')');
0982:                return data;
0983:            }
0984:
0985:            public Object visit(ASTConcat node, Object data) {
0986:                StringBuffer buf = (StringBuffer) data;
0987:                JDBCFunctionMappingMetaData function = typeMapping
0988:                        .getFunctionMapping(JDBCTypeMappingMetaData.CONCAT);
0989:                Object[] args = childrenToStringArr(2, node);
0990:                function.getFunctionSql(args, buf);
0991:                return data;
0992:            }
0993:
0994:            public Object visit(ASTSubstring node, Object data) {
0995:                StringBuffer buf = (StringBuffer) data;
0996:                JDBCFunctionMappingMetaData function = typeMapping
0997:                        .getFunctionMapping(JDBCTypeMappingMetaData.SUBSTRING);
0998:                Object[] args = childrenToStringArr(3, node);
0999:                function.getFunctionSql(args, buf);
1000:                return data;
1001:            }
1002:
1003:            public Object visit(ASTUCase node, Object data) {
1004:                StringBuffer buf = (StringBuffer) data;
1005:                JDBCFunctionMappingMetaData function = typeMapping
1006:                        .getFunctionMapping(JDBCTypeMappingMetaData.UCASE);
1007:                Object[] args = childrenToStringArr(1, node);
1008:                function.getFunctionSql(args, buf);
1009:                return data;
1010:            }
1011:
1012:            public Object visit(ASTLCase node, Object data) {
1013:                StringBuffer buf = (StringBuffer) data;
1014:                JDBCFunctionMappingMetaData function = typeMapping
1015:                        .getFunctionMapping(JDBCTypeMappingMetaData.LCASE);
1016:                Object[] args = childrenToStringArr(1, node);
1017:                function.getFunctionSql(args, buf);
1018:                return data;
1019:            }
1020:
1021:            public Object visit(ASTLength node, Object data) {
1022:                StringBuffer buf = (StringBuffer) data;
1023:                JDBCFunctionMappingMetaData function = typeMapping
1024:                        .getFunctionMapping(JDBCTypeMappingMetaData.LENGTH);
1025:                Object[] args = childrenToStringArr(1, node);
1026:                function.getFunctionSql(args, buf);
1027:                return data;
1028:            }
1029:
1030:            public Object visit(ASTLocate node, Object data) {
1031:                StringBuffer buf = (StringBuffer) data;
1032:                JDBCFunctionMappingMetaData function = typeMapping
1033:                        .getFunctionMapping(JDBCTypeMappingMetaData.LOCATE);
1034:                Object[] args = new Object[3];
1035:                args[0] = node.jjtGetChild(0).jjtAccept(this ,
1036:                        new StringBuffer()).toString();
1037:                args[1] = node.jjtGetChild(1).jjtAccept(this ,
1038:                        new StringBuffer()).toString();
1039:                if (node.jjtGetNumChildren() == 3) {
1040:                    args[2] = node.jjtGetChild(2).jjtAccept(this ,
1041:                            new StringBuffer()).toString();
1042:                } else {
1043:                    args[2] = "1";
1044:                }
1045:                function.getFunctionSql(args, buf);
1046:                return data;
1047:            }
1048:
1049:            public Object visit(ASTAbs node, Object data) {
1050:                StringBuffer buf = (StringBuffer) data;
1051:                JDBCFunctionMappingMetaData function = typeMapping
1052:                        .getFunctionMapping(JDBCTypeMappingMetaData.ABS);
1053:                Object[] args = childrenToStringArr(1, node);
1054:                function.getFunctionSql(args, buf);
1055:                return data;
1056:            }
1057:
1058:            public Object visit(ASTSqrt node, Object data) {
1059:                StringBuffer buf = (StringBuffer) data;
1060:                JDBCFunctionMappingMetaData function = typeMapping
1061:                        .getFunctionMapping(JDBCTypeMappingMetaData.SQRT);
1062:                Object[] args = childrenToStringArr(1, node);
1063:                function.getFunctionSql(args, buf);
1064:                return data;
1065:            }
1066:
1067:            public Object visit(ASTMod node, Object data) {
1068:                StringBuffer buf = (StringBuffer) data;
1069:                JDBCFunctionMappingMetaData function = typeMapping
1070:                        .getFunctionMapping(JDBCTypeMappingMetaData.MOD);
1071:                Object[] args = childrenToStringArr(2, node);
1072:                function.getFunctionSql(args, buf);
1073:                return data;
1074:            }
1075:
1076:            public Object visit(ASTAvg node, Object data) {
1077:                node.setResultType(returnType);
1078:                StringBuffer buf = (StringBuffer) data;
1079:                Object[] args = new Object[] {
1080:                        node.distinct,
1081:                        node.jjtGetChild(0).jjtAccept(this , new StringBuffer())
1082:                                .toString(), };
1083:                JDBCTypeMappingMetaData.AVG_FUNC.getFunctionSql(args, buf);
1084:                return data;
1085:            }
1086:
1087:            public Object visit(ASTMax node, Object data) {
1088:                node.setResultType(returnType);
1089:                StringBuffer buf = (StringBuffer) data;
1090:                Object[] args = new Object[] {
1091:                        node.distinct,
1092:                        node.jjtGetChild(0).jjtAccept(this , new StringBuffer())
1093:                                .toString(), };
1094:                JDBCTypeMappingMetaData.MAX_FUNC.getFunctionSql(args, buf);
1095:                return data;
1096:            }
1097:
1098:            public Object visit(ASTMin node, Object data) {
1099:                node.setResultType(returnType);
1100:                StringBuffer buf = (StringBuffer) data;
1101:                Object[] args = new Object[] {
1102:                        node.distinct,
1103:                        node.jjtGetChild(0).jjtAccept(this , new StringBuffer())
1104:                                .toString(), };
1105:                JDBCTypeMappingMetaData.MIN_FUNC.getFunctionSql(args, buf);
1106:                return data;
1107:            }
1108:
1109:            public Object visit(ASTSum node, Object data) {
1110:                node.setResultType(returnType);
1111:                StringBuffer buf = (StringBuffer) data;
1112:                Object[] args = new Object[] {
1113:                        node.distinct,
1114:                        node.jjtGetChild(0).jjtAccept(this , new StringBuffer())
1115:                                .toString(), };
1116:                JDBCTypeMappingMetaData.SUM_FUNC.getFunctionSql(args, buf);
1117:                return data;
1118:            }
1119:
1120:            public Object visit(ASTCount node, Object data) {
1121:                StringBuffer buf = (StringBuffer) data;
1122:                node.setResultType(returnType);
1123:
1124:                Object args[];
1125:                final ASTPath cntPath = (ASTPath) node.jjtGetChild(0);
1126:                if (cntPath.isCMPField()) {
1127:                    args = new Object[] {
1128:                            node.distinct,
1129:                            node.jjtGetChild(0).jjtAccept(this ,
1130:                                    new StringBuffer()).toString() };
1131:                } else {
1132:                    JDBCAbstractEntityBridge entity = (JDBCAbstractEntityBridge) cntPath
1133:                            .getEntity();
1134:                    final JDBCFieldBridge[] pkFields = entity
1135:                            .getPrimaryKeyFields();
1136:                    if (pkFields.length > 1) {
1137:                        countCompositePk = true;
1138:                        forceDistinct = node.distinct.length() > 0;
1139:
1140:                        addLeftJoinPath(cntPath);
1141:
1142:                        String alias = aliasManager.getAlias(cntPath.getPath());
1143:                        SQLUtil.getColumnNamesClause(entity
1144:                                .getPrimaryKeyFields(), alias, buf);
1145:
1146:                        return buf;
1147:                    } else {
1148:                        final String alias = aliasManager.getAlias(cntPath
1149:                                .getPath());
1150:                        StringBuffer keyColumn = new StringBuffer(20);
1151:                        SQLUtil.getColumnNamesClause(pkFields[0], alias,
1152:                                keyColumn);
1153:                        args = new Object[] { node.distinct,
1154:                                keyColumn.toString() };
1155:                    }
1156:                }
1157:
1158:                JDBCTypeMappingMetaData.COUNT_FUNC.getFunctionSql(args, buf);
1159:                return data;
1160:            }
1161:
1162:            public Object visit(ASTPath node, Object data) {
1163:                StringBuffer buf = (StringBuffer) data;
1164:                if (!node.isCMPField()) {
1165:                    throw new IllegalStateException(
1166:                            "Can only visit cmp valued path node. "
1167:                                    + "Should have been handled at a higher level.");
1168:                }
1169:
1170:                JDBCFieldBridge cmpField = (JDBCFieldBridge) node.getCMPField();
1171:
1172:                // make sure this is mapped to a single column
1173:                switch (node.type) {
1174:                case EJBQLTypes.ENTITY_TYPE:
1175:                case EJBQLTypes.VALUE_CLASS_TYPE:
1176:                    if (cmpField.getJDBCType().hasMapper()
1177:                            || cmpField.getJDBCType().getParameterSetter() != null) {
1178:                        break;
1179:                    }
1180:                case EJBQLTypes.UNKNOWN_TYPE:
1181:                    throw new IllegalStateException(
1182:                            "Can not visit multi-column path "
1183:                                    + "node. Should have been handled at a higher level.");
1184:                }
1185:
1186:                addLeftJoinPath(node);
1187:                String alias = aliasManager.getAlias(node
1188:                        .getPath(node.size() - 2));
1189:                SQLUtil.getColumnNamesClause(cmpField, alias, buf);
1190:                return data;
1191:            }
1192:
1193:            public Object visit(ASTAbstractSchema node, Object data) {
1194:                throw new IllegalStateException(
1195:                        "Can not visit abstract schema node. "
1196:                                + " Should have been handled at a higher level.");
1197:            }
1198:
1199:            public Object visit(ASTIdentifier node, Object data) {
1200:                throw new UnsupportedOperationException(
1201:                        "Must not visit ASTIdentifier noe.");
1202:            }
1203:
1204:            public Object visit(ASTParameter node, Object data) {
1205:                StringBuffer buf = (StringBuffer) data;
1206:                Class type = getParameterType(node.number);
1207:
1208:                // make sure this is mapped to a single column
1209:                int ejbqlType = EJBQLTypes.getEJBQLType(type);
1210:                if (ejbqlType == EJBQLTypes.ENTITY_TYPE
1211:                        || ejbqlType == EJBQLTypes.VALUE_CLASS_TYPE
1212:                        || ejbqlType == EJBQLTypes.UNKNOWN_TYPE) {
1213:                    throw new IllegalStateException(
1214:                            "Can not visit multi-column "
1215:                                    + "parameter node. Should have been handled at a higher level.");
1216:                }
1217:
1218:                QueryParameter param = new QueryParameter(node.number - 1,
1219:                        typeFactory.getJDBCType(type));
1220:                inputParameters.add(param);
1221:                buf.append('?');
1222:
1223:                return data;
1224:            }
1225:
1226:            public Object visit(ASTExactNumericLiteral node, Object data) {
1227:                StringBuffer buf = (StringBuffer) data;
1228:                buf.append(node.literal);
1229:                return data;
1230:            }
1231:
1232:            public Object visit(ASTApproximateNumericLiteral node, Object data) {
1233:                StringBuffer buf = (StringBuffer) data;
1234:                buf.append(node.literal);
1235:                return data;
1236:            }
1237:
1238:            public Object visit(ASTStringLiteral node, Object data) {
1239:                StringBuffer buf = (StringBuffer) data;
1240:                buf.append(node.value);
1241:                return data;
1242:            }
1243:
1244:            public Object visit(ASTBooleanLiteral node, Object data) {
1245:                StringBuffer buf = (StringBuffer) data;
1246:                if (node.value) {
1247:                    buf.append(typeMapping.getTrueMapping());
1248:                } else {
1249:                    buf.append(typeMapping.getFalseMapping());
1250:                }
1251:                return data;
1252:            }
1253:
1254:            public Object visit(ASTFrom from, Object data) {
1255:                StringBuffer sql = (StringBuffer) data;
1256:                from.jjtGetChild(0).jjtAccept(this , data);
1257:                for (int i = 1; i < from.jjtGetNumChildren(); ++i) {
1258:                    from.jjtGetChild(i).jjtAccept(this , data);
1259:                }
1260:
1261:                return data;
1262:            }
1263:
1264:            public Object visit(ASTCollectionMemberDeclaration node, Object data) {
1265:                ASTPath path = (ASTPath) node.jjtGetChild(0);
1266:
1267:                // assign the same alias for path and identifier
1268:                ASTIdentifier id = (ASTIdentifier) node.jjtGetChild(1);
1269:                String alias = aliasManager.getAlias(id.identifier);
1270:                aliasManager.addAlias(path.getPath(), alias);
1271:
1272:                addInnerJoinPath(path);
1273:
1274:                return data;
1275:            }
1276:
1277:            public Object visit(ASTRangeVariableDeclaration node, Object data) {
1278:                ASTAbstractSchema schema = (ASTAbstractSchema) node
1279:                        .jjtGetChild(0);
1280:                JDBCAbstractEntityBridge entity = (JDBCAbstractEntityBridge) schema.entity;
1281:                ASTIdentifier id = (ASTIdentifier) node.jjtGetChild(1);
1282:                declareTable(id.identifier, entity.getQualifiedTableName());
1283:                return data;
1284:            }
1285:
1286:            // Private
1287:
1288:            private void compareEntity(boolean not, Node fromNode, Node toNode,
1289:                    StringBuffer buf) {
1290:                buf.append('(');
1291:                if (not) {
1292:                    buf.append(SQLUtil.NOT).append('(');
1293:                }
1294:
1295:                ASTPath fromPath = (ASTPath) fromNode;
1296:                addLeftJoinPath(fromPath);
1297:                String fromAlias = aliasManager.getAlias(fromPath.getPath());
1298:                JDBCAbstractEntityBridge fromEntity = (JDBCAbstractEntityBridge) fromPath
1299:                        .getEntity();
1300:
1301:                if (toNode instanceof  ASTParameter) {
1302:                    ASTParameter toParam = (ASTParameter) toNode;
1303:
1304:                    // can only compare like kind entities
1305:                    verifyParameterEntityType(toParam.number, fromEntity);
1306:
1307:                    inputParameters.addAll(QueryParameter.createParameters(
1308:                            toParam.number - 1, fromEntity));
1309:
1310:                    SQLUtil.getWhereClause(fromEntity.getPrimaryKeyFields(),
1311:                            fromAlias, buf);
1312:                } else {
1313:                    ASTPath toPath = (ASTPath) toNode;
1314:                    addLeftJoinPath(toPath);
1315:                    String toAlias = aliasManager.getAlias(toPath.getPath());
1316:                    JDBCAbstractEntityBridge toEntity = (JDBCAbstractEntityBridge) toPath
1317:                            .getEntity();
1318:
1319:                    // can only compare like kind entities
1320:                    if (!fromEntity.equals(toEntity)) {
1321:                        throw new IllegalStateException(
1322:                                "Only like types can be "
1323:                                        + "compared: from entity="
1324:                                        + fromEntity.getEntityName()
1325:                                        + " to entity="
1326:                                        + toEntity.getEntityName());
1327:                    }
1328:
1329:                    SQLUtil.getSelfCompareWhereClause(fromEntity
1330:                            .getPrimaryKeyFields(), fromAlias, toAlias, buf);
1331:                }
1332:
1333:                if (not) {
1334:                    buf.append(')');
1335:                }
1336:                buf.append(')');
1337:            }
1338:
1339:            private void join(String alias, StringBuffer sql) {
1340:                Map paths = (Map) joinPaths.get(alias);
1341:                if (paths == null || paths.isEmpty()) {
1342:                    return;
1343:                }
1344:
1345:                for (Iterator iter = paths.values().iterator(); iter.hasNext();) {
1346:                    String leftAlias = alias;
1347:                    ASTPath path = (ASTPath) iter.next();
1348:                    for (int i = 1; i < path.size(); ++i) {
1349:                        if (path.isCMRField(i)) {
1350:                            final String curPath = path.getPath(i);
1351:                            final String joinAlias = aliasManager
1352:                                    .getAlias(curPath);
1353:
1354:                            if (joinedAliases.add(joinAlias)) {
1355:                                final JDBCAbstractCMRFieldBridge cmrField = (JDBCAbstractCMRFieldBridge) path
1356:                                        .getCMRField(i);
1357:                                final JDBCAbstractEntityBridge joinEntity = (JDBCAbstractEntityBridge) cmrField
1358:                                        .getRelatedEntity();
1359:
1360:                                JDBCRelationMetaData relation = cmrField
1361:                                        .getMetaData().getRelationMetaData();
1362:
1363:                                String join = (path.innerJoin ? " INNER JOIN "
1364:                                        : " LEFT OUTER JOIN ");
1365:
1366:                                if (relation.isTableMappingStyle()) {
1367:                                    String relTableAlias = aliasManager
1368:                                            .getRelationTableAlias(curPath);
1369:                                    sql.append(join).append(
1370:                                            cmrField.getQualifiedTableName())
1371:                                            .append(' ').append(relTableAlias)
1372:                                            .append(" ON ");
1373:                                    SQLUtil.getRelationTableJoinClause(
1374:                                            cmrField, leftAlias, relTableAlias,
1375:                                            sql);
1376:
1377:                                    sql.append(join).append(
1378:                                            joinEntity.getQualifiedTableName())
1379:                                            .append(' ').append(joinAlias)
1380:                                            .append(" ON ");
1381:                                    SQLUtil.getRelationTableJoinClause(cmrField
1382:                                            .getRelatedCMRField(), joinAlias,
1383:                                            relTableAlias, sql);
1384:                                } else {
1385:                                    sql.append(join).append(
1386:                                            joinEntity.getQualifiedTableName())
1387:                                            .append(' ').append(joinAlias)
1388:                                            .append(" ON ");
1389:
1390:                                    SQLUtil.getJoinClause(cmrField, leftAlias,
1391:                                            joinAlias, sql);
1392:                                }
1393:
1394:                                join(joinAlias, sql);
1395:                            }
1396:                            leftAlias = joinAlias;
1397:                        }
1398:                    }
1399:                }
1400:            }
1401:
1402:            private void declareTable(String alias, String table) {
1403:                identifierToTable.put(alias, table);
1404:            }
1405:
1406:            private void addLeftJoinPath(ASTPath path) {
1407:                if (path.size() > 1 && path.isCMRField(1)) {
1408:                    final String identifier = path.getPath(0);
1409:                    final String alias = aliasManager.getAlias(identifier);
1410:                    Map paths = (Map) joinPaths.get(alias);
1411:                    if (paths == null) {
1412:                        paths = new HashMap();
1413:                        joinPaths.put(alias, paths);
1414:                    }
1415:
1416:                    ASTPath oldPath = (ASTPath) paths.put(path, path);
1417:                    if (oldPath != null && oldPath.innerJoin) {
1418:                        path.innerJoin = true;
1419:                    }
1420:                }
1421:            }
1422:
1423:            private void addInnerJoinPath(ASTPath path) {
1424:                if (path.size() > 1 && path.isCMRField(1)) {
1425:                    final String identifier = path.getPath(0);
1426:                    final String alias = aliasManager.getAlias(identifier);
1427:                    Map paths = (Map) joinPaths.get(alias);
1428:                    if (paths == null) {
1429:                        paths = new HashMap();
1430:                        joinPaths.put(alias, paths);
1431:                    }
1432:
1433:                    path.innerJoin = true;
1434:                    paths.put(path, path);
1435:                }
1436:            }
1437:
1438:            private Object[] childrenToStringArr(int numChildren, Node node) {
1439:                Object[] args = new Object[numChildren];
1440:                for (int i = 0; i < numChildren; ++i) {
1441:                    args[i] = node.jjtGetChild(i).jjtAccept(this ,
1442:                            new StringBuffer()).toString();
1443:                }
1444:                return args;
1445:            }
1446:
1447:            /**
1448:             * Recursively searches for ASTPath among children.
1449:             *
1450:             * @param selectFunction a node implements SelectFunction
1451:             * @return ASTPath child or null if there was no child of type ASTPath
1452:             */
1453:            private ASTPath getPathFromChildren(Node selectFunction) {
1454:                for (int childInd = 0; childInd < selectFunction
1455:                        .jjtGetNumChildren(); ++childInd) {
1456:                    Node child = selectFunction.jjtGetChild(childInd);
1457:                    if (child instanceof  ASTPath) {
1458:                        return (ASTPath) child;
1459:                    } else if (child instanceof  SelectFunction) {
1460:                        Node path = getPathFromChildren(child);
1461:                        if (path != null) {
1462:                            return (ASTPath) path;
1463:                        }
1464:                    }
1465:                }
1466:                return null;
1467:            }
1468:
1469:            private void setTypeFactory(JDBCTypeFactory typeFactory) {
1470:                this .typeFactory = typeFactory;
1471:                this .typeMapping = typeFactory.getTypeMapping();
1472:                aliasManager = new AliasManager(typeMapping
1473:                        .getAliasHeaderPrefix(), typeMapping
1474:                        .getAliasHeaderSuffix(), typeMapping
1475:                        .getAliasMaxLength());
1476:            }
1477:
1478:            private Class getParameterType(int index) {
1479:                int zeroBasedIndex = index - 1;
1480:                Class[] params = parameterTypes;
1481:                if (zeroBasedIndex < params.length) {
1482:                    return params[zeroBasedIndex];
1483:                }
1484:                return null;
1485:            }
1486:
1487:            // verify that parameter is the same type as the entity
1488:            private void verifyParameterEntityType(int number,
1489:                    JDBCAbstractEntityBridge entity) {
1490:                Class parameterType = getParameterType(number);
1491:                Class remoteClass = entity.getRemoteInterface();
1492:                Class localClass = entity.getLocalInterface();
1493:                if ((localClass == null || !localClass
1494:                        .isAssignableFrom(parameterType))
1495:                        && (remoteClass == null || !remoteClass
1496:                                .isAssignableFrom(parameterType))) {
1497:                    throw new IllegalStateException(
1498:                            "Only like types can be compared: from entity="
1499:                                    + entity.getEntityName()
1500:                                    + " to parameter type=" + parameterType);
1501:                }
1502:            }
1503:
1504:            private void reset() {
1505:                returnType = null;
1506:                parameterTypes = null;
1507:                readAhead = null;
1508:                inputParameters.clear();
1509:                selectObject = null;
1510:                selectManager = null;
1511:                typeFactory = null;
1512:                typeMapping = null;
1513:                aliasManager = null;
1514:                forceDistinct = false;
1515:                limitParam = 0;
1516:                limitValue = 0;
1517:                offsetParam = 0;
1518:                offsetValue = 0;
1519:                leftJoinCMRList.clear();
1520:                onFindCMRJoin = null;
1521:                countCompositePk = false;
1522:                joinPaths.clear();
1523:                identifierToTable.clear();
1524:                joinedAliases.clear();
1525:                selectDistinct = false;
1526:            }
1527:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.