You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ky...@apache.org on 2004/12/18 00:51:17 UTC

svn commit: r122686 - in incubator/beehive/trunk/controls: src/runtime/org/apache/beehive/controls/runtime/bean src/runtime/org/apache/beehive/controls/runtime/generator src/runtime/org/apache/beehive/controls/runtime/generator/apt test test/src/controls/org/apache/beehive/controls/test/controls/generic test/src/units/org/apache/beehive/controls/test/java/generic

Author: kylem
Date: Fri Dec 17 15:51:15 2004
New Revision: 122686

URL: http://svn.apache.org/viewcvs?view=rev&rev=122686
Log:
Add support for using JDK 1.5 generics with Controls.  Controls codegen will take any generic formal type declarations found on control interfaces/extensions and propagate them correctly to derived artifacts.  It's possible to write a control type and associated impl with full type parameterization, including for associated operations and events.   The test suite contains a simple example of a ListControl where the contained element types are parameterized, as well as specific List implementation class to use for managing elements (in controls/org/apache/beehive/controls/test/controls/generic) and associated examples of usage (both programmatic and declarative) of ListControl w/ specific type bindings can be found in controls/test/src/units/org/apache/beehive/controls/test/java/generic.


Added:
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControl.java
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControlImpl.jcs
   incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/generic/
   incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/generic/GenericTest.java
Modified:
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
   incubator/beehive/trunk/controls/test/build.xml

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java	Fri Dec 17 15:51:15 2004
@@ -864,6 +864,30 @@
         public boolean postEvent( Class eventSet, Method m, Object [] args, org.apache.beehive.controls.api.context.ControlBeanContext cbc ) { return true; }
     }
 
+    /** BEGIN unsynchronized fields */
+
+    /**
+     * The following fields are initialized in the constructor and never subsequently changed,
+     * so they are safe for unsynchronized read access
+     */
+
+    /**
+     * The control implementation class bound to this ControlBean
+     */
+    protected Class _implClass;
+
+    /**
+     * The threading policy associated with the control implementation wrapped by this
+     * ControlBean.
+     */
+    transient private ThreadingPolicy _threadingPolicy = ThreadingPolicy.SINGLE_THREADED;
+
+    /**
+     *  Contains the per-instance properties set for this ControlBean.
+     */
+    private PropertyMap _properties;
+
+    /** END unsynchronized fields */
 
     /* BEGIN synchronized fields */
 
@@ -875,11 +899,6 @@
      */
 
     /**
-     * The control implementation class bound to this ControlBean
-     */
-    private Class _implClass;
-
-    /**
      * The control implementation instance wrapped by this ControlBean
      */
     private Object _control;
@@ -902,12 +921,6 @@
     transient private boolean _hasServices = false;
 
     /**
-     * The threading policy associated with the control implementation wrapped by this
-     * ControlBean.
-     */
-    transient private ThreadingPolicy _threadingPolicy = ThreadingPolicy.SINGLE_THREADED;
-
-    /**
      * Used to guarantee single threaded invocation when required.  If the
      * outer container provides the guarantee or the implementation itself
      * is threadsafe, then the value will be null.
@@ -940,11 +953,6 @@
      * The public control interface associated with this ControlBean
      */
     private Class _controlIntf;
