1 19 20 package org.apache.cayenne.query; 21 22 import org.apache.commons.lang.StringUtils; 23 import org.apache.cayenne.CayenneRuntimeException; 24 import org.apache.cayenne.ObjectId; 25 import org.apache.cayenne.exp.Expression; 26 import org.apache.cayenne.exp.ExpressionFactory; 27 import org.apache.cayenne.map.EntityResolver; 28 import org.apache.cayenne.map.ObjEntity; 29 import org.apache.cayenne.map.ObjRelationship; 30 import org.apache.cayenne.reflect.ArcProperty; 31 import org.apache.cayenne.reflect.ClassDescriptor; 32 33 41 public class RelationshipQuery extends IndirectQuery { 42 43 protected ObjectId objectId; 44 protected String relationshipName; 45 protected boolean refreshing; 46 47 protected transient EntityResolver metadataResolver; 48 protected transient QueryMetadata metadata; 49 protected transient ArcProperty arc; 50 51 private RelationshipQuery() { 53 54 } 55 56 63 public RelationshipQuery(ObjectId objectID, String relationshipName) { 64 this(objectID, relationshipName, true); 65 } 66 67 74 public RelationshipQuery(ObjectId objectID, String relationshipName, 75 boolean refreshing) { 76 if (objectID == null) { 77 throw new CayenneRuntimeException("Null objectID"); 78 } 79 80 this.objectId = objectID; 81 this.relationshipName = relationshipName; 82 this.refreshing = refreshing; 83 } 84 85 88 public QueryMetadata getMetaData(final EntityResolver resolver) { 91 updateMetadata(resolver); 92 return metadata; 93 } 94 95 public ObjectId getObjectId() { 96 return objectId; 97 } 98 99 public boolean isRefreshing() { 100 return refreshing; 101 } 102 103 public String getRelationshipName() { 104 return relationshipName; 105 } 106 107 protected Query createReplacementQuery(EntityResolver resolver) { 108 109 if (objectId.isTemporary() && !objectId.isReplacementIdAttached()) { 110 throw new CayenneRuntimeException("Can't build a query for relationship '" 111 + relationshipName 112 + "' for temporary id: " 113 + objectId); 114 } 115 116 ObjRelationship relationship = getRelationship(resolver); 117 118 Expression qualifier = ExpressionFactory.matchDbExp(relationship 120 .getReverseDbRelationshipPath(), objectId); 121 122 SelectQuery query = new SelectQuery( 123 (ObjEntity) relationship.getTargetEntity(), 124 qualifier); 125 query.setRefreshingObjects(refreshing); 126 return query; 127 } 128 129 132 public ObjRelationship getRelationship(EntityResolver resolver) { 133 updateMetadata(resolver); 134 return arc.getRelationship(); 135 } 136 137 void updateMetadata(EntityResolver resolver) { 138 if (metadataResolver != resolver) { 140 141 if (objectId == null) { 142 throw new CayenneRuntimeException( 143 "Can't resolve query - objectID is null."); 144 } 145 146 ClassDescriptor descriptor = resolver.getClassDescriptor(objectId 147 .getEntityName()); 148 this.arc = (ArcProperty) descriptor.getProperty(relationshipName); 149 150 if (arc == null) { 151 throw new CayenneRuntimeException("No relationship named " 152 + relationshipName 153 + " found in entity " 154 + objectId.getEntityName() 155 + "; object id: " 156 + objectId); 157 } 158 159 this.metadata = new DefaultQueryMetadata() { 160 161 public boolean isRefreshingObjects() { 162 return refreshing; 163 } 164 165 public ObjEntity getObjEntity() { 166 return arc.getTargetDescriptor().getEntity(); 167 } 168 169 public ClassDescriptor getClassDescriptor() { 170 return arc.getTargetDescriptor(); 171 } 172 }; 173 174 this.metadataResolver = resolver; 175 } 176 } 177 178 182 public String toString() { 183 return StringUtils.substringAfterLast(getClass().getName(), ".") 184 + ":" 185 + getRelationshipName(); 186 } 187 } 188 | Popular Tags |