1 package org.apache.ojb.broker.accesslayer;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Iterator;
21
22 import org.apache.ojb.broker.Identity;
23 import org.apache.ojb.broker.PersistenceBrokerFactory;
24 import org.apache.ojb.broker.core.PersistenceBrokerConfiguration;
25 import org.apache.ojb.broker.core.PersistenceBrokerImpl;
26 import org.apache.ojb.broker.metadata.ClassDescriptor;
27 import org.apache.ojb.broker.metadata.DescriptorRepository;
28 import org.apache.ojb.broker.metadata.FieldDescriptor;
29 import org.apache.ojb.broker.query.Criteria;
30 import org.apache.ojb.broker.query.Query;
31 import org.apache.ojb.broker.query.QueryByCriteria;
32 import org.apache.ojb.broker.query.QueryFactory;
33 import org.apache.ojb.broker.util.configuration.ConfigurationException;
34 import org.apache.ojb.broker.util.logging.Logger;
35 import org.apache.ojb.broker.util.logging.LoggerFactory;
36
37
38
39
40
41
42 public abstract class BasePrefetcher implements RelationshipPrefetcher
43 {
44
45 protected static final int IN_LIMIT = getPrefetchInLimit();
46
47 private Logger logger;
48 private PersistenceBrokerImpl broker;
49
50 protected ClassDescriptor itemClassDesc;
51
52 protected final int pkLimit;
53
54
55
56
57
58
59 private static int getPrefetchInLimit()
60 {
61 try
62 {
63 PersistenceBrokerConfiguration config = (PersistenceBrokerConfiguration) PersistenceBrokerFactory.getConfigurator().getConfigurationFor(null);
64
65 return config.getSqlInLimit();
66 }
67 catch (ConfigurationException e)
68 {
69 return 200;
70 }
71 }
72
73
74
75
76 public BasePrefetcher(PersistenceBrokerImpl aBroker, Class anItemClass)
77 {
78 super();
79 broker = aBroker;
80 itemClassDesc = aBroker.getDescriptorRepository().getDescriptorFor(anItemClass);
81 logger = LoggerFactory.getLogger(this.getClass());
82 pkLimit = getPrefetchInLimit() / getItemClassDescriptor().getPkFields().length;
83 }
84
85
86
87
88 public int getLimit()
89 {
90 return pkLimit;
91 }
92
93
94
95
96 protected abstract void associateBatched(Collection owners, Collection children);
97
98
99
100
101 public void prefetchRelationship(Collection owners)
102 {
103 Query queries[];
104 Collection children = new ArrayList();
105
106 queries = buildPrefetchQueries(owners, children);
107
108 for (int i = 0; i < queries.length; i++)
109 {
110 Iterator iter = getBroker().getIteratorByQuery(queries[i]);
111 while (iter.hasNext())
112 {
113 children.add(iter.next());
114 }
115 }
116
117
118
119 getBroker().getReferenceBroker().performRetrievalTasks();
120
121 associateBatched(owners, children);
122 }
123
124
125 protected QueryByCriteria buildPrefetchQuery(Collection ids, FieldDescriptor[] fields)
126 {
127 return buildPrefetchQuery(getItemClassDescriptor().getClassOfObject(), ids, fields);
128 }
129
130
131
132
133
134
135
136
137 protected Criteria buildPrefetchCriteria(Collection ids, FieldDescriptor[] fields)
138 {
139 if (fields.length == 1)
140 {
141 return buildPrefetchCriteriaSingleKey(ids, fields[0]);
142 }
143 else
144 {
145 return buildPrefetchCriteriaMultipleKeys(ids, fields);
146 }
147
148 }
149
150
151
152
153
154
155
156
157 protected QueryByCriteria buildPrefetchQuery(Class clazz, Collection ids, FieldDescriptor[] fields)
158 {
159 return QueryFactory.newQuery(clazz, buildPrefetchCriteria(ids, fields));
160 }
161
162
163
164
165
166
167
168 private Criteria buildPrefetchCriteriaSingleKey(Collection ids, FieldDescriptor field)
169 {
170 Criteria crit = new Criteria();
171 ArrayList values = new ArrayList(ids.size());
172 Iterator iter = ids.iterator();
173 Identity id;
174
175 while (iter.hasNext())
176 {
177 id = (Identity) iter.next();
178 values.add(id.getPrimaryKeyValues()[0]);
179 }
180
181 switch (values.size())
182 {
183 case 0:
184 break;
185 case 1:
186 crit.addEqualTo(field.getAttributeName(), values.get(0));
187 break;
188 default:
189
190 crit.addIn(field.getAttributeName(), values);
191 break;
192 }
193
194 return crit;
195 }
196
197
198
199
200
201
202
203 private Criteria buildPrefetchCriteriaMultipleKeys(Collection ids, FieldDescriptor fields[])
204 {
205 Criteria crit = new Criteria();
206 Iterator iter = ids.iterator();
207 Object[] val;
208 Identity id;
209
210 while (iter.hasNext())
211 {
212 Criteria c = new Criteria();
213 id = (Identity) iter.next();
214 val = id.getPrimaryKeyValues();
215 for (int i = 0; i < val.length; i++)
216 {
217 if (val[i] == null)
218 {
219 c.addIsNull(fields[i].getAttributeName());
220 }
221 else
222 {
223 c.addEqualTo(fields[i].getAttributeName(), val[i]);
224 }
225 }
226 crit.addOrCriteria(c);
227 }
228
229 return crit;
230 }
231
232
233
234
235 protected DescriptorRepository getDescriptorRepository()
236 {
237 return getBroker().getDescriptorRepository();
238 }
239
240
241
242
243
244 public ClassDescriptor getItemClassDescriptor()
245 {
246 return itemClassDesc;
247 }
248
249 protected abstract Query[] buildPrefetchQueries(Collection owners, Collection children);
250
251
252
253
254
255 protected PersistenceBrokerImpl getBroker()
256 {
257 return broker;
258 }
259
260
261
262
263
264 protected Logger getLogger()
265 {
266 return logger;
267 }
268 }