You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ma...@apache.org on 2009/05/27 16:54:27 UTC

svn commit: r779201 - in /myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change: ChangeManager.java NullChangeManager.java SessionChangeManager.java

Author: matzew
Date: Wed May 27 14:54:27 2009
New Revision: 779201

URL: http://svn.apache.org/viewvc?rev=779201&view=rev
Log:
TRINIDAD-1488 - ChangeManager: Ability to apply component changes to a subtree

thanks to Andy for his patch;

Modified:
    myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/ChangeManager.java
    myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/NullChangeManager.java
    myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java

Modified: myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/ChangeManager.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/ChangeManager.java?rev=779201&r1=779200&r2=779201&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/ChangeManager.java (original)
+++ myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/ChangeManager.java Wed May 27 14:54:27 2009
@@ -22,6 +22,7 @@
 
 import javax.el.ValueExpression;
 
+import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
@@ -170,6 +171,26 @@
   {
     throw new UnsupportedOperationException("Subclassers must implement");
   }
+
+  /**
+   * Applies the ComponentChanges added so far for components underneath
+   * the specified NamingContainer.
+   * Developers should not need to call this method. Internal implementation
+   * will call it as the component tree is built and is ready to take changes.
+   * @param facesContext The FacesContext instance for the current request.
+   * @param root The NamingContainer that contains the component subtree
+   * to which ComponentChanges should be applied.  If null, all changes are
+   * applied.
+   * @throws IllegalArgumentException if the root NamingContainer is not a
+   *   UIComponent instance.
+   */
+  public void applyComponentChangesForSubtree(
+    FacesContext facesContext,
+    NamingContainer root
+    )
+  {
+    throw new UnsupportedOperationException("Subclassers must implement");
+  }
   
   private static class AttributeConverter extends DocumentChangeFactory
   {

Modified: myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/NullChangeManager.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/NullChangeManager.java?rev=779201&r1=779200&r2=779201&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/NullChangeManager.java (original)
+++ myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/NullChangeManager.java Wed May 27 14:54:27 2009
@@ -18,6 +18,7 @@
  */
 package org.apache.myfaces.trinidad.change;
 
+import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 import javax.faces.context.FacesContext;
 
@@ -48,4 +49,16 @@
   {
     //no-op
   }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public void applyComponentChangesForSubtree(
+    FacesContext facesContext,
+    NamingContainer root
+    )
+  {
+    //no-op
+  }
 }

Modified: myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java?rev=779201&r1=779200&r2=779201&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java (original)
+++ myfaces/trinidad/branches/1.2.11.3-branch/trinidad-api/src/main/java/org/apache/myfaces/trinidad/change/SessionChangeManager.java Wed May 27 14:54:27 2009
@@ -31,6 +31,7 @@
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
@@ -57,31 +58,32 @@
   @Override
   public void applyComponentChangesForCurrentView(FacesContext facesContext)
   {
-    UIViewRoot viewRoot = facesContext.getViewRoot();
-    
-    // retrieve the ComponentChanges for this current viewid
-    ChangesForView changesForView = _getChangesForView(facesContext, viewRoot.getViewId(), false);
+    _applyComponentChanges(facesContext, null);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+   @Override
+  public void applyComponentChangesForSubtree(
+    FacesContext facesContext,
+    NamingContainer root
+    )
+  {
+    String rootId = null;
     
-    // loop through the viewId's changes, applying the changes
-    for (QualifiedComponentChange qualifiedChange : changesForView.getComponentChangesForView())
+    if (root != null)
     {
-      UIComponent targetComponent = 
-        viewRoot.findComponent(qualifiedChange.getTargetComponentScopedId());
-      
-      // Possible that the target component no more exists in the view
-      if (targetComponent != null)
+      if (!(root instanceof UIComponent))
       {
-        ComponentChange componentChange = qualifiedChange.getComponentChange();
-        componentChange.changeComponent(targetComponent);
-      }
-      else
-      {
-        _LOG.info(this.getClass().getName(),
-                  "applyComponentChangesForCurrentView",
-                  "TARGET_COMPONENT_MISSING_CHANGE_FAILED",
-                  qualifiedChange.getTargetComponentScopedId());
+        throw new IllegalArgumentException(_LOG.getMessage(
+          "INVALID_TYPE", root));
       }
+      
+      rootId = ComponentUtils.getScopedIdForComponent((UIComponent)root, null);
     }
+
+    _applyComponentChanges(facesContext, rootId);
   }
 
   /**
@@ -194,6 +196,77 @@
   {
     return null;
   }
+  
+  /**
+   * Implementation shared by applyComponentChangesForCurrentView() and
+   * applyComponentChangesForSubtree().
+   * @param facesContext The FacesContext instance for this request.
+   * @param rootId The scoped id of theNamingContainer that contains the 
+   * component subtree to which ComponentChanges should be applied.  If null, 
+   * all changes are applied.
+   */
+  private void _applyComponentChanges(
+    FacesContext facesContext,
+    String       rootId
+    )
+  {
+    UIViewRoot viewRoot = facesContext.getViewRoot();
+    
+    // retrieve the ComponentChanges for this current viewid
+    ChangesForView changesForView = _getChangesForView(facesContext, viewRoot.getViewId(), false);
+    
+    // loop through the viewId's changes, applying the changes
+    for (QualifiedComponentChange qualifiedChange : changesForView.getComponentChangesForView())
+    {
+      if (!_acceptChange(qualifiedChange, rootId))
+        continue;
+
+      UIComponent targetComponent = 
+        viewRoot.findComponent(qualifiedChange.getTargetComponentScopedId());
+      
+      // Possible that the target component no more exists in the view
+      if (targetComponent != null)
+      {
+        ComponentChange componentChange = qualifiedChange.getComponentChange();
+        componentChange.changeComponent(targetComponent);
+      }
+      else
+      {
+        _LOG.info(this.getClass().getName(),
+                  "applyComponentChangesForCurrentView",
+                  "TARGET_COMPONENT_MISSING_CHANGE_FAILED",
+                  qualifiedChange.getTargetComponentScopedId());
+      }
+    }    
+  }
+
+  /**
+   * Tests whether the specified change should be applied based on the
+   * specified root id.  If root id is null, all changes are accepted/applied.
+   * If the root id is non-null, only changes which target ids underneath
+   * the root id are accepted/applied.
+   * 
+   * @param qualifiedChange the change to test
+   * @param rootId the scoped id of the NamingContainer for which we
+   *   are applying changes
+   * @return true if rootId is null, or if the qualifiedChange targets a
+   *   component underneath the NamingContainer identified by the rootId.
+   */
+  private boolean _acceptChange(
+    QualifiedComponentChange qualifiedChange,
+    String rootId
+    )
+  {
+    boolean accept = true;
+
+    if (rootId != null)
+    {
+      String id = qualifiedChange.getTargetComponentScopedId();
+      accept = (id.startsWith(rootId) && (id.length() != rootId.length()));    
+    }
+    
+    return accept;
+  }
 
   /**
    * Gets the in-order list of component changes for the given view.