summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java
diff options
context:
space:
mode:
Diffstat (limited to 'projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java')
-rw-r--r--projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java672
1 files changed, 292 insertions, 380 deletions
diff --git a/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java b/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java
index 5792303..9eece7e 100644
--- a/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java
+++ b/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSKeyValueCoding.java
@@ -25,374 +25,293 @@ import net.wotonomy.foundation.internal.NullPrimitiveException;
import net.wotonomy.foundation.internal.WotonomyException;
/**
-* NSKeyValueCoding defines an interface for classes that
-* need to have more control over the wotonomy's property
-* introspection facilities. <br><br>
-*
-* On an object that implements this interface, wotonomy
-* will call these methods, and otherwise use the static
-* methods on NSKeyValueCodingSupport. <br><br>
-*
-* NSKeyValueCodingSupport implements the default behaviors
-* for each of these methods, so classes implementing this
-* interface can call those methods to acheive the same
-* behavior. <br><br>
-*
-* valueForKey and takeValueForKey are called in response
-* to user actions, like viewing an object or updating its
-* value in a user interface. These should call the public
-* getter and setter methods on the object itself and the
-* operations should be subject to validation. <br><br>
-*
-* storedValueForKey and takeStoredValueForKey are called
-* in response to wotonomy actions, like snapshotting,
-* faulting, commits, and reverts. These operations should
-* bypass the public methods and directly modify the internal
-* state of the object without validation.
-*
-* @author michael@mpowers.net
-* @author $Author: cgruber $
-* @version $Revision: 893 $
-*/
-public interface NSKeyValueCoding
-{
+ * NSKeyValueCoding defines an interface for classes that need to have more
+ * control over the wotonomy's property introspection facilities. <br>
+ * <br>
+ *
+ * On an object that implements this interface, wotonomy will call these
+ * methods, and otherwise use the static methods on NSKeyValueCodingSupport.
+ * <br>
+ * <br>
+ *
+ * NSKeyValueCodingSupport implements the default behaviors for each of these
+ * methods, so classes implementing this interface can call those methods to
+ * acheive the same behavior. <br>
+ * <br>
+ *
+ * valueForKey and takeValueForKey are called in response to user actions, like
+ * viewing an object or updating its value in a user interface. These should
+ * call the public getter and setter methods on the object itself and the
+ * operations should be subject to validation. <br>
+ * <br>
+ *
+ * storedValueForKey and takeStoredValueForKey are called in response to
+ * wotonomy actions, like snapshotting, faulting, commits, and reverts. These
+ * operations should bypass the public methods and directly modify the internal
+ * state of the object without validation.
+ *
+ * @author michael@mpowers.net
+ * @author $Author: cgruber $
+ * @version $Revision: 893 $
+ */
+public interface NSKeyValueCoding {
public static final Null NullValue = new Null();
- /**
- * Returns the value for the specified property.
- * If the property does not exist, this method should
- * call handleQueryWithUnboundKey.
- */
- Object valueForKey( String aKey );
-
- /**
- * Sets the property to the specified value.
- * If the property does not exist, this method should
- * call handleTakeValueForUnboundKey.
- * If the property is of a type that cannot allow
- * null (e.g. primitive types) and aValue is null,
- * this method should call unableToSetNullForKey.
- */
- void takeValueForKey( Object aValue, String aKey );
-
- /**
- * Returns the value for the private field that
- * corresponds to the specified property.
- */
- Object storedValueForKey( String aKey );
-
- /**
- * Sets the the private field that corresponds to the
- * specified property to the specified value.
- */
- void takeStoredValueForKey( Object aValue, String aKey );
-
- /**
- * Called by valueForKey when the specified key is
- * not found on this object. Implementing classes
- * should handle the specified value or otherwise
- * throw an exception.
- */
- Object handleQueryWithUnboundKey( String aKey );
-
- /**
- * Called by takeValueForKey when the specified key
- * is not found on this object. Implementing classes
- * should handle the specified value or otherwise
- * throw an exception.
- */
- void handleTakeValueForUnboundKey( Object aValue, String aKey );
-
- /**
- * Called by takeValueForKey when the type of the
- * specified key is not allowed to be null, as is
- * the case with primitive types. Implementing
- * classes should handle this case appropriately
- * or otherwise throw an exception.
- */
- void unableToSetNullForKey( String aKey );
-
- /**
- * Static utility methods that
- * call the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- public class Utility
- {
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public Object valueForKey(
- Object anObject, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- return ((NSKeyValueCoding)anObject).valueForKey( aKey );
- }
- return DefaultImplementation.valueForKey( anObject, aKey );
- }
-
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public void takeValueForKey(
- Object anObject, Object aValue, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- ((NSKeyValueCoding)anObject).takeValueForKey( aValue, aKey );
- }
- DefaultImplementation.takeValueForKey( anObject, aValue, aKey );
- }
-
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public Object storedValueForKey(
- Object anObject, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- return ((NSKeyValueCoding)anObject).storedValueForKey( aKey );
- }
- return DefaultImplementation.storedValueForKey( anObject, aKey );
- }
-
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public void takeStoredValueForKey(
- Object anObject, Object aValue, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- ((NSKeyValueCoding)anObject).takeStoredValueForKey( aValue, aKey );
- }
- DefaultImplementation.takeStoredValueForKey( anObject, aValue, aKey );
- }
-
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public Object handleQueryWithUnboundKey(
- Object anObject, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- return ((NSKeyValueCoding)anObject).handleQueryWithUnboundKey( aKey );
- }
- return DefaultImplementation.handleQueryWithUnboundKey( anObject, aKey );
- }
-
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public void handleTakeValueForUnboundKey(
- Object anObject, Object aValue, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- ((NSKeyValueCoding)anObject).handleTakeValueForUnboundKey( aValue, aKey );
- }
- DefaultImplementation.handleTakeValueForUnboundKey( anObject, aValue, aKey );
- }
-
- /**
- * Calls the appropriate method if the object implements
- * NSKeyValueCoding, otherwise calls the method
- * on DefaultImplementation.
- */
- static public void unableToSetNullForKey(
- Object anObject, String aKey )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- ((NSKeyValueCoding)anObject).unableToSetNullForKey( aKey );
- }
- DefaultImplementation.unableToSetNullForKey( anObject, aKey );
- }
- }
-
- public class DefaultImplementation
- {
- /**
- * Returns the value for the specified property key
- * on the specified object. <br><br>
- *
- * If the property does not exist, this method calls
- * handleQueryWithUnboundKey on the object if it
- * implements NSKeyValueCoding, otherwise calls
- * handleQueryWithUnboundKey on this class. <br><br>
- */
- static public Object valueForKey(
- Object anObject, String aKey )
- {
- if ( anObject == null ) return null;
- //TODO: may need to handle "." nesting here so
- // that handleQueryWithUnboundKey gets called for
- // for the nested object, not the parent object
-
- //Correction: need to handle key paths in
- // KeyValueCodingAdditionsSupport.
-
- try
- {
- return Introspector.get( anObject, aKey );
- }
- catch ( IntrospectorException exc )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- return ((NSKeyValueCoding)anObject).handleQueryWithUnboundKey( aKey );
- }
- return handleQueryWithUnboundKey( anObject, aKey );
- }
- }
-
- /**
- * Sets the property to the specified value on
- * the specified object.
- *
- * If the property does not exist, this method calls
- * handleTakeValueForUnboundKey on the object if it
- * implements NSKeyValueCoding, otherwise calls
- * handleTakeValueForUnboundKey on this class.
- *
- * If the property is of a type that cannot allow
- * null (e.g. primitive types) and aValue is null,
- * this method should call unableToSetNullForKey
- * on the object if it implements NSKeyValueCoding,
- * otherwise calls unableToSetNullForKey on this class.
- */
- static public void takeValueForKey(
- Object anObject, Object aValue, String aKey )
- {
- if ( anObject == null ) return;
- //TODO: may need to handle "." nesting here so
- // that handleTakeValueForUnboundKey gets called for
- // for the nested object, not the parent object
- try
- {
- Introspector.set( anObject, aKey, aValue );
- }
- catch ( NullPrimitiveException exc )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- ((NSKeyValueCoding)anObject).unableToSetNullForKey( aKey );
- }
- else
- {
- unableToSetNullForKey( anObject, aKey );
- }
- }
- catch ( MissingPropertyException exc )
- {
- if ( anObject instanceof NSKeyValueCoding )
- {
- ((NSKeyValueCoding)anObject).handleTakeValueForUnboundKey(
- aValue, aKey );
- }
- else
- {
- handleTakeValueForUnboundKey( anObject, aValue, aKey );
- }
- }
-
- }
-
- /**
- * Returns the value for the private field that
- * corresponds to the specified property on
- * the specified object.
- *
- * This implementation currently calls valueForKey,
- * because java security currently prevents us from
- * accessing the fields of another object.
- */
- static public Object storedValueForKey(
- Object anObject, String aKey )
- {
- //TODO: this currently just calls valueForKey
- return valueForKey( anObject, aKey );
- }
-
- /**
- * Sets the the private field that corresponds to the
- * specified property to the specified value on the
- * specified object.
- *
- * This implementation currently calls takeValueForKey,
- * because java security currently prevents us from
- * accessing the fields of another object.
- */
- static public void takeStoredValueForKey(
- Object anObject, Object aValue, String aKey )
- {
- //TODO: this currently just calls takeValueForKey
- takeValueForKey( anObject, aValue, aKey );
- }
-
- /**
- * Called by valueForKey when the specified key is
- * not found on the specified object, if that object
- * does not implement NSKeyValueCoding.
- *
- * This implementation throws a WotonomyException.
- */
- static public Object handleQueryWithUnboundKey(
- Object anObject, String aKey )
- {
- throw new WotonomyException(
- "Key not found for object: "
- + aKey + " : " + anObject );
- }
-
- /**
- * Called by takeValueForKey when the specified key
- * is not found on the specified object, if that object
- * does not implement NSKeyValueCoding.
- *
- * This implementation throws a WotonomyException.
- */
- static public void handleTakeValueForUnboundKey(
- Object anObject, Object aValue, String aKey )
- {
- throw new WotonomyException(
- "Key not found for object while setting value: "
- + aKey + " : " + anObject + " : " + aValue );
- }
-
- /**
- * Called by takeValueForKey when the type of the
- * specified key is not allowed to be null, as is
- * the case with primitive types, if the specified
- * object does not implement NSKeyValueCoding.
- *
- * This implementation throws a WotonomyException.
- */
- static public void unableToSetNullForKey(
- Object anObject, String aKey )
- {
- throw new WotonomyException(
- "Tried to key on object to null: "
- + aKey + " : " + anObject );
- }
- }
+ /**
+ * Returns the value for the specified property. If the property does not exist,
+ * this method should call handleQueryWithUnboundKey.
+ */
+ Object valueForKey(String aKey);
+
+ /**
+ * Sets the property to the specified value. If the property does not exist,
+ * this method should call handleTakeValueForUnboundKey. If the property is of a
+ * type that cannot allow null (e.g. primitive types) and aValue is null, this
+ * method should call unableToSetNullForKey.
+ */
+ void takeValueForKey(Object aValue, String aKey);
+
+ /**
+ * Returns the value for the private field that corresponds to the specified
+ * property.
+ */
+ Object storedValueForKey(String aKey);
+
+ /**
+ * Sets the the private field that corresponds to the specified property to the
+ * specified value.
+ */
+ void takeStoredValueForKey(Object aValue, String aKey);
+
+ /**
+ * Called by valueForKey when the specified key is not found on this object.
+ * Implementing classes should handle the specified value or otherwise throw an
+ * exception.
+ */
+ Object handleQueryWithUnboundKey(String aKey);
+
+ /**
+ * Called by takeValueForKey when the specified key is not found on this object.
+ * Implementing classes should handle the specified value or otherwise throw an
+ * exception.
+ */
+ void handleTakeValueForUnboundKey(Object aValue, String aKey);
+
+ /**
+ * Called by takeValueForKey when the type of the specified key is not allowed
+ * to be null, as is the case with primitive types. Implementing classes should
+ * handle this case appropriately or otherwise throw an exception.
+ */
+ void unableToSetNullForKey(String aKey);
+
+ /**
+ * Static utility methods that call the appropriate method if the object
+ * implements NSKeyValueCoding, otherwise calls the method on
+ * DefaultImplementation.
+ */
+ public class Utility {
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public Object valueForKey(Object anObject, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ return ((NSKeyValueCoding) anObject).valueForKey(aKey);
+ }
+ return DefaultImplementation.valueForKey(anObject, aKey);
+ }
+
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public void takeValueForKey(Object anObject, Object aValue, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ ((NSKeyValueCoding) anObject).takeValueForKey(aValue, aKey);
+ }
+ DefaultImplementation.takeValueForKey(anObject, aValue, aKey);
+ }
+
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public Object storedValueForKey(Object anObject, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ return ((NSKeyValueCoding) anObject).storedValueForKey(aKey);
+ }
+ return DefaultImplementation.storedValueForKey(anObject, aKey);
+ }
+
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public void takeStoredValueForKey(Object anObject, Object aValue, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ ((NSKeyValueCoding) anObject).takeStoredValueForKey(aValue, aKey);
+ }
+ DefaultImplementation.takeStoredValueForKey(anObject, aValue, aKey);
+ }
+
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public Object handleQueryWithUnboundKey(Object anObject, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ return ((NSKeyValueCoding) anObject).handleQueryWithUnboundKey(aKey);
+ }
+ return DefaultImplementation.handleQueryWithUnboundKey(anObject, aKey);
+ }
+
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public void handleTakeValueForUnboundKey(Object anObject, Object aValue, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ ((NSKeyValueCoding) anObject).handleTakeValueForUnboundKey(aValue, aKey);
+ }
+ DefaultImplementation.handleTakeValueForUnboundKey(anObject, aValue, aKey);
+ }
+
+ /**
+ * Calls the appropriate method if the object implements NSKeyValueCoding,
+ * otherwise calls the method on DefaultImplementation.
+ */
+ static public void unableToSetNullForKey(Object anObject, String aKey) {
+ if (anObject instanceof NSKeyValueCoding) {
+ ((NSKeyValueCoding) anObject).unableToSetNullForKey(aKey);
+ }
+ DefaultImplementation.unableToSetNullForKey(anObject, aKey);
+ }
+ }
+
+ public class DefaultImplementation {
+ /**
+ * Returns the value for the specified property key on the specified object.
+ * <br>
+ * <br>
+ *
+ * If the property does not exist, this method calls handleQueryWithUnboundKey
+ * on the object if it implements NSKeyValueCoding, otherwise calls
+ * handleQueryWithUnboundKey on this class. <br>
+ * <br>
+ */
+ static public Object valueForKey(Object anObject, String aKey) {
+ if (anObject == null)
+ return null;
+ // TODO: may need to handle "." nesting here so
+ // that handleQueryWithUnboundKey gets called for
+ // for the nested object, not the parent object
+
+ // Correction: need to handle key paths in
+ // KeyValueCodingAdditionsSupport.
+
+ try {
+ return Introspector.get(anObject, aKey);
+ } catch (IntrospectorException exc) {
+ if (anObject instanceof NSKeyValueCoding) {
+ return ((NSKeyValueCoding) anObject).handleQueryWithUnboundKey(aKey);
+ }
+ return handleQueryWithUnboundKey(anObject, aKey);
+ }
+ }
+
+ /**
+ * Sets the property to the specified value on the specified object.
+ *
+ * If the property does not exist, this method calls
+ * handleTakeValueForUnboundKey on the object if it implements NSKeyValueCoding,
+ * otherwise calls handleTakeValueForUnboundKey on this class.
+ *
+ * If the property is of a type that cannot allow null (e.g. primitive types)
+ * and aValue is null, this method should call unableToSetNullForKey on the
+ * object if it implements NSKeyValueCoding, otherwise calls
+ * unableToSetNullForKey on this class.
+ */
+ static public void takeValueForKey(Object anObject, Object aValue, String aKey) {
+ if (anObject == null)
+ return;
+ // TODO: may need to handle "." nesting here so
+ // that handleTakeValueForUnboundKey gets called for
+ // for the nested object, not the parent object
+ try {
+ Introspector.set(anObject, aKey, aValue);
+ } catch (NullPrimitiveException exc) {
+ if (anObject instanceof NSKeyValueCoding) {
+ ((NSKeyValueCoding) anObject).unableToSetNullForKey(aKey);
+ } else {
+ unableToSetNullForKey(anObject, aKey);
+ }
+ } catch (MissingPropertyException exc) {
+ if (anObject instanceof NSKeyValueCoding) {
+ ((NSKeyValueCoding) anObject).handleTakeValueForUnboundKey(aValue, aKey);
+ } else {
+ handleTakeValueForUnboundKey(anObject, aValue, aKey);
+ }
+ }
+
+ }
+
+ /**
+ * Returns the value for the private field that corresponds to the specified
+ * property on the specified object.
+ *
+ * This implementation currently calls valueForKey, because java security
+ * currently prevents us from accessing the fields of another object.
+ */
+ static public Object storedValueForKey(Object anObject, String aKey) {
+ // TODO: this currently just calls valueForKey
+ return valueForKey(anObject, aKey);
+ }
+
+ /**
+ * Sets the the private field that corresponds to the specified property to the
+ * specified value on the specified object.
+ *
+ * This implementation currently calls takeValueForKey, because java security
+ * currently prevents us from accessing the fields of another object.
+ */
+ static public void takeStoredValueForKey(Object anObject, Object aValue, String aKey) {
+ // TODO: this currently just calls takeValueForKey
+ takeValueForKey(anObject, aValue, aKey);
+ }
+
+ /**
+ * Called by valueForKey when the specified key is not found on the specified
+ * object, if that object does not implement NSKeyValueCoding.
+ *
+ * This implementation throws a WotonomyException.
+ */
+ static public Object handleQueryWithUnboundKey(Object anObject, String aKey) {
+ throw new WotonomyException("Key not found for object: " + aKey + " : " + anObject);
+ }
+
+ /**
+ * Called by takeValueForKey when the specified key is not found on the
+ * specified object, if that object does not implement NSKeyValueCoding.
+ *
+ * This implementation throws a WotonomyException.
+ */
+ static public void handleTakeValueForUnboundKey(Object anObject, Object aValue, String aKey) {
+ throw new WotonomyException(
+ "Key not found for object while setting value: " + aKey + " : " + anObject + " : " + aValue);
+ }
+
+ /**
+ * Called by takeValueForKey when the type of the specified key is not allowed
+ * to be null, as is the case with primitive types, if the specified object does
+ * not implement NSKeyValueCoding.
+ *
+ * This implementation throws a WotonomyException.
+ */
+ static public void unableToSetNullForKey(Object anObject, String aKey) {
+ throw new WotonomyException("Tried to key on object to null: " + aKey + " : " + anObject);
+ }
+ }
public class Null {
public Null() {
@@ -406,26 +325,19 @@ public interface NSKeyValueCoding
}
/*
- * $Log$
- * Revision 1.2 2006/02/16 13:15:00 cgruber
- * Check in all sources in eclipse-friendly maven-enabled packages.
+ * $Log$ Revision 1.2 2006/02/16 13:15:00 cgruber Check in all sources in
+ * eclipse-friendly maven-enabled packages.
*
- * Revision 1.3 2003/08/07 02:43:56 chochos
- * added NullValue, which points to a Null instance.
+ * Revision 1.3 2003/08/07 02:43:56 chochos added NullValue, which points to a
+ * Null instance.
*
- * Revision 1.2 2003/01/18 23:30:42 mpowers
- * WODisplayGroup now compiles.
+ * Revision 1.2 2003/01/18 23:30:42 mpowers WODisplayGroup now compiles.
*
- * Revision 1.1 2003/01/17 14:40:49 mpowers
- * Adding files to fix build.
+ * Revision 1.1 2003/01/17 14:40:49 mpowers Adding files to fix build.
*
- * Revision 1.2 2001/03/28 16:12:30 mpowers
- * Documented interface.
+ * Revision 1.2 2001/03/28 16:12:30 mpowers Documented interface.
*
- * Revision 1.1 2001/03/27 23:25:05 mpowers
- * Contributing interface, no docs yet.
+ * Revision 1.1 2001/03/27 23:25:05 mpowers Contributing interface, no docs yet.
*
*
*/
-
-