Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • + addMyListener(MyListener) : void - This method is created based on the generic type of your annotated List field. The name and parameter type is are based on the List field's generic parameter.
  • + removeMyListener(MyListener) : void- This method is created based on the generic type of your annotated List field. The name and parameter type is are based on the List field's generic parameter.
  • + getMyListeners() : MyListener[] - This method is created based on the generic type of your annotated List field.The name is the plural form of the List field's generic parameter, and the return type is an array of the generic parameter.
  • + fireEventOccurred(MyEvent) : void - This method is created based on the type that the List's generic type points to. In this case, MyListener is a one method interface with an eventOccurred(MyEvent) method. The method name is fire[MethodName of the interface] and the parameter is the parameter list from the interface. (Note: what happens where there are two parameters on the method?)
  • + fireEventOccurred(Object, String) : void - This should be removed as it is too complex to generate a proper parameter list. What if the object has 2 constructors? Are there two methods generated? 10 constructors = 10 methods? Yuck.
    Gets turned into:
    Code Block
    public class MyBeanClass {
    
        @groovy.beans.ListenerList
        private List<MyListener> listeners
    
        public void addMyListener(MyListener listener) {
            if ( listeners == null) { listeners = [] }
            listeners.add(listener)
        }
    
        public void removeMyListener(MyListener listener) {
            if ( listeners == null) { listeners = [] }
            listeners.remove(listener)
        }
    
        public MyListener[] getMyListeners() {
            def __result = []
            if ( listeners != null) {
                __result.addAll(listeners)
            }
            __result as MyListener[]
        }
    
        public void fireEventOccurred(MyEvent p0) {
            if ( listeners != null) {
                def __list = new ArrayList(listeners)
                for (listener : __list ) {
                    listener.eventOccurred(p0)
                }
            }
        }
    
        public void fireEventOccurred(java.lang.Object p0, java.lang.String p1) {
            if ( listeners != null) {
                def __list = new ArrayList(listeners)
                for (listener : __list ) {
                    listener.eventOccurred(new MyEvent(p0, p1))
                }
            }
        }
    }
    
    Notes - 1) add listener and remove listener have conflicting code. There is a guard clause that returns null when parameter is null and a guard clause that lazy instantiates the listener. Can't have both. 2) The fireEvent methods do not seem to be part of the bean spec. To simplify, let's remove the 2nd one with 2 parameters.

...

Specifying a Listener Type and Event Type

This example shows the basic usage of the @ListenerList annotation. Is this really needed? Just use a List with generic parameter.

Code Block
class TestEvent {
    def source
    String message

    TestEvent(def source, String message) {
        this.source = source
        this.message = message
    }
}

interface TestListener {
    void eventOccurred(TestEvent event)
}
class TestClass {
     @ListenerList(listener = TestListener, event = TestEvent)
     def listeners
}

...

Code Block
public class TestClass1 {

    @groovy.beans.ListenerList(event = TestEvent, listener = TestListener)
    private Object listeners

    public void addTestListener(TestListener listener) {
        if ( listeners == null) { listeners = [] }
        listeners.add(listener)
    }

    public void removeTestListener(TestListener listener) {
        if ( listeners == null) { listeners = [] }
        listeners.remove(listener)
    }

    public TestListener[] getTestListeners() {
        def __result = []
        if ( listeners != null) {
            __result.addAll(listeners)
        }
        return  __result as TestListener[]
    }

    public void fireEventOccurred(TestEvent p0) {
        if ( listeners != null) {
            def __list = new ArrayList(listeners)
            for (listener : __list ) {
                listener.eventOccurred(p0)
            }
        }
    }

    public void fireEventOccurred(java.lang.Object p0, java.lang.String p1) {
        if ( listeners != null) {
            def __list = new ArrayList(listeners)
            for (listener : __list ) {
                listener.eventOccurred(new TestEvent(p0, p1))
            }
        }
    }
}

Rejected Alternatives

  • We considered allowing @ListenerList to be a Class/Type annotation. The benefit was terseness. You don't even need to declare a field in that case. However, we decided it brings too much complexity. We are searching for ways to simplify this, and removing this option reduces the complexity with no real loss in functionality.

Advanced Examples

All of these examples assume the following:

...

Code Block
public class TestClass12 extends java.lang.Object {

    @groovy.beans.ListenerList(event = java.lang.String)
    private java.util.List<TestObjectListener> listeners

    public void addTestObjectListener(TestObjectListener listener) {
        if ( listener == null) {
            return null
        }
        if ( listeners == null) {
            listeners = []
        }
        listeners.add(listener)
    }

    public void removeTestObjectListener(TestObjectListener listener) {
        if ( listener == null) {
            return null
        }
        if ( listeners == null) {
            listeners = []
        }
        listeners.remove(listener)
    }

    public TestObjectListener[] getTestObjectListeners() {
        java.lang.Object __result = []
        if ( listeners != null) {
            __result.addAll(listeners)
        }
        return (( __result ) as TestObjectListener[])
    }

