1 package org.apache.ojb.broker.accesslayer; 2 3 17 18 import java.lang.reflect.Array ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.HashMap ; 22 import java.util.HashSet ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 26 import org.apache.ojb.broker.Identity; 27 import org.apache.ojb.broker.ManageableCollection; 28 import org.apache.ojb.broker.OJBRuntimeException; 29 import org.apache.ojb.broker.PersistenceBroker; 30 import org.apache.ojb.broker.IdentityFactory; 31 import org.apache.ojb.broker.core.PersistenceBrokerImpl; 32 import org.apache.ojb.broker.core.proxy.CollectionProxyDefaultImpl; 33 import org.apache.ojb.broker.core.proxy.ProxyHelper; 34 import org.apache.ojb.broker.metadata.ClassDescriptor; 35 import org.apache.ojb.broker.metadata.CollectionDescriptor; 36 import org.apache.ojb.broker.metadata.FieldHelper; 37 import org.apache.ojb.broker.metadata.MetadataException; 38 import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor; 39 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; 40 import org.apache.ojb.broker.query.Query; 41 import org.apache.ojb.broker.query.QueryByCriteria; 42 import org.apache.ojb.broker.util.BrokerHelper; 43 import org.apache.ojb.broker.util.collections.RemovalAwareCollection; 44 import org.apache.ojb.broker.util.collections.RemovalAwareList; 45 import org.apache.ojb.broker.util.collections.RemovalAwareSet; 46 47 53 public class CollectionPrefetcher extends RelationshipPrefetcherImpl 54 { 55 56 62 public CollectionPrefetcher(PersistenceBrokerImpl aBroker, ObjectReferenceDescriptor anOrd) 63 { 64 super(aBroker, anOrd); 65 } 66 67 72 protected Query[] buildPrefetchQueries(Collection owners, Collection children) 73 { 74 ClassDescriptor cld = getOwnerClassDescriptor(); 75 Class topLevelClass = getBroker().getTopLevelClass(cld.getClassOfObject()); 76 BrokerHelper helper = getBroker().serviceBrokerHelper(); 77 Collection queries = new ArrayList (owners.size()); 78 Collection idsSubset = new HashSet (owners.size()); 79 Object [] fkValues; 80 Object owner; 81 Identity id; 82 83 Iterator iter = owners.iterator(); 84 while (iter.hasNext()) 85 { 86 owner = iter.next(); 87 fkValues = helper.extractValueArray(helper.getKeyValues(cld, owner)); 88 id = getBroker().serviceIdentity().buildIdentity(null, topLevelClass, fkValues); 89 idsSubset.add(id); 90 if (idsSubset.size() == pkLimit) 91 { 92 queries.add(buildPrefetchQuery(idsSubset)); 93 idsSubset.clear(); 94 } 95 } 96 97 if (idsSubset.size() > 0) 98 { 99 queries.add(buildPrefetchQuery(idsSubset)); 100 } 101 102 return (Query[]) queries.toArray(new Query[queries.size()]); 103 } 104 105 110 protected Query buildPrefetchQuery(Collection ids) 111 { 112 CollectionDescriptor cds = getCollectionDescriptor(); 113 QueryByCriteria query = buildPrefetchQuery(ids, cds.getForeignKeyFieldDescriptors(getItemClassDescriptor())); 114 115 if (!cds.getOrderBy().isEmpty()) 117 { 118 Iterator iter = cds.getOrderBy().iterator(); 119 while (iter.hasNext()) 120 { 121 query.addOrderBy((FieldHelper) iter.next()); 122 } 123 } 124 125 return query; 126 } 127 128 131 protected void associateBatched(Collection owners, Collection children) 132 { 133 CollectionDescriptor cds = getCollectionDescriptor(); 134 PersistentField field = cds.getPersistentField(); 135 PersistenceBroker pb = getBroker(); 136 Class ownerTopLevelClass = pb.getTopLevelClass(getOwnerClassDescriptor().getClassOfObject()); 137 Class collectionClass = cds.getCollectionClass(); HashMap ownerIdsToLists = new HashMap (owners.size()); 139 140 IdentityFactory identityFactory = pb.serviceIdentity(); 141 for (Iterator it = owners.iterator(); it.hasNext();) 143 { 144 Object owner = it.next(); 145 ownerIdsToLists.put(identityFactory.buildIdentity(getOwnerClassDescriptor(), owner), new ArrayList ()); 146 } 147 148 for (Iterator it = children.iterator(); it.hasNext();) 150 { 151 Object child = it.next(); 152 ClassDescriptor cld = getDescriptorRepository().getDescriptorFor(ProxyHelper.getRealClass(child)); 154 155 Object [] fkValues = cds.getForeignKeyValues(child, cld); 156 Identity ownerId = identityFactory.buildIdentity(null, ownerTopLevelClass, fkValues); 157 List list = (List ) ownerIdsToLists.get(ownerId); 158 if (list != null) 159 { 160 list.add(child); 161 } 162 } 163 164 for (Iterator it = owners.iterator(); it.hasNext();) 166 { 167 Object result; 168 Object owner = it.next(); 169 Identity ownerId = identityFactory.buildIdentity(owner); 170 List list = (List ) ownerIdsToLists.get(ownerId); 171 172 if ((collectionClass == null) && field.getType().isArray()) 173 { 174 int length = list.size(); 175 Class itemtype = field.getType().getComponentType(); 176 result = Array.newInstance(itemtype, length); 177 for (int j = 0; j < length; j++) 178 { 179 Array.set(result, j, list.get(j)); 180 } 181 } 182 else 183 { 184 ManageableCollection col = createCollection(cds, collectionClass); 185 for (Iterator it2 = list.iterator(); it2.hasNext();) 186 { 187 col.ojbAdd(it2.next()); 188 } 189 result = col; 190 } 191 192 Object value = field.get(owner); 193 if ((value instanceof CollectionProxyDefaultImpl) && (result instanceof Collection )) 194 { 195 ((CollectionProxyDefaultImpl) value).setData((Collection ) result); 196 } 197 else 198 { 199 field.set(owner, result); 200 } 201 } 202 } 203 204 213 protected ManageableCollection createCollection(CollectionDescriptor desc, Class collectionClass) 214 { 215 Class fieldType = desc.getPersistentField().getType(); 216 ManageableCollection col; 217 218 if (collectionClass == null) 219 { 220 if (ManageableCollection.class.isAssignableFrom(fieldType)) 221 { 222 try 223 { 224 col = (ManageableCollection)fieldType.newInstance(); 225 } 226 catch (Exception e) 227 { 228 throw new OJBRuntimeException("Cannot instantiate the default collection type "+fieldType.getName()+" of collection "+desc.getAttributeName()+" in type "+desc.getClassDescriptor().getClassNameOfObject()); 229 } 230 } 231 else if (fieldType.isAssignableFrom(RemovalAwareCollection.class)) 232 { 233 col = new RemovalAwareCollection(); 234 } 235 else if (fieldType.isAssignableFrom(RemovalAwareList.class)) 236 { 237 col = new RemovalAwareList(); 238 } 239 else if (fieldType.isAssignableFrom(RemovalAwareSet.class)) 240 { 241 col = new RemovalAwareSet(); 242 } 243 else 244 { 245 throw new MetadataException("Cannot determine a default collection type for collection "+desc.getAttributeName()+" in type "+desc.getClassDescriptor().getClassNameOfObject()); 246 } 247 } 248 else 249 { 250 try 251 { 252 col = (ManageableCollection)collectionClass.newInstance(); 253 } 254 catch (Exception e) 255 { 256 throw new OJBRuntimeException("Cannot instantiate the collection class "+collectionClass.getName()+" of collection "+desc.getAttributeName()+" in type "+desc.getClassDescriptor().getClassNameOfObject()); 257 } 258 } 259 return col; 260 } 261 262 protected CollectionDescriptor getCollectionDescriptor() 263 { 264 return (CollectionDescriptor) getObjectReferenceDescriptor(); 265 } 266 } 267 | Popular Tags |