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

svn commit: r629254 - in /myfaces/trinidad/trunk: src/site/xdoc/devguide/ trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/ trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ trinidad-api/src/main/xrts/org/apache/myfaces/trinidad...

Author: jwaldman
Date: Tue Feb 19 14:33:53 2008
New Revision: 629254

URL: http://svn.apache.org/viewvc?rev=629254&view=rev
Log:
TRINIDAD-936 changed the partialTrigger syntax so '::' pops out of naming container.
added test cases
changed RenderUtils's getRelativeId to work the same way.

Added:
    myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidad/util/FindRelativeComponentTest.java
    myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/TestRelativePartialTriggers.java
    myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx
    myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggersPrevRelease.jspx
Modified:
    myfaces/trinidad/trunk/src/site/xdoc/devguide/ppr.xml
    myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java
    myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java
    myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
    myfaces/trinidad/trunk/trinidad-build/src/main/resources/META-INF/maven-faces-plugin/components/trinidad/core/includes/CommonAttrs.xml
    myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
    myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/pprDemos.jspx
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
    myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/CoreRenderKitTest.java

Modified: myfaces/trinidad/trunk/src/site/xdoc/devguide/ppr.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/src/site/xdoc/devguide/ppr.xml?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/src/site/xdoc/devguide/ppr.xml (original)
+++ myfaces/trinidad/trunk/src/site/xdoc/devguide/ppr.xml Tue Feb 19 14:33:53 2008
@@ -155,21 +155,17 @@
 
 <P>
 Also, if you've got JSF NamingContainers (e.g., f:subview) between the trigger and its target,
