You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ky...@apache.org on 2004/11/03 21:21:07 UTC

svn commit: rev 56522 - in incubator/beehive/trunk: controls controls/src/api/org/apache/beehive/controls/api/context controls/src/api/org/apache/beehive/controls/api/events controls/src/runtime/org/apache/beehive/controls/runtime/bean controls/src/runtime/org/apache/beehive/controls/runtime/servlet controls/test/src/controls/org/apache/beehive/controls/test/controls/event controls/test/src/controls/org/apache/beehive/controls/test/controls/util controls/test/src/drivers/org/apache/beehive/controls/test/driver/event controls/test/src/units/org/apache/beehive/controls/test/java/event wsm/src/runtime/org/apache/beehive/wsm/axis

Author: kylem
Date: Wed Nov  3 12:21:06 2004
New Revision: 56522

Added:
   incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlContainerContext.java
   incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlThreadContext.java
   incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventDispatchHelper.java
   incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventDispatcher.java
   incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventRef.java
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/SerializeUtils.java
Modified:
   incubator/beehive/trunk/controls/build.xml
   incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlHandle.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/bean/ControlContainerContext.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletContextService.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletRequestService.java
   incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletResponseService.java
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/Hello.java
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/HelloImpl.jcs
   incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/TestBeanContext.java
   incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/event/DriveListener.java
   incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/ListenerTest.java
   incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/axis/ControlProvider.java
Log:
Initial cut at base infrastructure for supporting async event delivery to controls, including:

- Definition of a serializable EventRef class that represents a control event
- Dispatch path support for event invocation based upon ControlHandle.sendEvent()
- Movement of some of the basic control container integ interfaces into the public API set, as
  a step towards publishing these interfaces for additional containers.
- Extension of the TestBeanContext test container to add a simple ControlHandle impl that
  can be used to fire events.
- A basic checkin test that validates serializability of EventRefs and event dispatch using the 
  test container



Modified: incubator/beehive/trunk/controls/build.xml
==============================================================================
--- incubator/beehive/trunk/controls/build.xml	(original)
+++ incubator/beehive/trunk/controls/build.xml	Wed Nov  3 12:21:06 2004
@@ -136,6 +136,7 @@
     <!-- ==================================================================== -->
     <target name="clean">
         <delete dir="${build.dir}"/>
+        <ant dir="./test" target="clean" inheritAll="false"/>
     </target>
     <!-- ==================================================================== -->
     <!-- clean_all  -->

Added: incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlContainerContext.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlContainerContext.java	Wed Nov  3 12:21:06 2004
@@ -0,0 +1,57 @@
+package org.apache.beehive.controls.api.context;
+
+/*
+ * 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 org.apache.beehive.controls.api.bean.ControlBean;
+import org.apache.beehive.controls.api.context.ControlHandle;
+import org.apache.beehive.controls.api.events.EventDispatcher;
+
+/**
+ * The ControlContainerContext interface defines the basic contract between an external container
+ * of controls and the Controls runtime.
+ */
+public interface ControlContainerContext extends EventDispatcher, ControlBeanContext
+{
+    /**
+     *  Makes the ControlContainerContext instance the current active context.  This is
+     *  called at the beginning of the execution scope for the control container.
+     */
+    public void beginContext();
+
+    /**
+     * Ends the active context associated with the ControlContainerContext.  This is called
+     * at the end of the execution scope for the control container.
+     */
+    public void endContext();
+
+    /** 
+     * Returns the binding from a control interface to a control implementation for the
+     * current container context.
+     */
+    public Class getControlBinding(Class controlClass);
+
+    /**
+     * Returns a ControlHandle to the component containing the control.  This handle can be
+     * used to dispatch events and operations to a control instance.  This method will return
+     * null if the containing component does not support direct dispatch.
+     *
+     * @param targetID the composite ID of the target control bean
+     */
+    public ControlHandle getControlHandle(ControlBean bean);
+}

Modified: incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlHandle.java
==============================================================================
--- incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlHandle.java	(original)
+++ incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlHandle.java	Wed Nov  3 12:21:06 2004
@@ -17,6 +17,7 @@
  * $Header:$
  */
 
+import org.apache.beehive.controls.api.events.EventRef;
 import java.lang.reflect.InvocationTargetException;
 
 /**
@@ -33,14 +34,8 @@
     public String getControlID();
 
     /**
-     * Invokes the named operation on the target control referenced by this handle.
-     */
-    public Object invokeOperation(String operationName, Object [] args) 
-                  throws InvocationTargetException;
-
-    /**
      * Delivers the specified event to the target control referenced by this handle.
      */
-    public Object sendEvent(String eventSet, String eventName, Object [] args) 
-                  throws InvocationTargetException;
+    public Object sendEvent(EventRef event, Object [] args) 
+                  throws IllegalAccessException,IllegalArgumentException,InvocationTargetException;
 }

