package net.wotonomy.test; import java.util.Iterator; import java.util.List; import java.util.Map; import net.wotonomy.control.EOEditingContext; import net.wotonomy.control.EOFetchSpecification; import net.wotonomy.control.EOGlobalID; import net.wotonomy.control.EOObjectStore; import net.wotonomy.control.EOObserverCenter; import net.wotonomy.test.DataKeyID; import net.wotonomy.datastore.DataSoup; import net.wotonomy.datastore.DataView; import net.wotonomy.datastore.XMLFileSoup; import net.wotonomy.foundation.NSArray; import net.wotonomy.foundation.NSMutableArray; import net.wotonomy.foundation.internal.Duplicator; import net.wotonomy.foundation.internal.WotonomyException; /** * An object store that wraps a datastore for vending test objects. */ public class TestObjectStore extends EOObjectStore { DataSoup soup; /** * Constructor specifies path to datastore. */ public TestObjectStore(String aPath) { soup = new XMLFileSoup(aPath); } /** * This implementation simply returns objectsWithSourceGlobalID. */ @Override public NSArray arrayFaultWithSourceGlobalID(EOGlobalID aGlobalID, String aRelationship, EOEditingContext aContext) { return objectsForSourceGlobalID(aGlobalID, aRelationship, aContext); } /** * This implementation returns the actual object for the specified id. */ @Override public Object faultForGlobalID(EOGlobalID aGlobalID, EOEditingContext aContext) { System.out.println("TestObjectStore: * reading object * : " + aGlobalID); return soup.getObjectByKey(((DataKeyID) aGlobalID).getKey()); } /** * Returns a fault representing an object of the specified entity type with * values from the specified dictionary. The fault should belong to the * specified editing context. */ @Override public Object faultForRawRow(Map aDictionary, String anEntityName, EOEditingContext aContext) { // TODO: faults are not yet supported throw new WotonomyException("Faults are not yet supported."); } /** * Given a newly instantiated object, this method initializes its properties to * values appropriate for the specified id. The object should belong to the * specified editing context. This method is called to populate faults. */ @Override public void initializeObject(Object anObject, EOGlobalID aGlobalID, EOEditingContext aContext) { System.out.println("TestObjectStore: * reading object * : " + aGlobalID); Object original = soup.getObjectByKey(((DataKeyID) aGlobalID).getKey()); EOObserverCenter.notifyObserversObjectWillChange(anObject); Duplicator.deepCopy(original, anObject); // TODO: need to handle child object registration in aContext } /** * Remove all values from all objects in memory, turning them into faults, and * posts a notification that all objects have been invalidated. */ @Override public void invalidateAllObjects() { // does nothing } /** * Removes values with the specified ids from memory, turning them into faults, * and posts a notification that those objects have been invalidated. */ @Override public void invalidateObjectsWithGlobalIDs(List aList) { // does nothing } /** * Returns false because locking is not permitted. */ @Override public boolean isObjectLockedWithGlobalID(EOGlobalID aGlobalID, EOEditingContext aContext) { return false; } /** * Does nothing because locking is not permitted. */ @Override public void lockObjectWithGlobalID(EOGlobalID aGlobalID, EOEditingContext aContext) { // does nothing } /** * Returns a List of objects associated with the object with the specified id * for the specified property relationship. Faults are not allowed in the array. * All objects should belong to the specified editing context. */ @Override public NSArray objectsForSourceGlobalID(EOGlobalID aGlobalID, String aRelationship, EOEditingContext aContext) { // TODO: relationships are not yet supported throw new WotonomyException("Relationships are not yet supported."); } /** * Returns a List of objects the meet the criteria of the supplied * specification. Faults are not allowed in the array. Each object is registered * with the specified editing context. If any object is already registered in * the specified context, it is not refetched and that object should be used in * the array. */ @Override public NSArray objectsWithFetchSpecification(EOFetchSpecification aFetchSpec, EOEditingContext aContext) { // TODO: fetch specs are not yet supported DataView view = soup.queryObjects(null, null); System.out.println("TestObjectStore: ** querying all objects **"); NSMutableArray result = new NSMutableArray(); Object o; Object existing; DataKeyID id; Iterator it = view.iterator(); while (it.hasNext()) { o = it.next(); id = new DataKeyID(view.getKeyForObject(o)); existing = aContext.objectForGlobalID(id); if (existing != null) { o = existing; } else { aContext.recordObject(o, id); } result.addObject(o); } return result; } /** * Removes all values from the specified object, converting it into a fault for * the specified id. New or deleted objects should not be refaulted. */ @Override public void refaultObject(Object anObject, EOGlobalID aGlobalID, EOEditingContext aContext) { // TODO: faults are not yet supported // just re-initialize the object initializeObject(anObject, aGlobalID, aContext); } /** * Writes all changes in the specified editing context to the respository. */ @Override public void saveChangesInEditingContext(EOEditingContext aContext) { Object o; DataKeyID id; Iterator it; System.out.println(aContext.updatedObjects()); // process updates it = aContext.updatedObjects().iterator(); while (it.hasNext()) { o = it.next(); id = (DataKeyID) aContext.globalIDForObject(o); System.out.println("TestObjectStore: * updating object * : " + id); soup.updateObject(id.getKey(), o); } // process deletes it = aContext.deletedObjects().iterator(); while (it.hasNext()) { o = it.next(); id = (DataKeyID) aContext.globalIDForObject(o); System.out.println("TestObjectStore: * deleting object * : " + id); soup.removeObject(id.getKey()); // remove object from editing context aContext.forgetObject(o); } // process inserts it = aContext.insertedObjects().iterator(); while (it.hasNext()) { o = it.next(); id = new DataKeyID(soup.addObject(o)); System.out.println("TestObjectStore: * adding object * : " + id); // register object in editing context with new id aContext.forgetObject(o); aContext.recordObject(o, id); } } }