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; + [EMAIL PROTECTED] +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; + [EMAIL PROTECTED] +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 + */ [EMAIL PROTECTED]("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"); + } +}
