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.1 2007-08-24 22:17:30 ewestfal Exp $
038 */
039 public class PlainPrefetcher extends BasePrefetcher
040 {
041
042 public PlainPrefetcher(PersistenceBrokerImpl aBroker, Class anItemClass)
043 {
044 super(aBroker, anItemClass);
045 }
046
047 public void prepareRelationshipSettings()
048 {
049 // no op
050 }
051
052 public void restoreRelationshipSettings()
053 {
054 // no op
055 }
056
057 protected void associateBatched(Collection proxies, Collection realSubjects)
058 {
059 PersistenceBroker pb = getBroker();
060 IndirectionHandler handler;
061 Identity id;
062 Object proxy;
063 Object realSubject;
064 HashMap realSubjectsMap = new HashMap(realSubjects.size());
065
066 for (Iterator it = realSubjects.iterator(); it.hasNext(); )
067 {
068 realSubject = it.next();
069 realSubjectsMap.put(pb.serviceIdentity().buildIdentity(realSubject), realSubject);
070 }
071
072 for (Iterator it = proxies.iterator(); it.hasNext(); )
073 {
074 proxy = it.next();
075 handler = ProxyHelper.getIndirectionHandler(proxy);
076
077 if (handler == null)
078 {
079 continue;
080 }
081
082 id = handler.getIdentity();
083 realSubject = realSubjectsMap.get(id);
084 if (realSubject != null)
085 {
086 handler.setRealSubject(realSubject);
087 }
088 }
089 }
090
091 /**
092 * Build the multiple queries for one relationship because of limitation of IN(...)
093 * @param proxies Collection containing all proxy objects to load
094 * @param realSubjects Collection where real subjects found in the cache should be added.
095 */
096 protected Query[] buildPrefetchQueries(Collection proxies, Collection realSubjects)
097 {
098 Collection queries = new ArrayList();
099 Collection idsSubset;
100 Object proxy;
101 IndirectionHandler handler;
102 Identity id;
103 Class realClass;
104 HashMap classToIds = new HashMap();
105 Class topLevelClass = getItemClassDescriptor().getClassOfObject();
106 PersistenceBroker pb = getBroker();
107 ObjectCache cache = pb.serviceObjectCache();
108
109 for (Iterator it = proxies.iterator(); it.hasNext(); )
110 {
111 proxy = it.next();
112 handler = ProxyHelper.getIndirectionHandler(proxy);
113
114 if (handler == null)
115 {
116 continue;
117 }
118
119 id = handler.getIdentity();
120 if (cache.lookup(id) != null)
121 {
122 realSubjects.add(pb.getObjectByIdentity(id));
123 continue;
124 }
125 realClass = id.getObjectsRealClass();
126 if (realClass == null)
127 {
128 realClass = Object.class; // to remember that the real class is unknown
129 }
130 idsSubset = (HashSet) classToIds.get(realClass);
131 if (idsSubset == null)
132 {
133 idsSubset = new HashSet();
134 classToIds.put(realClass, idsSubset);
135 }
136 idsSubset.add(id);
137 if (idsSubset.size() == pkLimit)
138 {
139 Query query;
140 if (realClass == Object.class)
141 {
142 query = buildPrefetchQuery(topLevelClass, idsSubset, true);
143 }
144 else
145 {
146 query = buildPrefetchQuery(realClass, idsSubset, false);
147 }
148 queries.add(query);
149 idsSubset.clear();
150 }
151 }
152
153 for (Iterator it = classToIds.entrySet().iterator(); it.hasNext(); )
154 {
155 Map.Entry entry = (Map.Entry) it.next();
156 realClass = (Class) entry.getKey();
157 idsSubset = (HashSet) entry.getValue();
158 if (idsSubset.size() > 0)
159 {
160 Query query;
161 if (realClass == Object.class)
162 {
163 query = buildPrefetchQuery(topLevelClass, idsSubset, true);
164 }
165 else
166 {
167 query = buildPrefetchQuery(realClass, idsSubset, false);
168 }
169 queries.add(query);
170 }
171 }
172
173 return (Query[]) queries.toArray(new Query[queries.size()]);
174 }
175
176 protected Query buildPrefetchQuery(Class clazz, Collection ids, boolean withExtents)
177 {
178 Query query = buildPrefetchQuery(clazz, ids,
179 getDescriptorRepository().getDescriptorFor(clazz).getPkFields());
180 query.setWithExtents(withExtents);
181 return query;
182 }
183 }