1 19 20 package org.apache.cayenne.util; 21 22 import java.util.ArrayList ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 26 import org.apache.cayenne.ObjectContext; 27 import org.apache.cayenne.ObjectId; 28 import org.apache.cayenne.PersistenceState; 29 import org.apache.cayenne.Persistent; 30 import org.apache.cayenne.QueryResponse; 31 import org.apache.cayenne.cache.QueryCache; 32 import org.apache.cayenne.cache.QueryCacheEntryFactory; 33 import org.apache.cayenne.query.ObjectIdQuery; 34 import org.apache.cayenne.query.Query; 35 import org.apache.cayenne.query.QueryMetadata; 36 import org.apache.cayenne.query.RelationshipQuery; 37 import org.apache.cayenne.reflect.ArcProperty; 38 import org.apache.cayenne.reflect.ClassDescriptor; 39 40 51 public abstract class ObjectContextQueryAction { 52 53 protected static final boolean DONE = true; 54 55 protected ObjectContext targetContext; 56 protected ObjectContext actingContext; 57 protected Query query; 58 protected QueryMetadata metadata; 59 60 protected transient QueryResponse response; 61 62 public ObjectContextQueryAction(ObjectContext actingContext, 63 ObjectContext targetContext, Query query) { 64 65 this.actingContext = actingContext; 66 this.query = query; 67 68 this.targetContext = targetContext != actingContext ? targetContext : null; 71 this.metadata = query.getMetaData(actingContext.getEntityResolver()); 72 } 73 74 77 public QueryResponse execute() { 78 79 if (interceptOIDQuery() != DONE) { 80 if (interceptRelationshipQuery() != DONE) { 81 if (interceptLocalCache() != DONE) { 82 runQuery(); 83 } 84 } 85 } 86 87 interceptObjectConversion(); 88 89 return response; 90 } 91 92 97 protected void interceptObjectConversion() { 98 99 if (targetContext != null && !metadata.isFetchingDataRows()) { 100 101 103 GenericResponse childResponse = new GenericResponse(); 104 105 for (response.reset(); response.next();) { 106 if (response.isList()) { 107 108 List objects = response.currentList(); 109 if (objects.isEmpty()) { 110 childResponse.addResultList(objects); 111 } 112 else { 113 114 117 List childObjects = new ArrayList (objects.size()); 118 Iterator it = objects.iterator(); 119 while (it.hasNext()) { 120 Persistent object = (Persistent) it.next(); 121 childObjects.add(targetContext.localObject(object 122 .getObjectId(), object)); 123 } 124 125 childResponse.addResultList(childObjects); 126 } 127 } 128 else { 129 childResponse.addBatchUpdateCount(response.currentUpdateCount()); 130 } 131 } 132 133 response = childResponse; 134 } 135 136 } 137 138 protected boolean interceptOIDQuery() { 139 if (query instanceof ObjectIdQuery) { 140 ObjectIdQuery oidQuery = (ObjectIdQuery) query; 141 142 if (!oidQuery.isFetchMandatory() && !oidQuery.isFetchingDataRows()) { 143 Object object = actingContext.getGraphManager().getNode( 144 oidQuery.getObjectId()); 145 if (object != null) { 146 147 if (((Persistent) object).getPersistenceState() == PersistenceState.HOLLOW) { 149 return !DONE; 150 } 151 152 this.response = new ListResponse(object); 153 return DONE; 154 } 155 } 156 } 157 158 return !DONE; 159 } 160 161 protected boolean interceptRelationshipQuery() { 162 163 if (query instanceof RelationshipQuery) { 164 RelationshipQuery relationshipQuery = (RelationshipQuery) query; 165 if (!relationshipQuery.isRefreshing()) { 166 167 171 if (targetContext == null 172 && relationshipQuery.getRelationship( 173 actingContext.getEntityResolver()).isToMany()) { 174 return !DONE; 175 } 176 177 ObjectId id = relationshipQuery.getObjectId(); 178 Object object = actingContext.getGraphManager().getNode(id); 179 180 if (object != null) { 181 182 ClassDescriptor descriptor = actingContext 183 .getEntityResolver() 184 .getClassDescriptor(id.getEntityName()); 185 186 if (!descriptor.isFault(object)) { 187 188 ArcProperty property = (ArcProperty) descriptor 189 .getProperty(relationshipQuery.getRelationshipName()); 190 191 if (!property.isFault(object)) { 192 193 Object related = property.readPropertyDirectly(object); 194 195 List result; 196 197 if (related == null) { 199 result = new ArrayList (1); 200 } 201 else if (related instanceof List ) { 203 result = (List ) related; 204 } 205 else { 207 result = new ArrayList (1); 208 result.add(related); 209 } 210 211 this.response = new ListResponse(result); 212 return DONE; 213 214 } 215 } 216 } 217 } 218 } 219 220 return !DONE; 221 } 222 223 226 protected boolean interceptLocalCache() { 227 228 if (metadata.getCacheKey() == null) { 229 return !DONE; 230 } 231 232 boolean cache = QueryMetadata.LOCAL_CACHE.equals(metadata.getCachePolicy()); 233 boolean cacheOrCacheRefresh = cache 234 || QueryMetadata.LOCAL_CACHE_REFRESH.equals(metadata.getCachePolicy()); 235 236 if (!cacheOrCacheRefresh) { 237 return !DONE; 238 } 239 240 QueryCache queryCache = getQueryCache(); 241 QueryCacheEntryFactory factory = getCacheObjectFactory(); 242 243 if (cache) { 244 List cachedResults = queryCache.get(metadata, factory); 245 246 if (response == null) { 249 response = new ListResponse(cachedResults); 250 } 251 } 252 else { 253 queryCache.put(metadata, (List ) factory.createObject()); 255 } 256 257 return DONE; 258 } 259 260 263 protected abstract QueryCache getQueryCache(); 264 265 268 protected QueryCacheEntryFactory getCacheObjectFactory() { 269 return new QueryCacheEntryFactory() { 270 271 public Object createObject() { 272 runQuery(); 273 return response.firstList(); 274 } 275 }; 276 } 277 278 281 protected void runQuery() { 282 this.response = actingContext.getChannel().onQuery(actingContext, query); 283 } 284 } 285 | Popular Tags |