001: /*
002: * $Id: EntityExpr.java,v 1.3 2004/04/23 01:42:16 doogie Exp $
003: *
004: * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: *
024: */
025: package org.ofbiz.entity.condition;
026:
027: import java.util.Collection;
028: import java.util.Iterator;
029: import java.util.List;
030:
031: import org.ofbiz.entity.GenericEntity;
032: import org.ofbiz.entity.GenericModelException;
033: import org.ofbiz.entity.model.ModelEntity;
034: import org.ofbiz.entity.model.ModelField;
035:
036: /**
037: * Encapsulates simple expressions used for specifying queries
038: *
039: * @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
040: * @version $Revision: 1.4 $
041: * @since 2.0
042: */
043: public class EntityExpr extends EntityCondition {
044:
045: private Object lhs;
046: private boolean leftUpper = false;
047: private EntityOperator operator;
048: private Object rhs;
049: private boolean rightUpper = false;
050:
051: protected EntityExpr() {
052: }
053:
054: public EntityExpr(Object lhs, EntityComparisonOperator operator,
055: Object rhs) {
056: if (lhs == null) {
057: throw new IllegalArgumentException(
058: "The field name cannot be null");
059: }
060: if (operator == null) {
061: throw new IllegalArgumentException(
062: "The operator argument cannot be null");
063: }
064:
065: if (rhs == null) {
066: if (!EntityOperator.NOT_EQUAL.equals(operator)
067: && !EntityOperator.EQUALS.equals(operator)) {
068: throw new IllegalArgumentException(
069: "Operator must be EQUALS or NOT_EQUAL when right/rhs argument is NULL ");
070: }
071: }
072:
073: if (EntityOperator.BETWEEN.equals(operator)) {
074: if (!(rhs instanceof Collection)
075: || (((Collection) rhs).size() != 2)) {
076: throw new IllegalArgumentException(
077: "BETWEEN Operator requires a Collection with 2 elements for the right/rhs argument");
078: }
079: }
080:
081: this .lhs = lhs;
082: this .operator = operator;
083: this .rhs = rhs;
084: }
085:
086: public EntityExpr(String lhs, boolean leftUpper,
087: EntityComparisonOperator operator, Object rhs,
088: boolean rightUpper) {
089: this (lhs, operator, rhs);
090: this .leftUpper = leftUpper;
091: this .rightUpper = rightUpper;
092: }
093:
094: public EntityExpr(EntityCondition lhs, EntityJoinOperator operator,
095: EntityCondition rhs) {
096: if (lhs == null) {
097: throw new IllegalArgumentException(
098: "The left EntityCondition argument cannot be null");
099: }
100: if (rhs == null) {
101: throw new IllegalArgumentException(
102: "The right EntityCondition argument cannot be null");
103: }
104: if (operator == null) {
105: throw new IllegalArgumentException(
106: "The operator argument cannot be null");
107: }
108:
109: this .lhs = lhs;
110: this .operator = operator;
111: this .rhs = rhs;
112: }
113:
114: public void setLUpper(boolean upper) {
115: leftUpper = upper;
116: }
117:
118: public boolean isLUpper() {
119: return leftUpper;
120: }
121:
122: public boolean isRUpper() {
123: return rightUpper;
124: }
125:
126: public void setRUpper(boolean upper) {
127: rightUpper = upper;
128: }
129:
130: public Object getLhs() {
131: return lhs;
132: }
133:
134: public EntityOperator getOperator() {
135: return operator;
136: }
137:
138: public Object getRhs() {
139: return rhs;
140: }
141:
142: public String makeWhereString(ModelEntity modelEntity,
143: List entityConditionParams) {
144: // if (Debug.verboseOn()) Debug.logVerbose("makeWhereString for entity " + modelEntity.getEntityName(), module);
145: StringBuffer whereStringBuffer = new StringBuffer();
146:
147: if (lhs instanceof String) {
148: ModelField field = getField(modelEntity, (String) this
149: .getLhs());
150: String colName = getColName(field, (String) this .getLhs());
151: if (colName != null) {
152: if (this .getRhs() == null) {
153: whereStringBuffer.append(colName);
154: if (EntityOperator.NOT_EQUAL.equals(this
155: .getOperator())) {
156: whereStringBuffer.append(" IS NOT NULL ");
157: } else if (EntityOperator.EQUALS.equals(this
158: .getOperator())) {
159: whereStringBuffer.append(" IS NULL ");
160: } else {
161: throw new IllegalArgumentException(
162: "Operator should be EQUAL or NOT EQUAL when right argument is NULL ");
163: }
164: } else {
165: if (this .isLUpper()) {
166: whereStringBuffer.append("UPPER(" + colName
167: + ")");
168: } else {
169: whereStringBuffer.append(colName);
170: }
171: whereStringBuffer.append(' ');
172: whereStringBuffer.append(this .getOperator()
173: .toString());
174: whereStringBuffer.append(' ');
175:
176: // treat the IN operator as a special case, especially with a Collection rhs
177: if (EntityOperator.IN.equals(this .getOperator())
178: || EntityOperator.NOT_IN.equals(this
179: .getOperator())) {
180: whereStringBuffer.append('(');
181:
182: if (rhs instanceof Collection) {
183: Iterator rhsIter = ((Collection) rhs)
184: .iterator();
185:
186: while (rhsIter.hasNext()) {
187: Object inObj = rhsIter.next();
188:
189: addValue(whereStringBuffer, field,
190: inObj, entityConditionParams);
191:
192: if (rhsIter.hasNext()) {
193: whereStringBuffer.append(", ");
194: }
195:
196: }
197: } else {
198: addValue(whereStringBuffer, field, rhs,
199: entityConditionParams);
200: }
201:
202: whereStringBuffer.append(')');
203: } else if (EntityOperator.BETWEEN.equals(this
204: .getOperator())) {
205: if ((rhs instanceof Collection)
206: && (((Collection) rhs).size() == 2)) {
207: Iterator rhsIter = ((Collection) rhs)
208: .iterator();
209: Object beginObj = rhsIter.next();
210: Object endObj = rhsIter.next();
211:
212: addValue(whereStringBuffer, field,
213: beginObj, entityConditionParams);
214: whereStringBuffer.append(" AND ");
215: addValue(whereStringBuffer, field, endObj,
216: entityConditionParams);
217: } else {
218: throw new IllegalArgumentException(
219: "BETWEEN Operator requires a Collection with 2 elements");
220: }
221: } else {
222: addValue(whereStringBuffer, field, rhs,
223: entityConditionParams);
224: }
225: }
226: } else {
227: throw new IllegalArgumentException(
228: "ModelField with field name "
229: + (String) this .getLhs() + " not found");
230: }
231: } else if (lhs instanceof EntityCondition) {
232: whereStringBuffer.append('(');
233: whereStringBuffer
234: .append(((EntityCondition) lhs).makeWhereString(
235: modelEntity, entityConditionParams));
236: whereStringBuffer.append(") ");
237: whereStringBuffer.append(this .getOperator().toString());
238: whereStringBuffer.append(" (");
239: if (rhs instanceof EntityCondition) {
240: whereStringBuffer.append(((EntityCondition) rhs)
241: .makeWhereString(modelEntity,
242: entityConditionParams));
243: } else {
244: addValue(whereStringBuffer, null, rhs,
245: entityConditionParams);
246: }
247: whereStringBuffer.append(')');
248: }
249: return whereStringBuffer.toString();
250: }
251:
252: public boolean entityMatches(GenericEntity entity) {
253: ModelEntity modelEntity = entity.getModelEntity();
254: if (this .operator instanceof EntityComparisonOperator) {
255: EntityComparisonOperator comparer = (EntityComparisonOperator) this .operator;
256: Object leftValue;
257: if (lhs instanceof String) {
258: leftValue = entity.get((String) lhs);
259: if (this .isLUpper() && leftValue instanceof String) {
260: leftValue = ((String) leftValue).toUpperCase();
261: }
262: } else if (lhs instanceof EntityFunction) {
263: EntityFunction func = (EntityFunction) lhs;
264: leftValue = func.eval(entity);
265: } else {
266: leftValue = lhs;
267: }
268: Object rightValue;
269: if (rhs instanceof EntityFunction) {
270: EntityFunction func = (EntityFunction) rhs;
271: rightValue = func.eval(entity);
272: } else {
273: rightValue = rhs;
274: }
275: if (this .isRUpper() && rightValue instanceof String) {
276: rightValue = ((String) rightValue).toUpperCase();
277: }
278:
279: return comparer.compare(leftValue, rightValue);
280: } else if (lhs instanceof EntityCondition
281: && this .operator instanceof EntityJoinOperator) {
282: EntityJoinOperator joiner = (EntityJoinOperator) this .operator;
283: EntityOperator.MatchResult result = joiner.join(
284: (EntityCondition) lhs, entity);
285: if (!result.shortCircuit) {
286: result = joiner.join((EntityCondition) rhs, entity);
287: }
288: return result.matches;
289: } else {
290: return false;
291: }
292: }
293:
294: public void checkCondition(ModelEntity modelEntity)
295: throws GenericModelException {
296: // if (Debug.verboseOn()) Debug.logVerbose("checkCondition for entity " + modelEntity.getEntityName(), module);
297: if (lhs instanceof String) {
298: if (modelEntity.getField((String) lhs) == null) {
299: throw new GenericModelException("Field with name "
300: + lhs + " not found in the "
301: + modelEntity.getEntityName() + " Entity");
302: }
303: } else if (lhs instanceof EntityCondition) {
304: ((EntityCondition) lhs).checkCondition(modelEntity);
305: ((EntityCondition) rhs).checkCondition(modelEntity);
306: }
307: }
308:
309: protected void addValue(StringBuffer buffer, ModelField field,
310: Object value, List params) {
311: if (this .isRUpper()) {
312: if (value instanceof String) {
313: value = ((String) value).toUpperCase();
314: }
315: }
316: super.addValue(buffer, field, value, params);
317: }
318: }
|