Source Code Cross Referenced for JDBCEJBQLCompiler.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.HashMap;
0027:        import java.util.HashSet;
0028:        import java.util.Iterator;
0029:        import java.util.List;
0030:        import java.util.Map;
0031:        import java.util.Set;
0032:
0033:        import org.jboss.ejb.plugins.cmp.ejbql.ASTAbs;
0034:        import org.jboss.ejb.plugins.cmp.ejbql.ASTAbstractSchema;
0035:        import org.jboss.ejb.plugins.cmp.ejbql.ASTBooleanLiteral;
0036:        import org.jboss.ejb.plugins.cmp.ejbql.ASTCollectionMemberDeclaration;
0037:        import org.jboss.ejb.plugins.cmp.ejbql.ASTConcat;
0038:        import org.jboss.ejb.plugins.cmp.ejbql.ASTEJBQL;
0039:        import org.jboss.ejb.plugins.cmp.ejbql.ASTEntityComparison;
0040:        import org.jboss.ejb.plugins.cmp.ejbql.ASTFrom;
0041:        import org.jboss.ejb.plugins.cmp.ejbql.ASTIdentifier;
0042:        import org.jboss.ejb.plugins.cmp.ejbql.ASTIsEmpty;
0043:        import org.jboss.ejb.plugins.cmp.ejbql.ASTLCase;
0044:        import org.jboss.ejb.plugins.cmp.ejbql.ASTLength;
0045:        import org.jboss.ejb.plugins.cmp.ejbql.ASTLocate;
0046:        import org.jboss.ejb.plugins.cmp.ejbql.ASTMemberOf;
0047:        import org.jboss.ejb.plugins.cmp.ejbql.ASTNullComparison;
0048:        import org.jboss.ejb.plugins.cmp.ejbql.ASTOrderBy;
0049:        import org.jboss.ejb.plugins.cmp.ejbql.ASTParameter;
0050:        import org.jboss.ejb.plugins.cmp.ejbql.ASTPath;
0051:        import org.jboss.ejb.plugins.cmp.ejbql.ASTRangeVariableDeclaration;
0052:        import org.jboss.ejb.plugins.cmp.ejbql.ASTSelect;
0053:        import org.jboss.ejb.plugins.cmp.ejbql.ASTSqrt;
0054:        import org.jboss.ejb.plugins.cmp.ejbql.ASTSubstring;
0055:        import org.jboss.ejb.plugins.cmp.ejbql.ASTUCase;
0056:        import org.jboss.ejb.plugins.cmp.ejbql.ASTValueClassComparison;
0057:        import org.jboss.ejb.plugins.cmp.ejbql.ASTWhere;
0058:        import org.jboss.ejb.plugins.cmp.ejbql.BasicVisitor;
0059:        import org.jboss.ejb.plugins.cmp.ejbql.Catalog;
0060:        import org.jboss.ejb.plugins.cmp.ejbql.EJBQLParser;
0061:        import org.jboss.ejb.plugins.cmp.ejbql.EJBQLTypes;
0062:        import org.jboss.ejb.plugins.cmp.ejbql.JBossQLParser;
0063:        import org.jboss.ejb.plugins.cmp.ejbql.Node;
0064:        import org.jboss.ejb.plugins.cmp.ejbql.SimpleNode;
0065:        import org.jboss.ejb.plugins.cmp.ejbql.ASTLimitOffset;
0066:        import org.jboss.ejb.plugins.cmp.ejbql.ASTCount;
0067:        import org.jboss.ejb.plugins.cmp.ejbql.SelectFunction;
0068:        import org.jboss.ejb.plugins.cmp.ejbql.ASTExactNumericLiteral;
0069:        import org.jboss.ejb.plugins.cmp.ejbql.ASTMax;
0070:        import org.jboss.ejb.plugins.cmp.ejbql.ASTMin;
0071:        import org.jboss.ejb.plugins.cmp.ejbql.ASTAvg;
0072:        import org.jboss.ejb.plugins.cmp.ejbql.ASTSum;
0073:        import org.jboss.ejb.plugins.cmp.ejbql.ASTWhereConditionalTerm;
0074:        import org.jboss.ejb.plugins.cmp.ejbql.ASTMod;
0075:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
0076:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge;
0077:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
0078:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
0079:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCAbstractEntityBridge;
0080:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCFunctionMappingMetaData;
0081:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCReadAheadMetaData;
0082:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCTypeMappingMetaData;
0083:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData;
0084:        import org.jboss.ejb.plugins.cmp.bridge.CMPFieldBridge;
0085:        import org.jboss.ejb.EntityPersistenceStore;
0086:        import org.jboss.deployment.DeploymentException;
0087:
0088:        /**
0089:         * Compiles EJB-QL and JBossQL into SQL.
0090:         *
0091:         * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
0092:         * @author <a href="mailto:alex@jboss.org">Alex Loubyansky</a>
0093:         * @version $Revision: 63343 $
0094:         */
0095:        public final class JDBCEJBQLCompiler extends BasicVisitor implements 
0096:                QLCompiler {
0097:            // input objects
0098:            private final Catalog catalog;
0099:            private Class returnType;
0100:            private Class[] parameterTypes;
0101:            private JDBCReadAheadMetaData readAhead;
0102:            private boolean lazyResultSetLoading;
0103:
0104:            // alias info
0105:            private AliasManager aliasManager;
0106:
0107:            // join info
0108:            private Set declaredPaths = new HashSet();
0109:            private Set ctermJoinPaths = new HashSet();
0110:            private Set allJoinPaths = new HashSet();
0111:            private Map ctermCollectionMemberJoinPaths = new HashMap();
0112:            private Map allCollectionMemberJoinPaths = new HashMap();
0113:            private Map ctermLeftJoinPaths = new HashMap();
0114:            private Map allLeftJoinPaths = new HashMap();
0115:
0116:            // mapping metadata
0117:            private JDBCTypeMappingMetaData typeMapping;
0118:            private JDBCTypeFactory typeFactory;
0119:            private boolean subquerySupported;
0120:
0121:            // output objects
0122:            private boolean forceDistinct;
0123:            private String sql;
0124:            private int offsetParam;
0125:            private int offsetValue;
0126:            private int limitParam;
0127:            private int limitValue;
0128:            private JDBCStoreManager selectManager;
0129:            private Object selectObject;
0130:            private List inputParameters = new ArrayList();
0131:
0132:            /**
0133:             * deep read ahead for cmrs
0134:             */
0135:            private List leftJoinCMRList = new ArrayList();
0136:            private StringBuffer onFindCMRJoin;
0137:
0138:            private boolean countCompositePk;
0139:            private String selectAlias;
0140:            private boolean selectDistinct;
0141:
0142:            public JDBCEJBQLCompiler(Catalog catalog) {
0143:                this .catalog = catalog;
0144:            }
0145:
0146:            public void compileEJBQL(String ejbql, Class returnType,
0147:                    Class[] parameterTypes, JDBCQueryMetaData metadata)
0148:                    throws Exception {
0149:                // reset all state variables
0150:                reset();
0151:
0152:                // set input arguemts
0153:                this .returnType = returnType;
0154:                this .parameterTypes = parameterTypes;
0155:                this .readAhead = metadata.getReadAhead();
0156:                this .lazyResultSetLoading = metadata.isLazyResultSetLoading();
0157:
0158:                // get the parser
0159:                EJBQLParser parser = new EJBQLParser(new StringReader(
0160:                        SQLUtil.EMPTY_STRING));
0161:
0162:                try {
0163:                    // parse the ejbql into an abstract sytax tree
0164:                    ASTEJBQL ejbqlNode;
0165:                    ejbqlNode = parser.parse(catalog, parameterTypes, ejbql);
0166:
0167:                    // translate to sql
0168:                    sql = ejbqlNode.jjtAccept(this , new StringBuffer())
0169:                            .toString();
0170:                } catch (Exception e) {
0171:                    // if there is a problem reset the state before exiting
0172:                    reset();
0173:                    throw e;
0174:                } catch (Error e) {
0175:                    // lame javacc lexer throws Errors
0176:                    reset();
0177:                    throw e;
0178:                }
0179:            }
0180:
0181:            public void compileJBossQL(String ejbql, Class returnType,
0182:                    Class[] parameterTypes, JDBCQueryMetaData metadata)
0183:                    throws Exception {
0184:                // reset all state variables
0185:                reset();
0186:
0187:                // set input arguemts
0188:                this .returnType = returnType;
0189:                this .parameterTypes = parameterTypes;
0190:                this .readAhead = metadata.getReadAhead();
0191:                this .lazyResultSetLoading = metadata.isLazyResultSetLoading();
0192:
0193:                // get the parser
0194:                JBossQLParser parser = new JBossQLParser(new StringReader(
0195:                        SQLUtil.EMPTY_STRING));
0196:
0197:                try {
0198:                    // parse the ejbql into an abstract sytax tree
0199:                    ASTEJBQL ejbqlNode;
0200:                    ejbqlNode = parser.parse(catalog, parameterTypes, ejbql);
0201:
0202:                    // translate to sql
0203:                    sql = ejbqlNode.jjtAccept(this , new StringBuffer())
0204:                            .toString();
0205:                } catch (Exception e) {
0206:                    // if there is a problem reset the state before exiting
0207:                    reset();
0208:                    throw e;
0209:                } catch (Error e) {
0210:                    // lame javacc lexer throws Errors
0211:                    reset();
0212:                    throw e;
0213:                }
0214:            }
0215:
0216:            private void reset() {
0217:                returnType = null;
0218:                parameterTypes = null;
0219:                readAhead = null;
0220:                inputParameters.clear();
0221:                declaredPaths.clear();
0222:                clearPerTermJoinPaths();
0223:                allJoinPaths.clear();
0224:                allCollectionMemberJoinPaths.clear();
0225:                allLeftJoinPaths.clear();
0226:                selectObject = null;
0227:                selectManager = null;
0228:                typeFactory = null;
0229:                typeMapping = null;
0230:                aliasManager = null;
0231:                subquerySupported = true;
0232:                forceDistinct = false;
0233:                limitParam = 0;
0234:                limitValue = 0;
0235:                offsetParam = 0;
0236:                offsetValue = 0;
0237:                leftJoinCMRList.clear();
0238:                onFindCMRJoin = null;
0239:                countCompositePk = false;
0240:                selectAlias = null;
0241:                selectDistinct = false;
0242:            }
0243:
0244:            public String getSQL() {
0245:                return sql;
0246:            }
0247:
0248:            public int getOffsetValue() {
0249:                return offsetValue;
0250:            }
0251:
0252:            public int getOffsetParam() {
0253:                return offsetParam;
0254:            }
0255:
0256:            public int getLimitValue() {
0257:                return limitValue;
0258:            }
0259:
0260:            public int getLimitParam() {
0261:                return limitParam;
0262:            }
0263:
0264:            public boolean isSelectEntity() {
0265:                return selectObject instanceof  JDBCEntityBridge;
0266:            }
0267:
0268:            public JDBCAbstractEntityBridge getSelectEntity() {
0269:                return (JDBCAbstractEntityBridge) selectObject;
0270:            }
0271:
0272:            public boolean isSelectField() {
0273:                return selectObject instanceof  JDBCCMPFieldBridge;
0274:            }
0275:
0276:            public JDBCFieldBridge getSelectField() {
0277:                return (JDBCCMPFieldBridge) selectObject;
0278:            }
0279:
0280:            public SelectFunction getSelectFunction() {
0281:                return (SelectFunction) selectObject;
0282:            }
0283:
0284:            public EntityPersistenceStore getStoreManager() {
0285:                return selectManager;
0286:            }
0287:
0288:            public List getInputParameters() {
0289:                return inputParameters;
0290:            }
0291:
0292:            public List getLeftJoinCMRList() {
0293:                return leftJoinCMRList;
0294:            }
0295:
0296:            public boolean isSelectDistinct() {
0297:                return selectDistinct;
0298:            }
0299:
0300:            public Object visit(SimpleNode node, Object data) {
0301:                throw new RuntimeException(
0302:                        "Internal error: Found unknown node type in "
0303:                                + "EJB-QL abstract syntax tree: node=" + node);
0304:            }
0305:
0306:            private void setTypeFactory(JDBCTypeFactory typeFactory) {
0307:                this .typeFactory = typeFactory;
0308:                this .typeMapping = typeFactory.getTypeMapping();
0309:                aliasManager = new AliasManager(typeMapping
0310:                        .getAliasHeaderPrefix(), typeMapping
0311:                        .getAliasHeaderSuffix(), typeMapping
0312:                        .getAliasMaxLength());
0313:                subquerySupported = typeMapping.isSubquerySupported();
0314:            }
0315:
0316:            private Class getParameterType(int index) {
0317:                int zeroBasedIndex = index - 1;
0318:                Class[] params = parameterTypes;
0319:                if (zeroBasedIndex < params.length) {
0320:                    return params[zeroBasedIndex];
0321:                }
0322:                return null;
0323:            }
0324:
0325:            // verify that parameter is the same type as the entity
0326:            private void verifyParameterEntityType(int number,
0327:                    JDBCEntityBridge entity) {
0328:                Class parameterType = getParameterType(number);
0329:                Class remoteClass = entity.getMetaData().getRemoteClass();
0330:                Class localClass = entity.getMetaData().getLocalClass();
0331:                if ((localClass == null || !localClass
0332:                        .isAssignableFrom(parameterType))
0333:                        && (remoteClass == null || !remoteClass
0334:                                .isAssignableFrom(parameterType))) {
0335:
0336:                    throw new IllegalStateException("Only like types can be "
0337:                            + "compared: from entity=" + entity.getEntityName()
0338:                            + " to parameter type=" + parameterType);
0339:                }
0340:            }
0341:
0342:            private void compareEntity(boolean not, Node fromNode, Node toNode,
0343:                    StringBuffer buf) {
0344:                buf.append('(');
0345:                if (not) {
0346:                    buf.append(SQLUtil.NOT).append('(');
0347:                }
0348:
0349:                String fromAlias;
0350:                JDBCEntityBridge fromEntity;
0351:                ASTPath fromPath = (ASTPath) fromNode;
0352:                addJoinPath(fromPath);
0353:                fromAlias = aliasManager.getAlias(fromPath.getPath());
0354:                fromEntity = (JDBCEntityBridge) fromPath.getEntity();
0355:
0356:                if (toNode instanceof  ASTParameter) {
0357:                    ASTParameter toParam = (ASTParameter) toNode;
0358:
0359:                    // can only compare like kind entities
0360:                    verifyParameterEntityType(toParam.number, fromEntity);
0361:
0362:                    inputParameters.addAll(QueryParameter.createParameters(
0363:                            toParam.number - 1, fromEntity));
0364:
0365:                    SQLUtil.getWhereClause(fromEntity.getPrimaryKeyFields(),
0366:                            fromAlias, buf);
0367:                } else {
0368:                    String toAlias;
0369:                    JDBCEntityBridge toEntity;
0370:                    ASTPath toPath = (ASTPath) toNode;
0371:                    addJoinPath(toPath);
0372:                    toAlias = aliasManager.getAlias(toPath.getPath());
0373:                    toEntity = (JDBCEntityBridge) toPath.getEntity();
0374:
0375:                    // can only compare like kind entities
0376:                    if (!fromEntity.equals(toEntity)) {
0377:                        throw new IllegalStateException(
0378:                                "Only like types can be "
0379:                                        + "compared: from entity="
0380:                                        + fromEntity.getEntityName()
0381:                                        + " to entity="
0382:                                        + toEntity.getEntityName());
0383:                    }
0384:
0385:                    SQLUtil.getSelfCompareWhereClause(fromEntity
0386:                            .getPrimaryKeyFields(), fromAlias, toAlias, buf);
0387:                }
0388:
0389:                if (not) {
0390:                    buf.append(')');
0391:                }
0392:                buf.append(')');
0393:            }
0394:
0395:            private void existsClause(ASTPath path, StringBuffer buf,
0396:                    boolean not) {
0397:                if (!path.isCMRField()) {
0398:                    throw new IllegalArgumentException(
0399:                            "path must be a cmr field");
0400:                }
0401:
0402:                JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0403:                        .getCMRField();
0404:                String pathStr = path.getPath(path.size() - 2);
0405:                String parentAlias = aliasManager.getAlias(pathStr);
0406:
0407:                // if exists is not supported we use a left join and is null
0408:                if (!subquerySupported) {
0409:                    // add the path to the list of paths to left join
0410:                    addLeftJoinPath(pathStr, path);
0411:                    forceDistinct = true;
0412:
0413:                    addJoinPath(path);
0414:
0415:                    if (cmrField.getRelationMetaData()
0416:                            .isForeignKeyMappingStyle()) {
0417:                        JDBCEntityBridge childEntity = (JDBCEntityBridge) cmrField
0418:                                .getRelatedEntity();
0419:                        String childAlias = aliasManager.getAlias(path
0420:                                .getPath());
0421:                        SQLUtil.getIsNullClause(!not, childEntity
0422:                                .getPrimaryKeyFields(), childAlias, buf);
0423:                    } else {
0424:                        String relationTableAlias = aliasManager
0425:                                .getRelationTableAlias(path.getPath());
0426:                        SQLUtil.getIsNullClause(!not, cmrField
0427:                                .getTableKeyFields(), relationTableAlias, buf);
0428:                    }
0429:                    return;
0430:                }
0431:
0432:                if (not) {
0433:                    buf.append(SQLUtil.NOT);
0434:                }
0435:                buf.append(SQLUtil.EXISTS).append('(');
0436:
0437:                if (cmrField.getRelationMetaData().isForeignKeyMappingStyle()) {
0438:                    JDBCEntityBridge childEntity = (JDBCEntityBridge) cmrField
0439:                            .getRelatedEntity();
0440:                    String childAlias = aliasManager.getAlias(path.getPath());
0441:
0442:                    buf.append(SQLUtil.SELECT);
0443:
0444:                    SQLUtil.getColumnNamesClause(
0445:                            childEntity.getPrimaryKeyFields(), childAlias, buf)
0446:                            .append(SQLUtil.FROM).append(
0447:                                    childEntity.getQualifiedTableName())
0448:                            .append(' ').append(childAlias).append(
0449:                                    SQLUtil.WHERE);
0450:                    SQLUtil.getJoinClause(cmrField, parentAlias, childAlias,
0451:                            buf);
0452:                } else {
0453:                    String relationTableAlias = aliasManager
0454:                            .getRelationTableAlias(path.getPath());
0455:                    buf.append(SQLUtil.SELECT);
0456:                    SQLUtil.getColumnNamesClause(cmrField.getTableKeyFields(),
0457:                            relationTableAlias, buf).append(SQLUtil.FROM)
0458:                            .append(cmrField.getQualifiedTableName()).append(
0459:                                    ' ').append(relationTableAlias).append(
0460:                                    SQLUtil.WHERE);
0461:                    SQLUtil.getRelationTableJoinClause(cmrField, parentAlias,
0462:                            relationTableAlias, buf);
0463:                }
0464:
0465:                buf.append(')');
0466:            }
0467:
0468:            public Object visit(ASTEJBQL node, Object data) {
0469:                Node selectNode = node.jjtGetChild(0);
0470:                Node fromNode = node.jjtGetChild(1);
0471:                Node whereNode = null;
0472:                Node orderByNode = null;
0473:                Node limitNode = null;
0474:
0475:                for (int childNode = 2; childNode < node.jjtGetNumChildren(); childNode++) {
0476:                    Node temp = node.jjtGetChild(childNode);
0477:                    if (temp instanceof  ASTWhere) {
0478:                        whereNode = temp;
0479:                    } else if (temp instanceof  ASTOrderBy) {
0480:                        orderByNode = temp;
0481:                    } else if (temp instanceof  ASTLimitOffset) {
0482:                        limitNode = temp;
0483:                    }
0484:                }
0485:
0486:                // translate select and add it to the buffer
0487:                StringBuffer select = new StringBuffer();
0488:                selectNode.jjtAccept(this , select);
0489:
0490:                // conditional term paths from the where clause are treated separately from those
0491:                // in select, from and order by.
0492:                // TODO come up with a nicer treatment implementation.
0493:                Set selectJoinPaths = new HashSet(ctermJoinPaths);
0494:                Map selectCollectionMemberJoinPaths = new HashMap(
0495:                        ctermCollectionMemberJoinPaths);
0496:                Map selectLeftJoinPaths = new HashMap(ctermLeftJoinPaths);
0497:
0498:                // translate where and save results to append later
0499:                StringBuffer where = new StringBuffer();
0500:                if (whereNode != null) {
0501:                    whereNode.jjtAccept(this , where);
0502:                }
0503:
0504:                // reassign conditional term paths and add paths from order by and from to select paths
0505:                ctermJoinPaths = selectJoinPaths;
0506:                ctermCollectionMemberJoinPaths = selectCollectionMemberJoinPaths;
0507:                ctermLeftJoinPaths = selectLeftJoinPaths;
0508:
0509:                // translate order by and save results to append later
0510:                StringBuffer orderBy = new StringBuffer();
0511:                if (orderByNode != null) {
0512:                    orderByNode.jjtAccept(this , orderBy);
0513:
0514:                    // hack alert - this should use the visitor approach
0515:                    for (int i = 0; i < orderByNode.jjtGetNumChildren(); i++) {
0516:                        Node orderByPath = orderByNode.jjtGetChild(i);
0517:                        ASTPath path = (ASTPath) orderByPath.jjtGetChild(0);
0518:                        if (!isSelected(path)) {
0519:                            select.append(SQLUtil.COMMA);
0520:                            path.jjtAccept(this , select);
0521:                        }
0522:                    }
0523:                }
0524:
0525:                if (limitNode != null) {
0526:                    limitNode.jjtAccept(this , null);
0527:                }
0528:
0529:                StringBuffer from = new StringBuffer(50);
0530:                fromNode.jjtAccept(this , from);
0531:
0532:                StringBuffer fromThetaJoin = new StringBuffer();
0533:                createThetaJoin(fromThetaJoin);
0534:
0535:                if (where.length() != 0 && fromThetaJoin.length() != 0) {
0536:                    where.insert(0, '(').append(')').append(SQLUtil.AND)
0537:                            .append(fromThetaJoin);
0538:                } else if (fromThetaJoin.length() != 0) {
0539:                    where.append(fromThetaJoin.toString());
0540:                }
0541:
0542:                selectDistinct = isDistinct(selectNode);
0543:
0544:                // select size
0545:                if (lazyResultSetLoading) {
0546:                    StringBuffer buf = new StringBuffer(200);
0547:                    if (isSelectEntity()) {
0548:                        final JDBCFieldBridge[] pkFields = getSelectEntity()
0549:                                .getPrimaryKeyFields();
0550:                        if (pkFields.length == 1) {
0551:                            buf.append('(').append(SQLUtil.SELECT).append(
0552:                                    "count(");
0553:                            if (selectDistinct) {
0554:                                buf.append(SQLUtil.DISTINCT);
0555:                            }
0556:                            SQLUtil.getColumnNamesClause(pkFields, selectAlias,
0557:                                    buf);
0558:                            buf.append(')').append(SQLUtil.FROM);
0559:                            buf.append(from);
0560:                            if (where.length() > 0) {
0561:                                buf.append(SQLUtil.WHERE).append(where);
0562:                            }
0563:                            buf.append("), ");
0564:                            select.insert(0, buf);
0565:                        } else {
0566:                            buf.append('(').append(SQLUtil.SELECT).append(
0567:                                    "count(*)").append(SQLUtil.FROM)
0568:                                    .append('(').append(SQLUtil.SELECT);
0569:
0570:                            if (selectDistinct) {
0571:                                buf.append(SQLUtil.DISTINCT);
0572:                            }
0573:
0574:                            SQLUtil.getColumnNamesClause(pkFields, selectAlias,
0575:                                    buf);
0576:                            buf.append(SQLUtil.FROM).append(from);
0577:
0578:                            if (where.length() > 0) {
0579:                                buf.append(SQLUtil.WHERE).append(where);
0580:                            }
0581:                            buf.append(") t_count), ");
0582:                            select.insert(0, buf);
0583:                        }
0584:                    } else if (isSelectField()) {
0585:                        buf.append('(').append(SQLUtil.SELECT).append("count(");
0586:                        if (selectDistinct) {
0587:                            buf.append(SQLUtil.DISTINCT);
0588:                        }
0589:                        buf.append(select).append(')').append(SQLUtil.FROM);
0590:                        buf.append(from);
0591:                        if (where.length() > 0) {
0592:                            buf.append(SQLUtil.WHERE).append(where);
0593:                        }
0594:                        buf.append("), ");
0595:                        select.insert(0, buf);
0596:                    }
0597:                }
0598:
0599:                // distinct
0600:                if (selectDistinct) {
0601:                    select.insert(0, SQLUtil.DISTINCT);
0602:                }
0603:
0604:                StringBuffer buf = (StringBuffer) data;
0605:                if (selectManager.getMetaData().hasRowLocking()) {
0606:                    JDBCFunctionMappingMetaData rowLockingTemplate = typeMapping
0607:                            .getRowLockingTemplate();
0608:                    Object args[] = new Object[] { select, from,
0609:                            where.length() == 0 ? null : where,
0610:                            orderBy.length() == 0 ? null : orderBy };
0611:                    rowLockingTemplate.getFunctionSql(args, buf);
0612:                } else {
0613:                    buf.append(SQLUtil.SELECT).append(select).append(
0614:                            SQLUtil.FROM).append(from);
0615:
0616:                    if (where.length() > 0) {
0617:                        buf.append(SQLUtil.WHERE).append(where);
0618:                    }
0619:
0620:                    if (orderBy.length() != 0) {
0621:                        buf.append(SQLUtil.ORDERBY).append(orderBy);
0622:                    }
0623:                }
0624:
0625:                // todo: ...
0626:                if (countCompositePk) {
0627:                    buf.insert(0, "SELECT COUNT(*) FROM (").append(") t_count");
0628:                }
0629:
0630:                return buf;
0631:            }
0632:
0633:            public Object visit(ASTFrom node, Object data) {
0634:                StringBuffer buf = (StringBuffer) data;
0635:
0636:                node.jjtGetChild(0).jjtAccept(this , buf);
0637:                for (int i = 1; i < node.jjtGetNumChildren(); i++) {
0638:                    buf.append(SQLUtil.COMMA);
0639:                    node.jjtGetChild(i).jjtAccept(this , buf);
0640:                }
0641:
0642:                // add all the additional path tables
0643:                if (!allJoinPaths.isEmpty()) {
0644:                    for (Iterator iter = allJoinPaths.iterator(); iter
0645:                            .hasNext();) {
0646:                        ASTPath path = (ASTPath) iter.next();
0647:                        for (int i = 0; i < path.size(); i++) {
0648:                            declareTables(path, i, buf);
0649:                        }
0650:                    }
0651:                }
0652:
0653:                // add all parent paths for collection member join paths
0654:                if (!allCollectionMemberJoinPaths.isEmpty()) {
0655:                    for (Iterator iter = allCollectionMemberJoinPaths.values()
0656:                            .iterator(); iter.hasNext();) {
0657:                        ASTPath path = (ASTPath) iter.next();
0658:                        // don't declare the last one as the first path was left joined
0659:                        for (int i = 0; i < path.size() - 1; i++) {
0660:                            declareTables(path, i, buf);
0661:                        }
0662:                    }
0663:                }
0664:
0665:                // get all the left joined paths
0666:                if (!allLeftJoinPaths.isEmpty()) {
0667:                    Set allLeftJoins = new HashSet();
0668:                    for (Iterator iter = allLeftJoinPaths.values().iterator(); iter
0669:                            .hasNext();) {
0670:                        allLeftJoins.addAll((Set) iter.next());
0671:                    }
0672:
0673:                    // add all parent paths for left joins
0674:                    for (Iterator iter = allLeftJoins.iterator(); iter
0675:                            .hasNext();) {
0676:                        ASTPath path = (ASTPath) iter.next();
0677:                        // don't declare the last one as the first path was left joined
0678:                        for (int i = 0; i < path.size() - 1; i++) {
0679:                            declareTables(path, i, buf);
0680:                        }
0681:                    }
0682:                }
0683:
0684:                return buf;
0685:            }
0686:
0687:            private void declareTables(ASTPath path, int i, StringBuffer buf) {
0688:                if (!path.isCMRField(i)
0689:                        || declaredPaths.contains(path.getPath(i))) {
0690:                    return;
0691:                }
0692:
0693:                JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0694:                        .getCMRField(i);
0695:                JDBCEntityBridge entity = (JDBCEntityBridge) path.getEntity(i);
0696:
0697:                buf.append(SQLUtil.COMMA)
0698:                        .append(entity.getQualifiedTableName()).append(' ')
0699:                        .append(aliasManager.getAlias(path.getPath(i)));
0700:                leftJoins(path.getPath(i), buf);
0701:
0702:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
0703:                    String relationTableAlias = aliasManager
0704:                            .getRelationTableAlias(path.getPath(i));
0705:                    buf.append(SQLUtil.COMMA).append(
0706:                            cmrField.getQualifiedTableName()).append(' ')
0707:                            .append(relationTableAlias);
0708:                }
0709:
0710:                declaredPaths.add(path.getPath(i));
0711:            }
0712:
0713:            private void leftJoins(String parentPath, StringBuffer buf) {
0714:                Set paths = (Set) ctermLeftJoinPaths.get(parentPath);
0715:                if (subquerySupported || paths == null) {
0716:                    return;
0717:                }
0718:
0719:                for (Iterator iter = paths.iterator(); iter.hasNext();) {
0720:                    ASTPath path = (ASTPath) iter.next();
0721:
0722:                    JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0723:                            .getCMRField();
0724:                    String parentAlias = aliasManager.getAlias(parentPath);
0725:
0726:                    if (cmrField.getRelationMetaData()
0727:                            .isForeignKeyMappingStyle()) {
0728:                        JDBCEntityBridge childEntity = (JDBCEntityBridge) cmrField
0729:                                .getRelatedEntity();
0730:                        String childAlias = aliasManager.getAlias(path
0731:                                .getPath());
0732:
0733:                        buf.append(SQLUtil.LEFT_JOIN).append(
0734:                                childEntity.getQualifiedTableName())
0735:                                .append(' ').append(childAlias).append(
0736:                                        SQLUtil.ON);
0737:                        SQLUtil.getJoinClause(cmrField, parentAlias,
0738:                                childAlias, buf);
0739:                    } else {
0740:                        String relationTableAlias = aliasManager
0741:                                .getRelationTableAlias(path.getPath());
0742:                        buf.append(SQLUtil.LEFT_JOIN).append(
0743:                                cmrField.getQualifiedTableName()).append(' ')
0744:                                .append(relationTableAlias).append(SQLUtil.ON);
0745:                        SQLUtil.getRelationTableJoinClause(cmrField,
0746:                                parentAlias, relationTableAlias, buf);
0747:                    }
0748:                }
0749:            }
0750:
0751:            private void createThetaJoin(StringBuffer buf) {
0752:                Set joinedAliases = new HashSet();
0753:                // add all the additional path tables
0754:                if (!ctermJoinPaths.isEmpty()) {
0755:                    for (Iterator iter = ctermJoinPaths.iterator(); iter
0756:                            .hasNext();) {
0757:                        ASTPath path = (ASTPath) iter.next();
0758:                        for (int i = 0; i < path.size(); i++) {
0759:                            createThetaJoin(path, i, joinedAliases, buf);
0760:                        }
0761:                    }
0762:                }
0763:
0764:                // add all the collection member path tables
0765:                if (!ctermCollectionMemberJoinPaths.isEmpty()) {
0766:                    for (Iterator iter = ctermCollectionMemberJoinPaths
0767:                            .entrySet().iterator(); iter.hasNext();) {
0768:                        Map.Entry entry = (Map.Entry) iter.next();
0769:                        String childAlias = (String) entry.getKey();
0770:                        ASTPath path = (ASTPath) entry.getValue();
0771:
0772:                        // join the memeber path
0773:                        createThetaJoin(path, path.size() - 1, joinedAliases,
0774:                                childAlias, buf);
0775:
0776:                        // join the memeber path parents
0777:                        for (int i = 0; i < path.size() - 1; i++) {
0778:                            createThetaJoin(path, i, joinedAliases, buf);
0779:                        }
0780:                    }
0781:                }
0782:
0783:                // get all the left joined paths
0784:                if (!ctermLeftJoinPaths.isEmpty()) {
0785:                    Set allLeftJoins = new HashSet();
0786:                    for (Iterator iter = ctermLeftJoinPaths.values().iterator(); iter
0787:                            .hasNext();) {
0788:                        allLeftJoins.addAll((Set) iter.next());
0789:                    }
0790:
0791:                    // add all parent paths for left joins
0792:                    for (Iterator iter = allLeftJoins.iterator(); iter
0793:                            .hasNext();) {
0794:                        ASTPath path = (ASTPath) iter.next();
0795:                        // don't declare the last one as the first path was left joined
0796:                        for (int i = 0; i < path.size() - 1; i++) {
0797:                            createThetaJoin(path, i, joinedAliases, buf);
0798:                        }
0799:                    }
0800:                }
0801:            }
0802:
0803:            private void createThetaJoin(ASTPath path, int i,
0804:                    Set joinedAliases, StringBuffer buf) {
0805:                String childAlias = aliasManager.getAlias(path.getPath(i));
0806:                createThetaJoin(path, i, joinedAliases, childAlias, buf);
0807:            }
0808:
0809:            private void createThetaJoin(ASTPath path, int i,
0810:                    Set joinedAliases, String childAlias, StringBuffer buf) {
0811:                if (!path.isCMRField(i) || joinedAliases.contains(childAlias)) {
0812:                    return;
0813:                }
0814:
0815:                JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0816:                        .getCMRField(i);
0817:                String parentAlias = aliasManager.getAlias(path.getPath(i - 1));
0818:
0819:                if (joinedAliases.size() > 0) {
0820:                    buf.append(SQLUtil.AND);
0821:                }
0822:
0823:                if (cmrField.getRelationMetaData().isForeignKeyMappingStyle()) {
0824:                    SQLUtil.getJoinClause(cmrField, parentAlias, childAlias,
0825:                            buf);
0826:                } else {
0827:                    String relationTableAlias = aliasManager
0828:                            .getRelationTableAlias(path.getPath(i));
0829:
0830:                    // parent to relation table
0831:                    SQLUtil.getRelationTableJoinClause(cmrField, parentAlias,
0832:                            relationTableAlias, buf).append(SQLUtil.AND);
0833:                    // child to relation table
0834:                    SQLUtil.getRelationTableJoinClause(cmrField
0835:                            .getRelatedCMRField(), childAlias,
0836:                            relationTableAlias, buf);
0837:                }
0838:
0839:                joinedAliases.add(childAlias);
0840:            }
0841:
0842:            public Object visit(ASTCollectionMemberDeclaration node, Object data) {
0843:                StringBuffer buf = (StringBuffer) data;
0844:
0845:                // first arg is a collection valued path
0846:                ASTPath path = (ASTPath) node.jjtGetChild(0);
0847:
0848:                // add this path to the list of declared paths
0849:                declaredPaths.add(path.getPath());
0850:
0851:                // get the entity at the end of this path
0852:                JDBCEntityBridge entity = (JDBCEntityBridge) path.getEntity();
0853:
0854:                // second arg is the identifier
0855:                ASTIdentifier id = (ASTIdentifier) node.jjtGetChild(1);
0856:
0857:                // get the alias
0858:                String alias = aliasManager.getAlias(id.identifier);
0859:
0860:                // add this path to the list of join paths so parent paths will be joined
0861:                addCollectionMemberJoinPath(alias, path);
0862:
0863:                // declare the alias mapping
0864:                aliasManager.addAlias(path.getPath(), alias);
0865:
0866:                buf.append(entity.getQualifiedTableName());
0867:                buf.append(' ');
0868:                buf.append(alias);
0869:                leftJoins(path.getPath(), buf);
0870:
0871:                if (onFindCMRJoin != null && alias.equals(selectAlias)) {
0872:                    buf.append(onFindCMRJoin);
0873:                    onFindCMRJoin = null;
0874:                }
0875:
0876:                // add the relation-table
0877:                JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0878:                        .getCMRField();
0879:                if (cmrField.getRelationMetaData().isTableMappingStyle()) {
0880:                    String relationTableAlias = aliasManager
0881:                            .getRelationTableAlias(path.getPath());
0882:                    buf.append(SQLUtil.COMMA).append(
0883:                            cmrField.getQualifiedTableName()).append(' ')
0884:                            .append(relationTableAlias);
0885:                }
0886:
0887:                return buf;
0888:            }
0889:
0890:            public Object visit(ASTRangeVariableDeclaration node, Object data) {
0891:                StringBuffer buf = (StringBuffer) data;
0892:
0893:                ASTAbstractSchema schema = (ASTAbstractSchema) node
0894:                        .jjtGetChild(0);
0895:                JDBCEntityBridge entity = (JDBCEntityBridge) schema.entity;
0896:                ASTIdentifier id = (ASTIdentifier) node.jjtGetChild(1);
0897:
0898:                String alias = aliasManager.getAlias(id.identifier);
0899:                buf.append(entity.getQualifiedTableName()).append(' ').append(
0900:                        alias);
0901:                leftJoins(id.identifier, buf);
0902:
0903:                if (onFindCMRJoin != null && alias.equals(selectAlias)) {
0904:                    buf.append(onFindCMRJoin);
0905:                    onFindCMRJoin = null;
0906:                }
0907:
0908:                return buf;
0909:            }
0910:
0911:            public Object visit(ASTSelect node, Object data) {
0912:                StringBuffer buf = (StringBuffer) data;
0913:
0914:                Node child0 = node.jjtGetChild(0);
0915:                ASTPath path;
0916:                if (child0 instanceof  ASTPath) {
0917:                    path = (ASTPath) child0;
0918:
0919:                    if (path.isCMPField()) {
0920:                        // set the select object
0921:                        JDBCCMPFieldBridge selectField = (JDBCCMPFieldBridge) path
0922:                                .getCMPField();
0923:                        selectManager = (JDBCStoreManager) selectField
0924:                                .getManager();
0925:                        selectObject = selectField;
0926:                        setTypeFactory(selectManager.getJDBCTypeFactory());
0927:
0928:                        addJoinPath(path);
0929:                        selectAlias = aliasManager.getAlias(path.getPath(path
0930:                                .size() - 2));
0931:                        SQLUtil.getColumnNamesClause(selectField, selectAlias,
0932:                                buf);
0933:                    } else {
0934:                        // set the select object
0935:                        JDBCEntityBridge selectEntity = (JDBCEntityBridge) path
0936:                                .getEntity();
0937:                        selectManager = (JDBCStoreManager) selectEntity
0938:                                .getManager();
0939:                        selectObject = selectEntity;
0940:                        setTypeFactory(selectManager.getJDBCTypeFactory());
0941:                        selectEntity(path, buf);
0942:                    }
0943:                } else {
0944:                    // the function should take a path expresion as a parameter
0945:                    path = getPathFromChildren(child0);
0946:
0947:                    if (path == null) {
0948:                        throw new IllegalStateException(
0949:                                "The function in SELECT clause does not contain a path expression.");
0950:                    }
0951:
0952:                    if (path.isCMPField()) {
0953:                        JDBCCMPFieldBridge selectField = (JDBCCMPFieldBridge) path
0954:                                .getCMPField();
0955:                        selectManager = (JDBCStoreManager) selectField
0956:                                .getManager();
0957:                    } else if (path.isCMRField()) {
0958:                        JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0959:                                .getCMRField();
0960:                        selectManager = (JDBCStoreManager) cmrField.getEntity()
0961:                                .getManager();
0962:                        addJoinPath(path);
0963:                    } else {
0964:                        final JDBCEntityBridge entity = (JDBCEntityBridge) path
0965:                                .getEntity();
0966:                        selectManager = (JDBCStoreManager) entity.getManager();
0967:                        addJoinPath(path);
0968:                    }
0969:
0970:                    setTypeFactory(selectManager.getJDBCTypeFactory());
0971:                    selectObject = child0;
0972:                    child0.jjtAccept(this , buf);
0973:                }
0974:
0975:                return buf;
0976:            }
0977:
0978:            /**
0979:             * Generates where clause without the "WHERE" keyword.
0980:             */
0981:            public Object visit(ASTWhere node, Object data) {
0982:                node.jjtGetChild(0).jjtAccept(this , data);
0983:                return data;
0984:            }
0985:
0986:            public Object visit(ASTNullComparison node, Object data) {
0987:                StringBuffer buf = (StringBuffer) data;
0988:
0989:                final Node child0 = node.jjtGetChild(0);
0990:                if (child0 instanceof  ASTPath) {
0991:                    ASTPath path = (ASTPath) child0;
0992:
0993:                    if (path.isCMRField()) {
0994:                        JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge) path
0995:                                .getCMRField();
0996:                        if (cmrField.getRelationMetaData()
0997:                                .isTableMappingStyle()) {
0998:                            existsClause(path, buf, !node.not);
0999:                            return buf;
1000:                        }
1001:                    }
1002:
1003:                    String alias = aliasManager.getAlias(path.getPath(path
1004:                            .size() - 2));
1005:                    JDBCFieldBridge field = (JDBCFieldBridge) path.getField();
1006:
1007:                    // if jdbc type is null then it should be a cmr field in
1008:                    // a one-to-one mapping that isn't a foreign key.
1009:                    // handle it the way the IS EMPTY on the one side of one-to-many
1010:                    // relationship is handled
1011:                    if (field.getJDBCType() == null) {
1012:                        existsClause(path, buf, !node.not);
1013:                        return buf;
1014:                    }
1015:
1016:                    // check the path for cmr fields and add them to join paths
1017:                    if (path.fieldList.size() > 2) {
1018:                        for (int i = 0; i < path.fieldList.size(); ++i) {
1019:                            Object pathEl = path.fieldList.get(i);
1020:                            if (pathEl instanceof  JDBCCMRFieldBridge) {
1021:                                addJoinPath(path);
1022:                                break;
1023:                            }
1024:                        }
1025:                    }
1026:
1027:                    buf = SQLUtil.getIsNullClause(node.not, field, alias, buf);
1028:                } else if (child0 instanceof  ASTParameter) {
1029:                    ASTParameter param = (ASTParameter) child0;
1030:                    Class type = getParameterType(param.number);
1031:
1032:                    QueryParameter queryParam = new QueryParameter(
1033:                            param.number - 1, typeFactory.getJDBCType(type));
1034:                    inputParameters.add(queryParam);
1035:
1036:                    buf.append("? IS ");
1037:                    if (node.not) {
1038:                        buf.append(SQLUtil.NOT);
1039:                    }
1040:                    buf.append(SQLUtil.NULL);
1041:                } else {
1042:                    throw new IllegalStateException(
1043:                            "Unexpected node in IS NULL clause: " + node);
1044:                }
1045:
1046:                return buf;
1047:            }
1048:
1049:            public Object visit(ASTIsEmpty node, Object data) {
1050:                StringBuffer buf = (StringBuffer) data;
1051:                ASTPath path = (ASTPath) node.jjtGetChild(0);
1052:
1053:                existsClause(path, buf, !node.not);
1054:                return buf;
1055:            }
1056:
1057:            /**
1058:             * Compare entity
1059:             */
1060:            public Object visit(ASTMemberOf node, Object data) {
1061:                StringBuffer buf = (StringBuffer) data;
1062:
1063:                // setup compare to vars first, so we can compre types in from vars
1064:                ASTPath toPath = (ASTPath) node.jjtGetChild(1);
1065:
1066:                JDBCCMRFieldBridge toCMRField = (JDBCCMRFieldBridge) toPath
1067:                        .getCMRField();
1068:
1069:                JDBCEntityBridge toChildEntity = (JDBCEntityBridge) toPath
1070:                        .getEntity();
1071:
1072:                String pathStr = toPath.getPath(toPath.size() - 2);
1073:                String toParentAlias = aliasManager.getAlias(pathStr);
1074:                String toChildAlias = aliasManager.getAlias(toPath.getPath());
1075:                String relationTableAlias = null;
1076:                if (toCMRField.getRelationMetaData().isTableMappingStyle()) {
1077:                    relationTableAlias = aliasManager
1078:                            .getRelationTableAlias(toPath.getPath());
1079:                }
1080:
1081:                // setup from variables
1082:                String fromAlias = null;
1083:                int fromParamNumber = -1;
1084:                if (node.jjtGetChild(0) instanceof  ASTParameter) {
1085:                    ASTParameter fromParam = (ASTParameter) node.jjtGetChild(0);
1086:
1087:                    // can only compare like kind entities
1088:                    verifyParameterEntityType(fromParam.number, toChildEntity);
1089:
1090:                    fromParamNumber = fromParam.number;
1091:                } else {
1092:                    ASTPath fromPath = (ASTPath) node.jjtGetChild(0);
1093:                    addJoinPath(fromPath);
1094:
1095:                    JDBCEntityBridge fromEntity = (JDBCEntityBridge) fromPath
1096:                            .getEntity();
1097:                    fromAlias = aliasManager.getAlias(fromPath.getPath());
1098:
1099:                    // can only compare like kind entities
1100:                    if (!fromEntity.equals(toChildEntity)) {
1101:                        throw new IllegalStateException(
1102:                                "Only like types can be "
1103:                                        + "compared: from entity="
1104:                                        + fromEntity.getEntityName()
1105:                                        + " to entity="
1106:                                        + toChildEntity.getEntityName());
1107:                    }
1108:                }
1109:
1110:                // add the path to the list of paths to left join
1111:                addLeftJoinPath(pathStr, toPath);
1112:
1113:                // first part makes toChild not in toParent.child
1114:                if (!subquerySupported) {
1115:                    addJoinPath(toPath);
1116:
1117:                    // subquery not supported; use a left join and is not null
1118:                    if (node.not) {
1119:                        buf.append(SQLUtil.NOT);
1120:                    }
1121:                    buf.append('(');
1122:
1123:                    if (relationTableAlias == null) {
1124:                        SQLUtil.getIsNullClause(true, toChildEntity
1125:                                .getPrimaryKeyFields(), toChildAlias, buf);
1126:                    } else {
1127:                        SQLUtil.getIsNullClause(true, toCMRField
1128:                                .getTableKeyFields(), relationTableAlias, buf);
1129:                    }
1130:                } else {
1131:                    // subquery supported; use exists subquery
1132:                    if (node.not) {
1133:                        buf.append(SQLUtil.NOT);
1134:                    }
1135:
1136:                    buf.append(SQLUtil.EXISTS).append('(');
1137:
1138:                    if (relationTableAlias == null) {
1139:                        buf.append(SQLUtil.SELECT);
1140:                        SQLUtil.getColumnNamesClause(
1141:                                toChildEntity.getPrimaryKeyFields(),
1142:                                toChildAlias, buf).append(SQLUtil.FROM).append(
1143:                                toChildEntity.getQualifiedTableName()).append(
1144:                                ' ').append(toChildAlias).append(SQLUtil.WHERE);
1145:                        SQLUtil.getJoinClause(toCMRField, toParentAlias,
1146:                                toChildAlias, buf);
1147:                    } else {
1148:                        buf.append(SQLUtil.SELECT);
1149:                        SQLUtil.getColumnNamesClause(
1150:                                toCMRField.getRelatedCMRField()
1151:                                        .getTableKeyFields(),
1152:                                relationTableAlias, buf).append(SQLUtil.FROM)
1153:                                .append(toCMRField.getQualifiedTableName())
1154:                                .append(' ').append(relationTableAlias).append(
1155:                                        SQLUtil.WHERE);
1156:                        SQLUtil.getRelationTableJoinClause(toCMRField,
1157:                                toParentAlias, relationTableAlias, buf);
1158:                    }
1159:                }
1160:
1161:                buf.append(SQLUtil.AND);
1162:
1163:                // second part makes fromNode equal toChild
1164:                if (fromAlias != null) {
1165:                    // compre pk to pk
1166:                    if (relationTableAlias == null) {
1167:                        SQLUtil.getSelfCompareWhereClause(toChildEntity
1168:                                .getPrimaryKeyFields(), toChildAlias,
1169:                                fromAlias, buf);
1170:                    } else {
1171:                        SQLUtil.getRelationTableJoinClause(toCMRField
1172:                                .getRelatedCMRField(), fromAlias,
1173:                                relationTableAlias, buf);
1174:                    }
1175:                } else {
1176:                    // add the parameters
1177:                    inputParameters.addAll(QueryParameter.createParameters(
1178:                            fromParamNumber - 1, toChildEntity));
1179:
1180:                    // compare pk to parameter
1181:                    if (relationTableAlias == null) {
1182:                        SQLUtil.getWhereClause(toChildEntity
1183:                                .getPrimaryKeyFields(), toChildAlias, buf);
1184:                    } else {
1185:                        SQLUtil.getWhereClause(toCMRField.getRelatedCMRField()
1186:                                .getTableKeyFields(), relationTableAlias, buf);
1187:                    }
1188:                }
1189:
1190:                buf.append(')');
1191:
1192:                return buf;
1193:            }
1194:
1195:            public Object visit(ASTValueClassComparison node, Object data) {
1196:                StringBuffer buf = (StringBuffer) data;
1197:
1198:                boolean not = (node.opp.equals(SQLUtil.NOT_EQUAL));
1199:                String comparison = node.opp;
1200:                buf.append('(');
1201:                if (not) {
1202:                    buf.append(SQLUtil.NOT).append('(');
1203:                    comparison = "=";
1204:                }
1205:
1206:                // setup the from path
1207:                ASTPath fromPath = (ASTPath) node.jjtGetChild(0);
1208:                addJoinPath(fromPath);
1209:                String fromAlias = aliasManager.getAlias(fromPath
1210:                        .getPath(fromPath.size() - 2));
1211:                JDBCCMPFieldBridge fromCMPField = (JDBCCMPFieldBridge) fromPath
1212:                        .getCMPField();
1213:
1214:                Node toNode = node.jjtGetChild(1);
1215:                if (toNode instanceof  ASTParameter) {
1216:                    ASTParameter toParam = (ASTParameter) toNode;
1217:
1218:                    // can only compare like kind entities
1219:                    Class parameterType = getParameterType(toParam.number);
1220:                    if (!(fromCMPField.getFieldType().equals(parameterType))) {
1221:                        throw new IllegalStateException(
1222:                                "Only like types can be "
1223:                                        + "compared: from CMP field="
1224:                                        + fromCMPField.getFieldType()
1225:                                        + " to parameter=" + parameterType);
1226:                    }
1227:
1228:                    inputParameters.addAll(QueryParameter.createParameters(
1229:                            toParam.number - 1, fromCMPField));
1230:                    SQLUtil.getWhereClause(fromCMPField.getJDBCType(),
1231:                            fromAlias, comparison, buf);
1232:                } else {
1233:                    ASTPath toPath = (ASTPath) toNode;
1234:                    addJoinPath(toPath);
1235:                    String toAlias = aliasManager.getAlias(toPath
1236:                            .getPath(toPath.size() - 2));
1237:                    JDBCCMPFieldBridge toCMPField = (JDBCCMPFieldBridge) toPath
1238:                            .getCMPField();
1239:
1240:                    // can only compare like kind entities
1241:                    if (!(fromCMPField.getFieldType().equals(toCMPField
1242:                            .getFieldType()))) {
1243:                        throw new IllegalStateException(
1244:                                "Only like types can be "
1245:                                        + "compared: from CMP field="
1246:                                        + fromCMPField.getFieldType()
1247:                                        + " to CMP field="
1248:                                        + toCMPField.getFieldType());
1249:                    }
1250:
1251:                    SQLUtil.getSelfCompareWhereClause(fromCMPField, toCMPField,
1252:                            fromAlias, toAlias, comparison, buf);
1253:                }
1254:
1255:                return (not ? buf.append(')') : buf).append(')');
1256:            }
1257:
1258:            /**
1259:             * compreEntity(arg0, arg1)
1260:             */
1261:            public Object visit(ASTEntityComparison node, Object data) {
1262:                StringBuffer buf = (StringBuffer) data;
1263:                Node arg0 = node.jjtGetChild(0);
1264:                Node arg1 = node.jjtGetChild(1);
1265:                if (node.opp.equals(SQLUtil.NOT_EQUAL)) {
1266:                    compareEntity(true, arg0, arg1, buf);
1267:                } else {
1268:                    compareEntity(false, arg0, arg1, buf);
1269:                }
1270:                return buf;
1271:            }
1272:
1273:            /**
1274:             * Type-mapping function translation
1275:             */
1276:            public Object visit(ASTConcat node, Object data) {
1277:                StringBuffer buf = (StringBuffer) data;
1278:                JDBCFunctionMappingMetaData function = typeMapping
1279:                        .getFunctionMapping(JDBCTypeMappingMetaData.CONCAT);
1280:                Object[] args = new Object[] {
1281:                        new NodeStringWrapper(node.jjtGetChild(0)),
1282:                        new NodeStringWrapper(node.jjtGetChild(1)), };
1283:                function.getFunctionSql(args, buf);
1284:                return buf;
1285:            }
1286:
1287:            /**
1288:             * Type-mapping function translation
1289:             */
1290:            public Object visit(ASTSubstring node, Object data) {
1291:                StringBuffer buf = (StringBuffer) data;
1292:                JDBCFunctionMappingMetaData function = typeMapping
1293:                        .getFunctionMapping(JDBCTypeMappingMetaData.SUBSTRING);
1294:                Object[] args = new Object[] {
1295:                        new NodeStringWrapper(node.jjtGetChild(0)),
1296:                        new NodeStringWrapper(node.jjtGetChild(1)),
1297:                        new NodeStringWrapper(node.jjtGetChild(2)), };
1298:                function.getFunctionSql(args, buf);
1299:                return buf;
1300:            }
1301:
1302:            /**
1303:             * Type-mapping function translation
1304:             */
1305:            public Object visit(ASTLCase node, Object data) {
1306:                StringBuffer buf = (StringBuffer) data;
1307:                JDBCFunctionMappingMetaData function = typeMapping
1308:                        .getFunctionMapping(JDBCTypeMappingMetaData.LCASE);
1309:                Object[] args = new Object[] { new NodeStringWrapper(node
1310:                        .jjtGetChild(0)), };
1311:                function.getFunctionSql(args, buf);
1312:                return buf;
1313:            }
1314:
1315:            /**
1316:             * Type-mapping function translation
1317:             */
1318:            public Object visit(ASTUCase node, Object data) {
1319:                StringBuffer buf = (StringBuffer) data;
1320:                JDBCFunctionMappingMetaData function = typeMapping
1321:                        .getFunctionMapping(JDBCTypeMappingMetaData.UCASE);
1322:                Object[] args = new Object[] { new NodeStringWrapper(node
1323:                        .jjtGetChild(0)), };
1324:                function.getFunctionSql(args, buf);
1325:                return buf;
1326:            }
1327:
1328:            /**
1329:             * Type-mapping function translation
1330:             */
1331:            public Object visit(ASTLength node, Object data) {
1332:                StringBuffer buf = (StringBuffer) data;
1333:                JDBCFunctionMappingMetaData function = typeMapping
1334:                        .getFunctionMapping(JDBCTypeMappingMetaData.LENGTH);
1335:                Object[] args = new Object[] { new NodeStringWrapper(node
1336:                        .jjtGetChild(0)), };
1337:                function.getFunctionSql(args, buf);
1338:                return buf;
1339:            }
1340:
1341:            /**
1342:             * Type-mapping function translation
1343:             */
1344:            public Object visit(ASTLocate node, Object data) {
1345:                StringBuffer buf = (StringBuffer) data;
1346:
1347:                JDBCFunctionMappingMetaData function = typeMapping
1348:                        .getFunctionMapping(JDBCTypeMappingMetaData.LOCATE);
1349:                Object[] args = new Object[3];
1350:                args[0] = new NodeStringWrapper(node.jjtGetChild(0));
1351:                args[1] = new NodeStringWrapper(node.jjtGetChild(1));
1352:                if (node.jjtGetNumChildren() == 3) {
1353:                    args[2] = new NodeStringWrapper(node.jjtGetChild(2));
1354:                } else {
1355:                    args[2] = "1";
1356:                }
1357:
1358:                // add the sql to the current buffer
1359:                function.getFunctionSql(args, buf);
1360:                return buf;
1361:            }
1362:
1363:            /**
1364:             * Type-mapping function translation
1365:             */
1366:            public Object visit(ASTAbs node, Object data) {
1367:                StringBuffer buf = (StringBuffer) data;
1368:                JDBCFunctionMappingMetaData function = typeMapping
1369:                        .getFunctionMapping(JDBCTypeMappingMetaData.ABS);
1370:                Object[] args = new Object[] { new NodeStringWrapper(node
1371:                        .jjtGetChild(0)), };
1372:                function.getFunctionSql(args, buf);
1373:                return buf;
1374:            }
1375:
1376:            /**
1377:             * Type-mapping function translation
1378:             */
1379:            public Object visit(ASTMod node, Object data) {
1380:                StringBuffer buf = (StringBuffer) data;
1381:                JDBCFunctionMappingMetaData function = typeMapping
1382:                        .getFunctionMapping(JDBCTypeMappingMetaData.MOD);
1383:                Object[] args = new Object[] {
1384:                        new NodeStringWrapper(node.jjtGetChild(0)),
1385:                        new NodeStringWrapper(node.jjtGetChild(1)), };
1386:                function.getFunctionSql(args, buf);
1387:                return buf;
1388:            }
1389:
1390:            /**
1391:             * Type-mapping function translation
1392:             */
1393:            public Object visit(ASTSqrt node, Object data) {
1394:                StringBuffer buf = (StringBuffer) data;
1395:                JDBCFunctionMappingMetaData function = typeMapping
1396:                        .getFunctionMapping(JDBCTypeMappingMetaData.SQRT);
1397:                Object[] args = new Object[] { new NodeStringWrapper(node
1398:                        .jjtGetChild(0)) };
1399:                function.getFunctionSql(args, buf);
1400:                return buf;
1401:            }
1402:
1403:            public Object visit(ASTCount node, Object data) {
1404:                StringBuffer buf = (StringBuffer) data;
1405:                node.setResultType(returnType);
1406:
1407:                Object args[];
1408:                final ASTPath cntPath = (ASTPath) node.jjtGetChild(0);
1409:                if (cntPath.isCMPField()) {
1410:                    args = new Object[] { node.distinct,
1411:                            new NodeStringWrapper(cntPath) };
1412:                } else {
1413:                    JDBCEntityBridge entity = (JDBCEntityBridge) cntPath
1414:                            .getEntity();
1415:                    final JDBCFieldBridge[] pkFields = entity
1416:                            .getPrimaryKeyFields();
1417:                    if (pkFields.length > 1) {
1418:                        countCompositePk = true;
1419:                        forceDistinct = node.distinct.length() > 0;
1420:                        selectEntity(cntPath, buf);
1421:                        return buf;
1422:                    } else {
1423:
1424:                        final String alias = aliasManager.getAlias(cntPath
1425:                                .getPath());
1426:                        StringBuffer keyColumn = new StringBuffer(20);
1427:                        SQLUtil.getColumnNamesClause(pkFields[0], alias,
1428:                                keyColumn);
1429:                        args = new Object[] { node.distinct,
1430:                                keyColumn.toString() };
1431:                    }
1432:                }
1433:
1434:                return JDBCTypeMappingMetaData.COUNT_FUNC.getFunctionSql(args,
1435:                        buf);
1436:            }
1437:
1438:            public Object visit(ASTMax node, Object data) {
1439:                node.setResultType(returnType);
1440:                StringBuffer buf = (StringBuffer) data;
1441:                Object[] args = new Object[] { node.distinct,
1442:                        new NodeStringWrapper(node.jjtGetChild(0)) };
1443:                return JDBCTypeMappingMetaData.MAX_FUNC.getFunctionSql(args,
1444:                        buf);
1445:            }
1446:
1447:            public Object visit(ASTMin node, Object data) {
1448:                node.setResultType(returnType);
1449:                StringBuffer buf = (StringBuffer) data;
1450:                Object[] args = new Object[] { node.distinct,
1451:                        new NodeStringWrapper(node.jjtGetChild(0)) };
1452:                return JDBCTypeMappingMetaData.MIN_FUNC.getFunctionSql(args,
1453:                        buf);
1454:            }
1455:
1456:            public Object visit(ASTAvg node, Object data) {
1457:                node.setResultType(returnType);
1458:                StringBuffer buf = (StringBuffer) data;
1459:                Object[] args = new Object[] { node.distinct,
1460:                        new NodeStringWrapper(node.jjtGetChild(0)), };
1461:                return JDBCTypeMappingMetaData.AVG_FUNC.getFunctionSql(args,
1462:                        buf);
1463:            }
1464:
1465:            public Object visit(ASTSum node, Object data) {
1466:                node.setResultType(returnType);
1467:                StringBuffer buf = (StringBuffer) data;
1468:                Object[] args = new Object[] { node.distinct,
1469:                        new NodeStringWrapper(node.jjtGetChild(0)) };
1470:                return JDBCTypeMappingMetaData.SUM_FUNC.getFunctionSql(args,
1471:                        buf);
1472:            }
1473:
1474:            /**
1475:             * tableAlias.columnName
1476:             */
1477:            public Object visit(ASTPath node, Object data) {
1478:                StringBuffer buf = (StringBuffer) data;
1479:                if (!node.isCMPField()) {
1480:                    throw new IllegalStateException(
1481:                            "Can only visit cmp valued path "
1482:                                    + "node. Should have been handled at a higher level.");
1483:                }
1484:
1485:                JDBCCMPFieldBridge cmpField = (JDBCCMPFieldBridge) node
1486:                        .getCMPField();
1487:
1488:                // make sure this is mapped to a single column
1489:                switch (node.type) {
1490:                case EJBQLTypes.ENTITY_TYPE:
1491:                case EJBQLTypes.VALUE_CLASS_TYPE:
1492:                    if (cmpField.getJDBCType().hasMapper()) {
1493:                        break;
1494:                    }
1495:                case EJBQLTypes.UNKNOWN_TYPE:
1496:                    throw new IllegalStateException(
1497:                            "Can not visit multi-column path "
1498:                                    + "node. Should have been handled at a higher level.");
1499:                }
1500:
1501:                addJoinPath(node);
1502:                String alias = aliasManager.getAlias(node
1503:                        .getPath(node.size() - 2));
1504:                SQLUtil.getColumnNamesClause(cmpField, alias, buf);
1505:                return buf;
1506:            }
1507:
1508:            public Object visit(ASTAbstractSchema node, Object data) {
1509:                throw new IllegalStateException(
1510:                        "Can not visit abstract schema node. "
1511:                                + "Should have been handled at a higher level.");
1512:            }
1513:
1514:            /**
1515:             * ?
1516:             */
1517:            public Object visit(ASTParameter node, Object data) {
1518:                StringBuffer buf = (StringBuffer) data;
1519:                Class type = getParameterType(node.number);
1520:
1521:                // make sure this is mapped to a single column
1522:                int ejbqlType = EJBQLTypes.getEJBQLType(type);
1523:                if (ejbqlType == EJBQLTypes.ENTITY_TYPE
1524:                        || ejbqlType == EJBQLTypes.VALUE_CLASS_TYPE
1525:                        || ejbqlType == EJBQLTypes.UNKNOWN_TYPE) {
1526:                    throw new IllegalStateException(
1527:                            "Can not visit multi-column "
1528:                                    + "parameter node. Should have been handled at a higher level.");
1529:                }
1530:
1531:                QueryParameter param = new QueryParameter(node.number - 1,
1532:                        typeFactory.getJDBCType(type));
1533:                inputParameters.add(param);
1534:                buf.append('?');
1535:                return buf;
1536:            }
1537:
1538:            /**
1539:             * typeMapping.get<True/False>Mapping()
1540:             */
1541:            public Object visit(ASTBooleanLiteral node, Object data) {
1542:                StringBuffer buf = (StringBuffer) data;
1543:                if (node.value) {
1544:                    buf.append(typeMapping.getTrueMapping());
1545:                } else {
1546:                    buf.append(typeMapping.getFalseMapping());
1547:                }
1548:                return data;
1549:            }
1550:
1551:            public Object visit(ASTLimitOffset node, Object data) {
1552:                int child = 0;
1553:                if (node.hasOffset) {
1554:                    Node offsetNode = node.jjtGetChild(child++);
1555:                    if (offsetNode instanceof  ASTParameter) {
1556:                        ASTParameter param = (ASTParameter) offsetNode;
1557:                        Class parameterType = getParameterType(param.number);
1558:                        if (int.class != parameterType
1559:                                && Integer.class != parameterType) {
1560:                            throw new UnsupportedOperationException(
1561:                                    "OFFSET parameter must be an int");
1562:                        }
1563:                        offsetParam = param.number;
1564:                    } else {
1565:                        ASTExactNumericLiteral param = (ASTExactNumericLiteral) offsetNode;
1566:                        offsetValue = (int) param.value;
1567:                    }
1568:                }
1569:                if (node.hasLimit) {
1570:                    Node limitNode = node.jjtGetChild(child);
1571:                    if (limitNode instanceof  ASTParameter) {
1572:                        ASTParameter param = (ASTParameter) limitNode;
1573:                        Class parameterType = getParameterType(param.number);
1574:                        if (int.class != parameterType
1575:                                && Integer.class != parameterType) {
1576:                            throw new UnsupportedOperationException(
1577:                                    "LIMIT parameter must be an int");
1578:                        }
1579:                        limitParam = param.number;
1580:                    } else {
1581:                        ASTExactNumericLiteral param = (ASTExactNumericLiteral) limitNode;
1582:                        limitValue = (int) param.value;
1583:                    }
1584:                }
1585:                return data;
1586:            }
1587:
1588:            public Object visit(ASTWhereConditionalTerm node, Object data) {
1589:                // clear per term paths
1590:                clearPerTermJoinPaths();
1591:
1592:                StringBuffer buf = (StringBuffer) data;
1593:                buf.append('(');
1594:                for (int i = 0; i < node.jjtGetNumChildren(); ++i) {
1595:                    node.jjtGetChild(i).jjtAccept(this , data);
1596:                }
1597:
1598:                StringBuffer thetaJoin = new StringBuffer();
1599:                createThetaJoin(thetaJoin);
1600:
1601:                if (thetaJoin.length() > 0) {
1602:                    buf.append(SQLUtil.AND).append(thetaJoin.toString());
1603:                }
1604:
1605:                buf.append(')');
1606:                return data;
1607:            }
1608:
1609:            /**
1610:             * Wrap a node with a class that when ever toString is called visits the
1611:             * node.  This is used by the function implmentations, for parameters.
1612:             * <p/>
1613:             * Be careful with this class because it visits the node for each call of
1614:             * toString, which could have undesireable result if called multiple times.
1615:             */
1616:            private final class NodeStringWrapper {
1617:                final Node node;
1618:
1619:                public NodeStringWrapper(Node node) {
1620:                    this .node = node;
1621:                }
1622:
1623:                public String toString() {
1624:                    return node.jjtAccept(JDBCEJBQLCompiler.this ,
1625:                            new StringBuffer()).toString();
1626:                }
1627:            }
1628:
1629:            /**
1630:             * Recursively searches for ASTPath among children.
1631:             *
1632:             * @param selectFunction a node implements SelectFunction
1633:             * @return ASTPath child or null if there was no child of type ASTPath
1634:             */
1635:            private ASTPath getPathFromChildren(Node selectFunction) {
1636:                for (int childInd = 0; childInd < selectFunction
1637:                        .jjtGetNumChildren(); ++childInd) {
1638:                    Node child = selectFunction.jjtGetChild(childInd);
1639:                    if (child instanceof  ASTPath) {
1640:                        return (ASTPath) child;
1641:                    } else if (child instanceof  SelectFunction) {
1642:                        Node path = getPathFromChildren(child);
1643:                        if (path != null) {
1644:                            return (ASTPath) path;
1645:                        }
1646:                    }
1647:                }
1648:                return null;
1649:            }
1650:
1651:            /**
1652:             * Checks whether the path passed in is already in the SELECT clause.
1653:             *
1654:             * @param path the path to check.
1655:             * @return true  if the path is already in the SELECT clause.
1656:             */
1657:            private boolean isSelected(ASTPath path) {
1658:                boolean selected = false;
1659:
1660:                CMPFieldBridge cmpField = path.getCMPField();
1661:                if (selectObject instanceof  JDBCCMPFieldBridge
1662:                        && cmpField == selectObject) {
1663:                    selected = true;
1664:                } else if (selectObject instanceof  JDBCEntityBridge) {
1665:                    JDBCEntityBridge entity = (JDBCEntityBridge) selectObject;
1666:                    JDBCFieldBridge[] pkFields = entity.getPrimaryKeyFields();
1667:                    for (int pkInd = 0; pkInd < pkFields.length; ++pkInd) {
1668:                        if (pkFields[pkInd] == cmpField) {
1669:                            selected = true;
1670:                            break;
1671:                        }
1672:                    }
1673:                } else if (selectObject instanceof  SelectFunction) {
1674:                    Node funcNode = (Node) selectObject;
1675:                    ASTPath fieldPath = getPathFromChildren(funcNode);
1676:                    if (fieldPath.getCMPField() == cmpField) {
1677:                        selected = true;
1678:                    }
1679:                }
1680:
1681:                return selected;
1682:            }
1683:
1684:            private void selectEntity(ASTPath path, StringBuffer buf) {
1685:                JDBCEntityBridge selectEntity = (JDBCEntityBridge) path
1686:                        .getEntity();
1687:
1688:                StringBuffer columnNamesClause = new StringBuffer(200);
1689:                addJoinPath(path);
1690:                selectAlias = aliasManager.getAlias(path.getPath());
1691:
1692:                // get a list of all fields to be loaded
1693:                // get the identifier for this field
1694:                SQLUtil.getColumnNamesClause(
1695:                        selectEntity.getPrimaryKeyFields(), selectAlias,
1696:                        columnNamesClause);
1697:
1698:                if (readAhead.isOnFind()) {
1699:                    String eagerLoadGroupName = readAhead.getEagerLoadGroup();
1700:                    boolean[] loadGroupMask = selectEntity
1701:                            .getLoadGroupMask(eagerLoadGroupName);
1702:                    SQLUtil.appendColumnNamesClause(selectEntity
1703:                            .getTableFields(), loadGroupMask, selectAlias,
1704:                            columnNamesClause);
1705:
1706:                    try {
1707:                        leftJoinCMRList = JDBCAbstractQueryCommand
1708:                                .getLeftJoinCMRNodes(selectEntity, path
1709:                                        .getPath(), readAhead.getLeftJoins(),
1710:                                        declaredPaths);
1711:                    } catch (DeploymentException e) {
1712:                        throw new IllegalStateException(e.getMessage());
1713:                    }
1714:
1715:                    if (!leftJoinCMRList.isEmpty()) {
1716:                        onFindCMRJoin = new StringBuffer(100);
1717:                        JDBCAbstractQueryCommand.leftJoinCMRNodes(selectAlias,
1718:                                leftJoinCMRList, aliasManager, onFindCMRJoin);
1719:                        JDBCAbstractQueryCommand.appendLeftJoinCMRColumnNames(
1720:                                leftJoinCMRList, aliasManager,
1721:                                columnNamesClause);
1722:                    }
1723:                }
1724:                buf.append(columnNamesClause);
1725:            }
1726:
1727:            private void addJoinPath(ASTPath path) {
1728:                ctermJoinPaths.add(path);
1729:                allJoinPaths.add(path);
1730:            }
1731:
1732:            private void addCollectionMemberJoinPath(String alias, ASTPath path) {
1733:                ctermCollectionMemberJoinPaths.put(alias, path);
1734:                allCollectionMemberJoinPaths.put(alias, path);
1735:            }
1736:
1737:            private void addLeftJoinPath(String pathStr, ASTPath path) {
1738:                Set set = (Set) ctermLeftJoinPaths.get(pathStr);
1739:                if (set == null) {
1740:                    set = new HashSet();
1741:                    ctermLeftJoinPaths.put(pathStr, set);
1742:                }
1743:                set.add(path);
1744:
1745:                set = (Set) allLeftJoinPaths.get(pathStr);
1746:                if (set == null) {
1747:                    set = new HashSet();
1748:                    allLeftJoinPaths.put(pathStr, set);
1749:                }
1750:                set.add(path);
1751:            }
1752:
1753:            private void clearPerTermJoinPaths() {
1754:                ctermJoinPaths.clear();
1755:                ctermCollectionMemberJoinPaths.clear();
1756:                ctermLeftJoinPaths.clear();
1757:            }
1758:
1759:            private boolean isDistinct(Node selectNode) {
1760:                return ((ASTSelect) selectNode).distinct
1761:                        || returnType.equals(Set.class) || forceDistinct;
1762:            }
1763:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.