1 19 20 package org.apache.cayenne.util; 21 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.Map ; 27 28 import org.apache.cayenne.CayenneRuntimeException; 29 import org.apache.cayenne.ObjectId; 30 import org.apache.cayenne.Persistent; 31 import org.apache.cayenne.map.EntityResolver; 32 import org.apache.cayenne.query.PrefetchTreeNode; 33 import org.apache.cayenne.reflect.AttributeProperty; 34 import org.apache.cayenne.reflect.ClassDescriptor; 35 import org.apache.cayenne.reflect.Property; 36 import org.apache.cayenne.reflect.PropertyVisitor; 37 import org.apache.cayenne.reflect.ToManyProperty; 38 import org.apache.cayenne.reflect.ToOneProperty; 39 40 48 public class ObjectDetachOperation { 49 50 protected EntityResolver targetResolver; 51 protected Map seen; 52 53 public ObjectDetachOperation(EntityResolver targetResolver) { 54 this.targetResolver = targetResolver; 55 this.seen = new HashMap (); 56 } 57 58 public void reset() { 59 seen.clear(); 60 } 61 62 67 public Object detach( 68 Object object, 69 ClassDescriptor descriptor, 70 final PrefetchTreeNode prefetchTree) { 71 if (!(object instanceof Persistent)) { 72 throw new CayenneRuntimeException("Expected Persistent, got: " + object); 73 } 74 75 final Persistent source = (Persistent) object; 76 ObjectId id = source.getObjectId(); 77 78 if (id == null) { 80 throw new CayenneRuntimeException("Server returned an object without an id: " 81 + source); 82 } 83 84 Object seenTarget = seen.get(id); 85 if (seenTarget != null) { 86 return seenTarget; 87 } 88 89 descriptor = descriptor.getSubclassDescriptor(source.getClass()); 90 91 final ClassDescriptor targetDescriptor = targetResolver.getClassDescriptor(id 93 .getEntityName()); 94 95 final Persistent target = (Persistent) targetDescriptor.createObject(); 96 target.setObjectId(id); 97 seen.put(id, target); 98 99 descriptor.visitProperties(new PropertyVisitor() { 100 101 public boolean visitToOne(ToOneProperty property) { 102 if (prefetchTree != null) { 103 104 PrefetchTreeNode child = prefetchTree.getNode(property.getName()); 105 106 if (child != null) { 107 Object destinationSource = property.readProperty(source); 108 109 Object destinationTarget = destinationSource != null ? detach( 110 destinationSource, 111 property.getTargetDescriptor(), 112 child) : null; 113 114 ToOneProperty targetProperty = (ToOneProperty) targetDescriptor 115 .getProperty(property.getName()); 116 Object oldTarget = targetProperty.isFault(target) 117 ? null 118 : targetProperty.readProperty(target); 119 targetProperty 120 .writeProperty(target, oldTarget, destinationTarget); 121 } 122 } 123 124 return true; 125 } 126 127 public boolean visitToMany(ToManyProperty property) { 128 if (prefetchTree != null) { 129 PrefetchTreeNode child = prefetchTree.getNode(property.getName()); 130 131 if (child != null) { 132 Collection collection = (Collection ) property 133 .readProperty(source); 134 135 Collection targetCollection = new ArrayList (collection.size()); 136 137 Iterator it = collection.iterator(); 138 while (it.hasNext()) { 139 Object destinationSource = it.next(); 140 Object destinationTarget = destinationSource != null 141 ? detach(destinationSource, property 142 .getTargetDescriptor(), child) 143 : null; 144 145 targetCollection.add(destinationTarget); 146 } 147 148 ToManyProperty targetProperty = (ToManyProperty) targetDescriptor 149 .getProperty(property.getName()); 150 targetProperty.writeProperty(target, null, targetCollection); 151 } 152 } 153 154 return true; 155 } 156 157 public boolean visitAttribute(AttributeProperty property) { 158 Property targetProperty = targetDescriptor 159 .getProperty(property.getName()); 160 targetProperty.writeProperty(target, null, property.readProperty(source)); 161 return true; 162 } 163 }); 164 165 return target; 166 } 167 } 168 | Popular Tags |