001: package org.apache.ojb.broker.accesslayer;
002:
003: /* Copyright 2003-2005 The Apache Software Foundation
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.HashMap;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.Map;
024:
025: import org.apache.ojb.broker.Identity;
026: import org.apache.ojb.broker.PersistenceBroker;
027: import org.apache.ojb.broker.cache.ObjectCache;
028: import org.apache.ojb.broker.core.PersistenceBrokerImpl;
029: import org.apache.ojb.broker.core.proxy.IndirectionHandler;
030: import org.apache.ojb.broker.core.proxy.ProxyHelper;
031: import org.apache.ojb.broker.query.Query;
032:
033: /**
034: * Prefetcher for plain list of objects (no relations).
035: *
036: * @author <a href="mailto:olegnitz@apache.org">Oleg Nitz</a>
037: * @version $Id: PlainPrefetcher.java,v 1.9.2.2 2005/12/21 22:22:58 tomdz Exp $
038: */
039: public class PlainPrefetcher extends BasePrefetcher {
040:
041: public PlainPrefetcher(PersistenceBrokerImpl aBroker,
042: Class anItemClass) {
043: super (aBroker, anItemClass);
044: }
045:
046: public void prepareRelationshipSettings() {
047: // no op
048: }
049:
050: public void restoreRelationshipSettings() {
051: // no op
052: }
053:
054: protected void associateBatched(Collection proxies,
055: Collection realSubjects) {
056: PersistenceBroker pb = getBroker();
057: IndirectionHandler handler;
058: Identity id;
059: Object proxy;
060: Object realSubject;
061: HashMap realSubjectsMap = new HashMap(realSubjects.size());
062:
063: for (Iterator it = realSubjects.iterator(); it.hasNext();) {
064: realSubject = it.next();
065: realSubjectsMap.put(pb.serviceIdentity().buildIdentity(
066: realSubject), realSubject);
067: }
068:
069: for (Iterator it = proxies.iterator(); it.hasNext();) {
070: proxy = it.next();
071: handler = ProxyHelper.getIndirectionHandler(proxy);
072:
073: if (handler == null) {
074: continue;
075: }
076:
077: id = handler.getIdentity();
078: realSubject = realSubjectsMap.get(id);
079: if (realSubject != null) {
080: handler.setRealSubject(realSubject);
081: }
082: }
083: }
084:
085: /**
086: * Build the multiple queries for one relationship because of limitation of IN(...)
087: * @param proxies Collection containing all proxy objects to load
088: * @param realSubjects Collection where real subjects found in the cache should be added.
089: */
090: protected Query[] buildPrefetchQueries(Collection proxies,
091: Collection realSubjects) {
092: Collection queries = new ArrayList();
093: Collection idsSubset;
094: Object proxy;
095: IndirectionHandler handler;
096: Identity id;
097: Class realClass;
098: HashMap classToIds = new HashMap();
099: Class topLevelClass = getItemClassDescriptor()
100: .getClassOfObject();
101: PersistenceBroker pb = getBroker();
102: ObjectCache cache = pb.serviceObjectCache();
103:
104: for (Iterator it = proxies.iterator(); it.hasNext();) {
105: proxy = it.next();
106: handler = ProxyHelper.getIndirectionHandler(proxy);
107:
108: if (handler == null) {
109: continue;
110: }
111:
112: id = handler.getIdentity();
113: if (cache.lookup(id) != null) {
114: realSubjects.add(pb.getObjectByIdentity(id));
115: continue;
116: }
117: realClass = id.getObjectsRealClass();
118: if (realClass == null) {
119: realClass = Object.class; // to remember that the real class is unknown
120: }
121: idsSubset = (HashSet) classToIds.get(realClass);
122: if (idsSubset == null) {
123: idsSubset = new HashSet();
124: classToIds.put(realClass, idsSubset);
125: }
126: idsSubset.add(id);
127: if (idsSubset.size() == pkLimit) {
128: Query query;
129: if (realClass == Object.class) {
130: query = buildPrefetchQuery(topLevelClass,
131: idsSubset, true);
132: } else {
133: query = buildPrefetchQuery(realClass, idsSubset,
134: false);
135: }
136: queries.add(query);
137: idsSubset.clear();
138: }
139: }
140:
141: for (Iterator it = classToIds.entrySet().iterator(); it
142: .hasNext();) {
143: Map.Entry entry = (Map.Entry) it.next();
144: realClass = (Class) entry.getKey();
145: idsSubset = (HashSet) entry.getValue();
146: if (idsSubset.size() > 0) {
147: Query query;
148: if (realClass == Object.class) {
149: query = buildPrefetchQuery(topLevelClass,
150: idsSubset, true);
151: } else {
152: query = buildPrefetchQuery(realClass, idsSubset,
153: false);
154: }
155: queries.add(query);
156: }
157: }
158:
159: return (Query[]) queries.toArray(new Query[queries.size()]);
160: }
161:
162: protected Query buildPrefetchQuery(Class clazz, Collection ids,
163: boolean withExtents) {
164: Query query = buildPrefetchQuery(clazz, ids,
165: getDescriptorRepository().getDescriptorFor(clazz)
166: .getPkFields());
167: query.setWithExtents(withExtents);
168: return query;
169: }
170: }
|