summaryrefslogtreecommitdiff
path: root/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java
diff options
context:
space:
mode:
authorBenjamin Culkin <scorpress@gmail.com>2024-05-19 17:56:33 -0400
committerBenjamin Culkin <scorpress@gmail.com>2024-05-19 17:56:33 -0400
commitaedc34d55462a75e329bbf342251ff6504cd117e (patch)
treebcc8f1f2352582717b484df302aeea6696b8f000 /projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java
Initial import from SVN
Diffstat (limited to 'projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java')
-rw-r--r--projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java391
1 files changed, 391 insertions, 0 deletions
diff --git a/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java b/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java
new file mode 100644
index 0000000..965606b
--- /dev/null
+++ b/projects/net.wotonomy.foundation/src/main/java/net/wotonomy/foundation/NSSelector.java
@@ -0,0 +1,391 @@
+/*
+Wotonomy: OpenStep design patterns for pure Java applications.
+Copyright (C) 2000 Blacksmith, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, see http://www.gnu.org
+*/
+
+package net.wotonomy.foundation;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Comparator;
+
+import net.wotonomy.foundation.internal.PropertyComparator;
+
+/**
+* A pure java implementation of NSSelector.
+*
+* @author michael@mpowers.net
+* @author $Author: cgruber $
+* @version $Revision: 892 $
+*/
+public class NSSelector implements Comparator, Serializable
+{
+ protected NSMutableDictionary methodMap; // map of classes to methods
+ protected String methodName;
+ protected Class[] parameterTypes;
+
+ /**
+ * A marker to indicate object not found.
+ */
+ protected static final String NOT_FOUND = "NOT_FOUND";
+
+ /**
+ * Saves creating a new class array for parameterless method invocation.
+ */
+ protected static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+
+ /**
+ * Saves creating a new object array for parameterless method invocation.
+ */
+ protected static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
+ /**
+ * Constructor specifying a method name and an array of parameter types.
+ */
+ public NSSelector (String aMethodName, Class[] aParameterTypeArray)
+ {
+ methodName = aMethodName;
+ parameterTypes = aParameterTypeArray;
+ methodMap = new NSMutableDictionary();
+ }
+
+ /**
+ * Constructor specifying a method name with no parameters.
+ */
+ public NSSelector (String aMethodName)
+ {
+ this( aMethodName, EMPTY_CLASS_ARRAY );
+ }
+
+ /**
+ * Constructor for custom subclasses that implement specific operators
+ * and that do not use dynamic method invocation.
+ */
+ protected NSSelector()
+ {
+ }
+
+ /**
+ * Returns the name of the method.
+ */
+ public String name ()
+ {
+ return methodName;
+ }
+
+ /**
+ * Returns the array of parameter types.
+ */
+ public Class[] parameterTypes ()
+ {
+ return parameterTypes;
+ }
+
+ /**
+ * A String description of this selector.
+ */
+ public String toString ()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append( "[" + getClass().getName() + ": name = " + name() + ", parameter types = [" );
+ if ( parameterTypes != null )
+ {
+ if ( parameterTypes.length > 0 )
+ {
+ result.append( parameterTypes[0].toString() );
+ }
+ for ( int i = 1; i < parameterTypes.length; i++ )
+ {
+ result.append( ", " );
+ result.append( parameterTypes[i].toString() );
+ }
+ }
+ result.append( "] ]" );
+ return result.toString();
+ }
+
+ /**
+ * Returns the appropriate method for the specified class.
+ */
+ public Method methodOnClass (Class aClass)
+ throws NoSuchMethodException
+ {
+ Object result = methodMap.objectForKey( aClass );
+
+ if ( result == null )
+ {
+ result = getMethodForClass( aClass );
+ if ( result == null )
+ {
+ result = NOT_FOUND;
+ }
+ methodMap.setObjectForKey( result, aClass );
+ }
+
+ if ( result == NOT_FOUND )
+ {
+ throw new NoSuchMethodException();
+ }
+ return (Method) result;
+ }
+
+ /**
+ * Returns the appropriate method, or null if not found.
+ */
+ private Method getMethodForClass( Class aClass )
+ {
+ Method[] methods = aClass.getMethods();
+ for ( int i = 0; i < methods.length; i++ )
+ {
+ if ( methods[i].getName().equals( name() ) )
+ {
+ Class[] params = methods[i].getParameterTypes();
+ if ( params.length == parameterTypes.length )
+ {
+ boolean pass = true;
+ for ( int j = 0; j < params.length; j++ )
+ {
+ if ( ! params[j].isAssignableFrom( parameterTypes[j] ) )
+ {
+ pass = false;
+ }
+ }
+ if ( pass ) return methods[i];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Convenience to get a method for an object.
+ */
+ public Method methodOnObject (Object anObject)
+ throws NoSuchMethodException
+ {
+ Method m = methodOnClass( anObject.getClass() );
+ if ( m == null ) throw new NoSuchMethodException( name() );
+ return m;
+ }
+
+ /**
+ * Returns whether the class implements the method for this selector.
+ */
+ public boolean implementedByClass (Class aClass)
+ {
+ try
+ {
+ methodOnClass( aClass );
+ return true;
+ }
+ catch ( NoSuchMethodException exc )
+ {
+ }
+ return false;
+ }
+
+ /**
+ * Returns whether the object's class implements the method
+ * for this selector.
+ */
+ public boolean implementedByObject (Object anObject)
+ {
+ try
+ {
+ methodOnObject( anObject );
+ return true;
+ }
+ catch ( NoSuchMethodException exc )
+ {
+ }
+ return false;
+ }
+
+ /**
+ * Invokes this selector's method on the specified object
+ * using the specified parameters.
+ */
+ public Object invoke (Object anObject, Object[] parameters)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return methodOnObject( anObject ).invoke( anObject, parameters );
+ }
+
+ /**
+ * Invokes this selector's method on the specified object
+ * with no parameters.
+ */
+ public Object invoke (Object anObject)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return invoke( anObject, EMPTY_OBJECT_ARRAY );
+ }
+
+ /**
+ * Invokes this selector's method on the specified object
+ * with the specified parameter.
+ */
+ public Object invoke (Object anObject, Object aParameter)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return invoke( anObject, new Object[] { aParameter } );
+ }
+
+ /**
+ * Invokes this selector's method on the specified object
+ * using the specified two parameters.
+ */
+ public Object invoke (Object anObject, Object p1, Object p2)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return invoke( anObject, new Object[] { p1, p2 } );
+ }
+
+ /**
+ * Invokes the method with the specified signature on the specified
+ * object using the specified parameters.
+ */
+ public static Object invoke
+ (String methodName, Class[] parameterTypes, Object anObject, Object[] parameters)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return new NSSelector( methodName, parameterTypes ).invoke( anObject, parameters );
+ }
+
+ /**
+ * Invokes the method with the specified signature on the specified object
+ * with no parameters.
+ */
+ public static Object invoke
+ (String methodName, Object anObject)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return NSSelector.invoke(
+ methodName, EMPTY_CLASS_ARRAY, anObject, EMPTY_OBJECT_ARRAY );
+ }
+
+ /**
+ * Invokes the method with the specified signature on the specified
+ * object using the specified parameter.
+ */
+ public static Object invoke
+ (String methodName, Class[] parameterTypes,
+ Object anObject, Object aParameter)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return NSSelector.invoke(
+ methodName, parameterTypes, anObject, new Object[] { aParameter } );
+ }
+
+ /**
+ * Invokes the method with the specified signature on the specified
+ * object using the specified two parameters.
+ */
+ public static Object invoke
+ (String methodName, Class[] parameterTypes,
+ Object anObject, Object p1, Object p2)
+ throws IllegalAccessException, IllegalArgumentException,
+ InvocationTargetException, NoSuchMethodException
+ {
+ return NSSelector.invoke(
+ methodName, parameterTypes, anObject, new Object[] { p1, p2 } );
+ }
+
+ // interface Comparator
+
+ private Comparator comparator;
+
+ /**
+ * Constructor specifying a method name and a comparator.
+ * This is not in the spec.
+ */
+ public NSSelector (String aMethodName, Comparator aComparator)
+ {
+ this( aMethodName, EMPTY_CLASS_ARRAY );
+ comparator = aComparator;
+ }
+
+ /**
+ * Returns the Comparator used for this selector.
+ * This is not in the spec.
+ */
+ public Comparator comparator()
+ {
+ if ( comparator == null )
+ {
+ comparator = new PropertyComparator( methodName );
+ }
+ return comparator;
+ }
+
+ public int compare(Object o1, Object o2)
+ {
+ if ( comparator == null )
+ {
+ comparator = new PropertyComparator( methodName );
+ }
+ return comparator.compare( o1, o2 );
+ }
+
+ public boolean equals(Object obj)
+ {
+ return ( obj == this );
+ }
+}
+
+/*
+ * $Log$
+ * Revision 1.1 2006/02/16 12:47:16 cgruber
+ * Check in all sources in eclipse-friendly maven-enabled packages.
+ *
+ * Revision 1.9 2003/02/12 19:34:35 mpowers
+ * Added accessor for comparator.
+ *
+ * Revision 1.8 2003/02/07 20:23:41 mpowers
+ * Provided backwards compatibility for comparators.
+ *
+ * Revision 1.7 2003/01/22 23:02:25 mpowers
+ * Fixed a null pointer error in NSSelector.toString.
+ *
+ * Revision 1.6 2003/01/18 23:46:58 mpowers
+ * EOSortOrdering is now correctly using NSSelectors.
+ *
+ * Revision 1.4 2001/10/31 15:24:45 mpowers
+ * Implicit constructor is now protected.
+ *
+ * Revision 1.3 2001/02/07 19:25:51 mpowers
+ * Fixed: method matching uses isAssignableFrom rather than ==.
+ *
+ * Revision 1.2 2001/01/08 23:30:16 mpowers
+ * Fixed major bug - selectors were not supposed to share a method map.
+ *
+ * Revision 1.1.1.1 2000/12/21 15:47:45 mpowers
+ * Contributing wotonomy.
+ *
+ * Revision 1.3 2000/12/20 16:25:39 michael
+ * Added log to all files.
+ *
+ *
+ */
+