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; } }