You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ek...@apache.org on 2006/05/10 18:28:46 UTC

svn commit: r405791 - in /beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime: bean/ControlBean.java bean/ControlBeanContext.java bean/ControlContainerContext.java bean/WebContextFactoryProvider.java servlet/ServletBeanContext.java

Author: ekoneil
Date: Wed May 10 09:28:38 2006
New Revision: 405791

URL: http://svn.apache.org/viewcvs?rev=405791&view=rev
Log:
This is the initial checkin of the work to allow a ControlBeanContext to provide a factory for creating its own BeanContextServices implementations.  This is necessary so that ControlBeanContext objects can avoid locking on the BC.gHL in the JDK and are thus faster.  The implication is that some ControlBean(Context) classes will use CBC objects that don't provide a level of synchronization that is appropriate in all situations.  Application developers that add ControlBeans in unsynchronized contexts should be careful to avoid grafting them into Control hierarchies that require synchronization.

Yes, this is a little tricky.  :)

This is a good first cut, but this functionality will clearly need to evolve over time.

BB: self
Test: Controls / NetUI / system controls pass


Added:
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/WebContextFactoryProvider.java
Modified:
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java
    beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletBeanContext.java

Modified: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java?rev=405791&r1=405790&r2=405791&view=diff
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java (original)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java Wed May 10 09:28:38 2006
@@ -91,18 +91,6 @@
         _localID = id;
         _controlIntf = controlIntf;
 
-        // Create the context that acts as the BeanContextProxy for this bean (the context that this bean _defines_).
-        try
-        {
-            DiscoverClass discoverer = new DiscoverClass();
-            Class factoryClass = discoverer.find(ControlBeanContextFactory.class, DefaultControlBeanContextFactory.class.getName());
-            ControlBeanContextFactory factory = (ControlBeanContextFactory)factoryClass.newInstance();
-            _cbc = factory.instantiate(this);
-        }
-        catch (Exception e) {
-            throw new ControlException("Exception creating ControlBeanContext", e);
-        }
-
         //
         // If no containing context was specified during construction, see if there is a current
         // active container context and implicitly associated the control with it.
@@ -110,6 +98,9 @@
         if (context == null)
             context = ControlThreadContext.getContext();
 
+        ControlBeanContextFactory cbcFactory = lookupControlBeanContextFactory(context);
+        _cbc = cbcFactory.instantiate(this);
+
         //
         // Associate this bean with the context.  Beans may run without a context!
         // Note that the add() call has the side-effect of calling ControlBean.setBeanContext(), which does