Added: incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlThreadContext.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/context/ControlThreadContext.java	Wed Nov  3 12:21:06 2004
@@ -0,0 +1,81 @@
+package org.apache.beehive.controls.api.context;
+/*
+ * 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.Stack;
+
+/**
+ * The ControlThreadContext class manages the association between ControlContainerContexts 
+ * and threads of execution.   For a given thread of execution, the beginning and ending of
+ * contexts will always be nested (never interleaved), so each thread will maintain its own 
+ * stack of currently executing contexts.  This can be used to reassociate with the current 
+ * active context.
+ */
+public class ControlThreadContext
+{
+    /**
+     * This thread local maintains a per-thread stack of ControlContainerContext instances.
+     */
+    static private ThreadLocal<Stack<ControlContainerContext>> _threadContexts = 
+                                            new ThreadLocal<Stack<ControlContainerContext>>(); 
+
+    /**
+     * Returns the active ControlContainerContext for the current thread, or null if no
+     * context is currently active.
+     * @returns the current active ControlContainerContext
+     */ 
+    public static ControlContainerContext getContext() 
+    {
+        Stack<ControlContainerContext> contextStack = _threadContexts.get();
+        if (contextStack == null || contextStack.size() == 0)
+            return null;
+
+        return contextStack.peek();
+    }
+
+    /**
+     * Defines the beginning of a new control container execution context.
+     */
+    public static void beginContext(ControlContainerContext context)
+    {
+        Stack<ControlContainerContext> contextStack = _threadContexts.get();
+        if (contextStack == null)
+        {
+            contextStack = new Stack<ControlContainerContext>();
+            _threadContexts.set(contextStack);
+        }
+        contextStack.push(context);
+    }
+
+    /**
+     * Ends the current control container execution context
+     * @throws IllegalStateExeption if there is not current active context or it is not
+     *         the requested context. 
+     */
+    public static void endContext(ControlContainerContext context)
+    {
+        Stack<ControlContainerContext> contextStack = _threadContexts.get();
+        if (contextStack == null || contextStack.size() == 0)
+            throw new IllegalStateException("No context started for current thread");
+
+        if (contextStack.peek() != context)
+            throw new IllegalStateException("Context is not the current active context");
+
+        contextStack.pop();
+    }
+}

Added: incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventDispatchHelper.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventDispatchHelper.java	Wed Nov  3 12:21:06 2004
@@ -0,0 +1,50 @@
+package org.apache.beehive.controls.api.events;
+/*
+ * 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.InvocationTargetException;
+
+import org.apache.beehive.controls.api.context.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlHandle;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
+
+/**
+ * The EventDispatchHelper class is a simple implementation of the EventDispatcher interface
+ * that is suitable for use <b>inside</b> the execution context of a control container.  It 
+ * assumes that you are already running inside the target container instance, and all that is 
+ * required is the correct routing of the event to the correct control.
+ */
+public class EventDispatchHelper implements EventDispatcher
+{
+    public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
+                  throws IllegalAccessException, IllegalArgumentException, 
+                         InvocationTargetException
+    {
+        //
+        // Obtain the current active control container context
+        //
+        ControlContainerContext context = ControlThreadContext.getContext();
+        if (context == null)
+            throw new IllegalStateException("No active control container context");
+
+        //
+        // Dispatch the event using it.
+        //
+        return context.dispatchEvent(target, event, args);
+    }
+}

Added: incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventDispatcher.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventDispatcher.java	Wed Nov  3 12:21:06 2004
@@ -0,0 +1,46 @@
+package org.apache.beehive.controls.api.events;
+/*
+ * 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.InvocationTargetException;
+
+import org.apache.beehive.controls.api.context.ControlHandle;
+
+/**
+ * The EventDispatcher interface defines the method signature that a container supporting
+ * the external dispatch of Control events would implement.
+ */
+public interface EventDispatcher
+{
+    /**
+     * Dispatches a Control event to a target control.
+     * @param target the target control
+     * @param event the event to deliver to the control
+     * @param args the parameters to the control event
+     * @throws IllegalAccessException the underlying event method is not accessible due to
+     *         access control.
+     * @throws IllegalArgumentException the target is not valid, the event is not a valid event
+     *         type for the requested target, or the argument types do not match the event
+     *         signature.
+     * @throws InvocationTargetException wraps any exception thrown by the underlying event
+     *         handler.
+     */ 
+    public Object dispatchEvent(ControlHandle target, EventRef event, Object [] args)
+                  throws IllegalAccessException, IllegalArgumentException, 
+                         InvocationTargetException;
+}

