1 56 package org.objectstyle.cayenne.access.util; 57 58 import java.util.ArrayList ; 59 import java.util.HashMap ; 60 import java.util.List ; 61 import java.util.ListIterator ; 62 import java.util.Map ; 63 64 import org.objectstyle.cayenne.CayenneRuntimeException; 65 import org.objectstyle.cayenne.DataObject; 66 import org.objectstyle.cayenne.ObjectId; 67 import org.objectstyle.cayenne.PersistenceState; 68 import org.objectstyle.cayenne.access.DataContext; 69 import org.objectstyle.cayenne.access.ToManyList; 70 import org.objectstyle.cayenne.exp.parser.ASTDbPath; 71 import org.objectstyle.cayenne.exp.parser.ASTIn; 72 import org.objectstyle.cayenne.exp.parser.ASTList; 73 import org.objectstyle.cayenne.map.DbRelationship; 74 import org.objectstyle.cayenne.map.ObjEntity; 75 import org.objectstyle.cayenne.map.ObjRelationship; 76 import org.objectstyle.cayenne.query.SelectQuery; 77 78 84 public class PrefetchHelper { 85 86 89 public static void resolveToOneRelations( 90 DataContext context, 91 List objects, 92 String relName) { 93 94 int len = objects.size(); 95 if (len == 0) { 96 return; 97 } 98 99 List oids = null; 100 101 for (int i = 0; i < len; i++) { 102 DataObject sourceObject = (DataObject) objects.get(i); 103 DataObject targetObject = (DataObject) sourceObject.readProperty(relName); 104 105 if (targetObject.getPersistenceState() == PersistenceState.HOLLOW) { 106 ObjectId oid = targetObject.getObjectId(); 107 108 if (oids == null) { 109 oids = new ArrayList (len); 110 } 111 112 oids.add(oid); 113 } 114 } 115 116 if (oids != null) { 117 SelectQuery sel = QueryUtils.selectQueryForIds(oids); 121 context.performQuery(sel); 122 } 123 } 124 125 135 public static void resolveToManyRelations( 136 DataContext context, 137 List objects, 138 String relName) { 139 140 int nobjects = objects.size(); 141 if (nobjects == 0) 142 return; 143 144 String dbKey = null; 145 Map listMap = new HashMap (nobjects); 146 147 150 for (int i = 0; i < nobjects; i++) { 151 DataObject object = (DataObject) objects.get(i); 152 ObjectId oid = object.getObjectId(); 153 if (dbKey == null) { 154 Map id = oid.getIdSnapshot(); 155 if (id.size() != 1) { 156 throw new CayenneRuntimeException( 157 "resolveToManyRelations expects single keys for now..."); 158 } 159 dbKey = (String ) id.keySet().iterator().next(); 160 } 161 listMap.put(oid.getValueForAttribute(dbKey), new ArrayList ()); 162 } 163 164 ObjEntity ent = context.getEntityResolver().lookupObjEntity( 165 (DataObject) objects.get(0)); 166 ObjRelationship rel = (ObjRelationship) ent.getRelationship(relName); 167 ObjEntity destEnt = (ObjEntity) rel.getTargetEntity(); 168 169 List dbRels = rel.getDbRelationships(); 170 171 if (dbRels == null || dbRels.size() == 0) { 173 throw new CayenneRuntimeException("ObjRelationship '" 174 + rel.getName() 175 + "' is unmapped."); 176 } 177 178 StringBuffer buf = new StringBuffer (); 182 ListIterator it = dbRels.listIterator(dbRels.size()); 183 while (it.hasPrevious()) { 184 if (buf.length() > 0) { 185 buf.append("."); 186 } 187 DbRelationship dbRel = (DbRelationship) it.previous(); 188 DbRelationship reverse = dbRel.getReverseRelationship(); 189 190 if (reverse == null) { 192 throw new CayenneRuntimeException("DbRelatitionship '" 193 + dbRel.getName() 194 + "' has no reverse relationship"); 195 } 196 197 buf.append(reverse.getName()); 198 } 199 200 202 ASTDbPath dbpath = new ASTDbPath(buf.toString()); 203 ASTList listExp = new ASTList(objects); 204 SelectQuery sel = new SelectQuery(destEnt, new ASTIn(dbpath, listExp)); 205 sel.setFetchingDataRows(true); 206 List results = context.performQuery(sel); 207 208 210 List destObjects = context.objectsFromDataRows(destEnt, results, false, false); 211 int nrows = destObjects.size(); 212 for (int k = 0; k < nrows; k++) { 213 Map row = (Map ) results.get(k); 214 ((List ) listMap.get(row.get(dbKey))).add(destObjects.get(k)); 215 } 216 217 for (int i = 0; i < nobjects; i++) { 219 DataObject object = (DataObject) objects.get(i); 220 ObjectId oid = object.getObjectId(); 221 List list = (List ) listMap.get(oid.getValueForAttribute(dbKey)); 222 223 ((ToManyList) object.readPropertyDirectly(relName)).setObjectList(list); 224 } 225 } 226 } | Popular Tags |