@@ -927,6 +918,42 @@
     {
         if (impl != _control)
             throw new ControlException("Cannot change implementation");
+    }
+
+    /**
+     * Internal method used to lookup a ControlBeanContextFactory.  This factory is used to create the
+     * ControlBeanContext object for this ControlBean.  The factory is discoverable from either the containing
+     * ControlBeanContext object or from the environment.  If the containing CBC object exposes a
+     * contextual service of type {@link ControlBeanContextFactory}, the factory returned from this will
+     * be used to create a ControlBeanContext object.
+     *
+     * @param context
+     * @return the ControlBeanContextFactory discovered in the environment or a default one if no factory is configured
+     */
+    private ControlBeanContextFactory lookupControlBeanContextFactory
+        (org.apache.beehive.controls.api.context.ControlBeanContext context) {
+
+        // first, try to find the CBCFactory from the container
+        if(context != null) {
+            ControlBeanContextFactory cbcFactory = context.getService(ControlBeanContextFactory.class, null);
+
+            if(cbcFactory != null) {
+                return cbcFactory;
+            }
+        }
+
+        // Create the context that acts as the BeanContextProxy for this bean (the context that this bean _defines_).
+        try
+        {
+            DiscoverClass discoverer = new DiscoverClass();
+            Class factoryClass =
+                discoverer.find(ControlBeanContextFactory.class, DefaultControlBeanContextFactory.class.getName());
+
+            return (ControlBeanContextFactory)factoryClass.newInstance();
+        }
+        catch (Exception e) {
+            throw new ControlException("Exception creating ControlBeanContext", e);
+        }
     }
 
     /**

Modified: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java?rev=405791&r1=405790&r2=405791&view=diff
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java (original)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java Wed May 10 09:28:38 2006
@@ -74,22 +74,39 @@
     java.io.Serializable
 {
     /**
-     * Creates a new ControlBeanContext instance associated with a specific
-     * control bean.
+     * Creates a new ControlBeanContext instance associated with a specific control bean.  If the
+     * <code>ControlBean</code> is null, this ControlBeanContext object represents a top-level Control
+     * container.  This constructor uses the default implementation of the
+     * {@link java.beans.beancontext.BeanContextServices} interface from the JDK.
      *
-     * @param bean The control bean that contains/scopes the ControlBeanContext.  If null,
-                   it means the ControlBeanContext is for a top-level container.
+     * @param bean The control bean that contains/scopes the ControlBeanContext.  If null, it means the
+     *        ControlBeanContext is for a top-level container.
      */
     protected ControlBeanContext(ControlBean bean)
     {
+        this(bean, DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY);
+    }
+
+    /**
+     * Creates a new ControlBeanContext instance associated with a specific control bean.  If the
+     * <code>ControlBean</code> is null, this ControlBeanContext object represents a top-level Control
+     * container.  This constructor uses the <code>beanContextServicesDelegate</code> instance as the
+     * implementation of the {@link java.beans.beancontext.BeanContextServices} interface.
+     *
+     * @param bean The control bean
+     * @param beanContextServicesFactory A factory that can be used to create the BeanContextServicesFactory object
+     *        that implements support for the {@link BeanContextServices} interface.
+     */
+    protected ControlBeanContext(ControlBean bean, BeanContextServicesFactory beanContextServicesFactory) {
+        super();
+
         _bean = bean;
 
-        //
-        // For now, just create an implementation of the classes in the JDK as a delegate.
-        //
-        _beanContextServicesDelegate =
-            new java.beans.beancontext.BeanContextServicesSupport(this);
+        // ensure that there is a valid factory for creating the BCS delegate
+        if(beanContextServicesFactory == null)
+            beanContextServicesFactory = DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY;
 
+        _beanContextServicesDelegate = beanContextServicesFactory.instantiate(this);
         initialize();
     }
 
@@ -102,7 +119,7 @@
         //
         // Register the ControlBeanContext provider on all new context instances.
         //
-        addService(org.apache.beehive.controls.api.context.ControlBeanContext.class, theProvider);
+        addService(org.apache.beehive.controls.api.context.ControlBeanContext.class, CONTROL_BEAN_CONTEXT_PROVIDER);
     }
 
     /**
@@ -762,6 +779,10 @@
         initialize();
     }
 
+    protected BeanContextServicesFactory getBeanContextServicesFactory() {
+        return DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY;
+    }
+
     public boolean equals(Object o) {
         /* todo: make sure this logic is right / sufficient */
         if (this == o)
@@ -934,14 +955,6 @@
        -------------------------------------------------------------------------- */
 
     /**
-     * Filename that contains ordering priority for controls interceptor services.
-     * Each line in the file is a fully qualified interface name.  The first line in the file
-     * is highest priority.
-     * @deprecated Use {@link InterceptorUtils#INTERCEPTOR_CONFIG_FILE} instead.  This constant
-     *             will be removed in the next point release.
-     */
-
-    /**
      * Applies externally defined (via INTERCEPTOR_CONFIG_FILE) ordering priority for
      * controls interceptor services.
      *
@@ -1022,12 +1035,33 @@
         }
     }
 
+    /*package*/ static abstract class BeanContextServicesFactory {
+        protected abstract BeanContextServices instantiate(ControlBeanContext controlBeanContext);
+    }
+
+    private static final class DefaultBeanContextServicesFactory
+        extends BeanContextServicesFactory {
+        protected BeanContextServices instantiate(ControlBeanContext controlBeanContext) {
+            return new java.beans.beancontext.BeanContextServicesSupport(controlBeanContext);
+        }
+    }
+
     /**
      * A singleton instance of the ControlBeanContextProvider class is that will be registered
      * on all ControlBeanContext instances.  The provider can be a singleton because it is
      * completely stateless and thread-safe.
      */
