dev@javaserverfaces.java.net

Seeking Review: 1757-DynamicAddRemove

From: Ed Burns <edburns_at_sun.com>
Date: Mon, 9 Aug 2010 13:40:57 -0700

https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1757


Ensure that Facelets mark and sweep algorithm correctly handles dynamically created components https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1757


SECTION: Modified Files
----------------------------
M jsf-ri/src/main/java/com/sun/faces/context/StateContext.java

- Change the use of the private DYNAMIC_COMPONENT component attribute key
  slightly. Used to be the value for this key was Boolean.TRUE. Now
  it's the integer indicating the index of the dynamic component in its
  parent's children list.

- Leverage the new meaning of private DYNAMIC_COMPONENT component
  attribute key to implement the new method
  getIndexOfDynamicallyAddedChildInParent().

- Add a new private component attribute key, HAS_ONE_OR_MORE_DYNAMIC_CHILD.

- Add methods that use this private component attribute key:

+ public boolean hasOneOrMoreDynamicChild(UIComponent parent) {

- This is used in ComponentTagTandlerDelegateImpl.adjustIndexOfDynamicChildren()
  to avoid even looking at the children list if there are no dynamic children.

+ private int incrementDynamicChildCount(UIComponent parent) {
+ private int decrementDynamicChildCount(UIComponent parent) {

- these are used in the AddRemoveListener.handle{Add,Remove}Event()
  methods.

M jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentTagHandlerDelegateImpl.java

- in apply() just after we call addComponentToView(), call
  adjustIndexOfDynamicChildren().

- new method adjustIndexOfDynamicChildren(). This is the heart of the
  fix. Because dynamic children have no facelet tag handler, we have to
  account for them somewhere in the mark and sweep system of Facelets.

M jsf-ri/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java

- This one line change is enormously significant. Always track view
  modifications, regardless of state saving mode.

M jsf-ri/systest/build-tests.xml
M jsf-ri/systest/web/WEB-INF/source1.taglib.xml
A jsf-ri/systest/src/com/sun/faces/systest/dynamic1757
A jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/UITestComponent.java
A jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757DynamicManagedBean.java
A jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757TestCase.java
A jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/TestComponentRenderer.java
A jsf-ri/systest/web/facelets/issue1757-dynamic-components.xhtml

- Test essentially contributed by Richard Kennard

SECTION: Diffs
----------------------------
Index: jsf-ri/src/main/java/com/sun/faces/context/StateContext.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/context/StateContext.java (revision 8541)
+++ jsf-ri/src/main/java/com/sun/faces/context/StateContext.java (working copy)
@@ -66,6 +66,8 @@
     private static final String KEY = StateContext.class.getName() + "_KEY";
     private static final String DYNAMIC_COMPONENT =
             StateContext.class.getName() + "_DYNAMIC_COMPONENT";
+ private static final String HAS_ONE_OR_MORE_DYNAMIC_CHILD =
+ StateContext.class.getName() + "_HAS_ONE_OR_MORE_DYNAMIC_CHILD";
 
 
     private boolean partial;
@@ -204,7 +206,48 @@
 
     }
 
+ public int getIndexOfDynamicallyAddedChildInParent(UIComponent c) {
+ int result = -1;
+ Map<String, Object> attrs = c.getAttributes();
+ if (attrs.containsKey(DYNAMIC_COMPONENT)) {
+ result = (Integer) attrs.get(DYNAMIC_COMPONENT);
+ }
+ return result;
+ }
 
+ public boolean hasOneOrMoreDynamicChild(UIComponent parent) {
+ return parent.getAttributes().containsKey(HAS_ONE_OR_MORE_DYNAMIC_CHILD);
+ }
+
+ private int incrementDynamicChildCount(UIComponent parent) {
+ int result = 0;
+ Map<String, Object> attrs = parent.getAttributes();
+ Integer cur;
+ if (null != (cur = (Integer) attrs.get(HAS_ONE_OR_MORE_DYNAMIC_CHILD))) {
+ result = cur++;
+ } else {
+ result = 1;
+ }
+ attrs.put(HAS_ONE_OR_MORE_DYNAMIC_CHILD, (Integer) result);
+
+ return result;
+ }
+
+ private int decrementDynamicChildCount(UIComponent parent) {
+ int result = 0;
+ Map<String, Object> attrs = parent.getAttributes();
+ Integer cur;
+ if (null != (cur = (Integer) attrs.get(HAS_ONE_OR_MORE_DYNAMIC_CHILD))) {
+ result = (0 < cur) ? cur-- : 0;
+
+ }
+ if (0 == result && null != cur){
+ attrs.remove(HAS_ONE_OR_MORE_DYNAMIC_CHILD);
+ }
+
+ return result;
+ }
+
     /**
      * @return a <code>Map</code> containing information about all components
      * added after the initial view construction.
@@ -230,7 +273,7 @@
     // ---------------------------------------------------------- Nested Classes
 
 
- public static class AddRemoveListener implements SystemEventListener {
+ public class AddRemoveListener implements SystemEventListener {
 
         private StateContext stateCtx;
         private LinkedHashMap<String, ComponentStruct> dynamicAdds;
@@ -293,6 +336,7 @@
             if (dynamicAdds != null && dynamicAdds.containsKey(clientId)) {
                 dynamicAdds.remove(clientId);
             }
+ StateContext.this.decrementDynamicChildCount(removed.getParent());
             dynamicRemoves.add(clientId);
         }
 
@@ -322,13 +366,14 @@
             }
 
             parent = added.getParent();
+ StateContext.this.incrementDynamicChildCount(parent);
             ComponentStruct toAdd = new ComponentStruct();
             toAdd.absorbComponent(context, added);
 
             if (dynamicRemoves != null) {
                 dynamicRemoves.remove(toAdd.clientId);
             }
- added.getAttributes().put(DYNAMIC_COMPONENT, Boolean.TRUE);
+ added.getAttributes().put(DYNAMIC_COMPONENT, new Integer(toAdd.indexOfChildInParent));
             getDynamicAdds().put(toAdd.clientId, toAdd);
 
         }
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentTagHandlerDelegateImpl.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentTagHandlerDelegateImpl.java (revision 8541)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/ComponentTagHandlerDelegateImpl.java (working copy)
@@ -61,6 +61,9 @@
 import javax.faces.view.facelets.TagException;
 import javax.faces.view.facelets.TagHandlerDelegate;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -184,6 +187,7 @@
         // this allows children to determine if it's
         // been part of the tree or not yet
         addComponentToView(ctx, parent, c, componentFound);
+ adjustIndexOfDynamicChildren(context, c);
         popComponentFromEL(ctx, c, ccStackManager, compcompPushed);
 
         if (shouldMarkInitialState(ctx.getFacesContext())) {
@@ -192,6 +196,33 @@
         
     }
 
+ private void adjustIndexOfDynamicChildren(FacesContext context,
+ UIComponent parent) {
+ StateContext stateContext = StateContext.getStateContext(context);
+ if (!stateContext.hasOneOrMoreDynamicChild(parent)) {
+ return;
+ }
+
+ List<UIComponent> children = parent.getChildren();
+ List<UIComponent> dynamicChildren = Collections.emptyList();
+
+ for (UIComponent cur : children) {
+ if (stateContext.componentAddedDynamically(cur)) {
+ if (dynamicChildren.isEmpty()) {
+ dynamicChildren = new ArrayList<UIComponent>(children.size());
+ }
+ dynamicChildren.add(cur);
+ }
+ }
+ for (UIComponent cur : dynamicChildren) {
+ int i = stateContext.getIndexOfDynamicallyAddedChildInParent(cur);
+ if (-1 != i) {
+ children.remove(cur);
+ children.add(i, cur);
+ }
+ }
+ }
+
     @Override
     public MetaRuleset createMetaRuleset(Class type) {
         Util.notNull("type", type);
Index: jsf-ri/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java (revision 8541)
+++ jsf-ri/src/main/java/com/sun/faces/application/view/FaceletViewHandlingStrategy.java (working copy)
@@ -1033,8 +1033,8 @@
         StateContext stateCtx = StateContext.getStateContext(ctx);
         if (stateCtx.partialStateSaving(ctx, root.getViewId())) {
             root.markInitialState();
- stateCtx.startTrackViewModifications();
         }
+ stateCtx.startTrackViewModifications();
     }
 
 
Index: jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/UITestComponent.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/UITestComponent.java (revision 0)
+++ jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/UITestComponent.java (revision 0)
@@ -0,0 +1,88 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.systest.dynamic1757;
+
+import javax.faces.component.FacesComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.component.UIViewRoot;
+import javax.faces.component.html.HtmlOutputText;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.PreRenderViewEvent;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+
+_at_FacesComponent( value = "com.sun.faces.systest.dynamic1757.UITestComponent" )
+public class UITestComponent
+ extends UIComponentBase
+ implements SystemEventListener
+{
+ public UITestComponent()
+ {
+ setRendererType( "testcomponent" );
+
+ FacesContext context = FacesContext.getCurrentInstance();
+ UIViewRoot root = context.getViewRoot();
+
+ if ( !context.isPostback() ) {
+ root.subscribeToViewEvent( PreRenderViewEvent.class, this );
+ }
+ }
+
+ @Override
+ public String getFamily()
+ {
+ return "com.sun.faces.systest.dynamic1757.UITestComponent";
+ }
+
+ public boolean isListenerForSource( Object source )
+ {
+ return ( source instanceof UIViewRoot );
+ }
+
+ @Override
+ public void processEvent( SystemEvent event )
+ throws AbortProcessingException
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ HtmlOutputText outputText = (HtmlOutputText) context.getApplication().createComponent( "javax.faces.HtmlOutputText" );
+ outputText.setValue( "Dynamically added child<br/>" );
+ outputText.setEscape( false );
+
+ getChildren().add( outputText );
+ }
+}
Index: jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757DynamicManagedBean.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757DynamicManagedBean.java (revision 0)
+++ jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757DynamicManagedBean.java (revision 0)
@@ -0,0 +1,52 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.systest.dynamic1757;
+
+import javax.faces.bean.ManagedBean;
+
+_at_ManagedBean
+public class Issue1757DynamicManagedBean
+{
+ //
+ // Public methods
+ //
+
+ public void save()
+ {
+ // Do nothing
+ }
+}
Index: jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757TestCase.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757TestCase.java (revision 0)
+++ jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/Issue1757TestCase.java (revision 0)
@@ -0,0 +1,104 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.systest.dynamic1757;
+
+
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
+import com.sun.faces.htmlunit.AbstractTestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Test cases for Facelets functionality
+ */
+public class Issue1757TestCase extends AbstractTestCase {
+
+
+ // --------------------------------------------------------------- Test Init
+
+
+ public Issue1757TestCase() {
+ this("Issue1757TestCase");
+ }
+
+
+ public Issue1757TestCase(String name) {
+ super(name);
+ }
+
+
+ /**
+ * Set up instance variables required by this test case.
+ */
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+
+ /**
+ * Return the tests included in this test suite.
+ */
+ public static Test suite() {
+ return (new TestSuite(Issue1757TestCase.class));
+ }
+
+
+ /**
+ * Tear down instance variables required by this test case.
+ */
+ public void tearDown() {
+ super.tearDown();
+ }
+
+
+ // ------------------------------------------------------------ Test Methods
+
+
+ public void testDynamicComponents() throws Exception {
+ HtmlPage page = getPage("/faces/facelets/issue1757-dynamic-components.xhtml");
+ String text = page.asText();
+ assertTrue(text.matches("(?s).*TestComponent::encodeBegin\\s*Manually added child\\s*Dynamically added child\\s*TestComponent::encodeEnd.*"));
+ HtmlSubmitInput button = (HtmlSubmitInput) page.getElementById("button");
+ page = button.click();
+ text = page.asText();
+ assertTrue(text.matches("(?s).*TestComponent::encodeBegin\\s*Manually added child\\s*Dynamically added child\\s*TestComponent::encodeEnd.*"));
+
+ }
+
+}
Index: jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/TestComponentRenderer.java
===================================================================
--- jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/TestComponentRenderer.java (revision 0)
+++ jsf-ri/systest/src/com/sun/faces/systest/dynamic1757/TestComponentRenderer.java (revision 0)
@@ -0,0 +1,69 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+
+package com.sun.faces.systest.dynamic1757;
+
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.render.FacesRenderer;
+import javax.faces.render.Renderer;
+
+_at_FacesRenderer( componentFamily = "com.sun.faces.systest.dynamic1757.UITestComponent", rendererType = "testcomponent" )
+public class TestComponentRenderer
+ extends Renderer
+{
+ @Override
+ public void encodeBegin( FacesContext context, UIComponent component )
+ throws IOException
+ {
+ context.getResponseWriter().write( "<div style=\"border: 1px solid red\">TestComponent::encodeBegin<br/>" );
+
+ super.encodeBegin( context, component );
+ }
+
+ @Override
+ public void encodeEnd( FacesContext context, UIComponent component )
+ throws IOException
+ {
+ context.getResponseWriter().write( "TestComponent::encodeEnd</div>" );
+
+ super.encodeEnd( context, component );
+ }
+
+}
Index: jsf-ri/systest/web/WEB-INF/source1.taglib.xml
===================================================================
--- jsf-ri/systest/web/WEB-INF/source1.taglib.xml (revision 8541)
+++ jsf-ri/systest/web/WEB-INF/source1.taglib.xml (working copy)
@@ -78,5 +78,12 @@
         </component>
     </tag>
 
+ <tag>
+ <tag-name>testcomponent</tag-name>
+ <component>
+ <component-type>com.sun.faces.systest.dynamic1757.UITestComponent</component-type>
+ </component>
+ </tag>
 
+
 </facelet-taglib>
Index: jsf-ri/systest/web/facelets/issue1757-dynamic-components.xhtml
===================================================================
--- jsf-ri/systest/web/facelets/issue1757-dynamic-components.xhtml (revision 0)
+++ jsf-ri/systest/web/facelets/issue1757-dynamic-components.xhtml (revision 0)
@@ -0,0 +1,69 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can obtain
+ a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ Sun designates this particular file as subject to the "Classpath" exception
+ as provided by Sun in the GPL Version 2 section of the License file that
+ accompanied this code. If applicable, add the following below the License
+ Header, with the fields enclosed by brackets [] replaced by your own
+ identifying information: "Portions Copyrighted [year]
+ [name of copyright owner]"
+
+ Contributor(s):
+
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:test="http://mojarra.dev.java.net/source1">
+
+ <body>
+
+ <h2>Instructions</h2>
+
+ <ol>
+ <li>The component should have dynamically modified the tree so that 'Dynamically added child' appears inside the red box</li>
+ <li>Click 'POSTback'. The dynamically added child will disappear!</li>
+ </ol>
+
+ <h:messages/>
+
+ <h:form prependId="false">
+
+ <test:testcomponent>
+ <h:outputText value="Manually added child&lt;br/&gt;" escape="false"/>
+ </test:testcomponent>
+
+ <br/>
+
+ <h:commandButton id="button" value="POSTback" action="#{issue1757DynamicManagedBean.save}"/>
+
+ </h:form>
+
+ </body>
+</html>
Index: jsf-ri/systest/build-tests.xml
===================================================================
--- jsf-ri/systest/build-tests.xml (revision 8541)
+++ jsf-ri/systest/build-tests.xml (working copy)
@@ -273,7 +273,7 @@
                    test-results-dir="${impl.test.results.dir}">
             <tests>
                 <fileset dir="${basedir}/build/classes"
- includes="com/sun/faces/systest/viewparameters/ViewParametersTestCase.class"/>
+ includes="com/sun/faces/systest/viewparameters/ViewParametersTestCase.class,com/sun/faces/systest/dynamic1757/*TestCase.class"/>
             </tests>
         </jsf.junit>
 
@@ -1369,11 +1369,14 @@
     </target>
 
     <target name="passthru">
- <jsf.tester
- ignoreIfContains="${ignore.path}/ignoreIfContains.txt"
- request="${context.path}/faces/composite/isCompositeComponentUsing.xhtml"
- golden="${golden.path}/composite/isCompositeComponentUsing.txt"/>
-
+ <jsf.junit context-path="${context.path}"
+ classpath-refid="html.classpath"
+ test-results-dir="${impl.test.results.dir}">
+ <tests>
+ <fileset dir="${basedir}/build/classes"
+ includes="com/sun/faces/systest/dynamic1757/*TestCase.class"/>
+ </tests>
+ </jsf.junit>
     </target>
 
 

-- 
| edburns_at_oracle.com | office: +1 407 458 0017
| homepage:          | http://ridingthecrest.com/
| 07 work days until JSF 2.1 Milestone 2