Source Code Cross Referenced for SqlSelectStatement.java in  » Database-ORM » db-ojb » org » apache » ojb » broker » accesslayer » sql » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


001:        package org.apache.ojb.broker.accesslayer.sql;
002:
003:        /* Copyright 2002-2005 The Apache Software Foundation
004:         *
005:         * Licensed under the Apache License, Version 2.0 (the "License");
006:         * you may not use this file except in compliance with the License.
007:         * You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        import java.util.ArrayList;
019:        import java.util.Iterator;
020:        import java.util.List;
021:        import java.util.Map;
022:        import java.util.Set;
023:        import java.lang.ref.WeakReference;
024:
025:        import org.apache.commons.collections.set.ListOrderedSet;
026:        import org.apache.ojb.broker.metadata.ClassDescriptor;
027:        import org.apache.ojb.broker.metadata.DescriptorRepository;
028:        import org.apache.ojb.broker.metadata.FieldDescriptor;
029:        import org.apache.ojb.broker.metadata.JdbcType;
030:        import org.apache.ojb.broker.platforms.Platform;
031:        import org.apache.ojb.broker.query.Criteria;
032:        import org.apache.ojb.broker.query.Query;
033:        import org.apache.ojb.broker.query.ReportQuery;
034:        import org.apache.ojb.broker.query.ReportQueryByCriteria;
035:        import org.apache.ojb.broker.util.SqlHelper;
036:        import org.apache.ojb.broker.util.logging.Logger;
037:
038:        /**
039:         * Model a SELECT Statement
040:         *
041:         * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
042:         * @version $Id: SqlSelectStatement.java,v 1.22.2.8 2005/12/22 18:25:51 brj Exp $
043:         */
044:        public class SqlSelectStatement extends SqlQueryStatement implements 
045:                SelectStatement {
046:            private WeakReference fieldsForSelect;
047:
048:            /**
049:             * Constructor for SqlSelectStatement.
050:             * 
051:             * @param pf
052:             * @param cld
053:             * @param query
054:             * @param logger
055:             */
056:            public SqlSelectStatement(Platform pf, ClassDescriptor cld,
057:                    Query query, Logger logger) {
058:                super (pf, cld, query, logger);
059:            }
060:
061:            /**
062:             * Constructor for SqlSelectStatement.
063:             *
064:             * @param parent
065:             * @param pf
066:             * @param cld
067:             * @param query
068:             * @param logger
069:             */
070:            public SqlSelectStatement(SqlQueryStatement parent, Platform pf,
071:                    ClassDescriptor cld, Query query, Logger logger) {
072:                super (parent, pf, cld, query, logger);
073:            }
074:
075:            /**
076:             * Append a Column with alias: A0 name -> A0.name
077:             * @param anAlias the TableAlias
078:             * @param field
079:             * @param buf
080:             */
081:            protected void appendColumn(TableAlias anAlias,
082:                    FieldDescriptor field, StringBuffer buf) {
083:                buf.append(anAlias.alias);
084:                buf.append(".");
085:                buf.append(field.getColumnName());
086:            }
087:
088:            /**
089:             * Appends to the statement a comma separated list of column names.
090:             *
091:             * DO NOT use this if order of columns is important. The row readers build reflectively and look up
092:             * column names to find values, so this is safe. In the case of update, you CANNOT use this as the
093:             * order of columns is important.
094:             *
095:             * @return list of column names for the set of all unique columns for multiple classes mapped to the
096:             * same table.
097:             */
098:            protected List appendListOfColumnsForSelect(StringBuffer buf) {
099:                FieldDescriptor[] fieldDescriptors = getFieldsForSelect();
100:                ArrayList columnList = new ArrayList();
101:                TableAlias searchAlias = getSearchTable();
102:
103:                for (int i = 0; i < fieldDescriptors.length; i++) {
104:                    FieldDescriptor field = fieldDescriptors[i];
105:                    TableAlias alias = getTableAliasForClassDescriptor(field
106:                            .getClassDescriptor());
107:                    if (alias == null) {
108:                        alias = searchAlias;
109:                    }
110:                    if (i > 0) {
111:                        buf.append(",");
112:                    }
113:                    appendColumn(alias, field, buf);
114:                    columnList.add(field.getAttributeName());
115:                }
116:
117:                appendClazzColumnForSelect(buf);
118:                return columnList;
119:            }
120:
121:            /**
122:             * Get MultiJoined ClassDescriptors
123:             * @param cld
124:             */
125:            private ClassDescriptor[] getMultiJoinedClassDescriptors(
126:                    ClassDescriptor cld) {
127:                DescriptorRepository repository = cld.getRepository();
128:                Class[] multiJoinedClasses = repository
129:                        .getSubClassesMultipleJoinedTables(cld, true);
130:                ClassDescriptor[] result = new ClassDescriptor[multiJoinedClasses.length];
131:
132:                for (int i = 0; i < multiJoinedClasses.length; i++) {
133:                    result[i] = repository
134:                            .getDescriptorFor(multiJoinedClasses[i]);
135:                }
136:
137:                return result;
138:            }
139:
140:            /**
141:             * Create the OJB_CLAZZ pseudo column based on CASE WHEN.
142:             * This column defines the Class to be instantiated.
143:             * @param buf
144:             */
145:            private void appendClazzColumnForSelect(StringBuffer buf) {
146:                ClassDescriptor cld = getSearchClassDescriptor();
147:                ClassDescriptor[] clds = getMultiJoinedClassDescriptors(cld);
148:
149:                if (clds.length == 0) {
150:                    return;
151:                }
152:
153:                buf.append(",CASE");
154:
155:                for (int i = clds.length; i > 0; i--) {
156:                    buf.append(" WHEN ");
157:
158:                    ClassDescriptor subCld = clds[i - 1];
159:                    FieldDescriptor[] fieldDescriptors = subCld.getPkFields();
160:
161:                    TableAlias alias = getTableAliasForClassDescriptor(subCld);
162:                    for (int j = 0; j < fieldDescriptors.length; j++) {
163:                        FieldDescriptor field = fieldDescriptors[j];
164:                        if (j > 0) {
165:                            buf.append(" AND ");
166:                        }
167:                        appendColumn(alias, field, buf);
168:                        buf.append(" IS NOT NULL");
169:                    }
170:                    buf.append(" THEN '").append(subCld.getClassNameOfObject())
171:                            .append("'");
172:                }
173:                buf.append(" ELSE '").append(cld.getClassNameOfObject())
174:                        .append("'");
175:                buf.append(" END AS " + SqlHelper.OJB_CLASS_COLUMN);
176:            }
177:
178:            /**
179:             * Return the Fields to be selected.
180:             *
181:             * @return the Fields to be selected
182:             */
183:            protected FieldDescriptor[] getFieldsForSelect() {
184:                if (fieldsForSelect == null || fieldsForSelect.get() == null) {
185:                    fieldsForSelect = new WeakReference(
186:                            buildFieldsForSelect(getSearchClassDescriptor()));
187:                }
188:                return (FieldDescriptor[]) fieldsForSelect.get();
189:            }
190:
191:            /**
192:             * Return the Fields to be selected.
193:             *
194:             * @param cld the ClassDescriptor
195:             * @return the Fields to be selected
196:             */
197:            protected FieldDescriptor[] buildFieldsForSelect(ClassDescriptor cld) {
198:                DescriptorRepository repository = cld.getRepository();
199:                Set fields = new ListOrderedSet(); // keep the order of the fields
200:
201:                // add Standard Fields
202:                // MBAIRD: if the object being queried on has multiple classes mapped to the table,
203:                // then we will get all the fields that are a unique set across all those classes so if we need to
204:                // we can materialize an extent
205:                FieldDescriptor fds[] = repository
206:                        .getFieldDescriptorsForMultiMappedTable(cld);
207:                for (int i = 0; i < fds.length; i++) {
208:                    fields.add(fds[i]);
209:                }
210:
211:                // add inherited Fields. This is important when querying for a class having a super-reference
212:                fds = cld.getFieldDescriptor(true);
213:                for (int i = 0; i < fds.length; i++) {
214:                    fields.add(fds[i]);
215:                }
216:
217:                // add Fields of joined subclasses
218:                Class[] multiJoinedClasses = repository
219:                        .getSubClassesMultipleJoinedTables(cld, true);
220:                for (int c = 0; c < multiJoinedClasses.length; c++) {
221:                    ClassDescriptor subCld = repository
222:                            .getDescriptorFor(multiJoinedClasses[c]);
223:                    fds = subCld.getFieldDescriptions();
224:                    for (int i = 0; i < fds.length; i++) {
225:                        fields.add(fds[i]);
226:                    }
227:                }
228:
229:                FieldDescriptor[] result = new FieldDescriptor[fields.size()];
230:                fields.toArray(result);
231:                return result;
232:            }
233:
234:            /**
235:             * Appends to the statement a comma separated list of column names.
236:             *
237:             * @param columns defines the columns to be selected (for reports)
238:             * @return list of column names
239:             */
240:            protected List appendListOfColumns(String[] columns,
241:                    StringBuffer buf) {
242:                ArrayList columnList = new ArrayList();
243:
244:                for (int i = 0; i < columns.length; i++) {
245:                    if (i > 0) {
246:                        buf.append(",");
247:                    }
248:                    appendColName(columns[i], false, null, buf);
249:                    columnList.add(columns[i]);
250:                }
251:                return columnList;
252:            }
253:
254:            /**
255:             * @see org.apache.ojb.broker.accesslayer.sql.SqlQueryStatement#buildStatement()
256:             */
257:            protected String buildStatement() {
258:                StringBuffer stmt = new StringBuffer(1024);
259:                Query query = getQuery();
260:                boolean first = true;
261:                List orderByFields = null;
262:                String[] attributes = null;
263:                String[] joinAttributes = null;
264:                Iterator it = getJoinTreeToCriteria().entrySet().iterator();
265:                List columnList = new ArrayList();
266:
267:                if (query instanceof  ReportQuery) {
268:                    attributes = ((ReportQuery) query).getAttributes();
269:                    joinAttributes = ((ReportQuery) query).getJoinAttributes();
270:                }
271:
272:                while (it.hasNext()) {
273:                    Map.Entry entry = (Map.Entry) it.next();
274:                    Criteria whereCrit = (Criteria) entry.getValue();
275:                    Criteria havingCrit = query.getHavingCriteria();
276:                    StringBuffer where = new StringBuffer();
277:                    StringBuffer having = new StringBuffer();
278:                    List groupByFields;
279:
280:                    // Set correct tree of joins for the current criteria
281:                    setRoot((TableAlias) entry.getKey());
282:
283:                    if (whereCrit != null && whereCrit.isEmpty()) {
284:                        whereCrit = null;
285:                    }
286:
287:                    if (havingCrit != null && havingCrit.isEmpty()) {
288:                        havingCrit = null;
289:                    }
290:
291:                    if (first) {
292:                        first = false;
293:                    } else {
294:                        stmt.append(" UNION ");
295:                    }
296:
297:                    stmt.append("SELECT ");
298:                    if (query.isDistinct()) {
299:                        stmt.append("DISTINCT ");
300:                    }
301:
302:                    if (attributes == null || attributes.length == 0) {
303:                        /**
304:                         * MBAIRD: use the appendListofColumnsForSelect, as it finds
305:                         * the union of select items for all object mapped to the same table. This
306:                         * will allow us to load objects with unique mapping fields that are mapped
307:                         * to the same table.
308:                         */
309:                        columnList.addAll(appendListOfColumnsForSelect(stmt));
310:                    } else {
311:                        columnList
312:                                .addAll(appendListOfColumns(attributes, stmt));
313:                    }
314:
315:                    // BRJ:
316:                    // joinColumns are only used to force the building of a join;
317:                    // they are not appended to the select-clause !
318:                    // these columns are used in COUNT-ReportQueries and
319:                    // are taken from the query the COUNT is based on 
320:                    if (joinAttributes != null && joinAttributes.length > 0) {
321:                        for (int i = 0; i < joinAttributes.length; i++) {
322:                            getAttributeInfo(joinAttributes[i], false, null,
323:                                    getQuery().getPathClasses());
324:                        }
325:                    }
326:
327:                    groupByFields = query.getGroupBy();
328:                    ensureColumns(groupByFields, columnList);
329:
330:                    orderByFields = query.getOrderBy();
331:                    columnList = ensureColumns(orderByFields, columnList, stmt);
332:                    /*
333:                     arminw:
334:                     TODO: this feature doesn't work, so remove this in future
335:                     */
336:                    /**
337:                     * treeder: going to map superclass tables here,
338:                     * not sure about the columns, just using all columns for now
339:                     */
340:                    ClassDescriptor cld = getBaseClassDescriptor();
341:                    ClassDescriptor cldSuper = null;
342:                    if (cld.getSuperClass() != null) {
343:                        // then we have a super class so join tables
344:                        cldSuper = cld.getRepository().getDescriptorFor(
345:                                cld.getSuperClass());
346:                        appendSuperClassColumns(cldSuper, stmt);
347:                    }
348:
349:                    stmt.append(" FROM ");
350:                    appendTableWithJoins(getRoot(), where, stmt);
351:
352:                    if (cld.getSuperClass() != null) {
353:                        appendSuperClassJoin(cld, cldSuper, stmt, where);
354:                    }
355:
356:                    appendWhereClause(where, whereCrit, stmt);
357:                    appendGroupByClause(groupByFields, stmt);
358:                    appendHavingClause(having, havingCrit, stmt);
359:                }
360:
361:                appendOrderByClause(orderByFields, columnList, stmt);
362:
363:                if (query instanceof  ReportQueryByCriteria) {
364:                    ((ReportQueryByCriteria) query)
365:                            .setAttributeFieldDescriptors(m_attrToFld);
366:                }
367:
368:                return stmt.toString();
369:            }
370:
371:            /*
372:             arminw:
373:             TODO: this feature doesn't work, so remove this in future
374:             */
375:            private void appendSuperClassJoin(ClassDescriptor cld,
376:                    ClassDescriptor cldSuper, StringBuffer stmt,
377:                    StringBuffer where) {
378:                stmt.append(",");
379:                appendTable(cldSuper, stmt);
380:
381:                if (where != null) {
382:                    if (where.length() > 0) {
383:                        where.append(" AND ");
384:                    }
385:
386:                    // get reference field in super class
387:                    // TODO: do not use the superclassfield anymore, just assume that the id is the same in both tables - @see PBroker.storeToDb
388:                    int super FieldRef = cld.getSuperClassFieldRef();
389:                    FieldDescriptor refField = cld
390:                            .getFieldDescriptorByIndex(super FieldRef);
391:
392:                    appendTable(cldSuper, where);
393:                    where.append(".");
394:                    appendField(cldSuper.getAutoIncrementFields()[0], where);
395:                    where.append(" = ");
396:                    appendTable(cld, where);
397:                    where.append(".");
398:                    appendField(refField, where);
399:                }
400:            }
401:
402:            private void appendSuperClassColumns(ClassDescriptor cldSuper,
403:                    StringBuffer buf) {
404:                FieldDescriptor[] fields = cldSuper.getFieldDescriptions();
405:                for (int i = 0; i < fields.length; i++) {
406:                    FieldDescriptor field = fields[i];
407:                    if (i > 0) {
408:                        buf.append(",");
409:                    }
410:                    buf.append(cldSuper.getFullTableName());
411:                    buf.append(".");
412:                    buf.append(field.getColumnName());
413:                }
414:            }
415:
416:            /**
417:             * Append table name. Quote if necessary.
418:             */
419:            protected void appendTable(ClassDescriptor cld, StringBuffer buf) {
420:                buf.append(cld.getFullTableName());
421:            }
422:
423:            /**
424:             * Append column name. Quote if necessary.
425:             */
426:            protected void appendField(FieldDescriptor fld, StringBuffer buf) {
427:                buf.append(fld.getColumnName());
428:            }
429:
430:            public Query getQueryInstance() {
431:                return getQuery();
432:            }
433:
434:            public int getColumnIndex(FieldDescriptor fld) {
435:                int index = JdbcType.MIN_INT;
436:                FieldDescriptor[] fields = getFieldsForSelect();
437:                if (fields != null) {
438:                    for (int i = 0; i < fields.length; i++) {
439:                        if (fields[i].equals(fld)) {
440:                            index = i + 1; // starts at 1
441:                            break;
442:                        }
443:                    }
444:                }
445:                return index;
446:            }
447:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.