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.HashMap;
21 import java.util.HashSet;
22 import java.util.Iterator;
23
24 import org.apache.ojb.broker.Identity;
25 import org.apache.ojb.broker.PersistenceBroker;
26 import org.apache.ojb.broker.cache.ObjectCache;
27 import org.apache.ojb.broker.core.PersistenceBrokerImpl;
28 import org.apache.ojb.broker.metadata.ClassDescriptor;
29 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
30 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
31 import org.apache.ojb.broker.query.Query;
32
33
34
35
36
37
38
39 public class ReferencePrefetcher extends RelationshipPrefetcherImpl
40 {
41
42
43
44
45
46
47 public ReferencePrefetcher(PersistenceBrokerImpl aBroker, ObjectReferenceDescriptor anOrd)
48 {
49 super(aBroker, anOrd);
50 }
51
52
53
54
55
56 protected void associateBatched(Collection owners, Collection children)
57 {
58 ObjectReferenceDescriptor ord = getObjectReferenceDescriptor();
59 ClassDescriptor cld = getOwnerClassDescriptor();
60 Object owner;
61 Object relatedObject;
62 Object fkValues[];
63 Identity id;
64 PersistenceBroker pb = getBroker();
65 PersistentField field = ord.getPersistentField();
66 Class topLevelClass = pb.getTopLevelClass(ord.getItemClass());
67 HashMap childrenMap = new HashMap(children.size());
68
69
70 for (Iterator it = children.iterator(); it.hasNext(); )
71 {
72 relatedObject = it.next();
73 childrenMap.put(pb.serviceIdentity().buildIdentity(relatedObject), relatedObject);
74 }
75
76 for (Iterator it = owners.iterator(); it.hasNext(); )
77 {
78 owner = it.next();
79 fkValues = ord.getForeignKeyValues(owner,cld);
80 if (isNull(fkValues))
81 {
82 field.set(owner, null);
83 continue;
84 }
85 id = pb.serviceIdentity().buildIdentity(null, topLevelClass, fkValues);
86 relatedObject = childrenMap.get(id);
87 field.set(owner, relatedObject);
88 }
89 }
90
91 private boolean isNull(Object[] arr)
92 {
93 for (int i = 0; i < arr.length; i++)
94 {
95 if (arr[i] != null)
96 {
97 return false;
98 }
99 }
100 return true;
101 }
102
103
104
105
106
107
108 protected Query[] buildPrefetchQueries(Collection owners, Collection children)
109 {
110 ClassDescriptor cld = getOwnerClassDescriptor();
111 ObjectReferenceDescriptor ord = getObjectReferenceDescriptor();
112 Collection queries = new ArrayList(owners.size());
113 Collection idsSubset = new HashSet(owners.size());
114 Iterator iter = owners.iterator();
115 Class topLevelClass = getBroker().getTopLevelClass(ord.getItemClass());
116 Object[] fkValues;
117 Object owner;
118 Identity id;
119 PersistenceBroker pb = getBroker();
120 ObjectCache cache = pb.serviceObjectCache();
121
122 while (iter.hasNext())
123 {
124 owner = iter.next();
125 fkValues = ord.getForeignKeyValues(owner,cld);
126 if (isNull(fkValues))
127 {
128 continue;
129 }
130 id = pb.serviceIdentity().buildIdentity(null, topLevelClass, fkValues);
131 if (cache.lookup(id) != null)
132 {
133 children.add(pb.getObjectByIdentity(id));
134 continue;
135 }
136 idsSubset.add(id);
137 if (idsSubset.size() == pkLimit)
138 {
139 queries.add(buildPrefetchQuery(idsSubset));
140 idsSubset.clear();
141 }
142 }
143
144 if (idsSubset.size() > 0)
145 {
146 queries.add(buildPrefetchQuery(idsSubset));
147 }
148
149 return (Query[]) queries.toArray(new Query[queries.size()]);
150 }
151
152
153
154
155 protected Query buildPrefetchQuery(Collection ids)
156 {
157 return buildPrefetchQuery(ids, getItemClassDescriptor().getPkFields());
158 }
159 }