Added: incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventRef.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/src/api/org/apache/beehive/controls/api/events/EventRef.java	Wed Nov  3 12:21:06 2004
@@ -0,0 +1,249 @@
+package org.apache.beehive.controls.api.events;
+/*
+ * 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.Method;
+import java.util.HashMap;
+import java.util.WeakHashMap;
+
+/**
+ * The EventRef class represents a reference to a specific Control event.   EventRefs can
+ * be used to fire external events into a Control, in contexts where the event source may
+ * not share the associated EventSet class instance with the event target, or even have
+ * access to the EventSet class itself.
+ * <p> 
+ * It is roughly equivalent to the java.lang.reflect.Method object that refers to a method 
+ * on an EventSet interface, but has several additional properties:
+ * <ul>
+ * <li>It is serializable, so can be persisted/restored or passed across the wire</li>
+ * <li>It supports materializing the EventRef back to a Method reference in a way that allows
+ * EventRefs to be passed across class loaders</li>
+ * <li>It can be constructed in contexts where a reference to the actual EventSet class might
+ * not be available (using a String event descriptor format to describe events)</li>
+ * </ul> 
+ */
+public class EventRef implements java.io.Serializable
+{
+    //
+    // Static helper map to go from a primitive type to the type descriptor string
+    //
+    static private HashMap<Class,String> _primToType = new HashMap<Class,String>();
+    static
+    {
+        _primToType.put(Integer.TYPE, "I");
+        _primToType.put(Boolean.TYPE, "Z");
+        _primToType.put(Byte.TYPE, "B");
+        _primToType.put(Character.TYPE, "C");
+        _primToType.put(Short.TYPE, "S");
+        _primToType.put(Long.TYPE, "J");
+        _primToType.put(Float.TYPE, "F");
+        _primToType.put(Double.TYPE, "D");
+        _primToType.put(Void.TYPE, "V");
+    }
+
+    /**
+     * Constructs a new EventRef based upon a Method reference.  The input method must be one
+     * that is declared within a Control EventSet interface.
+     * @param eventMethod the Method associated with the event
+     */
+    public EventRef(Method eventMethod)
+    {
+        _method = eventMethod;
+        _descriptor = computeEventDescriptor(eventMethod);
+    }
+
+    /**
+     * Constructs a new EventRef using an event descriptor string.  The format of this string
+     * is: 
+     * <pre> 
+     *      <eventSet>.<eventName><eventDescriptor>
+     * </pre> 
+     * where <i>eventSet</i> refers to the fully qualified name of the EventSet class,
+     * <i>eventName</i> refers to the name of the event Method, and <i>eventDescriptor</i>
+     * describes the event argument and return types using the method descriptor format
+     * defined in the Java Language Specification.
+     * <p>
+     * For example, given the following EventSet interface:
+     * <pre>
+     * @ControlInterface
+     * public interface MyControl
+     * {
+     *     @EventSet
+     *     public interface MyEvents
+     *     {
+     *          public String myEvent(int arg0, Object arg2);
+     *     }
+     * }
+     * </pre> 
+     * the eventDescriptor for myEvent would be:
+     * <pre> 
+     *     MyControl.MyEvents.myEvent(ILjava/lang/Object;)Ljava/lang/String;
+     * </pre> 
+     * @param eventDescriptor the event descriptor string associated with the event 
+     */ 
+    public EventRef(String eventDescriptor)
+    {
+        _descriptor = eventDescriptor;
+    }
+
+    /**
+     * Returns the event descriptor string associated with the EventRef. 
+     * @param controlInterface the ControlInterface 
+     */
+    public String getEventDescriptor(Class controlInterface)
+    {
+        //
+        // NOTE: The input controlInterface is currently unused, but included to
+        // enable downstream optimization of serialization representation.  See the
+        // OPTIMIZE comment below for more details.  If implemented, the interface
+        // is needed to reverse the transformation from a hash back to a method or
+        // descriptor.
+        //
+        if (_descriptor == null)
+            _descriptor = computeEventDescriptor(_method);
+
+        return _descriptor;
+    }
+
+    /**
+     * Helper method that computes the event descriptor sting for a method
+     */
+    private String computeEventDescriptor(Method method)
+    {
+        StringBuilder sb = new StringBuilder();
+
+        // Add event class and method name
+        sb.append(method.getDeclaringClass().getName());
+        sb.append(".");
+        sb.append(method.getName());
+
+        // Add event arguments
+        Class [] parms = method.getParameterTypes();
+        sb.append("(");
+        for (int i = 0; i < parms.length; i++)
+            appendTypeDescriptor(sb, parms[i]);
+        sb.append(")");
+
+        // Add event return type
+        appendTypeDescriptor(sb, method.getReturnType());
+
+        return sb.toString();
+    }
+
+    /**
+     * Helper method that appends a type descriptor to a StringBuilder.  Used
+     * while accumulating an event descriptor string.
+     */ 
+    private void appendTypeDescriptor(StringBuilder sb, Class clazz)
+    {
+        if (clazz.isPrimitive())
+            sb.append(_primToType.get(clazz));
+        else if (clazz.isArray())
+            sb.append(clazz.getName().replace('.','/'));
+        else
+        {
+            sb.append("L");
+            sb.append(clazz.getName().replace('.','/'));
+            sb.append(";");
+        }
+    }
+    
+    /**
+     *  Returns the event Method associated with this EventRef.
+     */
+    public Method getEventMethod(Class controlInterface)
+    {
+        //
+        // If we already hold a method reference and its loader matches up with the input
+        // interface, then just return it.
+        //
+        if (_method != null &&
+            _method.getDeclaringClass().getClassLoader().equals(controlInterface.getClassLoader()))
+            return _method;
+
+        //
+        // Otherwise, obtain the mapping from descriptors to methods, and use it to
+        // convert back to a method.
+        //
+        String eventDescriptor = getEventDescriptor(controlInterface); 
+        HashMap<String,Method> descriptorMap = getDescriptorMap(controlInterface);
+        if (!descriptorMap.containsKey(eventDescriptor))
+        {
+            throw new IllegalArgumentException("Control interface " + controlInterface + 
+                                               " does not contain an event method that " +
+                                               " corresponds to " + eventDescriptor);
+        }
+        return descriptorMap.get(eventDescriptor);
+    }
+
+    /**
+     * A WeakHashMap used to cache the event descriptor-to-Method mapping for control
+     * interfaces.
+     */
+    static private WeakHashMap<Class, HashMap<String,Method>> _descriptorMaps = 
+                                    new WeakHashMap<Class, HashMap<String,Method>>();
+
+    private HashMap<String,Method> getDescriptorMap(Class controlInterface)
+    {
+        //
+        // If the local cache has the mapping, then return it.
+        //
+        HashMap<String,Method> descMap = _descriptorMaps.get(controlInterface);
+        if (descMap == null)
+        {
+            //
+            // Compute the mapping from event descriptors to event methods, using reflection
+            //
+            descMap = new HashMap<String, Method>();
+            Class [] innerClasses = controlInterface.getClasses();
+            for (int i = 0; i < innerClasses.length; i++)
+            {
+                if (!innerClasses[i].isInterface() || 
+                    !innerClasses[i].isAnnotationPresent(EventSet.class))
+                    continue;
+
+                Method [] eventMethods = innerClasses[i].getMethods();
+                for (int j = 0; j < eventMethods.length; j++)
+                    descMap.put(computeEventDescriptor(eventMethods[j]), eventMethods[j]);
+            }
+            _descriptorMaps.put(controlInterface, descMap);
+        }
+        return descMap;
+    }
+
+
+    /**
+     * Two EventRefs are equal if the method descriptor string associated with them is equal
+     */
+    public boolean equals(Object obj)
+    {
+        if (obj == null || !(obj instanceof EventRef))
+            return false;
+
+        return _descriptor.equals(((EventRef)obj)._descriptor);
+    }
+
+    //
+    // OPTIMIZE: A more efficient internal representation for serialization/wire purposes
+    // would be to compute a hash of the descriptor string (ala RMI opnums), that could be
+    // reconstituted on the other end, given a candidate ControlInterface.  The public APIs
+    // are structured to support this downstream optimization.
+    //
+    private String  _descriptor;
+    transient private Method _method;
+}

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	Wed Nov  3 12:21:06 2004
@@ -28,11 +28,14 @@
 import java.io.ObjectOutputStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Field;
 import java.util.*;
 
 import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
