Author: kylem
Date: Tue Apr 12 12:08:26 2005
New Revision: 161092

URL: http://svn.apache.org/viewcvs?view=rev&rev=161092
Log:
Improved handling of how composite control IDs are computed and managed to 
resolve BEEHIVE-508.  Instead of managing the composite ID locally in each 
bean, it is now stored in a transient value on the associated context, computed 
on demand, and cached.  This makes it easier to ensure consistency, because 
cached values are now easily flushed if a bean is reparented to another 
context.  Added a DRT test case that verifies control IDs.

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/ControlBeanContext.java
    
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/InnerControlImpl.jcs
    
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
    
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java
URL: 
http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java?view=diff&r1=161091&r2=161092
==============================================================================
--- 
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
 Tue Apr 12 12:08:26 2005
@@ -73,7 +73,6 @@
         super();
 
         _localID = id;
-        _id = _localID;
         _controlIntf = controlIntf;
 
         // Create the context that acts as the BeanContextProxy for this bean 
(the context that this bean _defines_).
@@ -236,7 +235,7 @@
      */
     final public String getControlID()
     {
-        return _id;
+        return _cbc.getControlID();
     }
 
     /**
@@ -607,17 +606,6 @@
     }
 
     /**
-     * Sets the absolute controlID for this ControlBean.  This is called from 
the associated
-     * BeanContextChild instance when the bean is associated with a new 
context.
-     */
-    public void setControlID(String id)
-    {
-        _id = id;
-
-        // TODO: The ID change needs to be propagated down to nested children
-    }
-
-    /**
      * Sets a property on the ControlBean instance.  All generated property 
setter methods
      * will delegate down to this method.
      */
@@ -1039,14 +1027,9 @@
     /** END synchronized fields */
 
     /**
-     * The control ID associated with this instance
+     * The (context relative) control ID associated with this instance
      */
     private String _localID;
-
-    /**
-     * The control ID associated with this instance
-     */
-    private String _id;
 
     /**
      * The public control interface associated with this ControlBean

Modified: 
incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java
URL: 
http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBeanContext.java?view=diff&r1=161091&r2=161092
==============================================================================
--- 
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
 Tue Apr 12 12:08:26 2005
@@ -177,30 +177,15 @@
 
         super.setBeanContext(beanContext);
 
+        resetControlID();
+
         _hasSingleThreadedParent = cbcs != null ? 
cbcs.isSingleThreadedContainer() : false;
 
+        //
+        // Notify the bean that its context (container) has been set.
+        //
         if (_bean != null)
-        {
-            String id = _bean.getLocalID();
-
-            //
-            // Notify the bean that its context (container) has been set.
-            //
             _bean.setBeanContext(beanContext);
-
-            //
-            // Establish a new value for the absolute control ID based upon 
the nesting context
-            // and parent bean (if any).
-            //
-            if (beanContext != null)
-            {
-                ControlBean parentBean = cbcs.getControlBean();
-                if (parentBean != null)
-                    id = parentBean.getControlID() + 
org.apache.beehive.controls.api.bean.ControlBean.IDSeparator + id;
-            }
-
-            _bean.setControlID(id);
-        }
     }
 
     /**
@@ -819,6 +804,46 @@
         }
     }
 
+    /* package */ String getControlID()
+    {
+        if (_controlID != null || _bean == null)
+            return _controlID;
+
+        // Initially set to the local beans relative ID
+        _controlID = _bean.getLocalID();
+
+        // If there is a parent context, prepend its ID and the ID separator
+        BeanContext bc = getBeanContext();
+        if (bc != null && bc instanceof ControlBeanContext)
+        {
+            String parentID = ((ControlBeanContext)bc).getControlID();
+            if (parentID != null)
+            {
+                _controlID = parentID + 
+                             
org.apache.beehive.controls.api.bean.ControlBean.IDSeparator +
+                             _controlID;
+            }
+        }
+        return _controlID;
+    }
+
+    /**
+     * Resets the composite control ID for this context and all children 
beneath it.  This
+     * can be used to invalidate cached values when necessarily (for example, 
when a context
+     * is reparented).
+     */
+    private void resetControlID()
+    {
+        _controlID = null;
+        Iterator childIter = this.iterator();
+        while (childIter.hasNext())
+        {
+            Object child = childIter.next();
+            if (child instanceof ControlBeanContext)
+                ((ControlBeanContext)child).resetControlID();
+        }
+    }
+
     /**
      * The ControlBean instance that this context is providing services for.  
This value can
      * be null, if the context instance is associated with top-level 
(non-control) context.
@@ -851,6 +876,13 @@
      * Maintains the list of lifecycle event listeners (if any) for this 
context.
      */
     transient private Vector<LifeCycle> _lifeCycleListeners;
