1 19 20 package org.apache.cayenne.access; 21 22 import java.util.ArrayList ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import org.apache.cayenne.CayenneRuntimeException; 29 import org.apache.cayenne.Fault; 30 import org.apache.cayenne.Persistent; 31 import org.apache.cayenne.ValueHolder; 32 import org.apache.cayenne.query.PrefetchTreeNode; 33 import org.apache.cayenne.reflect.ArcProperty; 34 import org.apache.cayenne.reflect.ToOneProperty; 35 36 42 class PrefetchProcessorNode extends PrefetchTreeNode { 48 49 List dataRows; 50 List objects; 51 52 ArcProperty incoming; 53 ObjectResolver resolver; 54 55 Map partitionByParent; 56 boolean jointChildren; 57 boolean partitionedByParent; 58 59 Persistent lastResolved; 60 61 PrefetchProcessorNode(PrefetchTreeNode parent, String segmentPath) { 62 super(parent, segmentPath); 63 } 64 65 69 void afterInit() { 70 71 partitionedByParent = !phantom 72 && incoming != null 73 && incoming.getRelationship().isSourceIndependentFromTargetChange(); 74 75 if (partitionedByParent) { 76 partitionByParent = new HashMap (); 77 } 78 } 79 80 85 void linkToParent(Persistent object, Persistent parent) { 86 if (parent != null) { 87 88 if (incoming instanceof ToOneProperty) { 91 incoming.writePropertyDirectly(parent, null, object); 92 } 93 else { 94 95 List peers = (List ) partitionByParent.get(parent); 96 97 if (peers == null) { 100 peers = new ArrayList (); 101 partitionByParent.put(parent, peers); 102 } 103 else if (peers.contains(object)) { 107 return; 108 } 109 110 peers.add(object); 111 } 112 } 113 } 114 115 void connectToParents() { 116 117 if (isPartitionedByParent()) { 119 120 123 PrefetchProcessorNode parent = (PrefetchProcessorNode) getParent(); 124 boolean parentObjectsExist = parent.getObjects() != null 125 && parent.getObjects().size() > 0; 126 if (incoming.getRelationship().isToMany()) { 127 if (parentObjectsExist) { 128 connectToNodeParents(parent.getObjects()); 129 } 130 else { 131 connectToFaultedParents(); 132 } 133 } 134 else { 135 if (parentObjectsExist) { 138 clearNullRelationships(parent.getObjects()); 139 } 140 } 141 } 142 } 143 144 private final void clearNullRelationships(List parentObjects) { 145 Iterator it = parentObjects.iterator(); 146 while (it.hasNext()) { 147 Object object = it.next(); 148 if (incoming.readPropertyDirectly(object) instanceof Fault) { 149 incoming.writeProperty(object, null, null); 150 } 151 } 152 } 153 154 private final void connectToNodeParents(List parentObjects) { 155 156 Iterator it = parentObjects.iterator(); 157 while (it.hasNext()) { 158 Persistent object = (Persistent) it.next(); 159 List related = (List ) partitionByParent.get(object); 160 connect(object, related); 161 } 162 } 163 164 private final void connectToFaultedParents() { 165 Iterator it = partitionByParent.entrySet().iterator(); 166 while (it.hasNext()) { 167 Map.Entry entry = (Map.Entry ) it.next(); 168 169 Persistent object = (Persistent) entry.getKey(); 170 List related = (List ) entry.getValue(); 171 connect(object, related); 172 } 173 } 174 175 private final void connect(Persistent object, List related) { 176 if (incoming.getRelationship().isToMany()) { 177 ValueHolder toManyList = (ValueHolder) incoming.readProperty(object); 178 179 toManyList.setValueDirectly(related != null ? related : new ArrayList (1)); 182 } 183 else { 184 throw new CayenneRuntimeException( 186 "To-one relationship wasn't handled properly: " + incoming.getName()); 187 } 188 } 189 190 List getDataRows() { 191 return dataRows; 192 } 193 194 List getObjects() { 195 return objects; 196 } 197 198 void setResolver(ObjectResolver resolver) { 199 this.resolver = resolver; 200 } 201 202 ObjectResolver getResolver() { 203 return resolver; 204 } 205 206 ArcProperty getIncoming() { 207 return incoming; 208 } 209 210 void setIncoming(ArcProperty incoming) { 211 this.incoming = incoming; 212 } 213 214 void setDataRows(List dataRows) { 215 this.dataRows = dataRows; 216 } 217 218 void setObjects(List objects) { 219 this.objects = objects; 220 } 221 222 boolean isJointChildren() { 223 return jointChildren; 224 } 225 226 void setJointChildren(boolean jointChildren) { 227 this.jointChildren = jointChildren; 228 } 229 230 boolean isPartitionedByParent() { 231 return partitionedByParent; 232 } 233 234 Persistent getLastResolved() { 235 return lastResolved; 236 } 237 238 void setLastResolved(Persistent lastResolved) { 239 this.lastResolved = lastResolved; 240 } 241 } 242 | Popular Tags |