1 56 package org.objectstyle.cayenne.client; 57 58 import java.util.Collection ; 59 import java.util.Iterator ; 60 import java.util.List ; 61 62 import org.objectstyle.cayenne.CayenneRuntimeException; 63 import org.objectstyle.cayenne.ObjectContext; 64 import org.objectstyle.cayenne.PersistenceState; 65 import org.objectstyle.cayenne.Persistent; 66 import org.objectstyle.cayenne.QueryResponse; 67 import org.objectstyle.cayenne.distribution.BootstrapMessage; 68 import org.objectstyle.cayenne.distribution.CayenneConnector; 69 import org.objectstyle.cayenne.distribution.CommitMessage; 70 import org.objectstyle.cayenne.distribution.GenericQueryMessage; 71 import org.objectstyle.cayenne.distribution.GlobalID; 72 import org.objectstyle.cayenne.distribution.SelectMessage; 73 import org.objectstyle.cayenne.distribution.UpdateMessage; 74 import org.objectstyle.cayenne.graph.CompoundDiff; 75 import org.objectstyle.cayenne.graph.GraphDiff; 76 import org.objectstyle.cayenne.graph.GraphManager; 77 import org.objectstyle.cayenne.graph.OperationRecorder; 78 import org.objectstyle.cayenne.query.QueryExecutionPlan; 79 80 88 public class ClientObjectContext implements ObjectContext { 89 90 protected transient CayenneConnector connector; 93 94 protected ClientEntityResolver entityResolver; 95 protected GraphManager graphManager; 96 protected OperationRecorder changeRecorder; 97 protected ClientStateRecorder stateRecorder; 98 99 103 public ClientObjectContext(CayenneConnector connector) { 104 this.connector = connector; 105 106 this.graphManager = new GraphManager(); 108 109 this.changeRecorder = new OperationRecorder(); 110 this.stateRecorder = new ClientStateRecorder(); 111 112 graphManager.addLocalChangeHandler(changeRecorder); 113 graphManager.addLocalChangeHandler(stateRecorder); 114 graphManager.setRemoteChangeHandler(new ClientObjectContextMergeHandler( 115 stateRecorder, 116 graphManager)); 117 } 118 119 public ClientEntityResolver getEntityResolver() { 120 if (entityResolver == null) { 122 synchronized (this) { 123 if (entityResolver == null) { 124 entityResolver = new BootstrapMessage().sendBootstrap(connector); 125 } 126 } 127 } 128 129 return entityResolver; 130 } 131 132 public void setEntityResolver(ClientEntityResolver entityResolver) { 133 this.entityResolver = entityResolver; 134 } 135 136 139 public CayenneConnector getConnector() { 140 return connector; 141 } 142 143 148 public GraphDiff commit() { 149 150 if (!changeRecorder.isEmpty()) { 151 GraphDiff commitDiff = new CommitMessage(changeRecorder.getDiffs()) 152 .sendCommit(connector); 153 154 graphManager.mergeRemoteChange(commitDiff); 155 stateRecorder.processCommit(graphManager); 156 changeRecorder.clear(); 157 158 return commitDiff; 159 } 160 else { 161 return new CompoundDiff(); 162 } 163 } 164 165 169 public void deleteObject(Persistent object) { 170 if (object.getPersistenceState() == PersistenceState.TRANSIENT) { 171 return; 172 } 173 174 if (object.getPersistenceState() == PersistenceState.DELETED) { 175 return; 176 } 177 178 if (object.getPersistenceState() == PersistenceState.NEW) { 179 object.setPersistenceState(PersistenceState.TRANSIENT); 181 graphManager.unregisterNode(object.getOid()); 182 return; 183 } 184 185 187 object.setPersistenceState(PersistenceState.DELETED); 188 graphManager.nodeRemoved(object.getOid()); 189 } 190 191 194 public Persistent newObject(Class persistentClass) { 195 if (persistentClass == null) { 196 throw new NullPointerException ("Persistent class can't be null."); 197 } 198 199 Persistent object = null; 200 try { 201 object = (Persistent) persistentClass.newInstance(); 202 } 203 catch (Exception ex) { 204 throw new CayenneRuntimeException( 205 "Error instantiating persistent object of class " + persistentClass, 206 ex); 207 } 208 209 object.setOid(new GlobalID(getEntityResolver().lookupEntity(persistentClass))); 210 object.setPersistenceState(PersistenceState.NEW); 211 object.setObjectContext(this); 212 213 graphManager.registerNode(object.getOid(), object); 214 graphManager.nodeCreated(object.getOid()); 215 216 return object; 217 } 218 219 public int[] performUpdateQuery(QueryExecutionPlan query) { 220 return new UpdateMessage(query).send(connector); 221 } 222 223 public List performSelectQuery(QueryExecutionPlan query) { 224 List objects = new SelectMessage(query).send(connector); 225 226 Iterator it = objects.iterator(); 228 while (it.hasNext()) { 229 Persistent o = (Persistent) it.next(); 230 231 if (o.getOid() == null) { 233 throw new CayenneClientException( 234 "Server returned an object without an id: " + o); 235 } 236 237 o.setPersistenceState(PersistenceState.COMMITTED); 238 o.setObjectContext(this); 239 graphManager.registerNode(o.getOid(), o); 240 } 241 242 return objects; 243 } 244 245 public QueryResponse performGenericQuery(QueryExecutionPlan query) { 246 return new GenericQueryMessage(query).send(connector); 247 } 248 249 public void objectWillRead(Persistent dataObject, String property) { 250 if (dataObject.getPersistenceState() == PersistenceState.HOLLOW) { 251 throw new CayenneClientException("Resolving an object is Unimplemented"); 253 } 254 } 255 256 public void objectWillWrite( 257 Persistent object, 258 String property, 259 Object oldValue, 260 Object newValue) { 261 262 if (object.getPersistenceState() == PersistenceState.COMMITTED) { 264 object.setPersistenceState(PersistenceState.MODIFIED); 265 } 266 267 graphManager.nodePropertyChanged(object.getOid(), property, oldValue, newValue); 268 } 269 270 public Collection uncommittedObjects() { 271 return stateRecorder.dirtyNodes(graphManager); 273 } 274 275 public Collection deletedObjects() { 276 return stateRecorder.dirtyNodes(graphManager, PersistenceState.DELETED); 278 } 279 280 public Collection modifiedObjects() { 281 return stateRecorder.dirtyNodes(graphManager, PersistenceState.MODIFIED); 283 } 284 285 public Collection newObjects() { 286 return stateRecorder.dirtyNodes(graphManager, PersistenceState.NEW); 288 } 289 } | Popular Tags |