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
+}