Source Code Cross Referenced for SelectConstructor.java in  » Database-ORM » openjpa » org » apache » openjpa » jdbc » kernel » exps » 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 » openjpa » org.apache.openjpa.jdbc.kernel.exps 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.    
018:         */
019:        package org.apache.openjpa.jdbc.kernel.exps;
020:
021:        import java.io.Serializable;
022:        import java.util.HashMap;
023:        import java.util.Map;
024:
025:        import org.apache.openjpa.jdbc.meta.ClassMapping;
026:        import org.apache.openjpa.jdbc.sql.DBDictionary;
027:        import org.apache.openjpa.jdbc.sql.Joins;
028:        import org.apache.openjpa.jdbc.sql.SQLBuffer;
029:        import org.apache.openjpa.jdbc.sql.Select;
030:        import org.apache.openjpa.kernel.exps.AbstractExpressionVisitor;
031:        import org.apache.openjpa.kernel.exps.Constant;
032:        import org.apache.openjpa.kernel.exps.Expression;
033:        import org.apache.openjpa.kernel.exps.QueryExpressions;
034:        import org.apache.openjpa.kernel.exps.Value;
035:
036:        /**
037:         * Turns parsed queries into selects.
038:         *
039:         * @author Abe White
040:         * @nojavadoc
041:         */
042:        public class SelectConstructor implements  Serializable {
043:
044:            private boolean _extent = false;
045:
046:            /**
047:             * Return true if we know the select to have on criteria; to be an extent.
048:             * Note that even if this method returns false, {@link #evaluate} may still
049:             * return null if we haven't cached whether the query is an extent yet.
050:             */
051:            public boolean isExtent() {
052:                return _extent;
053:            }
054:
055:            /**
056:             * Evaluate the expression, returning a new select and filling in any
057:             * associated expression state. Use {@link #select} to then select the data.
058:             * 
059:             * @param ctx fill with execution context
060:             * @param state will be filled with expression state
061:             */
062:            public Select evaluate(ExpContext ctx, Select parent, String alias,
063:                    QueryExpressions exps, QueryExpressionsState state) {
064:                // already know that this query is equivalent to an extent?
065:                Select sel;
066:                if (_extent) {
067:                    sel = ctx.store.getSQLFactory().newSelect();
068:                    sel
069:                            .setAutoDistinct((exps.distinct & exps.DISTINCT_AUTO) != 0);
070:                    return sel;
071:                }
072:
073:                // create a new select and initialize it with the joins needed for
074:                // the criteria of this query
075:                sel = newSelect(ctx, parent, alias, exps, state);
076:
077:                // create where clause; if there are no where conditions and
078:                // no ordering or projections, we return null to signify that this
079:                // query should be treated like an extent
080:                Select inner = sel.getFromSelect();
081:                SQLBuffer where = buildWhere((inner != null) ? inner : sel,
082:                        ctx, state.filter, exps.filter);
083:                if (where == null && exps.projections.length == 0
084:                        && exps.ordering.length == 0
085:                        && (sel.getJoins() == null || sel.getJoins().isEmpty())) {
086:                    _extent = true;
087:                    sel
088:                            .setAutoDistinct((exps.distinct & exps.DISTINCT_AUTO) != 0);
089:                    return sel;
090:                }
091:
092:                // now set sql criteria; it goes on the inner select if present
093:                if (inner != null)
094:                    inner.where(where);
095:                else
096:                    sel.where(where);
097:
098:                // apply grouping and having.  this does not select the grouping
099:                // columns, just builds the GROUP BY clauses.  we don't build the
100:                // ORDER BY clauses yet because if we decide to add this select
101:                // to a union, the ORDER BY values get aliased differently
102:                if (exps.having != null) {
103:                    Exp havingExp = (Exp) exps.having;
104:                    SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
105:                    havingExp.appendTo(sel, ctx, state.having, buf);
106:                    sel.having(buf);
107:                }
108:                for (int i = 0; i < exps.grouping.length; i++)
109:                    ((Val) exps.grouping[i]).groupBy(sel, ctx,
110:                            state.grouping[i]);
111:                return sel;
112:            }
113:
114:            /**
115:             * Return a new select with expressions initialized.
116:             */
117:            private Select newSelect(ExpContext ctx, Select parent,
118:                    String alias, QueryExpressions exps,
119:                    QueryExpressionsState state) {
120:                Select sel = ctx.store.getSQLFactory().newSelect();
121:                sel.setAutoDistinct((exps.distinct & exps.DISTINCT_AUTO) != 0);
122:                sel.setJoinSyntax(ctx.fetch.getJoinSyntax());
123:                sel.setParent(parent, alias);
124:                initialize(sel, ctx, exps, state);
125:
126:                if (!sel.getAutoDistinct()) {
127:                    if ((exps.distinct & exps.DISTINCT_TRUE) != 0)
128:                        sel.setDistinct(true);
129:                    else if ((exps.distinct & exps.DISTINCT_FALSE) != 0)
130:                        sel.setDistinct(false);
131:                } else if (exps.projections.length > 0) {
132:                    if (!sel.isDistinct()
133:                            && (exps.distinct & exps.DISTINCT_TRUE) != 0) {
134:                        // if the select is not distinct but the query is, force
135:                        // the select to be distinct
136:                        sel.setDistinct(true);
137:                    } else if (sel.isDistinct()) {
138:                        // when aggregating data or making a non-distinct projection
139:                        // from a distinct select, we have to select from a tmp
140:                        // table formed by a distinct subselect in the from clause;
141:                        // this subselect selects the pks of the candidate (to
142:                        // get unique candidate values) and needed field values and
143:                        // applies the where conditions; the outer select applies
144:                        // ordering, grouping, etc
145:                        boolean agg = exps.isAggregate();
146:                        boolean candidate = ProjectionExpressionVisitor
147:                                .hasCandidateProjections(exps.projections);
148:                        if (agg
149:                                || (candidate && (exps.distinct & exps.DISTINCT_TRUE) == 0)) {
150:                            DBDictionary dict = ctx.store.getDBDictionary();
151:                            dict.assertSupport(dict.supportsSubselect,
152:                                    "SupportsSubselect");
153:
154:                            Select inner = sel;
155:                            sel = ctx.store.getSQLFactory().newSelect();
156:                            sel.setParent(parent, alias);
157:                            sel
158:                                    .setDistinct(agg
159:                                            && (exps.distinct & exps.DISTINCT_TRUE) != 0);
160:                            sel.setFromSelect(inner);
161:
162:                            // auto-distincting happens to get unique candidate instances
163:                            // back; don't auto-distinct if the user isn't selecting 
164:                            // candidate data
165:                        } else if (!candidate
166:                                && (exps.distinct & exps.DISTINCT_TRUE) == 0)
167:                            sel.setDistinct(false);
168:                    }
169:                }
170:                return sel;
171:            }
172:
173:            /**
174:             * Initialize all expressions.
175:             */
176:            private void initialize(Select sel, ExpContext ctx,
177:                    QueryExpressions exps, QueryExpressionsState state) {
178:                Map contains = null;
179:                if (HasContainsExpressionVisitor.hasContains(exps.filter)
180:                        || HasContainsExpressionVisitor
181:                                .hasContains(exps.having))
182:                    contains = new HashMap(7);
183:
184:                // initialize filter and having expressions
185:                Exp filterExp = (Exp) exps.filter;
186:                state.filter = filterExp.initialize(sel, ctx, contains);
187:                Exp havingExp = (Exp) exps.having;
188:                if (havingExp != null)
189:                    state.having = havingExp.initialize(sel, ctx, contains);
190:
191:                // get the top-level joins and null the expression's joins
192:                // at the same time so they aren't included in the where/having SQL
193:                Joins filterJoins = state.filter.joins;
194:                Joins havingJoins = (state.having == null) ? null
195:                        : state.having.joins;
196:                Joins joins = sel.and(filterJoins, havingJoins);
197:
198:                // initialize result values
199:                if (exps.projections.length > 0) {
200:                    state.projections = new ExpState[exps.projections.length];
201:                    Val resultVal;
202:                    for (int i = 0; i < exps.projections.length; i++) {
203:                        resultVal = (Val) exps.projections[i];
204:                        // have to join through to related type for pc object 
205:                        // projections; this ensures that we have all our joins cached
206:                        state.projections[i] = resultVal.initialize(sel, ctx,
207:                                Val.JOIN_REL | Val.FORCE_OUTER);
208:                        joins = sel.and(joins, state.projections[i].joins);
209:                    }
210:                }
211:
212:                // initialize grouping
213:                if (exps.grouping.length > 0) {
214:                    state.grouping = new ExpState[exps.grouping.length];
215:                    Val groupVal;
216:                    for (int i = 0; i < exps.grouping.length; i++) {
217:                        groupVal = (Val) exps.grouping[i];
218:                        // have to join through to related type for pc object groupings;
219:                        // this ensures that we have all our joins cached
220:                        state.grouping[i] = groupVal.initialize(sel, ctx,
221:                                Val.JOIN_REL);
222:                        joins = sel.and(joins, state.grouping[i].joins);
223:                    }
224:                }
225:
226:                // initialize ordering
227:                if (exps.ordering.length > 0) {
228:                    state.ordering = new ExpState[exps.ordering.length];
229:                    Val orderVal;
230:                    for (int i = 0; i < exps.ordering.length; i++) {
231:                        orderVal = (Val) exps.ordering[i];
232:                        state.ordering[i] = orderVal.initialize(sel, ctx, 0);
233:                        joins = sel.and(joins, state.ordering[i].joins);
234:                    }
235:                }
236:                sel.where(joins);
237:            }
238:
239:            /**
240:             * Create the where sql.
241:             */
242:            private SQLBuffer buildWhere(Select sel, ExpContext ctx,
243:                    ExpState state, Expression filter) {
244:                // create where buffer
245:                SQLBuffer where = new SQLBuffer(ctx.store.getDBDictionary());
246:                where.append("(");
247:                Exp filterExp = (Exp) filter;
248:                filterExp.appendTo(sel, ctx, state, where);
249:
250:                if (where.sqlEquals("(") || where.sqlEquals("(1 = 1"))
251:                    return null;
252:                return where.append(")");
253:            }
254:
255:            /**
256:             * Select the data for this query.
257:             */
258:            public void select(Select sel, ExpContext ctx,
259:                    ClassMapping mapping, boolean subclasses,
260:                    QueryExpressions exps, QueryExpressionsState state,
261:                    int eager) {
262:                Select inner = sel.getFromSelect();
263:                Val val;
264:                Joins joins = null;
265:                if (sel.getSubselectPath() != null)
266:                    joins = sel.newJoins().setSubselect(sel.getSubselectPath());
267:
268:                // build ordering clauses before select so that any eager join
269:                // ordering gets applied after query ordering
270:                for (int i = 0; i < exps.ordering.length; i++)
271:                    ((Val) exps.ordering[i]).orderBy(sel, ctx,
272:                            state.ordering[i], exps.ascending[i]);
273:
274:                // if no result string set, select matching objects like normal
275:                if (exps.projections.length == 0 && sel.getParent() == null) {
276:                    int subs = (subclasses) ? Select.SUBS_JOINABLE
277:                            : Select.SUBS_NONE;
278:                    sel.selectIdentifier(mapping, subs, ctx.store, ctx.fetch,
279:                            eager);
280:                } else if (exps.projections.length == 0) {
281:                    // subselect for objects; we really just need the primary key values
282:                    sel.select(mapping.getPrimaryKeyColumns(), joins);
283:                } else {
284:                    // if we have an inner select, we need to select the candidate
285:                    // class' pk columns to guarantee unique instances
286:                    if (inner != null)
287:                        inner.select(mapping.getPrimaryKeyColumns(), joins);
288:
289:                    // select each result value; no need to pass on the eager mode since
290:                    // under projections we always use EAGER_NONE
291:                    boolean pks = sel.getParent() != null;
292:                    for (int i = 0; i < exps.projections.length; i++) {
293:                        val = (Val) exps.projections[i];
294:                        if (inner != null)
295:                            val.selectColumns(inner, ctx, state.projections[i],
296:                                    pks);
297:                        val.select(sel, ctx, state.projections[i], pks);
298:                    }
299:
300:                    // make sure having columns are selected since it is required by 
301:                    // some DBs.  put them last so they don't affect result processing
302:                    if (exps.having != null && inner != null)
303:                        ((Exp) exps.having).selectColumns(inner, ctx,
304:                                state.having, true);
305:                }
306:
307:                // select ordering columns, since it is required by some DBs.  put them
308:                // last so they don't affect result processing
309:                for (int i = 0; i < exps.ordering.length; i++) {
310:                    val = (Val) exps.ordering[i];
311:                    if (inner != null)
312:                        val.selectColumns(inner, ctx, state.ordering[i], true);
313:                    val.select(sel, ctx, state.ordering[i], true);
314:                }
315:
316:                // add conditions limiting the projections to the proper classes; if
317:                // this isn't a projection or a subq then they will already be added
318:                if (exps.projections.length > 0 || sel.getParent() != null) {
319:                    ctx.store.loadSubclasses(mapping);
320:                    mapping.getDiscriminator().addClassConditions(
321:                            (inner != null) ? inner : sel, subclasses, joins);
322:                }
323:            }
324:
325:            /**
326:             * Used to check whether a query's result projections are on the candidate.
327:             */
328:            private static class ProjectionExpressionVisitor extends
329:                    AbstractExpressionVisitor {
330:
331:                private boolean _candidate = false;
332:                private int _level = 0;
333:
334:                public static boolean hasCandidateProjections(Value[] projs) {
335:                    ProjectionExpressionVisitor v = new ProjectionExpressionVisitor();
336:                    for (int i = 0; i < projs.length; i++) {
337:                        projs[i].acceptVisit(v);
338:                        if (v._candidate)
339:                            return true;
340:                    }
341:                    return false;
342:                }
343:
344:                public void enter(Value val) {
345:                    if (!_candidate) {
346:                        _candidate = (_level == 0 && val instanceof  Constant)
347:                                || (val instanceof  PCPath && !((PCPath) val)
348:                                        .isVariablePath());
349:                    }
350:                    _level++;
351:                }
352:
353:                public void exit(Value val) {
354:                    _level--;
355:                }
356:            }
357:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.