-you'll need to incorporate that into the partialTriggers definition:
+you'll need to incorporate that into the partialTriggers definition. The syntax is:
 <ul>
 <li>If you need to go down through a naming container to get to the trigger, include the naming container's ID with a colon (e.g., partialTriggers="theSubform:theLink"</li>
 <li>If you need to start at the root of the page to get the trigger component, start with a single colon (e.g., partialTriggers=":someRootComponent"</li>
-<li>If you need to go up and out of a parent naming container to get the trigger component, start with multiple colons. 
-  <ul>
-    <li>If the target component is not a NamingContainer, then the trigger is relative to the target component. To find it relative to the parent naming
-    container, start with two colons (e.g, partialTriggers="::myTrigger"). To find it relative to the grandparent naming container,
-    start with three colons (e.g., partialTriggers=":::myTrigger"), and so forth.
-    </li>
-    <li>If the target component is a NamingContainer, then the trigger is relative to the target component's parent, not the component itself.
-    </li>
-  </ul>
-</li>
+<li>If you need to go up and out of a naming container to get the trigger component, start with two colons. (e.g., partialTriggers="::someComponentOutsideNamingContainer")
+This includes the current component if the component is a NamingContainer. (e.g., tr:table partialTriggers="::mySiblingComponent" pops out of the table to get to the sibling)</li>
+<li>If you need to go up and out of two naming containers to get the trigger component, start with three colons.
+To pop out of three naming containers, start with four colons, and so on. (e.g., partialTriggers=":::someOtherComponent" pops out of two naming containers)</li>
 </ul>
+
+Here are some examples:
 </P>
 <source>
 <![CDATA[
@@ -189,23 +185,22 @@
               </f:subview>
             </f:subview>
 
-            <!-- Button 2 has four colons. Two to get it to button2WrapperB, three to get it to buttons2WrapperA,
-            and four to get it to wrapperAroundEverything. It will find the trigger from there. 
+            <!-- Button 2's partialTrigger starts with ':::'. 
+            Two colons to pop it out of button2WrapperB, another colon to pop it out of buttons2WrapperA.
             commandButton is not a NamingContainer -->
             <f:subview id="button2WrapperA">
               <f:subview id="button2WrapperB">
                 <tr:commandButton
-                  partialTriggers="::::button1WrapperA:button1WrapperB:button1"
+                  partialTriggers=":::button1WrapperA:button1WrapperB:button1"
                   partialSubmit="true"
                   id="button2"
                   text="button 2"/>
               </f:subview>
             </f:subview>
         ....
-            <!-- table is a NamingContainer, so finding the trigger starts
-            with the parent component -- the panelGroupLayout.. If the 
-            parent is a NamingContainer (like if you take the panelGroupLayout
-            away) then there would only be three colons. -->
+            <!-- table is a NamingContainer. Two colons pop out of the table.
+            Two more to pop it out of the two subviews.
+            -->
             <f:subview id="table7WrapperA">
               <f:subview id="table7WrapperB">
                 <tr:panelGroupLayout layout="vertical">

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java Tue Feb 19 14:33:53 2008
@@ -27,6 +27,8 @@
 import javax.faces.context.FacesContext;
 
 import org.apache.myfaces.trinidad.component.UIXForm;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.util.ComponentUtils;
 
 /**
  * Generic utilities for rendering.
@@ -102,67 +104,193 @@
   }
 
   /**
-   * Returns a relative ID for use at rendering time, e.g. "for"
-   * attributes on components.  It does not assume that the target
-   * component can be located.  A relative ID starting with
+   * Given a 'from' component and a relativeId, 
+   * return the clientId for use at rendering time that will identify the
+   * id of the component you are referencing on the client.
+   * This is used for attributes like e.g. "for" and "chooseId".
+   * 
+   * <p>
+   * e.g., given this hierarchy
+   * <br/>
+   *  &lt;f:subview id="aaa"&gt;&lt;f:subview id="xxx"&gt;<br/>
+           &lt;tr:chooseColor id="cp1" .../&gt;<br/>
+            &lt;f:subview id="yyy"><br/>
+               &lt;tr:inputColor id="sic1" chooseId="::cp1" .../&gt;<br/>
+            &lt;/f:subview&gt;<br/>
+         &lt;/f:subview&gt;&lt;/f:subview&gt;<br/>
+    </p>
+    <p>
+   * The 'from' component is the inputColor component.
+   * The 'relativeId' is "::cp1". ('::' pops up one naming container)
+   * The return value is 'aaa:xxx:cp1' when
+   * the clientId of the 'xxx' component is 'aaa:xxx'.
+   * 
+   * </p>
+   * <p>
+   * It does not assume that the target component can be located, although it does
+   * check. If it can't be found, returns the correct relativeId anyway.
+   * </p>
+   * <p>
+   * A relativeId starting with
    * NamingContainer.SEPARATOR_CHAR (that is, ':') will be
    * treated as absolute (after dropping that character).
+   * A relativeId with no colons means it is within the same naming container
+   * as the 'from' component (this is within the 'from' component if 'from'
+   * is a naming container).
+   * A relativeId starting with '::' pops out of the 'from' component's
+   * naming container. If the 'from' component is a naming container, then
+   * '::' will pop out of the 'from' component itself. A relativeId with ':::' pops up two naming containers, etc.
+   * ComponentUtils.findRelativeComponent finds and returns the component, whereas
+   * this method returns a relativeId that can be used during renderering 
+   * so the component can be found in javascript on the client.
+   * </p>
+   * @param context
+   * @param from the component to search relative to
+   * @param relativeId the relative path from the 'from' component 
+   *                   to the component to find
+   * @return the clientId for the 'relative' component.
+   @see ComponentUtils.findRelativeComponent(from, relativeId)
+
    */
   public static String getRelativeId(
     FacesContext context,
     UIComponent  from,
     String       relativeId)
   {
+    if (from == null)
+        return null;
+    
     if ((relativeId == null) || (relativeId.length() == 0))
       return null;
+
+    // Figure out how many colons
+    int colonCount = _getColonCount(relativeId);
+
+    // colonCount == 0: fully relative
+    // colonCount == 1: absolute 
+    // colonCount > 1: for each extra colon after 1, pop out of
+    // the naming container (to the view root, if naming containers run out)
     
-    UIComponent parentNC;
-    if (relativeId.charAt(0) == NamingContainer.SEPARATOR_CHAR)
+    if (colonCount == 1)
+      return relativeId.substring(1);
+    
+    // 
+    // We need to make it backward compatible, and 
+    // the only way is to use the findRelativeComponent code.
+    // This way we'll have a hint that the syntax is 'old' if 
+    // it can't be found. Plus, findRelativeComponent code has 
+    // backward compatibilty built in.
+    UIComponent component = 
+      ComponentUtils.findRelativeComponent(from, relativeId);
+    if (component == null && from instanceof NamingContainer)
     {
-      if (relativeId.length() > 1 && relativeId.charAt(1)
-        == NamingContainer.SEPARATOR_CHAR)
+      component = ComponentUtils.findRelativeComponent(from.getParent(), relativeId);
+      if (component != null)
       {
-        parentNC = _getParentNamingContainer(from.getParent());
-        int index = 2;
-        for (; index < relativeId.length() && relativeId.charAt(index) 
-          == NamingContainer.SEPARATOR_CHAR && parentNC != null; ++index)
-        {
-          parentNC = _getParentNamingContainer(parentNC.getParent());
-        }
-        if (parentNC == null || index >= relativeId.length())
-        {
-          // TODO: would it be better to return null from here?
-          return relativeId;
-        }
-        relativeId = relativeId.substring(index);
-      }
-      else
-      {
-        return relativeId.substring(1);
+        // TODO Log warning
+        _LOG.warning("DEPRECATED_RELATIVE_ID_SYNTAX", 
+          new Object[] {relativeId, from});
       }
     }
+    
+    // the component wasn't found, but go ahead and return something smart
+    if (component == null)
+    {
+      // TODO LOG warning
+      _LOG.warning("RELATIVE_ID_NOT_FOUND", 
+        new Object[] {relativeId, from});
+      return _getRelativeId(context, from, relativeId, colonCount);
+    }
     else
     {
-      parentNC = _getParentNamingContainer(from.getParent());
-      if (parentNC == null)
-      {
-        return relativeId;
-      }
+      return component.getClientId(context);
     }
 
-    return (parentNC.getClientId(context) +
-            NamingContainer.SEPARATOR_CHAR + relativeId);
   }
 
-  private static UIComponent _getParentNamingContainer(UIComponent from)
+
+  // This does NOT use findComponent
+  // ComponentUtils.findRelativeComponent finds the component, whereas
+  // this method returns a relativeId that can be used during renderering 
+  // so the component can be found in javascript on the client.
+  // This code is faster because it doesn't have to find the component.
+  // It is used when the getRelativeId's findRelativeComponent cannot find 
+  // the component. This way we can return the relativeId anyway.
+  private static String _getRelativeId(
+    FacesContext context,
+    UIComponent  from,
+    String       relativeId,
+    int          colonCount)
   {
-    while (from != null)
+
+
+    if (colonCount == 1)
+      return relativeId.substring(1);
+    else if (colonCount > 1)
+    {
+      relativeId = relativeId.substring(colonCount);
+    }
+      
+    // if the component is not a NamingContainer, then we need to 
+    // get the component's naming container and set this as the 'from'.
+
+    if (!(from instanceof NamingContainer))
     {
+      from = _getParentNamingContainer(from);
+    }
+    // pop out of the naming containers if there are multiple colons
+    // from will be null if there are no more naming containers
+    for (int j = 1; j < colonCount; j++)
+    {
+      from = _getParentNamingContainer(from);
+    }
+
+
+    if (from == null)
+      return relativeId;
+    else
+    {
+      return (from.getClientId(context) +
+              NamingContainer.SEPARATOR_CHAR + relativeId);
+    }
+
+
+  }
+
+
+  // Given a component, get its naming container. If the component
+  // is a naming container, it will get its naming container.
+  // This is different than the one in ComponentUtils. This one
+  // returns null if there are no more NamingContainers. The other one
+  // returns the ViewRoot.
+  private static UIComponent _getParentNamingContainer (
+    UIComponent from)
+  {
+
+    while (from != null && from.getParent() != null)
+    {
+      from = from.getParent();
       if (from instanceof NamingContainer)
         return from;
-      from = from.getParent();
     }
 
     return null;
   }
+  
+  // Figure out how many colons
+  private static int _getColonCount(String relativeId)
+  {
+    int idLength = relativeId.length();
+    int colonCount = 0;
+    while (colonCount < idLength)
+    {
+      if (relativeId.charAt(colonCount) != NamingContainer.SEPARATOR_CHAR)
+        break;
+      colonCount++;
+    }
+    return colonCount;
+  }
+  static private final TrinidadLogger _LOG =
+    TrinidadLogger.createTrinidadLogger(RenderUtils.class);
+
 }

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java Tue Feb 19 14:33:53 2008
@@ -25,12 +25,14 @@
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+
 /**
  * Utility functions used by the Apache Trinidad components.
  * <p>
  * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-api/src/main/java/oracle/adf/view/faces/util/ComponentUtils.java#0 $) $Date: 10-nov-2005.19:08:37 $
  */
-public class ComponentUtils
+public final class ComponentUtils
 {
   private ComponentUtils()
   {
@@ -319,24 +321,119 @@
     return t;
   }
 
+
   /**
    * Find a component relative to another.
    * <p>
    * The relative ID must account for NamingContainers. If the component is already inside
    * of a naming container, you can use a single colon to start the search from the root, 
-   * or multiple colons to move up through the NamingContainers - "::" will search from 
-   * the parent naming container, ":::" will search from the grandparent 
-   * naming container, etc.
+   * or multiple colons to move up through the NamingContainers - "::" will 
+   * pop out of the current naming container, ":::" will pop out of two
+   * naming containers, etc.
    * </p>
    * 
    * @param from the component to search relative to
    * @param relativeId the relative path to the component to find
    * @return the component if found, null otherwise
+   * @see RenderUtils.getRelativeId(from, relativeId)
    */
   public static UIComponent findRelativeComponent(
     UIComponent from,
     String      relativeId)
   {
+    if (from == null)
+        return null;
+    UIComponent originalFrom = from;
+    String originalRelativeId = relativeId;
+    
+    int idLength = relativeId.length();
+    // Figure out how many colons
+    int colonCount = 0;
+    while (colonCount < idLength)
+    {
+      if (relativeId.charAt(colonCount) != NamingContainer.SEPARATOR_CHAR)
+        break;
+      colonCount++;
+    }
+
+    // colonCount == 0: fully relative
+    // colonCount == 1: absolute (still normal findComponent syntax)
+    // colonCount > 1: for each extra colon after 1, pop out of
+    // the naming container (to the view root, if naming containers run out)
+    if (colonCount > 1)
+    {
+      relativeId = relativeId.substring(colonCount);
+      
+      // if the component is not a NamingContainer, then we need to 
+      // get the component's naming container and set this as the 'from'.
+      // this way we'll pop out of the component's 
+      // naming container if there is are multiple colons.
+      if (!(from instanceof NamingContainer))
+      {
+        from = _getParentNamingContainer(from);
+      }
+      
+      // pop out of the naming containers if there are multiple colons
+      for (int j = 1; j < colonCount; j++)
+      {
+        from = _getParentNamingContainer(from);
+      }
+    }
+
+    UIComponent found = from.findComponent(relativeId);
+    if (found != null)
+      return found;
+    else
+    {
+      // try the old way for backward compatability as far as it differed,
+      // which is only if the 'from' was not a NamingContainer.
+      if (!(originalFrom instanceof NamingContainer))
+        return _findRelativeComponentDeprecated(originalFrom, originalRelativeId);
+      else
+        return null;
+    }
+    
+  }
+  
+  // given a component, get its naming container. If the component
+  // is a naming container, it will get its naming container.
+  // if no parent naming containers exist, it stops at the ViewRoot.
+  private static UIComponent _getParentNamingContainer (
+    UIComponent from)
+  {
+    while (from.getParent() != null)
+    {
+      from = from.getParent();
+      if (from instanceof NamingContainer)
+        break;
+    }
+    return from;
+  }
+
+   /**
+    * Find a component relative to another.
+    * This method is the same as the 'old' public findRelativeComponent.
+   * This method is around so that the
+   * new findRelativeComponent method is backward compatibility.
+    * <p>
+    * The relative ID must account for NamingContainers. If the component is already inside
+    * of a naming container, you can use a single colon to start the search from the root, 
+    * or multiple colons to move up through the NamingContainers - "::" will search from 
+    * the parent naming container, ":::" will search from the grandparent 
+    * naming container, etc.
+    * </p>
+    * 
+    * @param from the component to search relative to
+    * @param relativeId the relative path to the component to find
+    * @return the component if found, null otherwise
+    */
+  private static UIComponent _findRelativeComponentDeprecated(
+    UIComponent from,
+    String      relativeId)
+  {  
+    UIComponent originalFrom = from;
+    String originalRelativeId = relativeId;
+
     int idLength = relativeId.length();
     // Figure out how many colons
     int colonCount = 0;
@@ -365,7 +462,15 @@
       }
     }
 
-    return from.findComponent(relativeId);
+    UIComponent found = from.findComponent(relativeId);
+    if (found != null)
+    {
+      _LOG.warning("DEPRECATED_RELATIVE_ID_SYNTAX", 
+        new Object[] {originalRelativeId, originalFrom});
+    }
+    return found;
   }
-
+  
+  static private final TrinidadLogger _LOG =
+    TrinidadLogger.createTrinidadLogger(ComponentUtils.class);
 }

