Author: kentam
Date: Fri Oct  1 11:13:41 2004
New Revision: 47657

Added:
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ClientInitializer.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlClient.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlClient.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/composition/ComposerBeanDriver.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/ComposerTest.java
   (contents, props changed)
Modified:
   
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlBeanContext.java
   
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/bean/ControlBeanContext.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlField.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlImpl.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.vm
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlField.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlImplementation.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
   
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/TwoPhaseAnnotationProcessor.java
   incubator/beehive/trunk/controls/test/build.xml
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/Composer.java
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/ComposerImpl.jcs
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/NestedImpl.jcs
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControl.java
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/context/BaseContextImpl.jcs
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/TestBeanContext.java
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/EventHandlerTest.java
Log:
Introduce generalized initializers for Java-based declarative control clients.  
These initializers provide a simple, uniform mechanism for any Java class to be 
a declarative control client, supporting @Control and @EventMethod annotations. 
 Apt-driven compilation of a Java class that has @Control annotations will 
result in an initializer class that encapsulates all the work necessary to wire 
up the contained controls.  See 
org.apache.beehive.controls.test.java.composition.DeclarativeTest for an 
example of this. 

The controls runtime itself now uses this mechanism to handle nested controls.
See org.apache.beehive.controls.runtime.bean.ControlBean for how this works.  



Modified: 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlBeanContext.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlBeanContext.java
    (original)
+++ 
incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlBeanContext.java
    Fri Oct  1 11:13:41 2004
@@ -19,6 +19,7 @@
 
 import java.beans.beancontext.BeanContextServices;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
 
 import org.apache.beehive.controls.api.events.EventSet;
@@ -119,6 +120,12 @@
      * @see org.apache.beehive.control.api.context.ControlHandle
      */
     public ControlHandle getControlHandle();