+import org.apache.beehive.controls.api.events.EventRef;
 import org.apache.beehive.controls.api.events.EventSet;
 import org.apache.beehive.controls.api.properties.AnnotatedElementMap;
 import org.apache.beehive.controls.api.properties.BeanPropertyMap;
@@ -125,7 +128,7 @@
         // active container context and implicitly associated the control with it.
         //
         if (context == null)
-            context = ControlContainerContext.getContext();
+            context = ControlThreadContext.getContext();
 
         //
         // Associate the constructed bean w/ a context (if any)
@@ -566,6 +569,34 @@
         // TODO: Property change notification and veto handling go here
         //
         _properties.setProperty(key, o);
+    }
+
+    /**
+     * Dispatches the requested operation event on the ControlBean.
+     * @see org.apache.beehive.controls.runtime.bean.ControlContainerContext#dispatchEvent
+     */
+    /* package */ Object dispatchEvent(EventRef event, Object [] args) 
+                         throws IllegalAccessException,IllegalArgumentException,
+                                InvocationTargetException
+    {
+        //
+        // Translate the EventRef back to an actual event method on the ControlInterface
+        //
+        Class controlInterface = getControlInterface();
+        Method method = event.getEventMethod(controlInterface);
+        
+        //
+        // Find the event notifier instance for the EventSet interface associated with the
+        // method.
+        //
+        EventNotifier eventNotifier = getEventNotifier(method.getDeclaringClass());
+        if (eventNotifier == null)
+            throw new IllegalArgumentException("No event notifier found for " + event);
+
+        //
+        // Dispatch the event
+        //
+        return method.invoke(eventNotifier, args);
     }
 
     //

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	Wed Nov  3 12:21:06 2004
@@ -320,6 +320,7 @@
      */
     public ControlBean getBean(String id)
     {
+        // If no control id separator found, the bean is a direct child of this context
         int delim = id.indexOf(ControlBean.IDSeparator);
         if (delim < 0)  // child is a direct descendent
             return (ControlBean)_childMap.get(id);
@@ -439,7 +440,7 @@
      * Returns the control implementation class that is bound to (implements) the
      * public or extension interface in the current context.
      */
-    protected Class getControlBinding(Class controlClass)
+    public Class getControlBinding(Class controlClass)
     {
         //
         // Delegate up until a ControlContainerContext is found to manage the binding.

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java	Wed Nov  3 12:21:06 2004
@@ -22,7 +22,10 @@
 import java.util.Stack;
 
 import org.apache.beehive.controls.api.context.ControlHandle;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
 import org.apache.beehive.controls.api.context.ResourceContext;
+import org.apache.beehive.controls.api.events.EventDispatcher;
+import org.apache.beehive.controls.api.events.EventRef;
 
 /**
  * The ControlContainerContext class provides a base class implementation for external containers
@@ -32,7 +35,9 @@
  * - defines a simplified contract for the external container to interact with resource
  *   management (beginContext/endContext)
  */
-public class ControlContainerContext extends ControlBeanContext
+public class ControlContainerContext 
+       extends ControlBeanContext
+       implements EventDispatcher, org.apache.beehive.controls.api.context.ControlContainerContext
 {
     public ControlContainerContext()
     {
@@ -40,37 +45,11 @@
     }
 
     /**
-     * Manages the association of ControlContainerContext with current threads of execution.
-     * Each thread will maintain its own Stack of currently executing contexts.  This can be
-     * used to reassociated with the currently active context.
-     */
-    static ThreadLocal _threadStacks = new ThreadLocal(); 
-
-    /**
-     * Returns the active ControlContainerContext for the current thread, or null if no
-     * context is currently active.
-     */ 
-    public static ControlContainerContext getContext() 
-    {
-        Stack contextStack = (Stack)_threadStacks.get();
-        if (contextStack == null || contextStack.size() == 0)
-            return null;
-
-        return (ControlContainerContext)contextStack.peek();
-    }
-
-    /**
      * Defines the beginning of a new control container execution context.
      */
     public void beginContext()
     {
-        Stack contextStack = (Stack)_threadStacks.get();
-        if (contextStack == null)
-        {
-            contextStack = new Stack();
-            _threadStacks.set(contextStack);
-        }
-        contextStack.push(this);
+        ControlThreadContext.beginContext(this);
     }
 
     /**
@@ -78,13 +57,6 @@
      */
     public void endContext()
     {
-        Stack contextStack = (Stack)_threadStacks.get();
-        if (contextStack == null)
-            throw new IllegalStateException("No context started for current thread");
-
-        if (contextStack.peek() != this)
-            throw new IllegalStateException("Context is not the current active context");
-
         try
         {
             //
@@ -94,7 +66,7 @@
         }
         finally
         {
-            contextStack.pop();
+            ControlThreadContext.endContext(this);
         }
     }
 
@@ -165,39 +137,18 @@
 
     /**
      * Dispatch an operation or an event to a bean within this container bean context.
-     * @param targetID the composite ID of the target control bean
+     * @param handle the control handle identifying the target bean
      * @param method the method to be invoked on the target bean
      * @param args the arguments to be passed to the target method invocation
      */
-    public Object dispatch(String targetID, Method method, Object [] args) 
+    public Object dispatchEvent(ControlHandle handle, EventRef event, Object [] args) 
             throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
     {
-        ControlBean bean = getBean(targetID);
+        ControlBean bean = getBean(handle.getControlID());
         if (bean == null)
-            throw new IllegalArgumentException("Invalid bean ID: " + targetID);
+            throw new IllegalArgumentException("Invalid bean ID: " + handle.getControlID());
 
-        //
-        // The method can be either an operation or event, so use reflection to determine
-        // how to deliver it.
-        //
-        Class methodClass = method.getDeclaringClass();
-        Class controlInterface = bean.getControlInterface();
-        if (methodClass.isAssignableFrom(controlInterface))     // an operation
-        {
-            //
-            // Operations are delivered directly to the target bean
-            //
-            return method.invoke(bean, args);
-        }
-        else    // an event
-        {
-            //
-            // If the method isn't implemented by the bean, then the only other
-            // possibility is that it is a callback on the bean.  Get the event
-            // notifier instance for the bean and invoke the callback on it.
-            //
-            return method.invoke(bean.getEventNotifier(method.getDeclaringClass()), args);
-        }
+        return bean.dispatchEvent(event, args);
     }
 
     /**
@@ -207,7 +158,7 @@
      *
      * @param targetID the composite ID of the target control bean
      */
-    protected ControlHandle getControlHandle(ControlBean bean)
+    public ControlHandle getControlHandle(org.apache.beehive.controls.api.bean.ControlBean bean)
     {
         //
         // The base implementation doesn't support dispatch.  Containers should override
@@ -220,7 +171,7 @@
      * Returns the binding from a control interface to a control implementation for the
      * current container context.
      */
-    protected Class getControlBinding(Class controlClass)
+    public Class getControlBinding(Class controlClass)
     {
         //
         // TODO: Add caching of relationships and external binding mechanisms
@@ -231,4 +182,3 @@
     boolean _releasingAll;
     Stack<ResourceContext> _resourceContexts = new Stack<ResourceContext>();
 }
-

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletContextService.java
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletContextService.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletContextService.java	Wed Nov  3 12:21:06 2004
@@ -19,7 +19,8 @@
 
 import javax.servlet.ServletContext;
 
-import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
 
 /**
  * This class is the contextual service implementation for javax.servlet.ServletContext.   It
@@ -45,7 +46,7 @@
     {
         if (_beanContext == null)
         {
-            ControlContainerContext ccc = ControlContainerContext.getContext();
+            ControlContainerContext ccc = ControlThreadContext.getContext();
             if (! (ccc instanceof ServletBeanContext))
                 throw new IllegalStateException("No ServletBeanContext available");
 

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletRequestService.java
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletRequestService.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletRequestService.java	Wed Nov  3 12:21:06 2004
@@ -20,7 +20,8 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletRequestWrapper;
 
-import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
 
 /**
  * This class is the contextual service implementation for javax.servlet.ServletRequest.   It
@@ -72,7 +73,7 @@
     {
         if (_beanContext == null)
         {
-            ControlContainerContext ccc = ControlContainerContext.getContext();
+            ControlContainerContext ccc = ControlThreadContext.getContext();
             if (! (ccc instanceof ServletBeanContext))
                 throw new IllegalStateException("No ServletBeanContext available");
 

Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletResponseService.java
==============================================================================
--- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletResponseService.java	(original)
+++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletResponseService.java	Wed Nov  3 12:21:06 2004
@@ -20,7 +20,8 @@
 import javax.servlet.ServletResponse;
 import javax.servlet.ServletResponseWrapper;
 
-import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
 
 /**
  * This class is the contextual service implementation for javax.servlet.ServletResponse.   It
@@ -72,7 +73,7 @@
     {
         if (_beanContext == null)
         {
-            ControlContainerContext ccc = ControlContainerContext.getContext();
+            ControlContainerContext ccc = ControlThreadContext.getContext();
             if (! (ccc instanceof ServletBeanContext))
                 throw new IllegalStateException("No ServletBeanContext available");
 

Modified: incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/Hello.java
==============================================================================
--- incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/Hello.java	(original)
+++ incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/Hello.java	Wed Nov  3 12:21:06 2004
@@ -31,4 +31,5 @@
     }
 
     public void triggerEvents();
+    public void triggerEventsUsingHandle();
 }

Modified: incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/HelloImpl.jcs
==============================================================================
--- incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/HelloImpl.jcs	(original)
+++ incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/event/HelloImpl.jcs	Wed Nov  3 12:21:06 2004
@@ -1,7 +1,14 @@
 package org.apache.beehive.controls.test.controls.event;
 
+import org.apache.beehive.controls.api.ControlException;
 import org.apache.beehive.controls.api.bean.ControlImplementation;
+import org.apache.beehive.controls.api.context.Context;
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.api.context.ControlHandle;
 import org.apache.beehive.controls.api.events.Client;
+import org.apache.beehive.controls.api.events.EventRef;
+
+import org.apache.beehive.controls.test.controls.util.SerializeUtils;
 
 /**
  * A control implementation that raises events when the method is invoked
@@ -13,6 +20,8 @@
     @Client Hello.EventSet1 eventSet1;
     @Client Hello.EventSet2 eventSet2;
 
+    @Context ControlBeanContext beanContext;
+
     public void triggerEvents() 
     {
         eventSet1.method1();
@@ -20,5 +29,44 @@
         eventSet2.set2Method2();
         eventSet2.set2OverloadedMethod();
         eventSet2.set2OverloadedMethod(68);
+    }
+
+    public void triggerEventsUsingHandle()
+    {
+        ControlHandle handle = beanContext.getControlHandle();
+        if (handle == null)
+            throw new ControlException("No control handle for context:" + beanContext);
+
+        Object [] emptyArgs = new Object [] {};
+
+        try
+        {
+            // Create an event ref using the method descriptor string format
+            EventRef eventRef = new EventRef(Hello.EventSet1.class.getName() + ".method1()V");
+            handle.sendEvent(eventRef, emptyArgs);
+
+            // Create an event ref using Method reflection
+            eventRef = new EventRef(Hello.EventSet2.class.getMethod("method1", new Class [] {}));
+            handle.sendEvent(eventRef, emptyArgs);
+
+            // Create an event ref using string descriptor, the serialize/deserialize before use
+            eventRef = new EventRef(Hello.EventSet2.class.getName() + ".set2Method2()I");
+            eventRef = SerializeUtils.testSerialize(eventRef); 
+            handle.sendEvent(eventRef, emptyArgs);
+
+            // Create an event ref using Method reflection, then serialize/deserialize before use
+            eventRef = new EventRef(Hello.EventSet2.class.getMethod("set2OverloadedMethod",
+                                                                    new Class []{}));
+            eventRef = SerializeUtils.testSerialize(eventRef); 
+            handle.sendEvent(eventRef, emptyArgs);
+    
+            // Create an event ref using string descriptor, where arg matching is required
+            eventRef = new EventRef(Hello.EventSet2.class.getName() + ".set2OverloadedMethod(I)Z");
+            handle.sendEvent(eventRef, new Object [] {68} );
+        }
+        catch (Exception e)
+        {
+            throw new ControlException("Event dispatch error", e);
+        }
     }
 }

Added: incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/SerializeUtils.java
==============================================================================
--- (empty file)
+++ incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/util/SerializeUtils.java	Wed Nov  3 12:21:06 2004
@@ -0,0 +1,51 @@
+package org.apache.beehive.controls.test.controls.util;
+
+import java.io.*;
+
+/**
+ * Utility code for testing serialization behavior
+ */
+public class SerializeUtils
+{
+    /**
+     * Serializes an object into a byte array, then deserializes it from the array and returns
+     * the deserialized object.
+     */ 
+    public static <T extends Object> T testSerialize(T obj)
+    {
+        byte [] serializedObject;
+        T returnObject;
+        try
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.flush();
+            serializedObject = baos.toByteArray();
+            oos.close();
+            baos.close();
+        } 
+        catch (Exception e)
+        {
+            throw new RuntimeException("Error serializing object", e);
+        }
+
+        try
+        {
+            ByteArrayInputStream bais = new ByteArrayInputStream(serializedObject);
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            returnObject = (T)ois.readObject();
+            ois.close();
+            bais.close();
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("Error deserializing object", e);
+        }
+
+        if (!obj.equals(returnObject))
+            throw new RuntimeException("Deserialized object is not equivalent to original!");
+
+        return returnObject;
+    }
+}

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	Wed Nov  3 12:21:06 2004
@@ -7,10 +7,13 @@
 import java.util.Vector;
 import java.util.Arrays;
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.InvocationTargetException;
 
-import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
-import org.apache.beehive.controls.runtime.bean.ControlBean;
+import org.apache.beehive.controls.api.events.EventRef;
+import org.apache.beehive.controls.api.context.ControlHandle;
 import org.apache.beehive.controls.api.properties.PropertyMap;
+import org.apache.beehive.controls.runtime.bean.ControlBean;
+import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
 
 /**
  * The TestBeanContext is a simple standalone bean context intended to be used as a test harness
@@ -88,6 +91,51 @@
     protected PropertyMap getBeanAnnotationMap( ControlBean bean, AnnotatedElement annotElem )
     {
         return super.getBeanAnnotationMap( bean, annotElem );    //To change body of overridden methods use File | Settings | File Templates.
+    }
+
+    /**
+     * A basic ControlHandle implementation for routing test events back.  <b>Note: this impl
+     * currently is not Serializable, but useful for test purposes where all context/beans
+     * remain memory-resident.
+     *
+     * TODO: Provide a Serializable implementation of TestControlHandle.
+     */ 
+    private static class TestControlHandle implements ControlHandle
+    {
+        TestControlHandle(TestBeanContext context, 
+                          org.apache.beehive.controls.api.bean.ControlBean bean)
+        {
+            _testContext = context;
+            _bean = bean;
+        }
+
+        public String getControlID() { return _bean.getControlID(); }
+
+        public Object sendEvent(EventRef event, Object [] args) 
+               throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
+        {
+            try
+            { 
+                //
+                // Push the test context, to simulate re-entering the container
+                //
+                _testContext.beginContext(); 
+
+                return _testContext.dispatchEvent(this, event, args);
+            }
+            finally
+            {
+                _testContext.endContext();
+            }
+        }
+
+        TestBeanContext _testContext;
+        org.apache.beehive.controls.api.bean.ControlBean _bean;
+    }
+
+    public ControlHandle getControlHandle(org.apache.beehive.controls.api.bean.ControlBean bean)
+    {
+        return new TestControlHandle(this, bean);
     }
 
     // TestContext.addEvent()

Modified: incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/event/DriveListener.java
==============================================================================
--- incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/event/DriveListener.java	(original)
+++ incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/event/DriveListener.java	Wed Nov  3 12:21:06 2004
@@ -23,6 +23,10 @@
 
 
 	public Report doTest(){
+        return doTest(false);
+    }
+
+	public Report doTest(boolean useHandle){
 
 		Report report=new Report();
 
@@ -47,11 +51,16 @@
 	   			myControl.addEventSet2Listener(event2listener);
 
 				/* Invokes methods on myHelloBean to trigger the events*/
-		    	myControl.triggerEvents();
+                if (!useHandle)
+		    	    myControl.triggerEvents();
+                else
+		    	    myControl.triggerEventsUsingHandle();
 
 				report.setStatus(Report.PASS);
 			}
 			catch(Exception e){
+System.err.println("Exception triggering");
+e.printStackTrace();
 				report.setStatus(Report.FAIL);
 				report.setExceptionStack(e);
 			}
@@ -65,11 +74,13 @@
 		Report report=new Report();
 		String failuredetail="";
 		if (!innerClassReceiveEvent){
+System.err.println("No inner event");
 			report.setStatus(Report.FAIL);
 			failuredetail="Innner Class didn't receive event.";
 		}
 
 		if (event2listener==null){
+System.err.println("No listener");
 			report.setStatus(Report.FAIL);
 			failuredetail=failuredetail+"Event2Listerner is NULL";
 		}
@@ -79,6 +90,7 @@
 			if (listenerResult.equals("0000"))
 				report.setStatus(Report.PASS);
 			else{
+System.err.println("Bad result: listenerResult");
 				report.setStatus(Report.FAIL);
 				failuredetail=failuredetail+"Listener Result:"+listenerResult;
 			}

Modified: incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/ListenerTest.java
==============================================================================
--- incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/ListenerTest.java	(original)
+++ incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/event/ListenerTest.java	Wed Nov  3 12:21:06 2004
@@ -6,6 +6,7 @@
 import org.apache.beehive.controls.api.bean.ControlBean;
 import org.apache.beehive.controls.test.controls.event.Hello;
 import org.apache.beehive.controls.test.controls.event.HelloBean;
+import org.apache.beehive.controls.test.controls.util.TestBeanContext;
 import org.apache.beehive.controls.test.driver.event.DriveListener;
 import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
 import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
@@ -39,31 +40,30 @@
      */
     public void testListenerReceiveEventsProgram() throws Exception
     {
-
 		Report report=new Report();
 		HelloBean hellobean=(HelloBean)java.beans.Beans.instantiate(
 			Thread.currentThread().getContextClassLoader() ,
 			"org.apache.beehive.controls.test.controls.event.HelloBean");
+        testListenerReceiveEvents(hellobean, false);
+    }
 
-		DriveListener driver=new DriveListener();
-		driver.setControl(hellobean);
-		report=driver.doTest();
-		String result=report.getStatus();
-		if (!result.equals(Report.PASS))
-			fail(report.getMessage());
-
-		try{
-			Thread.currentThread().sleep(1000);
-			report=driver.verifyResult();
-			result=report.getStatus();
-			if (!result.equals(Report.PASS))
-				fail(report.getMessage());
-
-		}
-		catch(Exception e){
-			fail("Exception caught:"+e.toString());
-		}
-
+    public void testListenerReceiveEventsProgramUsingHandle() throws Exception
+    {
+        TestBeanContext beanContext = new TestBeanContext();
+        beanContext.beginContext();
+        try
+        {
+		    Report report=new Report();
+		    HelloBean hellobean=(HelloBean)java.beans.Beans.instantiate(
+		    	Thread.currentThread().getContextClassLoader() ,
+			    "org.apache.beehive.controls.test.controls.event.HelloBean");
+            beanContext.add(hellobean);
+            testListenerReceiveEvents(hellobean, true);
+        }
+        finally
+        {
+            beanContext.endContext();
+        }
     }
 
     /**
@@ -75,10 +75,27 @@
 	@Status("inactive")
     public void testListenerReceiveEventsDeclare() throws Exception
     {
+        testListenerReceiveEvents(myHellobean, false);
+    }
+
+	@Freq("checkin")
+	@Status("inactive")
+    public void testListenerReceiveEventsDeclareUsingHandle() throws Exception
+    {
+        testListenerReceiveEvents(myHellobean, true);
+    }
+
+    /**
+     * Main body of test logic used by the various programmatic and declarative tests
+     */
+	@Freq("checkin")
+	@Status("inactive")
+    private void testListenerReceiveEvents(HelloBean hellobean, boolean useHandle)
+    {
 		Report report=new Report();
 		DriveListener driver=new DriveListener();
-		driver.setControl(myHellobean);
-		report=driver.doTest();
+		driver.setControl(hellobean);
+		report=driver.doTest(useHandle);
 		String result=report.getStatus();
 		if (!result.equals(Report.PASS))
 			fail(report.getMessage());
@@ -94,5 +111,4 @@
 			fail("Exception caught:"+e.toString());
 		}
     }
-
 }

Modified: incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/axis/ControlProvider.java
==============================================================================
--- incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/axis/ControlProvider.java	(original)
+++ incubator/beehive/trunk/wsm/src/runtime/org/apache/beehive/wsm/axis/ControlProvider.java	Wed Nov  3 12:21:06 2004
@@ -28,7 +28,8 @@
 import org.apache.axis.providers.java.RPCProvider;
 import org.apache.beehive.controls.api.bean.Control;
 import org.apache.beehive.controls.api.context.ControlBeanContext;
-import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlContainerContext;
+import org.apache.beehive.controls.api.context.ControlThreadContext;
 
 /**
  * ****************************************************************************
@@ -52,7 +53,7 @@
             if (null != field.getAnnotation(Control.class)) {
                 //attempt to load using client initializer.
                 ControlContainerContext ccc =
-                        ControlContainerContext.getContext();
+                        ControlThreadContext.getContext();
                 if (null == ccc) {
                     throw new Exception("no control container context found");
                 }
@@ -65,4 +66,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}