summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java
diff options
context:
space:
mode:
Diffstat (limited to 'projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java')
-rw-r--r--projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java863
1 files changed, 380 insertions, 483 deletions
diff --git a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java
index 76f7219..c02c3e2 100644
--- a/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java
+++ b/projects/net.wotonomy.persistence/src/main/java/net/wotonomy/control/PropertyDataSource.java
@@ -34,516 +34,413 @@ import net.wotonomy.foundation.internal.Introspector;
import net.wotonomy.foundation.internal.WotonomyException;
/**
-* A data source that reads and writes to an indexed
-* property of a java object. This class is used by
-* MasterDetailAssociation to retreive objects from
-* the master display group.
-*
-* @author michael@mpowers.net
-* @author $Author: cgruber $
-* @version $Revision: 894 $
-*/
-public class PropertyDataSource extends OrderedDataSource
-{
- protected Object source;
- protected String key;
- protected Class lastKnownType; // for best-guessing
- protected EOClassDescription classDesc;
- protected EOEditingContext context;
-
- /**
- * Creates a new PropertyDataSource with no editing context
- * and will try to guess the appropriate class description
- * when trying to create objects.
- */
- public PropertyDataSource()
- {
- this( null, (EOClassDescription) null );
- }
-
- /**
- * Creates a new PropertyDataSource that uses the specified
- * editing context, but will try to guess the appropriate
- * class description when trying to create objects.
- */
- public PropertyDataSource( EOEditingContext aContext )
- {
- this( aContext, (EOClassDescription) null );
- }
-
- /**
- * Creates a new PropertyDataSource that uses the specified
- * editing context and vends objects of the specified class.
- */
- public PropertyDataSource(
- EOEditingContext aContext, Class aClass )
- {
- this( aContext, EOClassDescription.classDescriptionForClass( aClass ) );
- }
-
- /**
- * Creates a new PropertyDataSource that uses the specified
- * editing context and vends objects of the specified
- * class description.
- */
- public PropertyDataSource(
- EOEditingContext aContext, EOClassDescription aClassDesc )
- {
- source = null;
- key = null;
- lastKnownType = null;
- classDesc = aClassDesc;
- context = aContext;
- }
-
- /**
- * Provides the master object for detail display groups.
- */
- public Object source()
- {
- return source;
- }
-
- /**
- * Allows a detail display group to set the master object.
- */
- public void setSource( Object anObject )
- {
- source = anObject;
- }
-
- /**
- * Provides the detail key for detail display groups.
- */
- public String key()
- {
- return key;
- }
-
- /**
- * Allows a detail display group to set the detail key.
- */
- public void setKey( String aKey )
- {
- key = aKey;
- }
-
- /**
- * Inserts the specified object into this data source.
- * Calls insertObjectAtIndex and appends to the end
- * of the list.
- */
- public void insertObject ( Object anObject )
- {
- insertObjectAtIndex( anObject, -1 ); // trick to force to end
- }
-
- /**
- * Inserts the specified object into this data source,
- * at the specified index.
- */
- public void insertObjectAtIndex (
- Object anObject, int anIndex )
- {
- if ( source == null ) return;
- List list = readAsList();
- if ( anIndex == -1 ) anIndex = list.size(); // force to end
- if ( anIndex > list.size() ) anIndex = list.size(); // force to end
- list.add( anIndex, anObject );
- writeAsList( list );
- }
-
- /**
- * Deletes the specified object from this data source.
- */
- public void deleteObject ( Object anObject )
- {
- if ( source == null ) return;
- List list = readAsList();
- list.remove( anObject );
- writeAsList( list );
- }
-
- public EOEditingContext editingContext ()
- {
- return context;
- }
-
- /**
- * Returns a List containing the objects in this
- * data source.
- */
- public NSArray fetchObjects ()
- {
- if ( source == null ) return NSArray.EmptyArray;
- return readAsList();
- }
-
- /**
- * Returns a new instance of this class.
- */
- public EODataSource
- dataSourceQualifiedByKey ( String aKey )
- {
- // determine the target class desc if possible
- EOClassDescription keyClassDesc = null;
- if ( classDesc != null )
- {
- keyClassDesc = classDesc.classDescriptionForDestinationKey( aKey );
- }
- return new PropertyDataSource( editingContext(), keyClassDesc );
- }
-
- /**
- * Restricts this data source to vend those
- * objects that are associated with the specified
- * key on the specified object.
- */
- public void
- qualifyWithRelationshipKey (
- String aKey, Object anObject )
- {
- source = anObject;
- key = aKey;
- }
-
- /**
- * Returns the class description passed to the
- * constructor, if any. If no class description and
- * if the bound property is an indexed property,
- * the type of the array is returned, otherwise
- * this method returns null. This method is called
- * by createObject().
- */
- public EOClassDescription
- classDescriptionForObjects ()
- {
- // just return the class description if we have one
- if ( classDesc != null ) return classDesc;
-
- // otherwise, try to do some guesswork
- EOClassDescription result = null;
-
- // lastKnownType is not updated here
- Class type = lastKnownType;
-
- // if no last known type
- if ( type == null )
- {
- // if source and key were specified
- if ( ( source != null ) && ( key != null ) )
- {
- // try to get an array type
- Method m = Introspector.getPropertyReadMethod(
- source.getClass(), key, new Class[0] );
- if ( m != null )
- {
- Class returnType = m.getReturnType();
- if ( returnType.isArray() )
- {
- type = returnType.getComponentType();
- }
- }
- else
- {
- throw new WotonomyException( "Key does not exist for object: " + key + " : " + source );
- }
- }
-
- // does not update lastKnownType because
- // we prefer to get that info from a fetch.
- }
-
- // if type has been determined
- if ( type != null )
- {
- result =
- EOClassDescription.classDescriptionForClass( type );
- }
-
- return result;
- }
-
- /**
- * Calls getValue() and returns the result as a List.
- * Sets lastKnownType to the retrieved type.
- */
- protected NSMutableArray readAsList()
- {
- Object value = getValue();
- if ( value == null )
- {
- return new NSMutableArray();
- }
-
- Object o;
- NSMutableArray result = new NSMutableArray();
- boolean hasReadType = false;
- lastKnownType = null;
-
- // if instance of array, convert to list
- if ( value.getClass().isArray() )
- {
- int count = Array.getLength( value );
- for ( int i = 0; i < count; i++ )
- {
- o = Array.get( value, i );
- if ( o != null )
- {
- // we've already found a type
- if ( hasReadType )
- {
- // check that this matches the last known type
- if ( o.getClass() != lastKnownType )
- {
- // not all of the same type: set to null
- lastKnownType = null;
- }
- }
- else // this is the first type we've found
- {
- // remember it
- hasReadType = true;
- lastKnownType = o.getClass();
- }
- }
- result.add( o );
+ * A data source that reads and writes to an indexed property of a java object.
+ * This class is used by MasterDetailAssociation to retreive objects from the
+ * master display group.
+ *
+ * @author michael@mpowers.net
+ * @author $Author: cgruber $
+ * @version $Revision: 894 $
+ */
+public class PropertyDataSource extends OrderedDataSource {
+ protected Object source;
+ protected String key;
+ protected Class lastKnownType; // for best-guessing
+ protected EOClassDescription classDesc;
+ protected EOEditingContext context;
+
+ /**
+ * Creates a new PropertyDataSource with no editing context and will try to
+ * guess the appropriate class description when trying to create objects.
+ */
+ public PropertyDataSource() {
+ this(null, (EOClassDescription) null);
+ }
+
+ /**
+ * Creates a new PropertyDataSource that uses the specified editing context, but
+ * will try to guess the appropriate class description when trying to create
+ * objects.
+ */
+ public PropertyDataSource(EOEditingContext aContext) {
+ this(aContext, (EOClassDescription) null);
+ }
+
+ /**
+ * Creates a new PropertyDataSource that uses the specified editing context and
+ * vends objects of the specified class.
+ */
+ public PropertyDataSource(EOEditingContext aContext, Class aClass) {
+ this(aContext, EOClassDescription.classDescriptionForClass(aClass));
+ }
+
+ /**
+ * Creates a new PropertyDataSource that uses the specified editing context and
+ * vends objects of the specified class description.
+ */
+ public PropertyDataSource(EOEditingContext aContext, EOClassDescription aClassDesc) {
+ source = null;
+ key = null;
+ lastKnownType = null;
+ classDesc = aClassDesc;
+ context = aContext;
+ }
+
+ /**
+ * Provides the master object for detail display groups.
+ */
+ public Object source() {
+ return source;
+ }
+
+ /**
+ * Allows a detail display group to set the master object.
+ */
+ public void setSource(Object anObject) {
+ source = anObject;
+ }
+
+ /**
+ * Provides the detail key for detail display groups.
+ */
+ public String key() {
+ return key;
+ }
+
+ /**
+ * Allows a detail display group to set the detail key.
+ */
+ public void setKey(String aKey) {
+ key = aKey;
+ }
+
+ /**
+ * Inserts the specified object into this data source. Calls insertObjectAtIndex
+ * and appends to the end of the list.
+ */
+ public void insertObject(Object anObject) {
+ insertObjectAtIndex(anObject, -1); // trick to force to end
+ }
+
+ /**
+ * Inserts the specified object into this data source, at the specified index.
+ */
+ public void insertObjectAtIndex(Object anObject, int anIndex) {
+ if (source == null)
+ return;
+ List list = readAsList();
+ if (anIndex == -1)
+ anIndex = list.size(); // force to end
+ if (anIndex > list.size())
+ anIndex = list.size(); // force to end
+ list.add(anIndex, anObject);
+ writeAsList(list);
+ }
+
+ /**
+ * Deletes the specified object from this data source.
+ */
+ public void deleteObject(Object anObject) {
+ if (source == null)
+ return;
+ List list = readAsList();
+ list.remove(anObject);
+ writeAsList(list);
+ }
+
+ public EOEditingContext editingContext() {
+ return context;
+ }
+
+ /**
+ * Returns a List containing the objects in this data source.
+ */
+ public NSArray fetchObjects() {
+ if (source == null)
+ return NSArray.EmptyArray;
+ return readAsList();
+ }
+
+ /**
+ * Returns a new instance of this class.
+ */
+ public EODataSource dataSourceQualifiedByKey(String aKey) {
+ // determine the target class desc if possible
+ EOClassDescription keyClassDesc = null;
+ if (classDesc != null) {
+ keyClassDesc = classDesc.classDescriptionForDestinationKey(aKey);
+ }
+ return new PropertyDataSource(editingContext(), keyClassDesc);
+ }
+
+ /**
+ * Restricts this data source to vend those objects that are associated with the
+ * specified key on the specified object.
+ */
+ public void qualifyWithRelationshipKey(String aKey, Object anObject) {
+ source = anObject;
+ key = aKey;
+ }
+
+ /**
+ * Returns the class description passed to the constructor, if any. If no class
+ * description and if the bound property is an indexed property, the type of the
+ * array is returned, otherwise this method returns null. This method is called
+ * by createObject().
+ */
+ public EOClassDescription classDescriptionForObjects() {
+ // just return the class description if we have one
+ if (classDesc != null)
+ return classDesc;
+
+ // otherwise, try to do some guesswork
+ EOClassDescription result = null;
+
+ // lastKnownType is not updated here
+ Class type = lastKnownType;
+
+ // if no last known type
+ if (type == null) {
+ // if source and key were specified
+ if ((source != null) && (key != null)) {
+ // try to get an array type
+ Method m = Introspector.getPropertyReadMethod(source.getClass(), key, new Class[0]);
+ if (m != null) {
+ Class returnType = m.getReturnType();
+ if (returnType.isArray()) {
+ type = returnType.getComponentType();
+ }
+ } else {
+ throw new WotonomyException("Key does not exist for object: " + key + " : " + source);
+ }
}
+
+ // does not update lastKnownType because
+ // we prefer to get that info from a fetch.
}
- else
- if ( value instanceof Collection )
- {
+
+ // if type has been determined
+ if (type != null) {
+ result = EOClassDescription.classDescriptionForClass(type);
+ }
+
+ return result;
+ }
+
+ /**
+ * Calls getValue() and returns the result as a List. Sets lastKnownType to the
+ * retrieved type.
+ */
+ protected NSMutableArray readAsList() {
+ Object value = getValue();
+ if (value == null) {
+ return new NSMutableArray();
+ }
+
+ Object o;
+ NSMutableArray result = new NSMutableArray();
+ boolean hasReadType = false;
+ lastKnownType = null;
+
+ // if instance of array, convert to list
+ if (value.getClass().isArray()) {
+ int count = Array.getLength(value);
+ for (int i = 0; i < count; i++) {
+ o = Array.get(value, i);
+ if (o != null) {
+ // we've already found a type
+ if (hasReadType) {
+ // check that this matches the last known type
+ if (o.getClass() != lastKnownType) {
+ // not all of the same type: set to null
+ lastKnownType = null;
+ }
+ } else // this is the first type we've found
+ {
+ // remember it
+ hasReadType = true;
+ lastKnownType = o.getClass();
+ }
+ }
+ result.add(o);
+ }
+ } else if (value instanceof Collection) {
// convert to list so we handle sets, etc.
- Iterator i = ((Collection)value).iterator();
- while ( i.hasNext() )
- {
- o = i.next();
- if ( o != null )
- {
- // we've already found a type
- if ( hasReadType )
- {
- // check that this matches the last known type
- if ( o.getClass() != lastKnownType )
- {
- // not all of the same type: set to null
- lastKnownType = null;
- }
- }
- else // this is the first type we've found
- {
- // remember it
- hasReadType = true;
- lastKnownType = o.getClass();
- }
- }
- result.add( o );
- }
+ Iterator i = ((Collection) value).iterator();
+ while (i.hasNext()) {
+ o = i.next();
+ if (o != null) {
+ // we've already found a type
+ if (hasReadType) {
+ // check that this matches the last known type
+ if (o.getClass() != lastKnownType) {
+ // not all of the same type: set to null
+ lastKnownType = null;
+ }
+ } else // this is the first type we've found
+ {
+ // remember it
+ hasReadType = true;
+ lastKnownType = o.getClass();
+ }
+ }
+ result.add(o);
+ }
+ } else {
+ lastKnownType = null;
+ throw new WotonomyException("PropertyDataSource: " + "bound property was not an indexed property: " + key);
}
- else
- {
- lastKnownType = null;
- throw new WotonomyException( "PropertyDataSource: " +
- "bound property was not an indexed property: " + key );
+
+ return result;
+ }
+
+ /**
+ * Converts the specified List to lastKnownType and calls setValue().
+ */
+ protected void writeAsList(List anObjectList) {
+ if (source == null) {
+ throw new WotonomyException("PropertyDataSource: " + "no source object: " + key);
+ }
+
+ Class c = source.getClass();
+ Method m = Introspector.getPropertyReadMethod(c, key, new Class[0]);
+ if (m == null) {
+ throw new WotonomyException("Could not read property for object: " + key + " : " + source + " (" + c + ")");
}
- return result;
- }
-
- /**
- * Converts the specified List to lastKnownType
- * and calls setValue().
- */
- protected void writeAsList( List anObjectList )
- {
- if ( source == null )
- {
- throw new WotonomyException( "PropertyDataSource: " +
- "no source object: " + key );
- }
-
- Class c = source.getClass();
- Method m = Introspector.getPropertyReadMethod( c, key, new Class[0] );
- if ( m == null )
- {
- throw new WotonomyException( "Could not read property for object: "
- + key + " : " + source + " (" + c + ")" );
- }
-
- Class returnType = m.getReturnType();
-
- int count = anObjectList.size();
- Object result = null;
-
- if ( returnType.isArray() )
- {
- Class type = returnType.getComponentType();
- result = Array.newInstance( type, count );
- for ( int i = 0; i < count; i++ )
- {
- Array.set( result, i, anObjectList.get( i ) );
- }
- }
- else
- {
- Collection collection = null;
-
- if ( ! returnType.isInterface() )
- {
- try
- {
- collection = (Collection) returnType.newInstance();
- }
- catch ( Exception exc )
- {
- // no default constructor, leave null
- }
- }
-
- // try to find an acceptable collections type
- if ( collection == null )
- {
- if ( returnType.isAssignableFrom( NSMutableArray.class ) )
- {
- collection = new NSMutableArray();
- }
- else
- if ( returnType.isAssignableFrom( LinkedList.class ) )
- {
- collection = new LinkedList();
- }
- else
- if ( returnType.isAssignableFrom( ArrayList.class ) )
- {
- collection = new ArrayList();
- }
- else
- if ( returnType.isAssignableFrom( HashSet.class ) )
- {
- collection = new HashSet();
- }
- else
- if ( returnType.isAssignableFrom( TreeSet.class ) )
- {
- collection = new TreeSet();
- }
- }
-
- if ( collection == null )
- {
- throw new WotonomyException( "Could not create a collection of type: " + returnType );
- }
-
- collection.addAll( anObjectList );
- result = collection;
- }
-
- setValue( result );
- }
-
- /**
- * Returns the value of the indexed property
- * specified by qualifyWithRelationshipKey.
- */
- protected Object getValue()
- {
- if ( source instanceof EOKeyValueCoding )
- {
- return ((EOKeyValueCoding)source).valueForKey( key );
- }
- return EOKeyValueCodingSupport.valueForKey( source, key );
- }
-
- /**
- * Sets the value of the indexed property
- * specified by qualifyWithRelationshipKey.
- * The argument is assumed to be of appropriate
- * type for the property. EOObserverCenter is
- * notified that the object will change.
- */
- protected void setValue( Object aValue )
- {
- EOClassDescription sourceDesc =
- EOClassDescription.classDescriptionForClass( source.getClass() );
-
-
- // if we're not editing a relationship (?)
+ Class returnType = m.getReturnType();
+
+ int count = anObjectList.size();
+ Object result = null;
+
+ if (returnType.isArray()) {
+ Class type = returnType.getComponentType();
+ result = Array.newInstance(type, count);
+ for (int i = 0; i < count; i++) {
+ Array.set(result, i, anObjectList.get(i));
+ }
+ } else {
+ Collection collection = null;
+
+ if (!returnType.isInterface()) {
+ try {
+ collection = (Collection) returnType.newInstance();
+ } catch (Exception exc) {
+ // no default constructor, leave null
+ }
+ }
+
+ // try to find an acceptable collections type
+ if (collection == null) {
+ if (returnType.isAssignableFrom(NSMutableArray.class)) {
+ collection = new NSMutableArray();
+ } else if (returnType.isAssignableFrom(LinkedList.class)) {
+ collection = new LinkedList();
+ } else if (returnType.isAssignableFrom(ArrayList.class)) {
+ collection = new ArrayList();
+ } else if (returnType.isAssignableFrom(HashSet.class)) {
+ collection = new HashSet();
+ } else if (returnType.isAssignableFrom(TreeSet.class)) {
+ collection = new TreeSet();
+ }
+ }
+
+ if (collection == null) {
+ throw new WotonomyException("Could not create a collection of type: " + returnType);
+ }
+
+ collection.addAll(anObjectList);
+ result = collection;
+ }
+
+ setValue(result);
+ }
+
+ /**
+ * Returns the value of the indexed property specified by
+ * qualifyWithRelationshipKey.
+ */
+ protected Object getValue() {
+ if (source instanceof EOKeyValueCoding) {
+ return ((EOKeyValueCoding) source).valueForKey(key);
+ }
+ return EOKeyValueCodingSupport.valueForKey(source, key);
+ }
+
+ /**
+ * Sets the value of the indexed property specified by
+ * qualifyWithRelationshipKey. The argument is assumed to be of appropriate type
+ * for the property. EOObserverCenter is notified that the object will change.
+ */
+ protected void setValue(Object aValue) {
+ EOClassDescription sourceDesc = EOClassDescription.classDescriptionForClass(source.getClass());
+
+ // if we're not editing a relationship (?)
// if ( ! sourceDesc.toManyRelationshipKeys().containsObject( key ) )
- {
- // mark the parent as changed
- EOObserverCenter.notifyObserversObjectWillChange( source );
- }
-
-
- if ( source instanceof EOKeyValueCoding )
- {
- ((EOKeyValueCoding)source).takeValueForKey( aValue, key );
- }
- else
- {
- EOKeyValueCodingSupport.takeValueForKey( source, aValue, key );
- }
- }
-
+ {
+ // mark the parent as changed
+ EOObserverCenter.notifyObserversObjectWillChange(source);
+ }
+
+ if (source instanceof EOKeyValueCoding) {
+ ((EOKeyValueCoding) source).takeValueForKey(aValue, key);
+ } else {
+ EOKeyValueCodingSupport.takeValueForKey(source, aValue, key);
+ }
+ }
+
}
/*
- * $Log$
- * Revision 1.2 2006/02/16 16:47:14 cgruber
- * Move some classes in to "internal" packages and re-work imports, etc.
+ * $Log$ Revision 1.2 2006/02/16 16:47:14 cgruber Move some classes in to
+ * "internal" packages and re-work imports, etc.
*
- * Also use UnsupportedOperationExceptions where appropriate, instead of WotonomyExceptions.
+ * Also use UnsupportedOperationExceptions where appropriate, instead of
+ * WotonomyExceptions.
*
- * Revision 1.1 2006/02/16 13:19:57 cgruber
- * Check in all sources in eclipse-friendly maven-enabled packages.
+ * Revision 1.1 2006/02/16 13:19:57 cgruber Check in all sources in
+ * eclipse-friendly maven-enabled packages.
*
- * Revision 1.14 2003/01/18 23:30:42 mpowers
- * WODisplayGroup now compiles.
+ * Revision 1.14 2003/01/18 23:30:42 mpowers WODisplayGroup now compiles.
*
- * Revision 1.13 2002/10/24 21:15:36 mpowers
- * New implementations of NSArray and subclasses.
+ * Revision 1.13 2002/10/24 21:15:36 mpowers New implementations of NSArray and
+ * subclasses.
*
- * Revision 1.12 2002/10/24 18:18:12 mpowers
- * NSArray's are now considered read-only, so we can return our internal
- * representation to reduce unnecessary object allocation.
+ * Revision 1.12 2002/10/24 18:18:12 mpowers NSArray's are now considered
+ * read-only, so we can return our internal representation to reduce unnecessary
+ * object allocation.
*
- * Revision 1.11 2002/04/15 21:55:33 mpowers
- * Catching a condition where the get may not return the value passed to set.
+ * Revision 1.11 2002/04/15 21:55:33 mpowers Catching a condition where the get
+ * may not return the value passed to set.
*
- * Revision 1.10 2002/03/08 23:20:37 mpowers
- * insertObject now calls insertObjectAtIndex.
+ * Revision 1.10 2002/03/08 23:20:37 mpowers insertObject now calls
+ * insertObjectAtIndex.
*
- * Revision 1.9 2001/06/05 19:10:41 mpowers
- * Better handling of null properties.
+ * Revision 1.9 2001/06/05 19:10:41 mpowers Better handling of null properties.
*
- * Revision 1.8 2001/05/21 14:03:35 mpowers
- * Added a convenience constructor for java classes.
+ * Revision 1.8 2001/05/21 14:03:35 mpowers Added a convenience constructor for
+ * java classes.
*
- * Revision 1.7 2001/04/30 13:15:24 mpowers
- * Child contexts re-initializing objects invalidated in parent now
- * propery transpose relationships.
+ * Revision 1.7 2001/04/30 13:15:24 mpowers Child contexts re-initializing
+ * objects invalidated in parent now propery transpose relationships.
*
- * Revision 1.6 2001/04/29 02:29:31 mpowers
- * Debugging relationship faulting.
+ * Revision 1.6 2001/04/29 02:29:31 mpowers Debugging relationship faulting.
*
- * Revision 1.5 2001/04/28 22:17:51 mpowers
- * Revised PropertyDataSource to be EOClassDescription-aware.
+ * Revision 1.5 2001/04/28 22:17:51 mpowers Revised PropertyDataSource to be
+ * EOClassDescription-aware.
*
- * Revision 1.4 2001/04/27 23:37:20 mpowers
- * Now using EOClassDescription in the EODataSource class, as we should.
+ * Revision 1.4 2001/04/27 23:37:20 mpowers Now using EOClassDescription in the
+ * EODataSource class, as we should.
*
- * Revision 1.3 2001/03/29 03:29:49 mpowers
- * Now using KeyValueCoding and Support instead of Introspector.
+ * Revision 1.3 2001/03/29 03:29:49 mpowers Now using KeyValueCoding and Support
+ * instead of Introspector.
*
- * Revision 1.2 2001/01/24 14:10:53 mpowers
- * Contributing OrderedDataSource, and PropertyDataSource extends it.
+ * Revision 1.2 2001/01/24 14:10:53 mpowers Contributing OrderedDataSource, and
+ * PropertyDataSource extends it.
*
- * Revision 1.1.1.1 2000/12/21 15:46:50 mpowers
- * Contributing wotonomy.
+ * Revision 1.1.1.1 2000/12/21 15:46:50 mpowers Contributing wotonomy.
*
- * Revision 1.3 2000/12/20 16:25:35 michael
- * Added log to all files.
+ * Revision 1.3 2000/12/20 16:25:35 michael Added log to all files.
*
*
*/
-