summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java
diff options
context:
space:
mode:
authorBenjamin Culkin <scorpress@gmail.com>2024-05-19 17:56:33 -0400
committerBenjamin Culkin <scorpress@gmail.com>2024-05-19 17:56:33 -0400
commitaedc34d55462a75e329bbf342251ff6504cd117e (patch)
treebcc8f1f2352582717b484df302aeea6696b8f000 /projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java
Initial import from SVN
Diffstat (limited to 'projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java')
-rw-r--r--projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java483
1 files changed, 483 insertions, 0 deletions
diff --git a/projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java b/projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java
new file mode 100644
index 0000000..d175f6e
--- /dev/null
+++ b/projects/net.wotonomy.test/src/main/java/net/wotonomy/test/DataObjectStore.java
@@ -0,0 +1,483 @@
+package net.wotonomy.test;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import net.wotonomy.control.ArrayFault;
+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.control.KeyValueCodingUtilities;
+import net.wotonomy.datastore.DataKey;
+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.NSMutableDictionary;
+import net.wotonomy.foundation.NSNotification;
+import net.wotonomy.foundation.NSNotificationQueue;
+import net.wotonomy.foundation.internal.WotonomyException;
+
+/**
+* An object store that wraps a datastore for vending test objects.
+*/
+public class DataObjectStore extends EOObjectStore
+{
+ DataSoup soup;
+
+ /**
+ * Constructor specifies path to datastore.
+ */
+ public DataObjectStore( String aPath )
+ {
+ soup = new XMLFileSoup( aPath );
+ }
+
+ /**
+ * This implementation returns an appropriately configured array fault.
+ */
+ public NSArray arrayFaultWithSourceGlobalID (
+ EOGlobalID aGlobalID,
+ String aRelationship,
+ EOEditingContext aContext )
+ {
+ return new ArrayFault(
+ aGlobalID, aRelationship, aContext );
+ }
+
+ /**
+ * This implementation returns the actual
+ * object for the specified id.
+ */
+ public Object faultForGlobalID (
+ EOGlobalID aGlobalID,
+ EOEditingContext aContext )
+ {
+System.out.println( "DataObjectStore.faultForGlobalID: * reading object * : " + aGlobalID );
+ Object result = soup.getObjectByKey(
+ ((DataKeyID)aGlobalID).getKey() );
+
+ if ( result == null ) return null;
+
+ //! transpose keys to objects
+ convertRelationKeysToObjects( aContext, result, aGlobalID );
+ //!
+
+ aContext.recordObject( result, aGlobalID );
+ return result;
+ }
+
+ /**
+ * 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) {
+ if (aGlobalID.isTemporary()) {
+ // TODO: this should never happen, but it does now until we get
+ // faults.
+
+ // do not reinit an uncommitted object
+ return;
+ }
+
+ System.out.println("DataObjectStore.initializeObject: * reading object * : "
+ + aGlobalID);
+ //net.wotonomy.ui.swing.util.StackTraceInspector.printShortStackTrace();
+ Object original = soup.getObjectByKey(((DataKeyID) aGlobalID).getKey());
+
+ // ! transpose keys to objects
+ convertRelationKeysToObjects(aContext, original, aGlobalID);
+ // !
+ EOObserverCenter.notifyObserversObjectWillChange(anObject);
+ KeyValueCodingUtilities.copy(aContext, original, aContext, anObject);
+ }
+
+ /**
+ * 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 except post notification
+
+ NSNotificationQueue.defaultQueue().enqueueNotification(
+ new NSNotification(
+ InvalidatedAllObjectsInStoreNotification, this ),
+ NSNotificationQueue.PostNow );
+ }
+
+ /**
+ * 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. This method may not return an array fault
+ * because array faults call this method to fetch on demand.
+ * All objects must be registered the specified editing context.
+ * The specified relationship key must produce a result of
+ * type Collection for the source object or an exception is thrown.
+ */
+ public NSArray objectsForSourceGlobalID (
+ EOGlobalID aGlobalID,
+ String aRelationship,
+ EOEditingContext aContext )
+ {
+ System.out.println( "DataObjectStore.objectsForSourceGlobalID: * reading object * : " + aGlobalID );
+ Object object = soup.getObjectByKey(((DataKeyID)aGlobalID).getKey() );
+
+ if ( object == null ) return null;
+
+ Object fault;
+ EOGlobalID id;
+ NSMutableArray result = new NSMutableArray();
+
+ Iterator it = ((TestObject)object).getChildList().iterator();
+ while ( it.hasNext() )
+ {
+ id = new DataKeyID((DataKey)it.next());
+ fault = aContext.faultForGlobalID( id, aContext );
+
+ // if key still exists
+ if ( fault != null )
+ {
+//System.out.println( "objectsForSourceGlobalID: found: " + id + " : " + fault );
+ result.add( fault );
+
+// for testing purposes
+((TestObject)fault).setParent( (TestObject) object );
+ }
+ else // key no longer exists
+ {
+ // do not add
+System.out.println( "objectsForSourceGlobalID: could not find fault for id: " + id );
+ }
+ }
+ return result;
+
+ }
+
+ /**
+ * Returns a List of objects the meet the criteria of
+ * the supplied specification.
+ * 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( "DataObjectStore: ** querying all objects **" );
+
+ // we've changed this implementation so that
+ // it simply calls faultForGlobalID on the context
+ // for each id in the result set.
+ // this way, child contexts inherit parent's state.
+ // however, it's unclear if the specification allows
+ // faults in the resulting array. sounds like it doesn't.
+ NSMutableArray result = new NSMutableArray();
+ DataKeyID id;
+ Iterator it = view.iterator();
+ while ( it.hasNext() )
+ {
+ id = new DataKeyID( view.getKeyForObject( it.next() ) );
+ result.addObject( aContext.faultForGlobalID( id, aContext ) );
+ }
+ 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;
+
+ // process deletes
+ it = aContext.deletedObjects().iterator();
+ while ( it.hasNext() )
+ {
+ o = it.next();
+ id = (DataKeyID) aContext.globalIDForObject( o );
+System.out.println( "DataObjectStore: * deleting object * : " + id );
+ soup.removeObject( id.getKey() );
+ // remove object from editing context
+ aContext.forgetObject( o );
+ }
+
+ // process inserts
+ NSMutableDictionary userInfo = null;
+ it = aContext.insertedObjects().iterator();
+ while ( it.hasNext() )
+ {
+ o = it.next();
+ EOGlobalID oldId = aContext.globalIDForObject( o );
+
+ //! transpose objects to keys
+ convertRelationObjectsToKeys( aContext, (TestObject) o );
+ id = new DataKeyID( soup.addObject( o ) );
+ convertRelationKeysToObjects( aContext, (TestObject) o, oldId );
+ //!
+
+System.out.println( "DataObjectStore: * adding object * : " + id );
+
+ // save mapping of old id to new id
+ if ( userInfo == null )
+ {
+ userInfo = new NSMutableDictionary();
+ }
+ userInfo.setObjectForKey( id, oldId );
+ }
+
+ // broadcast inserted objects' new ids if necessary
+ if ( userInfo != null )
+ {
+ NSNotificationQueue.defaultQueue().enqueueNotification(
+ new NSNotification(
+ EOGlobalID.GlobalIDChangedNotification, null, userInfo ),
+ NSNotificationQueue.PostNow );
+ }
+
+ System.out.println( aContext.updatedObjects() );
+
+ // process updates
+ it = aContext.updatedObjects().iterator();
+ while ( it.hasNext() )
+ {
+//if ( true ) // test validation error message handling
+//throw new RuntimeException( "Update not allowed." );
+ o = it.next();
+ id = (DataKeyID) aContext.globalIDForObject( o );
+System.out.println( "DataObjectStore: * updating object * : " + id );
+
+ //! transpose objects to keys
+ convertRelationObjectsToKeys( aContext, (TestObject) o );
+ soup.updateObject( id.getKey(), o );
+ convertRelationKeysToObjects( aContext, (TestObject) o, id );
+ //!
+
+ }
+ }
+
+ private void convertRelationKeysToObjects(
+ EOEditingContext aContext, Object anObject, EOGlobalID aGlobalID )
+ { // System.out.println( "convertRelationKeysToObjects: " + anObject );
+// set editing context for testing
+((TestObject)anObject).editingContext = aContext;
+
+ Object fault;
+ DataKeyID id;
+ List result = new LinkedList();
+ Iterator it = ((TestObject)anObject).getChildList().iterator();
+ while ( it.hasNext() )
+ {
+ id = new DataKeyID((DataKey)it.next());
+ fault = aContext.faultForGlobalID( id, aContext );
+
+ // if key still exists
+ if ( fault != null )
+ {
+//System.out.println( "convertRelationObjectsToKeys: found: " + id + " : " + fault );
+ result.add( fault );
+
+// for testing purposes
+((TestObject)fault).setParent( (TestObject) anObject );
+ }
+ else // key no longer exists
+ {
+ // do not add
+System.out.println( "convertRelationObjectsToKeys: could not find fault for id: " + id );
+ }
+ }
+ // this tests loading manually on-demand
+// ((TestObject)anObject).setChildList( null );
+ // this tests loading immediately
+ ((TestObject)anObject).setChildList( result );
+ // this tests loading array faults
+// ((TestObject)result).setChildList( null );
+ ((TestObject)anObject).setChildList(
+ aContext.arrayFaultWithSourceGlobalID(
+ aGlobalID, "childList", aContext ) );
+
+ }
+
+ private void convertRelationObjectsToKeys(
+ EOEditingContext aContext, Object anObject )
+ { // System.out.println( "convertRelationObjectsToKeys: " + anObject );
+ Object o;
+ DataKeyID id;
+ List result = new LinkedList();
+ Iterator it = ((TestObject)anObject).getChildList().iterator();
+// for testing purposes
+((TestObject)anObject).setParent( null );
+((TestObject)anObject).editingContext = null;
+ while ( it.hasNext() )
+ {
+ o = it.next();
+//System.out.println( "convertRelationObjectsToKeys: " + o + " : " + aContext.globalIDForObject( o ) );
+ id = (DataKeyID)aContext.globalIDForObject( o );
+
+ // if object still exists in context
+ if ( id != null )
+ {
+ result.add( id.getKey() );
+ }
+ else // object was deleted
+ {
+ // do not add
+System.out.println( "convertRelationObjectsToKeys: could not find id for object: " + o );
+System.out.println( aContext.registeredObjects() );
+ }
+
+ }
+ ((TestObject)anObject).setChildList( result );
+ }
+
+
+/*
+ * $Log$
+ * Revision 1.1 2006/02/19 16:30:25 cgruber
+ * Update imports and maven dependencies.
+ *
+ * Revision 1.1 2006/02/16 13:18:56 cgruber
+ * Check in all sources in eclipse-friendly maven-enabled packages.
+ *
+ * Revision 1.18 2002/03/11 03:18:39 mpowers
+ * Now properly handling ObserverChangesLater.
+ *
+ * Revision 1.17 2001/10/26 18:39:44 mpowers
+ * Posting notifications immediately, rather than delayed.
+ *
+ * Revision 1.16 2001/05/06 18:27:10 mpowers
+ * More broadly catching editing contexts for now.
+ *
+ * Revision 1.15 2001/05/05 23:05:43 mpowers
+ * Implemented Array Faults.
+ *
+ * Revision 1.14 2001/05/05 15:00:06 mpowers
+ * Tested load-on-demand: still works.
+ * Now using registerClone for consistency.
+ * Editing context is temporarily posting notification on objectWillChange.
+ *
+ * Revision 1.13 2001/05/04 23:24:30 mpowers
+ * Changes to test code.
+ *
+ * Revision 1.12 2001/05/04 16:57:56 mpowers
+ * Now correctly transposing references to editing contexts when
+ * cloning/copying between editing contexts.
+ *
+ * Revision 1.11 2001/05/02 17:33:28 mpowers
+ * More changes for testing.
+ *
+ * Revision 1.10 2001/04/30 13:15:24 mpowers
+ * Child contexts re-initializing objects invalidated in parent now
+ * propery transpose relationships.
+ *
+ * Revision 1.9 2001/04/29 22:02:45 mpowers
+ * Work on id transposing between editing contexts.
+ *
+ * Revision 1.8 2001/04/29 02:29:31 mpowers
+ * Debugging relationship faulting.
+ *
+ * Revision 1.7 2001/04/28 22:17:51 mpowers
+ * Revised PropertyDataSource to be EOClassDescription-aware.
+ *
+ * Revision 1.6 2001/04/28 16:18:44 mpowers
+ * Implementing relationships.
+ *
+ * Revision 1.5 2001/04/13 16:33:36 mpowers
+ * Now broadcasting notifications.
+ *
+ * Revision 1.4 2001/04/08 21:00:54 mpowers
+ * Changes to support new objectsForFetchSpecification scheme.
+ *
+ * Revision 1.3 2001/03/22 21:37:52 mpowers
+ * Testing new features.
+ *
+ * Revision 1.2 2001/03/15 21:10:41 mpowers
+ * Implemented global id re-registration for newly saved inserts.
+ *
+ * Revision 1.1 2001/03/05 22:12:11 mpowers
+ * Created the control package for a datastore-specific implementation
+ * of EOObjectStore.
+ *
+ *
+ */
+}
+