Source Code Cross Referenced for SelectIdsMetaPropertyVisitor.java in  » Portal » mypersonalizer » es » udc » mypersonalizer » kernel » model » query » executor » 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 » Portal » mypersonalizer » es.udc.mypersonalizer.kernel.model.query.executor.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Header: /export/home/cvsroot/MyPersonalizerRepository/MyPersonalizer/Subsystems/Kernel/Sources/es/udc/mypersonalizer/kernel/model/query/executor/sql/SelectIdsMetaPropertyVisitor.java,v 1.1.1.1 2004/03/25 12:08:37 fbellas Exp $
003:         * $Revision: 1.1.1.1 $
004:         * $Date: 2004/03/25 12:08:37 $
005:         *
006:         * =============================================================================
007:         *
008:         * Copyright (c) 2003, The MyPersonalizer Development Group
009:         * (http://www.tic.udc.es/~fbellas/mypersonalizer/index.html) at 
010:         * University Of A Coruņa
011:         * All rights reserved.
012:         *
013:         * Redistribution and use in source and binary forms, with or without
014:         * modification, are permitted provided that the following conditions are met:
015:         *
016:         *  - Redistributions of source code must retain the above copyright notice, 
017:         *    this list of conditions and the following disclaimer.
018:         *
019:         *  - Redistributions in binary form must reproduce the above copyright notice,
020:         *    this list of conditions and the following disclaimer in the documentation
021:         *    and/or other materials provided with the distribution.
022:         *
023:         *  - Neither the name of the University Of A Coruņa nor the names of its 
024:         *    contributors may be used to endorse or promote products derived from 
025:         *    this software without specific prior written permission.
026:         *
027:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
028:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
029:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
030:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
031:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
032:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
033:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
034:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
035:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
036:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
037:         * POSSIBILITY OF SUCH DAMAGE.
038:         *
039:         */
040:        package es.udc.mypersonalizer.kernel.model.query.executor.sql;
041:
042:        import java.util.ArrayList;
043:        import java.util.HashSet;
044:        import java.util.Iterator;
045:        import java.util.List;
046:        import java.util.Set;
047:
048:        import es.udc.mypersonalizer.kernel.log.Log;
049:        import es.udc.mypersonalizer.kernel.log.LogManager;
050:        import es.udc.mypersonalizer.kernel.log.LogNamingConventions;
051:        import es.udc.mypersonalizer.kernel.model.annotators.sql.SQLPersistenceTypeAnnotationHelper;
052:        import es.udc.mypersonalizer.kernel.model.metainfo.MetaCompoundProperty;
053:        import es.udc.mypersonalizer.kernel.model.metainfo.MetaProperty;
054:        import es.udc.mypersonalizer.kernel.model.metainfo.MetaPropertyNotFoundException;
055:        import es.udc.mypersonalizer.kernel.model.metainfo.MetaSimpleProperty;
056:        import es.udc.mypersonalizer.kernel.model.query.ast.Query;
057:        import es.udc.mypersonalizer.kernel.model.query.ast.Step;
058:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.ContainsFunctionExpression;
059:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.EqualsExpression;
060:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.Expression;
061:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.ExpressionVisitor;
062:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.GreaterOrEqualExpression;
063:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.GreaterThanExpression;
064:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LesserOrEqualExpression;
065:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LesserThanExpression;
066:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LiteralBooleanExpression;
067:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LiteralNumericExpression;
068:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LiteralStringExpression;
069:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LogicalAndExpression;
070:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.LogicalOrExpression;
071:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.NotEqualsExpression;
072:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.StartsWithFunctionExpression;
073:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.StepExpression;
074:        import es.udc.mypersonalizer.kernel.model.query.ast.expr.PropertyListExpression;
075:        import es.udc.mypersonalizer.kernel.model.query.virtualmetainfo.LinkMetaPropertyAnnotationHelper;
076:        import es.udc.mypersonalizer.kernel.model.query.virtualmetainfo.VirtualMetaPropertyAnnotationHelper;
077:        import es.udc.mypersonalizer.kernel.model.repository.sql.config.DatabaseConventionsConfigManager;
078:        import es.udc.mypersonalizer.kernel.util.exceptions.InternalErrorException;
079:        import es.udc.mypersonalizer.kernel.util.exceptions.VisitorException;
080:
081:        /**
082:         * This visitor incrementally builds an SQL query to retrieve the property
083:         * identifiers of the result root properties.
084:         * 
085:         * @author Abel Muinho
086:         * @since 1.0
087:         */
088:        public class SelectIdsMetaPropertyVisitor implements 
089:                MetaProperty.Visitor, ExpressionVisitor {
090:
091:            private boolean targetTableIsURITable;
092:
093:            private static final Log log = LogManager
094:                    .getLog(LogNamingConventions.MYPERSONALIZER);
095:
096:            /* Constants for building SQL queries. */
097:            private static final String WHERE_STRING = " WHERE ";
098:
099:            private static final String COMMA_STRING = ", ";
100:
101:            private static final String AND_STRING = " AND ";
102:
103:            private static final String OR_STRING = " OR ";
104:
105:            private static final String NOT_STRING = " NOT ";
106:
107:            private static final String GREATER_THAN_STRING = " > ";
108:
109:            private static final String GREATER_OR_EQUAL_STRING = ">=";
110:
111:            private static final String LESSER_THAN_STRING = " < ";
112:
113:            private static final String LESSER_OR_EQUAL_STRING = "<=";
114:
115:            private static final String EQUAL_STRING = " = ";
116:
117:            private static final String NOT_EQUAL_STRING = " <> ";
118:
119:            private static final String RPAREN_STRING = ")";
120:
121:            private static final String LPAREN_STRING = "(";
122:
123:            private static final String PARAMETER_STRING = "?";
124:
125:            private static final String LIKE_STRING = " LIKE ";
126:
127:            private static final char ESCAPE_CHAR = '#';
128:
129:            private static final String ESCAPE_STRING = " ESCAPE '"
130:                    + ESCAPE_CHAR + "' ";
131:
132:            private static final String FROM_STRING = " FROM ";
133:
134:            private static final String DOT_STRING = ".";
135:
136:            private static final String AS_STRING = " AS ";
137:
138:            private static final String SELECT_STRING = "SELECT ";
139:
140:            private static final String DISTINCT_STRING = "DISTINCT ";
141:
142:            private static final String ORDER_BY_STRING = " ORDER BY ";
143:
144:            private static final String GROUP_BY_STRING = " GROUP BY ";
145:
146:            private static String PROPERTY_ID_COLUMN = null;
147:
148:            private static String GENERATED_ID_COLUMN = null;
149:
150:            private static String LOGIN_COLUMN = null;
151:
152:            /** "Unique" name for the order by column alias. */
153:            private static final String ORDER_BY_COLUMN_NAME = "obc658amv";
154:
155:            private String resultTable = null;
156:
157:            private String orderByTable = null;
158:
159:            private String orderByColumn = null;
160:
161:            private Set tables = new HashSet();
162:
163:            private Set joinConditions = new HashSet();
164:
165:            private List whereConditions = new ArrayList();
166:
167:            /** Parameter values to be used in the SQL query, in the right order. */
168:            private List parameters = new ArrayList();
169:
170:            /** A temporary queue used for sorting the parameters. */
171:            private List pendingParametersQueue = new ArrayList();
172:
173:            private MetaProperty previousMetaProperty = null;
174:
175:            private MetaProperty targetMetaProperty = null;
176:
177:            /**
178:             * Creates a new visitor.
179:             * 
180:             * @throws InternalErrorException
181:             *             if errors occur while trying to retrieve values from the
182:             *             configuration.
183:             */
184:            public SelectIdsMetaPropertyVisitor() throws InternalErrorException {
185:
186:                if (PROPERTY_ID_COLUMN == null) {
187:                    PROPERTY_ID_COLUMN = DatabaseConventionsConfigManager
188:                            .getConfig().getPropertyIdentifierColumn();
189:                }
190:                if (GENERATED_ID_COLUMN == null) {
191:                    GENERATED_ID_COLUMN = DatabaseConventionsConfigManager
192:                            .getConfig().getGeneratedIdentifierColumn();
193:                }
194:                if (LOGIN_COLUMN == null) {
195:                    LOGIN_COLUMN = DatabaseConventionsConfigManager.getConfig()
196:                            .getLoginColumn();
197:                }
198:
199:            }
200:
201:            /**
202:             * Prepares the query for generation.
203:             * 
204:             * @param query
205:             *            the <code>Query</code> to be prepared.
206:             * @throws InternalErrorException
207:             *             if errors occur while accessing the data from the
208:             *             configuration.
209:             */
210:            public void buildQuery(Query query) throws InternalErrorException {
211:                MetaProperty metaProperty = null;
212:
213:                targetMetaProperty = ((Step) query.getReturnClause().get(
214:                        query.getReturnClause().size() - 1)).getMetaProperty();
215:                resultTable = SQLPersistenceTypeAnnotationHelper
216:                        .getTableNameAnnotation(targetMetaProperty);
217:                tables.add(resultTable);
218:
219:                try {
220:                    StepExpression stepExpression = new StepExpression();
221:                    stepExpression.setSteps(query.getReturnClause());
222:                    stepExpression.accept(this );
223:
224:                    if (query.getOrderByClause() != null) {
225:                        previousMetaProperty = null;
226:                        Iterator orderByIt = query.getOrderByClause()
227:                                .iterator();
228:                        while (orderByIt.hasNext()) {
229:                            Step step = (Step) orderByIt.next();
230:                            metaProperty = step.getMetaProperty();
231:                            metaProperty.accept(this );
232:                            if (step.getExpression() != null) {
233:                                whereConditions.add(step.getExpression()
234:                                        .accept(this ));
235:                            }
236:                        }
237:
238:                        int orderSteps = query.getOrderByClause().size();
239:                        Step lastOrderStep = (Step) query.getOrderByClause()
240:                                .get(orderSteps - 1);
241:                        MetaProperty lastOrderMetaProperty = lastOrderStep
242:                                .getMetaProperty();
243:
244:                        orderByTable = SQLPersistenceTypeAnnotationHelper
245:                                .getTableNameAnnotation(lastOrderMetaProperty);
246:                        tables.add(orderByTable);
247:                        orderByColumn = SQLPersistenceTypeAnnotationHelper
248:                                .getColumnNameAnnotation(lastOrderMetaProperty);
249:                    }
250:                } catch (VisitorException e) {
251:                    throw new InternalErrorException(e);
252:                }
253:                targetTableIsURITable = SQLQueryExecutorHelper
254:                        .isUserRegistrationInformationTable(resultTable);
255:            }
256:
257:            /**
258:             * Obtains the currently built query <code>SELECT</code> ing just the
259:             * property identifier column.
260:             * 
261:             * @return the SQL query with parameters suitable for use in a <code>PreparedStatement</code>.
262:             */
263:            public String getSqlForPropertyIds() {
264:                StringBuffer result = new StringBuffer(255);
265:
266:                /* SELECT */
267:                result.append(SELECT_STRING).append(DISTINCT_STRING).append(
268:                        resultTable).append(DOT_STRING).append("* ");
269:                if (orderByTable != null && orderByColumn != null) {
270:                    result.append(COMMA_STRING).append(orderByTable).append(
271:                            DOT_STRING).append(orderByColumn).append(AS_STRING)
272:                            .append(ORDER_BY_COLUMN_NAME);
273:                }
274:                /* FROM */
275:                result.append(FROM_STRING);
276:                Iterator itTables = tables.iterator();
277:                while (itTables.hasNext()) {
278:                    result.append((String) itTables.next());
279:                    if (itTables.hasNext()) {
280:                        result.append(COMMA_STRING);
281:                    }
282:                }
283:                /* WHERE */
284:                if (joinConditions.size() > 0 || whereConditions.size() > 0) {
285:                    result.append(WHERE_STRING);
286:
287:                    Iterator itJoins = joinConditions.iterator();
288:                    while (itJoins.hasNext()) {
289:                        result.append(LPAREN_STRING).append(
290:                                (String) itJoins.next()).append(RPAREN_STRING);
291:                        if (itJoins.hasNext()) {
292:                            result.append(AND_STRING);
293:                        }
294:                    }
295:                    if (joinConditions.size() > 0 && whereConditions.size() > 0) {
296:                        result.append(AND_STRING);
297:                    }
298:                    Iterator itWhere = whereConditions.iterator();
299:                    while (itWhere.hasNext()) {
300:                        result.append(LPAREN_STRING).append(
301:                                (String) itWhere.next()).append(RPAREN_STRING);
302:                        if (itWhere.hasNext()) {
303:                            result.append(AND_STRING);
304:                        }
305:                    }
306:                }
307:
308:                /* ORDER BY */
309:                boolean isOrdered = orderByTable != null
310:                        && orderByColumn != null;
311:                boolean isTargetMultivalued = targetMetaProperty
312:                        .isMultiValued();
313:                result.append(ORDER_BY_STRING);
314:                if (isTargetMultivalued || isOrdered) {
315:                    /* ORDER BY the foreign key, if multivalued. */
316:                    if (isTargetMultivalued) {
317:                        result.append(resultTable).append(DOT_STRING);
318:                        if (targetTableIsURITable) {
319:                            result.append(LOGIN_COLUMN);
320:                        } else {
321:                            result.append(PROPERTY_ID_COLUMN);
322:                        }
323:                        /* Separate from other fields. */
324:                        result.append(COMMA_STRING);
325:                        if (!isOrdered) {
326:                            /* Use generated id to keep document order */
327:                            result.append(GENERATED_ID_COLUMN);
328:                        }
329:                    }
330:                    if (isOrdered) {
331:                        result.append(ORDER_BY_COLUMN_NAME);
332:                    }
333:                } else {
334:                    /*
335:                     * If it is not multivalued, not ordered, use primary key to keep
336:                     * "document order" (primary key order)
337:                     */
338:                    result.append(resultTable).append(DOT_STRING);
339:                    if (targetTableIsURITable) {
340:                        result.append(LOGIN_COLUMN);
341:                    } else {
342:                        result.append(PROPERTY_ID_COLUMN);
343:                    }
344:                }
345:
346:                log.write("Generated SQL: " + result.toString(), null,
347:                        SelectIdsMetaPropertyVisitor.class);
348:                log.write("Parameters: " + parameters.toString(), null,
349:                        SelectIdsMetaPropertyVisitor.class);
350:                return result.toString();
351:            }
352:
353:            /**
354:             * Obtains the list of parameters to be used with the generated SQL.
355:             * 
356:             * @return the list of parameters.
357:             */
358:            public List getParameters() {
359:                return parameters;
360:            }
361:
362:            /*
363:             * ------------------------------------------------------------------------
364:             * Implementation of the MetaProperty.Visitor interface.
365:             */
366:
367:            public Object visitMetaSimpleProperty(
368:                    MetaSimpleProperty metaProperty) {
369:
370:                /*
371:                 * SimpleProperties can't be root of MetaServices and only are stored
372:                 * in a table if they are multivalued.
373:                 */
374:                if (metaProperty.isMultiValued()) {
375:                    joinConditions.add(buildJoinCondition(previousMetaProperty,
376:                            metaProperty));
377:                }
378:                return null;
379:            }
380:
381:            public Object visitMetaCompoundProperty(
382:                    MetaCompoundProperty metaProperty) throws VisitorException {
383:
384:                boolean isVirtual = VirtualMetaPropertyAnnotationHelper
385:                        .isVirtual(metaProperty);
386:
387:                /*
388:                 * For tables beyond the first one, add a join clause.
389:                 */
390:                if (previousMetaProperty != null) {
391:                    /* At least one previously visited metaproperty, JOIN required. */
392:                    if (!isVirtual) {
393:                        /* Handle non virtual properties. */
394:                        String joinCondition = buildJoinCondition(
395:                                previousMetaProperty, metaProperty);
396:                        joinConditions.add(joinCondition);
397:                    } else {
398:                        /* Handle virtual properties. */
399:                        /* TODO: Refactor using the command pattern if grows. */
400:                        /* TODO: only valid for the metaservice-link */
401:                        visitVirtualLinkMetaProperty(metaProperty);
402:                    }
403:                } else {
404:                    /* This is the first metaproperty. */
405:                    /* Add its table to the result. */
406:                    tables.add(SQLPersistenceTypeAnnotationHelper
407:                            .getTableNameAnnotation(metaProperty));
408:                }
409:                previousMetaProperty = metaProperty;
410:
411:                return null;
412:            }
413:
414:            /**
415:             * @param metaProperty
416:             * @throws VisitorException
417:             */
418:            protected void visitVirtualLinkMetaProperty(
419:                    MetaCompoundProperty metaProperty) throws VisitorException {
420:                MetaProperty sourceMetaProperty;
421:                try {
422:                    sourceMetaProperty = previousMetaProperty
423:                            .findMetaProperty(LinkMetaPropertyAnnotationHelper
424:                                    .getSourceProperty(metaProperty));
425:                } catch (MetaPropertyNotFoundException e) {
426:                    throw new VisitorException(e);
427:                }
428:
429:                if (sourceMetaProperty.isMultiValued()) {
430:                    /* Need to join with the parent. */
431:                    joinConditions.add(buildJoinCondition(previousMetaProperty,
432:                            sourceMetaProperty));
433:                }
434:
435:                String joinCondition = buildLinkJoinCondition(
436:                        sourceMetaProperty, metaProperty);
437:
438:                /*
439:                 * FIX for BUG0002,
440:                 * Avoid adding new parameters if the join condition has been
441:                 * already used.
442:                 * 
443:                 * @see SQLQueryExecutorDelegateTest#testBug0002
444:                 */
445:                if (!joinConditions.contains(joinCondition)) {
446:                    joinConditions.add(joinCondition);
447:                    if (!LinkMetaPropertyAnnotationHelper
448:                            .isInternalReference(metaProperty)) {
449:                        String sourceTable = SQLPersistenceTypeAnnotationHelper
450:                                .getTableNameAnnotation(sourceMetaProperty);
451:                        joinConditions.add(sourceTable + DOT_STRING
452:                                + "serviceId = ?");
453:                        parameters.add(LinkMetaPropertyAnnotationHelper
454:                                .getTargetMetaService(metaProperty));
455:                    }
456:                }
457:            }
458:
459:            /*
460:             * ------------------------------------------------------------------------
461:             * Implementation of the MetaProperty.Visitor interface.
462:             */
463:
464:            public Object visit(LogicalAndExpression e) throws VisitorException {
465:                return LPAREN_STRING + e.getLHS().accept(this ) + RPAREN_STRING
466:                        + AND_STRING + LPAREN_STRING + e.getRHS().accept(this )
467:                        + RPAREN_STRING;
468:            }
469:
470:            public Object visit(LogicalOrExpression e) throws VisitorException {
471:                return LPAREN_STRING + e.getLHS().accept(this ) + RPAREN_STRING
472:                        + OR_STRING + LPAREN_STRING + e.getRHS().accept(this )
473:                        + RPAREN_STRING;
474:            }
475:
476:            public Object visit(EqualsExpression e) throws VisitorException {
477:                return e.getLHS().accept(this ) + EQUAL_STRING
478:                        + e.getRHS().accept(this );
479:            }
480:
481:            // @see
482:            // es.udc.mypersonalizer.kernel.model.query.ast.expr.ExpressionVisitor#visit(es.udc.mypersonalizer.kernel.model.query.ast.expr.NotEqualsExpression)
483:            public Object visit(NotEqualsExpression e) throws VisitorException {
484:                return e.getLHS().accept(this ) + NOT_EQUAL_STRING
485:                        + e.getRHS().accept(this );
486:            }
487:
488:            public Object visit(LiteralBooleanExpression e) {
489:                enqueueParameterValue(e.getValue());
490:                return PARAMETER_STRING;
491:            }
492:
493:            public Object visit(LiteralNumericExpression e) {
494:                enqueueParameterValue(e.getValue());
495:                return PARAMETER_STRING;
496:            }
497:
498:            public Object visit(LiteralStringExpression e) {
499:                enqueueParameterValue(e.getValue());
500:                return PARAMETER_STRING;
501:            }
502:
503:            public Object visit(PropertyListExpression e) {
504:                /* This call is not possible. */
505:                throw new UnsupportedOperationException();
506:            }
507:
508:            public Object visit(StepExpression e) throws VisitorException {
509:                /* Backup current state as "old" */
510:                MetaProperty oldPreviousMetaProperty = this .previousMetaProperty;
511:
512:                MetaProperty metaProperty = null;
513:                Iterator it = e.getSteps().iterator();
514:                while (it.hasNext()) {
515:                    Step step = (Step) it.next();
516:                    metaProperty = step.getMetaProperty();
517:                    metaProperty.accept(this );
518:                    if (step.getExpression() != null) {
519:                        /* Create temporary space for the paramters. */
520:                        pendingParametersQueue.add(0, new ArrayList());
521:                        whereConditions.add(step.getExpression().accept(this ));
522:                        parameters.addAll((List) pendingParametersQueue.get(0));
523:                        /* We are done with our holding space. */
524:                        pendingParametersQueue.remove(0);
525:                    }
526:                }
527:                String result = SQLPersistenceTypeAnnotationHelper
528:                        .getTableNameAnnotation(metaProperty)
529:                        + DOT_STRING
530:                        + SQLPersistenceTypeAnnotationHelper
531:                                .getColumnNameAnnotation(metaProperty);
532:                /* Restore backed-up state. */
533:                previousMetaProperty = oldPreviousMetaProperty;
534:
535:                return result;
536:            }
537:
538:            public Object visit(ContainsFunctionExpression expression)
539:                    throws VisitorException {
540:                Expression container = expression.getArguments()[0];
541:                Expression contained = expression.getArguments()[1];
542:                if (contained instanceof  LiteralStringExpression) {
543:                    LiteralStringExpression stringExpr = (LiteralStringExpression) contained;
544:                    String value = escapeLike(stringExpr.getString());
545:
546:                    stringExpr.setValue('%' + value + '%');
547:                    return container.accept(this ) + LIKE_STRING
548:                            + stringExpr.accept(this ) + ESCAPE_STRING;
549:                } else {
550:                    throw new VisitorException("Second argument for 'contains'"
551:                            + " must be a literal String");
552:                }
553:            }
554:
555:            public Object visit(StartsWithFunctionExpression expression)
556:                    throws VisitorException {
557:                Expression container = expression.getArguments()[0];
558:                Expression contained = expression.getArguments()[1];
559:                if (contained instanceof  LiteralStringExpression) {
560:                    LiteralStringExpression stringExpr = (LiteralStringExpression) contained;
561:                    String value = escapeLike(stringExpr.getString());
562:
563:                    stringExpr.setValue(value + '%');
564:                    return container.accept(this ) + LIKE_STRING
565:                            + stringExpr.accept(this ) + ESCAPE_STRING;
566:                } else {
567:                    throw new VisitorException(
568:                            "Second argument for 'starts-with'"
569:                                    + " must be a literal String");
570:                }
571:            }
572:
573:            public Object visit(GreaterThanExpression e)
574:                    throws VisitorException {
575:                return e.getLHS().accept(this ) + GREATER_THAN_STRING
576:                        + e.getRHS().accept(this );
577:            }
578:
579:            public Object visit(LesserThanExpression e) throws VisitorException {
580:                return e.getLHS().accept(this ) + LESSER_THAN_STRING
581:                        + e.getRHS().accept(this );
582:
583:            }
584:
585:            public Object visit(GreaterOrEqualExpression e)
586:                    throws VisitorException {
587:                return e.getLHS().accept(this ) + GREATER_OR_EQUAL_STRING
588:                        + e.getRHS().accept(this );
589:            }
590:
591:            public Object visit(LesserOrEqualExpression e)
592:                    throws VisitorException {
593:                return e.getLHS().accept(this ) + LESSER_OR_EQUAL_STRING
594:                        + e.getRHS().accept(this );
595:            }
596:
597:            /**
598:             * Escapes the string constant to be used as a literal in the RHS of a SQL
599:             * LIKE expression.
600:             * 
601:             * @param sql
602:             *            the string to escape.
603:             * @return the escaped string.
604:             */
605:            private String escapeLike(String sql) {
606:                return sql.replaceAll("(_|%|" + ESCAPE_CHAR + ")", ESCAPE_CHAR
607:                        + "$1");
608:            }
609:
610:            /**
611:             * Adds a parameter's value to the temporary queue.
612:             * 
613:             * @param value
614:             *            the value of the parameter.
615:             */
616:            private void enqueueParameterValue(Object value) {
617:                ((List) pendingParametersQueue.get(0)).add(value);
618:            }
619:
620:            /**
621:             * Builds the join condition for "real" properties.
622:             * 
623:             * @param parent
624:             *            the parent property.
625:             * @param child
626:             *            the child property.
627:             * @return the join condition as SQL.
628:             */
629:            private String buildJoinCondition(MetaProperty parent,
630:                    MetaProperty child) {
631:                String previousTable = SQLPersistenceTypeAnnotationHelper
632:                        .getTableNameAnnotation(parent);
633:                String previousTableKey = SQLPersistenceTypeAnnotationHelper
634:                        .getIdColumnAnnotation(parent);
635:                String currentTable = SQLPersistenceTypeAnnotationHelper
636:                        .getTableNameAnnotation(child);
637:                String currentTableReference = SQLPersistenceTypeAnnotationHelper
638:                        .getFKColumnAnnotation(child);
639:                /* Make sure that our tables are in the FROM clause. */
640:                tables.add(previousTable);
641:                tables.add(currentTable);
642:                return previousTable + DOT_STRING + previousTableKey
643:                        + EQUAL_STRING + currentTable + DOT_STRING
644:                        + currentTableReference;
645:            }
646:
647:            /**
648:             * Builds the join condition for "virtual" link properties.
649:             * 
650:             * @param parent
651:             *            the parent property.
652:             * @param child
653:             *            the child property.
654:             * @return the join condition as SQL.
655:             */
656:            private String buildLinkJoinCondition(MetaProperty parent,
657:                    MetaProperty child) {
658:                String previousTable = SQLPersistenceTypeAnnotationHelper
659:                        .getTableNameAnnotation(parent);
660:                String previousTableReference = SQLPersistenceTypeAnnotationHelper
661:                        .getColumnNameAnnotation(parent);
662:                String currentTable = SQLPersistenceTypeAnnotationHelper
663:                        .getTableNameAnnotation(child);
664:                String currentTableKey = SQLPersistenceTypeAnnotationHelper
665:                        .getFKColumnAnnotation(child);
666:                /* Make sure that our tables are in the FROM clause. */
667:                tables.add(previousTable);
668:                tables.add(currentTable);
669:                return previousTable + DOT_STRING + previousTableReference
670:                        + EQUAL_STRING + currentTable + DOT_STRING
671:                        + currentTableKey;
672:            }
673:        }
w___w__w.ja__v__a_2_s_.c__o__m__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.