+
+    /**
+     * Caches the full composite control ID, that includes the entire path 
from the root
+     * ContainerContext to the associated bean.  This value can be transient, 
since it
+     * can be easily recomputed when needed.
+     */
+    transient private String _controlID;
 
     private static ArrayList<String> _interceptorPriorities;
 }

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/InnerControlImpl.jcs
URL: 
http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/InnerControlImpl.jcs?view=diff&r1=161091&r2=161092
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/InnerControlImpl.jcs
 (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/InnerControlImpl.jcs
 Tue Apr 12 12:08:26 2005
@@ -12,7 +12,7 @@
  * This control shall be instantiated by another control.
  */
 @ControlImplementation
-public class InnerControlImpl implements InnerControl
+public class InnerControlImpl implements InnerControl, java.io.Serializable
 { 
     @Context ControlBeanContext context;
     @Client Activity activity;

Modified: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
URL: 
http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs?view=diff&r1=161091&r2=161092
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
 (original)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/composition/OuterControlImpl.jcs
 Tue Apr 12 12:08:26 2005
@@ -16,7 +16,7 @@
  * Makes two instances of nested control be declaration.
  */
 @ControlImplementation
-public class OuterControlImpl implements OuterControl
+public class OuterControlImpl implements OuterControl, java.io.Serializable
 { 
     static final long serialVersionUID = 1L;
     static final String EVENT_RECEIVED="Event Received";
@@ -40,7 +40,7 @@
     private boolean innerControlInnerClassDoStuff=false;  
     
     @Client
-    OuterEvents outerEvents;
+    transient OuterEvents outerEvents;
 
     /*Instantiates a nested control without reconfiguring the property*/
     @Control 

Modified: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
URL: 
http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java?view=diff&r1=161091&r2=161092
==============================================================================
--- 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
 (original)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/composition/DeclarativeTest.java
 Tue Apr 12 12:08:26 2005
@@ -3,6 +3,11 @@
 import junit.framework.Assert;
 import junit.framework.TestCase;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
 import org.apache.beehive.controls.api.bean.Control;
 import org.apache.beehive.controls.api.events.EventHandler;
 import org.apache.beehive.controls.test.controls.composition.OuterControl;
@@ -20,7 +25,7 @@
  * All tests are deactivated until this is supported
  */
 @Freq("checkin")
-public class DeclarativeTest extends TestCase
+public class DeclarativeTest extends TestCase implements java.io.Serializable
 {
     // initialize declared controls once
     public DeclarativeTest(String name) throws Exception
@@ -100,6 +105,31 @@
         outerControl.fireOuterEvents("this is the reported msg");
         Assert.assertEquals("this is the reported msg", _reportMsg );
         System.out.println( "_reportMsg=" + _reportMsg );
+    }
+
+    /**
+     * Tests that control IDS properly represent the composition relationship
+     */
+    public void testControlIDs() throws Exception
+    {
+        Assert.assertEquals("outerControl", outerControl.getControlID());
+        Assert.assertEquals("outerControl/innerControl",
+                            
outerControl.getDeclaredNestedControl().getControlID());
+
+        // Test the relationships and identifiers are preserved across 
serialization and
+        // deserialization
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(outerControl);
+        oos.close();
+        ByteArrayInputStream bais = new 
ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        OuterControlBean outerCopy = (OuterControlBean)ois.readObject();
+        ois.close();
+
+        Assert.assertEquals("outerControl", outerCopy.getControlID());
+        Assert.assertEquals("outerControl/innerControl",
+                            
outerCopy.getDeclaredNestedControl().getControlID());
     }
 
     /**


Reply via email to