Modified: myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts Tue Feb 19 14:33:53 2008
@@ -396,4 +396,10 @@
  <!-- RESOURCE_PATH_CONTAINS_DOTS -->
  <resource key="RESOURCE_PATH_DOTS">The resource path {0} contains "..". Browsers resolve out the "..", so this is a suspicious path.</resource>
 
+<!-- DEPRECATED_RELATIVE_ID_SYNTAX -->
+<resource key="DEPRECATED_RELATIVE_ID_SYNTAX">Could not find the component with relative id {0} from {1} with the supported syntax. The component was found with the deprecated syntax. Please use the supported syntax.</resource>
+
+<!-- RELATIVE_ID_NOT_FOUND -->
+<resource key="RELATIVE_ID_NOT_FOUND">Could not find the component with relative id {0} from {1}. This method will return the relative id anyway. Please double-check the syntax and make sure the component exists.</resource>
+
 </resources>

Added: myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidad/util/FindRelativeComponentTest.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidad/util/FindRelativeComponentTest.java?rev=629254&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidad/util/FindRelativeComponentTest.java (added)
+++ myfaces/trinidad/trunk/trinidad-api/src/test/java/org/apache/myfaces/trinidad/util/FindRelativeComponentTest.java Tue Feb 19 14:33:53 2008
@@ -0,0 +1,213 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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.
+ */
+package org.apache.myfaces.trinidad.util;
+
+import junit.framework.TestCase;
+
+import javax.faces.component.NamingContainer;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.myfaces.trinidad.component.UIXCommand;
+import org.apache.myfaces.trinidad.component.UIXInput;
+import org.apache.myfaces.trinidad.component.UIXPanel;
+import org.apache.myfaces.trinidad.component.UIXTable;
+
+public class FindRelativeComponentTest extends TestCase
+{
+  public static final Test suite()
+  {
+    return new TestSuite(FindRelativeComponentTest.class);
+  }
+  
+  public static void main(String[] args) throws Throwable
+  {
+    junit.textui.TestRunner.run(suite());
+  }
+
+  public FindRelativeComponentTest(
+    String testName)
+  {
+    super(testName);
+  }
+
+  static private class TestNamingContainer extends UIXPanel
+                                           implements NamingContainer
+  {
+
+  }
+
+  
+  // Test sibling components
+  @SuppressWarnings("unchecked")
+  public void testSiblingButtons()
+  {
+
+      UIXCommand button1 = new UIXCommand();
+      button1.setId("commandButton1");
+      UIXCommand button2 = new UIXCommand();
+      button2.setId("commandButton2");
+      UIXPanel rootPanel = new UIXPanel();
+      rootPanel.getChildren().add(button1);
+      rootPanel.getChildren().add(button2);
+      
+      UIComponent cmp = 
+          ComponentUtils.findRelativeComponent(button2, "commandButton1");
+      // old and new are the same
+      assertEquals(cmp, button1);
+      
+      cmp = ComponentUtils.findRelativeComponent(button2, "::::::commandButton1");
+      // old and new are the same
+      assertEquals(cmp, button1);
+
+    
+  }
+    
+  // Test sibling components where one is a table and one is a button
+  @SuppressWarnings("unchecked")
+  public void testSiblingWithTable()
+  {
+      // panel
+      //    table1
+      //       tableChild
+      //    button1 (table1 & button1 peers)
+      UIXCommand button1 = new UIXCommand();
+      button1.setId("commandButton1");
+  
+      UIXTable table1 = new UIXTable();
+      table1.setId("table1");
+      UIXPanel rootPanel = new UIXPanel();
+      rootPanel.getChildren().add(button1);
+      rootPanel.getChildren().add(table1);
+      UIXPanel tableChild = new UIXPanel();
+      tableChild.setId("tableChildId");
+      table1.getChildren().add(tableChild);
+      
+      
+      UIComponent cmp =
+        ComponentUtils.findRelativeComponent(table1,"::commandButton1");
+       // new & old (because  in old it starts from the viewRoot)
+      assertEquals(button1, cmp);
+      
+      cmp = ComponentUtils.findRelativeComponent(table1, "commandButton1");
+      // old & new are the same
+      // uses findComponent rules if it doesn't start with multiple colons
+      // - if this UIComponent is a NamingContainer it will serve as the basis.
+      assertEquals(null, cmp);
+      
+    cmp = ComponentUtils.findRelativeComponent(button1, "table1");
+    assertEquals(table1, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(button1, "tableChildId");
+    assertEquals(null, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(button1, "table1:tableChildId");
+    assertEquals(tableChild, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(table1, "tableChildId");
+    assertEquals(tableChild, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(tableChild, "table1");
+    assertEquals(table1, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(tableChild, ":commandButton1");
+    assertEquals(button1, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(tableChild, ":::commandButton1");
+    assertEquals(button1, cmp);
+    
+    cmp = ComponentUtils.findRelativeComponent(tableChild, "::commandButton1");   
+    assertEquals(button1, cmp); // new way
+    //assertEquals(null, cmp); // old way
+    
+
+  }
+    
+
+
+  @SuppressWarnings("unchecked")
+  public void testRelativeSearch()
+  {
+    /*<f:subview id="ncRoot">
+     *  <commandButton1>
+     *  <commandButton2>
+     *     <f:subview id="nc1">
+     *     <tr:inputText id="inputA" pT="::commandButton1"/>
+           <tr:panelGroupLayout>
+             <tr:inputText 
+             id="input1"
+             partialTriggers="::commandButton1"/>
+           </tr:panelGroupLayout>
+          </f:subview>
+       </f:subview>
+     */
+
+    // set up component hierarchy
+    UIForm form = new UIForm();
+    TestNamingContainer ncRoot = new TestNamingContainer(); ncRoot.setId("ncRoot");
+    UIXCommand button1 = new UIXCommand();
+    button1.setId("commandButton1");
+    UIXCommand button2 = new UIXCommand();
+    button2.setId("commandButton2");
+    
+    form.getChildren().add(ncRoot);
+    ncRoot.getChildren().add(button1);
+    ncRoot.getChildren().add(button2);
+      
+    TestNamingContainer nc = new TestNamingContainer(); nc.setId("nc1");
+    UIXInput inputA = new UIXInput(); inputA.setId("inputA");
+    UIXPanel panel = new UIXPanel(); panel.setId("panel1");
+    UIXInput input1 = new UIXInput(); input1.setId("input1");  
+    ncRoot.getChildren().add(nc);
+    nc.getChildren().add(inputA);
+    nc.getChildren().add(panel);
+    panel.getChildren().add(input1);
+      
+    // input1's parent is panel. panel's parent is nc1 (::) goes there. ::: goes to ncRoot
+    // in old way. New way pops OUT of nc1 with '::'.
+    UIComponent cmp =
+      ComponentUtils.findRelativeComponent(input1,":::commandButton1");
+    assertEquals(button1, cmp); // old way
+    // assertEquals(null, cmp); // new way (popped too far), so the code looks the old way
+    
+    cmp = ComponentUtils.findRelativeComponent(input1, "::::ncRoot:commandButton1");
+    assertEquals(button1, cmp); // old way & new way
+    
+    cmp = ComponentUtils.findRelativeComponent(input1, ":::ncRoot:commandButton1");
+    assertEquals(button1, cmp); // old way
+    
+    
+    // inputA's parent is nc1. ::  will get you there. : will pop you out. /old way
+    // :: will pop you out of nc1
+    cmp = ComponentUtils.findRelativeComponent(inputA, ":::commandButton1");
+    assertEquals(button1, cmp); // old way
+    //assertEquals(null, cmp);   // new way
+    
+    cmp = ComponentUtils.findRelativeComponent(inputA, "::ncRoot:commandButton1");
+    //assertEquals(null, cmp); // old way
+    assertEquals(button1, cmp);   // new way    
+ 
+  }
+
+
+}
+

Modified: myfaces/trinidad/trunk/trinidad-build/src/main/resources/META-INF/maven-faces-plugin/components/trinidad/core/includes/CommonAttrs.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-build/src/main/resources/META-INF/maven-faces-plugin/components/trinidad/core/includes/CommonAttrs.xml?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-build/src/main/resources/META-INF/maven-faces-plugin/components/trinidad/core/includes/CommonAttrs.xml (original)
+++ myfaces/trinidad/trunk/trinidad-build/src/main/resources/META-INF/maven-faces-plugin/components/trinidad/core/includes/CommonAttrs.xml Tue Feb 19 14:33:53 2008
@@ -58,20 +58,22 @@
       </property-extension>
     </property>
     <property>
-      <description><![CDATA[<p>the IDs of the components that should trigger a partial update.
+      <description><![CDATA[the IDs of the components that should trigger a partial update.
+        <p>
         This component will listen on the trigger components. If one of the
         trigger components receives an event that will cause it to update
         in some way, this component will request to be updated too.</p>
         <p>
-        Separate multiple triggers with a space.
-        Trigger identifiers are relative to the source component for non-NamingContainer components and relative to the parent component for NamingContainer components. 
+        Separate multiple triggers with a space. e.g., partialTriggers="cmp1 cmp2"
+        </p>
+        <p>
         Identifiers must account for NamingContainers.  You can use a single colon to start the search from the root,
         or use multiple colons to move up through the NamingContainer. For example,
-        for a non-NamingContainer component, "::" will
-        search from the parent naming container, ":::" will search
-        from the grandparent naming container, etc. For a NamingContainer component,
-        "::" will search from the parent component's parent naming container. ":::" will
-        search from the parent component's grandparent naming container.</p>]]>
+        "::" will pop out of this component's naming container (it pops out of itself if it is a naming container), 
+        ":::" will pop out of two naming containers, etc. The search for
+        the partialTrigger begins from there. e.g., partialTriggers=":::commandButton1" the search begins for the 
+        component with id = commandButton1 after popping out of two naming containers relative to this component.
+        To go into naming containers, you separate the naming containers with ':', e.g.,partialTriggers= "nc1:nc2:nc3:componentId".</p>]]>
       </description>
       <property-name>partialTriggers</property-name>
       <property-class>java.lang.String[]</property-class>

Added: myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/TestRelativePartialTriggers.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/TestRelativePartialTriggers.java?rev=629254&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/TestRelativePartialTriggers.java (added)
+++ myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/TestRelativePartialTriggers.java Tue Feb 19 14:33:53 2008
@@ -0,0 +1,238 @@
+package org.apache.myfaces.trinidaddemo;
+
+
+import java.awt.Color;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.faces.event.ValueChangeEvent;
+
+import org.apache.myfaces.trinidad.component.core.data.CoreTable;
+import org.apache.myfaces.trinidad.component.core.input.CoreInputText;
+import org.apache.myfaces.trinidad.component.core.nav.CoreCommandButton;
+import org.apache.myfaces.trinidad.component.core.output.CoreOutputText;
+import org.apache.myfaces.trinidad.event.SelectionEvent;
+
+public class TestRelativePartialTriggers {
+
+
+  public String commandButton1_action() 
+  {
+      // Add event code here...
+    if (commandButton2 != null)
+      commandButton2.setText("Found!");
+    if (inputText1 != null)
+      inputText1.setValue("inputText1 found commandButton1");
+    if (inputText2 != null)
+      inputText2.setValue("inputText2 found commandButton1");
+    if (inputText3 != null)
+      inputText3.setContentStyle("background-color:green");
+    if (inputText4 != null)
+      inputText4.setValue("inputText4 found commandButton1");
+    if (table1 != null)
+      table1.setInlineStyle("background-color: red");
+    if (table2 != null)
+      table2.setInlineStyle("background-color: aqua");    
+    
+    return null;
+  } 
+  
+  public String commandButton3_action() 
+  {
+
+    if (inputText1 != null)
+      inputText1.setValue("inputText1 found commandButton3");
+    if (inputText2 != null)
+      inputText2.setValue("inputText2 found commandButton3");
+    if (inputText3 != null)
+      inputText3.setDisabled(true);
+    // Add event code here...
+    if (table1 != null)
+      table1.setInlineStyle("background-color: pink");
+    
+    return null;
+  }  
+  
+  
+  public void setCommandButton2(CoreCommandButton cb2) 
+  {
+    this.commandButton2 = cb2;
+  }
+
+  public CoreCommandButton getCommandButton2() 
+  {
+    return commandButton2;
+  } 
+  
+  public void setInputText1(CoreInputText inputText1) 
+  {
+    this.inputText1 = inputText1;
+  }
+
+  public CoreInputText getInputText1() 
+  {
+    return inputText1;
+  }
+  
+  public void setInputText2(CoreInputText inputText2) 
+  {
+    this.inputText2 = inputText2;
+  }
+
+  public CoreInputText getInputText2() 
+  {
+    return inputText2;
+  }   
+  
+  public void setInputText3(CoreInputText inputText3) 
+  {
+    this.inputText3 = inputText3;
+  }
+
+  public CoreInputText getInputText3() 
+  {
+    return inputText3;
+  }
+  
+  public void setInputText4(CoreInputText inputText4) 
+  {
+    this.inputText4 = inputText4;
+  }
+
+  public CoreInputText getInputText4() 
+  {
+    return inputText4;
+  } 
+  
+  public void setTable1(CoreTable table1) 
+  {
+    this.table1 = table1;
+  }
+
+  public CoreTable getTable1() 
+  {
+    return table1;
+  }  
+  
+  public void setTable2(CoreTable table2) 
+  {
+    this.table2 = table2;
+  }
+
+  public CoreTable getTable2() 
+  {
+    return table2;
+  }   
+  
+  public List<Person> getTableData() 
+  {
+    if (tableData == null)
+    {
+      tableData = new ArrayList<Person>();
+      tableData.add(new Person("Bob"));
+      tableData.add(new Person("Kat"));
+    }
+    return tableData;
+  }
+
+  public String commandButton4_action()
+  {
+    // Add event code here...
+    // refresh the table
+    if (table1 != null)
+      table1.setInlineStyle("background-color: gold");
+    return null;
+  }
+  
+  public String getInputText5Value()
+  {
+    return inputText5Value;
+  }
+
+  public void setInputText5Value(String value)
+  {
+    inputText5Value = value;
+  }
+  
+  /* table demo (between columns), in/out of table, etc */
+  public void setOutputText1x(CoreOutputText outputText1x) {
+    this.outputText1x = outputText1x;
+  }
+
+  public CoreOutputText getOutputText1x() {
+    return outputText1x;
+  } 
+  
+  public void setCommandButton1x(CoreCommandButton cb1x) 
+  {
+    this.commandButton1x = cb1x;
+  }
+
+  public CoreCommandButton getCommandButton1x() 
+  {
+    return commandButton1x;
+  } 
+  
+  public void input1xChanged(ValueChangeEvent vce)
+  {
+    if (outputText1x != null)
+      outputText1x.setInlineStyle("color: red");   
+    if (commandButton1x != null)
+      commandButton1x.setInlineStyle("color: red");
+ 
+  }
+  
+  public String commandButton1x_action() 
+  {
+    if (outputText1x != null)
+      outputText1x.setInlineStyle("color: pink");  
+    return null;
+  }
+  
+  public void tableRowSelected(SelectionEvent se)
+  {
+    if (outputText1x != null)
+      outputText1x.setInlineStyle("color: aqua"); 
+    if (commandButton1x != null)
+      commandButton1x.setInlineStyle("color: aqua"); 
+  }
+  
+
+  public static class Person 
+  {
+    public Person(String name)
+    {
+      _name = name;
+    }
+    private String _name;
+    
+    public String getName()
+    {
+      return _name;
+    }
+    
+    public void setName(String name)
+    {
+      _name = name;
+    }
+  }
+  private CoreCommandButton commandButton2;
+  private CoreInputText inputText1;
+  private CoreInputText inputText2;   
+  private CoreInputText inputText3;
+  private CoreInputText inputText4;
+  private String         inputText5Value;
+
+  private CoreTable table1;
+  private CoreTable table2;  
+  private List<Person> tableData;
+  
+  // table specific demos (between columns, etc)
+  private CoreOutputText outputText1x;
+  private CoreCommandButton commandButton1x;
+
+  
+
+}

Modified: myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml (original)
+++ myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml Tue Feb 19 14:33:53 2008
@@ -3056,4 +3056,9 @@
     <managed-bean-class>org.apache.myfaces.trinidaddemo.DemoShowDetailDisclosureBean</managed-bean-class>
     <managed-bean-scope>request</managed-bean-scope>
   </managed-bean>
+  <managed-bean>
+    <managed-bean-name>testTriggers</managed-bean-name>
+    <managed-bean-class>org.apache.myfaces.trinidaddemo.TestRelativePartialTriggers</managed-bean-class>
+    <managed-bean-scope>request</managed-bean-scope>
+  </managed-bean>
 </faces-config>

Modified: myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/pprDemos.jspx
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/pprDemos.jspx?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/pprDemos.jspx (original)
+++ myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/pprDemos.jspx Tue Feb 19 14:33:53 2008
@@ -245,10 +245,9 @@
        <tr:panelHeader text="Naming container tests; partial triggers are the previous command components with partialSubmit"> 
          <tr:panelGroupLayout layout="vertical">
            <f:subview id="sub">
-             <!-- use '::' in front of the identifier to get to the parent naming
-             container, add ':::' to get to the grandparent naming container, etc.
-             This works for non-Naming Container components. -->
-             <tr:outputFormatted  partialTriggers=":::pSub_link :::pSub_button"
+             <!-- use '::' in front of the identifier to pop out of the current naming container.
+             Additional colons continue to pop. -->
+             <tr:outputFormatted  partialTriggers="::pSub_link ::pSub_button"
                                   styleUsage="instruction"
                                   value="#{partialDemoUtil.status.linkUpdate}">
                <f:convertDateTime pattern="HH:mm:ss"/>
@@ -259,7 +258,7 @@
              This works for non-Naming Container components. -->
            <f:subview id="sub2">
             <f:subview id="sub3">
-             <tr:outputFormatted  partialTriggers="::::pSub_link ::::pSub_button"
+             <tr:outputFormatted  partialTriggers=":::pSub_link :::pSub_button"
                                   styleUsage="instruction"
                                   value="#{partialDemoUtil.status.linkUpdate}">
                <f:convertDateTime pattern="HH:mm:ss"/>
@@ -284,6 +283,10 @@
           <tr:selectItem label="Index" value="/index.jspx"/>
           <tr:selectItem label="Component Demos" value="/componentDemos.jspx"/>
          </tr:selectOneChoice>
+       </tr:panelHeader>
+        <tr:panelHeader text="More ppr demos showing partialTriggers syntax with regard to NamingContainers.">
+        <tr:goLink text="Relative Partial Triggers Demo"
+                destination="testRelativePartialTriggers.jspx" />      
        </tr:panelHeader>
       </tr:panelGroupLayout>
      </tr:panelHeader>

Added: myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx?rev=629254&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx (added)
+++ myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx Tue Feb 19 14:33:53 2008
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you 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.
+	   
+-->
+<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
+          xmlns:f="http://java.sun.com/jsf/core"
+          xmlns:h="http://java.sun.com/jsf/html"
+          xmlns:trh="http://myfaces.apache.org/trinidad/html"
+          xmlns:tr="http://myfaces.apache.org/trinidad">
+  <jsp:directive.page contentType="text/html;charset=utf-8"/>
+  <f:view>
+    <tr:document title="Partial Page Rendering Demos">
+      <tr:form>
+        <tr:panelPage>
+          <f:facet name="navigationGlobal">
+            <tr:navigationPane hint="buttons">
+              <tr:commandNavigationItem text="Return to Feature Demos page"
+                                        immediate="true" action="demos"/>
+              <tr:commandNavigationItem text="Return to PPR Demo page"
+                                  immediate="true"
+                                  action="demos.ppr"/>
+            </tr:navigationPane>
+          </f:facet>
+          <tr:outputText  styleClass="AFInstructionText" 
+            value="This tests the syntax for partialTriggers. :: pops you out of the current NamingContainer 
+            including yourself if you are a naming container. Each additional colon pops out of a NamingContainer."/>
+          <tr:separator/>
+          <f:subview id="nc1">
+            <tr:commandButton text="commandButton 1" partialSubmit="true"
+                              id="commandButton1"
+                              action="#{testTriggers.commandButton1_action}"/>
+            <tr:commandButton text="commandButton 2"
+                              binding="#{testTriggers.commandButton2}"
+                              id="commandButton2"
+                              partialTriggers="commandButton1"/>
+            <f:subview id="nc2">
+              <tr:panelGroupLayout>
+                <tr:inputText label="Label 1"
+                              binding="#{testTriggers.inputText1}"
+                              id="inputText1"
+                              partialTriggers="::commandButton1 ::nc4:table1:commandButton3"/>
+              </tr:panelGroupLayout>
+            </f:subview>
+            <f:subview id="nc3">
+              <tr:inputText label="Label 2" binding="#{testTriggers.inputText2}"
+                            id="inputText2"
+                            partialTriggers="::commandButton1 ::nc4:table1:commandButton3"/>
+            </f:subview>
+            <f:subview id="nc4">
+              <tr:table value="#{testTriggers.tableData}" id="table1" var="row"
+                        partialTriggers=":::commandButton1 commandButton3  ::commandButton4"
+                        binding="#{testTriggers.table1}">
+                <tr:column headerText="Column">
+                  <tr:panelGroupLayout>
+                    <tr:inputText value="#{row.name}" id="inputText3"
+                                  binding="#{testTriggers.inputText3}"
+                                  partialTriggers=":::commandButton1 commandButton3"/>
+                    <tr:commandButton text="Make table pink"
+                                      action="#{testTriggers.commandButton3_action}"
+                                      id="commandButton3" partialSubmit="true"/>
+                  </tr:panelGroupLayout>
+                </tr:column>
+              </tr:table>
+              <tr:commandButton text="Make table gold"
+                                action="#{testTriggers.commandButton4_action}"
+                                id="commandButton4" partialSubmit="true"/>
+            </f:subview>
+            <tr:separator/>
+            <tr:panelGroupLayout layout="vertical">
+              <tr:outputText styleClass="AFInstructionText"
+                             value="table's partialTrigger is the first command button on the page. Nobody is listening for the inputText's to change."/>                                
+            </tr:panelGroupLayout>
+            <f:subview id="nc5">
+              <tr:panelHeader text="Header">
+                <tr:table value="#{testTriggers.tableData}" id="table2"
+                          var="row" partialTriggers=":::commandButton1"
+                          binding="#{testTriggers.table2}">
+                  <tr:column headerText="Table2Column">
+                    <tr:inputText value="#{row.name}" id="inputText4" autoSubmit="true"/>
+                  </tr:column>
+                </tr:table>
+              </tr:panelHeader>
+            </f:subview>
+            
+            <!-- type in inputText, outputText should turn red, commandButton's color turns red --> 
+            <!-- click on the button, the outputText should turn pink -->
+            <!-- select a row in the table, and the outputText should turn aqua -->
+            <tr:panelGroupLayout layout="vertical">
+              <tr:outputText styleClass="AFInstructionText"
+                             value="type in inputText, outputText should turn red, commandButton's color turns red"/>
+              <tr:outputText styleClass="AFInstructionText"
+                             value="click on the button, the outputText should turn pink"/>  
+              <tr:outputText styleClass="AFInstructionText"
+                             value="select a row in the table, and the outputText should turn aqua, button color turns aqua"/>                                
+            </tr:panelGroupLayout>
+            <tr:commandButton id="commandButton1x" action="#{testTriggers.commandButton1x_action}" text="Make output pink"
+              binding="#{testTriggers.commandButton1x}"
+              partialTriggers="table1x:inputText1x table1x"/>
+            <tr:table id="table1x" value="#{testTriggers.tableData}" autoSubmit="true" rowSelection="single" selectionListener="#{testTriggers.tableRowSelected}" >
+                <tr:column>
+                    <tr:inputText id="inputText1x" autoSubmit="true" valueChangeListener="#{testTriggers.input1xChanged}"/>
+                </tr:column>
+                <tr:column>
+                    <tr:outputText id="outputText1x" partialTriggers="inputText1x ::commandButton1x ::table1x" value="hello, outputText"
+                                  binding ="#{testTriggers.outputText1x}"/>
+                </tr:column>
+            </tr:table>
+
+          </f:subview>
+          
+        <!-- a couple of ways you can do the same thing -->
+        <tr:panelGroupLayout layout="vertical">
+          <tr:outputText styleClass="AFInstructionText"
+                             value="type in inputText, and see the value in the fields below"/>                          
+        </tr:panelGroupLayout>
+        <tr:subform id="autosf">
+          <tr:inputText autoSubmit="true" id="inputText5" label="inputText"
+                         value="#{testTriggers.inputText5Value}"/>
+          <tr:inputText partialTriggers="inputText5" label="value submitted" id="xxxxx" readOnly="true"
+                         value="#{testTriggers.inputText5Value}"/>
+          <tr:inputText partialTriggers="::autosf:inputText5" label="value submitted" id="xxxxxy" readOnly="true"
+                         value="#{testTriggers.inputText5Value}"/>   
+          <tr:inputText partialTriggers=":::::::autosf:inputText5" label="value submitted" id="xxxxxz" readOnly="true"
+                         value="#{testTriggers.inputText5Value}"/>                           
+        </tr:subform>
+           <tr:inputText partialTriggers="autosf:inputText5" label="value submitted out of subform" id="xxxxxza" readOnly="true"
+                         value="#{testTriggers.inputText5Value}"/>       
+        
+        </tr:panelPage>
+
+      </tr:form>
+    </tr:document>
+  </f:view>
+</jsp:root>
+

Added: myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggersPrevRelease.jspx
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggersPrevRelease.jspx?rev=629254&view=auto
==============================================================================
--- myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggersPrevRelease.jspx (added)
+++ myfaces/trinidad/trunk/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggersPrevRelease.jspx Tue Feb 19 14:33:53 2008
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you 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.
+	   
+-->
+<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
+          xmlns:f="http://java.sun.com/jsf/core"
+          xmlns:h="http://java.sun.com/jsf/html"
+          xmlns:trh="http://myfaces.apache.org/trinidad/html"
+          xmlns:tr="http://myfaces.apache.org/trinidad">
+  <jsp:directive.page contentType="text/html;charset=utf-8"/>
+  <f:view>
+    <tr:document title="Partial Page Rendering Demos, previous release syntax (backward-compatible)">
+      <tr:form>
+        <tr:panelPage>
+          <f:facet name="navigationGlobal">
+            <tr:navigationPane hint="buttons">
+              <tr:commandNavigationItem text="Return to Feature Demos page"
+                                        immediate="true" action="demos"/>
+              <tr:commandNavigationItem text="Return to PPR Demo page"
+                                        immediate="true" action="demos.ppr"/>                                       
+            </tr:navigationPane>
+          </f:facet>
+          <tr:outputText styleClass="AFInstructionText" 
+            value="This tests the DEPRECATED syntax for partialTriggers. It's meant as a test for backward compatibility.
+            You will see warnings in the console for using deprecated syntax."/>
+          <tr:goLink destination="testRelativePartialTriggers.jspx" text="Go to SUPPORTED syntax test page"/>
+          <tr:separator/>
+          <f:subview id="nc1">
+            <tr:commandButton text="commandButton 1" partialSubmit="true"
+                              id="commandButton1"
+                              action="#{testTriggers.commandButton1_action}"/>
+            <tr:commandButton text="commandButton 2"
+                              binding="#{testTriggers.commandButton2}"
+                              id="commandButton2"
+                              partialTriggers="commandButton1"/>
+            <f:subview id="nc2">
+              <tr:panelGroupLayout>
+                <tr:inputText label="Label 1"
+                              binding="#{testTriggers.inputText1}"
+                              id="inputText1"
+                              partialTriggers=":::commandButton1 :::nc4:table1:commandButton3"/>
+              </tr:panelGroupLayout>
+            </f:subview>
+            <f:subview id="nc3">
+              <tr:inputText label="Label 2" binding="#{testTriggers.inputText2}"
+                            id="inputText2"
+                            partialTriggers=":::commandButton1 :::nc4:table1:commandButton3"/>
+            </f:subview>
+            <f:subview id="nc4">
+              <tr:table value="#{testTriggers.tableData}" id="table1" var="row"
+                        partialTriggers="::commandButton1 table1:commandButton3 commandButton4"
+                        binding="#{testTriggers.table1}">
+                <tr:column headerText="Column">
+                  <tr:panelGroupLayout>
+                    <tr:inputText value="#{row.name}" id="inputText3"
+                                  binding="#{testTriggers.inputText3}"
+                                  partialTriggers=":::commandButton1 commandButton3"/>
+                    <tr:commandButton text="Refresh table"
+                                      action="#{testTriggers.commandButton3_action}"
+                                      id="commandButton3" partialSubmit="true"/>
+                  </tr:panelGroupLayout>
+                </tr:column>
+              </tr:table>
+              <tr:commandButton text="Make table gold"
+                                action="#{testTriggers.commandButton4_action}"
+                                id="commandButton4" partialSubmit="true"/>
+            </f:subview>
+            <tr:separator/>
+            <f:subview id="nc5">
+              <tr:panelHeader text="Header">
+                <tr:table value="#{testTriggers.tableData}" id="table2"
+                          var="row" partialTriggers=":::commandButton1"
+                          binding="#{testTriggers.table2}">
+                  <tr:column headerText="Table2Column">
+                    <tr:inputText value="#{row.name}" id="inputText4"/>
+                  </tr:column>
+                </tr:table>
+              </tr:panelHeader>
+            </f:subview>
+            
+               
+             <!-- type in inputText, outputText should turn red, commandButton's color turns red --> 
+            <!-- click on the button, the outputText should turn pink -->
+            <!-- select a row in the table, and the outputText should turn aqua -->
+            <tr:panelGroupLayout layout="vertical">
+              <tr:outputText styleClass="AFInstructionText"
+                             value="type in inputText, outputText should turn red, commandButton's color turns red"/>
+              <tr:outputText styleClass="AFInstructionText"
+                             value="click on the button, the outputText should turn pink"/>  
+              <tr:outputText styleClass="AFInstructionText"
+                             value="select a row in the table, and the outputText should turn aqua, button color turns aqua"/>                                
+            </tr:panelGroupLayout>
+            <tr:commandButton id="commandButton1x" action="#{testTriggers.commandButton1x_action}" text="Make output pink"
+              binding="#{testTriggers.commandButton1x}"
+              partialTriggers="table1x:inputText1x table1x"/>
+            <tr:table id="table1x" value="#{testTriggers.tableData}" autoSubmit="true" rowSelection="single" selectionListener="#{testTriggers.tableRowSelected}" >
+                <tr:column>
+                    <tr:inputText id="inputText1x" autoSubmit="true" valueChangeListener="#{testTriggers.input1xChanged}"/>
+                </tr:column>
+                <tr:column>
+                    <tr:outputText id="outputText1x" partialTriggers="::inputText1x :::commandButton1x :::table1x" value="hello, outputText"
+                                  binding ="#{testTriggers.outputText1x}"/>
+                </tr:column>
+            </tr:table>           
+          </f:subview>
+        </tr:panelPage>
+      </tr:form>
+    </tr:document>
+  </f:view>
+</jsp:root>
+

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java Tue Feb 19 14:33:53 2008
@@ -550,31 +550,23 @@
       // the old ADF Faces rules, and now we should stick with it for
       // backwards compatibility even within Trinidad)
       
-      // The rule is "if the component is a naming container, search relative 
-      // to the parent; otherwise, search relative to the component." In the
-      // non-naming container case, if it fails, then search relative to the 
-      // parent, for backwards compatibility only, since we were always 
-      // searching relative to the parent.
-      UIComponent from;
-      boolean isNamingContainer = false;
+      UIComponent master = ComponentUtils.findRelativeComponent(listener, trigger);
+      
       boolean deprecatedFind = false;
-      if (listener instanceof NamingContainer)
+    
+      if (master == null)
       {
-        from = listener.getParent();
-        isNamingContainer = true;
-      }
-      else
-        from = listener;
-        
-      UIComponent master = ComponentUtils.findRelativeComponent(from, trigger);
-      
-      if (master == null && !isNamingContainer)
+        UIComponent from = listener;
+        // backward compatible code
+        // The old rule is "if the component is a naming container, search relative 
+        // to the parent; otherwise, search relative to the component." 
+      if (listener instanceof NamingContainer)
       {
-        // for backwards compatibility, look from the parent.
         from = listener.getParent();
         master = ComponentUtils.findRelativeComponent(from, trigger);
         deprecatedFind = true;
       }
+      }
 
       if (master == null)
       {
@@ -582,11 +574,11 @@
       }
       else
       {
-        // if we found this with the deprecated method of searching relative to
-        // the component's parent, then warn the user to change their syntax.
+        // if we found this with the deprecated method, 
+        // then warn the user to change their syntax.
         if (deprecatedFind)
         {
-          _LOG.warning("DEPRECATED_PARTIAL_TRIGGER_SYNTAX", 
+          _LOG.warning("DEPRECATED_TRIGGER_SYNTAX", 
             new Object[] {trigger, listener});
         }
       

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts Tue Feb 19 14:33:53 2008
@@ -1053,8 +1053,8 @@
 <!-- INVALID_TIMEZONE_IN_CONFIG -->
 <resource key="INVALID_TIMEZONE_IN_CONFIG">The trinidad-config.xml contains an invalid value for time-zone ({0}). The default timezone will be used instead.</resource>
 
-<!-- DEPRECATED_PARTIAL_TRIGGER_SYNTAX -->
-<resource key="DEPRECATED_PARTIAL_TRIGGER_SYNTAX">Could not find partial trigger {0} from {1} searching relative to the component. The partial trigger was found relative to the component's parent but this is deprecated. Change the partial trigger to be relative to component, not relative to parent.</resource>
+<!-- DEPRECATED_TRIGGER_SYNTAX -->
+<resource key="DEPRECATED_TRIGGER_SYNTAX">Could not find partial trigger {0} from {1} with the supported partialTriggers syntax. The partial trigger was found with the deprecated syntax. Please use the supported syntax.</resource>
 
 <!-- DATETIMERANGEVALIDATOR_REQUIRES_VALUEHOLDER -->
 <resource key="DATETIMERANGEVALIDATOR_REQUIRES_EDITABLEVALUEHOLDER">The DateTimeRangeValidator requires the component to be an EditableValueHolder for client validation to work. Client validation will be disabled for component {0}.</resource>

Modified: myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/CoreRenderKitTest.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/CoreRenderKitTest.java?rev=629254&r1=629253&r2=629254&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/CoreRenderKitTest.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/CoreRenderKitTest.java Tue Feb 19 14:33:53 2008
@@ -6,9 +6,9 @@
  *  to you 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
@@ -36,6 +36,7 @@
 import org.apache.myfaces.trinidad.component.core.CoreForm;
 import org.apache.myfaces.trinidad.component.html.HtmlHtml;
 import org.apache.myfaces.trinidad.context.RequestContext;
+import org.apache.myfaces.trinidad.render.RenderUtils;
 
 import org.apache.myfaces.trinidadinternal.renderkit.core.CoreRenderKit;
 
@@ -74,14 +75,14 @@
     UIViewRoot  root,
     TestScript  script)
   {
-    String componentType = 
+    String componentType =
            script.getDefinition().getComponentInfo().componentType;
 
     if ("org.apache.myfaces.trinidad.HtmlHtml".equals(componentType))
     {
       return root;
     }
-    
+
     if (_sHtmlComponents.contains(componentType))
     {
       HtmlHtml html = new HtmlHtml();
@@ -114,6 +115,13 @@
     Logger logger = Logger.getLogger(CoreRenderKit.class.getName());
     logger.setLevel(Level.SEVERE);
     logger.setUseParentHandlers(false);
+    // Force the RenderUtils logger level to SEVERE to bypass the
+    // warnings in getRelativeId method when the component
+    // with the relativeId could not be found which is the case in our
+    // render kit rendering tests.
+    Logger loggerTwo = Logger.getLogger(RenderUtils.class.getName());
+    loggerTwo.setLevel(Level.SEVERE);
+    loggerTwo.setUseParentHandlers(false);
 
     _definitions.add(new SuiteDefinition("minimal",
                                          "minimal",