summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java
diff options
context:
space:
mode:
authorBenjamin Culkin <scorpress@gmail.com>2024-05-20 17:58:16 -0400
committerBenjamin Culkin <scorpress@gmail.com>2024-05-20 17:58:16 -0400
commit40a9d99496e098562f090fb7ffce9e749011b131 (patch)
tree437df24d65470582e943e494a52db8ed65a881ae /projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java
parentff072dfe782f6f22123cd4ba050828d35c0d0fbd (diff)
Formatting pass
Diffstat (limited to 'projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java')
-rw-r--r--projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java605
1 files changed, 264 insertions, 341 deletions
diff --git a/projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java b/projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java
index 2aea8d3..54cd04e 100644
--- a/projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java
+++ b/projects/net.wotonomy.ui/src/main/java/net/wotonomy/ui/MasterDetailAssociation.java
@@ -27,380 +27,303 @@ import net.wotonomy.foundation.NSArray;
import net.wotonomy.foundation.NSMutableArray;
/**
-* MasterDetailAssociation binds a display group to a property
-* on the selected object of another display group.
-* Bindings are:
-* <ul>
-* <li>parent: The property on the selected object of the
-* bound display group that is expected to be an indexed property.</li>
-* </ul>
-*
-* @author michael@mpowers.net
-* @author $Author: cgruber $
-* @version $Revision: 904 $
-*/
-public class MasterDetailAssociation extends EOAssociation
-{
- static final NSArray aspects =
- new NSArray( new Object[] {
- ParentAspect
- } );
- static final NSArray aspectSignatures =
- new NSArray( new Object[] {
- AttributeToOneAspectSignature
- } );
- static final NSArray objectKeysTaken =
- new NSArray( new Object[] {
- "allObjects"
- } );
-
- /**
- * Used to be notified of changes to objects in the
- * controlled display group. requalify() should place
- * all objects fetched into the controlled group into
- * this array.
- * Otherwise, the parent object is only marked as
- * changed for inserts and deletes.
- */
- protected NSMutableArray observableArray;
-
- /**
- * Constructor expecting an EODisplayGroup.
- * If the controlled display group does not have a data source,
- * a new PropertyDataSource will be used.
- */
- public MasterDetailAssociation ( Object anObject )
- {
- super( anObject );
- observableArray = new ObservableArray( this );
- }
-
- /**
- * Returns a List of aspect signatures whose contents
- * correspond with the aspects list. Each element is
- * a string whose characters represent a capability of
- * the corresponding aspect. <ul>
- * <li>"A" attribute: the aspect can be bound to
- * an attribute.</li>
- * <li>"1" to-one: the aspect can be bound to a
- * property that returns a single object.</li>
- * <li>"M" to-one: the aspect can be bound to a
- * property that returns multiple objects.</li>
- * </ul>
- * An empty signature "" means that the aspect can
- * bind without needing a key.
- * This implementation returns "A1M" for each
- * element in the aspects array.
- */
- public static NSArray aspectSignatures ()
- {
- return aspectSignatures;
- }
-
- /**
- * Returns a List that describes the aspects supported
- * by this class. Each element in the list is the string
- * name of the aspect. This implementation returns an
- * empty list.
- */
- public static NSArray aspects ()
- {
- return aspects;
- }
-
- /**
- * Returns a List of EOAssociation subclasses that,
- * for the objects that are usable for this association,
- * are less suitable than this association.
- */
- public static NSArray associationClassesSuperseded ()
- {
- return new NSArray();
- }
-
- /**
- * Returns whether this class can control the specified
- * object.
- */
- public static boolean isUsableWithObject ( Object anObject )
- {
- return ( anObject instanceof EODisplayGroup );
- }
-
- /**
- * Returns a List of properties of the controlled object
- * that are controlled by this class. For example,
- * "stringValue", or "selected".
- */
- public static NSArray objectKeysTaken ()
- {
- return objectKeysTaken;
- }
-
- /**
- * Returns the aspect that is considered primary
- * or default. This is typically "value" or somesuch.
- */
- public static String primaryAspect ()
- {
- return ParentAspect;
- }
-
- /**
- * Returns whether this association can bind to the
- * specified display group on the specified key for
- * the specified aspect.
- */
- public boolean canBindAspect (
- String anAspect, EODisplayGroup aDisplayGroup, String aKey)
- {
- return ( aspects.containsObject( anAspect ) );
- }
-
- /**
- * Establishes a connection between this association
- * and the controlled object. Subclasses should begin
- * listening for events from their controlled object here.
- */
- public void establishConnection ()
- {
- //NOTE: if nothing refers to this assocation, it gets gc'd.
- // otherwise, this is not needed.
- component().addObserver( this );
-
- EODisplayGroup displayGroup =
- displayGroupForAspect( ParentAspect );
- String key =
- displayGroupKeyForAspect( ParentAspect );
-
- // obtain and qualify new data source from existing source if necessary
- if ( component().dataSource() == null )
- {
- if ( ( displayGroup != null ) && ( displayGroup.dataSource() != null ) )
- {
- component().setDataSource(
- displayGroup.dataSource().
- dataSourceQualifiedByKey( key ) );
- }
- }
-
- // set up proxy data source if necessary
- if ( component().dataSource() == null )
- {
- // get context and class desc from master group
- EOEditingContext editingContext = null;
- EOClassDescription classDesc = null;
- if ( displayGroup != null )
- {
- EODataSource dataSource = displayGroup.dataSource();
- if ( dataSource != null )
- {
- editingContext = dataSource.editingContext();
- EOClassDescription parentDesc = dataSource.classDescriptionForObjects();
- if ( parentDesc != null )
- {
- classDesc = parentDesc.classDescriptionForDestinationKey( key );
- }
- }
- }
-
- //FIXME: should this be called DetailDataSource?
- component().setDataSource(
- new PropertyDataSource( editingContext, classDesc ) );
- }
-
- super.establishConnection();
+ * MasterDetailAssociation binds a display group to a property on the selected
+ * object of another display group. Bindings are:
+ * <ul>
+ * <li>parent: The property on the selected object of the bound display group
+ * that is expected to be an indexed property.</li>
+ * </ul>
+ *
+ * @author michael@mpowers.net
+ * @author $Author: cgruber $
+ * @version $Revision: 904 $
+ */
+public class MasterDetailAssociation extends EOAssociation {
+ static final NSArray aspects = new NSArray(new Object[] { ParentAspect });
+ static final NSArray aspectSignatures = new NSArray(new Object[] { AttributeToOneAspectSignature });
+ static final NSArray objectKeysTaken = new NSArray(new Object[] { "allObjects" });
+
+ /**
+ * Used to be notified of changes to objects in the controlled display group.
+ * requalify() should place all objects fetched into the controlled group into
+ * this array. Otherwise, the parent object is only marked as changed for
+ * inserts and deletes.
+ */
+ protected NSMutableArray observableArray;
+
+ /**
+ * Constructor expecting an EODisplayGroup. If the controlled display group does
+ * not have a data source, a new PropertyDataSource will be used.
+ */
+ public MasterDetailAssociation(Object anObject) {
+ super(anObject);
+ observableArray = new ObservableArray(this);
+ }
+
+ /**
+ * Returns a List of aspect signatures whose contents correspond with the
+ * aspects list. Each element is a string whose characters represent a
+ * capability of the corresponding aspect.
+ * <ul>
+ * <li>"A" attribute: the aspect can be bound to an attribute.</li>
+ * <li>"1" to-one: the aspect can be bound to a property that returns a single
+ * object.</li>
+ * <li>"M" to-one: the aspect can be bound to a property that returns multiple
+ * objects.</li>
+ * </ul>
+ * An empty signature "" means that the aspect can bind without needing a key.
+ * This implementation returns "A1M" for each element in the aspects array.
+ */
+ public static NSArray aspectSignatures() {
+ return aspectSignatures;
+ }
+
+ /**
+ * Returns a List that describes the aspects supported by this class. Each
+ * element in the list is the string name of the aspect. This implementation
+ * returns an empty list.
+ */
+ public static NSArray aspects() {
+ return aspects;
+ }
+
+ /**
+ * Returns a List of EOAssociation subclasses that, for the objects that are
+ * usable for this association, are less suitable than this association.
+ */
+ public static NSArray associationClassesSuperseded() {
+ return new NSArray();
+ }
+
+ /**
+ * Returns whether this class can control the specified object.
+ */
+ public static boolean isUsableWithObject(Object anObject) {
+ return (anObject instanceof EODisplayGroup);
+ }
+
+ /**
+ * Returns a List of properties of the controlled object that are controlled by
+ * this class. For example, "stringValue", or "selected".
+ */
+ public static NSArray objectKeysTaken() {
+ return objectKeysTaken;
+ }
+
+ /**
+ * Returns the aspect that is considered primary or default. This is typically
+ * "value" or somesuch.
+ */
+ public static String primaryAspect() {
+ return ParentAspect;
+ }
+
+ /**
+ * Returns whether this association can bind to the specified display group on
+ * the specified key for the specified aspect.
+ */
+ public boolean canBindAspect(String anAspect, EODisplayGroup aDisplayGroup, String aKey) {
+ return (aspects.containsObject(anAspect));
+ }
+
+ /**
+ * Establishes a connection between this association and the controlled object.
+ * Subclasses should begin listening for events from their controlled object
+ * here.
+ */
+ public void establishConnection() {
+ // NOTE: if nothing refers to this assocation, it gets gc'd.
+ // otherwise, this is not needed.
+ component().addObserver(this);
+
+ EODisplayGroup displayGroup = displayGroupForAspect(ParentAspect);
+ String key = displayGroupKeyForAspect(ParentAspect);
+
+ // obtain and qualify new data source from existing source if necessary
+ if (component().dataSource() == null) {
+ if ((displayGroup != null) && (displayGroup.dataSource() != null)) {
+ component().setDataSource(displayGroup.dataSource().dataSourceQualifiedByKey(key));
+ }
+ }
+
+ // set up proxy data source if necessary
+ if (component().dataSource() == null) {
+ // get context and class desc from master group
+ EOEditingContext editingContext = null;
+ EOClassDescription classDesc = null;
+ if (displayGroup != null) {
+ EODataSource dataSource = displayGroup.dataSource();
+ if (dataSource != null) {
+ editingContext = dataSource.editingContext();
+ EOClassDescription parentDesc = dataSource.classDescriptionForObjects();
+ if (parentDesc != null) {
+ classDesc = parentDesc.classDescriptionForDestinationKey(key);
+ }
+ }
+ }
+
+ // FIXME: should this be called DetailDataSource?
+ component().setDataSource(new PropertyDataSource(editingContext, classDesc));
+ }
+
+ super.establishConnection();
requalify();
- }
-
- /**
- * Breaks the connection between this association and
- * its object. Override to stop listening for events
- * from the object.
- */
- public void breakConnection ()
- {
- //NOTE: if nothing refers to this assocation, it gets gc'd.
- // otherwise, this is not needed.
- component().deleteObserver( this );
-
- super.breakConnection();
- }
-
- /**
- * Called when either the selection or the contents
- * of an associated display group have changed.
- */
- public void subjectChanged ()
- {
+ }
+
+ /**
+ * Breaks the connection between this association and its object. Override to
+ * stop listening for events from the object.
+ */
+ public void breakConnection() {
+ // NOTE: if nothing refers to this assocation, it gets gc'd.
+ // otherwise, this is not needed.
+ component().deleteObserver(this);
+
+ super.breakConnection();
+ }
+
+ /**
+ * Called when either the selection or the contents of an associated display
+ * group have changed.
+ */
+ public void subjectChanged() {
EODisplayGroup displayGroup;
// parent aspect
- displayGroup = displayGroupForAspect( ParentAspect );
- if ( displayGroup != null )
- {
- if ( displayGroup.selectionChanged() )
- {
- requalify();
+ displayGroup = displayGroupForAspect(ParentAspect);
+ if (displayGroup != null) {
+ if (displayGroup.selectionChanged()) {
+ requalify();
+ } else if (displayGroup.contentsChanged()) {
+ requalify();
}
- else
- if ( displayGroup.contentsChanged() )
- {
- requalify();
+ }
+ }
+
+ /**
+ * Overridden to intercept notifications of changes to objects in the controlled
+ * display group and broadcast a change on the parent group's selected object.
+ * All other notifications are passed to the super implementation.
+ */
+ public void objectWillChange(Object anObject) {
+ // if child display group is notifying
+ if (!(anObject instanceof EODisplayGroup)) {
+ // mark parent group's object as changed
+ EODisplayGroup displayGroup = displayGroupForAspect(ParentAspect);
+ if (displayGroup != null) {
+ Object selected = displayGroup.selectedObject();
+ if (selected != null) {
+ // only notify if childrenKey is an attribute of parentDesc
+ // (and therefore not a toOne or toMany relationship)
+ EOClassDescription parentDesc = EOClassDescription.classDescriptionForClass(selected.getClass());
+ String key = displayGroupKeyForAspect(ParentAspect);
+ if (key != null) {
+ int idx = key.indexOf('.');
+ if (idx != -1)
+ key = key.substring(0, idx);
+ if (parentDesc.attributeKeys().contains(key)) {
+ // only notify if we are an attribute key
+ EOObserverCenter.notifyObserversObjectWillChange(selected);
+ }
+ }
+ }
}
+ } else // display group is notifying
+ {
+ // call super so subjectChanged will be called
+ super.objectWillChange(anObject);
}
- }
-
- /**
- * Overridden to intercept notifications of changes to objects
- * in the controlled display group and broadcast a change on the
- * parent group's selected object. All other notifications are
- * passed to the super implementation.
- */
- public void objectWillChange ( Object anObject )
- {
- // if child display group is notifying
- if ( ! ( anObject instanceof EODisplayGroup ) )
- {
- // mark parent group's object as changed
- EODisplayGroup displayGroup = displayGroupForAspect( ParentAspect );
- if ( displayGroup != null )
- {
- Object selected = displayGroup.selectedObject();
- if ( selected != null )
- {
- // only notify if childrenKey is an attribute of parentDesc
- // (and therefore not a toOne or toMany relationship)
- EOClassDescription parentDesc =
- EOClassDescription.classDescriptionForClass(
- selected.getClass() );
- String key = displayGroupKeyForAspect( ParentAspect );
- if ( key != null )
- {
- int idx = key.indexOf( '.' );
- if ( idx != -1 ) key = key.substring( 0, idx );
- if ( parentDesc.attributeKeys().contains( key ) )
- {
- // only notify if we are an attribute key
- EOObserverCenter.notifyObserversObjectWillChange( selected );
- }
- }
- }
- }
- }
- else // display group is notifying
- {
- // call super so subjectChanged will be called
- super.objectWillChange( anObject );
- }
- }
-
- /**
- * Called by subjectChanged() to requalify the controlled
- * display group with the selected object and the bound key.
- */
- protected void requalify()
- {
+ }
+
+ /**
+ * Called by subjectChanged() to requalify the controlled display group with the
+ * selected object and the bound key.
+ */
+ protected void requalify() {
EODisplayGroup component = component();
- EODisplayGroup displayGroup = displayGroupForAspect( ParentAspect );
- String key = displayGroupKeyForAspect( ParentAspect );
-
- if ( ( displayGroup.selectedObject() != null )
- && ( component.dataSource() != null ) )
- {
- component.dataSource().qualifyWithRelationshipKey(
- key, displayGroup.selectedObject() );
+ EODisplayGroup displayGroup = displayGroupForAspect(ParentAspect);
+ String key = displayGroupKeyForAspect(ParentAspect);
+
+ if ((displayGroup.selectedObject() != null) && (component.dataSource() != null)) {
+ component.dataSource().qualifyWithRelationshipKey(key, displayGroup.selectedObject());
component.fetch();
- observableArray.setArray( component.allObjects() );
- }
- else // no selection or no data source, clear
+ observableArray.setArray(component.allObjects());
+ } else // no selection or no data source, clear
{
- component.setObjectArray( null );
- observableArray.removeAllObjects();
+ component.setObjectArray(null);
+ observableArray.removeAllObjects();
}
- component.updateDisplayedObjects();
+ component.updateDisplayedObjects();
+ }
+
+ /**
+ * This implementation returns ObserverPrioritySecond so that master detail
+ * assocations are notified before other associations.
+ */
+ public int priority() {
+ return ObserverPrioritySecond;
}
-
- /**
- * This implementation returns ObserverPrioritySecond
- * so that master detail assocations are notified before
- * other associations.
- */
- public int priority ()
- {
- return ObserverPrioritySecond;
- }
// convenience
- private EODisplayGroup component()
- {
- return (EODisplayGroup) object();
- }
-
+ private EODisplayGroup component() {
+ return (EODisplayGroup) object();
+ }
+
}
/*
- * $Log$
- * Revision 1.2 2006/02/18 23:14:35 cgruber
- * Update imports and maven dependencies.
+ * $Log$ Revision 1.2 2006/02/18 23:14:35 cgruber Update imports and maven
+ * dependencies.
*
- * Revision 1.1 2006/02/16 13:22:22 cgruber
- * Check in all sources in eclipse-friendly maven-enabled packages.
+ * Revision 1.1 2006/02/16 13:22:22 cgruber Check in all sources in
+ * eclipse-friendly maven-enabled packages.
*
- * Revision 1.14 2004/02/04 20:00:49 mpowers
- * Improved change notification for dotted key paths.
+ * Revision 1.14 2004/02/04 20:00:49 mpowers Improved change notification for
+ * dotted key paths.
*
- * Revision 1.13 2003/08/06 23:07:52 chochos
- * general code cleanup (mostly, removing unused imports)
+ * Revision 1.13 2003/08/06 23:07:52 chochos general code cleanup (mostly,
+ * removing unused imports)
*
- * Revision 1.12 2001/10/26 18:39:05 mpowers
- * Now a delayed observer with a higher priority, so that it is processed
- * before other associations.
+ * Revision 1.12 2001/10/26 18:39:05 mpowers Now a delayed observer with a
+ * higher priority, so that it is processed before other associations.
*
- * Revision 1.11 2001/06/26 21:39:33 mpowers
- * Added check for null component data source before requalifying.
+ * Revision 1.11 2001/06/26 21:39:33 mpowers Added check for null component data
+ * source before requalifying.
*
- * Revision 1.10 2001/05/21 14:04:15 mpowers
- * No longer changing a detail group's data source if it's already specified.
+ * Revision 1.10 2001/05/21 14:04:15 mpowers No longer changing a detail group's
+ * data source if it's already specified.
*
- * Revision 1.9 2001/05/18 21:08:46 mpowers
- * Now calling updateDisplayedObjects on detail after master changes.
+ * Revision 1.9 2001/05/18 21:08:46 mpowers Now calling updateDisplayedObjects
+ * on detail after master changes.
*
- * Revision 1.8 2001/05/14 15:26:42 mpowers
- * Modified logic for controlled groups that have no data source already set.
+ * Revision 1.8 2001/05/14 15:26:42 mpowers Modified logic for controlled groups
+ * that have no data source already set.
*
- * Revision 1.7 2001/05/04 14:42:58 mpowers
- * Now getting stored values in KeyValueCoding.
- * MasterDetail now marks dirty based on whether it's an attribute
- * or relation.
- * Implemented editing context marker.
+ * Revision 1.7 2001/05/04 14:42:58 mpowers Now getting stored values in
+ * KeyValueCoding. MasterDetail now marks dirty based on whether it's an
+ * attribute or relation. Implemented editing context marker.
*
- * 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.4 2001/02/20 16:38:55 mpowers
- * MasterDetailAssociations now observe their controlled display group's
- * objects for changes to that the parent object will be marked as updated.
- * Before, only inserts and deletes to an object's items are registered.
- * Also, moved ObservableArray to package access.
+ * Revision 1.4 2001/02/20 16:38:55 mpowers MasterDetailAssociations now observe
+ * their controlled display group's objects for changes to that the parent
+ * object will be marked as updated. Before, only inserts and deletes to an
+ * object's items are registered. Also, moved ObservableArray to package access.
*
- * Revision 1.3 2001/01/18 16:57:18 mpowers
- * Fixed problem with losing connection: the association was getting
- * garbage collected because nothing referred to it. All other associations
- * make themselves listeners of their controlled object, and that has been
- * the only thing keeping them from getting gc'd. This will need to be fixed.
+ * Revision 1.3 2001/01/18 16:57:18 mpowers Fixed problem with losing
+ * connection: the association was getting garbage collected because nothing
+ * referred to it. All other associations make themselves listeners of their
+ * controlled object, and that has been the only thing keeping them from getting
+ * gc'd. This will need to be fixed.
*
- * Revision 1.2 2001/01/17 23:06:09 mpowers
- * TreeAssociation now modifies the contents of the children display
- * group rather than adding items to the titles display group.
+ * Revision 1.2 2001/01/17 23:06:09 mpowers TreeAssociation now modifies the
+ * contents of the children display group rather than adding items to the titles
+ * display group.
*
- * Revision 1.1.1.1 2000/12/21 15:48:23 mpowers
- * Contributing wotonomy.
+ * Revision 1.1.1.1 2000/12/21 15:48:23 mpowers Contributing wotonomy.
*
- * Revision 1.5 2000/12/20 16:25:40 michael
- * Added log to all files.
+ * Revision 1.5 2000/12/20 16:25:40 michael Added log to all files.
*
*
*/
-