1 19 20 package org.apache.cayenne.util; 21 22 import java.util.List ; 23 24 import org.apache.cayenne.CayenneRuntimeException; 25 import org.apache.cayenne.FaultFailureException; 26 import org.apache.cayenne.Persistent; 27 import org.apache.cayenne.ValueHolder; 28 29 36 public class PersistentObjectHolder extends RelationshipFault implements ValueHolder { 37 38 protected boolean fault; 39 protected Object value; 40 41 private PersistentObjectHolder() { 43 fault = true; 44 } 45 46 public PersistentObjectHolder(Persistent relationshipOwner, String relationshipName) { 47 super(relationshipOwner, relationshipName); 48 fault = !isTransientParent(); 49 } 50 51 54 public boolean isFault() { 55 return fault; 56 } 57 58 public void invalidate() { 59 fault = true; 60 value = null; 61 } 62 63 66 public Object getValue() throws CayenneRuntimeException { 67 68 if (fault) { 69 resolve(); 70 } 71 72 return value; 73 } 74 75 public Object getValueDirectly() throws CayenneRuntimeException { 76 return value; 77 } 78 79 82 public synchronized Object setValue(Object value) throws CayenneRuntimeException { 83 84 if (fault) { 85 resolve(); 86 } 87 88 Object oldValue = setValueDirectly(value); 89 90 if (oldValue != value) { 91 if (relationshipOwner.getObjectContext() != null) { 93 relationshipOwner.getObjectContext().propertyChanged( 94 relationshipOwner, 95 relationshipName, 96 oldValue, 97 value); 98 } 99 } 100 101 return oldValue; 102 } 103 104 public Object setValueDirectly(Object value) throws CayenneRuntimeException { 105 106 if (value instanceof Persistent) { 108 value = connect((Persistent) value); 109 } 110 111 Object oldValue = this.value; 112 113 this.value = value; 114 this.fault = false; 115 116 return oldValue; 117 } 118 119 123 protected Object connect(Persistent persistent) { 124 125 if (persistent == null) { 126 return null; 127 } 128 129 if (relationshipOwner.getObjectContext() != persistent.getObjectContext()) { 130 throw new CayenneRuntimeException( 131 "Cannot set object as destination of relationship " 132 + relationshipName 133 + " because it is in a different ObjectContext"); 134 } 135 136 return persistent; 137 } 138 139 142 protected synchronized void resolve() { 143 if (!fault) { 144 return; 145 } 146 147 150 List objects = resolveFromDB(); 151 152 if (objects.size() == 0) { 153 this.value = null; 154 } 155 else if (objects.size() == 1) { 156 this.value = objects.get(0); 157 } 158 else { 159 throw new FaultFailureException( 160 "Expected either no objects or a single object, instead fault query resolved to " 161 + objects.size() 162 + " objects."); 163 } 164 165 fault = false; 166 } 167 } 168 | Popular Tags |