package groovy; import java.util.List; /** * Groovy Category to verify overriding of the various operators (+, -, *, /, * %, |, &, ++, --, [] get/put, ==, != , <, <=, >, >=, <=>). * *

* The {@link MyNum} static nested class is defined at the bottom of this * class. */ public class OperatorCategory { private static final String CLASSNAME = OperatorCategory.class.getName(); private static final boolean DEBUG = true; private static String lastOp; /** Get and clear last operation string. */ public static String lastOp() { String ret = lastOp; lastOp = null; return ret; } public static Number plus( Number a, Number b ) { lastOp = "plus"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() + b.intValue(); } public static Number minus( Number a, Number b ) { lastOp = "minus"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() - b.intValue(); } public static Number multiply( Number a, Number b ) { lastOp = "multiply"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() * b.intValue(); } public static Number div( Number a, Number b ) { lastOp = "div"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() / b.intValue(); } public static Number mod( Number a, Number b ) { lastOp = "mod"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() % b.intValue(); } public static Number or( Number a, Number b ) { lastOp = "or"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() | b.intValue(); } public static Number and( Number a, Number b ) { lastOp = "and"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() & b.intValue(); } public static Number next( Number a ) { lastOp = "next"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a)" ); return a.intValue()+1; } public static int previous( Number a ) { lastOp = "previous"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a)" ); return a.intValue()-1; } public static Object getAt( List a, Integer index ) { lastOp = "getAt"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(List a, Integer index)" ); return ((List)a).get(index); } public static Object putAt( List a, Integer index, Object value ) { lastOp = "putAt"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(List a, Integer index, Object value)" ); return a.set(index, value); } public static Number leftShift( Number a, Number b ) { lastOp = "leftShift"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() << b.intValue(); } public static Number rightShift( Number a, Number b ) { lastOp = "rightShift"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() >> b.intValue(); } public static Number rightShiftUnsigned( Number a, Number b ) { lastOp = "rightShiftUnsigned"; if (DEBUG) System.out.println( CLASSNAME + "." + lastOp + "(Number a, Number b)" ); return a.intValue() >> b.intValue(); } public static boolean equals( Number a, Number b ) { lastOp = "equalsNumberNumber"; if (DEBUG) System.out.println( CLASSNAME + ".equals(Number a, Number b)" ); return a.equals(b); } public static boolean equals( MyNum a, MyNum b ) { lastOp = "equalsMyNumMyNum"; if (DEBUG) System.out.println( CLASSNAME + ".equals(MyNum a, MyNum b)" ); return a.equals(b); } public static boolean equals( MyNum a, Number b ) { lastOp = "equalsMyNumNumber"; if (DEBUG) System.out.println( CLASSNAME + ".equals(MyNum a, Number b)" ); return a.equals(b); } public static boolean equals( Number a, MyNum b ) { if (DEBUG) System.out.println( CLASSNAME + ".equals(Number a, MyNum b)" ); boolean ret = equals(b,a); // Yes the args are reversed intentionally lastOp = "equalsNumberMyNum"; return ret; } public static Number compareTo( Number a, Number b ) { lastOp = "compareToNumberNumber"; if (DEBUG) System.out.println( CLASSNAME + ".compareTo(Number a, Number b)" ); if ((a instanceof Comparable) && (b instanceof Comparable)) { return ((Comparable)a).compareTo((Comparable)b); } else { double diff = a.doubleValue() - b.doubleValue(); return (diff < 0) ? -1 : ((diff > 0) ? 1 : 0); } } public static int compareTo( MyNum a, MyNum b ) { lastOp = "compareToMyNumMyNum"; if (DEBUG) System.out.println( CLASSNAME + ".compareTo(MyNum a, MyNum b)" ); return a.compareTo(b); } public static int compareTo( MyNum a, Number b ) { lastOp = "compareToMyNumNumber"; if (DEBUG) System.out.println( CLASSNAME + ".compareTo(MyNum a, Number b)" ); return a.compareTo(b); } public static int compareTo( Number a, MyNum b ) { if (DEBUG) System.out.println( CLASSNAME + ".compareTo(Number a, MyNum b)" ); int ret = -compareTo(b,a); // Yes the args are reversed intentionally lastOp = "compareToNumberMyNum"; return ret; } public static class MyNum implements Comparable { Comparable _value; public MyNum( Number num ) { if (num == null) throw new NullPointerException( "num can not be null" ); if (!(num instanceof Comparable)) { throw new NullPointerException( "num is not a Comparable (" + num.getClass().getName() + ")" ); } _value = (Comparable) num; } public boolean equals( Object other ) { if (this == other) return true; else if (other == null) return false; else if (getClass() == other.getClass()) { return _value.equals( ((MyNum)other)._value ); } else if (other instanceof Number) { return _value.equals( other ); } return false; } public int hashCode() { return _value.hashCode(); } public int compareTo(Object other) { if (this == other) return 0; else if (other == null) return 1; else if (getClass() == other.getClass()) { return _value.compareTo( ((MyNum)other)._value ); } else if (other instanceof Number) { return _value.compareTo( other ); } throw new IllegalArgumentException( getClass() + " and " + other.getClass() + " are not Comparable" ); } } }