-    private static ControlBeanContextProvider theProvider = new ControlBeanContextProvider();
+    private static final ControlBeanContextProvider CONTROL_BEAN_CONTEXT_PROVIDER =
+        new ControlBeanContextProvider();
+
+    /**
+     * A singleton instance of the BeanContextServicesFactory class that can be implemented by subclasses
+     * to allow top-level Control containers to provide their own implementations of the
+     * {@link java.beans.beancontext.BeanContextServices} interface.  This field is considered an implementation
+     * detail and should not be referenced directly.
+     */
+    private static final BeanContextServicesFactory DEFAULT_BEAN_CONTEXT_SERVICES_FACTORY =
+        new DefaultBeanContextServicesFactory();
 
     /**
      * The ControlBean instance that this context is providing services for.  This value can

Modified: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java?rev=405791&r1=405790&r2=405791&view=diff
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java (original)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlContainerContext.java Wed May 10 09:28:38 2006
@@ -34,13 +34,17 @@
  * - defines a simplified contract for the external container to interact with resource
  *   management (beginContext/endContext)
  */
-public class ControlContainerContext 
+public class ControlContainerContext
        extends ControlBeanContext
        implements EventDispatcher, org.apache.beehive.controls.api.context.ControlContainerContext
 {
     public ControlContainerContext()
     {
         super(null);
+    }
+
+    protected ControlContainerContext(BeanContextServicesFactory beanContextServicesFactory) {
+        super(null, beanContextServicesFactory);
     }
 
     /**

Added: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/WebContextFactoryProvider.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/WebContextFactoryProvider.java?rev=405791&view=auto
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/WebContextFactoryProvider.java (added)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/WebContextFactoryProvider.java Wed May 10 09:28:38 2006
@@ -0,0 +1,98 @@
+/*
+ * 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:$
+ */
+package org.apache.beehive.controls.runtime.bean;
+
+import java.beans.beancontext.BeanContextServices;
+import java.beans.beancontext.BeanContextServiceProvider;
+import java.util.Iterator;
+import java.util.Collections;
+
+import org.apache.beehive.controls.spi.context.ControlBeanContextFactory;
+
+/**
+ * <p>
+ * This class acts as a ControlBeanContextFactoryProvider that exposes this factory as a contextual service
+ * from inside of a ControlBeanContext.
+ * </p>
+ * <p>
+ * <b>Note:</b> This class, the service provider, and the contextual service it provides are considerd an implementation
+ * detail and <b>should not</b> be used from user code.
+ * </p>
+ */
+public class WebContextFactoryProvider
+    implements BeanContextServiceProvider {
+
+    private static final WebContextFactoryProvider theProvider = new WebContextFactoryProvider();
+    private static final WebControlBeanContextFactory theFactory = new WebControlBeanContextFactory();
+
+    public static final ControlBeanContext.BeanContextServicesFactory WEB_CONTEXT_BCS_FACTORY =
+        new WebContextBeanContextServicesFactory();
+
+    public static BeanContextServiceProvider getProvider() {
+        return theProvider;
+    }
+
+    private WebContextFactoryProvider() {
+    }
+
+    public Object getService(BeanContextServices bcs, Object requestor, Class serviceClass, Object serviceSelector) {
+        return theFactory;
+    }
+
+    public void releaseService(BeanContextServices bcs, Object requestor, Object service) {
+    }
+
+    public Iterator getCurrentServiceSelectors(BeanContextServices bcs, Class serviceClass) {
+        return Collections.EMPTY_LIST.iterator();
+    }
+
+    /**
+     * <p>
+     * {@link ControlBeanContextFactory} implementation that provides a {@link ControlBeanContext} object
+     * used for web-tier control containment.
+     * </p>
+     * <p>
+     * <b>Note:</b> This factory is considerd an implementation detail and <b>should not</b> be referenced from user code.
+     * </p>
+     */
+    /*package*/ static class WebControlBeanContextFactory
+        implements ControlBeanContextFactory {
+
+        public org.apache.beehive.controls.api.context.ControlBeanContext instantiate
+            (org.apache.beehive.controls.api.bean.ControlBean controlBean) {
+
+            if(!(controlBean instanceof ControlBean))
+                throw new IllegalArgumentException("The ControlBean of type \"" +
+                    controlBean.getClass().getName() +
+                    "\" is unsupported.  The ControlBean must extend " +
+                    ControlBean.class.getName());
+
+            ControlBean runtimeControlBean = (ControlBean)controlBean;
+
+            return new ControlBeanContext(runtimeControlBean, WEB_CONTEXT_BCS_FACTORY);
+        }
+    }
+
+    /*package*/ static class WebContextBeanContextServicesFactory
+        extends ControlBeanContext.BeanContextServicesFactory {
+        protected BeanContextServices instantiate(ControlBeanContext controlBeanContext) {
+            //return new ControlBeanContextServicesSupport(controlBeanContext);
+            return new java.beans.beancontext.BeanContextServicesSupport(controlBeanContext);
+        }
+    }
+}

Modified: beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletBeanContext.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletBeanContext.java?rev=405791&r1=405790&r2=405791&view=diff
==============================================================================
--- beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletBeanContext.java (original)
+++ beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/servlet/ServletBeanContext.java Wed May 10 09:28:38 2006
@@ -20,6 +20,8 @@
 import java.util.Stack;
 import java.io.InputStream;
 import java.beans.beancontext.BeanContextChild;
+import java.beans.beancontext.BeanContextServices;
+import java.beans.beancontext.BeanContextServiceProvider;
 import java.net.URL;
 import java.net.MalformedURLException;
 import javax.servlet.ServletContext;
@@ -29,6 +31,8 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.beehive.controls.runtime.bean.ControlContainerContext;
+import org.apache.beehive.controls.runtime.bean.WebContextFactoryProvider;
+import org.apache.beehive.controls.spi.context.ControlBeanContextFactory;
 
 /**
  * The ServletBeanContext provides a ControlBeanContext implementation that offers services
@@ -37,23 +41,12 @@
 public class ServletBeanContext
     extends ControlContainerContext
 {
-    private static class RequestContext
-    {
-        RequestContext(ServletContext context, ServletRequest req, ServletResponse resp)
-        {
-            _context = context;
-            _request = req;
-            _response = resp;
-        }
-
-        ServletContext _context;
-        ServletResponse _response;
-        ServletRequest _request;
-    }
-
-    public ServletBeanContext()
-    {
-        super();
+    public ServletBeanContext() {
+        //
+        // This sets the BeanContextServicesFactory instance on the ControlBeanContext and allows this
+        // CCC object to be created with a BeanContextServicesDelegate of the type returned by this factory
+        //
+        super(WebContextFactoryProvider.WEB_CONTEXT_BCS_FACTORY);
     }
 
     /**
@@ -73,6 +66,13 @@
         addService(ServletResponse.class, ssp);
         addService(HttpServletRequest.class, ssp);
         addService(HttpServletResponse.class, ssp);
+
+        //
+        // Register an *internal* service that is used to create ControlBeanContext objects for
+        // children of this control container
+        //
+        BeanContextServiceProvider cbcFactoryProvider = WebContextFactoryProvider.getProvider();
+        addService(ControlBeanContextFactory.class, cbcFactoryProvider);
     }
 
     /**
@@ -194,7 +194,7 @@
         ServletContext sc = getServletContext();
         if ( sc != null )
             return sc.getResourceAsStream( name );
-        
+
         return null;
     }
 
@@ -228,6 +228,20 @@
 
     protected boolean useWrappers() {
         return _useWrappers;
+    }
+
+    private static class RequestContext
+    {
+        RequestContext(ServletContext context, ServletRequest req, ServletResponse resp)
+        {
+            _context = context;
+            _request = req;
+            _response = resp;
+        }
+
+        ServletContext _context;
+        ServletResponse _response;
+        ServletRequest _request;
     }
 
     private boolean _useWrappers = true;