    public void fireEventOccurred(java.lang.String p0) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(p0)
            }
        }
    }

    public void fireEventOccurred() {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String())
            }
        }
    }

    public void fireEventOccurred([C p0) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0))
            }
        }
    }

    public void fireEventOccurred([C p0, int p1, int p2) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2))
            }
        }
    }

    public void fireEventOccurred([I p0, int p1, int p2) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2))
            }
        }
    }

    public void fireEventOccurred([B p0, int p1, int p2, int p3) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2, p3))
            }
        }
    }

    public void fireEventOccurred([B p0, int p1) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1))
            }
        }
    }

    public void fireEventOccurred([B p0, int p1, int p2, java.lang.String p3) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2, p3))
            }
        }
    }

    public void fireEventOccurred([B p0, int p1, int p2, java.nio.charset.Charset p3) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2, p3))
            }
        }
    }

    public void fireEventOccurred([B p0, java.lang.String p1) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1))
            }
        }
    }

    public void fireEventOccurred([B p0, java.nio.charset.Charset p1) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1))
            }
        }
    }

    public void fireEventOccurred([B p0, int p1, int p2) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2))
            }
        }
    }

    public void fireEventOccurred([B p0) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0))
            }
        }
    }

    public void fireEventOccurred(java.lang.StringBuffer p0) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0))
            }
        }
    }

    public void fireEventOccurred(java.lang.StringBuilder p0) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0))
            }
        }
    }

    public void fireEventOccurred(int p0, int p1, [C p2) {
        if ( listeners != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(listeners)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new java.lang.String(p0, p1, p2))
            }
        }
    }

}

This example:

Code Block

@ListenerList(listener = TestListener, event = TestEvent)
class TestClass14 {
}

Gets turned into:

Code Block

public class TestClass14 extends java.lang.Object {

    private java.util.List<E extends java.lang.Object> testListenerList

    public void addTestListener(TestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( testListenerList == null) {
            testListenerList = []
        }
        testListenerList.add(listener)
    }

    public void removeTestListener(TestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( testListenerList == null) {
            testListenerList = []
        }
        testListenerList.remove(listener)
    }

    public TestListener[] getTestListeners() {
        java.lang.Object __result = []
        if ( testListenerList != null) {
            __result.addAll(testListenerList)
        }
        return (( __result ) as TestListener[])
    }

    public void fireEventOccurred(TestEvent p0) {
        if ( testListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(testListenerList)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(p0)
            }
        }
    }

    public void fireEventOccurred(java.lang.Object p0, java.lang.String p1) {
        if ( testListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(testListenerList)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new TestEvent(p0, p1))
            }
        }
    }

}

This example:

Code Block

@ListenerList(listener = TestListener, event = TestEvent)
class TestClass15 {
     def testListenerList
}

Gets turned into:

Code Block

public class TestClass15 extends java.lang.Object {

    private java.lang.Object testListenerList

    public void addTestListener(TestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( testListenerList == null) {
            testListenerList = []
        }
        testListenerList.add(listener)
    }

    public void removeTestListener(TestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( testListenerList == null) {
            testListenerList = []
        }
        testListenerList.remove(listener)
    }

    public TestListener[] getTestListeners() {
        java.lang.Object __result = []
        if ( testListenerList != null) {
            __result.addAll(testListenerList)
        }
        return (( __result ) as TestListener[])
    }

    public void fireEventOccurred(TestEvent p0) {
        if ( testListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(testListenerList)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(p0)
            }
        }
    }

    public void fireEventOccurred(java.lang.Object p0, java.lang.String p1) {
        if ( testListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(testListenerList)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new TestEvent(p0, p1))
            }
        }
    }

}

This example:

Code Block

@ListenerList(listener = TestListener, event = TestEvent)
@ListenerList(listener = SomeOtherTestListener, event = SomeOtherTestEvent)
class TestClass16 {
}

Gets turned into:

Code Block

public class TestClass16 extends java.lang.Object {

    private java.util.List<E extends java.lang.Object> testListenerList
    private java.util.List<E extends java.lang.Object> someOtherTestListenerList

    public void addTestListener(TestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( testListenerList == null) {
            testListenerList = []
        }
        testListenerList.add(listener)
    }

    public void removeTestListener(TestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( testListenerList == null) {
            testListenerList = []
        }
        testListenerList.remove(listener)
    }

    public TestListener[] getTestListeners() {
        java.lang.Object __result = []
        if ( testListenerList != null) {
            __result.addAll(testListenerList)
        }
        return (( __result ) as TestListener[])
    }

    public void fireEventOccurred(TestEvent p0) {
        if ( testListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(testListenerList)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(p0)
            }
        }
    }

    public void fireEventOccurred(java.lang.Object p0, java.lang.String p1) {
        if ( testListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(testListenerList)
            for (java.lang.Object listener : __list ) {
                listener.eventOccurred(new TestEvent(p0, p1))
            }
        }
    }

    public void addSomeOtherTestListener(SomeOtherTestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( someOtherTestListenerList == null) {
            someOtherTestListenerList = []
        }
        someOtherTestListenerList.add(listener)
    }

    public void removeSomeOtherTestListener(SomeOtherTestListener listener) {
        if ( listener == null) {
            return null
        }
        if ( someOtherTestListenerList == null) {
            someOtherTestListenerList = []
        }
        someOtherTestListenerList.remove(listener)
    }

    public SomeOtherTestListener[] getSomeOtherTestListeners() {
        java.lang.Object __result = []
        if ( someOtherTestListenerList != null) {
            __result.addAll(someOtherTestListenerList)
        }
        return (( __result ) as SomeOtherTestListener[])
    }

    public void fireEvent2Occurred(SomeOtherTestEvent p0) {
        if ( someOtherTestListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(someOtherTestListenerList)
            for (java.lang.Object listener : __list ) {
                listener.event2Occurred(p0)
            }
        }
    }

    public void fireEvent2Occurred(java.lang.Object p0, java.lang.String p1) {
        if ( someOtherTestListenerList != null) {
            java.util.ArrayList<E extends java.lang.Object> __list = new java.util.ArrayList<E extends java.lang.Object>(someOtherTestListenerList)
            for (java.lang.Object listener : __list ) {
                listener.event2Occurred(new SomeOtherTestEvent(p0, p1))
            }
        }
    }

}