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