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. */ public NSArray arrayFaultWithSourceGlobalID ( EOGlobalID aGlobalID, String aRelationship, EOEditingContext aContext ) { return objectsForSourceGlobalID( aGlobalID, aRelationship, aContext ); } /** * This implementation returns the actual * object for the specified id. */ 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. */ 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. */ 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. */ 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. */ public void invalidateObjectsWithGlobalIDs ( List aList ) { // does nothing } /** * Returns false because locking is not permitted. */ public boolean isObjectLockedWithGlobalID ( EOGlobalID aGlobalID, EOEditingContext aContext ) { return false; } /** * Does nothing because locking is not permitted. */ 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. */ 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. */ 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. */ 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. */ 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 ); } } }