package net.wotonomy.control; import java.util.Collection; import java.util.Iterator; import net.wotonomy.foundation.NSArray; import net.wotonomy.foundation.NSMutableArray; /** * A data source that automates the process of * creating a child editing context and copying * objects from a parent context into it. * Attach this data source to a display group * that represents a "detail" or "drill-down" * view.

* * Once created, editingContext() will return the * child context, and fetch() will return the objects * that were copied into the child context. */ public class ChildDataSource extends EODataSource { private EODataSource parent; private EOEditingContext context; private EOClassDescription classDescription; private NSMutableArray objects; /** * Creates a child editing context for the * specified parent's context and copies the * specified object into the child context. * The object must exist in the parent context. * fetch() will return the child's object. */ public ChildDataSource( EODataSource aParentSource, Object anObject ) { this( aParentSource, new NSArray( (Object) anObject ) ); } /** * Creates a child editing context for the * specified parent's context and copies the * specified objects into the child context. * The objects must exist in the parent context. * The order of the parent's objects in the * collection will determine the order in * which the child objects are returned from * fetch(). */ public ChildDataSource( EODataSource aParentSource, Collection anObjectList ) { EOEditingContext parentContext = aParentSource.editingContext(); parent = aParentSource; context = new EOEditingContext( parentContext ); //!new net.wotonomy.ui.swing.util.ObjectInspector( context ); objects = new NSMutableArray(); classDescription = null; Object o; Object copy; boolean allSameClass = true; Iterator it = anObjectList.iterator(); while ( it.hasNext() ) { o = it.next(); // determine class if ( allSameClass == true ) { Class c = o.getClass(); if ( classDescription == null ) { classDescription = EOClassDescription.classDescriptionForClass( c ); } else { if ( c != classDescription.getDescribedClass() ) { allSameClass = false; classDescription = null; } } } // copy and add to list objects.addObject( parentContext.faultForGlobalID( parentContext.globalIDForObject( o ), context ) ); } } /** * Returns the editing context for this data source, * which was created in the constructor and whose * parent is the editing context specified in the * constructor. */ public EOEditingContext editingContext() { return context; } /** * This implementation does nothing. */ public void insertObject ( Object anObject ) { } /** * This implementation does nothing. */ public void deleteObject ( Object anObject ) { } /** * Returns a List containing the objects in this * data source. This implementation returns all * TestObjects that have been persisted to the * datastore in the data directory. */ public NSArray fetchObjects () { return new NSArray( (Collection) objects ); } /** * Returns a data source that is capable of * manipulating objects of the type returned by * applying the specified key to objects * vended by this data source. * This implementation forwards the call to * the parent data source. * @see #qualifyWithRelationshipKey */ public EODataSource dataSourceQualifiedByKey ( String aKey ) { //FIXME: This is fundamentally broken. // Objects vended from the returned source // are not registered in our editing context. // We probably need yet another utility data // source class that would wrap another source // and convert vended objects into a different // context. return parent.dataSourceQualifiedByKey( aKey ); } /** * Restricts this data source to vend those * objects that are associated with the specified * key on the specified object. * This implementation forwards the call to * the parent data source. */ public void qualifyWithRelationshipKey ( String aKey, Object anObject ) { parent.qualifyWithRelationshipKey( aKey, anObject ); } /** * Returns the description of the class of the * objects that is vended by this data source, * or null if this cannot be determined. * This implementation returns the class of the * objects passed to the constructor if they are * all the same class, otherwise returns null. */ public EOClassDescription classDescriptionForObjects () { return classDescription; } }