-
-    /**
-     *  Contains the per-instance properties set for this ControlBean.
-     */
-    private PropertyMap _properties;
 
     /**
      * This field manages the register listener list(s) associated with event set interfaces

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptClientField.java	Fri Dec 17 15:51:15 2004
@@ -37,11 +37,9 @@
     {
         super(fieldDecl);
         _controlImpl = controlImpl;
-        _fieldDecl = fieldDecl;
         _env = env;
     };
 
-    private FieldDeclaration _fieldDecl;
     private AptControlImplementation _controlImpl;
     private AnnotationProcessorEnvironment _env;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptContextField.java	Fri Dec 17 15:51:15 2004
@@ -40,7 +40,6 @@
     {
         super(fieldDecl);
         _controlImpl = controlImpl;
-        _fieldDecl = fieldDecl;
         _env = env;
     };
 
@@ -66,7 +65,6 @@
                                        _env);
     }
 
-    private FieldDeclaration _fieldDecl;
     private AptControlImplementation _controlImpl;
     private AnnotationProcessorEnvironment _env;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlClient.java	Fri Dec 17 15:51:15 2004
@@ -276,7 +276,7 @@
             //
             boolean found = false;
             String eventName = (String)handlerAnnot.getObjectValue("eventName");
-            AptMethod handlerMethod = new AptMethod(clientMethod);
+            AptMethod handlerMethod = new AptMethod(clientMethod, _env);
             for (AptEvent controlEvent : eventSet.getEvents())
             {
                 if (controlEvent == null || 
@@ -287,7 +287,13 @@
                 if ( controlEvent.getArgTypes() == null )
                     continue;
 
-                if (controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()))
+                //
+                // BUGBUG: If the arguments are parameterized, then the event handler
+                // might declare a specific bound version of the type, so a direct
+                // comparison will fail.  If parameterized, we don't validate.
+                //
+                if (controlEvent.hasParameterizedArguments() ||
+                    controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()))
                 {
                     adaptor.addHandler(controlEvent, 
                                        new AptEventHandler(controlEvent, clientMethod, _env));

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlField.java	Fri Dec 17 15:51:15 2004
@@ -46,7 +46,6 @@
     {
         super( controlDecl );
         _controlClient = controlClient;
-        _controlDecl = controlDecl;
         _env = env;
         _controlBean = new ControlBean(getControlInterface());
     };
@@ -56,10 +55,10 @@
      */
     protected AptControlInterface initControlInterface()
     {
-        TypeMirror controlType = _controlDecl.getType();
+        TypeMirror controlType = _fieldDecl.getType();
         if (! (controlType instanceof DeclaredType))
         {
-            _env.getMessager().printError(_controlDecl.getPosition(),
+            _env.getMessager().printError(_fieldDecl.getPosition(),
                 "@Control field type must be a valid ControlBean class or control interface");
             return null;
         }
@@ -95,7 +94,7 @@
 
             if (controlIntf == null)
             {
-                _env.getMessager().printError(_controlDecl.getPosition(), 
+                _env.getMessager().printError(_fieldDecl.getPosition(), 
                                               "Unable to identify control type of field");
                 return null; 
             }
@@ -106,7 +105,7 @@
         }
         else
         {
-            _env.getMessager().printError(_controlDecl.getPosition(),
+            _env.getMessager().printError(_fieldDecl.getPosition(),
                                           "Control field is not a valid type");
             return null;
         }
@@ -119,7 +118,6 @@
      */
     public ControlBean getControlBean() { return _controlBean; }
 
-    private FieldDeclaration _controlDecl;
     private AnnotationProcessorEnvironment _env;
     private AptType _controlClient;
     private ControlBean _controlBean;

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlImplementation.java	Fri Dec 17 15:51:15 2004
@@ -376,7 +376,7 @@
             //
             boolean found = false;
             String eventName = (String)handlerAnnot.getObjectValue("eventName");
-            AptMethod handlerMethod = new AptMethod(implMethod);
+            AptMethod handlerMethod = new AptMethod(implMethod, _env);
             for (AptEvent controlEvent : eventSet.getEvents())
             {
                 if (controlEvent == null || controlEvent.getName() == null || 
@@ -385,7 +385,13 @@
                 if ( controlEvent.getArgTypes() == null )
                     continue;
 
-                if (controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()))
+                //
+                // BUGBUG: If the arguments are parameterized, then the event handler
+                // might declare a specific bound version of the type, so a direct
+                // comparison will fail.  If parameterized, we don't validate.
+                //
+                if (controlEvent.hasParameterizedArguments() ||
+                    controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()))
                 {
                     adaptor.addHandler(controlEvent, 
                                        new AptEventHandler(controlEvent, implMethod, _env));

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptControlInterface.java	Fri Dec 17 15:51:15 2004
@@ -463,7 +463,7 @@
     public AptEventSet getEventSet(String name)
     {
         for (AptEventSet eventSet: getEventSets())
-            if (eventSet.getName().equals(name))
+            if (eventSet.getClassName().equals(name))
                 return eventSet;
         return null;
     }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEvent.java	Fri Dec 17 15:51:15 2004
@@ -39,10 +39,9 @@
     public AptEvent(AptEventSet eventSet, MethodDeclaration eventDecl, 
                     AnnotationProcessorEnvironment env)
     {
-        super(eventDecl);
+        super(eventDecl, env);
         _eventSet = eventSet;
         _eventDecl = eventDecl;
-        _env = env;
     }
 
     /**
@@ -73,5 +72,4 @@
 
     MethodDeclaration _eventDecl;
     private AptEventSet _eventSet;
-    AnnotationProcessorEnvironment _env;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventField.java	Fri Dec 17 15:51:15 2004
@@ -19,8 +19,14 @@
 
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 
 import com.sun.mirror.declaration.FieldDeclaration;
+import com.sun.mirror.declaration.TypeDeclaration;
+import com.sun.mirror.declaration.TypeParameterDeclaration;
+import com.sun.mirror.type.DeclaredType;
+import com.sun.mirror.type.ReferenceType;
+import com.sun.mirror.type.TypeMirror;
 
 /**
  * The AptEventField class represents a field type that is also an event source
@@ -40,12 +46,67 @@
     abstract protected AptControlInterface initControlInterface();
 
     /**
+     * Computes the binding from any formal type parameters declared on the control interface
+     * to bound types on the field declaration.
+     */
+    private void initTypeParameterBindings()
+    {
+        //
+        // Get an iterator to both the declared type arguments and the original type
+        // declaration on the associated control interface
+        //
+        DeclaredType fieldType = (DeclaredType)_fieldDecl.getType();
+        Iterator<TypeMirror> paramBoundIter = fieldType.getActualTypeArguments().iterator();
+
+        TypeDeclaration intfDecl = (TypeDeclaration)_controlIntf.getTypeDeclaration();
+        Iterator<TypeParameterDeclaration> paramDeclIter = 
+                                            intfDecl.getFormalTypeParameters().iterator();
+
+        //
+        // Iterate through them in parallel, creating a mapping from the original formal
+        // type parameter name to the actual bound type.  In parallel, also build up a
+        // representation of the bound type declaration.
+        //
+        // NOTE: If no type binding is done on the field declaration, then loop below
+        // will not execute and no mappings/empty bound decl will be the result.
+        //
+        StringBuffer sb = new StringBuffer();
+        boolean isFirst = true;
+        while (paramBoundIter.hasNext())
+        {
+            TypeMirror paramBound = paramBoundIter.next();
+            TypeParameterDeclaration paramDecl = paramDeclIter.next();
+
+            //
+            // Save a mapping from the formal type name to the bound mirror type
+            //
+            _typeBindingMap.put(paramDecl.getSimpleName(), paramBound);
+
+            if (isFirst)
+            {
+                sb.append("<");
+                isFirst = false;
+            }
+            else
+                sb.append(", ");
+            sb.append(paramBound);
+        }
+        if (!isFirst)
+            sb.append(">");
+        
+        _boundParameterDecl = sb.toString();
+    }
+
+    /**
      * Returns the ControlInterface associated with this event field
      */
     public AptControlInterface getControlInterface()
     {
         if (_controlIntf == null)
+        {
             _controlIntf = initControlInterface();
+            initTypeParameterBindings();
+        }
         return _controlIntf;
     }
 
@@ -74,8 +135,26 @@
         return _eventAdaptors.values();
     }
 
+    /**
+     * Returns the bound parameter declaration for this event field
+     */
+    public String getBoundParameters()
+    {
+        return _boundParameterDecl;
+    }
+
+    /**
+     * Returns the formal type binding map (from name to bound type) for the event field
+     */
+    public HashMap<String, TypeMirror> getTypeBindingMap()
+    {
+        return _typeBindingMap;
+    }
+
     HashMap<AptEventSet, EventAdaptor> _eventAdaptors = 
         new HashMap<AptEventSet, EventAdaptor>();
 
+    String _boundParameterDecl;
+    HashMap<String,TypeMirror> _typeBindingMap = new HashMap<String,TypeMirror>();
     private AptControlInterface _controlIntf;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventHandler.java	Fri Dec 17 15:51:15 2004
@@ -41,10 +41,9 @@
     public AptEventHandler(AptEvent event, MethodDeclaration handlerDecl,
                            AnnotationProcessorEnvironment env)
     {
-        super(handlerDecl);
+        super(handlerDecl, env);
         _event = event;
         _handlerDecl = handlerDecl;
-        _env = env;
     }
 
     /**
@@ -54,5 +53,4 @@
 
     MethodDeclaration _handlerDecl;
     private AptEvent _event;
-    AnnotationProcessorEnvironment _env;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptEventSet.java	Fri Dec 17 15:51:15 2004
@@ -24,6 +24,8 @@
 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
 import com.sun.mirror.declaration.InterfaceDeclaration;
 import com.sun.mirror.declaration.MethodDeclaration;
+import com.sun.mirror.declaration.TypeDeclaration;
+import com.sun.mirror.declaration.TypeParameterDeclaration;
 import com.sun.mirror.type.InterfaceType;
 
 import org.apache.beehive.controls.api.packaging.EventSetInfo;
@@ -36,7 +38,7 @@
  * The AptEventSet class represents a control EventSet where the events
  * are derived using APT metadata.
  */
-public class AptEventSet
+public class AptEventSet extends AptType
 {
     /**
      * Constructs a new AptEventSet instance from APT metadata
@@ -50,7 +52,43 @@
         _controlIntf = controlIntf;
         _eventSet = eventSet;
         _env = env;
+        setDeclaration(eventSet);
 
+        //
+        // If an EventSet interface has formal type parameters, they must be a subset of
+        // the original formal type parameters declared on the original control interface.
+        // This is required because it must be possible to bind the types of events immediately
+        // upon construction of the bean... there is no opportunity to separately specify 
+        // parameterization for the event set for the purpose of creating listeners, client
+        // notifiers, etc.
+        //
+        TypeDeclaration intfDecl = controlIntf.getTypeDeclaration();
+        for (TypeParameterDeclaration estpd : _eventSet.getFormalTypeParameters())
+        {
+            boolean found = false;
+            for (TypeParameterDeclaration citpd : intfDecl.getFormalTypeParameters())
+            {
+                if (estpd.getSimpleName().equals(citpd.getSimpleName()))
+                {
+                    found = true;
+                    break;
+                }
+            }
+            if (! found)
+            {
+                //
+                // BUGBUG: Ideally, this would be estpd.getPosition, but this seems to return
+                // 0,0 for the current APT implementation, so we use the event set position
+                // instead.
+                // Once this work, the 'break' below can also be removed to present errors
+                // for multiple invalid parameters
+                //
+                env.getMessager().printError(eventSet.getPosition(),
+                    "Any EventSet formal type parameters must match ones declared on the associated control type.  No new formal type parameters may be introduced.");
+                break;
+            }
+        }
+         
         _superEventSet = initSuperEventSet();
         _events = initEvents();
     }
@@ -83,7 +121,7 @@
             Collection<AptEventSet> superEventSets = superControl.getEventSets();
             for (AptEventSet superEventSet : superEventSets)
             {
-                if (extendNames.contains(superEventSet.getName()))
+                if (extendNames.contains(superEventSet.getClassName()))
                     return superEventSet;
             }
 
@@ -122,7 +160,7 @@
             // Don't add events that are derived from a super event set.
             //
             if (_superEventSet != null &&
-                _superEventSet.getName().equals(intfDecl.getQualifiedName()))
+                _superEventSet.getClassName().equals(intfDecl.getQualifiedName()))
                 continue;
 
             //
@@ -162,26 +200,6 @@
     }
 
     /**
-     * Returns the fully qualified EventSet name
-     */
-    public String getName()
-    {
-        if ( _eventSet == null )
-            return "";
-        return _eventSet.getQualifiedName();
-    }
-
-    /**
-     * Returns the unqualified class name for this event set
-     */
-    public String getShortName()
-    {
-        String eventSetName = getName();
-        int lastDot = eventSetName.lastIndexOf('.');
-        return eventSetName.substring(lastDot + 1);
-    }
-
-    /**
      * Returns the programmatic descriptor name to be returned by the EventDescriptor
      * for the event set.
      */
@@ -201,7 +219,17 @@
      */
     public String getNotifierClass()
     {
-        return getShortName() + "Notifier";
+        StringBuffer sb = new StringBuffer(getShortName());
+        sb.append("Notifier");
+
+        //
+        // If the event set declaration has any parameterized types, then include them on
+        // the notifier class as well.  Currently, these can only be parameterized types
+        // from the outer (control interface), since there is no other mechanism for specifying
+        // type values at notifier construction (other than propagation from the outer type).
+        // 
+        sb.append(getFormalTypeParameterNames());
+        return sb.toString();
     }
 
     /**
@@ -256,6 +284,14 @@
             return null;
         
         return _eventSet.getAnnotation(EventSetInfo.class);
+    }
+
+    /**
+     * Returns the underlying APT InterfaceDeclaration associated with this event set
+     */
+    public InterfaceDeclaration getDeclaration()
+    {
+        return _eventSet;
     }
 
     private AnnotationProcessorEnvironment  _env;

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptField.java	Fri Dec 17 15:51:15 2004
@@ -59,6 +59,24 @@
     }
 
     /**
+     * Returns the class name of the field (does not include any formal type parameters
+     */
+    public String getClassName()
+    {
+        if ( _fieldDecl == null || _fieldDecl.getType() == null )
+            return "";
+
+        //
+        // This is lazily... but much easier than navigating the APT type system and just
+        // as effective ;)
+        String typeName = _fieldDecl.getType().toString();
+        int formalIndex = typeName.indexOf('<');
+        if (formalIndex > 0)
+            return typeName.substring(0, formalIndex);
+        return typeName;
+    }
+
+    /**
      * Returns the access modifier associated with the field
      */
     public String getAccessModifier()
@@ -85,5 +103,5 @@
         return "_" + getName() + "Field";
     }
 
-    FieldDeclaration _fieldDecl;
+    protected FieldDeclaration _fieldDecl;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java	Fri Dec 17 15:51:15 2004
@@ -24,13 +24,16 @@
 import java.util.Collection;
 import java.util.Collections;
 
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
 import com.sun.mirror.declaration.ClassDeclaration;
 import com.sun.mirror.declaration.MethodDeclaration;
 import com.sun.mirror.declaration.ParameterDeclaration;
+import com.sun.mirror.declaration.TypeParameterDeclaration;
 import com.sun.mirror.type.ClassType;
 import com.sun.mirror.type.PrimitiveType;
 import com.sun.mirror.type.ReferenceType;
 import com.sun.mirror.type.TypeMirror;
+import com.sun.mirror.type.WildcardType;
 
 import org.apache.beehive.controls.api.packaging.FeatureInfo;
 
@@ -75,9 +78,10 @@
     /**
      * Constructs a new AptMethod instance associated with a specific method declaration
      */
-    public AptMethod(MethodDeclaration methodDecl)
+    public AptMethod(MethodDeclaration methodDecl, AnnotationProcessorEnvironment env)
     {
         _methodDecl = methodDecl;
+        _env = env;
     }
 
     /**
@@ -92,9 +96,10 @@
     }
 
     /**
-     * Returns the argument declaration of the method
+     * Returns the argument declaration of the method, applying the bindings in the provided
+     * type map to any parameter types
      */
-    public String getArgDecl()
+    public String getArgDecl(HashMap<String,TypeMirror> bindingMap)
     {
         StringBuffer sb = new StringBuffer();
 
@@ -104,13 +109,18 @@
         int i = 0;
         for (ParameterDeclaration paramDecl : _methodDecl.getParameters())
         {
-            if ( paramDecl.getType() == null )
+            TypeMirror paramType = paramDecl.getType();
+            if ( paramType == null )
                 return "";
                 
+            if (bindingMap != null && bindingMap.containsKey(paramType.toString()))
+                paramType = bindingMap.get(paramType.toString());
+
             if (i != 0)
                 sb.append(", ");
             
-            sb.append(paramDecl.getType().toString());
+            sb.append(paramType.toString());
+
             sb.append(' ');
 
             // BUGBUG: when the MethodDeclaration is derived from Reflection, this seems
@@ -127,6 +137,14 @@
     }
 
     /**
+     * Returns the arguments declarations for the method, with no formal parameter binding applied
+     */
+    public String getArgDecl()
+    {
+        return getArgDecl(null);
+    }
+
+    /**
      * Returns the the method argument names, in a comma separated list
      */
     public String getArgList(boolean quoteDelimit)
@@ -174,26 +192,86 @@
         
         for (ParameterDeclaration paramDecl : _methodDecl.getParameters())
         {
-            if ( paramDecl.getType() == null )
-                return "";
-            
             if (i++ != 0)
                 sb.append(", ");
-            sb.append(paramDecl.getType().toString());
+
+            TypeMirror paramType = paramDecl.getType();
+            if (paramType == null)
+                return "";
+
+            //
+            // Use the erasure here, because we only want the raw type, not the reference
+            // type
+            //
+            sb.append(_env.getTypeUtils().getErasure(paramType));
             sb.append(".class");
         }
         return sb.toString();
     }
 
     /**
-     * Returns the method return type
+     * Returns 'true' if the method uses any parameterized types as parameters
      */
-    public String getReturnType()
+    public boolean hasParameterizedArguments()
+    {
+        for (ParameterDeclaration paramDecl : _methodDecl.getParameters())
+        {
+            TypeMirror paramType = paramDecl.getType();
+            if (paramType instanceof ReferenceType || paramType instanceof WildcardType)
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the declaration of any generic formal types associated with the method
+     */
+    public String getFormalTypes()
+    {
+        if ( _methodDecl == null || _methodDecl.getReturnType() == null )
+            return "";
+
+        Collection<TypeParameterDeclaration> formalTypes = _methodDecl.getFormalTypeParameters();
+        if (formalTypes.size() == 0)
+            return "";
+
+        StringBuffer sb = new StringBuffer("<");
+        boolean isFirst = true;
+        for (TypeParameterDeclaration tpd: formalTypes)
+        {
+            if (isFirst)
+                isFirst = false;
+            else
+                sb.append(", ");
+
+            sb.append(tpd.toString());
+        }
+        sb.append(">");
+        return sb.toString();
+    }
+
+    /**
+     * Returns the method return type, applying any formal type parameter bindings defined
+     * by the provided map.
+     */
+    public String getReturnType(HashMap<String,TypeMirror> bindingMap)
     {
         if ( _methodDecl == null || _methodDecl.getReturnType() == null )
             return "";
         
-        return _methodDecl.getReturnType().toString();
+        String returnType = _methodDecl.getReturnType().toString();
+        if (bindingMap != null && bindingMap.containsKey(returnType))
+            return bindingMap.get(returnType).toString();
+
+        return returnType;
+    }
+
+    /**
+     * Returns the method return type with no type bindings applied
+     */
+    public String getReturnType()
+    {
+        return getReturnType(null);
     }
 
     /**
@@ -239,17 +317,25 @@
     }
 
     /**
-     * Returns a default return value string for the method, based upon return type
+     * Returns a default return value string for the method, based upon bound return type
      */
-    public String getDefaultReturnValue()
+    public String getDefaultReturnValue(HashMap<String,TypeMirror> typeBinding)
     {
-        String returnType = getReturnType();
+        String returnType = getReturnType(typeBinding);
         if (_defaultReturnValues.containsKey(returnType))
             return _defaultReturnValues.get(returnType);
         return "null";
     }
 
     /**
+     * Returns a default return value string for the method, with no type binding applied
+     */
+    public String getDefaultReturnValue()
+    {
+        return getDefaultReturnValue(null);
+    }
+
+    /**
      * Returns any FeatureInfo associated with the method (or null if none)
      */ 
     public FeatureInfo getFeatureInfo()
@@ -276,4 +362,5 @@
 
     MethodDeclaration _methodDecl;
     int _index = -1;
+    AnnotationProcessorEnvironment _env;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java	Fri Dec 17 15:51:15 2004
@@ -40,10 +40,9 @@
     public AptOperation(AptControlInterface controlIntf, MethodDeclaration methodDecl,
                         AnnotationProcessorEnvironment env)
     {
-        super(methodDecl);
+        super(methodDecl, env);
         _controlIntf = controlIntf;
         _operDecl = methodDecl;
-        _env = env;
 
         _interceptorServiceNames = initInterceptorServiceNames();
     }
@@ -139,7 +138,6 @@
     }
 
     MethodDeclaration _operDecl;
-    AnnotationProcessorEnvironment _env;
     AptControlInterface _controlIntf;
     Collection<String> _interceptorServiceNames;
 }

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptType.java	Fri Dec 17 15:51:15 2004
@@ -18,11 +18,13 @@
  */
 
 import java.io.IOException;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 
 import com.sun.mirror.apt.Filer;
 import com.sun.mirror.declaration.TypeDeclaration;
+import com.sun.mirror.declaration.TypeParameterDeclaration;
 
 /**
  * The AptType abstract class defines a base set of methods that are generally available
@@ -69,6 +71,81 @@
             return "";
         
         return _typeDecl.getSimpleName();
+    }
+
+    /**
+     * Helper method to return type parameter information
+     */
+    private String getFormalTypeParameters(boolean namesOnly)
+    {
+        Collection<TypeParameterDeclaration> ftColl = _typeDecl.getFormalTypeParameters();
+        if (ftColl.size() == 0)
+            return ""; 
+
+        StringBuffer sb = new StringBuffer("<");
+        boolean isFirst = true;
+        for (TypeParameterDeclaration tpDecl : ftColl)
+        {
+            if (!isFirst)
+                sb.append(",");
+            else
+                isFirst = false;
+        
+            if (namesOnly)
+                sb.append(tpDecl.getSimpleName());
+            else
+                sb.append(tpDecl.toString());
+        }
+        sb.append(">");
+        return sb.toString();
+    }
+
+    /**
+     * Returns the full formal type parameter declaration associated with the type declaration
+     */
+    public String getFormalTypeParameters()
+    {
+        return getFormalTypeParameters(false);
+    }
+
+    /**
+     * Returns the name of any formal type parameter names associated with the type declaration.
+     */
+    public String getFormalTypeParameterNames()
+    {
+        return getFormalTypeParameters(true);
+    }
+
+    /**
+     * Returns the short name and the names of any formal type parameters associated with
+     * the type.  The format is suitable for use in location (such as variable declarations
+     * or extends clauses) where you want formal type parameters listed.
+     */
+    public String getFormalShortName()
+    {
+        StringBuffer sb = new StringBuffer(getShortName());
+        sb.append(getFormalTypeParameterNames());
+        return sb.toString();
+    }
+
+    /**
+     * Returns the class name and the names of any formal type parameters associated with
+     * the type.  The format is suitable for use in location (such as variable declarations
+     * or extends clauses) where you want formal type parameters listed.
+     */
+    public String getFormalClassName()
+    {
+        StringBuffer sb = new StringBuffer(getClassName());
+        sb.append(getFormalTypeParameterNames());
+        return sb.toString();
+    }
+
+    /**
+     * Returns the underlying type declaration name
+     */
+    public TypeDeclaration getTypeDeclaration()
+    {
+        return _typeDecl;
     }
 
     TypeDeclaration _typeDecl;

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm	Fri Dec 17 15:51:15 2004
@@ -56,19 +56,21 @@
 ##
 #macro (declareEventAdaptor $adaptor)
     #set ($eventSet = $adaptor.eventSet)
-    protected static class $adaptor.className implements $eventSet.name, java.io.Serializable
+    #set ($binding = $adaptor.eventField.typeBindingMap)
+    protected static class $adaptor.className 
+                     implements ${eventSet.className}${adaptor.eventSetBinding}, java.io.Serializable
     {
         $client.className _client;
 
         ${adaptor.className}($client.className client) { _client = client; }
 
         #foreach ($event in $eventSet.events)
-            public ${event.returnType} ${event.name}(${event.argDecl}) $event.throwsClause
+            public ${event.getReturnType($binding)} ${event.name}(${event.getArgDecl($binding)}) $event.throwsClause
             {
             #if ($adaptor.hasHandler($event))
                 #if ($event.returnType != "void") return #end _client.${adaptor.getHandler($event).name}(${event.argList});
             #elseif ($event.returnType != "void")
-                return $event.defaultReturnValue;
+                return $event.getDefaultReturnValue($binding);
             #end
             }
         #end

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.java	Fri Dec 17 15:51:15 2004
@@ -64,6 +64,16 @@
     public String getClassName() { return _className; }
 
     /**
+     * Returns the class declaration for the ControlBean
+     */
+    public String getClassDeclaration() 
+    {
+        StringBuffer sb = new StringBuffer(_shortName);
+        sb.append(_controlIntf.getFormalTypeParameters());
+        return sb.toString();
+    }
+
+    /**
      * Returns the fully qualified classname of the ControlBean BeanInfo class.  The
      * standard JavaBean naming convention is used to enable automatic location by
      * the JavaBean introspector.

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm	Fri Dec 17 15:51:15 2004
@@ -98,12 +98,12 @@
     /**
      * Implements ${intf.className}.${operation.name}
      */
-    public $returnType ${operation.name}($operation.argDecl) $operation.throwsClause
+    public $operation.formalTypes $returnType ${operation.name}($operation.argDecl) $operation.throwsClause
     {
         Object [] argArray = new Object[] { $operation.argList };
         Throwable thrown = null;
         #if (!$intf.isExtension())
-        $intf.className target = ($intf.className)ensureControl();
+        $intf.formalClassName target = ($intf.formalClassName)ensureControl();
         #else
         Extensible target = (Extensible)ensureControl();
         #end
@@ -305,7 +305,7 @@
         $returnType retval = ${event.defaultReturnValue};
         #end
 
-        $event.eventSet.shortName listener = ($event.eventSet.shortName)getEventNotifier(${event.eventSet.shortName}.class).getListener();
+        $event.eventSet.formalShortName listener = ($event.eventSet.formalShortName)getEventNotifier(${event.eventSet.shortName}.class).getListener();
 
         //
         // If an event listener has been registered, then deliver the event
@@ -332,8 +332,9 @@
      * This inner class implements a simple proxy to deliver $eventSet.shortName events 
      * back to a register listener.
      */
-    protected class $eventSet.notifierClass extends $eventSet.notifierExtends
-        implements $eventSet.shortName, java.io.Serializable
+    protected class $eventSet.notifierClass
+        extends $eventSet.notifierExtends
+        implements ${eventSet.formalShortName}, java.io.Serializable
     {
         #foreach ($eventMethod in $eventSet.events)
             #declareEventImpl($eventMethod)
@@ -348,7 +349,7 @@
     /**
      * Registers a new listener for ${eventSet.shortName} events on the bean.
      */
-    public synchronized void ${eventSet.addListenerMethod}($eventSet.shortName listener)
+    public synchronized void ${eventSet.addListenerMethod}($eventSet.formalShortName listener)
                              throws java.util.TooManyListenersException
     {
         getEventNotifier(${eventSet.shortName}.class).addListener(listener);
@@ -357,7 +358,7 @@
     /**
      * Unregisters an existing listener for ${eventSet.shortName} events on the bean.
      */
-    public synchronized void ${eventSet.removeListenerMethod}($eventSet.shortName listener)
+    public synchronized void ${eventSet.removeListenerMethod}($eventSet.formalShortName listener)
     {
         getEventNotifier(${eventSet.shortName}.class).removeListener(listener);
     }
@@ -426,7 +427,9 @@
 import org.apache.beehive.controls.api.properties.PropertyMap;
 import org.apache.beehive.controls.api.versioning.*;
 
-public class ${bean.shortName} extends $bean.superClass.className implements $intf.className
+public class ${bean.classDeclaration} 
+       extends $bean.superClass.className 
+       implements ${intf.formalClassName}
 {
     #if ($intf.operations.size() != 0)
     #declareMethodStatics()

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBeanInfo.vm	Fri Dec 17 15:51:15 2004
@@ -248,7 +248,7 @@
         Class eventIntf;
 
         #foreach ($eventSet in $intf.eventSets)
-            eventIntf = ${eventSet.name}.class;
+            eventIntf = ${eventSet.className}.class;
 
             //
             // Find the add/remove listener methods

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlMacros.vm	Fri Dec 17 15:51:15 2004
@@ -69,7 +69,7 @@
         #end
         #foreach ($eventSet in $intf.eventSets)
             #foreach ($event in $eventSet.events)
-                $event.methodField = ${eventSet.name}.class.getMethod("${event.name}", new Class [] {$event.argTypes});
+                $event.methodField = ${eventSet.className}.class.getMethod("${event.name}", new Class [] {$event.argTypes});
                 _methodParamMap.put($event.methodField, new String [] { $event.getArgList(true) });
             #end
         #end

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/EventAdaptor.java	Fri Dec 17 15:51:15 2004
@@ -19,6 +19,9 @@
 
 import java.util.HashMap;
 
+import com.sun.mirror.type.TypeMirror;
+import com.sun.mirror.declaration.TypeParameterDeclaration;
+
 /**
  * The EventAdaptor class represents the generated class that is necessary to route
  * events for a EventSet onto implemented EventHandlers on an implementation class.
@@ -32,21 +35,27 @@
     {
         _eventField = eventField;
         _eventSet = eventSet;
+        _className = initClassName();
+    }
 
+    /**
+     * Computes a unique adaptor class name
+     */
+    private String initClassName()
+    {
         StringBuffer sb = new StringBuffer();
-
-        String fieldName = eventField.getName();
-        String setName = eventSet.getName();
+        String fieldName = _eventField.getName();
+        String setName = _eventSet.getClassName();
         sb.append(Character.toUpperCase(fieldName.charAt(0)));
         if (fieldName.length() > 1)
             sb.append(fieldName.substring(1));
         sb.append(setName.substring(setName.lastIndexOf('.') + 1));
         sb.append("EventAdaptor");
-        _className = sb.toString();
+        return sb.toString();
     }
 
     /**
-     * Returns the name of the generated class for this adaptor
+     * Returns the name of the generated class for this adaptor.
      */
     public String getClassName()
     {
@@ -54,6 +63,22 @@
     }
 
     /**
+     * Returns the name of the generated class for this adaptor, including any formal type
+     * declarations from the associate event set.
+     */
+    public String getFormalClassName()
+    {
+        StringBuffer sb = new StringBuffer(_className);
+        sb.append(_eventSet.getFormalTypeParameters());
+        return sb.toString();
+    }
+
+    /**
+     * Returns the event field associated with this event adaptor
+     */
+    public AptEventField getEventField() { return _eventField; }
+
+    /**
      * Returns the EventSet associated with this Adaptor
      */
     public AptEventSet getEventSet() { return _eventSet; }
@@ -81,6 +106,44 @@
     public AptMethod getHandler(AptEvent event)
     {
         return _handlerMap.get(event);
+    }
+
+    /**
+     * Returns any formal type parameter declaration for EventSet interface associated with 
+     * the adaptor class.  This will bind the formal types of the interface based on any type 
+     * binding from the event field declaration
+     */
+    public String getEventSetBinding()
+    {
+        // Get the type bindings for the associated event field.
+        HashMap<String,TypeMirror> typeBinding = _eventField.getTypeBindingMap();
+
+        StringBuffer sb = new StringBuffer();
+        boolean isFirst = true;
+        for (TypeParameterDeclaration tpd : 
+             _eventSet.getDeclaration().getFormalTypeParameters())
+        {
+            if (isFirst)
+            {
+                sb.append("<");
+                isFirst = false;
+            }
+            else
+                sb.append(", ");
+
+            // Map from the declared formal type name to the bound type name
+            // If no map entry exists (i.e. not bindings were specified on the field
+            // declaration, then the implied binding is to Object.class
+            String typeName = tpd.getSimpleName();
+            if (typeBinding.containsKey(typeName))
+                sb.append(typeBinding.get(tpd.getSimpleName()));
+            else
+                sb.append("java.lang.Object");
+        }
+        if (!isFirst)
+            sb.append(">");
+
+        return sb.toString();
     }
 
     private String _className;

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ImplInitializer.vm	Fri Dec 17 15:51:15 2004
@@ -56,7 +56,7 @@
 ##
 #macro (declareEventAdaptor $adaptor)
     #set ($eventSet = $adaptor.eventSet)
-    protected static class $adaptor.className implements $eventSet.name, java.io.Serializable
+    protected static class $adaptor.className implements $eventSet.className, java.io.Serializable
     {
         $impl.className _impl;
 
@@ -126,7 +126,7 @@
 ## This macro defines the initialization of a event notification proxy
 ##
 #macro (initEventProxy $proxy)
-    $proxy.type $proxy.localName = ($proxy.type)getEventNotifier(bean, ${proxy.type}.class);
+    $proxy.className $proxy.localName = ($proxy.className)getEventNotifier(bean, ${proxy.className}.class);
     #if ($init.needsReflection($proxy))
     ${proxy.reflectField}.set(impl, $proxy.localName);
     #else

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java&r1=122685&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java	Fri Dec 17 15:51:15 2004
@@ -132,9 +132,9 @@
                     ControlInterface annot = controlIntf.getDeclaration().getAnnotation(ControlInterface.class);
                     String defBinding = annot.defaultBinding();
 
-                    defBinding = ControlBeanContext.resolveDefaultBinding( defBinding, controlIntf.toString() );
+                    defBinding = ControlBeanContext.resolveDefaultBinding( defBinding, controlIntf.getDeclaration().getQualifiedName() );
 
-                    mf.addControlType( controlIntfOrExt.toString(), defBinding );
+                    mf.addControlType( controlIntfOrExt.getDeclaration().getQualifiedName(), defBinding );
                 }
 
                 mf.emit( f, clientPkg, clientManifestName, null );

Modified: incubator/beehive/trunk/controls/test/build.xml
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/build.xml?view=diff&rev=122686&p1=incubator/beehive/trunk/controls/test/build.xml&r1=122685&p2=incubator/beehive/trunk/controls/test/build.xml&r2=122686
==============================================================================
--- incubator/beehive/trunk/controls/test/build.xml	(original)
+++ incubator/beehive/trunk/controls/test/build.xml	Fri Dec 17 15:51:15 2004
@@ -141,7 +141,7 @@
     <!-- build - target to build controls, test drivers and junit tests -->
     <!-- ==================================================================== -->
 
-    <target name="build" depends="dirs, dbControl">
+    <target name="build" depends="dirs">
         <ant target="build-test-auxilaries"/>
         <ant target="build-test-beans" />
         <ant target="build-test-drivers" />
@@ -176,7 +176,7 @@
           inheritall="false"/>
     </target>
 
-    <target name="build-test-beans" depends="dirs,build-test-auxilaries">
+    <target name="build-test-beans" depends="dirs,build-test-auxilaries,dbControl">
 
         <!-- Build the InnerControl controls used by composition tests.  This is only
              necessary because the bean types are needed to compile a public interface -->
@@ -325,7 +325,7 @@
     <target name="checkin.tests" >
         <antcall target="clean" />
         <antcall target="build" />
-        <!--antcall target="run" /-->
+        <antcall target="run" />
         <echo message="${do.start.tomcat}"/>
         <property name="test.freq" value="checkin"/>
         <antcall target="run.test" />

Added: incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControl.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControl.java?view=auto&rev=122686
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControl.java	Fri Dec 17 15:51:15 2004
@@ -0,0 +1,53 @@
+package org.apache.beehive.controls.test.controls.generic;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.beehive.controls.api.bean.ControlInterface;
+import org.apache.beehive.controls.api.events.EventHandler;
+import org.apache.beehive.controls.api.events.EventSet;
+import org.apache.beehive.controls.api.properties.PropertySet;
+
+@ControlInterface
+public interface ListControl<E, T extends List<? extends E>>
+{
+    //
+    // Note: JSR-175 annotation types cannot have formal type parameters
+    //
+    @PropertySet
+    @Target( {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD} )
+    @Retention(RetentionPolicy.RUNTIME)
+    public static @interface ListProps
+    {
+        /**
+         * This property can be used to set the concrete List implementation
+         * to use for containing elements
+         */
+        Class<? extends List> listClass() default ArrayList.class;
+    }
+
+    public void add(E val);
+
+    public <X extends E> boolean contains(X val);
+
+    public E get(int index);
+
+    public T copy(Collection<? extends E> src);
+
+    public <X extends E> E getLast(Collection<X> coll);
+
+    //
+    // Test an EventSet that uses formal type paramters defined in the outer control interface.
+    //
+    @EventSet
+    public interface ListEvents<E>
+    {
+        public E onAdd(E newElement);
+    }
+}

Added: incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControlImpl.jcs
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControlImpl.jcs?view=auto&rev=122686
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/generic/ListControlImpl.jcs	Fri Dec 17 15:51:15 2004
@@ -0,0 +1,101 @@
+package org.apache.beehive.controls.test.controls.generic;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.bean.ControlImplementation;
+import org.apache.beehive.controls.api.bean.Extensible;
+import org.apache.beehive.controls.api.context.Context;
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.api.events.Client;
+import org.apache.beehive.controls.api.events.EventHandler;
+
+@ControlImplementation
+public class ListControlImpl<E, T extends List<E>> implements ListControl<E, T>, Extensible
+{ 
+    @Context ControlBeanContext context;
+
+    @EventHandler(field="context", eventSet=ControlBeanContext.LifeCycle.class, 
+                  eventName="onCreate")
+    public void onCreate()
+    {
+    }
+
+    @Client ListEvents<E> client;
+
+    /**
+     * Returns the list used to store control elements.  This is lazily instantiated, to
+     * allow the list class to be set by either an annotation or by calling setListClass()
+     * on the bean prior to manipulating the list.
+     */
+    private T getList()
+    {
+        if (_list == null)
+        {
+            Class<? extends List> listClass = 
+                                        context.getControlPropertySet(ListProps.class).listClass();
+            try
+            {
+                _list = (T)listClass.newInstance();
+            }
+            catch (Exception e)
+            {
+                throw new ControlException("Cannot create List", e);
+            }
+        }
+        return _list;
+    }
+
+    public void add(E val) 
+    {
+        getList().add(val);
+        client.onAdd(val);
+    };
+
+    public <X extends E> boolean contains(X val) 
+    { 
+        return getList().contains(val); 
+    }
+
+    public E get(int index) 
+    { 
+        return getList().get(index); 
+    }
+
+    public T copy(Collection<? extends E> src) 
+    {
+        T list = getList();
+        for (E item: src)
+            list.add(item);
+
+        return list;
+    }
+
+    public <X extends E> E getLast(Collection<X> coll) 
+    { 
+        E last = null;
+        Iterator<X> collIter = coll.iterator();
+        while (collIter.hasNext())
+            last = collIter.next();
+
+        return last;
+    }
+
+    /**
+     * TBD
+     */
+    public Object invoke(Method method, Object [] args) throws Throwable
+    {
+        // To Be Implemented
+        //
+        return null; 
+    }
+
+    //
+    // NEVER ACCESS DIRECTLY... ALWAYS CALL GETLIST()!!!!
+    //
+    T _list;
+}

Added: incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/generic/GenericTest.java
Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/generic/GenericTest.java?view=auto&rev=122686
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/generic/GenericTest.java	Fri Dec 17 15:51:15 2004
@@ -0,0 +1,119 @@
+package org.apache.beehive.controls.test.java.generic;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.beehive.controls.api.bean.Control;
+import org.apache.beehive.controls.api.events.EventHandler;
+
+import org.apache.beehive.controls.test.controls.generic.ListControl;
+import org.apache.beehive.controls.test.controls.generic.ListControlBean;
+import org.apache.beehive.controls.test.controls.util.TestBeanContext;
+
+import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
+
+/**
+ * A TestCase that tests control composition.
+ * The outer control is instantiated declaratively, and the outer
+ * control instantiates the nested control declaratively
+ *
+ * Instantiating controls declaratively is not supported currently.
+ * All tests are deactivated until this is supported
+ */
+@Freq("checkin")
+public class GenericTest extends TestCase
+{
+    // initialize declared controls once
+    public GenericTest(String name) throws Exception
+    {
+        super(name);
+    	_testContext = createTestBeanContext();
+    }
+
+
+    // begin and end control bean context for each test
+    public void setUp() throws Exception
+    {
+        org.apache.beehive.controls.api.bean.Controls.initializeClient( null, this, _testContext );
+        _testContext.beginContext();
+    }
+
+    public void tearDown() throws Exception
+    {
+        _testContext.endContext();
+    }
+
+    /**
+     * Returns a new TestBeanContext to act as a container for control testing.
+     */
+    private TestBeanContext createTestBeanContext() throws Exception
+    {
+        return new TestBeanContext();
+    }
+
+    private TestBeanContext _testContext;
+
+    /**
+     * A control that contains a nested control
+     */
+    @Control
+    @ListControl.ListProps(listClass=ArrayList.class)
+    public ListControlBean<String,ArrayList<String>> stringBean;
+
+    /**
+     * Declare a specific bound event handler to process events.  Note that the parameter and
+     * return type are bound to 'String', based upon the field declaration binding 
+     * (E -> String) above
+     */
+    @EventHandler(field="stringBean", eventSet=ListControl.ListEvents.class, 
+                  eventName="onAdd")
+    public String onAdd( String addString )
+    {
+        _addString = addString;
+        return addString;
+    }
+
+    private String _addString;
+
+    /**
+     * Tests usage of a generic control type/event handler that are declaratively instantiated
+     */
+    public void testDeclarative() throws Exception
+    {
+        // Test invoking a bound operation, this should also result in the above event
+        // handler being called in a bound fashion
+        stringBean.add("foo");
+
+        // Check the event handler invocation
+        if (!"foo".equals(_addString))
+            fail("onAdd event handler not called");
+    }
+
+    int _newInt;
+
+    /**
+     * Tests usage of a generic control type/event handler that are programmatic instantiated
+     */
+    public void testProgrammatic() throws Exception
+    {
+        ListControlBean<Integer, LinkedList<Integer>> intBean = 
+            new ListControlBean<Integer, LinkedList<Integer>>();
+        intBean.setListClass(LinkedList.class);
+        intBean.addListEventsListener(
+            new ListControl.ListEvents<Integer>()
+                { 
+                    public Integer onAdd(Integer newInt) 
+                    { 
+                        _newInt = newInt; 
+                        return newInt;
+                    } 
+                }
+            );
+        intBean.add(3);
+        if (_newInt != 3)
+            fail("onAdd listener not called");
+    }
+}