Source Code Cross Referenced for JDBCAbstractQueryCommand.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) 


001:        /*
002:         * JBoss, Home of Professional Open Source.
003:         * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004:         * as indicated by the @author tags. See the copyright.txt file in the
005:         * distribution for a full listing of individual contributors.
006:         *
007:         * This is free software; you can redistribute it and/or modify it
008:         * under the terms of the GNU Lesser General Public License as
009:         * published by the Free Software Foundation; either version 2.1 of
010:         * the License, or (at your option) any later version.
011:         *
012:         * This software is distributed in the hope that it will be useful,
013:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015:         * Lesser General Public License for more details.
016:         *
017:         * You should have received a copy of the GNU Lesser General Public
018:         * License along with this software; if not, write to the Free
019:         * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021:         */
022:        package org.jboss.ejb.plugins.cmp.jdbc;
023:
024:        import java.lang.reflect.Method;
025:        import java.sql.Connection;
026:        import java.sql.PreparedStatement;
027:        import java.sql.ResultSet;
028:        import java.sql.SQLException;
029:        import java.util.ArrayList;
030:        import java.util.Collection;
031:        import java.util.List;
032:        import java.util.StringTokenizer;
033:        import java.util.Collections;
034:        import java.util.Iterator;
035:        import java.util.AbstractCollection;
036:        import java.util.NoSuchElementException;
037:        import java.util.Set;
038:        import javax.ejb.FinderException;
039:        import javax.ejb.EJBException;
040:        import javax.transaction.Synchronization;
041:
042:        import org.jboss.deployment.DeploymentException;
043:        import org.jboss.ejb.EntityEnterpriseContext;
044:        import org.jboss.ejb.GenericEntityObjectFactory;
045:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMPFieldBridge;
046:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCEntityBridge;
047:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCCMRFieldBridge;
048:        import org.jboss.ejb.plugins.cmp.jdbc.bridge.JDBCFieldBridge;
049:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCQueryMetaData;
050:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCLeftJoinMetaData;
051:        import org.jboss.ejb.plugins.cmp.jdbc.metadata.JDBCRelationMetaData;
052:        import org.jboss.ejb.plugins.cmp.ejbql.SelectFunction;
053:        import org.jboss.logging.Logger;
054:
055:        /**
056:         * Abstract superclass of finder commands that return collections.
057:         * Provides the handleResult() implementation that these all need.
058:         * 
059:         * @author <a href="mailto:dain@daingroup.com">Dain Sundstrom</a>
060:         * @author <a href="mailto:rickard.oberg@telkel.com">Rickard �berg</a>
061:         * @author <a href="mailto:marc.fleury@telkel.com">Marc Fleury</a>
062:         * @author <a href="mailto:shevlandj@kpi.com.au">Joe Shevland</a>
063:         * @author <a href="mailto:justin@j-m-f.demon.co.uk">Justin Forder</a>
064:         * @author <a href="mailto:alex@jboss.org">Alex Loubyansky</a>
065:         * @version $Revision: 57209 $
066:         */
067:        public abstract class JDBCAbstractQueryCommand implements 
068:                JDBCQueryCommand {
069:            private JDBCQueryMetaData queryMetaData;
070:            protected Logger log;
071:
072:            private JDBCStoreManager selectManager;
073:            private JDBCEntityBridge selectEntity;
074:            private JDBCCMPFieldBridge selectField;
075:            private SelectFunction selectFunction;
076:            private boolean[] eagerLoadMask;
077:            private String eagerLoadGroup;
078:            private String sql;
079:            private int offsetParam;
080:            private int offsetValue;
081:            private int limitParam;
082:            private int limitValue;
083:            private List parameters = new ArrayList(0);
084:            private List onFindCMRList = Collections.EMPTY_LIST;
085:            private QueryCollectionFactory collectionFactory;
086:
087:            public JDBCAbstractQueryCommand(JDBCStoreManager manager,
088:                    JDBCQueryMetaData q) throws DeploymentException {
089:                this .log = Logger.getLogger(this .getClass().getName() + "."
090:                        + manager.getMetaData().getName() + "#"
091:                        + q.getMethod().getName());
092:
093:                queryMetaData = q;
094:                collectionFactory = q.isLazyResultSetLoading() ? new LazyCollectionFactory()
095:                        : (QueryCollectionFactory) new EagerCollectionFactory();
096:
097:                //      setDefaultOffset(q.getOffsetParam());
098:                //      setDefaultLimit(q.getLimitParam());
099:                setSelectEntity((JDBCEntityBridge) manager.getEntityBridge());
100:            }
101:
102:            public void setOffsetValue(int offsetValue) {
103:                this .offsetValue = offsetValue;
104:            }
105:
106:            public void setLimitValue(int limitValue) {
107:                this .limitValue = limitValue;
108:            }
109:
110:            public void setOffsetParam(int offsetParam) {
111:                this .offsetParam = offsetParam;
112:            }
113:
114:            public void setLimitParam(int limitParam) {
115:                this .limitParam = limitParam;
116:            }
117:
118:            public void setOnFindCMRList(List onFindCMRList) {
119:                this .onFindCMRList = onFindCMRList;
120:            }
121:
122:            public JDBCStoreManager getSelectManager() {
123:                return selectManager;
124:            }
125:
126:            public Collection execute(Method finderMethod, Object[] args,
127:                    EntityEnterpriseContext ctx,
128:                    GenericEntityObjectFactory factory) throws FinderException {
129:                int offset = toInt(args, offsetParam, offsetValue);
130:                int limit = toInt(args, limitParam, limitValue);
131:                return execute(sql, args, offset, limit, selectEntity,
132:                        selectField, selectFunction, selectManager,
133:                        eagerLoadMask, parameters, onFindCMRList,
134:                        queryMetaData, factory, log);
135:            }
136:
137:            protected static int toInt(Object[] params, int paramNumber,
138:                    int defaultValue) {
139:                if (paramNumber == 0) {
140:                    return defaultValue;
141:                }
142:                Integer arg = (Integer) params[paramNumber - 1];
143:                return arg.intValue();
144:            }
145:
146:            protected Collection execute(String sql, Object[] args, int offset,
147:                    int limit, JDBCEntityBridge selectEntity,
148:                    JDBCCMPFieldBridge selectField,
149:                    SelectFunction selectFunction,
150:                    JDBCStoreManager selectManager, boolean[] eagerLoadMask,
151:                    List parameters, List onFindCMRList,
152:                    JDBCQueryMetaData queryMetaData,
153:                    GenericEntityObjectFactory factory, Logger log)
154:                    throws FinderException {
155:                int count = offset;
156:                Connection con = null;
157:                PreparedStatement ps = null;
158:                ResultSet rs = null;
159:                final JDBCEntityBridge entityBridge = (JDBCEntityBridge) selectManager
160:                        .getEntityBridge();
161:                boolean throwRuntimeExceptions = entityBridge.getMetaData()
162:                        .getThrowRuntimeExceptions();
163:
164:                // if metadata is true, the getconnection is done inside 
165:                // its own try catch block to throw a runtime exception (EJBException)
166:                if (throwRuntimeExceptions) {
167:                    try {
168:                        con = entityBridge.getDataSource().getConnection();
169:                    } catch (SQLException sqle) {
170:                        javax.ejb.EJBException ejbe = new javax.ejb.EJBException(
171:                                "Could not get a connection; " + sqle);
172:                        ejbe.initCause(sqle);
173:                        throw ejbe;
174:                    }
175:                }
176:
177:                try {
178:                    // create the statement
179:                    if (log.isDebugEnabled()) {
180:                        log.debug("Executing SQL: " + sql);
181:                        if (limit != 0 || offset != 0) {
182:                            log.debug("Query offset=" + offset + ", limit="
183:                                    + limit);
184:                        }
185:                    }
186:
187:                    // if metadata is false, the getconnection is done inside this try catch block
188:                    if (!throwRuntimeExceptions) {
189:                        con = entityBridge.getDataSource().getConnection();
190:                    }
191:                    ps = con.prepareStatement(sql);
192:
193:                    // Set the fetch size of the statement
194:                    if (entityBridge.getFetchSize() > 0) {
195:                        ps.setFetchSize(entityBridge.getFetchSize());
196:                    }
197:
198:                    // set the parameters
199:                    for (int i = 0; i < parameters.size(); i++) {
200:                        QueryParameter parameter = (QueryParameter) parameters
201:                                .get(i);
202:                        parameter.set(log, ps, i + 1, args);
203:                    }
204:
205:                    // execute statement
206:                    rs = ps.executeQuery();
207:
208:                    // skip 'offset' results
209:                    while (count > 0 && rs.next()) {
210:                        count--;
211:                    }
212:
213:                    count = limit;
214:                } catch (Exception e) {
215:                    JDBCUtil.safeClose(rs);
216:                    JDBCUtil.safeClose(ps);
217:                    JDBCUtil.safeClose(con);
218:
219:                    log.error("Find failed", e);
220:                    FinderException fe = new FinderException("Find failed: "
221:                            + e);
222:                    fe.initCause(e);
223:                    throw fe;
224:                }
225:
226:                return collectionFactory.createCollection(con, ps, rs, limit,
227:                        count, selectEntity, selectField, selectFunction,
228:                        selectManager, onFindCMRList, eagerLoadMask, factory);
229:            }
230:
231:            protected Logger getLog() {
232:                return log;
233:            }
234:
235:            protected void setSQL(String sql) {
236:                this .sql = sql;
237:                if (log.isDebugEnabled()) {
238:                    log.debug("SQL: " + sql);
239:                }
240:            }
241:
242:            protected void setParameterList(List p) {
243:                for (int i = 0; i < p.size(); i++) {
244:                    if (!(p.get(i) instanceof  QueryParameter)) {
245:                        throw new IllegalArgumentException("Element " + i
246:                                + " of list "
247:                                + "is not an instance of QueryParameter, but "
248:                                + p.get(i).getClass().getName());
249:                    }
250:                }
251:                parameters = new ArrayList(p);
252:            }
253:
254:            protected JDBCEntityBridge getSelectEntity() {
255:                return selectEntity;
256:            }
257:
258:            protected void setSelectEntity(JDBCEntityBridge selectEntity)
259:                    throws DeploymentException {
260:                if (queryMetaData.getMethod().getName().startsWith("find")
261:                        && this .selectEntity != null
262:                        && this .selectEntity != selectEntity) {
263:                    throw new DeploymentException("Finder "
264:                            + queryMetaData.getMethod().getName()
265:                            + " defined on "
266:                            + this .selectEntity.getEntityName()
267:                            + " should return only instances of "
268:                            + this .selectEntity.getEntityName()
269:                            + " but the query results in instances of "
270:                            + selectEntity.getEntityName());
271:                }
272:
273:                this .selectField = null;
274:                this .selectFunction = null;
275:                this .selectEntity = selectEntity;
276:                this .selectManager = (JDBCStoreManager) selectEntity
277:                        .getManager();
278:            }
279:
280:            protected JDBCCMPFieldBridge getSelectField() {
281:                return selectField;
282:            }
283:
284:            protected void setSelectField(JDBCCMPFieldBridge selectField) {
285:                this .selectEntity = null;
286:                this .selectFunction = null;
287:                this .selectField = selectField;
288:                this .selectManager = (JDBCStoreManager) selectField
289:                        .getManager();
290:            }
291:
292:            protected void setSelectFunction(SelectFunction func,
293:                    JDBCStoreManager manager) {
294:                this .selectEntity = null;
295:                this .selectField = null;
296:                this .selectFunction = func;
297:                this .selectManager = manager;
298:            }
299:
300:            protected void setEagerLoadGroup(String eagerLoadGroup) {
301:                this .eagerLoadGroup = eagerLoadGroup;
302:                this .eagerLoadMask = selectEntity
303:                        .getLoadGroupMask(eagerLoadGroup);
304:            }
305:
306:            protected String getEagerLoadGroup() {
307:                return eagerLoadGroup;
308:            }
309:
310:            protected boolean[] getEagerLoadMask() {
311:                return this .eagerLoadMask;
312:            }
313:
314:            /**
315:             * Replaces the parameters in the specifiec sql with question marks, and
316:             * initializes the parameter setting code. Parameters are encoded in curly
317:             * brackets use a zero based index.
318:             * 
319:             * @param sql the sql statement that is parsed for parameters
320:             * @return the original sql statement with the parameters replaced with a
321:             *         question mark
322:             * @throws DeploymentException if a error occures while parsing the sql
323:             */
324:            protected String parseParameters(String sql)
325:                    throws DeploymentException {
326:                StringBuffer sqlBuf = new StringBuffer();
327:                ArrayList params = new ArrayList();
328:
329:                // Replace placeholders {0} with ?
330:                if (sql != null) {
331:                    sql = sql.trim();
332:
333:                    StringTokenizer tokens = new StringTokenizer(sql, "{}",
334:                            true);
335:                    while (tokens.hasMoreTokens()) {
336:                        String token = tokens.nextToken();
337:                        if (token.equals("{")) {
338:                            token = tokens.nextToken();
339:                            if (Character.isDigit(token.charAt(0))) {
340:                                QueryParameter parameter = new QueryParameter(
341:                                        selectManager, queryMetaData
342:                                                .getMethod(), token);
343:
344:                                // of if we are here we can assume that we have
345:                                // a parameter and not a function
346:                                sqlBuf.append("?");
347:                                params.add(parameter);
348:
349:                                if (!tokens.nextToken().equals("}")) {
350:                                    throw new DeploymentException(
351:                                            "Invalid parameter - missing closing '}' : "
352:                                                    + sql);
353:                                }
354:                            } else {
355:                                // ok we don't have a parameter, we have a function
356:                                // push the tokens on the buffer and continue
357:                                sqlBuf.append("{").append(token);
358:                            }
359:                        } else {
360:                            // not parameter... just append it
361:                            sqlBuf.append(token);
362:                        }
363:                    }
364:                }
365:
366:                parameters = params;
367:
368:                return sqlBuf.toString();
369:            }
370:
371:            // Static
372:
373:            public static List getLeftJoinCMRNodes(JDBCEntityBridge entity,
374:                    String path, Iterator leftJoinIter, Set declaredPaths)
375:                    throws DeploymentException {
376:                List leftJoinCMRNodes;
377:
378:                if (leftJoinIter.hasNext()) {
379:                    leftJoinCMRNodes = new ArrayList();
380:                    while (leftJoinIter.hasNext()) {
381:                        JDBCLeftJoinMetaData leftJoin = (JDBCLeftJoinMetaData) leftJoinIter
382:                                .next();
383:                        JDBCCMRFieldBridge cmrField = entity
384:                                .getCMRFieldByName(leftJoin.getCmrField());
385:                        if (cmrField == null) {
386:                            throw new DeploymentException(
387:                                    "cmr-field in left-join was not found: cmr-field="
388:                                            + leftJoin.getCmrField()
389:                                            + ", entity="
390:                                            + entity.getEntityName());
391:                        }
392:
393:                        List subNodes;
394:                        JDBCEntityBridge relatedEntity = cmrField
395:                                .getRelatedJDBCEntity();
396:                        String childPath = path + '.' + cmrField.getFieldName();
397:                        if (declaredPaths != null) {
398:                            declaredPaths.add(childPath);
399:                        }
400:
401:                        subNodes = getLeftJoinCMRNodes(relatedEntity,
402:                                childPath, leftJoin.getLeftJoins(),
403:                                declaredPaths);
404:
405:                        boolean[] mask = relatedEntity
406:                                .getLoadGroupMask(leftJoin.getEagerLoadGroup());
407:                        LeftJoinCMRNode node = new LeftJoinCMRNode(childPath,
408:                                cmrField, mask, subNodes);
409:                        leftJoinCMRNodes.add(node);
410:                    }
411:                } else {
412:                    leftJoinCMRNodes = Collections.EMPTY_LIST;
413:                }
414:
415:                return leftJoinCMRNodes;
416:            }
417:
418:            public static final void leftJoinCMRNodes(String alias,
419:                    List onFindCMRNodes, AliasManager aliasManager,
420:                    StringBuffer sb) {
421:                for (int i = 0; i < onFindCMRNodes.size(); ++i) {
422:                    LeftJoinCMRNode node = (LeftJoinCMRNode) onFindCMRNodes
423:                            .get(i);
424:                    JDBCCMRFieldBridge cmrField = node.cmrField;
425:                    JDBCEntityBridge relatedEntity = cmrField
426:                            .getRelatedJDBCEntity();
427:                    String relatedAlias = aliasManager.getAlias(node.path);
428:
429:                    JDBCRelationMetaData relation = cmrField.getMetaData()
430:                            .getRelationMetaData();
431:                    if (relation.isTableMappingStyle()) {
432:                        String relTableAlias = aliasManager
433:                                .getRelationTableAlias(node.path);
434:                        sb.append(" LEFT OUTER JOIN ").append(
435:                                cmrField.getQualifiedTableName()).append(' ')
436:                                .append(relTableAlias).append(" ON ");
437:                        SQLUtil.getRelationTableJoinClause(cmrField, alias,
438:                                relTableAlias, sb);
439:
440:                        sb.append(" LEFT OUTER JOIN ").append(
441:                                relatedEntity.getQualifiedTableName()).append(
442:                                ' ').append(relatedAlias).append(" ON ");
443:                        SQLUtil.getRelationTableJoinClause(cmrField
444:                                .getRelatedCMRField(), relatedAlias,
445:                                relTableAlias, sb);
446:                    } else {
447:                        // foreign key mapping style
448:                        sb.append(" LEFT OUTER JOIN ").append(
449:                                relatedEntity.getQualifiedTableName()).append(
450:                                ' ').append(relatedAlias).append(" ON ");
451:                        SQLUtil
452:                                .getJoinClause(cmrField, alias, relatedAlias,
453:                                        sb);
454:                    }
455:
456:                    List subNodes = node.onFindCMRNodes;
457:                    if (!subNodes.isEmpty()) {
458:                        leftJoinCMRNodes(relatedAlias, subNodes, aliasManager,
459:                                sb);
460:                    }
461:                }
462:            }
463:
464:            public static final void appendLeftJoinCMRColumnNames(
465:                    List onFindCMRNodes, AliasManager aliasManager,
466:                    StringBuffer sb) {
467:                for (int i = 0; i < onFindCMRNodes.size(); ++i) {
468:                    LeftJoinCMRNode node = (LeftJoinCMRNode) onFindCMRNodes
469:                            .get(i);
470:                    JDBCCMRFieldBridge cmrField = node.cmrField;
471:                    JDBCEntityBridge relatedEntity = cmrField
472:                            .getRelatedJDBCEntity();
473:                    String childAlias = aliasManager.getAlias(node.path);
474:
475:                    // primary key fields
476:                    SQLUtil.appendColumnNamesClause(relatedEntity
477:                            .getPrimaryKeyFields(), childAlias, sb);
478:
479:                    // eager load group
480:                    if (node.eagerLoadMask != null) {
481:                        SQLUtil.appendColumnNamesClause(relatedEntity
482:                                .getTableFields(), node.eagerLoadMask,
483:                                childAlias, sb);
484:                    }
485:
486:                    List subNodes = node.onFindCMRNodes;
487:                    if (!subNodes.isEmpty()) {
488:                        appendLeftJoinCMRColumnNames(subNodes, aliasManager, sb);
489:                    }
490:                }
491:            }
492:
493:            private static int loadOnFindCMRFields(Object pk,
494:                    List onFindCMRNodes, ResultSet rs, int index, Logger log) {
495:                Object[] ref = new Object[1];
496:                for (int nodeInd = 0; nodeInd < onFindCMRNodes.size(); ++nodeInd) {
497:                    LeftJoinCMRNode node = (LeftJoinCMRNode) onFindCMRNodes
498:                            .get(nodeInd);
499:                    JDBCCMRFieldBridge cmrField = node.cmrField;
500:                    ReadAheadCache myCache = cmrField.getJDBCStoreManager()
501:                            .getReadAheadCache();
502:                    JDBCEntityBridge relatedEntity = cmrField
503:                            .getRelatedJDBCEntity();
504:                    ReadAheadCache relatedCache = cmrField.getRelatedManager()
505:                            .getReadAheadCache();
506:
507:                    // load related id
508:                    ref[0] = null;
509:                    index = relatedEntity.loadPrimaryKeyResults(rs, index, ref);
510:                    Object relatedId = ref[0];
511:                    boolean cacheRelatedData = relatedId != null;
512:
513:                    if (pk != null) {
514:                        if (cmrField.getMetaData().getRelatedRole()
515:                                .isMultiplicityOne()) {
516:                            // cacheRelatedData the value
517:                            myCache.addPreloadData(pk, cmrField,
518:                                    relatedId == null ? Collections.EMPTY_LIST
519:                                            : Collections
520:                                                    .singletonList(relatedId));
521:                        } else {
522:                            Collection cachedValue = myCache.getCachedCMRValue(
523:                                    pk, cmrField);
524:                            if (cachedValue == null) {
525:                                cachedValue = new ArrayList();
526:                                myCache.addPreloadData(pk, cmrField,
527:                                        cachedValue);
528:                            }
529:
530:                            if (relatedId != null) {
531:                                if (cachedValue.contains(relatedId)) {
532:                                    cacheRelatedData = false;
533:                                } else {
534:                                    cachedValue.add(relatedId);
535:                                }
536:                            }
537:                        }
538:                    }
539:
540:                    // load eager load group
541:                    if (node.eagerLoadMask != null) {
542:                        JDBCFieldBridge[] tableFields = relatedEntity
543:                                .getTableFields();
544:                        for (int fieldInd = 0; fieldInd < tableFields.length; ++fieldInd) {
545:                            if (node.eagerLoadMask[fieldInd]) {
546:                                JDBCFieldBridge field = tableFields[fieldInd];
547:                                ref[0] = null;
548:                                index = field.loadArgumentResults(rs, index,
549:                                        ref);
550:
551:                                if (cacheRelatedData) {
552:                                    if (log.isTraceEnabled()) {
553:                                        log.trace("Caching "
554:                                                + relatedEntity.getEntityName()
555:                                                + '[' + relatedId + "]."
556:                                                + field.getFieldName() + "="
557:                                                + ref[0]);
558:                                    }
559:                                    relatedCache.addPreloadData(relatedId,
560:                                            field, ref[0]);
561:                                }
562:                            }
563:                        }
564:                    }
565:
566:                    List subNodes = node.onFindCMRNodes;
567:                    if (!subNodes.isEmpty()) {
568:                        index = loadOnFindCMRFields(relatedId, subNodes, rs,
569:                                index, log);
570:                    }
571:                }
572:
573:                return index;
574:            }
575:
576:            public static final class LeftJoinCMRNode {
577:                public final String path;
578:                public final JDBCCMRFieldBridge cmrField;
579:                public final boolean[] eagerLoadMask;
580:                public final List onFindCMRNodes;
581:
582:                public LeftJoinCMRNode(String path,
583:                        JDBCCMRFieldBridge cmrField, boolean[] eagerLoadMask,
584:                        List onFindCMRNodes) {
585:                    this .path = path;
586:                    this .cmrField = cmrField;
587:                    this .eagerLoadMask = eagerLoadMask;
588:                    this .onFindCMRNodes = onFindCMRNodes;
589:                }
590:
591:                public boolean equals(Object o) {
592:                    boolean result;
593:                    if (o == this ) {
594:                        result = true;
595:                    } else if (o instanceof  LeftJoinCMRNode) {
596:                        LeftJoinCMRNode other = (LeftJoinCMRNode) o;
597:                        result = cmrField == other.cmrField;
598:                    } else {
599:                        result = false;
600:                    }
601:                    return result;
602:                }
603:
604:                public int hashCode() {
605:                    return cmrField == null ? Integer.MIN_VALUE : cmrField
606:                            .hashCode();
607:                }
608:
609:                public String toString() {
610:                    return '[' + cmrField.getFieldName() + ": "
611:                            + onFindCMRNodes + ']';
612:                }
613:            }
614:
615:            interface QueryCollectionFactory {
616:                Collection createCollection(Connection con,
617:                        PreparedStatement ps, ResultSet rs, int limit,
618:                        int count, JDBCEntityBridge selectEntity,
619:                        JDBCCMPFieldBridge selectField,
620:                        SelectFunction selectFunction,
621:                        JDBCStoreManager selectManager, List onFindCMRList,
622:                        boolean[] eagerLoadMask,
623:                        GenericEntityObjectFactory factory)
624:                        throws FinderException;
625:            }
626:
627:            class EagerCollectionFactory implements  QueryCollectionFactory {
628:                public Collection createCollection(Connection con,
629:                        PreparedStatement ps, ResultSet rs, int limit,
630:                        int count, JDBCEntityBridge selectEntity,
631:                        JDBCCMPFieldBridge selectField,
632:                        SelectFunction selectFunction,
633:                        JDBCStoreManager selectManager, List onFindCMRList,
634:                        boolean[] eagerLoadMask,
635:                        GenericEntityObjectFactory factory)
636:                        throws FinderException {
637:                    try {
638:                        List results = new ArrayList();
639:
640:                        if (selectEntity != null) {
641:                            ReadAheadCache selectReadAheadCache = selectManager
642:                                    .getReadAheadCache();
643:                            List ids = new ArrayList();
644:
645:                            boolean loadOnFindCmr = !onFindCMRList.isEmpty();
646:                            Object[] ref = new Object[1];
647:                            Object prevPk = null;
648:
649:                            while ((limit == 0 || count-- > 0) && rs.next()) {
650:                                int index = 1;
651:
652:                                // get the pk
653:                                index = selectEntity.loadPrimaryKeyResults(rs,
654:                                        index, ref);
655:                                Object pk = ref[0];
656:
657:                                boolean addPk = (loadOnFindCmr ? !pk
658:                                        .equals(prevPk) : true);
659:                                if (addPk) {
660:                                    ids.add(pk);
661:                                    results.add(factory.getEntityEJBObject(pk));
662:                                    prevPk = pk;
663:                                }
664:
665:                                // read the preload fields
666:                                if (eagerLoadMask != null) {
667:                                    JDBCFieldBridge[] tableFields = selectEntity
668:                                            .getTableFields();
669:                                    for (int i = 0; i < eagerLoadMask.length; i++) {
670:                                        if (eagerLoadMask[i]) {
671:                                            JDBCFieldBridge field = tableFields[i];
672:                                            ref[0] = null;
673:
674:                                            // read the value and store it in the readahead cache
675:                                            index = field.loadArgumentResults(
676:                                                    rs, index, ref);
677:
678:                                            if (addPk) {
679:                                                selectReadAheadCache
680:                                                        .addPreloadData(pk,
681:                                                                field, ref[0]);
682:                                            }
683:                                        }
684:                                    }
685:
686:                                    if (!onFindCMRList.isEmpty()) {
687:                                        index = loadOnFindCMRFields(pk,
688:                                                onFindCMRList, rs, index, log);
689:                                    }
690:                                }
691:                            }
692:
693:                            // add the results list to the cache
694:                            selectReadAheadCache.addFinderResults(ids,
695:                                    queryMetaData.getReadAhead());
696:                        } else if (selectField != null) {
697:                            // load the field
698:                            Object[] valueRef = new Object[1];
699:                            while ((limit == 0 || count-- > 0) && rs.next()) {
700:                                valueRef[0] = null;
701:                                selectField
702:                                        .loadArgumentResults(rs, 1, valueRef);
703:                                results.add(valueRef[0]);
704:                            }
705:                        } else {
706:                            while (rs.next()) {
707:                                results.add(selectFunction.readResult(rs));
708:                            }
709:                        }
710:
711:                        if (log.isDebugEnabled() && limit != 0 && count == 0) {
712:                            log.debug("Query result was limited to " + limit
713:                                    + " row(s)");
714:                        }
715:
716:                        return results;
717:                    } catch (Exception e) {
718:                        log.error("Find failed", e);
719:                        throw new FinderException("Find failed: " + e);
720:                    } finally {
721:                        JDBCUtil.safeClose(rs);
722:                        JDBCUtil.safeClose(ps);
723:                        JDBCUtil.safeClose(con);
724:                    }
725:                }
726:
727:            }
728:
729:            class LazyCollectionFactory implements  QueryCollectionFactory {
730:                public Collection createCollection(Connection con,
731:                        PreparedStatement ps, ResultSet rs, int limit,
732:                        int count, JDBCEntityBridge selectEntity,
733:                        JDBCCMPFieldBridge selectField,
734:                        SelectFunction selectFunction,
735:                        JDBCStoreManager selectManager, List onFindCMRList,
736:                        boolean[] eagerLoadMask,
737:                        GenericEntityObjectFactory factory)
738:                        throws FinderException {
739:                    return new LazyCollection(con, ps, rs, limit, count,
740:                            selectEntity, selectField, selectFunction,
741:                            selectManager, eagerLoadMask, factory);
742:                }
743:
744:                private class LazyCollection extends AbstractCollection {
745:                    private final Connection con;
746:                    private final PreparedStatement ps;
747:                    private final ResultSet rs;
748:                    private final int limit;
749:                    private int count;
750:                    private final JDBCEntityBridge selectEntity;
751:                    private final JDBCCMPFieldBridge selectField;
752:                    private final SelectFunction selectFunction;
753:                    private final JDBCStoreManager selectManager;
754:                    private final boolean[] eagerLoadMask;
755:                    private final GenericEntityObjectFactory factory;
756:
757:                    private Object prevPk;
758:                    private Object curPk;
759:                    private Object currentResult;
760:
761:                    Object[] ref = new Object[1];
762:
763:                    boolean loadOnFindCmr;
764:
765:                    private List results = null;
766:                    private Iterator firstIterator;
767:                    private int size;
768:                    private boolean resourcesClosed;
769:
770:                    public LazyCollection(final Connection con,
771:                            final PreparedStatement ps, final ResultSet rs,
772:                            int limit, int count,
773:                            JDBCEntityBridge selectEntity,
774:                            JDBCCMPFieldBridge selectField,
775:                            SelectFunction selectFunction,
776:                            JDBCStoreManager selectManager,
777:                            boolean[] eagerLoadMask,
778:                            GenericEntityObjectFactory factory) {
779:                        this .con = con;
780:                        this .ps = ps;
781:                        this .rs = rs;
782:                        this .limit = limit;
783:                        this .count = count;
784:                        this .selectEntity = selectEntity;
785:                        this .selectField = selectField;
786:                        this .selectFunction = selectFunction;
787:                        this .selectManager = selectManager;
788:                        this .eagerLoadMask = eagerLoadMask;
789:                        this .factory = factory;
790:                        loadOnFindCmr = !onFindCMRList.isEmpty();
791:
792:                        firstIterator = getFirstIterator();
793:                        if (firstIterator.hasNext()) {
794:                            try {
795:                                size = rs.getInt(1);
796:                            } catch (SQLException e) {
797:                                throw new EJBException(
798:                                        "Failed to read ResultSet.", e);
799:                            }
800:
801:                            if (limit > 0 && size > limit) {
802:                                size = limit;
803:                            }
804:                        }
805:
806:                        if (size < 1) {
807:                            firstIterator = null;
808:                            results = new ArrayList(0);
809:                            closeResources();
810:                        } else {
811:                            results = new ArrayList(size);
812:                            try {
813:                                selectManager.getContainer()
814:                                        .getTransactionManager()
815:                                        .getTransaction()
816:                                        .registerSynchronization(
817:                                                new Synchronization() {
818:                                                    public void beforeCompletion() {
819:                                                        closeResources();
820:                                                    }
821:
822:                                                    public void afterCompletion(
823:                                                            int status) {
824:                                                        closeResources();
825:                                                    }
826:                                                });
827:                            } catch (Exception e) {
828:                                throw new EJBException(
829:                                        "Failed to obtain current transaction",
830:                                        e);
831:                            }
832:                        }
833:                    }
834:
835:                    private void closeResources() {
836:                        if (!resourcesClosed) {
837:                            JDBCUtil.safeClose(rs);
838:                            JDBCUtil.safeClose(ps);
839:                            JDBCUtil.safeClose(con);
840:                            resourcesClosed = true;
841:                        }
842:                    }
843:
844:                    public Iterator iterator() {
845:                        return firstIterator != null ? firstIterator : results
846:                                .iterator();
847:                    }
848:
849:                    public int size() {
850:                        return firstIterator != null ? size : results.size();
851:                    }
852:
853:                    public boolean add(Object o) {
854:                        if (firstIterator == null) {
855:                            return results.add(o);
856:                        }
857:                        throw new IllegalStateException(
858:                                "Can't modify collection while the first iterator is not exhausted.");
859:                    }
860:
861:                    public boolean remove(Object o) {
862:                        if (firstIterator == null) {
863:                            return results.remove(o);
864:                        }
865:                        throw new IllegalStateException(
866:                                "Can't modify collection while the first iterator is not exhausted.");
867:                    }
868:
869:                    private boolean hasNextResult() {
870:                        try {
871:                            boolean has = (limit == 0 || count-- > 0)
872:                                    && rs.next();
873:                            if (!has) {
874:                                if (log.isTraceEnabled()) {
875:                                    log.trace("first iterator exhausted!");
876:                                }
877:                                firstIterator = null;
878:                                closeResources();
879:                            }
880:                            return has;
881:                        } catch (Exception e) {
882:                            log.error("Failed to read ResultSet.", e);
883:                            throw new EJBException("Failed to read ResultSet: "
884:                                    + e.getMessage());
885:                        }
886:                    }
887:
888:                    private Object readNext() {
889:                        try {
890:                            if (selectEntity != null) {
891:                                ReadAheadCache selectReadAheadCache = selectManager
892:                                        .getReadAheadCache();
893:
894:                                // first one is size
895:                                int index = 2;
896:
897:                                // get the pk
898:                                index = selectEntity.loadPrimaryKeyResults(rs,
899:                                        index, ref);
900:                                curPk = ref[0];
901:
902:                                boolean addPk = (loadOnFindCmr ? !curPk
903:                                        .equals(prevPk) : true);
904:                                if (addPk) {
905:                                    prevPk = curPk;
906:                                    currentResult = factory
907:                                            .getEntityEJBObject(curPk);
908:                                }
909:
910:                                // read the preload fields
911:                                if (eagerLoadMask != null) {
912:                                    JDBCFieldBridge[] tableFields = selectEntity
913:                                            .getTableFields();
914:                                    for (int i = 0; i < eagerLoadMask.length; i++) {
915:                                        if (eagerLoadMask[i]) {
916:                                            JDBCFieldBridge field = tableFields[i];
917:                                            ref[0] = null;
918:
919:                                            // read the value and store it in the readahead cache
920:                                            index = field.loadArgumentResults(
921:                                                    rs, index, ref);
922:
923:                                            if (addPk) {
924:                                                selectReadAheadCache
925:                                                        .addPreloadData(curPk,
926:                                                                field, ref[0]);
927:                                            }
928:                                        }
929:                                    }
930:
931:                                    if (!onFindCMRList.isEmpty()) {
932:                                        index = loadOnFindCMRFields(curPk,
933:                                                onFindCMRList, rs, index, log);
934:                                    }
935:                                }
936:                            } else if (selectField != null) {
937:                                // load the field
938:                                selectField.loadArgumentResults(rs, 2, ref);
939:                                currentResult = ref[0];
940:                            } else {
941:                                currentResult = selectFunction.readResult(rs);
942:                            }
943:
944:                            if (log.isTraceEnabled() && limit != 0
945:                                    && count == 0) {
946:                                log.trace("Query result was limited to "
947:                                        + limit + " row(s)");
948:                            }
949:
950:                            return currentResult;
951:                        } catch (Exception e) {
952:                            log.error("Failed to read ResultSet", e);
953:                            throw new EJBException("Failed to read ResultSet: "
954:                                    + e.getMessage());
955:                        }
956:                    }
957:
958:                    private Iterator getFirstIterator() {
959:                        return new Iterator() {
960:                            private boolean hasNext;
961:                            private Object cursor;
962:
963:                            public boolean hasNext() {
964:                                return hasNext ? hasNext
965:                                        : (hasNext = hasNextResult());
966:                            }
967:
968:                            public Object next() {
969:                                if (!hasNext()) {
970:                                    throw new NoSuchElementException();
971:                                }
972:                                hasNext = false;
973:
974:                                cursor = readNext();
975:                                results.add(cursor);
976:
977:                                return cursor;
978:                            }
979:
980:                            public void remove() {
981:                                --size;
982:                                results.remove(cursor);
983:                            }
984:                        };
985:                    }
986:                }
987:            }
988:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.