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: Contributors:
016: 2003 Erik Bengtson - removed ununsed imports
017: 2003 Andy Jefferson - coding standards
018: 2004 Andy Jefferson - renamed from SetLiteral
019: ...
020: **********************************************************************/package org.jpox.store.expression;
021:
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import org.jpox.store.DatastoreAdapter;
028: import org.jpox.store.mapping.JavaTypeMapping;
029:
030: /**
031: * An SQL expression that will test if a column of a table falls within the
032: * given Collection of values. This is used for Querys where a transient
033: * Collection is passed in as a parameter.
034: *
035: * @version $Revision: 1.11 $
036: */
037: public class CollectionLiteral extends ScalarExpression {
038: private final boolean isEmpty;
039: private final boolean containsNull;
040: private final DatastoreAdapter dba;
041: /** ScalarExpressions for all elements in the Collection **/
042: private List scalarExpressions;
043:
044: /**
045: * Constructor.
046: * @param qs The QueryStatement the CollectionLiteral will be used in.
047: * @param value The transient Collection that is the value.
048: * @param mapping The mapping to the Collection
049: */
050: public CollectionLiteral(QueryExpression qs,
051: JavaTypeMapping mapping, Collection value) {
052: super (qs);
053:
054: this .mapping = mapping;
055: containsNull = (value != null) && value.contains(null);
056: dba = qs.getStoreManager().getDatastoreAdapter();
057:
058: /*
059: * We'll consider the Collection to be empty if it is null, is really
060: * empty, or only contains null.
061: * If it contains null we need a special case when creating the SQL.
062: */
063: isEmpty = (value == null) || (value.isEmpty())
064: || (value.size() == 1 && containsNull);
065:
066: // If the Collection is empty, don't build the list of SQLExpressions.
067: if (!isEmpty) {
068: scalarExpressions = new ArrayList();
069: st.append("(");
070:
071: boolean hadPrev = false;
072:
073: for (Iterator it = value.iterator(); it.hasNext();) {
074: Object current = it.next();
075: if (current != null) {
076: JavaTypeMapping m = dba.getMapping(current
077: .getClass(), qs.getStoreManager(), qs
078: .getClassLoaderResolver());
079: ScalarExpression expr = m.newLiteral(qs, current);
080:
081: // Append the SQLExpression (should be a literal) for the
082: // current element.
083: st.append(hadPrev ? "," : "");
084: st.append(expr);
085: scalarExpressions.add(expr);
086:
087: hadPrev = true;
088: }
089: }
090:
091: st.append(")");
092: }
093: }
094:
095: /**
096: * Method to check the containing of an element.
097: * Return the BooleanExpression that results from
098: * CollectionLiteral.contains(SQLExpression).
099: *
100: * @param expr The SQLExpression that is checked for membership in the
101: * Collection
102: * @return The BooleanExpression that results from
103: * CollectionLiteral.contains(SQLExpression).
104: */
105: public BooleanExpression containsMethod(ScalarExpression expr) {
106: if (isEmpty) {
107: return new BooleanLiteral(qs, mapping, false);
108: }
109: BooleanExpression bExpr = null;
110: for (int i = 0; i < scalarExpressions.size(); i++) {
111: if (bExpr == null) {
112: bExpr = ((ScalarExpression) scalarExpressions.get(i))
113: .eq(expr);
114: } else {
115: bExpr = bExpr.ior(((ScalarExpression) scalarExpressions
116: .get(i)).eq(expr));
117: }
118: }
119: bExpr.encloseWithInParentheses();
120: return bExpr;
121: }
122:
123: /**
124: * Method to check for emptiness of the collection.
125: * @return The BooleanExpression.
126: **/
127: public BooleanExpression isEmptyMethod() {
128: return new BooleanLiteral(qs, mapping, isEmpty);
129: }
130: }
|