Source Code Cross Referenced for ScalarExpression.java in  » Database-ORM » JPOX » org » jpox » store » expression » 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 » JPOX » org.jpox.store.expression 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /**********************************************************************
0002:        Copyright (c) 2002 Mike Martin (TJDO) and others. All rights reserved.
0003:        Licensed under the Apache License, Version 2.0 (the "License");
0004:        you may not use this file except in compliance with the License.
0005:        You may obtain a copy of the License at
0006:
0007:            http://www.apache.org/licenses/LICENSE-2.0
0008:
0009:        Unless required by applicable law or agreed to in writing, software
0010:        distributed under the License is distributed on an "AS IS" BASIS,
0011:        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012:        See the License for the specific language governing permissions and
0013:        limitations under the License.
0014:         
0015:
0016:        Contributors:
0017:        2003 Andy Jefferson - commented
0018:            ...
0019:         **********************************************************************/package org.jpox.store.expression;
0020:
0021:        import java.lang.reflect.InvocationTargetException;
0022:        import java.lang.reflect.Method;
0023:        import java.util.ArrayList;
0024:        import java.util.Iterator;
0025:        import java.util.List;
0026:        import java.util.ListIterator;
0027:
0028:        import org.jpox.exceptions.JPOXException;
0029:        import org.jpox.exceptions.JPOXUserException;
0030:        import org.jpox.store.DatastoreField;
0031:        import org.jpox.store.mapping.JavaTypeMapping;
0032:        import org.jpox.store.query.JPOXQueryInvalidParametersException;
0033:        import org.jpox.store.query.StatementText;
0034:        import org.jpox.util.Localiser;
0035:
0036:        /**
0037:         * A Scalar expression in a Query. Used to compute values with a resulting type 
0038:         *
0039:         * @version $Revision: 1.34 $
0040:         **/
0041:        public abstract class ScalarExpression {
0042:            /** Localiser for messages */
0043:            protected static final Localiser LOCALISER = Localiser
0044:                    .getInstance("org.jpox.store.Localisation");
0045:
0046:            /**
0047:             * when translated to StatementText, the expression is generated to
0048:             * be projected as result of executing a statement
0049:             **/
0050:            public static int PROJECTION = 0;
0051:
0052:            /**
0053:             * when translated to StatementText, the expression is generated to
0054:             * be used as filter to a executing statement
0055:             **/
0056:            public static int FILTER = 1;
0057:
0058:            /**
0059:             * Inner class representing an Operator
0060:             **/
0061:            protected static class Operator {
0062:                protected final String symbol;
0063:                protected final int precedence;
0064:
0065:                /**
0066:                 * Operator
0067:                 * @param symbol the source text or symbol of an operator. e.g  =, ==, +, /, >, <, etc
0068:                 * @param precedence the order of precedence where the expression is compiled 
0069:                 */
0070:                public Operator(String symbol, int precedence) {
0071:                    this .symbol = symbol;
0072:                    this .precedence = precedence;
0073:                }
0074:
0075:                public String toString() {
0076:                    return symbol;
0077:                }
0078:            }
0079:
0080:            /**
0081:             * "Monadic" operator performs a function on one operand.
0082:             * It can be in either postfix or prefix notation. 
0083:             * <ul>
0084:             * <li>
0085:             * Prefix notation means that the operator appears before its operand. <i>operator operand</i>
0086:             * </li>
0087:             * <li>
0088:             * Postfix notation means that the operator appears after its operand. <i>operand operator</i>
0089:             * </li>
0090:             * </ul>
0091:             **/
0092:            protected static class MonadicOperator extends Operator {
0093:                /**
0094:                 * Monodiac operator
0095:                 * @param symbol the source text or symbol of an operator. e.g  =, ==, +, /, >, <, etc
0096:                 * @param precedence the order of precedence where the expression is compiled 
0097:                 */
0098:                public MonadicOperator(String symbol, int precedence) {
0099:                    super (symbol, precedence);
0100:                }
0101:
0102:                /**
0103:                 * Check if this operator has higher precedence than <code>op</code>
0104:                 * @param op the operator
0105:                 * @return true if this operation is higher
0106:                 */
0107:                public boolean isHigherThan(Operator op) {
0108:                    if (op == null) {
0109:                        return false;
0110:                    } else {
0111:                        return precedence > op.precedence;
0112:                    }
0113:                }
0114:            }
0115:
0116:            /**
0117:             * "Dyadic" operator performs operation on one or two operands
0118:             **/
0119:            protected static class DyadicOperator extends Operator {
0120:                /**
0121:                 * An associative operator is one for which parentheses can be inserted and removed without changing the meaning of the expression 
0122:                 */
0123:                private final boolean isAssociative;
0124:
0125:                /**
0126:                 * Dyadic operator
0127:                 * @param symbol the source text or symbol of an operator. e.g  =, ==, +, /, >, <, etc
0128:                 * @param precedence the order of precedence where the expression is compiled 
0129:                 * @param isAssociative true if associative operator. An associative operator is one for which parentheses can be inserted and removed without changing the meaning of the expression 
0130:                 */
0131:                public DyadicOperator(String symbol, int precedence,
0132:                        boolean isAssociative) {
0133:                    super (" " + symbol + " ", precedence);
0134:                    this .isAssociative = isAssociative;
0135:                }
0136:
0137:                /**
0138:                 * Checks if this operation is higher than operator <code>op</code> in left side of the expression
0139:                 * @param op the operator in the left side of the expression
0140:                 * @return true if this operation is higher than operator <code>op</code> in left side of the expression
0141:                 */
0142:                public boolean isHigherThanLeftSide(Operator op) {
0143:                    if (op == null) {
0144:                        return false;
0145:                    } else {
0146:                        return precedence > op.precedence;
0147:                    }
0148:                }
0149:
0150:                /**
0151:                 * Checks if this operation is higher than operator <code>op</code> in right side of the expression
0152:                 * @param op the operator in the right side of the expression
0153:                 * @return true if this operation is higher than operator <code>op</code> in right side of the expression
0154:                 */
0155:                public boolean isHigherThanRightSide(Operator op) {
0156:                    if (op == null) {
0157:                        return false;
0158:                    } else if (precedence == op.precedence) {
0159:                        return !isAssociative;
0160:                    } else {
0161:                        return precedence > op.precedence;
0162:                    }
0163:                }
0164:            }
0165:
0166:            /** OR **/
0167:            public static final DyadicOperator OP_OR = new DyadicOperator("OR",
0168:                    0, true);
0169:            /** AND **/
0170:            public static final DyadicOperator OP_AND = new DyadicOperator(
0171:                    "AND", 1, true);
0172:            /** NOT **/
0173:            public static final MonadicOperator OP_NOT = new MonadicOperator(
0174:                    "NOT ", 2);
0175:            /** EQ **/
0176:            public static final DyadicOperator OP_EQ = new DyadicOperator("=",
0177:                    3, false);
0178:            /** NOTEQ **/
0179:            public static final DyadicOperator OP_NOTEQ = new DyadicOperator(
0180:                    "<>", 3, false);
0181:            /** LT **/
0182:            public static final DyadicOperator OP_LT = new DyadicOperator("<",
0183:                    3, false);
0184:            /** LTEQ **/
0185:            public static final DyadicOperator OP_LTEQ = new DyadicOperator(
0186:                    "<=", 3, false);
0187:            /** GT **/
0188:            public static final DyadicOperator OP_GT = new DyadicOperator(">",
0189:                    3, false);
0190:            /** GTEQ **/
0191:            public static final DyadicOperator OP_GTEQ = new DyadicOperator(
0192:                    ">=", 3, false);
0193:            /** LIKE **/
0194:            public static final DyadicOperator OP_LIKE = new DyadicOperator(
0195:                    "LIKE", 3, false);
0196:            /** NOT LIKE **/
0197:            public static final DyadicOperator OP_NOTLIKE = new DyadicOperator(
0198:                    "NOT LIKE", 3, false);
0199:            /** BETWEEN **/
0200:            public static final DyadicOperator OP_BETWEEN = new DyadicOperator(
0201:                    "BETWEEN", 3, false);
0202:            /** IS **/
0203:            public static final DyadicOperator OP_IS = new DyadicOperator("IS",
0204:                    3, false);
0205:            /** ISNOT **/
0206:            public static final DyadicOperator OP_ISNOT = new DyadicOperator(
0207:                    "IS NOT", 3, false);
0208:            /** IN **/
0209:            public static final DyadicOperator OP_IN = new DyadicOperator("IN",
0210:                    3, false);
0211:            /** NOT IN **/
0212:            public static final DyadicOperator OP_NOTIN = new DyadicOperator(
0213:                    "NOT IN", 3, false);
0214:            /** ADD **/
0215:            public static final DyadicOperator OP_ADD = new DyadicOperator("+",
0216:                    4, true);
0217:            /** SUB **/
0218:            public static final DyadicOperator OP_SUB = new DyadicOperator("-",
0219:                    4, false);
0220:            /** CONCAT **/
0221:            public static final DyadicOperator OP_CONCAT = new DyadicOperator(
0222:                    "||", 4, true);
0223:            /** MUL **/
0224:            public static final DyadicOperator OP_MUL = new DyadicOperator("*",
0225:                    5, true);
0226:            /** DIV **/
0227:            public static final DyadicOperator OP_DIV = new DyadicOperator("/",
0228:                    5, false);
0229:            /** MOD **/
0230:            public static final DyadicOperator OP_MOD = new DyadicOperator("%",
0231:                    5, false);
0232:            /** NEG **/
0233:            public static final MonadicOperator OP_NEG = new MonadicOperator(
0234:                    "-", 6);
0235:            /** COM **/
0236:            public static final MonadicOperator OP_COM = new MonadicOperator(
0237:                    "~", 6);
0238:
0239:            /** The Query Expression. */
0240:            protected final QueryExpression qs;
0241:
0242:            /** The table expression being used. */
0243:            protected LogicSetExpression te;
0244:
0245:            /** The Statement Text for this expression. */
0246:            protected final StatementText st = new StatementText();
0247:
0248:            protected Operator lowestOperator = null;
0249:
0250:            /** alias identifier for this expression **/
0251:            protected String aliasIdentifier;
0252:
0253:            /** The expression string without any alias. */
0254:            private String nonAliasExpression;
0255:
0256:            /** Mapping for the field. */
0257:            protected JavaTypeMapping mapping;
0258:
0259:            /** List of sub-expressions. Used where we have a field that has multiple datastore mappings (one subexpression for each). */
0260:            protected ExpressionList expressionList = new ExpressionList();
0261:
0262:            /** Name of a parameter that this expression/literal represents (if any). */
0263:            protected String parameterName = null;
0264:
0265:            /** Flag whether we should make checks for type assignability (currently for JPA). */
0266:            protected boolean checkForTypeAssignability = false;
0267:
0268:            /**
0269:             * Constructor.
0270:             * @param qs The Query Expression
0271:             */
0272:            protected ScalarExpression(QueryExpression qs) {
0273:                this .qs = qs;
0274:            }
0275:
0276:            /**
0277:             * Constructor for an expression of the mapping in the specified table.
0278:             * Creates a list of (field) expressions for the datastore mappings of the specified field.
0279:             * @param qs The Query Expression
0280:             * @param mapping The field mapping
0281:             * @param te The table
0282:             */
0283:            protected ScalarExpression(QueryExpression qs,
0284:                    JavaTypeMapping mapping, LogicSetExpression te) {
0285:                this (qs);
0286:                this .mapping = mapping;
0287:                this .te = te;
0288:                for (int i = 0; i < mapping.getNumberOfDatastoreFields(); i++) {
0289:                    DatastoreFieldExpression fieldExpr = new DatastoreFieldExpression(
0290:                            qs, mapping.getDataStoreMapping(i)
0291:                                    .getDatastoreField(), te);
0292:                    expressionList.addExpression(fieldExpr);
0293:                }
0294:                st.append(expressionList.toString());
0295:            }
0296:
0297:            /**
0298:             * Generates statement as e.g. FUNCTION_NAME(arg[,argN])
0299:             * @param functionName Name of the function
0300:             * @param args ScalarExpression list
0301:             */
0302:            protected ScalarExpression(String functionName, List args) {
0303:                st.append(functionName).append('(');
0304:
0305:                ListIterator i = args.listIterator();
0306:                ScalarExpression arg = (ScalarExpression) i.next();
0307:                st.append(arg);
0308:                qs = arg.qs;
0309:
0310:                while (i.hasNext()) {
0311:                    arg = (ScalarExpression) i.next();
0312:                    st.append(',').append(arg);
0313:                }
0314:
0315:                st.append(')');
0316:            }
0317:
0318:            /**
0319:             * Generates statement as e.g. FUNCTION_NAME(arg AS type[,argN as typeN])
0320:             * @param functionName Name of function
0321:             * @param args ScalarExpression list
0322:             * @param types String or ScalarExpression list
0323:             */
0324:            protected ScalarExpression(String functionName, List args,
0325:                    List types) {
0326:                st.append(functionName).append('(');
0327:
0328:                ListIterator i = args.listIterator();
0329:                ListIterator iTypes = types.listIterator();
0330:                ScalarExpression arg = (ScalarExpression) i.next();
0331:                st.append(arg);
0332:                st.append(" AS ");
0333:                Object type = iTypes.next();
0334:                if (type instanceof  ScalarExpression) {
0335:                    st.append((ScalarExpression) type);
0336:                } else {
0337:                    st.append(type.toString());
0338:                }
0339:                this .qs = arg.qs;
0340:
0341:                while (i.hasNext()) {
0342:                    arg = (ScalarExpression) i.next();
0343:                    st.append(',').append(arg);
0344:                    st.append(" AS ");
0345:                    type = iTypes.next();
0346:                    if (type instanceof  ScalarExpression) {
0347:                        st.append((ScalarExpression) type);
0348:                    } else {
0349:                        st.append(type.toString());
0350:                    }
0351:                }
0352:
0353:                st.append(')');
0354:            }
0355:
0356:            /**
0357:             * Perform a function <code>op</code> on <code>operand</code> 
0358:             * @param op operator
0359:             * @param operand operand
0360:             */
0361:            protected ScalarExpression(MonadicOperator op,
0362:                    ScalarExpression operand) {
0363:                st.append(op.toString());
0364:
0365:                if (op.isHigherThan(operand.lowestOperator)) {
0366:                    st.append('(').append(operand).append(')');
0367:                } else {
0368:                    st.append(operand);
0369:                }
0370:
0371:                qs = operand.qs;
0372:                lowestOperator = op;
0373:                mapping = operand.mapping;
0374:            }
0375:
0376:            /**
0377:             * Performs a function on two arguments.
0378:             * op(operand1,operand2)
0379:             * operand1 op operand2 
0380:             * @param operand1 the first expression
0381:             * @param op the operator between operands
0382:             * @param operand2 the second expression
0383:             */
0384:            protected ScalarExpression(ScalarExpression operand1,
0385:                    DyadicOperator op, ScalarExpression operand2) {
0386:                qs = operand1.qs;
0387:                lowestOperator = op;
0388:
0389:                if (op == ScalarExpression.OP_CONCAT) {
0390:                    //enclose within parentheses to make sure the concat expression is first evaluated
0391:                    st.append(qs.getStoreManager().getDatastoreAdapter()
0392:                            .concatOperator(operand1, operand2)
0393:                            .encloseWithInParentheses());
0394:                } else {
0395:                    if (op.isHigherThanLeftSide(operand1.lowestOperator)) {
0396:                        st.append('(').append(operand1).append(')');
0397:                    } else {
0398:                        st.append(operand1);
0399:                    }
0400:
0401:                    st.append(op.toString());
0402:
0403:                    if (op.isHigherThanRightSide(operand2.lowestOperator)) {
0404:                        st.append('(').append(operand2).append(')');
0405:                    } else {
0406:                        st.append(operand2);
0407:                    }
0408:
0409:                    // some databases use a ESCAPE expression with LIKE when using an escaped pattern
0410:                    if (op == ScalarExpression.OP_LIKE
0411:                            && operand1.qs.getStoreManager()
0412:                                    .getDatastoreAdapter()
0413:                                    .supportsEscapeExpressionInLikePredicate()) {
0414:                        if (operand2 instanceof  Literal) {
0415:                            st.append(' ');
0416:                            st.append(operand1.qs.getStoreManager()
0417:                                    .getDatastoreAdapter()
0418:                                    .getEscapePatternExpression());
0419:                            st.append(' ');
0420:                        }
0421:                    }
0422:                }
0423:            }
0424:
0425:            /**
0426:             * Mutator to set the parameter name that this expression/literal represents.
0427:             * @param paramName Name of the parameter
0428:             */
0429:            public void setParameterName(String paramName) {
0430:                this .parameterName = paramName;
0431:            }
0432:
0433:            /**
0434:             * Accessor for the parameter name that this expression/literal represents (if any).
0435:             * @return Name of the parameter represented by this expression
0436:             */
0437:            public String getParameterName() {
0438:                return parameterName;
0439:            }
0440:
0441:            /**
0442:             * Accessor for whether this expression/literal represents a parameter.
0443:             * @return Whether a parameter is being represented.
0444:             */
0445:            public boolean isParameter() {
0446:                return parameterName != null;
0447:            }
0448:
0449:            /**
0450:             * Method to mark this expression/literal as needing checking for type assignability.
0451:             * TODO Make this part of ObjectManager and allow ScalarExpression to reach the ObjectManager
0452:             * so we don't need to propagate the info
0453:             */
0454:            public void checkForTypeAssignability() {
0455:                checkForTypeAssignability = true;
0456:            }
0457:
0458:            /**
0459:             * Accessor for the query expression.
0460:             * @return The query expression
0461:             */
0462:            public QueryExpression getQueryExpression() {
0463:                return qs;
0464:            }
0465:
0466:            /**
0467:             * Accessor for the table expression being used by this expression.
0468:             * @return Returns the table expression for this expression.
0469:             */
0470:            public LogicSetExpression getLogicSetExpression() {
0471:                return te;
0472:            }
0473:
0474:            /**
0475:             * Conditional And. Evaluates its right-hand operand only if the value of its left-hand operand is true.
0476:             * @param expr the right-hand operand
0477:             * @return the result value is true if both operand values are true; otherwise, the result is false.
0478:             */
0479:            public BooleanExpression and(ScalarExpression expr) {
0480:                throw new IllegalOperationException(this , "&&", expr);
0481:            }
0482:
0483:            /**
0484:             * Exclusive OR
0485:             * @param expr the right-hand operand
0486:             * @return the result value is the bitwise exclusive OR of the operand values.
0487:             */
0488:            public BooleanExpression eor(ScalarExpression expr) {
0489:                throw new IllegalOperationException(this , "^", expr);
0490:            }
0491:
0492:            /**
0493:             * Conditional OR. Evaluates its right-hand operand only if the value of its left-hand operand is false. 
0494:             * @param expr the right-hand operand
0495:             * @return the result value is false if both operand values are false; otherwise, the result is true.
0496:             */
0497:            public BooleanExpression ior(ScalarExpression expr) {
0498:                throw new IllegalOperationException(this , "||", expr);
0499:            }
0500:
0501:            /**
0502:             * Logical complement 
0503:             * @return the result value is false if operand is true; otherwise, the result is true.
0504:             */
0505:            public BooleanExpression not() {
0506:                throw new IllegalOperationException("!", this );
0507:            }
0508:
0509:            /**
0510:             * Equality operator (equals to)
0511:             * @param expr the right-hand operand
0512:             * @return The type of an equality expression is a boolean
0513:             */
0514:            public BooleanExpression eq(ScalarExpression expr) {
0515:                if (this  instanceof  UnknownLiteral
0516:                        || expr instanceof  UnknownLiteral) {
0517:                    return new BooleanLiteral(qs, mapping, true);
0518:                }
0519:                throw new IllegalOperationException(this , "==", expr);
0520:            }
0521:
0522:            /**
0523:             * Equality operator (not equals to)
0524:             * @param expr the right-hand operand
0525:             * @return The type of an equality expression is a boolean
0526:             */
0527:            public BooleanExpression noteq(ScalarExpression expr) {
0528:                if (this  instanceof  UnknownLiteral
0529:                        || expr instanceof  UnknownLiteral) {
0530:                    return new BooleanLiteral(qs, mapping, true);
0531:                }
0532:                throw new IllegalOperationException(this , "!=", expr);
0533:            }
0534:
0535:            /**
0536:             * Relational operator (lower than)
0537:             * @param expr the right-hand operand
0538:             * @return true if the value of the left-hand operand is less than the value of the right-hand operand, and otherwise is false.
0539:             */
0540:            public BooleanExpression lt(ScalarExpression expr) {
0541:                if (this  instanceof  UnknownLiteral
0542:                        || expr instanceof  UnknownLiteral) {
0543:                    return new BooleanLiteral(qs, mapping, true);
0544:                }
0545:                throw new IllegalOperationException(this , "<", expr);
0546:            }
0547:
0548:            /**
0549:             * Relational operator (lower than or equals)
0550:             * @param expr the right-hand operand
0551:             * @return true if the value of the left-hand operand is less than or equal to the value of the right-hand operand, and otherwise is false.
0552:             */
0553:            public BooleanExpression lteq(ScalarExpression expr) {
0554:                if (this  instanceof  UnknownLiteral
0555:                        || expr instanceof  UnknownLiteral) {
0556:                    return new BooleanLiteral(qs, mapping, true);
0557:                }
0558:                throw new IllegalOperationException(this , "<=", expr);
0559:            }
0560:
0561:            /**
0562:             * Relational operator (greater than)
0563:             * @param expr the right-hand operand
0564:             * @return true if the value of the left-hand operand is greater than the value of the right-hand operand, and otherwise is false.
0565:             */
0566:            public BooleanExpression gt(ScalarExpression expr) {
0567:                if (this  instanceof  UnknownLiteral
0568:                        || expr instanceof  UnknownLiteral) {
0569:                    return new BooleanLiteral(qs, mapping, true);
0570:                }
0571:                throw new IllegalOperationException(this , ">", expr);
0572:            }
0573:
0574:            /**
0575:             * Relational operator (greater than or equals)
0576:             * @param expr the right-hand operand
0577:             * @return true if the value of the left-hand operand is greater than or equal the value of the right-hand operand, and otherwise is false.
0578:             */
0579:            public BooleanExpression gteq(ScalarExpression expr) {
0580:                if (this  instanceof  UnknownLiteral
0581:                        || expr instanceof  UnknownLiteral) {
0582:                    return new BooleanLiteral(qs, mapping, true);
0583:                }
0584:                throw new IllegalOperationException(this , ">=", expr);
0585:            }
0586:
0587:            /**
0588:             * Type Comparison Operator instanceof
0589:             * @param expr the right-hand ReferenceType expression
0590:             * @return true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.
0591:             */
0592:            public BooleanExpression instanceOf(ScalarExpression expr) {
0593:                if (this  instanceof  UnknownLiteral
0594:                        || expr instanceof  UnknownLiteral) {
0595:                    return new BooleanLiteral(qs, mapping, true);
0596:                }
0597:                throw new IllegalOperationException(this , "instanceof", expr);
0598:            }
0599:
0600:            /**
0601:             * In expression. Return true if this is contained by <code>expr</code>
0602:             * @param expr the right-hand expression
0603:             * @return true if the left-hand expression is contained by the right-hand expression. Otherwise the result is false.
0604:             */
0605:            public BooleanExpression in(ScalarExpression expr) {
0606:                if (this  instanceof  UnknownLiteral
0607:                        || expr instanceof  UnknownLiteral) {
0608:                    return new BooleanLiteral(qs, mapping, true);
0609:                }
0610:                throw new IllegalOperationException(this , "in", expr);
0611:            }
0612:
0613:            /**
0614:             * Additive Operator. The binary + operator performs addition when applied to two operands of numeric type, producing the sum of the operands. If the type of either operand of a + operator is String, then the operation is string concatenation.
0615:             * @param expr the right-hand operand
0616:             * @return If one of the operands is String, the returned value is the string concatenation; The sum of two operands of numeric type. The left-hand operand is the minuend and the right-hand operand is the subtrahend;
0617:             */
0618:            public ScalarExpression add(ScalarExpression expr) {
0619:                if (this  instanceof  UnknownLiteral
0620:                        || expr instanceof  UnknownLiteral) {
0621:                    return new FloatingPointLiteral(qs, mapping,
0622:                            new Double(0.0));
0623:                }
0624:                throw new IllegalOperationException(this , "+", expr);
0625:            }
0626:
0627:            /**
0628:             * Additive Operator. The binary - operator subtracts right-hand operand from left-hand operand.
0629:             * @param expr the right-hand operand
0630:             * @return The binary - operator performs subtraction when applied to two operands of numeric type producing the difference of its operands; the left-hand operand is the minuend and the right-hand operand is the subtrahend.
0631:             */
0632:            public ScalarExpression sub(ScalarExpression expr) {
0633:                if (this  instanceof  UnknownLiteral
0634:                        || expr instanceof  UnknownLiteral) {
0635:                    return new FloatingPointLiteral(qs, mapping,
0636:                            new Double(0.0));
0637:                }
0638:                throw new IllegalOperationException(this , "-", expr);
0639:            }
0640:
0641:            /**
0642:             * Multiplication Operator 
0643:             * @param expr the right-hand operator
0644:             * @return The binary * operator performs multiplication, producing the product of its operands. 
0645:             */
0646:            public ScalarExpression mul(ScalarExpression expr) {
0647:                if (this  instanceof  UnknownLiteral
0648:                        || expr instanceof  UnknownLiteral) {
0649:                    return new FloatingPointLiteral(qs, mapping,
0650:                            new Double(0.0));
0651:                }
0652:                throw new IllegalOperationException(this , "*", expr);
0653:            }
0654:
0655:            /**
0656:             * Division Operator. The left-hand operand is the dividend and the right-hand operand is the divisor.
0657:             * @param expr the right-hand operator
0658:             * @return The binary / operator performs division, producing the quotient of its operands
0659:             */
0660:            public ScalarExpression div(ScalarExpression expr) {
0661:                if (this  instanceof  UnknownLiteral
0662:                        || expr instanceof  UnknownLiteral) {
0663:                    return new FloatingPointLiteral(qs, mapping,
0664:                            new Double(0.0));
0665:                }
0666:                throw new IllegalOperationException(this , "/", expr);
0667:            }
0668:
0669:            /**
0670:             * Remainder Operator. The left-hand operand is the dividend and the right-hand operand is the divisor.
0671:             * @param expr the right-hand operator
0672:             * @return The binary % operator is said to yield the remainder of its operands from an implied division
0673:             */
0674:            public ScalarExpression mod(ScalarExpression expr) {
0675:                if (this  instanceof  UnknownLiteral
0676:                        || expr instanceof  UnknownLiteral) {
0677:                    return new FloatingPointLiteral(qs, mapping,
0678:                            new Double(0.0));
0679:                }
0680:                throw new IllegalOperationException(this , "%", expr);
0681:            }
0682:
0683:            /**
0684:             * Unary Minus Operator
0685:             * @return the type of the unary minus expression is the promoted type of the operand.
0686:             */
0687:            public ScalarExpression neg() {
0688:                throw new IllegalOperationException("-", this );
0689:            }
0690:
0691:            /**
0692:             * Bitwise Complement Operator
0693:             * @return the type of the unary bitwise complement expression is the promoted type of the operand.
0694:             */
0695:            public ScalarExpression com() {
0696:                throw new IllegalOperationException("~", this );
0697:            }
0698:
0699:            /**
0700:             * A cast expression converts, at run time, a value of one type to a similar value of another type;
0701:             * or confirms, at compile time, that the type of an expression is boolean; or checks, at run time, that a reference
0702:             * value refers to an object whose class is compatible with a specified reference type.
0703:             * The type of the operand expression must be converted to the type explicitly named by the cast operator.
0704:             * @param type the type named by the cast operator
0705:             * @return the converted value
0706:             */
0707:            public ScalarExpression cast(Class type) {
0708:                throw new IllegalOperationException(
0709:                        "cast to " + type.getName(), this );
0710:            }
0711:
0712:            /**
0713:             * A field access expression may access a field of an object or array, a reference to which is the value of an expression 
0714:             * @param fieldName the field identifier
0715:             * @param innerJoin true if in datastore to use inner joins; false to use left joins 
0716:             * @return the field expression
0717:             */
0718:            public ScalarExpression accessField(String fieldName,
0719:                    boolean innerJoin) {
0720:                throw new IllegalOperationException(
0721:                        "access field " + fieldName, this );
0722:            }
0723:
0724:            /**
0725:             * Define a new identifier for this expression
0726:             * @param aliasIdentifier the alias
0727:             * @return this
0728:             */
0729:            public ScalarExpression as(String aliasIdentifier) {
0730:                if (this .aliasIdentifier == null) {
0731:                    this .aliasIdentifier = aliasIdentifier;
0732:                    nonAliasExpression = st.toString();
0733:                    st.postpend(" AS " + aliasIdentifier);
0734:                    expressionList.updateExpressionAlias();
0735:                }
0736:                return this ;
0737:            }
0738:
0739:            /**
0740:             * Accessor for the alias (if any).
0741:             * @return Returns the alias.
0742:             */
0743:            public String getAlias() {
0744:                return aliasIdentifier;
0745:            }
0746:
0747:            /**
0748:             * Accessor for the expression without any alias.
0749:             * @return Returns the nonAliasExpression.
0750:             */
0751:            public String getNonAliasExpression() {
0752:                return nonAliasExpression;
0753:            }
0754:
0755:            /*
0756:             * This can be enlarged as needed, but for the present there are no methods
0757:             * accepting more than 7 arguments.
0758:             */
0759:            private static final Class[][] PARAM_TYPE_SIGNATURES = {
0760:                    null,
0761:                    new Class[] { ScalarExpression.class },
0762:                    new Class[] { ScalarExpression.class,
0763:                            ScalarExpression.class },
0764:                    new Class[] { ScalarExpression.class,
0765:                            ScalarExpression.class, ScalarExpression.class },
0766:                    new Class[] { ScalarExpression.class,
0767:                            ScalarExpression.class, ScalarExpression.class,
0768:                            ScalarExpression.class },
0769:                    new Class[] { ScalarExpression.class,
0770:                            ScalarExpression.class, ScalarExpression.class,
0771:                            ScalarExpression.class, ScalarExpression.class },
0772:                    new Class[] { ScalarExpression.class,
0773:                            ScalarExpression.class, ScalarExpression.class,
0774:                            ScalarExpression.class, ScalarExpression.class,
0775:                            ScalarExpression.class },
0776:                    new Class[] { ScalarExpression.class,
0777:                            ScalarExpression.class, ScalarExpression.class,
0778:                            ScalarExpression.class, ScalarExpression.class,
0779:                            ScalarExpression.class, ScalarExpression.class } };
0780:
0781:            /**
0782:             * Invoke a function in a expression. The scalar expression must have
0783:             * a method with the signature "<code>methodName</code>Method([ScalarExpression argument1, [ScalarExpression argument2],...])".
0784:             * The number of arguments is equivalent to the size of the <code>arguments</code> list.
0785:             * @param methodName the function name
0786:             * @param arguments the arguments
0787:             * @return the result returned when invoking the function
0788:             */
0789:            public ScalarExpression callMethod(String methodName, List arguments) {
0790:                ScalarExpression expr;
0791:
0792:                try {
0793:                    int numArgs = arguments.size();
0794:                    if (numArgs >= PARAM_TYPE_SIGNATURES.length) {
0795:                        throw new NoSuchMethodException(methodName
0796:                                + typeList(arguments));
0797:                    }
0798:
0799:                    boolean hasArrayArgument = false;
0800:                    for (int i = 0; i < arguments.size(); i++) {
0801:                        if (arguments.get(i) instanceof  ArrayExpression) {
0802:                            hasArrayArgument = true;
0803:                            break;
0804:                        }
0805:                    }
0806:                    Method m;
0807:                    if (!hasArrayArgument) {
0808:                        m = getClass().getMethod(methodName + "Method",
0809:                                PARAM_TYPE_SIGNATURES[numArgs]);
0810:                        expr = (ScalarExpression) m.invoke(this , arguments
0811:                                .toArray());
0812:                    } else {
0813:                        Class[] argTypes = new Class[arguments.size()];
0814:                        Object[] args = new Object[arguments.size()];
0815:                        for (int i = 0; i < arguments.size(); i++) {
0816:                            if (arguments.get(i) instanceof  ArrayExpression) {
0817:                                argTypes[i] = new ScalarExpression[0]
0818:                                        .getClass();
0819:                                args[i] = ((ArrayExpression) arguments.get(i)).exprs;
0820:                            } else {
0821:                                argTypes[i] = ScalarExpression.class;
0822:                                args[i] = arguments.get(i);
0823:                            }
0824:                        }
0825:                        m = getClass().getMethod(methodName + "Method",
0826:                                argTypes);
0827:                        expr = (ScalarExpression) m.invoke(this , args);
0828:                    }
0829:                } catch (InvocationTargetException e) {
0830:                    Throwable t = e.getTargetException();
0831:
0832:                    if (t instanceof  Error) {
0833:                        throw (Error) t;
0834:                    }
0835:                    if (t instanceof  JPOXException) {
0836:                        throw (JPOXException) t;
0837:                    } else {
0838:                        throw new MethodInvocationException(methodName,
0839:                                arguments, t);
0840:                    }
0841:                } catch (Exception e) {
0842:                    throw new MethodInvocationException(methodName, arguments,
0843:                            e);
0844:                }
0845:
0846:                return expr;
0847:            }
0848:
0849:            /**
0850:             * Method to request the enclosure of this expression within parentheses
0851:             * @return the enclosed expression
0852:             */
0853:            public ScalarExpression encloseWithInParentheses() {
0854:                st.encloseWithInParentheses();
0855:                return this ;
0856:            }
0857:
0858:            /**
0859:             * StatementText representation of this expression. I.E. A Boolean field may be stored in 
0860:             * boolean format like 0 or 1, and it can also be stored in other formats, like Y or N, TRUE or FALSE, and so on.
0861:             * The projection mode for the boolean field is the real content of the value stored, (e.g. Y or N), and opposed to
0862:             * that the filter mode for the boolean field is always represented by a boolean expression (e.g. Y=Y or N=N)
0863:             * In SQL, the projection can be exemplified as "SELECT BOOLEAN_FIELD ... " and the filter as 
0864:             * "SELECT COLUMNS ... WHERE BOOLEAN_FIELD ='Y'" 
0865:             * 
0866:             * @param mode (0=PROJECTION;1=FILTER)
0867:             * @return the StatementText 
0868:             */
0869:            public StatementText toStatementText(int mode) {
0870:                return st;
0871:            }
0872:
0873:            /**
0874:             * Equality operator providing a simple comparison of expressions.
0875:             * @param o The other object
0876:             * @return Whether they are equal
0877:             */
0878:            public boolean equals(Object o) {
0879:                if (o == null) {
0880:                    return false;
0881:                }
0882:                if (o == this ) {
0883:                    return true;
0884:                }
0885:                if (!(o instanceof  ScalarExpression)) {
0886:                    return false;
0887:                }
0888:
0889:                // Just compare if the statement text is the same, removing any ALIAS
0890:                String this String = toStatementText(ScalarExpression.FILTER)
0891:                        .toString();
0892:                String otherString = ((ScalarExpression) o).toStatementText(
0893:                        ScalarExpression.FILTER).toString();
0894:                if (this String.indexOf(" AS ") > 0) {
0895:                    this String = this String.substring(0, this String
0896:                            .indexOf(" AS "));
0897:                }
0898:                if (otherString.indexOf(" AS ") > 0) {
0899:                    otherString = otherString.substring(0, otherString
0900:                            .indexOf(" AS "));
0901:                }
0902:
0903:                return this String.equals(otherString);
0904:            }
0905:
0906:            public String toString() {
0907:                String value;
0908:
0909:                try {
0910:                    value = " \""
0911:                            + toStatementText(ScalarExpression.FILTER)
0912:                                    .toString() + '"';
0913:                } catch (JPOXException e) {
0914:                    value = "";
0915:                }
0916:
0917:                String className = getClass().getName();
0918:
0919:                return className.substring(className.lastIndexOf('.') + 1)
0920:                        + value;
0921:            }
0922:
0923:            private static String typeList(List exprs) {
0924:                StringBuffer s = new StringBuffer("(");
0925:                Iterator i = exprs.iterator();
0926:
0927:                while (i.hasNext()) {
0928:                    s.append(i.next()).append(i.hasNext() ? ',' : ')');
0929:                }
0930:
0931:                return s.toString();
0932:            }
0933:
0934:            /**
0935:             * Method to check if the passed expression when being a parameter is of a valid type for
0936:             * comparison. Throws a JPOXQueryInvalidParametersException if not of the same type.
0937:             * @param expr The other expression
0938:             */
0939:            protected void assertValidTypeForParameterComparison(
0940:                    ScalarExpression expr, Class type) {
0941:                if ((checkForTypeAssignability || expr.checkForTypeAssignability)
0942:                        && expr.isParameter()
0943:                        && !type.isAssignableFrom(expr.getClass())) {
0944:                    throw new JPOXQueryInvalidParametersException(LOCALISER
0945:                            .msg("021077", expr.getParameterName(), getClass()
0946:                                    .getName(), expr.getClass().getName()));
0947:                }
0948:            }
0949:
0950:            /**
0951:             * Convenience method to return a ScalarExpression that we can use to compare against this object.
0952:             * Returns the input expression unless it is for a parameter and the parameter expression has a different
0953:             * datastore mapping (the default mapping whereas this has had its datastore mapping specially
0954:             * selected).
0955:             * @param expr The expression to check
0956:             * @return The expression to use
0957:             */
0958:            protected ScalarExpression getConsistentTypeForParameterComparison(
0959:                    ScalarExpression expr) {
0960:                if (expr.isParameter()
0961:                        && !isParameter()
0962:                        && mapping != null
0963:                        && expr.getMapping() != null
0964:                        && mapping.getDataStoreMapping(0).getClass() != expr
0965:                                .getMapping().getDataStoreMapping(0).getClass()
0966:                        && ((Literal) expr).getRawValue() != null) {
0967:                    // TODO We should make the check in the opposite direction too but that would need to go in each method
0968:                    // Parameter literal with different datastore mapping, so replace with one with the same datastore mapping
0969:                    // Only replace if the literal has its raw value (TODO is this restriction needed ?)
0970:                    expr = mapping.newLiteral(qs, ((Literal) expr)
0971:                            .getRawValue());
0972:                }
0973:                return expr;
0974:            }
0975:
0976:            /**
0977:             * Accessor for the mapping for this expression (if any).
0978:             * @return Returns the mapping.
0979:             */
0980:            public JavaTypeMapping getMapping() {
0981:                return mapping;
0982:            }
0983:
0984:            /**
0985:             * Ordered list of expressions comma separated
0986:             **/
0987:            public class ExpressionList {
0988:                private List expressions = new ArrayList();
0989:
0990:                /**
0991:                 * Add a new Expression to the list
0992:                 * @param expression in RDBMS datastore expressions can be columns
0993:                 */
0994:                public void addExpression(ScalarExpression expression) {
0995:                    expressions.add(expression);
0996:                }
0997:
0998:                /**
0999:                 * Convenience method for the situation where the alias of a single-field expression has been
1000:                 * updated since adding the expression to the list. Does nothing when there are more than 1
1001:                 * expression in the list.
1002:                 */
1003:                public void updateExpressionAlias() {
1004:                    if (expressions.size() == 1) {
1005:                        ((ScalarExpression) expressions.get(0))
1006:                                .as(aliasIdentifier);
1007:                    }
1008:                }
1009:
1010:                /**
1011:                 * Gets the expression in the index
1012:                 * @param index the position for the expression in the list of expressions
1013:                 * @return the expression in the index
1014:                 */
1015:                public ScalarExpression getExpression(int index) {
1016:                    return (ScalarExpression) expressions.get(index);
1017:                }
1018:
1019:                /**
1020:                 * Number of expressions enclosed in this Scalar Expression
1021:                 * @return number of expressions enclosed in this Scalar Expression
1022:                 */
1023:                public int size() {
1024:                    return expressions.size();
1025:                }
1026:
1027:                /**
1028:                 * Returns an string with a serie of expression comma separated.
1029:                 * BNF notation: [ expr [, expr] ] 
1030:                 * @return the expression list comma separated 
1031:                 */
1032:                public String toString() {
1033:                    StringBuffer expr = new StringBuffer();
1034:                    for (int i = 0; i < expressions.size(); i++) {
1035:                        expr.append(getExpression(i).toString());
1036:                        if (i < (expressions.size() - 1)) {
1037:                            expr.append(',');
1038:                        }
1039:                    }
1040:                    return expr.toString();
1041:                }
1042:
1043:                /**
1044:                 * Return an array of nested expressions
1045:                 * @return ScalarExpression[]
1046:                 */
1047:                public ScalarExpression[] toArray() {
1048:                    return (ScalarExpression[]) expressions
1049:                            .toArray(new ScalarExpression[expressions.size()]);
1050:                }
1051:            }
1052:
1053:            /**
1054:             * Returns the expression list.
1055:             * @return The expressions list with atomic expressions (ScalarExpression.FieldExpression). A expression in this list can't be split down
1056:             */
1057:            public ExpressionList getExpressionList() {
1058:                return expressionList;
1059:            }
1060:
1061:            /**
1062:             * A field expression represents a storage location for the value with an associated type
1063:             */
1064:            public static class DatastoreFieldExpression extends
1065:                    ScalarExpression {
1066:                DatastoreField field;
1067:
1068:                /**
1069:                 * 
1070:                 * @param qs
1071:                 * @param field
1072:                 * @param te
1073:                 */
1074:                public DatastoreFieldExpression(QueryExpression qs,
1075:                        DatastoreField field, LogicSetExpression te) {
1076:                    super (qs);
1077:                    this .field = field;
1078:                    this .te = te;
1079:                    st.append(te.referenceColumn(field));
1080:                }
1081:
1082:                public BooleanExpression eq(ScalarExpression expr) {
1083:                    return new BooleanExpression(expr, OP_EQ, this );
1084:                }
1085:
1086:                public BooleanExpression noteq(ScalarExpression expr) {
1087:                    return new BooleanExpression(expr, OP_NOTEQ, this );
1088:                }
1089:
1090:                public int hashCode() {
1091:                    return te.hashCode() ^ field.hashCode();
1092:                }
1093:
1094:                public boolean equals(Object o) {
1095:                    if (o == this ) {
1096:                        return true;
1097:                    }
1098:
1099:                    if (!(o instanceof  DatastoreFieldExpression)) {
1100:                        return false;
1101:                    }
1102:
1103:                    DatastoreFieldExpression qsc = (DatastoreFieldExpression) o;
1104:
1105:                    return te.equals(qsc.te) && field.equals(qsc.field);
1106:                }
1107:
1108:                public String toString() {
1109:                    if (aliasIdentifier != null) {
1110:                        return te.referenceColumn(field) + " AS "
1111:                                + aliasIdentifier;
1112:                    } else {
1113:                        return te.referenceColumn(field);
1114:                    }
1115:                }
1116:            }
1117:
1118:            /**
1119:             * An illegal argument error represents method invocations with unsupported/invalid argument types
1120:             **/
1121:            public static class IllegalArgumentTypeException extends
1122:                    IllegalArgumentException {
1123:                /**
1124:                 * Constructor
1125:                 * @param arg the illegal expression for the method
1126:                 */
1127:                public IllegalArgumentTypeException(ScalarExpression arg) {
1128:                    super ("Illegal argument type: " + arg);
1129:                }
1130:            }
1131:
1132:            /**
1133:             * A method invocation error represents an effort to invoke a operation on a expression
1134:             **/
1135:            public static class MethodInvocationException extends
1136:                    JPOXUserException {
1137:                /**
1138:                 * Constructor
1139:                 * @param methodName the function name
1140:                 * @param arguments the arguments
1141:                 * @param t the nested exception
1142:                 */
1143:                public MethodInvocationException(String methodName,
1144:                        List arguments, Throwable t) {
1145:                    super ("Exception occurred invoking method " + methodName
1146:                            + typeList(arguments), t);
1147:                }
1148:            }
1149:
1150:            /**
1151:             * Inner class representing an illegal operation.
1152:             **/
1153:            public static class IllegalOperationException extends
1154:                    JPOXUserException {
1155:                /**
1156:                 * Constructor
1157:                 * @param operation the operation. It may include a descriptive localised error message
1158:                 * @param operand the operand
1159:                 */
1160:                public IllegalOperationException(String operation,
1161:                        ScalarExpression operand) {
1162:                    super ("Cannot perform operation \"" + operation + "\" on "
1163:                            + operand);
1164:                }
1165:
1166:                /**
1167:                 * Constructor
1168:                 * @param operation the operation. It may include a descriptive error message
1169:                 * @param operand1 the left-hand operand
1170:                 * @param operand2 the right-hand operand
1171:                 */
1172:                public IllegalOperationException(ScalarExpression operand1,
1173:                        String operation, ScalarExpression operand2) {
1174:                    super ("Cannot perform operation \"" + operation + "\" on "
1175:                            + operand1 + " and " + operand2);
1176:                }
1177:            }
1178:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.