001: /**********************************************************************
002: Copyright (c) 2002 Kelly Grizzle (TJDO) and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: 2002 Mike Martin (TJDO)
018: 2003 Andy Jefferson - coding standards
019: ...
020: **********************************************************************/package org.jpox.store.expression;
021:
022: import org.jpox.store.mapping.JavaTypeMapping;
023:
024: /**
025: * Representation of a Boolean expression in a Query.
026: *
027: * @version $Revision: 1.12 $
028: **/
029: public class BooleanExpression extends ScalarExpression {
030: /**
031: * Constructor
032: * @param qs the QueryExpression
033: */
034: protected BooleanExpression(QueryExpression qs) {
035: super (qs);
036: }
037:
038: /**
039: *
040: * @param qs the QueryExpression
041: * @param mapping the mapping associated to this expression
042: * @param te the TableExpression where this expression refers to
043: */
044: public BooleanExpression(QueryExpression qs,
045: JavaTypeMapping mapping, LogicSetExpression te) {
046: super (qs, mapping, te);
047: }
048:
049: /**
050: * Perform a boolean operator <code>op</code> on a operand <code>operand</code>
051: * @param op the operator
052: * @param operand the operand
053: */
054: public BooleanExpression(MonadicOperator op,
055: ScalarExpression operand) {
056: super (op, operand);
057: }
058:
059: /**
060: * Perform a boolean operator <code>op</code> between two operands <code>operand1</code> and <code>operand2</code>
061: * @param op the operator
062: * @param operand1 the operand
063: * @param operand2 the operand
064: */
065: public BooleanExpression(ScalarExpression operand1,
066: DyadicOperator op, ScalarExpression operand2) {
067: super (operand1, op, operand2);
068: }
069:
070: public BooleanExpression and(ScalarExpression expr) {
071: if (expr instanceof BooleanLiteral) {
072: return expr.and(this );
073: } else if (expr instanceof ExistsExpression
074: && !(this instanceof ExistsExpression)) {
075: // WHERE ... && fld.contains(...)
076: boolean existsIncludesAll = false;
077: Object ext = expr.qs
078: .getValueForExtension("org.jpox.rdbms.jdoql.existsIncludesConstraints");
079: if (ext != null && ((String) ext).equals("true")) {
080: existsIncludesAll = true;
081: }
082: if (existsIncludesAll) {
083: // e.g 1. SELECT FROM MyClass WHERE fld1.contains(val1) && val1.name == 'some value'
084: // with this will result in the val1.name constraint being applied to the EXISTS - correct
085: // e.g 2. SELECT FROM MyClass WHERE fld1 == val1 && (fld2.contains(val2) && val2.name == 'some value')
086: // with this will result in the "fld1 == val1" being applied to the EXISTS too - wrong
087: // This is a hack for some queries
088: return expr.and(this );
089: } else {
090: // e.g 1. SELECT FROM MyClass WHERE fld1.contains(val1) && val1.name == 'some value'
091: // will result in val1.name being outside the EXISTS - wrong
092: // e.g 2. SELECT FROM MyClass WHERE fld1 == val1 && (fld2.contains(val2) && val2.name == 'some value')
093: // will result in the "fld1 == val1" being outside the EXISTS - correct
094: }
095: }
096:
097: if (expr instanceof BooleanExpression) {
098: return new BooleanExpression(this , OP_AND, expr);
099: } else {
100: return super .and(expr);
101: }
102: }
103:
104: public BooleanExpression eor(ScalarExpression expr) {
105: if (expr instanceof BooleanLiteral) {
106: return expr.eor(this );
107: } else if (expr instanceof ExistsExpression) {
108: return expr.eor(this );
109: } else if (expr instanceof BooleanExpression) {
110: if (qs.getStoreManager().getDatastoreAdapter()
111: .supportsBooleanComparison()) {
112: return new BooleanExpression(this , OP_NOTEQ, expr);
113: } else {
114: return and(expr.not()).ior(not().and(expr));
115: }
116: } else {
117: return super .eor(expr);
118: }
119: }
120:
121: public BooleanExpression ior(ScalarExpression expr) {
122: if (expr instanceof BooleanLiteral) {
123: return expr.ior(this );
124: } else if (expr instanceof BooleanExpression) {
125: return new BooleanExpression(this , OP_OR, expr);
126: } else {
127: return super .ior(expr);
128: }
129: }
130:
131: public BooleanExpression not() {
132: return new BooleanExpression(OP_NOT, this );
133: }
134:
135: public BooleanExpression eq(ScalarExpression expr) {
136: assertValidTypeForParameterComparison(expr,
137: BooleanExpression.class);
138:
139: if (expr instanceof BooleanLiteral
140: || expr instanceof NullLiteral) {
141: return expr.eq(this );
142: } else if (expr instanceof BooleanExpression) {
143: if (qs.getStoreManager().getDatastoreAdapter()
144: .supportsBooleanComparison()) {
145: return new BooleanExpression(this , OP_EQ, expr);
146: } else {
147: return and(expr).ior(not().and(expr.not()));
148: }
149: } else {
150: return super .eq(expr);
151: }
152: }
153:
154: public BooleanExpression noteq(ScalarExpression expr) {
155: assertValidTypeForParameterComparison(expr,
156: BooleanExpression.class);
157:
158: if (expr instanceof BooleanLiteral
159: || expr instanceof NullLiteral) {
160: return expr.noteq(this );
161: } else if (expr instanceof BooleanExpression) {
162: if (qs.getStoreManager().getDatastoreAdapter()
163: .supportsBooleanComparison()) {
164: return new BooleanExpression(this , OP_NOTEQ, expr);
165: } else {
166: return and(expr.not()).ior(not().and(expr));
167: }
168: } else {
169: return super .noteq(expr);
170: }
171: }
172:
173: public BooleanExpression in(ScalarExpression expr) {
174: return new BooleanExpression(this , OP_IN, expr);
175: }
176:
177: public ScalarExpression neg() {
178: return new NumericExpression(OP_NEG, this);
179: }
180: }
|