+
+    /**
+     * Returns the PropertyMap containing default properties for an 
AnnotatedElement
+     * in the current context.
+     */
+    public PropertyMap getAnnotationMap(AnnotatedElement annotElem);
 
     /**
      * Returns the ClassLoader used to load the ControlBean class associated 
with the control

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ClientInitializer.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ClientInitializer.java
        Fri Oct  1 11:13:41 2004
@@ -0,0 +1,39 @@
+package org.apache.beehive.controls.runtime.bean;
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+import java.lang.reflect.AnnotatedElement;
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.api.properties.PropertyMap;
+
+/**
+ * The ClientInitializer class is an abstract base class that all generated 
Control
+ * client initializer classes will extend.  It provides common utilities and 
supporting code
+ * for initialization, and has a shared package relationship with the base 
ControlBean
+ * class providing access to internals not available in a more general context.
+ */
+abstract public class ClientInitializer
+{
+    /**
+     * Returns the annotation map for the specified bean/element combination.
+     */
+    public static PropertyMap getAnnotationMap(ControlBeanContext cbc, 
AnnotatedElement annotElem)
+    {
+        return cbc.getAnnotationMap(annotElem);
+    }
+}

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/bean/ControlBean.java
      (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java
      Fri Oct  1 11:13:41 2004
@@ -26,6 +26,7 @@
 import java.beans.beancontext.BeanContextSupport;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Method;
+import java.lang.reflect.Field;
 import java.lang.annotation.Annotation;
 import java.util.*;
 
@@ -290,23 +291,41 @@
                 // Query the current context for the binding between public 
interface and
                 // an associated implementation.
                 //
-                ControlBeanContext context = getBeanContextProxy(); 
+                ControlBeanContext context = getBeanContextProxy();
                 Class implClass = context.getControlBinding(_controlClass);
 
                 //
                 // Create and initialize the new instance
                 //
                 _control = implClass.newInstance();
+
                 try
                 {
+                    if ( isControlClient( implClass ) )
+                    {
+                        // TODO: localize computation of initializer classname
+                        Class clientInitClass = 
implClass.getClassLoader().loadClass(
+                                                    implClass.getName() + 
"ClientInitializer" );
+
+                        Method clientInitMethod =
+                            clientInitClass.getMethod( "initialize",
+                                                       
org.apache.beehive.controls.api.context.ControlBeanContext.class,
+                                                       implClass );
+                        if ( clientInitMethod == null )
+                           throw new Exception( "Control client init class " + 
clientInitClass +
+                                                " missing initialize() method" 
);
+
+                        clientInitMethod.invoke( null, 
this.getControlBeanContext(), _control );
+                    }
+
                     Class initClass = implClass.getClassLoader().loadClass(
                                             implClass.getName() + 
"Initializer");
                     ControlInitializer initializer = 
(ControlInitializer)initClass.newInstance();
                     initializer.initialize(this, _control);
                 }
-                catch (ClassNotFoundException cnfe)
+                catch (Exception e)
                 {
-                    throw new ControlException("Control initialization 
failure", cnfe);
+                    throw new ControlException("Control initialization 
failure", e);
                 }
 
                 //
@@ -604,6 +623,28 @@
     /* package */ PropertyMap getPropertyMap()
     {
         return _properties;
+    }
+
+    /**
+     * Determines if the control impl class uses controls (is a control client)
+     */
+    protected boolean isControlClient( Class implClass )
+    {
+        // Examine all fields for @Control annotation.
+        // Can't use Class.getFields() since that only returns public fields
+        while ( implClass != null )
+        {
+            Field [] fields = implClass.getDeclaredFields();
+            for ( Field f : fields )
+            {
+                if ( f.getAnnotation( 
org.apache.beehive.controls.api.bean.Control.class ) != null )
+                    return true;
+            }
+
+            implClass = implClass.getSuperclass();
+        }
+
+        return false;
     }
 
     /**

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
       (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
       Fri Oct  1 11:13:41 2004
@@ -387,6 +387,8 @@
         ControlBeanContext beanContext = this;
         while (beanContext != null)
         {
+            // REVIEW: should ControlContainerContext-derived classes override 
getBeanAnnotationMap?  Not sure
+            // that name makes sense, and perhaps it shouldn't take a 
ControlBean.
             if (beanContext instanceof ControlContainerContext)
                 return beanContext.getBeanAnnotationMap(_bean, annotElem);
             beanContext = (ControlBeanContext)beanContext.getBeanContext();
@@ -403,11 +405,15 @@
     protected PropertyMap getBeanAnnotationMap(ControlBean bean, 
AnnotatedElement annotElem)
     {
         PropertyMap map = new AnnotatedElementMap(annotElem);
-        setDelegateMap( map, bean, annotElem );
+
+        // REVIEW: is this the right place to handle the general control 
client case?
+        if ( bean != null )
+            setDelegateMap( map, bean, annotElem );
+        
         return map;
     }
 
-    protected void setDelegateMap( PropertyMap map, ControlBean bean, 
AnnotatedElement annotElem )
+    static protected void setDelegateMap( PropertyMap map, ControlBean bean, 
AnnotatedElement annotElem )
     {
         //
         // If building an annotation map for a method or field, we want to 
delegate back

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.java
   Fri Oct  1 11:13:41 2004
@@ -0,0 +1,107 @@
+package org.apache.beehive.controls.runtime.generator;
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+
+/**
+ * The ClientInitializer represents a generated class that contains the code
+ * necessary to initialize a client that uses controls declaratively (via 
Control and
+ * EventHandler annotations).
+ */
+public class ClientInitializer extends GenClass
+{
+    /**
+     * Constructs a new ClientInitializer class supporting a particular 
control bean implementation
+     * @param beanInterface the public interface associated with the bean
+     */
+    protected ClientInitializer(ControlClient controlClient)
+    {
+        super();
+        _controlClient = controlClient;
+        if (_controlClient != null)
+        {
+            _packageName = _controlClient.getPackage();
+            _shortName = _controlClient.getShortName() + "ClientInitializer";
+            _className = _packageName + "." + _shortName;
+        }
+
+        //
+        // Compute the list of impl fields that will require reflected Fields. 
 This is
+        // done unconditionally for all @Control fields (to support 
PropertyMap initialization)
+        //
+
+        _reflectFields = new ArrayList<GenField>();
+        for (GenField genField : _controlClient.getControls())
+            _reflectFields.add(genField);
+    }
+
+    /**
+     * Returns the package name of the ClientInitializer
+     */
+    public String getPackage() { return _packageName; }
+
+    /**
+     * Returns the unqualified classname of the ClientInitializer
+     */
+    public String getShortName() { return _shortName; }
+
+    /**
+     * Returns the fully qualfied classname of the ClientInitializer
+     */
+    public String getClassName() { return _className; }
+
+    /**
+     * Returns the ControlBean implementation instance
+     */
+    public ControlClient getControlClient() { return _controlClient; }
+
+    public ClientInitializer getSuperClass() { return null; }
+
+    /**
+     * Returns true if the initializer will use Reflection to initialize the 
field, false
+     * otherwise.
+     */
+    static public boolean needsReflection(GenField genField)
+    {
+        //
+        // Since initializers are generated into the same package as the 
initialized class,
+        // only private access fields require reflection
+        //
+        String accessModifier = genField.getAccessModifier();
+        if (accessModifier.equals("private"))
+            return true;
+
+        return false;
+    }
+
+    /**
+     * Returns the list of impl class fields that must be initialized using 
Reflection
+     */
+    public ArrayList<GenField> getReflectFields()
+    {
+        return _reflectFields;
+    }
+
+    String _packageName;
+    String _shortName;
+    String _className;
+    ControlClient _controlClient;
+    ArrayList<GenField> _reflectFields;
+}

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ClientInitializer.vm
     Fri Oct  1 11:13:41 2004
@@ -0,0 +1,174 @@
+##
+## The Velocity code generation template for the ClientInitializer class 
generated for
+## a control client class (a class that uses controls declaratively).
+##
+## Copyright 2004 The Apache Software Foundation.
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+## 
+##     http://www.apache.org/licenses/LICENSE-2.0
+## 
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+## $Header:$
+##
+## The following context variables are used by this template:
+##      $client - a ControlClient instance
+##      $init - a ClientInitializer instance that defines the attributes of 
the intializer
+##
+## The actual class template apears at the end of this file, and is preceded 
by a number of
+## supporting macros that define elements of the template.
+##
+## SUPPORTING MACROS
+##
+## This macro defines any static final Field values needed for field 
initialization
+##
+#macro (declareReflectFields)
+    #foreach ($field in $init.reflectFields)
+        static final Field $field.reflectField;
+    #end
+#end
+##
+## This macro initializes the value of any static final Field values for field 
initialization
+##
+#macro (initReflectFields)
+    try
+    {
+    #foreach ($field in $init.reflectFields)
+        $field.reflectField = 
${client.className}.class.getDeclaredField("$field.name");
+        ${field.reflectField}.setAccessible(true);
+    #end
+    }
+    catch (NoSuchFieldException nsfe)
+    {
+        throw new ExceptionInInitializerError(nsfe);
+    }
+#end
+##
+## This macro declares a new event adaptor class that maps events from an 
EventSet to
+## a set of implemented handlers on a control client
+##
+#macro (declareEventAdaptor $adaptor)
+    #set ($eventSet = $adaptor.eventSet)
+    protected static class $adaptor.className implements $eventSet.name, 
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
+            {
+            #if ($adaptor.hasHandler($event))
+                #if ($event.returnType != "void") return #end 
_client.${adaptor.getHandler($event).name}(${event.argList});
+            #elseif ($event.returnType != "void")
+                return $event.defaultReturnValue;
+            #end
+            }
+        #end
+    }
+
+#end
+##
+## This macro declares the generated classes that act as event adaptors 
between an event
+## source (control in this case) and client class event handlers.
+##
+#macro (declareEventAdaptors)
+    #foreach ($control in $client.controls)
+        #foreach ($adaptor in $control.eventAdaptors)
+            #declareEventAdaptor($adaptor)
+        #end
+    #end
+#end
+##
+## This macro initializes any event adaptors for a declared control
+##
+#macro (initEventAdaptors $control)
+    #foreach ($adaptor in $control.eventAdaptors)
+        ${control.localName}.${adaptor.eventSet.addListenerMethod}(new 
${adaptor.className}(client));
+    #end
+#end
+##
+##
+## This macro defines the initialization of a declared control
+##
+#macro (initControl $control)
+    $control.controlBean.className $control.localName = new 
${control.controlBean.className}(cbc, "$control.name", getAnnotationMap(cbc, 
${control.reflectField}));
+    #initEventAdaptors($control)
+    #if ($init.needsReflection($control))
+    ${control.reflectField}.set(client, $control.localName);
+    #else
+    client.${control.name} = $control.localName; 
+    #end
+
+#end
+##
+## This macro defines the initialization method for all declared control 
instances.
+##
+#macro (declareFieldInit)
+    private static void initializeFields(ControlBeanContext cbc,
+                                         $client.className client)
+    {
+        try
+        {
+            #foreach ($control in $client.Controls)
+            #if ($velocityCount == 1)
+            //
+            // Initialize any nested controls used by the client
+            //
+            #end 
+            #initControl($control) 
+            #end
+        }
+        catch (RuntimeException re) { throw re; }
+        catch (Exception e)
+        {
+            throw new ControlException("Initializer failure", e);
+        }
+    }
+#end
+
+##
+## THE CONTROL INITIALIZER CLASS TEMPLATE
+##
+package $init.package;
+
+import java.lang.reflect.Field;
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.runtime.bean.ControlBean;
+
+public class $init.shortName
+             extends org.apache.beehive.controls.runtime.bean.ClientInitializer
+{
+    #if ($init.reflectFields.size() != 0)
+        #declareReflectFields()
+        static
+        {
+            #initReflectFields()
+        }
+    #end
+
+    #if ($client.needsFieldInit())
+    #declareEventAdaptors()
+
+    #declareFieldInit()
+    #end
+
+    public static void initialize(ControlBeanContext cbc, $client.ClassName 
client)
+    {
+        #if ($client.hasSuperClient())
+        ${client.SuperClientName}.initialize( cbc, client );
+        #end
+
+        #if ($client.needsFieldInit())
+        initializeFields( cbc, client );
+        #end
+    }
+}

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlClient.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlClient.java
       Fri Oct  1 11:13:41 2004
@@ -0,0 +1,123 @@
+package org.apache.beehive.controls.runtime.generator;
+
+import com.sun.mirror.apt.Filer;
+
+import java.util.List;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.io.IOException;
+import java.io.Writer;
+
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+public abstract class ControlClient extends GenClass
+{
+    /**
+     * Initializes the ControlClient class.  This will be called by custom 
subclasses to drive
+     * the initialization process.
+     */
+    protected void init()
+    {
+        _controls = initControls();
+        initEventAdaptors();
+
+        //
+        // Construct a new initializer class from this implementation class
+        //
+        _init = new ClientInitializer(this);       
+    }
+
+    /**
+     * Initializes the list of ControlFields declared directly by this 
ControlClient
+     */
+    abstract protected ArrayList<ControlField> initControls();
+
+    /**
+     * Returns the list of ControlFields declared directly by this ControlImpl
+     */
+    public ArrayList<ControlField> getControls() { return _controls; }
+
+    /**
+     * Returns true if the implemenation class contains any nested controls
+     */
+    public boolean hasControls() { return _controls.size() != 0; }
+
+    abstract protected boolean hasSuperClient();
+
+    /**
+     * Returns the fully qualified classname of the closest control client in 
the inheritance chain.
+     * @return
+     */
+    abstract protected String getSuperClientName();
+
+    /**
+     * Initializes the ControlEventAdaptors associated with this ControlClient
+     */
+    abstract protected void initEventAdaptors();
+
+    /**
+     * Returns true if the control client needs field initialization support
+     */
+    public boolean needsFieldInit()
+    {
+        return hasControls();
+    }
+
+    /**
+     * Returns the field with the specified name
+     */
+    public GenField getField(String name)
+    {
+        for (GenField genField : _controls)
+            if (genField.getName().equals(name))
+                return genField;
+
+        return null;
+    }
+
+    /**
+     * Returns the list of fully qualified class names for types that are 
derived
+     * from this GenClass
+     */
+    public String [] getGeneratedTypes()
+    {
+        return new String [] { _init.getClassName() };
+    }
+
+    /**
+     * Returns the information necessary to generate a ControlBean from this 
ControlInterface
+     */
+    public List<GeneratorOutput> getGeneratorOutput(Filer filer) throws 
IOException
+    {
+        HashMap<String,Object> map = new HashMap<String,Object>();
+        map.put("client", this);                                // control 
client
+        map.put("init", _init);                                 // control 
client initializer
+
+        Writer writer = new 
IndentingWriter(filer.createSourceFile(_init.getClassName()));
+        GeneratorOutput genOut =
+            new 
GeneratorOutput(writer,"org/apache/beehive/controls/runtime/generator/ClientInitializer.vm",
+                                map);
+        ArrayList<GeneratorOutput> genList = new ArrayList<GeneratorOutput>(1);
+        genList.add(genOut);
+        return genList;
+    }
+
+    ArrayList<ControlField> _controls;
+    ClientInitializer _init;
+}

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlField.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlField.java
        (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlField.java
        Fri Oct  1 11:13:41 2004
@@ -27,12 +27,12 @@
 {
     /**
      * Base constructor, protected so only a custom subclass can invoke
-     * @param controlImpl the declaring ControlImpl
+     * @param controlClient
      */
-    protected ControlField(ControlImpl controlImpl) 
+    protected ControlField( GenClass controlClient )
     {
-        _controlImpl = controlImpl;
-    };
+        _controlClient = controlClient;
+    }
 
     /**
      * Initializes the ControlField instance.  This will be called by custom 
subclasses to drive
@@ -49,6 +49,6 @@
      */
     public ControlBean getControlBean() { return _controlBean; }
 
-    private ControlImpl _controlImpl;
+    private GenClass    _controlClient;
     private ControlBean _controlBean;
 }

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlImpl.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlImpl.java
 (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlImpl.java
 Fri Oct  1 11:13:41 2004
@@ -17,7 +17,6 @@
  * $Header:$
  */
 
-import java.io.File;
 import java.io.IOException;
 import java.io.Writer;
 import java.util.ArrayList;
@@ -39,9 +38,9 @@
     protected void init()
     {
         _superClass = initSuperClass();
-        _controls = initControls();
         _contexts = initContexts();
         _clients = initClients();
+        _ignoredEventFields = initIgnoredEventFields();
         initEventAdaptors();
 
         //
@@ -62,11 +61,6 @@
     abstract public ControlInterface getControlInterface();
 
     /**
-     * Initializes the list of ControlFields declared directly by this 
ControlImpl
-     */
-    abstract protected ArrayList<ControlField> initControls();
-
-    /**
      * Initializes the list of ContextFields declared directly by this 
ControlImpl
      */
     abstract protected ArrayList<ContextField> initContexts();
@@ -77,19 +71,18 @@
     abstract protected ArrayList<ClientField> initClients();
 
     /**
-     * Returns the super interface for this interface
+     * Initializes the list of fields for which event handlers should be 
ignored
+     * for this ControlImpl.
+     *
+     * This allows multiple annotation processors to process event handlers 
without
+     * spurious errors.
      */
-    public ControlImpl getSuperClass() { return _superClass; }
+    abstract protected ArrayList<EventField> initIgnoredEventFields();
 
     /**
-     * Returns the list of ControlFields declared directly by this ControlImpl
-     */
-    public ArrayList<ControlField> getControls() { return _controls; }
-
-    /**
-     * Returns true if the implemenation class contains any nested controls
+     * Returns the super interface for this interface
      */
-    public boolean hasControls() { return _controls.size() != 0; }
+    public ControlImpl getSuperClass() { return _superClass; }
 
     /**
      * Returns the list of ContextFields declared directly by this ControlImpl
@@ -121,7 +114,7 @@
      */
     public boolean needsFieldInit()
     {
-        return hasControls() || hasContexts() || hasClients();
+        return hasContexts() || hasClients();
     }
 
     /**
@@ -129,9 +122,6 @@
      */
     public GenField getField(String name)
     {
-        for (GenField genField : _controls)
-            if (genField.getName().equals(name))
-                return genField;
         for (GenField genField : _contexts)
             if (genField.getName().equals(name))
                 return genField;
@@ -142,6 +132,15 @@
         return null;
     }
 
+    public EventField getIgnoredEventField(String name)
+    {
+        for (EventField eventField : _ignoredEventFields)
+            if (eventField.getName().equals(name))
+                return eventField;
+        
+        return null;
+    }
+
     /**
      * Returns the list of fully qualified class names for types that are 
derived
      * from this GenClass
@@ -159,8 +158,6 @@
         HashMap<String,Object> map = new HashMap<String,Object>();
         map.put("impl", this);                                  // control 
implementation
         map.put("init", _init);                                  // control 
impl initializer
-        map.put("intf", getControlInterface());                 // control 
interface
-        map.put("bean", new ControlBean(getControlInterface()));// control bean
 
         Writer writer = new 
IndentingWriter(filer.createSourceFile(_init.getClassName()));
         GeneratorOutput genOut = 
@@ -172,8 +169,8 @@
     }
 
     ControlImpl _superClass;
-    ArrayList<ControlField> _controls;
     ArrayList<ContextField> _contexts;
     ArrayList<ClientField> _clients;
+    ArrayList<EventField> _ignoredEventFields;
     ControlInitializer _init;
 }

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.java
  (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.java
  Fri Oct  1 11:13:41 2004
@@ -52,12 +52,9 @@
         }
 
         //
-        // Compute the list of impl fields that will require reflected Fields. 
 This is
-        // done unconditionally for all @Control fields (to support 
PropertyMap initialization),            // and only if needed to initialize for 
fields of other types.
+        // Compute the list of impl fields that will require reflected Fields.
         //
         _reflectFields = new ArrayList<GenField>();
-        for (GenField genField : _controlImpl.getControls())
-            _reflectFields.add(genField);
         for (GenField genField : _controlImpl.getContexts())
             if (needsReflection(genField))
                 _reflectFields.add(genField);

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.vm
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.vm
    (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlInitializer.vm
    Fri Oct  1 11:13:41 2004
@@ -20,7 +20,6 @@
 ##
 ## The following context variables are used by this template:
 ##      $init - a ControlInitializer instance that defines the attributes of 
the intializer
-##      $intf - a ControlInterface instance that defines the attributes of the 
public interface
 ##
 ## The actual class template apears at the end of this file, and is preceded 
by a number of
 ## supporting macros that define elements of the template.
@@ -72,8 +71,6 @@
                 return $event.defaultReturnValue;
             #end
             }
-
-            #set ($eventHandler = "")
         #end
     }
 
@@ -83,11 +80,6 @@
 ## source (control or context) and implementation class event handlers.
 ##
 #macro (declareEventAdaptors)
-    #foreach ($control in $impl.controls)
-        #foreach ($adaptor in $control.eventAdaptors)
-            #declareEventAdaptor($adaptor)
-        #end
-    #end
     #foreach ($context in $impl.contexts)
         #foreach ($adaptor in $context.eventAdaptors)
             #declareEventAdaptor($adaptor)
@@ -104,27 +96,13 @@
 #end
 ##
 ##
-## This macro defines the initialization of a nested control
-##
-#macro (initControl $control)
-    $control.controlBean.className $control.localName = new 
${control.controlBean.className}(_initBeanContext, "$control.name", 
getAnnotationMap(bean, ${control.reflectField}));
-    #initEventAdaptors($control)
-    #if ($init.needsReflection($control))
-    ${control.reflectField}.set(impl, $control.localName);
-    #else
-    impl.$control.name = $control.localName; 
-    #end
-
-#end
-##
-##
 ## This macro defines the initialization of a contextual service
 ##
 #macro (initContext $context)
     #if 
($context.getType().equals("org.apache.beehive.controls.api.context.ControlBeanContext"))
-    $context.type $context.localName = _initBeanContext;
+    $context.type $context.localName = initBeanContext;
     #else
-    $context.type $context.localName = 
($context.type)_initBeanContext.getService(${context.type}.class, null);
+    $context.type $context.localName = 
($context.type)initBeanContext.getService(${context.type}.class, null);
     #end
     if ($context.localName == null)
         throw new ControlException("Contextual service $context.type is not 
available");
@@ -156,17 +134,9 @@
     public void initializeFields(ControlBean bean, $impl.className impl)
     {
 
-        ControlBeanContext _initBeanContext = bean.getControlBeanContext();
+        ControlBeanContext initBeanContext = bean.getControlBeanContext();
         try
         {
-            #foreach ($control in $impl.controls)
-            #if ($velocityCount == 1)
-            //
-            // Initialize any nested controls used by the implementation
-            //
-            #end 
-            #initControl($control) 
-            #end
             #foreach ($context in $impl.contexts)
             #if ($velocityCount == 1)
             //
@@ -224,14 +194,14 @@
 
     public void initialize(ControlBean bean, Object impl)
     {
-        $impl.className _impl = ($impl.ClassName)impl;
+        $impl.className specificImpl = ($impl.ClassName)impl;
 
         #if ($init.hasSuperClass())
-        super.initialize(bean, _impl);
+        super.initialize(bean, specificImpl);
 
         #end
         #if ($impl.needsFieldInit())
-        initializeFields(bean, _impl);
+        initializeFields(bean, specificImpl);
 
         #end
     }

Added: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlClient.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlClient.java
        Fri Oct  1 11:13:41 2004
@@ -0,0 +1,263 @@
+package org.apache.beehive.controls.runtime.generator.apt;
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.declaration.*;
+import com.sun.mirror.type.TypeMirror;
+import com.sun.mirror.type.ClassType;
+
+import org.apache.beehive.controls.api.events.EventHandler;
+
+import org.apache.beehive.controls.runtime.generator.*;
+
+public class AptControlClient extends ControlClient
+{
+    /**
+     * Constructs a new ControlImpl instance where information is derived
+     * from APT metadata
+     * @param decl the annotated declaration
+     */
+    public AptControlClient(TypeDeclaration decl, 
AnnotationProcessorEnvironment env)
+    {
+        super();
+        _env = env;
+        if (! (decl instanceof ClassDeclaration))
+        {
+            env.getMessager().printError(decl.getPosition(),
+              "The Control annotation may only be used in a Java class");
+            return;
+        }
+
+        _clientDecl = (ClassDeclaration)decl;
+
+        init();
+    }
+
+    /**
+     * Initializes the list of ControlFields declared directly by this 
ControlClient
+     */
+    protected ArrayList<ControlField> initControls()
+    {
+        ArrayList<ControlField> controls = new ArrayList<ControlField>();
+
+        if ( _clientDecl == null || _clientDecl.getFields() == null )
+            return controls;
+
+        Collection<FieldDeclaration> declaredFields = _clientDecl.getFields();
+        for (FieldDeclaration fieldDecl : declaredFields)
+        {
+            if 
(fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != 
null)
+                controls.add(new AptControlField(this, fieldDecl, _env));
+        }
+        return controls;
+    }
+
+    protected boolean hasSuperClient()
+    {
+        return ( getSuperClientName() != null );
+    }
+
+    /**
+     * Returns the fully qualified classname of the closest control client in 
the inheritance chain.
+     * @return
+     */
+    protected String getSuperClientName()
+    {
+        ClassType superType = _clientDecl.getSuperclass();
+        ClassDeclaration superDecl = superType.getDeclaration();
+
+        while ( superType != null )
+        {
+            Collection<FieldDeclaration> declaredFields = 
superDecl.getFields();
+            for (FieldDeclaration fieldDecl : declaredFields)
+            {
+                if 
(fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != 
null)
+                {
+                    // Found an @control annotated field, so return this class 
name
+                    return superDecl.getQualifiedName();
+                }
+            }
+
+            superType = superType.getSuperclass();
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the super class for this class
+     */
+    public GenClass getSuperClass() { return null; }
+
+    /**
+     * Returns the fully qualified package name of the ControlImpl
+     */
+    public String getPackage()
+    {
+        if ( _clientDecl == null || _clientDecl.getPackage() == null )
+            return null;
+        
+        return _clientDecl.getPackage().getQualifiedName();
+    }
+
+    /**
+     * Returns the unqualified classname of this ControlImpl
+     */
+    public String getShortName()
+    {
+        if ( _clientDecl == null )
+            return null;
+        
+        return _clientDecl.getSimpleName();
+    }
+
+    /**
+     * Returns the fully qualified classname of this ControlImpl
+     */
+    public String getClassName()
+    {
+        if ( _clientDecl == null )
+            return null;
+        
+        assert _clientDecl.getQualifiedName().equals( getPackage() + "." + 
getShortName() );
+        
+        return _clientDecl.getQualifiedName();
+    }
+
+    /**
+     * Initializes the list of EventAdaptors for this ControlImpl
+     */
+    protected void initEventAdaptors()
+    {
+        if ( _clientDecl == null || _clientDecl.getMethods() == null )
+            return;
+        
+        for (MethodDeclaration clientMethod : _clientDecl.getMethods())
+        {
+            //
+            // Do a quick check for the presence of the EventHandler 
annotation on methods
+            //
+            if (clientMethod.getAnnotation(EventHandler.class) == null)
+                continue;
+
+            //
+            // If found, we must actually read the value using an 
AnnotationMirror, since it
+            // contains a Class element (eventSet) that cannot be loaded
+            //
+            AnnotationMirror handlerMirror = null;
+            for (AnnotationMirror annot : clientMethod.getAnnotationMirrors())
+            {
+                if ( annot == null ||
+                    annot.getAnnotationType() == null ||
+                    annot.getAnnotationType().getDeclaration() == null ||
+                    
annot.getAnnotationType().getDeclaration().getQualifiedName() == null )
+                    return;
+
+                if ( 
annot.getAnnotationType().getDeclaration().getQualifiedName().equals(
+                        "org.apache.beehive.controls.api.events.EventHandler"))
+                {
+                    handlerMirror = annot;
+                    break;
+                }
+            }
+            if (handlerMirror == null)
+            {
+                throw new CodeGenerationException("Unable to find EventHandler 
annotation on " +
+                                                  clientMethod);
+            }
+
+            AptAnnotationHelper handlerAnnot = new 
AptAnnotationHelper(handlerMirror);
+
+            //
+            // Locate the EventField based upon the field element value
+            //
+            String fieldName = (String)handlerAnnot.getObjectValue("field");
+            EventField eventField = (EventField)getField(fieldName);
+            if (eventField == null)
+            {
+                // Deliberately not issuing a diagnostic if an event handler 
specifies
+                // a field that isn't a control.  Other annotation processors 
also
+                // handle event handlers, so delegate diagnostic 
responsibility to them.
+                continue;
+            }
+
+            //
+            // Locate the EventSet based upon the eventSet element value
+            //
+            TypeMirror tm = (TypeMirror)( 
handlerAnnot.getObjectValue("eventSet") );
+            if ( tm == null )
+                continue;
+            String setName = tm.toString();
+
+            ControlInterface controlIntf = eventField.getControlInterface();
+            ControlEventSet eventSet = controlIntf.getEventSet(setName);
+            if (eventSet == null)
+            {                
+                _env.getMessager().printError(clientMethod.getPosition(),
+                    "Cannot find EventSet interface: " + setName);
+                continue;
+            }
+
+            //
+            // Register a new EventAdaptor for the EventSet, if none exists 
already
+            //
+            EventAdaptor adaptor = eventField.getEventAdaptor(eventSet);
+            if (adaptor == null)
+            {
+                adaptor = new EventAdaptor(eventField, eventSet);
+                eventField.addEventAdaptor(eventSet, adaptor);
+            }
+
+            //
+            // Locate the EventSet method based upon the eventName element 
value.  Once
+            // found, add a new AptEventHandler to the adaptor for this event.
+            //
+            boolean found = false;
+            String eventName = 
(String)handlerAnnot.getObjectValue("eventName");
+            AptMethodHelper handlerMethod = new AptMethodHelper(clientMethod);
+            for (ControlEvent controlEvent : eventSet.getEvents())
+            {
+                if (controlEvent == null || controlEvent.getName() == null || 
!controlEvent.getName().equals(eventName))
+                    continue;
+                if ( controlEvent.getArgTypes() == null )
+                    continue;
+
+                if 
(controlEvent.getArgTypes().equals(handlerMethod.getArgTypes()))
+                {
+                    adaptor.addHandler(controlEvent, 
+                                       new AptEventHandler(controlEvent, 
clientMethod, _env));
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+            {
+                _env.getMessager().printError(clientMethod.getPosition(),
+                    "No event method with matching name and signature found on 
EventSet: " +
+                    setName);
+            }
+        } 
+    }
+
+    ClassDeclaration _clientDecl;
+    AnnotationProcessorEnvironment _env;
+}

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlField.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlField.java
 (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlField.java
 Fri Oct  1 11:13:41 2004
@@ -32,6 +32,7 @@
 import org.apache.beehive.controls.runtime.generator.ControlField;
 import org.apache.beehive.controls.runtime.generator.ControlImpl;
 import org.apache.beehive.controls.runtime.generator.ControlInterface;
+import org.apache.beehive.controls.runtime.generator.GenClass;
 
 /**
  * The AptControlField class is an implementation of ControlField where values 
are derived
@@ -41,12 +42,12 @@
 {
     /**
      * Base constructor, protected so only a custom subclass can invoke
-     * @param controlImpl the declaring ControlImplementation
+     * @param controlClient the declaring ControlImplementation
      */
-    protected AptControlField(ControlImpl controlImpl, FieldDeclaration 
controlDecl,
+    protected AptControlField(GenClass controlClient, FieldDeclaration 
controlDecl,
                               AnnotationProcessorEnvironment env) 
     {
-        super(controlImpl);
+        super( controlClient );
         _controlDecl = controlDecl;
         _env = env;
         _helper = new AptFieldHelper(_controlDecl);

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlImplementation.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlImplementation.java
        (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/AptControlImplementation.java
        Fri Oct  1 11:13:41 2004
@@ -19,8 +19,6 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
 
 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
 import com.sun.mirror.declaration.AnnotationMirror;
@@ -143,25 +141,6 @@
     }
 
     /**
-     * Initializes the list of ControlFields declared directly by this 
ControlImpl
-     */
-    protected ArrayList<ControlField> initControls()
-    {
-        ArrayList<ControlField> controls = new ArrayList<ControlField>();
-        
-        if ( _implDecl == null || _implDecl.getFields() == null )
-            return controls;
-
-        Collection<FieldDeclaration> declaredFields = _implDecl.getFields();
-        for (FieldDeclaration fieldDecl : declaredFields)
-        {
-            if 
(fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != 
null)
-                controls.add(new AptControlField(this, fieldDecl, _env));
-        }
-        return controls;
-    }
-
-    /**
      * Initializes the list of ContextFields declared directly by this 
ControlImpl
      */
     protected ArrayList<ContextField> initContexts()
@@ -200,6 +179,25 @@
     }
 
     /**
+     * Initializes the list of EventFields that this ControlImpl should ignore 
for event handling purposes.
+     */
+    protected ArrayList<EventField> initIgnoredEventFields()
+    {
+        ArrayList<EventField> fields = new ArrayList<EventField>();
+
+        if ( _implDecl == null || _implDecl.getFields() == null )
+            return fields;
+
+        Collection<FieldDeclaration> declaredFields = _implDecl.getFields();
+        for (FieldDeclaration fieldDecl : declaredFields)
+        {
+            if 
(fieldDecl.getAnnotation(org.apache.beehive.controls.api.bean.Control.class) != 
null)
+                fields.add(new AptControlField(this, fieldDecl, _env));
+        }
+        return fields;
+    }
+
+    /**
      * Initializes the list of EventAdaptors for this ControlImpl
      */
     protected void initEventAdaptors()
@@ -250,8 +248,12 @@
             EventField eventField = (EventField)getField(fieldName);
             if (eventField == null)
             {
-                _env.getMessager().printError(implMethod.getPosition(),
-                    "Cannot find event source field: " + fieldName);
+                // eventField == null means this field isn't interesting for 
the purposes
+                // of this processor (control impls).  However, only emit an 
error message
+                // if the field isn't on the "ignore" list.
+                if ( getIgnoredEventField(fieldName) == null )
+                    _env.getMessager().printError(implMethod.getPosition(),
+                        "Cannot find event source field: " + fieldName);
                 continue;
             }
 
@@ -291,7 +293,7 @@
             AptMethodHelper handlerMethod = new AptMethodHelper(implMethod);
             for (ControlEvent controlEvent : eventSet.getEvents())
             {
-                if (controlEvent == null || controlEvent.getName() == null | 
!controlEvent.getName().equals(eventName))
+                if (controlEvent == null || controlEvent.getName() == null || 
!controlEvent.getName().equals(eventName))
                     continue;
                 if ( controlEvent.getArgTypes() == null )
                     continue;

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/ControlClientAnnotationProcessor.java
==============================================================================
--- 
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 Oct  1 11:13:41 2004
@@ -25,20 +25,18 @@
 import com.sun.mirror.declaration.*;
 import com.sun.mirror.apt.*;
 import com.sun.mirror.type.*;
-import com.sun.mirror.util.*;
+
 import java.util.*;
 
 import org.apache.beehive.controls.runtime.generator.CodeGenerationException;
+import org.apache.beehive.controls.runtime.generator.GenClass;
+import org.apache.beehive.controls.runtime.generator.GeneratorOutput;
+import org.apache.beehive.controls.runtime.generator.CodeGenerator;
 import org.apache.beehive.controls.runtime.bean.ControlBeanContext;
-import org.apache.beehive.controls.api.bean.Control;
-import org.apache.beehive.controls.api.bean.ControlBean;
-import org.apache.beehive.controls.api.bean.ControlInterface;
-import org.apache.beehive.controls.api.bean.ControlExtension;
-import java.util.Iterator;
+import org.apache.beehive.controls.api.bean.*;
+
 import java.util.Set;
-import java.lang.annotation.Annotation;
 import java.io.File;
-import java.io.PrintWriter;
 import java.io.IOException;
 
 public class ControlClientAnnotationProcessor extends 
TwoPhaseAnnotationProcessor
@@ -102,8 +100,9 @@
             }
         }
 
-        // For each client type, emit a controls client manifest in the same 
dir as the
-        // client type's class.
+        // For each client type:
+        //   1 - emit a controls client manifest in the same dir as the client 
type's class.
+        //   2 - emit a controls client initializer class in the same pkg/dir 
as the client type's class
 
         // TODO: support @ClientReferences
 
@@ -111,6 +110,8 @@
         Set<TypeDeclaration> clientTypes = clientsMap.keySet();
         for ( TypeDeclaration clientType : clientTypes )
         {
+            // Emit manifest
+
             String clientPkg = clientType.getPackage().getQualifiedName();
             File clientManifestName =
                 new File( clientType.getSimpleName() + 
ControlClientManifest.FILE_EXTENSION );
@@ -140,6 +141,30 @@
                 printError( clientType, "controls.client.manifest.ioerror" );
                 ie.printStackTrace( );
             }
+
+            // Emit initializer
+
+            AnnotationProcessorEnvironment env = 
getAnnotationProcessorEnvironment();
+            GenClass genClass = new AptControlClient( clientType, env );
+
+            if ( genClass != null )
+            {
+                try
+                {
+                    List<GeneratorOutput> genList = 
genClass.getGeneratorOutput(env.getFiler());
+                    if (genList == null || genList.size() == 0)
+                        return;
+
+                    for (GeneratorOutput genOut : genList)
+                    {
+                        getGenerator().generate(genOut);
+                    }
+                }
+                catch (IOException ioe)
+                {
+                    throw new CodeGenerationException("Code generation 
failure: ", ioe);
+                }
+            }
         }
     }
     
@@ -150,7 +175,6 @@
 
     private void checkControlField( FieldDeclaration f )
     {
-         Types typeUtils = getAnnotationProcessorEnvironment().getTypeUtils();
          TypeMirror fieldType = f.getType();
 
          // Valid control field instances can be of an interface type
@@ -293,28 +317,47 @@
         return ci;
     }
 
-    private final void printError( Declaration d, String id )
-    {
-        getAnnotationProcessorEnvironment().getMessager().printError(
-            d.getPosition(), getResourceString( id ) );
-    }
-
-    private final void printWarning( Declaration d, String id )
+    /**
+     * Returns the CodeGenerator instance supporting this processor, 
instantiating a new
+     * generator instance if necessary.
+     */
+    protected CodeGenerator getGenerator()
     {
-        getAnnotationProcessorEnvironment().getMessager().printWarning(
-            d.getPosition(), getResourceString( id ) );
-    }
+        if (_generator == null)
+        {
+            //
+            // Locate the class that wraps the Velocity code generation process
+            //
+            AnnotationProcessorEnvironment env = 
getAnnotationProcessorEnvironment();
+            String generatorName = null;
+
+            // BUGBUG: getting the name should be as easy as the code below... 
but for some
+            // reason the APT option processing is busted, and doesn't parse 
-A keys correctly.
+            // The entire value of the -Aoption will be the key, and the value 
will be 'null'
+            // generatorName = env.getOptions().get("-AcontrolGenerator");
+            for (String keyName : env.getOptions().keySet())
+            {
+                if (keyName.startsWith("-AcontrolGenerator="))
+                {
+                    generatorName = keyName.substring(19);
+                    break;
+                }
+            }
 
-    private final void printNotice( Declaration d, String id )
-    {
-        getAnnotationProcessorEnvironment().getMessager().printNotice(
-            d.getPosition(), getResourceString( id ) );
+            if (generatorName == null)
+                generatorName  = 
"org.apache.beehive.controls.runtime.generator.VelocityGenerator";
+            try
+            {
+                Class generatorClass = Class.forName(generatorName);
+                _generator = (CodeGenerator)generatorClass.newInstance();
+            }
+            catch (Exception e)
+            {
+                throw new CodeGenerationException("Unable to create code 
generator", e);
+            }
+        }
+        return _generator;
     }
 
-    private final String getResourceString( String id )
-    {
-        ResourceBundle rb = ResourceBundle.getBundle(
-            ControlClientAnnotationProcessor.class.getPackage().getName() + 
".strings" );
-        return rb.getString( id );
-    }        
+    CodeGenerator _generator;
 }

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/TwoPhaseAnnotationProcessor.java
==============================================================================
--- 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/TwoPhaseAnnotationProcessor.java
     (original)
+++ 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/apt/TwoPhaseAnnotationProcessor.java
     Fri Oct  1 11:13:41 2004
@@ -18,17 +18,12 @@
  * $Header:$
  */
 
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.text.MessageFormat;
 
 import com.sun.mirror.apt.AnnotationProcessor;
 import com.sun.mirror.apt.AnnotationProcessorEnvironment;
+import com.sun.mirror.apt.Messager;
 import com.sun.mirror.declaration.AnnotationTypeDeclaration;
 import com.sun.mirror.declaration.Declaration;
 
@@ -78,6 +73,7 @@
     {
         _atds = atds;
         _env = env;
+        _locale = Locale.getDefault();
     }
 
     /**
@@ -149,6 +145,42 @@
         return _env;
     }
 
+    //
+    // Helper functions for localizing diagnostics
+    //
+
+    protected void printError( Declaration d, String id, Object... args )
+    {
+        String message = getResourceString(id, args);
+        getMessager().printError(d.getPosition(), message);
+    }
+
+    protected void printWarning( Declaration d, String id, Object... args )
+    {
+        String message = getResourceString(id, args);
+        getMessager().printWarning(d.getPosition(), message);
+    }
+
+    protected void printNotice( Declaration d, String id, Object... args )
+    {
+        String message = getResourceString(id, args);
+        getMessager().printNotice(d.getPosition(), message );
+    }
+
+    protected String getResourceString( String id, Object... args )
+    {
+        ResourceBundle rb = ResourceBundle.getBundle(
+            this.getClass().getPackage().getName() + ".strings", _locale );
+           String pattern = rb.getString(id);
+           return MessageFormat.format(pattern, args);
+    }
+
+    private final Messager getMessager()
+    {
+        return getAnnotationProcessorEnvironment().getMessager();
+    }
+
     Set<AnnotationTypeDeclaration> _atds;
     AnnotationProcessorEnvironment _env;
+    Locale _locale;
 }

Modified: incubator/beehive/trunk/controls/test/build.xml
==============================================================================
--- incubator/beehive/trunk/controls/test/build.xml     (original)
+++ incubator/beehive/trunk/controls/test/build.xml     Fri Oct  1 11:13:41 2004
@@ -197,9 +197,12 @@
 
     <target name="build-java-tests" depends="build-test-drivers" 
unless="_build.java.tests.ran">
         <!-- Build the test source directory -->
-        <javac srcdir="${tests.src}"
+        <apt srcdir="${tests.src}"
             destdir="${build.tests}"
+            gendir="${build.beansrc}"
             classpathref="test.classpath"
+            compileByExtension="true"
+            srcExtensions="*.java"
             debug="on"
             optimize="on"
             verbose="false"
@@ -210,7 +213,7 @@
                <pathelement location="${httpunit.jar}"/>
                <pathelement path="${build.tests.driver}"/>
             </classpath>
-        </javac>
+        </apt>
         <property name="_build.java.tests.ran" value="true"/>
     </target>
 
@@ -224,7 +227,7 @@
         <!--antcall target="run" /-->
         <echo message="${do.start.tomcat}"/>
         <property name="test.freq" value="checkin"/>
-        <antcall target="run.test" />
+        <antcall target="run.junit.java" />
     </target>
 
     <target name="detailed.tests" >

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/Composer.java
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/Composer.java
      (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/Composer.java
      Fri Oct  1 11:13:41 2004
@@ -25,4 +25,9 @@
     // Returns a propertySet value for an extension nested control
     //
     public Annotation getExtensionControlPropertySet(Class propertySet);
+
+    //
+    // Invokes nested controls
+    //
+    public void invokeNestedControls();
 }

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/ComposerImpl.jcs
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/ComposerImpl.jcs
   (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/ComposerImpl.jcs
   Fri Oct  1 11:13:41 2004
@@ -1,25 +1,27 @@
 package org.apache.beehive.controls.test.controls.composition;
 
 import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
 
 import org.apache.beehive.controls.api.bean.ControlImplementation;
 import org.apache.beehive.controls.api.bean.Control;
-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.EventHandler;
-import org.apache.beehive.controls.api.properties.PropertySet;
 
 import org.apache.beehive.controls.test.controls.property.Props;
 import org.apache.beehive.controls.test.controls.property.PropsExtension;
 
+import org.apache.beehive.controls.test.controls.util.TestContext;
+
+
 @ControlImplementation
 public class ComposerImpl implements Composer
 { 
     static final long serialVersionUID = 1L;
 
-    @Control 
+    @Context
+    TestContext _testContext;
+
+    @Control
     @Props.SimpleProps(simpleString="A field annotation value")
     Props propControl;
 
@@ -53,60 +55,104 @@
         return propExtControl.getControlPropertySet(propertySet);
     }
 
+    public void invokeNestedControls()
+    {
+        nested1.fireEvent( "Return", "returnVoid" );
+        nested1.fireEvent( "Return", "returnInt" );
+        nested1.fireEvent( "Return", "returnString" );
+    }
+
     //
     // Define various event handlers for the nested controls
     //
     @EventHandler(field="nested1", eventSet=Nested.Return.class, 
eventName="returnVoid")
-    public void nested1ReturnVoid() { return; }
+    public void nested1ReturnVoid()
+    {
+        _testContext.addEvent( "nested1ReturnVoid" );
+        return;
+    }
 
     @EventHandler(field="nested1", eventSet=Nested.Return.class, 
eventName="returnString")
-    public String nested1ReturnString() { return "Hello"; }
+    public String nested1ReturnString()
+    {
+        _testContext.addEvent( "nested1ReturnString" );
+        return "Hello";
+    }
 
     @EventHandler(field="nested1", eventSet=Nested.Return.class, 
eventName="returnInt")
-    public int nested1ReturnInt() { return 21; }
+    public int nested1ReturnInt()
+    {
+        _testContext.addEvent( "nested1ReturnInt" );
+        return 21;
+    }
 
     @EventHandler(field="nested2", eventSet=Nested.Args.class, 
eventName="argsInt")
-    public int nested2ArgsInt(int value) { return value; } 
+    public int nested2ArgsInt(int value)
+    {
+        _testContext.addEvent( "nested2ArgsInt" );
+        return value;
+    }
 
     @EventHandler(field="nested2", eventSet=Nested.Args.class, 
eventName="argsString")
-    public String nested2ArgsString(String value) { return value; }
+    public String nested2ArgsString(String value)
+    {
+        _testContext.addEvent( "nested2ArgsString" );
+        return value;
+    }
 
     @EventHandler(field="nested2", eventSet=Nested.Args.class, 
eventName="argsMultiple")
-    public Object [] nested2ArgsMultiple(int val1, String val2) {return new 
Object[] {val1,val2};}
+    public Object [] nested2ArgsMultiple(int val1, String val2)
+    {
+        _testContext.addEvent( "nested2ArgsMultiple" );
+        return new Object[] {val1,val2};
+    }
 
     @EventHandler(field="nested3", eventSet=Nested.Except.class, 
eventName="exceptIO")
     public void nested3ExceptIO() throws java.io.IOException
     {
+        _testContext.addEvent( "nested3ExceptIO" );
         throw new java.io.IOException("Ouch");
     }
 
     @EventHandler(field="nested3", eventSet=Nested.Except.class, 
eventName="exceptRuntime")
     public void nested3ExceptRuntime() throws java.lang.RuntimeException
     {
+        _testContext.addEvent( "nested3ExceptRuntime" );
         throw new RuntimeException("Crash");
     }
 
     @EventHandler(field="nested3", eventSet=Nested.Except.class, 
eventName="exceptLocal")
     public void nested3ExceptLocal() throws Nested.LocalException
     {
+        _testContext.addEvent( "nested3ExceptLocal" );
         throw new Nested.LocalException("Bang");
     }
 
     @EventHandler(field="nested3", eventSet=Nested.Except.class, 
eventName="exceptMultiple")
-    public void exceptMultiple() throws java.io.IOException, RuntimeException
+    public void nested3ExceptMultiple() throws java.io.IOException, 
RuntimeException
     {
+        _testContext.addEvent( "nested3ExceptMultiple" );
         throw new java.io.IOException("Play nice!");
     }
 
     @EventHandler(field="nested4", eventSet=Nested.Return.class, 
eventName="returnInt")
-    public int nested4ReturnInt() { return 99; }
+    public int nested4ReturnInt()
+    {
+        _testContext.addEvent( "nested4ReturnInt" );
+        return 99;
+    }
 
     @EventHandler(field="nested4", eventSet=Nested.Args.class, 
eventName="argsString")
-    public String nested4ArgsString(String value) { return value; }
+    public String nested4ArgsString(String value)
+    {
+        _testContext.addEvent( "nested4ArgsString" );
+        return value;
+    }
 
     @EventHandler(field="nested4", eventSet=Nested.Except.class, 
eventName="exceptLocal")
     public void nested4ExceptLocal() throws Nested.LocalException
     {
+        _testContext.addEvent( "nested4ExceptLocal" );
         throw new Nested.LocalException("Bang");
     }
-} 
+}

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/NestedImpl.jcs
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/NestedImpl.jcs
     (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/NestedImpl.jcs
     Fri Oct  1 11:13:41 2004
@@ -1,18 +1,56 @@
 package org.apache.beehive.controls.test.controls.composition;
 
-import java.lang.reflect.Method;
-
 import org.apache.beehive.controls.api.bean.ControlImplementation;
 import org.apache.beehive.controls.api.events.Client;
+import org.apache.beehive.controls.api.context.Context;
+import org.apache.beehive.controls.test.controls.util.TestContext;
 
 @ControlImplementation( assembler=NestedAssembler.class )
 public class NestedImpl implements Nested
-{ 
+{
+    @Context TestContext testContext;
+
     @Client Return  returnClient;
     @Client Args    argsClient;
     @Client Except  exceptClient;
 
     public void fireEvent(String set, String name)
     {
+        if ( set.equals("Return") )
+        {
+            if ( name.equals( "returnVoid" ) )
+                returnClient.returnVoid();
+            if ( name.equals( "returnInt" ) )
+                returnClient.returnInt();
+            if ( name.equals( "returnString" ) )
+                returnClient.returnString();
+        }
+        else if ( set.equals("Args") )
+        {
+            if ( name.equals( "argsInt" ) )
+                argsClient.argsInt( 1 );
+            if ( name.equals( "argsString" ) )
+                argsClient.argsString( "foo" );
+            if ( name.equals( "argsMultiple" ) )
+                argsClient.argsMultiple( 2, "bar" );
+        }
+        else if ( set.equals( "Except") )
+        {
+            try
+            {
+                if ( name.equals( "exceptIO") );
+                    exceptClient.exceptIO();
+                if ( name.equals( "exceptRuntime") )
+                    exceptClient.exceptRuntime();
+                if ( name.equals( "exceptLocal") )
+                    exceptClient.exceptLocal();
+                if ( name.equals( "exceptMultiple") )
+                    exceptClient.exceptMultiple();
+            }
+            catch ( Exception e )
+            {
+                testContext.addEvent( e.getClass().getName() );
+            }
+        }
     }
 } 

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControl.java
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControl.java
  (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControl.java
  Fri Oct  1 11:13:41 2004
@@ -2,6 +2,7 @@
 
 
 import org.apache.beehive.controls.api.bean.ControlInterface;
+import org.apache.beehive.controls.api.events.EventSet;
 import org.apache.beehive.controls.test.controls.composition.InnerControlBean;
 
 
@@ -11,6 +12,13 @@
 @ControlInterface
 public interface OuterControl
 {
+    @EventSet
+    public interface OuterEvents
+    {
+        int report(String message);
+    }
+
+    public void fireOuterEvents( String message );
 
        public InnerControlBean getDeclaredNestedControl();
        public InnerControlBean getDeclaredNestedControl2();

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
       (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
       Fri Oct  1 11:13:41 2004
@@ -4,6 +4,7 @@
 import org.apache.beehive.controls.api.bean.Control;
 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;
 
 import org.apache.beehive.controls.test.controls.composition.InnerControlBean;
@@ -36,6 +37,9 @@
     private boolean innerControlInnerClassShopping=false;
     private boolean innerControlInnerClassDoStuff=false;  
     
+    @Client
+    OuterEvents outerEvents;
+
     /*Instantiates a nested control without reconfiguring the property*/
     @Control 
     InnerControlBean innerControl;
@@ -71,7 +75,7 @@
 
     @EventHandler(field="innerControl", eventSet=InnerControl.Action.class, 
eventName="doStuff")
     public void innerControldoStuff(String vakue) {
-       innerControlEventHandlerShopping=EVENT_RECEIVED;
+       innerControlEventHandlerDoStuff=EVENT_RECEIVED;
     }
 
     @EventHandler(field="innerControl2", eventSet=InnerControl.Activity.class, 
eventName="wakeup")
@@ -89,6 +93,10 @@
     @EventHandler(field="innerControl2", eventSet=InnerControl.Action.class, 
eventName="doStuff")
     public void innerControl2doStuff(String vakue) {}
 
+    public void fireOuterEvents( String message )
+    {
+        outerEvents.report( message );
+    }
     
     public InnerControlBean getDeclaredNestedControl(){
        return innerControl;

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/context/BaseContextImpl.jcs
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/context/BaseContextImpl.jcs
    (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/context/BaseContextImpl.jcs
    Fri Oct  1 11:13:41 2004
@@ -1,7 +1,5 @@
 package org.apache.beehive.controls.test.controls.context;
 
-import java.lang.reflect.Method;
-
 import org.apache.beehive.controls.api.bean.ControlImplementation;
 import org.apache.beehive.controls.api.context.Context;
 import org.apache.beehive.controls.api.context.ControlBeanContext;

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/TestBeanContext.java
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/TestBeanContext.java
      (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/TestBeanContext.java
      Fri Oct  1 11:13:41 2004
@@ -6,8 +6,11 @@
 import java.util.Iterator;
 import java.util.Vector;
 import java.util.Arrays;
+import java.lang.reflect.AnnotatedElement;
 
 import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
+import org.apache.beehive.controls.runtime.bean.ControlBean;
+import org.apache.beehive.controls.api.properties.PropertyMap;
 
 /**
  * The TestBeanContext is a simple standalone bean context intended to be used 
as a test harness
@@ -74,6 +77,17 @@
         // Register the ControlBeanContext provider on all new context 
instances.
         //
         
addService(org.apache.beehive.controls.test.controls.util.TestContext.class, 
theProvider);
+    }
+
+    /**
+     * Override default getBeanAnnotationMap to not depend on ControlBean
+     * @param bean
+     * @param annotElem
+     * @return
+     */
+    protected PropertyMap getBeanAnnotationMap( ControlBean bean, 
AnnotatedElement annotElem )
+    {
+        return super.getBeanAnnotationMap( bean, annotElem );    //To change 
body of overridden methods use File | Settings | File Templates.
     }
 
     // TestContext.addEvent()

Added: 
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/composition/ComposerBeanDriver.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/composition/ComposerBeanDriver.java
       Fri Oct  1 11:13:41 2004
@@ -0,0 +1,87 @@
+package org.apache.beehive.controls.test.driver.composition;
+
+import java.util.Arrays;
+import org.apache.beehive.test.tools.milton.common.Report;
+import org.apache.beehive.controls.test.controls.util.TestBeanContext;
+import org.apache.beehive.controls.test.controls.composition.Composer;
+
+/* This class contains the logic to test HelloControlBean
+       It will exercise the control in a certain way and generate a
+       test result report
+ */
+
+public class ComposerBeanDriver
+{
+    /**
+     * Returns a new TestBeanContext to act as a container for control testing.
+     */
+    private TestBeanContext createTestBeanContext() throws Exception
+    {
+        return new TestBeanContext();
+    }
+
+       /**
+        * When one event raised to a bean instance
+        */
+       public Report testComposerBean(Composer composerBean){
+
+               Report report=new Report();
+
+               TestBeanContext testContext =null;
+
+               try{
+               testContext = createTestBeanContext();
+            testContext.add(composerBean);
+               }
+               catch(Exception e){
+                       report.setStatus(Report.FAIL);
+                       report.setMessage("TestBeanContext could not be 
created.");
+                       report.setExceptionStack(e);
+
+                       return report;
+               }
+
+        try
+        {
+               testContext.beginContext();
+            testContext.resetEvents();
+            composerBean.invokeNestedControls();
+        }
+        finally
+        {
+            testContext.endContext();
+        }
+        if(checkEvents(testContext.getEvents(),
+                    new String [] { "nested1ReturnVoid", "nested1ReturnInt",
+                                    "nested1ReturnString" }))
+          report.setStatus(Report.PASS);
+        else{
+          report.setStatus(Report.FAIL);
+                 report.setMessage(Arrays.toString(testContext.getEvents()));
+               }
+
+               return report;
+       }
+
+    private boolean checkEvents(String [] expectResults, String [] 
actualResults)
+    {
+        boolean result=true;
+
+        if (expectResults.length != actualResults.length)
+        {
+                       result=false;
+        }
+               else{
+               for (int i = 0; i < expectResults.length; i++)
+               {
+                   if (!expectResults[i].equals(actualResults[i]))
+                   {
+                                       result=false;
+                                       break;
+                   }
+               }
+               }
+               return result;
+
+    }
+}

Added: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/ComposerTest.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/ComposerTest.java
 Fri Oct  1 11:13:41 2004
@@ -0,0 +1,52 @@
+package org.apache.beehive.controls.test.java.composition;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import java.beans.Beans;
+import org.apache.beehive.controls.api.bean.ControlBean;
+import org.apache.beehive.controls.test.controls.context.BaseContextBean;
+import org.apache.beehive.controls.test.controls.composition.ComposerBean;
+import org.apache.beehive.controls.test.driver.composition.ComposerBeanDriver;
+import org.apache.beehive.test.tools.milton.common.Report;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
+
+
+/**
+ * A TestCase that tests controls context services
+ */
[EMAIL PROTECTED]("checkin")
+public class ComposerTest extends TestCase
+{
+    public ComposerTest( String s ) { super( s ); }
+
+    public void setUp() { }
+
+
+    /**
+     * Creates a new ControlBean instance based upon the specified class name
+     */
+    private ControlBean createTestBean(String beanClassName) throws Exception
+    {
+        return 
(ControlBean)Beans.instantiate(Thread.currentThread().getContextClassLoader(),
+                                              beanClassName);
+    }
+
+    /**
+     * Tests basic Context events for Controls
+     */
+    public void testNestedControlEvents() throws Exception
+    {
+               ComposerBean composerBean = (ComposerBean)createTestBean(
+                       
"org.apache.beehive.controls.test.controls.composition.ComposerBean");
+
+               ComposerBeanDriver driver=new ComposerBeanDriver();
+               Report report=driver.testComposerBean(composerBean);
+
+        if (!Report.PASS.equals(report.getStatus()))
+        {
+            System.err.println("Message: " + report.getMessage());
+            System.err.println("Exception: " + report.getExceptionStack());
+            fail("testNestedControlEvents failed");
+        }
+    }
+}

Modified: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
      (original)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
      Fri Oct  1 11:13:41 2004
@@ -6,37 +6,48 @@
 import java.beans.Beans;
 import org.apache.beehive.controls.api.bean.Control;
 import org.apache.beehive.controls.api.bean.ControlBean;
+import org.apache.beehive.controls.api.events.EventHandler;
+import org.apache.beehive.controls.test.controls.composition.OuterControl;
 import org.apache.beehive.controls.test.controls.composition.OuterControlBean;
 import org.apache.beehive.controls.test.controls.composition.InnerControlBean;
+import org.apache.beehive.controls.test.controls.util.TestBeanContext;
 import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
 import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
 
 /**
- * A TeseCase that tests control composition.
+ * 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]("inactive")
[EMAIL PROTECTED]("checkin")
 public class DeclarativeTest extends TestCase
 {
-
+    // initialize declared controls once
     public DeclarativeTest(String name) throws Exception
-    {super(name);}
+    {
+        super(name);
+       _testContext = createTestBeanContext();
+        DeclarativeTestClientInitializer.initialize( _testContext, this );
+    }
 
-    /**
-     * A control that contains a nested control
-     */
-    @Control
-    public OuterControlBean outerControl;
+    // begin and end control bean context for each test
+    public void setUp() throws Exception
+    {
+        _testContext.beginContext();
+    }
+
+    public void tearDown() throws Exception
+    {
+        _testContext.endContext();
+    }
 
     /**
      * Tests outer control instantiats nested control by declaration
      */
-    public void testInstantiate() throws Exception
+    public void testInstantiation() throws Exception
     {
                Assert.assertNotNull(outerControl);
                Assert.assertNotNull(outerControl.getDeclaredNestedControl());
@@ -46,7 +57,7 @@
     /**
      * Tests outer control getting inner control property from control context
      */
-    public void testGetProppertyByContext() throws Exception
+    public void testGetPropertyByContext() throws Exception
     {
                Assert.assertNotNull(outerControl);
                InnerControlBean 
innercontrol=outerControl.getDeclaredNestedControl();
@@ -56,35 +67,6 @@
     }
 
     /**
-     * Tests outer control getting inner control property by getter
-     *
-
-       commented out temporarily, getter/setter causes compile error
-
-    public void testGetProppertyByGetter() throws Exception
-    {
-               Assert.assertNotNull(outerControl);
-               InnerControlBean 
innercontrol=outerControl.getDeclaredNestedControl();
-               Assert.assertNotNull(innercontrol);
-               Assert.assertEquals("Bob",innercontrol.getIdentityname());
-               Assert.assertNull(innercontrol.getIdentityjob());
-    }
-
-    /**
-     * Tests outer control setting inner control property by setter
-     *
-    public void testSetProppertyBySetter() throws Exception
-    {
-               Assert.assertNotNull(outerControl);
-               InnerControlBean 
innercontrol=outerControl.getDeclaredNestedControl();
-               Assert.assertNotNull(innercontrol);
-               innercontrol.setIdentityname("new name declare");
-               innercontrol.setIdentityjob("new job declare");
-               Assert.assertEquals("new name 
declare",innercontrol.getNameFromContext());
-               Assert.assertEquals("new job 
declare",innercontrol.getJobFromContext());
-    }
-       */
-    /**
      * Tests reconfigured property.
      * Outer control reconfigures the inner control's property when 
instantiating it
      */
@@ -112,23 +94,39 @@
     }
 
     /**
-     * Tests outer control receiving events from nested control using
-     * inner class
+     * Tests outer control firing events to us
      */
-    public void testEventInnerClass() throws Exception
+    public void testOuterEvents() throws Exception
     {
-               Assert.assertNotNull(outerControl);
-               
Assert.assertEquals("0",outerControl.testInnerClassListenerByDeclare());
+        System.out.println( "_reportMsg=" + _reportMsg );
+        Assert.assertNotNull(outerControl);
+        outerControl.fireOuterEvents("this is the reported msg");
+        Assert.assertEquals("this is the reported msg", _reportMsg );
+        System.out.println( "_reportMsg=" + _reportMsg );
     }
 
     /**
-     * Tests outer control receiving events from nested control using
-     * event listener
+     * A control that contains a nested control
      */
-    public void testEventListener() throws Exception
+    @Control
+    public OuterControlBean outerControl;
+
+    @EventHandler(field="outerControl", 
eventSet=OuterControl.OuterEvents.class, eventName="report")
+    public int onReport( String msg )
     {
-               Assert.assertNotNull(outerControl);
-               
Assert.assertEquals("0",outerControl.testEventListenerByDeclare());
+        _reportMsg = msg;
+        return 0;
+    }
+
+    private String _reportMsg;
+
+    /**
+     * Returns a new TestBeanContext to act as a container for control testing.
+     */
+    private TestBeanContext createTestBeanContext() throws Exception
+    {
+        return new TestBeanContext();
     }
 
+    private TestBeanContext _testContext;
 }

Modified: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/EventHandlerTest.java
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/EventHandlerTest.java
   (original)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/EventHandlerTest.java
   Fri Oct  1 11:13:41 2004
@@ -32,7 +32,7 @@
 
 
        /** EventHandler that receives EventSet1 from myHelloBean*/
-    @EventHandler (field="myHelloBean", eventSet= HelloBean.EventSet1.class,
+    @EventHandler (field="myHellobean", eventSet= HelloBean.EventSet1.class,
                                    eventName="method1")
      public void myHelloBeanMessageHandler()
      {
@@ -47,8 +47,8 @@
 
 
     /** EventHandler that receives EventSet2 from myHelloBean*/
-    @EventHandler (field="myHelloBean", eventSet= HelloBean.EventSet2.class, 
eventName="set2Method2")
-     public void myHelloBeanMessageHandler2()
+    @EventHandler (field="myHellobean", eventSet= HelloBean.EventSet2.class, 
eventName="set2Method2")
+     public int myHelloBeanMessageHandler2()
      {
         // Invoked when event is received
         /*
@@ -57,6 +57,7 @@
         
System.out.println("***************************************************");
                */
                event2Received=true;
+        return 0;
      }
 
 

Reply via email to