001: /**********************************************************************
002: Copyright (c) 2003 Erik Bengtson 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: 2004 Andy Jefferson - coding standards
017: ...
018: **********************************************************************/package org.jpox.store.query;
019:
020: import java.util.Collection;
021: import java.util.Iterator;
022:
023: import org.jpox.FetchPlan;
024: import org.jpox.ObjectManager;
025: import org.jpox.exceptions.JPOXException;
026: import org.jpox.store.DatastoreIdentifier;
027: import org.jpox.store.expression.BooleanExpression;
028: import org.jpox.store.expression.QueryExpression;
029: import org.jpox.store.expression.ScalarExpression;
030: import org.jpox.store.mapping.JavaTypeMapping;
031: import org.jpox.util.Localiser;
032:
033: /**
034: * Collection for candidates passed to the query by setCandidates(collection).
035: *
036: * @version $Revision: 1.14 $
037: */
038: public class CollectionCandidates implements Queryable {
039: protected static final Localiser LOCALISER = Localiser
040: .getInstance("org.jpox.store.Localisation");
041:
042: /** User-specified collection of possible candidates. */
043: private Collection userCandidates;
044:
045: /** Extent for the candidate class. */
046: private org.jpox.store.Extent extent;
047:
048: /**
049: * Constructor.
050: * @param om Object Manager
051: * @param candidateClass the Class candidate
052: * @param candidates The candidates
053: */
054: public CollectionCandidates(ObjectManager om, Class candidateClass,
055: Collection candidates) {
056: if (candidates == null) {
057: throw new JPOXException(LOCALISER.msg("021072")).setFatal();
058: }
059:
060: this .userCandidates = candidates;
061: this .extent = om.getExtent(candidateClass, true);
062: }
063:
064: /**
065: * @return Returns the userCandidates.
066: */
067: public Collection getUserCandidates() {
068: return userCandidates;
069: }
070:
071: /**
072: * Accessor for the fetch plan
073: * @return The fetch plan
074: */
075: public FetchPlan getFetchPlan() {
076: return extent.getFetchPlan();
077: }
078:
079: /**
080: * Accessor for a new Query statement.
081: * @return The Query Statement
082: */
083: public QueryExpression newQueryStatement() {
084: return ((Queryable) extent).newQueryStatement();
085: }
086:
087: /**
088: * Creates a QueryStatement. The elements that are ALLOWED to be returned
089: * after quering the database are the set of elements contained in the candidate collection.
090: * @param candidateClass Candidate class
091: * @param candidateAlias Alias to use for the candidate in the query (if the native query supports it)
092: * @return Query Statement
093: */
094: public QueryExpression newQueryStatement(Class candidateClass,
095: DatastoreIdentifier candidateAlias) {
096: QueryExpression stmt = ((Queryable) extent).newQueryStatement(
097: candidateClass, candidateAlias);
098: ObjectManager om = extent.getObjectManager();
099: JavaTypeMapping m = om.getStoreManager().getDatastoreClass(
100: candidateClass.getName(), om.getClassLoaderResolver())
101: .getIDMapping();
102:
103: /*
104: * creates a query like WHERE ... AND (CANDIDATE_ID = ?1 OR CANDIDATE_ID =
105: * ?2) or for classes with composite primary keys WHERE ... AND (
106: * (CANDIDATE_IDa = ?1a AND CANDIDATE_IDb = ?1b) OR (CANDIDATE_IDa = ?2a
107: * AND CANDIDATE_IDb = ?2b) )
108: */
109: BooleanExpression elementsExpr = null;
110: for (Iterator it = userCandidates.iterator(); it.hasNext();) {
111: Object candidateValue = it.next();
112: ScalarExpression expr = m.newScalarExpression(stmt, stmt
113: .getMainTableExpression());
114: BooleanExpression keyExpr = expr.eq(m.newLiteral(stmt,
115: candidateValue));
116: if (elementsExpr == null) {
117: elementsExpr = keyExpr;
118: } else {
119: elementsExpr = elementsExpr.ior(keyExpr);
120: }
121: }
122: if (elementsExpr != null) {
123: stmt.andCondition(elementsExpr, true);
124: }
125: return stmt;
126: }
127:
128: /* (non-Javadoc)
129: * @see org.jpox.store.query.Queryable#newResultObjectFactory(org.jpox.store.QueryStatement, boolean)
130: */
131: public ResultObjectFactory newResultObjectFactory(
132: QueryExpression stmt, boolean ignoreCache,
133: Class resultClass, boolean useFetchPlan) {
134: return ((Queryable) extent).newResultObjectFactory(stmt,
135: ignoreCache, resultClass, useFetchPlan);
136: }
137:
138: /**
139: * Returns <tt>true</tt> if this collection contains no elements.<p>
140: * @return <tt>true</tt> if this collection contains no elements.
141: */
142: public boolean isEmpty() {
143: return userCandidates.isEmpty();
144: }
145: }
|