diff options
| author | Benjamin Culkin <scorpress@gmail.com> | 2024-05-19 17:56:33 -0400 |
|---|---|---|
| committer | Benjamin Culkin <scorpress@gmail.com> | 2024-05-19 17:56:33 -0400 |
| commit | aedc34d55462a75e329bbf342251ff6504cd117e (patch) | |
| tree | bcc8f1f2352582717b484df302aeea6696b8f000 /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.java | 391 |
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. + * + * + */ + |
