You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by mc...@apache.org on 2008/02/19 23:20:20 UTC

svn commit: r629248 - /myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java

Author: mcooper
Date: Tue Feb 19 14:20:16 2008
New Revision: 629248

URL: http://svn.apache.org/viewvc?rev=629248&view=rev
Log:
Added the ability for UIXShowOne components to add rendering support for FlattenedComponent children, e.g. tr:iterator, tr:switcher, tr:group.

Modified:
    myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java

Modified: myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java?rev=629248&r1=629247&r2=629248&view=diff
==============================================================================
--- myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java (original)
+++ myfaces/trinidad/trunk_1.2.x/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXShowOneTemplate.java Tue Feb 19 14:20:16 2008
@@ -18,9 +18,11 @@
  */
 package org.apache.myfaces.trinidad.component;
 
+import java.io.IOException;
 import java.util.List;
 
 import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
 import javax.faces.event.FacesEvent;
 import javax.faces.event.PhaseId;
 
@@ -37,47 +39,111 @@
   @SuppressWarnings("unchecked")
   public void queueEvent(FacesEvent e)
   {
-    //  Care only if it is a DisclosureEvent, and only if its source is one of
-    //  its immediate children, for... one could bubble up from one of its grand
-    //  children that could be a ShowDetail.
-    if ( (e instanceof DisclosureEvent) &&
-         (this == e.getComponent().getParent()) )
+    // Care only if it is a DisclosureEvent, and only if its source is one of
+    // its immediate children, for... one could bubble up from one of its grand
+    // children that could be a ShowDetail.
+    FacesEvent unwrappedEvent = e;
+    while (unwrappedEvent instanceof WrapperEvent) // e.g. DisclosureEvent in a tr:iterator
     {
-      //  Care only if the incoming event was from the to-be-disclosed
-      //  showDetailItem
-      if (((DisclosureEvent) e).isExpanded())
+      unwrappedEvent = ((WrapperEvent)unwrappedEvent).getEvent();
+    }
+
+    if (unwrappedEvent instanceof DisclosureEvent)
+    {
+      UIComponent parent = unwrappedEvent.getComponent().getParent();
+      while (parent != null && parent instanceof FlattenedComponent)
+      {
+        parent = parent.getParent();
+      }
+
+      if (this == parent)
       {
-        UIXShowDetail toBeUnDisclosedChild = null;
-        List<UIComponent> children = getChildren();
-        for(UIComponent child : children)
+        // Care only if the incoming event was from the to-be-disclosed showDetailItem.
+        DisclosureEvent disclosureEvent = (DisclosureEvent)unwrappedEvent;
+        if (disclosureEvent.isExpanded())
         {
-          if (child instanceof UIXShowDetail)
+          FacesContext context = FacesContext.getCurrentInstance();
+          String disclosedClientId = disclosureEvent.getComponent().getClientId(context);
+
+          // Visit all of the flattened children:
+          try
           {
-            toBeUnDisclosedChild =  (UIXShowDetail) child;
-            if (toBeUnDisclosedChild.isDisclosed())
-              break;
+            UIXComponent.processFlattenedChildren(
+              context,
+              _undisclosureCallback,
+              getChildren(),
+              new UndisclosureCallbackState(e, disclosedClientId));
+          }
+          catch (IOException ioe)
+          {
+            // This exception is not expected since no IO is used in this visitor's implementation.
+            ioe.printStackTrace();
           }
         }
-        
-        //  Override the phaseId that would be already set on this event
-        //  (coming off of the to-be-disclosed showDetailItem), because the
-        //  phase-id should actually be determined by the 'immediate' attribute
-        //  on the to-be-undisclosed showDetailItem
-        if (toBeUnDisclosedChild.isImmediate())
-        {
-          e.setPhaseId(PhaseId.ANY_PHASE);
-        }
-        else
+      }
+    }
+    super.queueEvent(e);
+  }
+
+  /**
+   * State passed to the UndisclosureCallback.
+   */
+  private static class UndisclosureCallbackState
+  {
+    public UndisclosureCallbackState(
+      FacesEvent facesEvent,
+      String     clientIdBeingDisclosed)
+    {
+      this.facesEvent = facesEvent;
+      this.clientIdBeingDisclosed = clientIdBeingDisclosed;
+    }
+
+    protected final FacesEvent facesEvent;
+    protected final String clientIdBeingDisclosed;
+  }
+
+  /**
+   * Visitor for each flattened child, using the information in the UndisclosureCallbackState.
+   */
+  private class UndisclosureCallback implements ComponentProcessor<UndisclosureCallbackState>
+  {
+    public void processComponent(
+      FacesContext               facesContext,
+      ComponentProcessingContext processContext,
+      UIComponent                child,
+      UndisclosureCallbackState  callbackState)
+      throws IOException
+    {
+      String clientIdBeingDisclosed = callbackState.clientIdBeingDisclosed;
+
+      // Search for the other item(s) to undisclose (make sure to skip the clientIdBeingDisclosed):
+      String childClientId = child.getClientId(facesContext);
+      if (!clientIdBeingDisclosed.equals(childClientId))
+      {
+        UIXShowDetail toBeUnDisclosedChild = (UIXShowDetail)child;
+        if (toBeUnDisclosedChild.isDisclosed())
         {
-          e.setPhaseId(PhaseId.INVOKE_APPLICATION);
+          // Override the phaseId that would be already set on this event
+          // (coming off of the to-be-disclosed showDetailItem), because the
+          // phase-id should actually be determined by the 'immediate' attribute
+          // on the to-be-undisclosed showDetailItem
+          if (toBeUnDisclosedChild.isImmediate())
+          {
+            callbackState.facesEvent.setPhaseId(PhaseId.ANY_PHASE);
+          }
+          else
+          {
+            callbackState.facesEvent.setPhaseId(PhaseId.INVOKE_APPLICATION);
+          }
+
+          // Now queue the event for the to-be-undisclosed showDetailItem
+          // Note that this is always delivered earlier than the one that is
+          // already queued for to-be-disclosed showDetailItem.
+          (new DisclosureEvent(toBeUnDisclosedChild, false)).queue();
         }
-        //  Now queue the event for the to-be-undisclosed showDetailItem
-        //  Note that this is always delivered earlier than the one that is
-        //  already queued for to-be-disclosed showDetailItem.
-        (new DisclosureEvent(toBeUnDisclosedChild, false)).queue();
       }
     }
-    super.queueEvent(e);
   }
 
+  private final UndisclosureCallback _undisclosureCallback = new UndisclosureCallback();
 }