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/14 19:01:30 UTC
svn commit: r627816 - in /myfaces/trinidad/branches/jwaldman_1.2-issue936:
trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/
trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/
trinidad-api/src/test/java/org/apache/myfaces/trinida...
Author: jwaldman
Date: Thu Feb 14 10:01:21 2008
New Revision: 627816
URL: http://svn.apache.org/viewvc?rev=627816&view=rev
Log:
change RenderUtils.java's getRelativeId method to work the same way as ComponentUtils's findRelativeComponent method in that '::' pops out one naming container, ':::' pops out two, etc.
Also added a render/RenderUtilsTest.java test
Added:
myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/test/java/org/apache/myfaces/trinidad/render/
myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/test/java/org/apache/myfaces/trinidad/render/RenderUtilsTest.java
Modified:
myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java
myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java
myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx
Modified: myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java?rev=627816&r1=627815&r2=627816&view=diff
==============================================================================
--- myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java (original)
+++ myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/RenderUtils.java Thu Feb 14 10:01:21 2008
@@ -24,6 +24,7 @@
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.component.UIForm;
+import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import org.apache.myfaces.trinidad.component.UIXForm;
@@ -102,67 +103,125 @@
}
/**
- * 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 an ID 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
+ *
+ * <f:subview id="aaa">
+ <f:subview id="xxx">
+ <tr:chooseColor id="cp1" .../>
+ <f:subview id="yyy">
+ <tr:inputColor id="sic1" chooseId="::cp1" .../>
+ </f:subview>
+ </f:subview>
+ </f:subview>
+ * 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.
+ *
+ * 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. A relativeId with ':::' pops up two naming containers, etc.
+ * 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.
+ *
+ * </p>
+ * @param context
+ * @param from
+ * @param relativeId
+ * @return
*/
public static String getRelativeId(
FacesContext context,
UIComponent from,
String relativeId)
{
+ if (from == null)
+ return null;
+
if ((relativeId == null) || (relativeId.length() == 0))
return null;
- UIComponent parentNC;
- if (relativeId.charAt(0) == NamingContainer.SEPARATOR_CHAR)
+ int idLength = relativeId.length();
+ // Figure out how many colons
+ int colonCount = 0;
+ while (colonCount < idLength)
{
- if (relativeId.length() > 1 && relativeId.charAt(1)
- == NamingContainer.SEPARATOR_CHAR)
- {
- 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);
- }
+ if (relativeId.charAt(colonCount) != NamingContainer.SEPARATOR_CHAR)
+ break;
+ colonCount++;
}
+
+ // 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)
+ 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
{
- parentNC = _getParentNamingContainer(from.getParent());
- if (parentNC == null)
- {
- return relativeId;
- }
+ return (from.getClientId(context) +
+ NamingContainer.SEPARATOR_CHAR + relativeId);
}
- return (parentNC.getClientId(context) +
- NamingContainer.SEPARATOR_CHAR + relativeId);
}
- private static UIComponent _getParentNamingContainer(UIComponent from)
+ // 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)
+
+ while (from != null && from.getParent() != null)
{
+ from = from.getParent();
if (from instanceof NamingContainer)
return from;
- from = from.getParent();
}
return null;
}
+
+
}
Modified: myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java?rev=627816&r1=627815&r2=627816&view=diff
==============================================================================
--- myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java (original)
+++ myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ComponentUtils.java Thu Feb 14 10:01:21 2008
@@ -395,6 +395,7 @@
// 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)
{
Added: myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/test/java/org/apache/myfaces/trinidad/render/RenderUtilsTest.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/test/java/org/apache/myfaces/trinidad/render/RenderUtilsTest.java?rev=627816&view=auto
==============================================================================
--- myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/test/java/org/apache/myfaces/trinidad/render/RenderUtilsTest.java (added)
+++ myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-api/src/test/java/org/apache/myfaces/trinidad/render/RenderUtilsTest.java Thu Feb 14 10:01:21 2008
@@ -0,0 +1,199 @@
+/*
+ * 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.component;
+
+
+import javax.faces.component.NamingContainer;
+
+import javax.faces.context.FacesContext;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.myfaces.trinidad.render.RenderUtils;
+
+
+public class RenderUtilsTest extends TestCase
+{
+ public static final Test suite()
+ {
+ return new TestSuite(RenderUtilsTest.class);
+ }
+
+ public static void main(String[] args) throws Throwable
+ {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public RenderUtilsTest(
+ String testName)
+ {
+ super(testName);
+ }
+
+ static private class TestNamingContainer extends UIXPanel
+ implements NamingContainer
+ {
+ @Override
+ public String getClientId(FacesContext context)
+ {
+ // NOTE - client ids cannot be cached because the generated
+ // value has to be dynamically calculated in some cases (UIData)
+
+ String clientId = getId() + "_Client";
+ return clientId;
+ }
+ }
+
+ static private class TestUIXPanel extends UIXPanel
+ {
+ @Override
+ public String getClientId(FacesContext context)
+ {
+ // NOTE - client ids cannot be cached because the generated
+ // value has to be dynamically calculated in some cases (UIData)
+
+ String clientId = getId() + "_Client";
+ return clientId;
+ }
+ }
+
+
+ // Test sibling components where one is a table and one is a button
+ @SuppressWarnings("unchecked")
+ public void testButtonAndNamingContainerSiblings()
+ {
+ // set up a button and a table that are siblings
+ // under a rootPanel (not a naming container)
+ // no naming containers above these components.
+ UIXCommand button1 = new UIXCommand();
+ button1.setId("commandButton1");
+
+ TestNamingContainer table1 = new TestNamingContainer();
+ table1.setId("table1");
+ TestUIXPanel rootPanel = new TestUIXPanel();
+ rootPanel.setId("rootPanel");
+ rootPanel.getChildren().add(button1);
+ rootPanel.getChildren().add(table1);
+
+ String relativeId =
+ RenderUtils.getRelativeId(null, button1, "table1");
+ assertEquals("table1", relativeId);
+
+ // to get to the commandButton from the table, you need to pop out of the
+ // table.
+ relativeId =
+ RenderUtils.getRelativeId(null, table1, "::commandButton1");
+ assertEquals("commandButton1", relativeId);
+
+ relativeId =
+ RenderUtils.getRelativeId(null, table1, ":commandButton1");
+ assertEquals("commandButton1", relativeId);
+
+ relativeId =
+ RenderUtils.getRelativeId(null, button1, ":table1");
+ assertEquals("table1", relativeId);
+
+
+ }
+
+
+
+ @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"
+ for="::commandButton1"/>
+ </tr:panelGroupLayout>
+ </f:subview>
+ </f:subview>
+ */
+
+ // set up component hierarchy
+ UIXForm form = new UIXForm(); form.setId("formId");
+ TestNamingContainer ncRoot = new TestNamingContainer(); ncRoot.setId("ncRoot");
+ UIXCommand button1 = new UIXCommand();
+ button1.setId("button1");
+ UIXCommand button2 = new UIXCommand();
+ button2.setId("button2");
+
+ 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 panel1 = new UIXPanel(); panel1.setId("panel1");
+ UIXInput input1 = new UIXInput(); input1.setId("input1");
+ ncRoot.getChildren().add(nc);
+ nc.getChildren().add(inputA);
+ nc.getChildren().add(panel1);
+ panel1.getChildren().add(input1);
+
+
+ String relativeId =
+ RenderUtils.getRelativeId(null, input1, "::button1");
+ // old way
+ //assertEquals("nc1_Client:button1", relativeId);
+
+ // new way should pop OUT of this with two ::
+ assertEquals("ncRoot_Client:button1", relativeId);
+
+
+ relativeId =
+ RenderUtils.getRelativeId(null, input1, ":::button1");
+ // old way
+ //assertEquals("ncRoot_Client:button1", relativeId);
+
+ // new way should pop OUT of both NC with two :::
+ assertEquals("button1", relativeId);
+
+ relativeId =
+ RenderUtils.getRelativeId(null, input1, "::::button1");
+
+ // old way returns the original id (THIS IS A BUG).
+ //assertEquals(":::::button1", relativeId);
+
+ // new way should return this
+ assertEquals("button1", relativeId);
+
+ relativeId =
+ RenderUtils.getRelativeId(null, input1, ":::::button1");
+
+ // old way returns the original id (THIS IS A BUG).
+ //assertEquals(":::::button1", relativeId);
+
+ // new way should return this
+ assertEquals("button1", relativeId);
+ }
+
+
+
+}
Modified: myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx?rev=627816&r1=627815&r2=627816&view=diff
==============================================================================
--- myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx (original)
+++ myfaces/trinidad/branches/jwaldman_1.2-issue936/trinidad-examples/trinidad-demo/src/main/webapp/demos/testRelativePartialTriggers.jspx Thu Feb 14 10:01:21 2008
@@ -135,7 +135,9 @@
<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}"/>
+ value="#{testTriggers.inputText5Value}"/>
+ <tr:inputText partialTriggers=":::::::autosf:inputText5" label="value submitted" id="xxxxxz" readOnly="true"
+ value="#{testTriggers.inputText5Value}"/>
</tr:subform>