dev@javaserverfaces.java.net

merge wta-head to jsf-head part one of four

From: Ed Burns <ed.burns_at_sun.com>
Date: Wed, 20 Apr 2005 14:32:42 -0700

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

Reviewers: please give special attention to entries marked

NOTSURE:

Step one of four for merging webtier-alignment HEAD (wta-head) into
javaserverfaces-sources HEAD (jsf-head):

  core code:

    merge the everything but code that depends on the new EL.

  automated tests:

    jsf-api and jsf-ri automated tests currently fail and need to be
    made to run again. This will happen after we complete step two of
    three.

Step two of four will be to create a branch of jsf-head to preserve the
pre merge state.

Step three of four will be to merge in the remaining changes from
wta-head. This will introduce a dependency into jsf-head on the not yet
public JSP 2.1 container. People still wanting to run the latest faces on JSP
1.2 must use the branch created in step two of four.

Step four of four will be to get the automated tests running again.

SECTION: API New Files

A jsf-api/src/javax/faces/webapp/UIComponentClassicTagBase.java

- the same as the one on webtier-alignment HEAD except:

  createVerbatimComponent():

     * <p>This implementation includes a hack to work around the absence
     * of JspIdConsumer in non JSP 2.1 containers. PENDING(edburns):
     * remove this hack when we get to JSP 2.1</p>

  findComponent():

   On a postback, for the ViewTag, if we don't have a binding, make sure
   to increment the viewRoot's uniqueId counter so that the inlined
   verbatim components match up properly.

A jsf-api/src/javax/faces/webapp/UIComponentTagBase.java

- the same as the one on webtier-alignment HEAD except:

  getELContext() is missing, since it depends on new EL API.

SECTION: API Changes

M jsf-api/build.xml

- turn on assertions

- use source=1.4 for javadoc

M jsf-api/doc/standard-html-renderkit.xml
M jsf-api/doc/standard-html-renderkit-base.xml

- add renders-children==true for all standard renderers

M jsf-api/src/javax/faces/component/UIComponent.java

- copy javadocs from wta-head for getRendersChildren()

- add encodeAll() from wta-head

+ * <p>If this component returns <code>true</code> from {_at_link
+ * #isRendered}, render this component and all its children that
+ * return <code>true</code> from <code>isRendered()</code>,
+ * regardless of the value of the {_at_link #getRendersChildren} flag.
+ * </p>
+ *
+ * @since 1.2
+ *
+ * @exception IOException if an input/output error occurs while rendering
+ * @exception NullPointerException if <code>context</code>
+ * is <code>null</code>

- add to processSaveState() that transient components must be skipped.

M jsf-api/src/javax/faces/component/UIComponentBase.java

- copy class javadocs from wta-head

- add impl of encodeAll().

- in processSaveState(), skip transient children and facets.

- add new methods: getNonTransientChildLength() getNonTransientFacetLength()

- in processRestoreState(), assert that we are not transient.

M jsf-api/src/javax/faces/component/UIForm.java

- javadoc changes, including changing id to clientId in the javadoc for
  getContainerClientId.

M jsf-api/src/javax/faces/render/Renderer.java

- modify encodeChildren to just call encodeAll().

M jsf-api/src/javax/faces/render/ResponseStateManager.java

- javadoc changes for [50-MultipleRenderKits]

  new constant RENDER_KIT_ID_PARAM

  javadoc changes to writeState()

- fix typo for s/SERVER/CLIENT/ where we talk about the state encrypting.

M jsf-api/src/javax/faces/webapp/AttributeTag.java

- deprecate this class.

- leverage UIComponentClassicTagBase.

- add doEndTag() that releases us.

M jsf-api/src/javax/faces/webapp/ConverterTag.java

- deprecate this class.

- leverage UIComponentClassicTagBase.

- if converter turns out to be null, throw JspException with a nice
  error message.

M jsf-api/src/javax/faces/webapp/UIComponentBodyTag.java

+ // remove all methods since UIComponentTag is now a body tag.

M jsf-api/src/javax/faces/webapp/UIComponentTag.java

- most of the functionality has been moved to UIComponentClassicTagBase.

- the rest is just a copy of wta-head.

M jsf-api/src/javax/faces/webapp/ValidatorTag.java

- deprecate this class.

- leverage UIComponentClassicTagBase

- if validator turns out to be null, throw JspException with a nice
  error message.

M jsf-api/test/javax/faces/webapp/UIComponentTagTestCase.java

- account for new responsewriter creation rules.

- test still doesn't run, needs more work.

SECTION: RI New Files

A jsf-ri/src/com/sun/faces/application/ViewHandlerResponseWrapper.java

 * <p>This class is used by {_at_link ViewHandler#createView} to obtain the
 * text that exists after the &lt;f:view&gt; tag.</p>

 straight copy from wta-head

SECTION: RI Changes

M jsf-ri/conf/test/web.xml

- convert to schema and servlet 2.4

M jsf-ri/src/com/sun/faces/RIConstants.java

- added

+ public static final String SAVED_STATE = FACES_PREFIX + "savedState";

  Used from ViewHandler.

M jsf-ri/src/com/sun/faces/application/StateManagerImpl.java

- we don't remove the transientChildrenAndFacets any more. We just
  check for id uniqueness. Removal is now done in ViewHandler.

M jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java

- the heart of the chages for TCCI

   * create a ViewHandlerResponseWrapper that is used by ViewTag to allow
     content that follows the <f:view> tag to appear in the proper place
     in the page.
 
   * execute the JSP page. Rely on changes to JSP tag layer to have it
     build the tree only, but not render it.
 
   * create the responseWriter here, instead of having the JSP layer do
     it. This is possible and desireable since the JSP layer no longer
     writes anything to the response (except for the ViewTag).
 
   * call responseWriter.startDocument()
 
   * call viewRoot.encodeAll(), followed by logic that leverages the
     ViewHandlerRespnoseWrapper to write out the text after the <f:view>
     tag.
 
   * call responseWriter.endDocument()

- account for 11-StateSavingWindowId issues
  
M jsf-ri/src/com/sun/faces/context/ExternalContextImpl.java

- NOTSURE:

  Use generic Maps as the type of the ivars.

  Use Collections.unmodifiableMap() where possible.

M jsf-ri/src/com/sun/faces/renderkit/html_basic/ButtonRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/CheckboxRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/FormRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/HiddenRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/ImageRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/LabelRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/MenuRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/MessagesRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/OutputMessageRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/SecretRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/TextRenderer.java
M jsf-ri/src/com/sun/faces/renderkit/html_basic/TextareaRenderer.java

- remove encodeChildren()

M jsf-ri/src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java

- make this have getRendersChildren() == true

- remove encodeRecursive() and supplicants.

M jsf-ri/src/com/sun/faces/renderkit/html_basic/MessageRenderer.java

- make encodeChildren() throw IOException, per superclass definition.

R jsf-ri/src/com/sun/faces/taglib/BaseComponentBodyTag.java

- no longer need this, since everything is a body tag now.

M jsf-ri/src/com/sun/faces/taglib/jsf_core/AttributeTag.java

- NOTSURE: I'm pretty sure this class needs more work.

- leveragre UIComponentClassicTagBase.

M jsf-ri/src/com/sun/faces/taglib/jsf_core/LoadBundleTag.java

- more verbose exception message.

M jsf-ri/src/com/sun/faces/taglib/jsf_core/VerbatimTag.java

- clear the body after sucking it into the UIOutput.

M jsf-ri/src/com/sun/faces/taglib/jsf_core/ViewTag.java

- big changes, javadoc'd thoroughly

M jsf-ri/src/com/sun/faces/util/DebugUtil.java

- check for null root in printTree().

M jsf-ri/src/com/sun/faces/util/Util.java

- re-add comment to passthru attr about the "type" attribute.

- NOTSURE: getExceptionMessageString(), if we have no message summary,
  use MessageFormat.format() to parse the message.

SECTION: API Diffs

Index: jsf-api/build.xml
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/build.xml,v
retrieving revision 1.142
diff -u -r1.142 build.xml
--- jsf-api/build.xml 5 Apr 2005 22:02:26 -0000 1.142
+++ jsf-api/build.xml 20 Apr 2005 21:23:54 -0000
@@ -69,6 +69,8 @@
        build.properties -->
   <property name="debug.jvm.args" value=""/>
 
+ <property name="jvm.assertions" value="-ea:javax.faces..."/>
+
   <path id="compile.classpath">
     <pathelement location="${build.classes}"/>
     <pathelement location="${servlet.jar}"/>
@@ -112,6 +114,7 @@
     <mkdir dir="${build.dir}"/>
     <mkdir dir="${build.classes}"/>
     <mkdir dir="${build.lib}"/>
+ <mkdir dir="${build.javadocs}"/>
   </target>
 
   <target name="prepare.generate"
@@ -387,6 +390,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.FactoryFinderTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -398,6 +402,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.FactoryFinderTestCase2"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -408,6 +413,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.NamingContainerTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -418,6 +424,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIColumnTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -428,6 +435,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UICommandTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -438,6 +446,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIComponentTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -448,6 +457,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIComponentBaseTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -458,6 +468,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIDataTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -468,6 +479,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIFormTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -478,6 +490,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIGraphicTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -488,6 +501,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIInputTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -498,6 +512,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIOutputTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -508,6 +523,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIPanelTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -518,6 +534,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIParameterTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -528,6 +545,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UISelectBooleanTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -538,6 +556,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UISelectItemTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -548,6 +567,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UISelectItemsTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -558,6 +578,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UISelectManyTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -568,6 +589,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UISelectOneTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -578,6 +600,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.component.UIViewRootTestCase"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -589,6 +612,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <sysproperty key="base.dir" value="${basedir}"/>
       <sysproperty key="org.apache.commons.logging.LogFactory"
                  value="${test.factory}"/>
@@ -606,6 +630,7 @@
     <java classname="${test.runner}" fork="yes"
         failonerror="${test.failonerror}">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <arg value="javax.faces.event.PhaseIdTest"/>
       <classpath refid="test.classpath"/>
     </java>
@@ -616,6 +641,7 @@
     <junit printSummary="no" fork="yes"
           haltonfailure="yes" haltonerror="yes">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <classpath refid="test.classpath"/>
       <formatter type="plain" usefile="false"/>
       <formatter type="xml" usefile="true"/>
@@ -631,6 +657,7 @@
     <junit printSummary="no" fork="yes"
           haltonfailure="yes" haltonerror="yes">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <classpath refid="test.classpath"/>
       <formatter type="plain" usefile="false"/>
       <formatter type="xml" usefile="true"/>
@@ -660,6 +687,7 @@
     <junit printSummary="no" fork="yes"
           haltonfailure="yes" haltonerror="yes">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <classpath refid="test.classpath"/>
       <formatter type="plain" usefile="false"/>
       <formatter type="xml" usefile="true"/>
@@ -675,6 +703,7 @@
     <junit printSummary="no" fork="yes"
           haltonfailure="yes" haltonerror="yes">
       <jvmarg line="${debug.jvm.args}"/>
+ <jvmarg line="${jvm.assertions}"/>
       <sysproperty key="base.dir" value="${basedir}"/>
       <classpath refid="test.classpath"/>
       <formatter type="plain" usefile="false"/>
@@ -806,6 +835,7 @@
              Overview="${src.dir}/overview.html"
              private="${javadoc.private}"
              protected="${javadoc.protected}"
+ source="1.4"
              windowtitle="${Name} (${version})"
              doctitle="${Name} (${version})"
              bottom="Copyright &#169; 2002-2004 Sun Microsystems, Inc. All
Rights Reserved.">
@@ -831,6 +861,7 @@
     <javadoc packagenames="javax.*"
              destdir="${build.mifdocs}"
              private="false"
+ source="1.4"
              protected="true">
        <fileset dir="${src.dir}">
          <include name="**/*.java"/>
Index: jsf-api/doc/standard-html-renderkit-base.xml
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/doc/standard-html-renderkit-base.xml,v
retrieving revision 1.7
diff -u -r1.7 standard-html-renderkit-base.xml
--- jsf-api/doc/standard-html-renderkit-base.xml 4 Apr 2005 18:59:08 -0000 1.7
+++ jsf-api/doc/standard-html-renderkit-base.xml 20 Apr 2005 21:23:57 -0000
@@ -1014,6 +1014,10 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="command-button-attrs.xml"
xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
+
         </renderer>
 
         <renderer>
@@ -1112,6 +1116,7 @@
             <renderer-extension>
                 <renders-children>true</renders-children>
                 <exclude-attributes>onclick</exclude-attributes>
+ <body-tag>true</body-tag>
             </renderer-extension>
 
         </renderer>
@@ -1281,6 +1286,7 @@
             <xi:include href="form-form-attrs.xml" xpointer="xpointer(/root/*)"/>
 
             <renderer-extension>
+ <renders-children>true</renders-children>
                 <tag-name>form</tag-name>
             </renderer-extension>
 
@@ -1309,6 +1315,9 @@
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="graphic-image-attrs.xml"
xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1343,6 +1352,9 @@
                 <xi:include href="standard-html-renderkit-impl.xml"
xpointer="xpointer(/root/input-hidden-renderer-class/text())"/>
             </renderer-class>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1388,6 +1400,9 @@
             <xi:include href="text-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1435,6 +1450,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="text-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1472,6 +1490,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="input-textarea-attrs.xml"
xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1544,6 +1565,9 @@
             <xi:include href="message-message-attrs.xml"
xpointer="xpointer(/root/*)"/>
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1578,6 +1602,9 @@
             <xi:include href="messages-messages-attrs.xml"
xpointer="xpointer(/root/*)"/>
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1610,6 +1637,9 @@
             <xi:include href="output-format-attrs.xml"
xpointer="xpointer(/root/*)"/>
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1632,6 +1662,9 @@
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="output-label-attrs.xml"
xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1663,6 +1696,7 @@
 
             <renderer-extension>
                 <renders-children>true</renders-children>
+ <body-tag>true</body-tag>
             </renderer-extension>
 
         </renderer>
@@ -1690,6 +1724,9 @@
             <xi:include href="output-text-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1808,6 +1845,9 @@
             <xi:include href="i18n-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -1870,6 +1910,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="selectmany-checkbox-attrs.xml"
xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -2004,6 +2047,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="listbox-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -2052,6 +2098,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="menu-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -2099,6 +2148,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="listbox-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -2147,6 +2199,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="menu-attrs.xml" xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
         <renderer>
@@ -2210,6 +2265,9 @@
             <xi:include href="input-attrs.xml" xpointer="xpointer(/root/*)"/>
             <xi:include href="selectone-radio-attrs.xml"
xpointer="xpointer(/root/*)"/>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
         </renderer>
 
     </render-kit>
Index: jsf-api/doc/standard-html-renderkit.xml
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/doc/standard-html-renderkit.xml,v
retrieving revision 1.79
diff -u -r1.79 standard-html-renderkit.xml
--- jsf-api/doc/standard-html-renderkit.xml 4 Apr 2005 18:59:08 -0000 1.79
+++ jsf-api/doc/standard-html-renderkit.xml 20 Apr 2005 21:24:20 -0000
@@ -16414,6 +16414,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render an HTML "a" anchor element that acts like a
@@ -16870,6 +16873,7 @@
       <renderer-extension>
         <renders-children>true</renders-children>
         <exclude-attributes>onclick</exclude-attributes>
+ <body-tag>true</body-tag>
       </renderer-extension>
     </renderer>
     <renderer>
@@ -17691,6 +17695,7 @@
       </attribute>
 
       <renderer-extension>
+ <renders-children>true</renders-children>
         <tag-name>form</tag-name>
       </renderer-extension>
     </renderer>
@@ -17990,6 +17995,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Renders an HTML "input" element of type
@@ -18019,6 +18027,9 @@
       <renderer-class>
         com.sun.faces.renderkit.html_basic.HiddenRenderer
     </renderer-class>
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Renders an HTML "input" element of "type"
"password".</p>
@@ -18476,6 +18487,9 @@
         <attribute-class>java.lang.String</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Renders an HTML "input"
@@ -18871,6 +18885,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Renders an HTML "textarea" element.</p>
@@ -19243,6 +19260,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render a single message for a specific
component.</p>
@@ -19467,6 +19487,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[
@@ -19667,6 +19690,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render parameterized text. Obtain the
@@ -19776,6 +19802,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description>Renders an HTML "label" element. Render the current value
@@ -20072,6 +20101,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[Render an HTML "a" anchor element. The value of the
@@ -20461,6 +20493,7 @@
 
       <renderer-extension>
         <renders-children>true</renders-children>
+ <body-tag>true</body-tag>
       </renderer-extension>
     </renderer>
     <renderer>
@@ -20565,6 +20598,9 @@
         </attribute-extension>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[Renders an HTML "table" element, conforming to the
@@ -21420,6 +21456,9 @@
         <attribute-class>java.lang.String</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render an HTML checkbox list.</p>
@@ -21837,6 +21876,9 @@
         <attribute-class>java.lang.String</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render an HTML option list.</p>
@@ -22310,6 +22352,9 @@
         <attribute-class>int</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render an HTML option list.</p>
@@ -22687,6 +22732,9 @@
         <attribute-class>java.lang.String</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render an HTML option list.</p>
@@ -23074,6 +23122,9 @@
         <attribute-class>int</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render an HTML option list.</p>
@@ -23451,6 +23502,9 @@
         <attribute-class>java.lang.String</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
     <renderer>
       <description><![CDATA[<p>Render a set of html "input" elements of type
@@ -23933,6 +23987,9 @@
         <attribute-class>java.lang.String</attribute-class>
       </attribute>
 
+ <renderer-extension>
+ <renders-children>true</renders-children>
+ </renderer-extension>
     </renderer>
   </render-kit>
 </faces-config>
Index: jsf-api/src/javax/faces/component/UIComponent.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIComponent.java,v
retrieving revision 1.128
diff -u -r1.128 UIComponent.java
--- jsf-api/src/javax/faces/component/UIComponent.java 4 Apr 2005 17:23:34
-0000 1.128
+++ jsf-api/src/javax/faces/component/UIComponent.java 20 Apr 2005 21:24:21 -0000
@@ -278,7 +278,10 @@
      * in {_at_link UIComponentBase#getRendersChildren} tries to find the
      * renderer for this component. If it does, it calls {_at_link
      * Renderer#getRendersChildren} and returns the result. If it
- * doesn't, it returns false.</p>
+ * doesn't, it returns false. As of version 1.2 of the JavaServer
+ * Faces Specification, component authors are encouraged to return
+ * <code>true</code> from this method and rely on {_at_link
+ * UIComponentBase#encodeChildren}.</p>
      */
     public abstract boolean getRendersChildren();
 
@@ -548,6 +551,21 @@
      */
     public abstract void encodeEnd(FacesContext context) throws IOException;
 
+ /**
+ * <p>If this component returns <code>true</code> from {_at_link
+ * #isRendered}, render this component and all its children that
+ * return <code>true</code> from <code>isRendered()</code>,
+ * regardless of the value of the {_at_link #getRendersChildren} flag.
+ * </p>
+ *
+ * @since 1.2
+ *
+ * @exception IOException if an input/output error occurs while rendering
+ * @exception NullPointerException if <code>context</code>
+ * is <code>null</code>
+ */
+ public abstract void encodeAll(FacesContext context) throws IOException;
+
 
     // -------------------------------------------------- Event Listener Methods
 
@@ -736,9 +754,10 @@
      * <li>consult the <code>transient</code> property of this
      * component. If true, just return <code>null</code>.</li>
      *
- * <li>Call the <code>processSaveState()</code> method of all
- * facets and children of this {_at_link UIComponent} in the order
- * determined by a call to <code>getFacetsAndChildren()</code>.</li>
+ * <li>Call the <code>processSaveState()</code> method of all facets
+ * and children of this {_at_link UIComponent} in the order determined
+ * by a call to <code>getFacetsAndChildren()</code>, skipping
+ * children and facets that are transient.</li>
      *
      * <li>Call the <code>saveState()</code> method of this component.</li>
      *
Index: jsf-api/src/javax/faces/component/UIComponentBase.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIComponentBase.java,v
retrieving revision 1.104
diff -u -r1.104 UIComponentBase.java
--- jsf-api/src/javax/faces/component/UIComponentBase.java 4 Apr 2005 17:23:34
-0000 1.104
+++ jsf-api/src/javax/faces/component/UIComponentBase.java 20 Apr 2005 21:24:23
-0000
@@ -51,9 +51,13 @@
  * <p>By default, this class defines <code>getRendersChildren()</code>
  * to find the renderer for this component and call its
  * <code>getRendersChildren()</code> method. The default implementation
- * on the <code>Renderer</code> returns <code>false</code>. Subclasses
- * that wish to manage the rendering of their children should override
- * this method to return <code>true</code> instead.</p>
+ * on the <code>Renderer</code> returns <code>false</code>. As of
+ * version 1.2 of the JavaServer Faces Specification, component authors
+ * are encouraged to return <code>true</code> from this method and rely
+ * on the implementation of {_at_link #encodeChildren} in this class and in
+ * the Renderer ({_at_link Renderer#encodeChildren}). Subclasses that wish
+ * to manage the rendering of their children should override this method
+ * to return <code>true</code> instead.</p>
  */
 
 public abstract class UIComponentBase extends UIComponent {
@@ -167,6 +171,7 @@
 
 
     /**
+ * {_at_inheritDoc}
      * @exception NullPointerException {_at_inheritDoc}
      */
     public ValueBinding getValueBinding(String name) {
@@ -184,6 +189,7 @@
 
 
     /**
+ * {_at_inheritDoc}
      * @exception IllegalArgumentException {_at_inheritDoc}
      * @exception NullPointerException {_at_inheritDoc}
      */
@@ -738,6 +744,7 @@
 
 
     /**
+ * @exception IOException {_at_inheritDoc}
      * @exception NullPointerException {_at_inheritDoc}
      */
     public void encodeEnd(FacesContext context) throws IOException {
@@ -755,6 +762,31 @@
 
     }
 
+ /**
+ * @exception IOException {_at_inheritDoc}
+ * @exception NullPointerException {_at_inheritDoc}
+ */
+
+ public void encodeAll(FacesContext context) throws IOException {
+ if (!isRendered()) {
+ return;
+ }
+
+ encodeBegin(context);
+ if (getRendersChildren()) {
+ encodeChildren(context);
+ }
+ else {
+ Iterator kids = getChildren().iterator();
+ while (kids.hasNext()) {
+ UIComponent kid = (UIComponent) kids.next();
+ kid.encodeAll(context);
+ }
+ }
+
+ encodeEnd(context);
+ }
+
     // -------------------------------------------------- Event Listener Methods
 
 
@@ -990,14 +1022,17 @@
         stateStruct[MY_STATE] = saveState(context);
         
         // Process all the children of this component
- int i = 0, len = getChildren().size() + getFacets().keySet().size();
-
+ int i = 0, len = getNonTransientChildLength() +
+ getNonTransientFacetLength();
+
         childState = new Object[len];
         stateStruct[CHILD_STATE] = childState;
         Iterator kids = getChildren().iterator();
         while (kids.hasNext()) {
             UIComponent kid = (UIComponent) kids.next();
- childState[i++] = kid.processSaveState(context);
+ if (!kid.isTransient()) {
+ childState[i++] = kid.processSaveState(context);
+ }
         }
         
         Iterator myFacets = getFacets().keySet().iterator();
@@ -1015,9 +1050,6 @@
                 facetSaveState[0][1] = facetState;
                 childState[i] = facetSaveState;
             }
- else {
- childState[i] = null;
- }
             i++;
         }
         return stateStruct;
@@ -1025,8 +1057,39 @@
     
 
     /**
- * @exception NullPointerException {_at_inheritDoc}
- */
+ * @return the number of non-transient children in our child list.
+ */
+
+ private int getNonTransientChildLength() {
+ int i, result = 0;
+ Iterator kids = getChildren().iterator();
+ UIComponent kid = null;
+ while (kids.hasNext()) {
+ kid = (UIComponent) kids.next();
+ i = kid.isTransient() ? result : result++;
+ }
+ return result;
+ }
+
+ /**
+ * @return the number of non-transient facet children in our facet
+ * children list.
+ */
+
+ private int getNonTransientFacetLength() {
+ int i, result = 0;
+ Iterator kids = getFacets().keySet().iterator();
+ UIComponent kid = null;
+ while (kids.hasNext()) {
+ kid = (UIComponent) getFacets().get(kids.next().toString());
+ i = kid.isTransient() ? result : result++;
+ }
+ return result;
+ }
+
+ /**
+ * @exception NullPointerException {_at_inheritDoc}
+ */
     public void processRestoreState(FacesContext context,
                                     Object state) {
         if (context == null) {
@@ -1142,9 +1205,8 @@
         values[5] = renderedSet ? Boolean.TRUE : Boolean.FALSE;
         values[6] = rendererType;
         values[7] = saveAttachedState(context, listeners);
- // Don't save the transient flag. Asssert that it is false
- // here.
-
+ assert(!transientFlag);
+
         return (values);
     }
 
Index: jsf-api/src/javax/faces/component/UIForm.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIForm.java,v
retrieving revision 1.46
diff -u -r1.46 UIForm.java
--- jsf-api/src/javax/faces/component/UIForm.java 4 Apr 2005 17:23:34 -0000 1.46
+++ jsf-api/src/javax/faces/component/UIForm.java 20 Apr 2005 21:24:24 -0000
@@ -91,7 +91,7 @@
 
 
     /**
- * <p>If <strong>this<strong> <code>UIForm</code> instance (as
+ * <p>If <strong>this</strong> <code>UIForm</code> instance (as
      * opposed to other forms in the page) is experiencing a submit
      * during this request processing lifecycle, this method must be
      * called, with <code>true</code> as the argument, during the {_at_link
@@ -221,7 +221,7 @@
     
     /**
      * <p>Override the {_at_link UIComponent#getContainerClientId} to allow
- * users to disable this form from prepending its <code>id</code> to
+ * users to disable this form from prepending its <code>clientId</code> to
      * its descendent's <code>clientIds</code> depending on the value of
      * this form's {_at_link #isPrependId} property.</p>
      */
Index: jsf-api/src/javax/faces/render/Renderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/render/Renderer.java,v
retrieving revision 1.33
diff -u -r1.33 Renderer.java
--- jsf-api/src/javax/faces/render/Renderer.java 26 Feb 2004 20:31:12 -0000 1.33
+++ jsf-api/src/javax/faces/render/Renderer.java 20 Apr 2005 21:24:25 -0000
@@ -113,11 +113,7 @@
         Iterator kids = component.getChildren().iterator();
         while (kids.hasNext()) {
             UIComponent kid = (UIComponent) kids.next();
- kid.encodeBegin(context);
- if (kid.getRendersChildren()) {
- kid.encodeChildren(context);
- }
- kid.encodeEnd(context);
+ kid.encodeAll(context);
         }
     }
 
Index: jsf-api/src/javax/faces/render/ResponseStateManager.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/render/ResponseStateManager.java,v
retrieving revision 1.20
diff -u -r1.20 ResponseStateManager.java
--- jsf-api/src/javax/faces/render/ResponseStateManager.java 6 Apr 2005
02:44:44 -0000 1.20
+++ jsf-api/src/javax/faces/render/ResponseStateManager.java 20 Apr 2005
21:24:25 -0000
@@ -32,6 +32,14 @@
 
 public abstract class ResponseStateManager {
 
+ /**
+ * <p>The name of the request parameter used by the default
+ * implementation of {_at_link
+ * javax.faces.application.ViewHandler#calculateRenderKitId} to
+ * derive a RenderKit ID.</p>
+ */
+ public static final String RENDER_KIT_ID_PARAM =
+ "javax.faces.RenderKitId";
 
     /*
      * <p>Take the argument <code>state</code> and write it into the
@@ -50,6 +58,20 @@
      * and also be tamper evident. The reference implementation follows
      * these recommendations. </p>
      *
+ * <p>Write out the render kit identifier associated with this
+ * <code>ResponseStateManager</code> implementation with the name
+ * as the value of the <code>String</code> constant
+ * <code>ResponseStateManager.RENDER_KIT_ID_PARAM</code>. The
+ * render kit identifier must not be written if:</p>
+ * <ul>
+ * <li>it is the default render kit identifier as returned by
+ * {_at_link Application#getDefaultRenderKitId()} or</li>
+ * <li>the render kit identfier is the value of
+ * <code>RenderKitFactory.HTML_BASIC_RENDER_KIT</code> and
+ * {_at_link Application.getDefaultRenderKitId()} returns <code>null</code>.
+ * </li>
+ * </ul>
+ *
      * <p>For backwards compatability with existing
      * <code>ResponseStateManager</code> implementations, the default
      * implementation of this method checks if the argument is an
@@ -93,7 +115,7 @@
      * suitable for inclusion as an HTTP request paramater.</p>
      *
      * <p>If the state saving method for this application is {_at_link
- * javax.faces.application.StateManager#STATE_SAVING_METHOD_SERVER},
+ * javax.faces.application.StateManager#STATE_SAVING_METHOD_CLIENT},
      * the implementation may encrypt the state to be saved to the
      * client. We recommend that the state be unreadable by the client,
      * and also be tamper evident. The reference implementation follows
Index: jsf-api/src/javax/faces/webapp/AttributeTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/webapp/AttributeTag.java,v
retrieving revision 1.12
diff -u -r1.12 AttributeTag.java
--- jsf-api/src/javax/faces/webapp/AttributeTag.java 29 Jul 2004 21:18:05 -0000 1.12
+++ jsf-api/src/javax/faces/webapp/AttributeTag.java 20 Apr 2005 21:24:25 -0000
@@ -24,6 +24,9 @@
  * if the component does not already contain an attribute with the
  * same name. This tag creates no output to the page currently
  * being created.</p>
+ *
+ * @deprecated The Faces implementation must now provide the
+ * implementation for this class.
  */
 
 public class AttributeTag extends TagSupport {
@@ -83,8 +86,8 @@
     public int doStartTag() throws JspException {
 
         // Locate our parent UIComponentTag
- UIComponentTag tag =
- UIComponentTag.getParentUIComponentTag(pageContext);
+ UIComponentClassicTagBase tag =
+ UIComponentTag.getParentUIComponentClassicTagBase(pageContext);
         if (tag == null) { // PENDING - i18n
             throw new JspException("Not nested in a UIComponentTag");
         }
@@ -117,6 +120,12 @@
     }
 
 
+ public int doEndTag() throws JspException {
+ this.release();
+ return (EVAL_PAGE);
+ }
+
+
     /**
      * <p>Release references to any acquired resources.
      */
Index: jsf-api/src/javax/faces/webapp/ConverterTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/webapp/ConverterTag.java,v
retrieving revision 1.13
diff -u -r1.13 ConverterTag.java
--- jsf-api/src/javax/faces/webapp/ConverterTag.java 20 Dec 2004 21:25:13 -0000 1.13
+++ jsf-api/src/javax/faces/webapp/ConverterTag.java 20 Apr 2005 21:24:25 -0000
@@ -56,6 +56,11 @@
  *
  * <p>This tag creates no output to the page currently being created. It
  * is used solely for the side effect of {_at_link Converter} creation.</p>
+ *
+ * @deprecated This has been partially replaced by {_at_link
+ * ConverterELTag}. The remainder of the functionality, namely, the
+ * binding facility and the implementation of the {_at_link
+ * #createConverter} method, is now an implementation detail.
  */
 
 public class ConverterTag extends TagSupport {
@@ -118,8 +123,8 @@
         Converter converter = null;
         
         // Locate our parent UIComponentTag
- UIComponentTag tag =
- UIComponentTag.getParentUIComponentTag(pageContext);
+ UIComponentClassicTagBase tag =
+ UIComponentTag.getParentUIComponentClassicTagBase(pageContext);
         if (tag == null) { // PENDING - i18n
             throw new JspException("Not nested in a UIComponentTag Error for
tag with handler class:"+
                     this.getClass().getName());
@@ -144,7 +149,22 @@
         converter = createConverter();
         
         if (converter == null) {
- return (SKIP_BODY);
+ String converterError = null;
+ if (binding != null) {
+ converterError = binding;
+ }
+ if (converterId != null) {
+ if (converterError != null) {
+ converterError += " or " + converterId;
+ } else {
+ converterError = converterId;
+ }
+ }
+
+ Object params [] = {"javax.faces.convert.Converter",converterError};
+ // PENDING i18n
+ throw new JspException("Can't create class of type:"+
+ "javax.faces.convert.Converter for:"+converterError);
         }
 
         ValueHolder vh = (ValueHolder)component;
@@ -234,10 +254,6 @@
                 throw new JspException(e);
             }
         }
-
- // PENDING - should log an error if neither "binding" or "converterId"
- // was set.
-
         return converter;
     }
 }
Index: jsf-api/src/javax/faces/webapp/UIComponentBodyTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/webapp/UIComponentBodyTag.java,v
retrieving revision 1.4
diff -u -r1.4 UIComponentBodyTag.java
--- jsf-api/src/javax/faces/webapp/UIComponentBodyTag.java 6 May 2004 16:12:24
-0000 1.4
+++ jsf-api/src/javax/faces/webapp/UIComponentBodyTag.java 20 Apr 2005 21:24:25
-0000
@@ -1,5 +1,5 @@
 /*
- * $Id: UIComponentBodyTag.java,v 1.4 2004/05/06 16:12:24 rlubke Exp $
+ * $Id: UIComponentBodyTag.java,v 1.8.2.1 2005/04/08 20:59:53 edburns Exp $
  */
 
 /*
@@ -10,138 +10,17 @@
 package javax.faces.webapp;
 
 
-import javax.servlet.jsp.JspException;
-import javax.servlet.jsp.JspWriter;
-import javax.servlet.jsp.tagext.BodyContent;
-import javax.servlet.jsp.tagext.BodyTag;
-import javax.servlet.jsp.tagext.Tag;
-
-
 /**
  * <p><strong>UIComponentBodyTag</strong> is a base class for all JSP custom
  * actions, related to a UIComponent, that need to process their tag bodies.
  * </p>
+ *
+ * @deprecated All component tags now implement <code>BodyTag</code>.
+ * This class has been replaced by {_at_link UIComponentELTag}.
  */
 
-public abstract class UIComponentBodyTag extends UIComponentTag
- implements BodyTag {
-
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * <p>The <code>bodyContent</code> for this tag handler.</p>
- */
- protected BodyContent bodyContent = null;
-
-
- // -------------------------------------------------------- BodyTag Methods
-
-
- /**
- * <p>Handle the ending of the nested body content for this tag. The
- * default implementation simply calls <code>getDoAfterBodyValue()</code>
- * to retrieve the flag value to be returned.</p>
- *
- * <p>It should be noted that if this method returns
- * <code>IterationTag.EVAL_BODY_AGAIN</code>, any nested
- * {_at_link UIComponentTag} <em>must</em> have an explicit ID set.</p>
- *
- * @exception JspException if an error is encountered
- */
- public int doAfterBody() throws JspException {
-
- return (getDoAfterBodyValue());
-
- }
-
-
- /**
- * <p>Prepare for evaluation of the body. This method is invoked by the
- * JSP page implementation object after <code>setBodyContent()</code>
- * and before the first time the body is to be evaluated. This method
- * will not be invoked for empty tags or for non-empty tags whose
- * <code>doStartTag()</code> method returns <code>SKIP_BODY</code>
- * or <code>EVAL_BODY_INCLUDE</code>.</p>
- *
- * @exception JspException if an error is encountered
- */
- public void doInitBody() throws JspException {
-
- ; // Default implementation does nothing
-
- }
-
- public void release() {
-
- bodyContent = null;
- super.release();
-
- }
-
-
- /**
- * <p>Set the <code>bodyContent</code> for this tag handler. This method
- * is invoked by the JSP page implementation object at most once per
- * action invocation, before <code>doInitiBody()</code>. This method
- * will not be invoked for empty tags or for non-empty tags whose
- * <code>doStartTag()</code> method returns <code>SKIP_BODY</code> or
- * <code>EVAL_BODY_INCLUDE</code>.</p>
- *
- * @param bodyContent The new <code>BodyContent</code> for this tag
- */
- public void setBodyContent(BodyContent bodyContent) {
-
- this.bodyContent = bodyContent;
-
- }
-
-
- // --------------------------------------------------------- Public Methods
-
-
- /**
- * <p>Return the <code>BodyContent</code> for this tag handler.</p>
- */
- public BodyContent getBodyContent() {
-
- return (this.bodyContent);
-
- }
-
-
- /**
- * <p>Get the <code>JspWriter</code> from our <code>BodyContent</code>.
- * </p>
- */
- public JspWriter getPreviousOut() {
-
- return (this.bodyContent.getEnclosingWriter());
-
- }
-
-
- // ------------------------------------------------------ Protected Methods
-
-
- /**
- * <p>Return the flag value that should be returned from the
- * <code>doAfterBody()</code> method when it is called. Subclasses
- * may override this method to return the appropriate value.</p>
- */
- protected int getDoAfterBodyValue() throws JspException {
-
- return (SKIP_BODY);
-
- }
-
-
- protected int getDoStartValue() throws JspException {
-
- return (EVAL_BODY_BUFFERED);
-
- }
+public abstract class UIComponentBodyTag extends UIComponentTag {
 
+ // remove all methods since UIComponentTag is now a body tag.
 
 }
Index: jsf-api/src/javax/faces/webapp/UIComponentTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/webapp/UIComponentTag.java,v
retrieving revision 1.54
diff -u -r1.54 UIComponentTag.java
--- jsf-api/src/javax/faces/webapp/UIComponentTag.java 17 Dec 2004 17:09:41
-0000 1.54
+++ jsf-api/src/javax/faces/webapp/UIComponentTag.java 20 Apr 2005 21:24:27 -0000
@@ -1,5 +1,5 @@
 /*
- * $Id: UIComponentTag.java,v 1.54 2004/12/17 17:09:41 edburns Exp $
+ * $Id: UIComponentTag.java,v 1.8.4.1 2005/04/08 20:59:54 edburns Exp $
  */
 
 /*
@@ -10,149 +10,34 @@
 package javax.faces.webapp;
 
 
-import javax.faces.FactoryFinder;
 import javax.faces.application.Application;
 import javax.faces.component.UIComponent;
-import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
 import javax.faces.el.ValueBinding;
-import javax.faces.render.RenderKit;
-import javax.faces.render.RenderKitFactory;
 import javax.servlet.jsp.JspException;
 import javax.servlet.jsp.PageContext;
 import javax.servlet.jsp.tagext.Tag;
 
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-
 
 /**
  * <p>{_at_link UIComponentTag} is the base class for all JSP custom
  * actions that correspond to user interface components in a page that is
- * rendered by JavaServer Faces. Tags that need to process their tag bodies
- * should subclass {_at_link UIComponentBodyTag} instead.</p>
+ * rendered by JavaServer Faces.</p>
+ *
+ * <p>In this version of the specification, <code>UIComponentTag</code>
+ * extends {_at_link UIComponentClassicTagBase} to add properties that use
+ * the Faces 1.1 Expression Language.</p>
+ *
+ * @deprecated Use of this class has been replaced with {_at_link
+ * UIComponentELTag}, which extends
+ * <code>UIComponentClassicTagBase</code> to add properties that use the
+ * EL API introduced as part of JSP 2.1.
  */
 
-public abstract class UIComponentTag implements Tag {
-
-
- // ------------------------------------------------------ Manifest Constants
-
-
- /**
- * <p>The request scope attribute under which a component tag stack
- * for the current request will be maintained.</p>
- */
- private static final String COMPONENT_TAG_STACK_ATTR =
- "javax.faces.webapp.COMPONENT_TAG_STACK";
-
-
- /**
- * <p>The {_at_link UIComponent} attribute under which we will store a
- * <code>List</code> of the component identifiers of child components
- * created on the previous generation of this page (if any).</p>
- */
- private static final String JSP_CREATED_COMPONENT_IDS =
- "javax.faces.webapp.COMPONENT_IDS";
-
-
- /**
- * <p>The {_at_link UIComponent} attribute under which we will store a
- * <code>List</code> of the facet names of facets created on the previous
- * generation of this page (if any).
- */
- private static final String JSP_CREATED_FACET_NAMES =
- "javax.faces.webapp.FACET_NAMES";
-
-
- /**
- * <p>The attribute name under which we will store all {_at_link UIComponent}
- * IDs of the current translation unit.</p>
- */
- private static final String GLOBAL_ID_VIEW =
- "javax.faces.webapp.GLOBAL_ID_VIEW";
-
- /**
- * <p>The attribute name under which we will store the {_at_link FacesContext}
- * for this request.</p>
- */
- private static final String CURRENT_FACES_CONTEXT =
- "javax.faces.webapp.CURRENT_FACES_CONTEXT";
-
- /**
- * <p>The attribute name under which we will store the {_at_link UIViewRoot}
- * for this request.</p>
- */
- private static final String CURRENT_VIEW_ROOT =
- "javax.faces.webapp.CURRENT_VIEW_ROOT";
-
-
-
- // ------------------------------------------------------ Instance Variables
-
-
- /**
- * <p>The {_at_link UIComponent} that is being encoded by this tag,
- * if any.</p>
- */
- private UIComponent component = null;
-
-
- /**
- * <p>The {_at_link FacesContext} for the request being processed, if any.
- * </p>
- */
- private FacesContext context = null;
-
-
- /**
- * <p>Was a new component instance dynamically created when our
- * <code>findComponent()</code> method was called.</p>
- */
- private boolean created = false;
-
-
- /**
- * <p>The <code>Lst</code> of {_at_link UIComponent} ids created or located
- * by nested {_at_link UIComponentTag}s while processing the current
- * request.</p>
- */
- private List createdComponents = null;
-
-
- /**
- * <p>The <code>List</code> of facet names created or located by nested
- * {_at_link UIComponentTag}s while processing the current request.</p>
- */
- private List createdFacets = null;
-
-
- /**
- * <p>The JSP <code>PageContext</code> for the page we are embedded in.</p>
- */
- protected PageContext pageContext = null;
-
-
- /**
- * <p>The JSP <code>Tag</code> that is the parent of this tag.</p>
- */
- private Tag parent = null;
-
-
- /**
- * <p>Flag indicating whether or not rendering should occur.</p>
- */
- private boolean suppressed = false;
-
-
- // ------------------------------------------------------------- Attributes
+public abstract class UIComponentTag extends UIComponentClassicTagBase
implements Tag {
 
+ // ------------------------------------------------------------- Properties
 
     /**
      * <p>The value binding expression (if any) used to wire up this component
@@ -177,36 +62,12 @@
         this.binding = binding;
     }
 
-
- /**
- * <p>The component identifier for the associated component.</p>
- */
- private String id = null;
-
-
- /**
- * <p>Set the component identifier for our component. If the
- * argument begins with {_at_link
- * UIViewRoot#UNIQUE_ID_PREFIX} throw an
- * <code>IllegalArgumentException</code></p>
- *
- * @param id The new component identifier. This may not start with
- * {_at_link UIViewRoot#UNIQUE_ID_PREFIX}.
- *
- * @exception IllegalArgumentException if the argument is
- * non-<code>null</code> and starts with {_at_link
- * UIViewRoot#UNIQUE_ID_PREFIX}.
- */
- public void setId(String id) {
- if (null != id && id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
- throw new IllegalArgumentException();
- }
-
- this.id = id;
-
+ protected boolean hasBinding() {
+ return null != binding;
     }
 
 
+
     /**
      * <p>An override for the rendered attribute associated with our
      * {_at_link UIComponent}.</p>
@@ -226,80 +87,23 @@
     }
 
 
- // ------------------------------------------------------------- Properties
-
-
- /**
- * <p>Return the component type for the component that is or will be
- * bound to this tag. This value can be passed to
- * {_at_link javax.faces.application.Application#createComponent} to create
- * the {_at_link UIComponent} instance for this tag. Subclasses must
- * override this method to return the appropriate value.</p>
- */
- public abstract String getComponentType();
-
-
- /**
- * <p>Return the {_at_link UIComponent} instance that is associated with
- * this tag instance. This method is designed to be used by tags nested
- * within this tag, and only returns useful results between the
- * execution of <code>doStartTag()</code> and <code>doEndTag()</code>
- * on this tag instance.</p>
- */
- public UIComponent getComponentInstance() {
-
- return (this.component);
-
- }
-
-
     /**
- * <p>Return <code>true</code> if we dynamically created a new component
- * instance during execution of this tag. This method is designed to be
- * used by tags nested within this tag, and only returns useful results
- * between the execution of <code>doStartTag()</code> and
- * <code>doEndTag()</code> on this tag instance.</p>
+ * <p>Flag indicating whether or not rendering should occur.</p>
      */
- public boolean getCreated() {
-
- return (this.created);
-
- }
+ private boolean suppressed = false;
 
 
- /**
- * <p>Locate and return the nearest enclosing {_at_link UIComponentTag} if any;
- * otherwise, return <code>null</code>.</p>
- *
- * @param context <code>PageContext</code> for the current page
- */
- public static UIComponentTag getParentUIComponentTag(PageContext context) {
+ protected boolean isSuppressed() {
 
- List list = (List) context.getAttribute(COMPONENT_TAG_STACK_ATTR,
- PageContext.REQUEST_SCOPE);
- if (list != null) {
- return ((UIComponentTag) list.get(list.size() - 1));
- } else {
- return (null);
- }
+ return (suppressed);
 
     }
-
-
- /**
- * <p>Return the <code>rendererType</code> property that selects the
- * <code>Renderer</code> to be used for encoding this component, or
- * <code>null</code> to ask the component to render itself directly.
- * Subclasses must override this method to return the appropriate value.
- * </p>
- */
- public abstract String getRendererType();
 
 
     /**
      * <p>Return <code>true</code> if the specified value conforms to the
      * syntax requirements of a value binding expression. Such expressions
- * may be used on most component tag attributes to signal a desire for
+` * may be used on most component tag attributes to signal a desire for
      * deferred evaluation of the attribute or property value to be set on
      * the underlying {_at_link UIComponent}.</p>
      *
@@ -321,563 +125,25 @@
 
     }
 
-
- // --------------------------------------------------------- Tag Properties
-
-
- /**
- * <p>Set the <code>PageContext</code> of the page containing this
- * tag instance.</p>
- *
- * @param pageContext The enclosing <code>PageContext</code>
- */
- public void setPageContext(PageContext pageContext) {
-
- this.pageContext = pageContext;
-
- }
-
-
- /**
- * <p>Return the <code>Tag</code> that is the parent of this instance.</p>
- */
- public Tag getParent() {
-
- return (this.parent);
-
- }
-
-
- /**
- * <p>Set the <code>Tag</code> that is the parent of this instance.</p>
- *
- * @param parent The new parent <code>Tag</code>
- */
- public void setParent(Tag parent) {
-
- this.parent = parent;
-
- }
-
-
- // ------------------------------------------------------------ Tag Methods
-
-
- /**
- * <p>Render the beginning of the {_at_link UIComponent} that is associated
- * with this tag (via the <code>id</code> attribute), by following these
- * steps.</p>
- * <ul>
- * <li>Ensure that an appropriate {_at_link ResponseWriter} is associated
- * with the current {_at_link FacesContext}. This ensures that encoded
- * output from the components is routed through the
- * <code>JspWriter</code> for the current page.</li>
- * <li>Locate the component (in the view) corresponding
- * to this tag, creating a new one if necesary.</li>
- * <li>If this {_at_link UIComponentTag} is nested within the body of
- * another {_at_link UIComponentTag}, call its <code>addChild</code>
- * method to save the component identifier for the {_at_link UIComponent}
- * that corresponds to this {_at_link UIComponentTag}.</li>
- * <li>Call <code>findComponent()</code> to locate the {_at_link UIComponent}
- * instance associated wth this {_at_link UIComponentTag}, creating a new
- * one if necessary.</li>
- * <li>Call the <code>encodeBegin()</code> method of the component,
- * unless rendering is suppressed or our component renders its
- * own children; if <code>encodeBegin()</code> is called,
- * <code>ResponseWriter.flush()</code> must also be called.</li>
- * </ul>
- *
- * <p>The flag value to be returned is acquired by calling the
- * <code>getDoStartValue()</code> method, which tag subclasses may
- * override if they do not want the default value.</p>
- *
- * @exception JspException if an error occurs
- */
- public int doStartTag() throws JspException {
- // make sure that these ivars are reset at the beginning of the
- // lifecycle for this tag.
- createdComponents = null;
- createdFacets = null;
-
- context =
- (FacesContext) pageContext.getAttribute(CURRENT_FACES_CONTEXT);
-
- if (context == null) {
- context = FacesContext.getCurrentInstance();
-
- if (context == null) { // PENDING - i18n
- throw new JspException("Cannot find FacesContext");
- }
-
- // store the current FacesContext for use by other
- // UIComponentTags in the same page
- pageContext.setAttribute(CURRENT_FACES_CONTEXT, context);
- }
-
- // Set up the ResponseWriter as needed
- setupResponseWriter();
-
- UIComponentTag parentTag = getParentUIComponentTag(pageContext);
- Map requestMap = context.getExternalContext().getRequestMap();
- Map componentIds = null;
- if (parentTag == null) {
- // create the map if we're the top level UIComponentTag
- componentIds = new HashMap();
- requestMap.put(GLOBAL_ID_VIEW, componentIds);
- } else {
- componentIds = (Map) requestMap.get(GLOBAL_ID_VIEW);
- }
-
- // Locate the UIComponent associated with this UIComponentTag,
- // creating one if necessary
- component = findComponent(context);
-
- Object tagInstance = null;
- String clientId = null;
- if (this.id != null) {
- clientId = component.getClientId(context);
- tagInstance = (componentIds.get(clientId) == this ? this : null);
- }
-
- // If we have a tag instance, then, most likely, a tag handler
- // returned EVAL_BODY_AGAIN somewhere. Make sure the instance
- // returned is the same as the current instance and if this is the case,
- // do not perform ID validation as it has already been done.
- if (tagInstance == null) {
-
- // only check for id uniqueness if the author has manually given
- // us an id.
- if (null != this.id) {
-
- // assert component ID uniqueness
- if (clientId != null) {
- if (componentIds.containsKey(clientId)) {
- // PENDING i18n
- throw new JspException(new
IllegalStateException("Duplicate component id: '" +
- clientId +
- "', first used in tag: '" +
- componentIds.get(clientId).getClass().getName() +
- "'"));
- } else {
- componentIds.put(clientId, this);
- }
- }
- }
-
- // Add to parent's list of created components or facets if needed
-
- if (parentTag != null) {
- if (getFacetName() == null) {
- parentTag.addChild(component);
- } else {
- parentTag.addFacet(getFacetName());
- }
- }
- }
-
- // Render the beginning of the component associated with this tag
- suppressed = shouldBeSuppressed(parentTag);
- try {
- if (!isSuppressed() && !component.getRendersChildren()) {
- encodeBegin();
- context.getResponseWriter().flush();
- }
- } catch (IOException e) {
- component = null;
- context = null;
- throw new JspException(e);
- }
-
- // Return the appropriate control value
- pushUIComponentTag();
- return (getDoStartValue());
-
- }
-
-
- /**
- * <p>Render the ending of the {_at_link UIComponent} that is associated
- * with this tag (via the <code>id</code> attribute), by following these
- * steps.</p>
- * <ul>
- * <li>Retrieve from the {_at_link UIComponent} the set of component ids
- * of child components created by {_at_link UIComponentTag} instances
- * the last time this page was processed (if any). Compare it to
- * the list of children created during this page processing pass,
- * and remove all children present in the old list but not the new.
- * Save the new list as a component attribute so that it gets saved
- * as part of the component's state.</li>
- * <li>Retrieve from the {_at_link UIComponent} the set of facet names
- * of facets created by {_at_link UIComponentTag} instances the last
- * time this page was processed (if any). Compare it to
- * the list of facets created during this page processing pass,
- * and remove all facets present in the old list but not the new.
- * Save the new list as a component attribute so that it gets saved
- * as part of the component's state.</li>
- * <li>If the <code>rendersChildren</code> property of this component is
- * <code>true</code>, call the <code>encodeBegin()</code> method
- * of this component.
- * <li>If the <code>rendersChildren</code> property of this component is
- * <code>true</code>, call the <code>encodeChildren()</code> method
- * of the component.</li>
- * <li>Call the <code>encodeEnd()</code> method of the component.</li>
- * <li>Release all references to the component, and pop it from
- * the component stack for this response, removing the stack
- * if this was the outermost component.</li>
- * </ul>
- *
- * <p>The flag value to be returned is acquired by calling the
- * <code>getDoEndValue()</code> method, which tag subclasses may
- * override if they do not want the default value.</p>
- *
- * @exception JspException if an error occurs
- */
- public int doEndTag() throws JspException {
-
- // Remove old children and facets as needed
- popUIComponentTag();
- removeOldChildren();
- removeOldFacets();
-
- // Render the children (if needed) and end of the component
- // associated with this tag
- try {
- if (!isSuppressed()) {
- if (component.getRendersChildren()) {
- encodeBegin();
- encodeChildren();
- }
- encodeEnd();
- }
- } catch (IOException e) {
- throw new JspException(e);
- } finally {
- component = null;
- context = null;
- }
-
- // Return the appropriate control value
- created = false;
- return (getDoEndValue());
-
- }
-
+ // ------------------------------------------ Methods from Tag
 
     /**
      * <p>Release any resources allocated during the execution of this
      * tag handler.</p>
      */
     public void release() {
-
- this.parent = null;
-
+
+ this.suppressed = false;
         this.binding = null;
- this.id = null;
- this.created = false;
         this.rendered = null;
+ super.release();
     }
 
 
- // ------------------------------------------------------- Protected Methods
-
+ // ---------------- Concrete Implementations of methods from superclass
 
     /**
- * <p>Delegate to the <code>encodeBegin()</code> method of our
- * corresponding {_at_link UIComponent}. This method is called from
- * <code>doStartTag()</code>. Normally, delegation occurs unconditionally;
- * however, this method is abstracted out so that advanced tags can
- * conditionally perform this call.
- *
- * @exception IOException if an input/output error occurs
- */
- protected void encodeBegin() throws IOException {
-
- component.encodeBegin(context);
-
- }
-
-
- /**
- * <p>Delegate to the <code>encodeChildren()</code> method of our
- * corresponding {_at_link UIComponent}. This method is called from
- * <code>doStartTag()</code>. Normally, delegation occurs unconditionally;
- * however, this method is abstracted out so that advanced tags can
- * conditionally perform this call.
- *
- * @exception IOException if an input/output error occurs
- */
- protected void encodeChildren() throws IOException {
-
- component.encodeChildren(context);
-
- }
-
-
- /**
- * <p>Delegate to the <code>encodeEnd()</code> method of our
- * corresponding {_at_link UIComponent}. This method is called from
- * <code>doStartTag()</code>. Normally, delegation occurs unconditionally;
- * however, this method is abstracted out so that advanced tags can
- * conditionally perform this call.
- *
- * @exception IOException if an input/output error occurs
- */
- protected void encodeEnd() throws IOException {
-
- component.encodeEnd(context);
-
- }
-
-
- /**
- * <p>Find and return the {_at_link UIComponent}, from the component
- * tree, that corresponds to this tag handler instance. If there
- * is no such {_at_link UIComponent}, create one
- * and add it as a child or facet of the {_at_link UIComponent} associated
- * with our nearest enclosing {_at_link UIComponentTag}. The process for
- * locating or creating the component is:</p>
- * <ol>
- * <li>If we have previously located this component, return it.</li>
- * <li>Locate the parent component by looking for a parent
- * {_at_link UIComponentTag} instance, and ask it for its component.
- * If there is no parent {_at_link UIComponentTag} instance, this tag
- * represents the root component, so get it from the current
- * <code>Tree</code> and return it.</li>
- * <li>If this {_at_link UIComponentTag} instance has the
- * <code>facetName</code> attribute set, ask the parent
- * {_at_link UIComponent} for a facet with this name. If not found,
- * create one, call <code>setProperties()</code> with the new
- * component as a parameter, and register it under this name.
- * Return the found or created facet {_at_link UIComponent}.</li>
- * <li>Determine the component id to be assigned to the new
- * component, as follows: if this {_at_link UIComponentTag} has
- * an <code>id</code> attribute set, use that value; otherwise,
- * generate an identifier that is guaranteed to be the same for
- * this {_at_link UIComponent} every time this page is processed
- * (i.e. one based on the location of all {_at_link UIComponentTag}
- * instances without an <code>id</code> attribute set).</li>
- * <li>Ask the parent {_at_link UIComponent} for a child with this identifier.
- * If not found, create one, call <code>setProperties()</code>
- * with the new component as a parameter, and register it as a child
- * with this identifier. Return the found or created
- * child {_at_link UIComponent}.</li>
- * </ol>
- * <p>When creating a component, the process is:</p>
- * <ol>
- * <li>Retrieve the component type by calling
- * {_at_link UIComponentTag#getComponentType}</li>
- * <li>If the component has a <code>binding</code> attribute,
- * create a {_at_link ValueBinding} from it, and call
- * {_at_link Application#createComponent} with that {_at_link ValueBinding},
- * the {_at_link FacesContext}, and the component type. Store the
- * {_at_link ValueBinding} using the key <code>"binding"</code> and
- * {_at_link UIComponent#setValueBinding}.</li>
- * <li>Otherwise, call {_at_link Application#createComponent} with
- * only the component type.
- * <li>Call <code>setProperties()</code>.
- * <li>Add the new component as a child or facet of its parent</li>
- * </ol>
- */
- protected UIComponent findComponent(FacesContext context)
- throws JspException {
-
- // Step 1 -- Have we already found the relevant component?
- if (component != null) {
- return (component);
- }
-
- // Step 2 -- Identify the component that is, or will be, our parent
- UIComponentTag parentTag = getParentUIComponentTag(pageContext);
- UIComponent parentComponent = null;
- if (parentTag != null) {
- parentComponent = parentTag.getComponentInstance();
- } else {
- // Special case. The component to be found is the
- // UIViewRoot.
- // see if this is the first time this tag instance is trying
- // to be bound to the UIViewRoot
- parentComponent = context.getViewRoot();
- // Has this UIViewRoot instance had a tag bound to it
- // before?
- if (null ==
- parentComponent.getAttributes().get(CURRENT_VIEW_ROOT)) {
- // No it hasn't.
-
- // make sure setProperties() and setId() are called
- // once per UIViewRoot instance.
- setProperties(parentComponent);
- if (null != this.id) {
- parentComponent.setId(this.id);
- }
- parentComponent.getAttributes().put(CURRENT_VIEW_ROOT,
- CURRENT_VIEW_ROOT);
- created = true;
- }
- else if (binding == null) {
- setProperties(parentComponent);
- created = false;
- }
-
- // this is not the first time this tag instance is trying to
- // be bound to this UIViewRoot, take no extra action.
-
- component = parentComponent;
- return (component);
- }
-
- // Step 3 -- Calculate the component identifier for this component
- String newId = createId();
-
- // Step 4 -- Create or return a facet with the specified name (if any)
- String facetName = getFacetName();
- if (facetName != null) {
- component = (UIComponent)
- parentComponent.getFacets().get(facetName);
- if (component == null) {
- component = createFacet(context, parentComponent, facetName,
- newId);
- }
- return (component);
- }
-
- // Step 5 -- Create or return a child with the specified id
- component = getChild(parentComponent, newId);
- if (component == null) {
- component = createChild(context, parentComponent, newId);
- }
- return (component);
-
- }
-
-
- /**
- * <p>Return the flag value that should be returned from the
- * <code>doEnd()</code> method when it is called. Subclasses
- * may override this method to return the appropriate value.</p>
- *
- * @exception JspException to cause <code>doEnd()</code> to
- * throw an exception
- */
- protected int getDoEndValue() throws JspException {
-
- return (EVAL_PAGE);
-
- }
-
-
- /**
- * <p>Return the flag value that should be returned from the
- * <code>doStart()</code> method when it is called. Subclasses
- * may override this method to return the appropriate value.</p>
- *
- * @exception JspException to cause <code>doStart()</code> to
- * throw an exception
- */
- protected int getDoStartValue() throws JspException {
-
- return (EVAL_BODY_INCLUDE);
-
- }
-
-
- /**
- * <p>Return the {_at_link FacesContext} instance for the current
- * request. This value will be non-<code>null</code> only from the
- * beginning of <code>doStartTag()</code> through the end of
- * <code>doEndTag()</code> for each tag instance.</p>
- */
- protected FacesContext getFacesContext() {
-
- return (context);
-
- }
-
-
- /**
- * <p>Return the facet name that we should be stored under, if any;
- * otherwise, return null (indicating that we will be a child component).
- * </p>
- */
- protected String getFacetName() {
-
- Tag parent = getParent();
- if (parent instanceof FacetTag) {
- return (((FacetTag) parent).getName());
- } else {
- return (null);
- }
-
- }
-
-
- /**
- * <p>Return the <code>id</code> value assigned by the page author.</p>
- */
- protected String getId() {
-
- return (id);
-
- }
-
-
- /**
- * <p>Return <code>true</code> if rendering should be suppressed because
- * of any of the follow reasons.</p>
- * <ul>
- * <li>The component is a facet (whose rendering, if any), is always
- * the responsibility of the owing component.</li>
- * <li>The component has its <code>rendered</code> property set
- * to <code>false</code>.</li>
- * <li>The component is a child of a parent whose
- * <code>rendersChildren</code> is <code>true</code>.</li>
- * <li>The component is a child of a parent whose rendering is itself
- * suppressed.</li>
- * </ul>
- */
- protected boolean isSuppressed() {
-
- return (suppressed);
-
- }
-
-
- /**
- * <p>Override properties and attributes of the specified component,
- * if the corresponding properties of this tag handler instance were
- * explicitly set. This method must be called <strong>ONLY</strong>
- * if the specified {_at_link UIComponent} was in fact created during
- * the execution of this tag handler instance, and this call will occur
- * <strong>BEFORE</strong> the {_at_link UIComponent} is added to
- * the view.</p>
- *
- * <p>Tag subclasses that want to support additional set properties
- * must ensure that the base class <code>setProperties()</code>
- * method is still called. A typical implementation that supports
- * extra properties <code>foo</code> and <code>bar</code> would look
- * something like this:</p>
- * <pre>
- * protected void setProperties(UIComponent component) {
- * super.setProperties(component);
- * if (foo != null) {
- * component.setAttribute("foo", foo);
- * }
- * if (bar != null) {
- * component.setAttribute("bar", bar);
- * }
- * }
- * </pre>
- *
- * <p>The default implementation overrides the following properties:</p>
- * <ul>
- * <li><code>rendered</code> - Set if a value for the
- * <code>rendered</code> property is specified for
- * this tag handler instance.</li>
- * <li><code>rendererType</code> - Set if the <code>getRendererType()</code>
- * method returns a non-null value.</li>
- * </ul>
- *
- * @param component {_at_link UIComponent} whose properties are to be
- * overridden
+ * @param component {_at_inheritDoc}
      */
     protected void setProperties(UIComponent component) {
         // The "id" property is explicitly set when components are created
@@ -885,7 +151,7 @@
         if (rendered != null) {
             if (isValueReference(rendered)) {
                 ValueBinding vb =
- context.getApplication().createValueBinding(rendered);
+ getFacesContext().getApplication().createValueBinding(rendered);
                 component.setValueBinding("rendered", vb);
             } else {
                 component.setRendered(Boolean.valueOf(rendered).booleanValue());
@@ -898,107 +164,17 @@
     }
 
 
- /**
- * <p>Set up the {_at_link ResponseWriter} for the current response,
- * if this has not been done already.</p>
- */
- protected void setupResponseWriter() {
-
- ResponseWriter writer = context.getResponseWriter();
- if (writer == null) {
- RenderKitFactory renderFactory = (RenderKitFactory)
- FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
- RenderKit renderKit =
- renderFactory.getRenderKit
- (context, context.getViewRoot().getRenderKitId());
- writer =
- renderKit.createResponseWriter(new Writer() {
- public void close() throws IOException {
- pageContext.getOut().close();
- }
- public void flush() throws IOException {
- // PENDING(craigmcc) - causes problems with includes
- // pageContext.getOut().flush();
- }
- public void write(char cbuf) throws IOException {
- pageContext.getOut().write(cbuf);
- }
- public void write(char[] cbuf, int off,
- int len) throws IOException {
- pageContext.getOut().write(cbuf, off, len);
- }
- public void write(int c) throws IOException {
- pageContext.getOut().write(c);
- }
- public void write(String str) throws IOException {
- pageContext.getOut().write(str);
- }
- public void write(String str, int off,
- int len) throws IOException {
- pageContext.getOut().write(str, off, len);
- }
- },
-
pageContext.getResponse().getContentType(),
- pageContext.getRequest().getCharacterEncoding());
-
- context.setResponseWriter(writer);
- }
-
- }
-
-
- // --------------------------------------------------------- Private Methods
-
-
- /**
- * <p>Add the component identifier of the specified {_at_link UIComponent}
- * to the list of component identifiers created or located by nested
- * {_at_link UIComponentTag}s processing this request.</p>
- *
- * @param child New child whose identifier should be added
- */
- private void addChild(UIComponent child) {
-
- if (createdComponents == null) {
- createdComponents = new ArrayList();
- }
- createdComponents.add(child.getId());
 
- }
 
 
     /**
- * <p>Add the facet name of the specified facet to the list of
- * facet names created or located by nested {_at_link UIComponentTag}s
- * processing this request.</p>
- *
- * @param name Facet name to be added
+ * <p>Implement <code>createComponent</code> using Faces 1.1 EL
+ * API.</p>
+ *
+ * @param context {_at_inheritDoc}
+ * @param newId {_at_inheritDoc}
      */
- private void addFacet(String name) {
-
- if (createdFacets == null) {
- createdFacets = new ArrayList();
- }
- createdFacets.add(name);
-
- }
-
-
- /**
- * <p>Create and return a new child component of the type returned by
- * calling <code>getComponentType()</code>. If this {_at_link UIComponentTag}
- * has a non-null <code>binding</code> attribute, this is done by
- * call {_at_link Application#createComponent} with the {_at_link ValueBinding}
- * created for the <code>binding</code> attribute, and the
- * {_at_link ValueBinding} will be stored on the component. Otherwise,
- * {_at_link Application#createComponent} is called with only
- * the component type. Finally, initialize the components id
- * and other properties.
- * </p>
- * @param context {_at_link FacesContext} for the current request
- * @param newId id of the component
- */
- private UIComponent createComponent(FacesContext context, String newId) {
+ protected UIComponent createComponent(FacesContext context, String newId) {
         UIComponent component = null;
         Application application = context.getApplication();
         if (binding != null) {
@@ -1017,274 +193,27 @@
     }
 
 
+ // Tag tree navigation
 
     /**
- * <p>Create a new child component using <code>createComponent</code>,
- * initialize its properties, and add it to its parent as a child.
- * </p>
- * @param context {_at_link FacesContext} for the current request
- * @param parent Parent {_at_link UIComponent} for the new child
- * @param componentId Component identifier for the new child,
- * or <code>null</code> for no explicit identifier
- */
- private UIComponent createChild(FacesContext context, UIComponent parent,
- String componentId) {
-
- UIComponent component = createComponent(context, componentId);
- UIComponentTag parentTag = getParentUIComponentTag(pageContext);
- parent.getChildren().add(parentTag.getIndex(), component);
- created = true;
- return (component);
-
- }
-
-
-
-
- /**
- * <p>Create a new child component using <code>createComponent</code>,
- * initialize its properties, and add it to its parent as a facet.
- * </p>
- * @param context {_at_link FacesContext} for the current request
- * @param parent Parent {_at_link UIComponent} of the new facet
- * @param name Name of the new facet
- * @param newId id of the new facet
- */
- private UIComponent createFacet(FacesContext context, UIComponent parent,
- String name, String newId) {
-
- UIComponent component = createComponent(context, newId);
- parent.getFacets().put(name, component);
- created = true;
- return (component);
-
- }
-
-
- /**
- * <p>Create the component identifier to be used for this component.</p>
- */
- private String createId() {
-
- if (this.id == null) {
- FacesContext context =
- (FacesContext) pageContext.getAttribute(CURRENT_FACES_CONTEXT);
- return context.getViewRoot().createUniqueId();
- } else {
- return (this.id);
- }
-
- }
-
-
- /**
- * <p>Return a child with the specified component id from the specified
- * component, if any; otherwise, return <code>null</code>.</p>
+ * <p>Locate and return the nearest enclosing {_at_link UIComponentTag}
+ * if any; otherwise, return <code>null</code>.</p>
      *
- * @param component {_at_link UIComponent} to be searched
- * @param componentId Component id to search for
- */
- private UIComponent getChild(UIComponent component, String componentId) {
-
- Iterator kids = component.getChildren().iterator();
- while (kids.hasNext()) {
- UIComponent kid = (UIComponent) kids.next();
- if (componentId.equals(kid.getId())) {
- return (kid);
- }
- }
- return (null);
-
- }
-
-
- /**
- * <p>Return the child list index to use for a new component to be created
- * by a nested {_at_link UIComponentTag} instance.</p>
- */
- private int getIndex() {
-
- if (createdComponents != null) {
- return (createdComponents.size());
- } else {
- return (0);
- }
-
- }
-
-
- /**
- * <p>Pop the top {_at_link UIComponentTag} instance off of our component tag
- * stack, deleting the stack if this was the last entry.</p>
- */
- private void popUIComponentTag() {
-
- List list = (List) pageContext.getAttribute(COMPONENT_TAG_STACK_ATTR,
- PageContext.REQUEST_SCOPE);
- if (list != null) {
- list.remove(list.size() - 1);
- if (list.size() < 1) {
- pageContext.removeAttribute(COMPONENT_TAG_STACK_ATTR,
- PageContext.REQUEST_SCOPE);
- }
- }
-
- }
-
-
- /**
- * <p>Push the specified {_at_link UIComponentTag} instance onto our component
- * tag stack, creating a stack if necessary.</p>
- */
- private void pushUIComponentTag() {
-
- List list = (List) pageContext.getAttribute(COMPONENT_TAG_STACK_ATTR,
- PageContext.REQUEST_SCOPE);
- if (list == null) {
- list = new ArrayList();
- pageContext.setAttribute(COMPONENT_TAG_STACK_ATTR, list,
- PageContext.REQUEST_SCOPE);
- }
- list.add(this);
-
- }
-
-
- /**
- * <p>Retrieve from the {_at_link UIComponent} corresponding to this tag
- * handler the list of all child component ids created by
- * {_at_link UIComponentTag} instances the previous time this tree was
- * rendered. Compare it to the list of children created during this
- * page processing pass, and remove all children present on the old list
- * but not in the new list. Save the list as a {_at_link UIComponent}
- * attribute so that it gets saved as part of the component's state.</p>
- */
- private void removeOldChildren() {
-
- // Remove old children that are no longer present
- List oldList =
- (List) component.getAttributes().get(JSP_CREATED_COMPONENT_IDS);
- if (oldList != null) {
-
- if (createdComponents != null) {
-
- // Components not in the new list need to be removed
- Iterator olds = oldList.iterator();
- while (olds.hasNext()) {
- String old = (String) olds.next();
- if (!createdComponents.contains(old)) {
- UIComponent child = component.findComponent(old);
- // if a component is marked transient, it would have
- // been already removed from the child list, but the
- // oldList would still have it. So,unless findComponent
- // is successful, we don't have to call remove child.
- if ( child != null) {
- component.getChildren().remove(child);
- }
- }
- }
-
- } else {
-
- // All old components need to be removed
- Iterator olds = oldList.iterator();
- while (olds.hasNext()) {
- String old = (String) olds.next();
- UIComponent child = component.findComponent(old);
- component.getChildren().remove(child);
- }
-
- }
-
- }
-
- // Save the current list as a component attribute
- if (createdComponents != null) {
- component.getAttributes().put(JSP_CREATED_COMPONENT_IDS,
- createdComponents);
- } else {
- component.getAttributes().remove(JSP_CREATED_COMPONENT_IDS);
- }
- createdComponents = null;
-
- }
-
-
- /**
- * <p>Retrieve from the {_at_link UIComponent} corresponding to this tag
- * handler the list of all facet names created by {_at_link UIComponentTag}
- * instances the previous time this tree was rendered. Compare it to the
- * list of facets created during this page processing pass, and remove
- * all facets present on the old list but not in the new list. Save the
- * list as a {_at_link UIComponent} attribute so that it gets saved as part
- * of the component's state.</p>
+ * @param context <code>PageContext</code> for the current page
      */
- private void removeOldFacets() {
-
- // Remove old facets that are no longer present
- List oldList =
- (List) component.getAttributes().get(JSP_CREATED_FACET_NAMES);
- if (oldList != null) {
-
- if (createdFacets != null) {
-
- // Facets not in the new list need to be removed
- Iterator olds = oldList.iterator();
- while (olds.hasNext()) {
- String old = (String) olds.next();
- if (!createdFacets.contains(old)) {
- component.getFacets().remove(old);
- }
- }
-
- } else {
-
- // All old facets need to be removed
- Iterator olds = oldList.iterator();
- while (olds.hasNext()) {
- String old = (String) olds.next();
- component.getFacets().remove(old);
- }
-
- }
-
- }
+ public static UIComponentTag getParentUIComponentTag(PageContext context) {
 
- // Save the current list as a component attribute
- if (createdFacets != null) {
- component.getAttributes().put(JSP_CREATED_FACET_NAMES,
- createdFacets);
- } else {
- component.getAttributes().remove(JSP_CREATED_FACET_NAMES);
- }
- createdFacets = null;
+ // PENDING(): this method may have to wrap the returned thing in
+ // an instance of UIComponentTag if it is not an instance of
+ // UIComponentTag.
+
+ UIComponentClassicTagBase result =
+ getParentUIComponentClassicTagBase(context);
+ return ((UIComponentTag)result);
 
     }
 
 
- /**
- * @see #isSuppressed()
- */
- private boolean shouldBeSuppressed(UIComponentTag parentTag) {
-
- if (getFacetName() != null) {
- return (true);
- }
 
- if (parentTag != null && parentTag.isSuppressed()) {
- return (true);
- }
 
- if (!component.isRendered()) {
- return (true);
- }
-
- UIComponent parent = this.component.getParent();
- if (parent != null && parent.getRendersChildren()) {
- return (true);
- }
-
- return (false);
-
- }
 }
Index: jsf-api/src/javax/faces/webapp/ValidatorTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/src/javax/faces/webapp/ValidatorTag.java,v
retrieving revision 1.19
diff -u -r1.19 ValidatorTag.java
--- jsf-api/src/javax/faces/webapp/ValidatorTag.java 20 Dec 2004 21:25:13 -0000 1.19
+++ jsf-api/src/javax/faces/webapp/ValidatorTag.java 20 Apr 2005 21:24:27 -0000
@@ -53,6 +53,11 @@
  *
  * <p>This tag creates no output to the page currently being created. It
  * is used solely for the side effect of {_at_link Validator} creation.</p>
+ *
+ * @deprecated This has been partially replaced by {_at_link
+ * ValidatorELTag}. The remainder of the functionality, namely, the
+ * binding facility and the implementation of the {_at_link
+ * #createValidator} method, is now an implementation detail.
  */
 
 public class ValidatorTag extends TagSupport {
@@ -117,8 +122,8 @@
         
         
         // Locate our parent UIComponentTag
- UIComponentTag tag =
- UIComponentTag.getParentUIComponentTag(pageContext);
+ UIComponentClassicTagBase tag =
+ UIComponentTag.getParentUIComponentClassicTagBase(pageContext);
         if (tag == null) {
                    //PENDING i18n
             throw new JspException("Not nested in a UIComponentTag Error for
tag with handler class:"+
@@ -143,10 +148,26 @@
 
         validator = createValidator();
         
- if (validator != null) {
- // Register an instance with the appropriate component
- ((EditableValueHolder)component).addValidator(validator);
+ if (validator == null) {
+ String validateError = null;
+ if (binding != null) {
+ validateError = binding;
+ }
+ if (validatorId != null) {
+ if (validateError != null) {
+ validateError += " or " + validatorId;
+ } else {
+ validateError = validatorId;
+ }
+ }
+
+ // PENDING i18n
+ throw new JspException("Can't create class of type:"+
+ "javax.faces.validator.Validator from:"+validateError);
         }
+
+ // Register an instance with the appropriate component
+ ((EditableValueHolder)component).addValidator(validator);
         
         return (SKIP_BODY);
 
@@ -214,10 +235,6 @@
                 throw new JspException(e);
             }
         }
-
- // PENDING - Should log an error if neither "binding" or "validatorId"
- // was set.
-
         return validator;
     }
 
Index: jsf-api/test/javax/faces/webapp/UIComponentTagTestCase.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-api/test/javax/faces/webapp/UIComponentTagTestCase.java,v
retrieving revision 1.25
diff -u -r1.25 UIComponentTagTestCase.java
--- jsf-api/test/javax/faces/webapp/UIComponentTagTestCase.java 26 Feb 2004
20:32:15 -0000 1.25
+++ jsf-api/test/javax/faces/webapp/UIComponentTagTestCase.java 20 Apr 2005
21:24:28 -0000
@@ -11,6 +11,7 @@
 
 
 import java.io.IOException;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -23,6 +24,7 @@
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
 import javax.faces.event.FacesEvent;
 import javax.faces.render.RenderKit;
 import javax.faces.render.RenderKitFactory;
@@ -90,6 +92,55 @@
     }
 
     /**
+ * <p>Since the JSP tag no longer creates the response writer, we
+ * must do it ourselves.</p>
+ */
+
+ public void setUp() throws Exception {
+ super.setUp();
+
+ ResponseWriter writer = facesContext.getResponseWriter();
+ if (writer == null) {
+ RenderKitFactory renderFactory = (RenderKitFactory)
+ FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+ RenderKit renderKit =
+ renderFactory.getRenderKit
+ (facesContext, facesContext.getViewRoot().getRenderKitId());
+ writer =
+ renderKit.createResponseWriter(new Writer() {
+ public void close() throws IOException {
+ pageContext.getOut().close();
+ }
+ public void flush() throws IOException {
+ // PENDING(craigmcc) - causes problems with includes
+ // pageContext.getOut().flush();
+ }
+ public void write(char cbuf) throws IOException {
+ pageContext.getOut().write(cbuf);
+ }
+ public void write(char[] cbuf, int off,
+ int len) throws IOException {
+ pageContext.getOut().write(cbuf, off, len);
+ }
+ public void write(int c) throws IOException {
+ pageContext.getOut().write(c);
+ }
+ public void write(String str) throws IOException {
+ pageContext.getOut().write(str);
+ }
+ public void write(String str, int off,
+ int len) throws IOException {
+ pageContext.getOut().write(str, off, len);
+ }
+ },
+ null,
+ pageContext.getRequest().getCharacterEncoding());
+
+ facesContext.setResponseWriter(writer);
+ }
+ }
+
+ /**
      * Tear down instance variables required by this test case.
      */
     public void tearDown() throws Exception {
@@ -404,6 +455,13 @@
         if (root != null) {
             render(root);
         }
+
+ try {
+ facesContext.getViewRoot().encodeAll(facesContext);
+ }
+ catch (IOException e) {
+ throw new JspException(e);
+ }
 
     }

SECTION: RI Diffs
 
Index: jsf-ri/conf/test/web.xml
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/conf/test/web.xml,v
retrieving revision 1.23
diff -u -r1.23 web.xml
--- jsf-ri/conf/test/web.xml 5 Apr 2005 22:03:01 -0000 1.23
+++ jsf-ri/conf/test/web.xml 20 Apr 2005 21:24:28 -0000
@@ -6,12 +6,10 @@
 -->
 
 
-<!DOCTYPE web-app
- PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/j2ee/dtds/web-app_2.3.dtd">
-
-<web-app>
-
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+ version="2.4">
     <context-param>
         <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
         <param-value>server</param-value>
Index: jsf-ri/src/com/sun/faces/RIConstants.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/RIConstants.java,v
retrieving revision 1.70
diff -u -r1.70 RIConstants.java
--- jsf-ri/src/com/sun/faces/RIConstants.java 11 Mar 2005 18:14:03 -0000 1.70
+++ jsf-ri/src/com/sun/faces/RIConstants.java 20 Apr 2005 21:24:28 -0000
@@ -54,6 +54,9 @@
     public static final String STATE_MAP = FACES_PREFIX +
         "saveStateMap";
 
+ public static final String SAVED_STATE = FACES_PREFIX + "savedState";
+
+
     /**
      * <p>Parser implementation for processing JSF reference expressions.</p>
      */
Index: jsf-ri/src/com/sun/faces/application/StateManagerImpl.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/StateManagerImpl.java,v
retrieving revision 1.28
diff -u -r1.28 StateManagerImpl.java
--- jsf-ri/src/com/sun/faces/application/StateManagerImpl.java 5 Apr 2005
20:25:13 -0000 1.28
+++ jsf-ri/src/com/sun/faces/application/StateManagerImpl.java 20 Apr 2005
21:24:28 -0000
@@ -70,9 +70,9 @@
             return result;
         }
         
- // honor the transient property and remove children from the tree
- // that are marked transient.
- removeTransientChildrenAndFacets(context, viewRoot, new HashSet());
+ // honor the requirement to check for id uniqueness
+ checkIdUniqueness(context, viewRoot, new HashSet());
+
         
          if (logger.isLoggable(Level.FINE)) {
             logger.fine("Begin creating serialized view for "
@@ -118,7 +118,7 @@
     }
 
 
- protected void removeTransientChildrenAndFacets(FacesContext context,
+ protected void checkIdUniqueness(FacesContext context,
         UIComponent component, Set componentIds) throws IllegalStateException{
         UIComponent kid;
         // deal with children that are marked transient.
@@ -137,11 +137,7 @@
                         new Object[]{id}));
             }
 
- if (kid.isTransient()) {
- kids.remove();
- } else {
- removeTransientChildrenAndFacets(context, kid, componentIds);
- }
+ checkIdUniqueness(context, kid, componentIds);
         }
         // deal with facets that are marked transient.
         kids = component.getFacets().values().iterator();
@@ -158,19 +154,14 @@
                         new Object[]{id}));
             }
 
- if (kid.isTransient()) {
- kids.remove();
- } else {
- removeTransientChildrenAndFacets(context, kid, componentIds);
- }
+ checkIdUniqueness(context, kid, componentIds);
 
         }
     }
 
 
     protected Object getComponentStateToSave(FacesContext context) {
- UIViewRoot viewRoot = context.getViewRoot();
- return viewRoot.processSaveState(context);
+ return context.getViewRoot().processSaveState(context);
     }
 
 
Index: jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java,v
retrieving revision 1.49
diff -u -r1.49 ViewHandlerImpl.java
--- jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java 5 Apr 2005
20:25:14 -0000 1.49
+++ jsf-ri/src/com/sun/faces/application/ViewHandlerImpl.java 20 Apr 2005
21:24:29 -0000
@@ -13,25 +13,36 @@
 
 package com.sun.faces.application;
 
-import com.sun.faces.RIConstants;
-import com.sun.faces.util.Util;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.logging.Level;
 
 import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.application.StateManager;
+import javax.faces.application.StateManager.SerializedView;
 import javax.faces.application.ViewHandler;
+import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.RenderKit;
 import javax.faces.render.RenderKitFactory;
 import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import javax.servlet.jsp.jstl.core.Config;
 
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.logging.Logger;
-import java.util.logging.Level;
+import com.sun.faces.RIConstants;
+import com.sun.faces.util.Util;
+
 
 /**
  * <B>ViewHandlerImpl</B> is the default implementation class for ViewHandler.
@@ -46,6 +57,9 @@
     static {
         logger = Util.getLogger(Util.FACES_LOGGER);
     }
+
+ private static final String AFTER_VIEW_CONTENT = RIConstants.FACES_PREFIX+
+ "AFTER_VIEW_CONTENT";
     
     /**
      * <p>The <code>request</code> scoped attribute to store the
@@ -71,72 +85,181 @@
             logger.log(Level.FINE,"Created ViewHandler instance ");
         }
     }
+
+
+ public void renderView(FacesContext context,
+ UIViewRoot viewToRender) throws IOException,
+ FacesException {
+
+ // suppress rendering if "rendered" property on the component is
+ // false
+ if (!viewToRender.isRendered()) {
+ return;
+ }
+
+ System.out.println("debug: edburns: ++++++++++++++++ tree before executing page");
+ System.out.println(com.sun.faces.util.DebugUtil.printTree(viewToRender));
 
+ try {
+ executePageToBuildView(context, viewToRender);
+ } catch (IOException e) {
+ throw new FacesException(e);
+ }
 
- public void renderView(FacesContext context,
- UIViewRoot viewToRender) throws IOException,
- FacesException {
+ if (logger.isLoggable(Level.FINE)) {
+ String treePrintout =
+ com.sun.faces.util.DebugUtil.printTree(viewToRender);
+ logger.log(Level.FINE, "View after executing page: \n" +
+ treePrintout);
+ }
+ System.out.println("debug: edburns: ++++++++++++++++ tree after executing page");
+ System.out.println(com.sun.faces.util.DebugUtil.printTree(viewToRender));
 
- if (null == context || null == viewToRender) {
- String message = Util.getExceptionMessageString
- (Util.NULL_PARAMETERS_ERROR_MESSAGE_ID);
- message = message + " context " + context + " viewToRender " +
- viewToRender;
- throw new NullPointerException(message);
+
+ // set up the ResponseWriter
+
+ RenderKitFactory renderFactory = (RenderKitFactory)
+ FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+ RenderKit renderKit =
+ renderFactory.getRenderKit(context, viewToRender.getRenderKitId());
+ ExternalContext extContext = context.getExternalContext();
+ ServletRequest request = (ServletRequest) extContext.getRequest();
+ ServletResponse response = (ServletResponse) extContext.getResponse();
+
+ ResponseWriter oldWriter = context.getResponseWriter();
+ ResponseWriter newWriter = null;
+ if (null != oldWriter) {
+ newWriter = oldWriter.cloneWithWriter(response.getWriter());
+ }
+ else {
+ newWriter = renderKit.createResponseWriter(response.getWriter(),
+ null,
+ request.getCharacterEncoding());
+ }
+ context.setResponseWriter(newWriter);
+
+ newWriter.startDocument();
+
+ doRenderView(context, viewToRender);
+
+ newWriter.endDocument();
+
+ if (null != oldWriter) {
+ context.setResponseWriter(oldWriter);
         }
-
+
+ if
(!context.getExternalContext().getRequestMap().containsKey(RIConstants.SAVED_STATE))
{
+ // if we didn't serialize the state, or we didn't save it in
+ // the client, we need to manually remove the transient
+ // children and facets.
+ removeTransientChildrenAndFacets(context, viewToRender,
+ new HashSet());
+ }
+ }
+
+ /**
+ * <p>This is a separate method to account for handling the content
+ * after the view tag.</p>
+ *
+ * <p>Create a new ResponseWriter around this response's Writer.
+ * Set it into the FacesContext, saving the old one aside.</p>
+ *
+ * <p>call encodeBegin(), encodeChildren(), encodeEnd() on the
+ * argument <code>UIViewRoot</code>.</p>
+ *
+ * <p>Restore the old ResponseWriter into the FacesContext.</p>
+ *
+ * <p>Write out the after view content to the response's writer.</p>
+ *
+ * <p>Flush the response buffer, and remove the after view content
+ * from the request scope.</p>
+ */
+
+ private void doRenderView(FacesContext context,
+ UIViewRoot viewToRender) throws IOException,
+ FacesException {
+ ExternalContext extContext = context.getExternalContext();
+ ServletResponse response = (ServletResponse) extContext.getResponse();
+
+ Object view =
+ Util.getStateManager(context).saveSerializedView(context);
+ extContext.getRequestMap().put(RIConstants.SAVED_STATE, view);
+
         ApplicationAssociate associate =
- ApplicationAssociate.getInstance(context.getExternalContext());
+ ApplicationAssociate.getInstance(extContext);
         
         if (null != associate) {
             associate.responseRendered();
         }
- String requestURI = viewToRender.getViewId();
+
         if (logger.isLoggable(Level.FINE)) {
- logger.log(Level.FINE, "About to render view " + requestURI);
+ logger.log(Level.FINE, "About to render view " +
viewToRender.getViewId());
         }
-
- String mapping = getFacesMapping(context);
- String newViewId = requestURI;
- // If we have a valid mapping (meaning we were invoked via the
- // FacesServlet) and we're extension mapped, do the replacement.
- if (mapping != null && !isPrefixMapped(mapping)) {
- if (logger.isLoggable(Level.FINE)) {
- logger.fine( "Found URL pattern mapping to FacesServlet "
- + mapping);
- }
- newViewId = convertViewId(context, requestURI);
+
+ viewToRender.encodeAll(context);
+
+ // write any AFTER_VIEW_CONTENT to the response
+ Object content = extContext.getRequestMap().get(AFTER_VIEW_CONTENT);
+ assert(null != content);
+ if (content instanceof byte []) {
+ response.getWriter().write(new String((byte[]) content));
+ } else if (content instanceof char []) {
+ response.getWriter().write((char []) content);
         } else {
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Found no URL patterns mapping to FacesServlet ");
- }
+ assert(false);
         }
-
-
- viewToRender.setViewId(newViewId);
-
- // update the JSTL locale attribute in request scope so that JSTL
- // picks up the locale from viewRoot. This attribute must be updated
- // before the JSTL setBundle tag is called because that is when the
- // new LocalizationContext object is created based on the locale.
- // PENDING: this only works for servlet based requests
- if (context.getExternalContext().getRequest()
- instanceof ServletRequest) {
- Config.set((ServletRequest)
- context.getExternalContext().getRequest(),
- Config.FMT_LOCALE, context.getViewRoot().getLocale());
- }
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Before dispacthMessage to newViewId " + newViewId);
+
+ response.flushBuffer(); // PENDING(edburns): necessary?
+
+ // remove the AFTER_VIEW_CONTENT from the view root
+ extContext.getRequestMap().remove(AFTER_VIEW_CONTENT);
+
+
+ }
+
+ private void removeTransientChildrenAndFacets(FacesContext context,
+ UIComponent component, Set componentIds) throws IllegalStateException{
+ UIComponent kid;
+ // deal with children that are marked transient.
+ Iterator kids = component.getChildren().iterator();
+ String id;
+ while (kids.hasNext()) {
+ kid = (UIComponent) kids.next();
+ // check for id uniqueness
+ id = kid.getClientId(context);
+ if (id != null && !componentIds.add(id)) {
+ throw new IllegalStateException(Util.getExceptionMessageString(
+ Util.DUPLICATE_COMPONENT_ID_ERROR_ID,
+ new Object[]{id}));
+ }
+
+ if (kid.isTransient()) {
+ kids.remove();
+ } else {
+ removeTransientChildrenAndFacets(context, kid, componentIds);
+ }
         }
- context.getExternalContext().dispatch(newViewId);
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("After dispacthMessage to newViewId " + newViewId);
+ // deal with facets that are marked transient.
+ kids = component.getFacets().values().iterator();
+ while (kids.hasNext()) {
+ kid = (UIComponent) kids.next();
+ // check for id uniqueness
+ id = kid.getClientId(context);
+ if (id != null && !componentIds.add(id)) {
+ throw new IllegalStateException(Util.getExceptionMessageString(
+ Util.DUPLICATE_COMPONENT_ID_ERROR_ID,
+ new Object[]{id}));
+ }
+
+ if (kid.isTransient()) {
+ kids.remove();
+ } else {
+ removeTransientChildrenAndFacets(context, kid, componentIds);
+ }
+
         }
-
     }
-
-
+
     public UIViewRoot restoreView(FacesContext context, String viewId) {
         if (context == null) {
             String message = Util.getExceptionMessageString
@@ -149,23 +272,28 @@
 
         // set the request character encoding. NOTE! This MUST be done
         // before any request praameter is accessed.
+
+ /*
+ HttpServletRequest request =
+ (HttpServletRequest) extContext.getRequest();
+ */
         Map headerMap = extContext.getRequestHeaderMap();
         String
- contentType = null,
- charEnc = null;
-
+ contentType = null,
+ charEnc = null;
+
         // look for a charset in the Content-Type header first.
         if (null != (contentType = (String) headerMap.get("Content-Type"))) {
             // see if this header had a charset
             String charsetStr = "charset=";
             int
- len = charsetStr.length(),
- i = 0;
-
+ len = charsetStr.length(),
+ i = 0;
+
             // if we have a charset in this Content-Type header AND it
             // has a non-zero length.
             if (-1 != (i = contentType.indexOf(charsetStr)) &&
- (i + len < contentType.length())) {
+ (i + len < contentType.length())) {
                 charEnc = contentType.substring(i + len);
             }
         }
@@ -173,7 +301,7 @@
         if (null == charEnc) {
             if (null != extContext.getSession(false)) {
                 charEnc = (String) extContext.getSessionMap().get
- (CHARACTER_ENCODING_KEY);
+ (CHARACTER_ENCODING_KEY);
             }
         }
         if (null != charEnc) {
@@ -196,49 +324,15 @@
 
         String mapping = getFacesMapping(context);
         UIViewRoot viewRoot = null;
-
- if (mapping != null && !isPrefixMapped(mapping)) {
- viewId = convertViewId(context, viewId);
- }
         
- // this is necessary to allow decorated impls.
- ViewHandler outerViewHandler =
- context.getApplication().getViewHandler();
- String renderKitId =
- outerViewHandler.calculateRenderKitId(context);
- viewRoot = Util.getStateManager(context).restoreView(context, viewId,
- renderKitId);
-
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Restored View Tree");
- logger.fine(com.sun.faces.util.DebugUtil.printTree(viewRoot));
- }
-
- return viewRoot;
- }
-
-
- public UIViewRoot createView(FacesContext context, String viewId) {
- if (context == null) {
- String message = Util.getExceptionMessageString
- (Util.NULL_PARAMETERS_ERROR_MESSAGE_ID);
- message = message +"context " + context;
- throw new NullPointerException(message);
- }
-
- ExternalContext extContext = context.getExternalContext();
- String mapping = getFacesMapping(context);
- UIViewRoot result = new UIViewRoot();
-
         if (mapping != null && !isPrefixMapped(mapping)) {
             viewId = convertViewId(context, viewId);
         }
- result.setViewId(viewId);
         
         // maping could be null if a non-faces request triggered
         // this response.
         if (extContext.getRequestPathInfo() == null && mapping != null &&
- isPrefixMapped(mapping) && viewId.equals(mapping)) {
+ isPrefixMapped(mapping)) {
             // this was probably an initial request
             // send them off to the root of the web application
             try {
@@ -247,10 +341,30 @@
                     logger.log(Level.FINE, "Response Complete for" + viewId);
                 }
                 extContext.redirect(extContext.getRequestContextPath());
- return result;
             } catch (IOException ioe) {
                 throw new FacesException(ioe);
             }
+ } else {
+ // this is necessary to allow decorated impls.
+ ViewHandler outerViewHandler =
+ context.getApplication().getViewHandler();
+ String renderKitId =
+ outerViewHandler.calculateRenderKitId(context);
+ viewRoot = Util.getStateManager(context).restoreView(context,
+ viewId,
+ renderKitId);
+ }
+
+ return viewRoot;
+ }
+
+
+ public UIViewRoot createView(FacesContext context, String viewId) {
+ if (context == null) {
+ String message = Util.getExceptionMessageString
+ (Util.NULL_PARAMETERS_ERROR_MESSAGE_ID);
+ message = message +"context " + context;
+ throw new NullPointerException(message);
         }
 
         Locale locale = null;
@@ -263,6 +377,9 @@
             locale = context.getViewRoot().getLocale();
             renderKitId = context.getViewRoot().getRenderKitId();
         }
+ UIViewRoot result = new UIViewRoot();
+ result.setViewId(viewId);
+
         if (logger.isLoggable(Level.FINE)) {
             logger.log(Level.FINE, "Created new view for " + viewId);
         }
@@ -307,8 +424,86 @@
 
         return result;
     }
-
-
+
+ private void executePageToBuildView(FacesContext context,
+ UIViewRoot viewToExecute) throws IOException, FacesException {
+
+ if (null == context || null == viewToExecute) {
+ String message = Util.getExceptionMessageString
+ (Util.NULL_PARAMETERS_ERROR_MESSAGE_ID);
+ message = message + " context " + context + " viewToExecute " +
+ viewToExecute;
+ throw new NullPointerException(message);
+ }
+
+ String requestURI = viewToExecute.getViewId();
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("About to execute view " + requestURI);
+ }
+
+ String mapping = getFacesMapping(context);
+ String newViewId = requestURI;
+ // If we have a valid mapping (meaning we were invoked via the
+ // FacesServlet) and we're extension mapped, do the replacement.
+ if (mapping != null && !isPrefixMapped(mapping)) {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine( "Found URL pattern mapping to FacesServlet "
+ + mapping);
+ }
+ newViewId = convertViewId(context, requestURI);
+ } else {
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Found no URL patterns mapping to FacesServlet ");
+ }
+ }
+
+
+ viewToExecute.setViewId(newViewId);
+ ExternalContext extContext = context.getExternalContext();
+
+ // update the JSTL locale attribute in request scope so that JSTL
+ // picks up the locale from viewRoot. This attribute must be updated
+ // before the JSTL setBundle tag is called because that is when the
+ // new LocalizationContext object is created based on the locale.
+ // PENDING: this only works for servlet based requests
+ if (extContext.getRequest()
+ instanceof ServletRequest) {
+ Config.set((ServletRequest)
+ extContext.getRequest(),
+ Config.FMT_LOCALE, context.getViewRoot().getLocale());
+ }
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Before dispacthMessage to newViewId " + newViewId);
+ }
+
+ // save the original response
+ Object originalResponse = extContext.getResponse();
+
+ // replace the response with our wrapper
+ ViewHandlerResponseWrapper wrapped = null;
+ extContext.setResponse(wrapped = new
ViewHandlerResponseWrapper((HttpServletResponse)extContext.getResponse()));
+
+ // build the view by executing the page
+ extContext.dispatch(newViewId);
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("After dispacthMessage to newViewId " + newViewId);
+ }
+
+ // Put the AFTER_VIEW_CONTENT into request scope
+ // temporarily
+ if (wrapped.isBytes()) {
+ extContext.getRequestMap().put(AFTER_VIEW_CONTENT,
+ wrapped.getBytes());
+ } else if (wrapped.isChars()) {
+ extContext.getRequestMap().put(AFTER_VIEW_CONTENT,
+ wrapped.getChars());
+ }
+
+ // replace the original response
+ extContext.setResponse(originalResponse);
+ }
+
+
     public Locale calculateLocale(FacesContext context) {
 
         if (context == null) {
@@ -387,27 +582,27 @@
                 }
             }
         }
- // if it's not in the supported locales,
- if (null == result) {
- Locale defaultLocale = context.getApplication().getDefaultLocale();
- if (defaultLocale != null) {
- if ( perf.equals(defaultLocale)) {
- // exact match
- result = defaultLocale;
- } else {
- // Make sure the preferred locale doesn't have country
- // set, when doing a language match, For ex., if the
- // preferred locale is "en-US", if one of supported
- // locales is "en-UK", even though its language matches
- // that of the preferred locale, we must ignore it.
- if (perf.getLanguage().equals(defaultLocale.getLanguage()) &&
- defaultLocale.getCountry().equals("")) {
+ // if it's not in the supported locales,
+ if (null == result) {
+ Locale defaultLocale = context.getApplication().getDefaultLocale();
+ if (defaultLocale != null) {
+ if ( perf.equals(defaultLocale)) {
+ // exact match
                     result = defaultLocale;
+ } else {
+ // Make sure the preferred locale doesn't have country
+ // set, when doing a language match, For ex., if the
+ // preferred locale is "en-US", if one of supported
+ // locales is "en-UK", even though its language matches
+ // that of the preferred locale, we must ignore it.
+ if (perf.getLanguage().equals(defaultLocale.getLanguage()) &&
+ defaultLocale.getCountry().equals("")) {
+ result = defaultLocale;
+ }
                 }
             }
         }
- }
-
+
         return result;
     }
 
@@ -419,17 +614,26 @@
             message = message +"context " + context;
             throw new NullPointerException(message);
         }
+ StateManager stateManager = Util.getStateManager(context);
         
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("Begin writing state to response for viewId " +
- context.getViewRoot().getViewId());
- }
- context.getResponseWriter().writeText(
- RIConstants.SAVESTATE_FIELD_MARKER, null);
- if (logger.isLoggable(Level.FINE)) {
- logger.fine("End writing state to response for viewId " +
- context.getViewRoot().getViewId());
- }
+ if (stateManager.isSavingStateInClient(context)) {
+ SerializedView viewState = (SerializedView)
+
context.getExternalContext().getRequestMap().get(RIConstants.SAVED_STATE);
+ assert(null != viewState);
+
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("Begin writing state to response for viewId " +
+ context.getViewRoot().getViewId());
+ }
+
+ // write out the state
+ stateManager.writeState(context, viewState);
+
+ if (logger.isLoggable(Level.FINE)) {
+ logger.fine("End writing state to response for viewId " +
+ context.getViewRoot().getViewId());
+ }
+ }
         
     }
 
@@ -444,13 +648,12 @@
         }
 
         if (viewId.charAt(0) != '/') {
+ String message =
Util.getExceptionMessageString(Util.ILLEGAL_VIEW_ID_ID,
+ new Object[]{viewId});
             if (logger.isLoggable(Level.SEVERE)) {
                 logger.log(Level.SEVERE, "jsf.illegal_view_id_error", viewId);
             }
- String message =
- Util.getExceptionMessageString(Util.ILLEGAL_VIEW_ID_ID,
- new Object[]{viewId});
- throw new IllegalArgumentException(message);
+ throw new IllegalArgumentException(message);
         }
         
         // Acquire the context path, which we will prefix on all results
@@ -586,7 +789,6 @@
             logger.log(Level.FINE, "servletPath " + servletPath);
             logger.log(Level.FINE, "pathInfo " + pathInfo);
         }
-
         // If the path returned by HttpServletRequest.getServletPath()
         // returns a zero-length String, then the FacesServlet has
         // been mapped to '/*'.
Index: jsf-ri/src/com/sun/faces/context/ExternalContextImpl.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/context/ExternalContextImpl.java,v
retrieving revision 1.27
diff -u -r1.27 ExternalContextImpl.java
--- jsf-ri/src/com/sun/faces/context/ExternalContextImpl.java 12 Mar 2005
19:06:16 -0000 1.27
+++ jsf-ri/src/com/sun/faces/context/ExternalContextImpl.java 20 Apr 2005
21:24:30 -0000
@@ -38,6 +38,8 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.Collections;
+import java.util.HashMap;
 
 /**
  * <p>This implementation of {_at_link ExternalContext} is specific to the
@@ -55,14 +57,16 @@
     private ApplicationMap applicationMap = null;
     private SessionMap sessionMap = null;
     private RequestMap requestMap = null;
- private RequestParameterMap requestParameterMap = null;
- private RequestParameterValuesMap requestParameterValuesMap = null;
- private RequestHeaderMap requestHeaderMap = null;
- private RequestHeaderValuesMap requestHeaderValuesMap = null;
- private RequestCookieMap cookieMap = null;
- private InitParameterMap initParameterMap = null;
-
-
+ private Map requestParameterMap = null;
+ private Map requestParameterValuesMap = null;
+ private Map requestHeaderMap = null;
+ private Map requestHeaderValuesMap = null;
+ private Map cookieMap = null;
+ private Map initParameterMap = null;
+
+ static Class theUnmodifiableMapClass =
+ Collections.unmodifiableMap(new HashMap()).getClass();
+
     public ExternalContextImpl(ServletContext sc, ServletRequest request,
                                ServletResponse response) {
 
@@ -160,8 +164,8 @@
 
     public Map getRequestHeaderMap() {
         if (null == requestHeaderMap) {
- requestHeaderMap =
- new RequestHeaderMap((HttpServletRequest) request);
+ requestHeaderMap =
+ Collections.unmodifiableMap(new
RequestHeaderMap((HttpServletRequest) request));
         }
         return requestHeaderMap;
     }
@@ -169,8 +173,8 @@
 
     public Map getRequestHeaderValuesMap() {
         if (null == requestHeaderValuesMap) {
- requestHeaderValuesMap =
- new RequestHeaderValuesMap((HttpServletRequest) request);
+ requestHeaderValuesMap =
+ Collections.unmodifiableMap(new
RequestHeaderValuesMap((HttpServletRequest) request));
         }
         return requestHeaderValuesMap;
     }
@@ -178,7 +182,8 @@
 
     public Map getRequestCookieMap() {
         if (null == cookieMap) {
- cookieMap = new RequestCookieMap((HttpServletRequest) request);
+ cookieMap =
+ Collections.unmodifiableMap(new
RequestCookieMap((HttpServletRequest) request));
         }
         return cookieMap;
     }
@@ -186,7 +191,8 @@
 
     public Map getInitParameterMap() {
         if (null == initParameterMap) {
- initParameterMap = new InitParameterMap(servletContext);
+ initParameterMap =
+ Collections.unmodifiableMap(new InitParameterMap(servletContext));
         }
         return initParameterMap;
     }
@@ -194,7 +200,8 @@
 
     public Map getRequestParameterMap() {
         if (null == requestParameterMap) {
- requestParameterMap = new RequestParameterMap(request);
+ requestParameterMap =
+ Collections.unmodifiableMap(new RequestParameterMap(request));
         }
         return requestParameterMap;
     }
@@ -202,7 +209,8 @@
 
     public Map getRequestParameterValuesMap() {
         if (null == requestParameterValuesMap) {
- requestParameterValuesMap = new RequestParameterValuesMap(request);
+ requestParameterValuesMap =
+ Collections.unmodifiableMap(new RequestParameterValuesMap(request));
         }
         return requestParameterValuesMap;
     }
@@ -696,8 +704,10 @@
 
 
     public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RequestParameterMap))
+ if (obj == null ||
+ !(obj.getClass() == ExternalContextImpl.theUnmodifiableMapClass)) {
             return false;
+ }
         return super.equals(obj);
     }
 } // END RequestParameterMap
@@ -736,8 +746,10 @@
 
 
     public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RequestParameterValuesMap))
+ if (obj == null ||
+ !(obj.getClass() == ExternalContextImpl.theUnmodifiableMapClass)) {
             return false;
+ }
         return super.equals(obj);
     }
 } // END RequestParameterValuesMap
@@ -775,8 +787,10 @@
 
 
     public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RequestHeaderMap))
+ if (obj == null ||
+ !(obj.getClass() == ExternalContextImpl.theUnmodifiableMapClass)) {
             return false;
+ }
         return super.equals(obj);
     }
 } // END RequestHeaderMap
@@ -814,8 +828,10 @@
 
 
     public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RequestHeaderValuesMap))
+ if (obj == null ||
+ !(obj.getClass() == ExternalContextImpl.theUnmodifiableMapClass)) {
             return false;
+ }
         return super.equals(obj);
     }
 
@@ -927,8 +943,10 @@
 
 
     public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof RequestCookieMap))
+ if (obj == null ||
+ !(obj.getClass() == ExternalContextImpl.theUnmodifiableMapClass)) {
             return false;
+ }
         return super.equals(obj);
     }
 } // END RequestCookiesMap
@@ -970,8 +988,10 @@
 
 
     public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof InitParameterMap))
+ if (obj == null ||
+ !(obj.getClass() == ExternalContextImpl.theUnmodifiableMapClass)) {
             return false;
+ }
         return super.equals(obj);
     }
 } // END InitParameterMap
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/ButtonRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/ButtonRenderer.java,v
retrieving revision 1.83
diff -u -r1.83 ButtonRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/ButtonRenderer.java 15 Apr
2005 21:19:38 -0000 1.83
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/ButtonRenderer.java 20 Apr
2005 21:24:31 -0000
@@ -208,16 +208,6 @@
         }
     }
 
-
- public void encodeChildren(FacesContext context, UIComponent component)
- throws IOException {
- if (context == null || component == null) {
- throw new NullPointerException(Util.getExceptionMessageString(
- Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
         if (context == null || component == null) {
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/CheckboxRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/CheckboxRenderer.java,v
retrieving revision 1.70
diff -u -r1.70 CheckboxRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/CheckboxRenderer.java 16 Dec
2004 17:56:37 -0000 1.70
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/CheckboxRenderer.java 20 Apr
2005 21:24:31 -0000
@@ -143,16 +143,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component)
- throws IOException {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
-
- }
-
-
     protected void getEndTextToRender(FacesContext context, UIComponent component,
                                       String currentValue) throws IOException {
 
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/FormRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/FormRenderer.java,v
retrieving revision 1.84
diff -u -r1.84 FormRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/FormRenderer.java 15 Apr 2005
21:19:38 -0000 1.84
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/FormRenderer.java 20 Apr 2005
21:24:31 -0000
@@ -162,15 +162,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
-
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
         if (context == null || component == null) {
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/HiddenRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/HiddenRenderer.java,v
retrieving revision 1.22
diff -u -r1.22 HiddenRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/HiddenRenderer.java 14 Mar
2005 23:41:08 -0000 1.22
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/HiddenRenderer.java 20 Apr
2005 21:24:31 -0000
@@ -71,14 +71,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(Util.getExceptionMessageString(
- Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     protected void getEndTextToRender(FacesContext context,
                                       UIComponent component, String currentValue)
         throws IOException {
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java,v
retrieving revision 1.89
diff -u -r1.89 HtmlBasicRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java 28 Feb
2005 18:48:20 -0000 1.89
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/HtmlBasicRenderer.java 20 Apr
2005 21:24:31 -0000
@@ -146,6 +146,9 @@
         }
     }
 
+ public boolean getRendersChildren() {
+ return true;
+ }
 
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
@@ -186,6 +189,58 @@
 
 
     /**
+ * <p>Render nested child components by invoking the encode methods
+ * on those components, but only when the <code>rendered</code>
+ * property is <code>true</code>.</p>
+ */
+ protected void encodeRecursive(FacesContext context, UIComponent component)
+ throws IOException {
+
+ // suppress rendering if "rendered" property on the component is
+ // false.
+ if (!component.isRendered()) {
+ return;
+ }
+
+ // Render this component and its children recursively
+ component.encodeBegin(context);
+ if (component.getRendersChildren()) {
+ component.encodeChildren(context);
+ } else {
+ Iterator kids = getChildren(component);
+ while (kids.hasNext()) {
+ UIComponent kid = (UIComponent) kids.next();
+ encodeRecursive(context, kid);
+ }
+ }
+ component.encodeEnd(context);
+ }
+
+
+ /**
+ * <p>Return an Iterator over the children of the specified
+ * component, selecting only those that have a
+ * <code>rendered</code> property of <code>true</code>.</p>
+ *
+ * @param component <code>UIComponent</code> for which to extract children
+ */
+ protected Iterator getChildren(UIComponent component) {
+
+ List results = new ArrayList();
+ Iterator kids = component.getChildren().iterator();
+ while (kids.hasNext()) {
+ UIComponent kid = (UIComponent) kids.next();
+ if (kid.isRendered()) {
+ results.add(kid);
+ }
+ }
+ return (results.iterator());
+
+ }
+
+
+
+ /**
      * Gets value to be rendered and formats it if required. Sets to empty
      * string if value is null.
      */
@@ -425,58 +480,6 @@
         return retComp;
     }
 
-
- /**
- * <p>Render nested child components by invoking the encode methods
- * on those components, but only when the <code>rendered</code>
- * property is <code>true</code>.</p>
- */
- protected void encodeRecursive(FacesContext context, UIComponent component)
- throws IOException {
-
- // suppress rendering if "rendered" property on the component is
- // false.
- if (!component.isRendered()) {
- return;
- }
-
- // Render this component and its children recursively
- component.encodeBegin(context);
- if (component.getRendersChildren()) {
- component.encodeChildren(context);
- } else {
- Iterator kids = getChildren(component);
- while (kids.hasNext()) {
- UIComponent kid = (UIComponent) kids.next();
- encodeRecursive(context, kid);
- }
- }
- component.encodeEnd(context);
- }
-
-
- /**
- * <p>Return an Iterator over the children of the specified
- * component, selecting only those that have a
- * <code>rendered</code> property of <code>true</code>.</p>
- *
- * @param component <code>UIComponent</code> for which to extract children
- */
- protected Iterator getChildren(UIComponent component) {
-
- List results = new ArrayList();
- Iterator kids = component.getChildren().iterator();
- while (kids.hasNext()) {
- UIComponent kid = (UIComponent) kids.next();
- if (kid.isRendered()) {
- results.add(kid);
- }
- }
- return (results.iterator());
-
- }
-
-
     /**
      * <p>Return the specified facet from the specified component, but
      * <strong>only</strong> if its <code>rendered</code> property is
@@ -517,7 +520,7 @@
             } catch (IOException e) {
                 if (log.isDebugEnabled()) {
                     // PENDING I18N
- log.debug("Can't write ID attribute", e);
+ log.debug("Can't write ID attribute" + e.getMessage());
                 }
             }
         }
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/ImageRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/ImageRenderer.java,v
retrieving revision 1.36
diff -u -r1.36 ImageRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/ImageRenderer.java 16 Dec 2004
17:56:37 -0000 1.36
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/ImageRenderer.java 20 Apr 2005
21:24:32 -0000
@@ -80,14 +80,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
         ResponseWriter writer = null;
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/LabelRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/LabelRenderer.java,v
retrieving revision 1.35
diff -u -r1.35 LabelRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/LabelRenderer.java 23 Feb 2005
21:57:44 -0000 1.35
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/LabelRenderer.java 20 Apr 2005
21:24:32 -0000
@@ -155,14 +155,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
 
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/MenuRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/MenuRenderer.java,v
retrieving revision 1.55
diff -u -r1.55 MenuRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/MenuRenderer.java 18 Mar 2005
20:10:16 -0000 1.55
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/MenuRenderer.java 20 Apr 2005
21:24:32 -0000
@@ -395,16 +395,6 @@
         }
     }
 
-
- public void encodeChildren(FacesContext context, UIComponent component)
- throws IOException {
- if (context == null || component == null) {
- throw new NullPointerException(Util.getExceptionMessageString(
- Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
 
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/MessageRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/MessageRenderer.java,v
retrieving revision 1.51
diff -u -r1.51 MessageRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/MessageRenderer.java 15 Mar
2005 15:50:32 -0000 1.51
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/MessageRenderer.java 20 Apr
2005 21:24:33 -0000
@@ -69,7 +69,7 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
+ public void encodeChildren(FacesContext context, UIComponent component)
throws IOException {
         if (context == null || component == null) {
             throw new NullPointerException(
                
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/MessagesRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/MessagesRenderer.java,v
retrieving revision 1.20
diff -u -r1.20 MessagesRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/MessagesRenderer.java 15 Mar
2005 15:50:32 -0000 1.20
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/MessagesRenderer.java 20 Apr
2005 21:24:33 -0000
@@ -50,14 +50,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
         Iterator messageIter = null;
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/OutputMessageRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/OutputMessageRenderer.java,v
retrieving revision 1.18
diff -u -r1.18 OutputMessageRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/OutputMessageRenderer.java 10
Mar 2005 21:39:15 -0000 1.18
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/OutputMessageRenderer.java 20
Apr 2005 21:24:33 -0000
@@ -83,14 +83,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     public void encodeEnd(FacesContext context, UIComponent component)
         throws IOException {
         if (context == null || component == null) {
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/SecretRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/SecretRenderer.java,v
retrieving revision 1.57
diff -u -r1.57 SecretRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/SecretRenderer.java 16 Dec
2004 17:56:38 -0000 1.57
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/SecretRenderer.java 20 Apr
2005 21:24:33 -0000
@@ -72,15 +72,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component)
- throws IOException {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     protected void getEndTextToRender(FacesContext context,
                                       UIComponent component, String currentValue)
         throws IOException {
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/TextRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/TextRenderer.java,v
retrieving revision 1.68
diff -u -r1.68 TextRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/TextRenderer.java 16 Dec 2004
17:56:38 -0000 1.68
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/TextRenderer.java 20 Apr 2005
21:24:33 -0000
@@ -74,14 +74,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(Util.getExceptionMessageString(
- Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     protected void getEndTextToRender(FacesContext context,
                                       UIComponent component, String currentValue)
         throws IOException {
Index: jsf-ri/src/com/sun/faces/renderkit/html_basic/TextareaRenderer.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/renderkit/html_basic/TextareaRenderer.java,v
retrieving revision 1.14
diff -u -r1.14 TextareaRenderer.java
--- jsf-ri/src/com/sun/faces/renderkit/html_basic/TextareaRenderer.java 16 Dec
2004 17:56:38 -0000 1.14
+++ jsf-ri/src/com/sun/faces/renderkit/html_basic/TextareaRenderer.java 20 Apr
2005 21:24:33 -0000
@@ -73,14 +73,6 @@
     }
 
 
- public void encodeChildren(FacesContext context, UIComponent component) {
- if (context == null || component == null) {
- throw new NullPointerException(
-
Util.getExceptionMessageString(Util.NULL_PARAMETERS_ERROR_MESSAGE_ID));
- }
- }
-
-
     protected void getEndTextToRender(FacesContext context, UIComponent component,
                                       String currentValue) throws IOException {
 
Index: jsf-ri/src/com/sun/faces/taglib/jsf_core/AttributeTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/taglib/jsf_core/AttributeTag.java,v
retrieving revision 1.2
diff -u -r1.2 AttributeTag.java
--- jsf-ri/src/com/sun/faces/taglib/jsf_core/AttributeTag.java 7 Jan 2005
20:41:53 -0000 1.2
+++ jsf-ri/src/com/sun/faces/taglib/jsf_core/AttributeTag.java 20 Apr 2005
21:24:33 -0000
@@ -12,6 +12,7 @@
 
 import javax.faces.component.UIComponent;
 import javax.faces.webapp.UIComponentTag;
+import javax.faces.webapp.UIComponentClassicTagBase;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
 import javax.servlet.jsp.JspException;
@@ -84,9 +85,9 @@
      */
     public int doStartTag() throws JspException {
 
- // Locate our parent UIComponentTag
- UIComponentTag tag =
- UIComponentTag.getParentUIComponentTag(pageContext);
+ // Locate our parent UIComponentTagBase
+ UIComponentClassicTagBase tag =
+
UIComponentClassicTagBase.getParentUIComponentClassicTagBase(pageContext);
         if (tag == null) { // PENDING - i18n
             throw new JspException("Not nested in a UIComponentTag");
         }
Index: jsf-ri/src/com/sun/faces/taglib/jsf_core/LoadBundleTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/taglib/jsf_core/LoadBundleTag.java,v
retrieving revision 1.8
diff -u -r1.8 LoadBundleTag.java
--- jsf-ri/src/com/sun/faces/taglib/jsf_core/LoadBundleTag.java 26 Feb 2004
20:33:17 -0000 1.8
+++ jsf-ri/src/com/sun/faces/taglib/jsf_core/LoadBundleTag.java 20 Apr 2005
21:24:34 -0000
@@ -87,7 +87,8 @@
         basename = (String) Util.evaluateVBExpression(basename_);
 
         if (null == basename || null == var) { // PENDING - i18n
- throw new JspException("null basename or var");
+ throw new JspException("The 'basename' or 'var' attributes" +
+ " evaluated to null.");
         }
 
         Map toStore = null;
@@ -103,7 +104,7 @@
 
         toStore =
             new Map() {
-// this is an immutable Map
+ // this is an immutable Map
 
                 // Do not need to implement for immutable Map
                 public void clear() {
Index: jsf-ri/src/com/sun/faces/taglib/jsf_core/VerbatimTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/taglib/jsf_core/VerbatimTag.java,v
retrieving revision 1.10
diff -u -r1.10 VerbatimTag.java
--- jsf-ri/src/com/sun/faces/taglib/jsf_core/VerbatimTag.java 8 Oct 2004
14:27:26 -0000 1.10
+++ jsf-ri/src/com/sun/faces/taglib/jsf_core/VerbatimTag.java 20 Apr 2005
21:24:34 -0000
@@ -13,7 +13,7 @@
 import javax.faces.component.UIOutput;
 import javax.faces.context.FacesContext;
 import javax.faces.el.ValueBinding;
-import javax.faces.webapp.UIComponentBodyTag;
+import javax.faces.webapp.UIComponentTag;
 import javax.servlet.jsp.JspException;
 
 /**
@@ -21,7 +21,7 @@
  * and allows the user to write raw markup.</p>
  */
 
-public class VerbatimTag extends UIComponentBodyTag {
+public class VerbatimTag extends UIComponentTag {
 
 
     // ------------------------------------------------------------- Attributes
@@ -81,6 +81,7 @@
             if (value != null) {
                 UIOutput output = (UIOutput) getComponentInstance();
                 output.setValue(value);
+ getBodyContent().clearBody();
             }
         }
         return (getDoAfterBodyValue());
Index: jsf-ri/src/com/sun/faces/taglib/jsf_core/ViewTag.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/taglib/jsf_core/ViewTag.java,v
retrieving revision 1.32
diff -u -r1.32 ViewTag.java
--- jsf-ri/src/com/sun/faces/taglib/jsf_core/ViewTag.java 15 Mar 2005 20:37:38
-0000 1.32
+++ jsf-ri/src/com/sun/faces/taglib/jsf_core/ViewTag.java 20 Apr 2005 21:24:34 -0000
@@ -14,16 +14,16 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import javax.faces.application.StateManager;
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
+import javax.faces.component.UIOutput;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.el.ValueBinding;
 import javax.faces.el.MethodBinding;
 import javax.faces.event.PhaseEvent;
-import javax.faces.webapp.UIComponentBodyTag;
+import javax.faces.webapp.UIComponentTag;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpSession;
@@ -34,17 +34,19 @@
 
 import java.io.IOException;
 import java.util.Locale;
+import com.sun.faces.application.ViewHandlerResponseWrapper;
+
 
 /**
- * All JSF component tags must be nested within UseFacesTag. This tag
- * corresponds to the root of the UIComponent tree. It does not have
- * any renderers or attributes. It exists mainly to save the state of
- * the response tree once all tags have been rendered.
+ * All JSF component tags must be nested within a f:view tag. This tag
+ * corresponds to the root of the UIComponent tree. It does not have a
+ * Renderer. It exists mainly to provide a guarantee that all faces
+ * components reside inside of this tag.
  *
  * @version $Id: ViewTag.java,v 1.32 2005/03/15 20:37:38 edburns Exp $
  */
 
-public class ViewTag extends UIComponentBodyTag {
+public class ViewTag extends UIComponentTag {
 
     //
     // Protected Constants
@@ -104,16 +106,45 @@
     // General Methods
     //
     
- //
- // Methods from FacesBodyTag
- //
-
     protected int getDoStartValue() throws JspException {
         return BodyTag.EVAL_BODY_BUFFERED;
     }
 
+ /**
+ * <p>Override parent <code>doStartTag()</code> to do the following:</p>
+ *
+ * <ul>
+ *
+ * <li><p>Get the {_at_link ViewHandlerResponseWrapper} from the
+ * request, which was placed there by {_at_link
+ * ViewHandler#renderView}, and call {_at_link
+ * ViewHandlerResponseWrapper#flushContentToWrappedResponse}. This
+ * causes any content that appears before the view to be written out
+ * to the response. This is necessary to allow proper ordering to
+ * happen.</p></li>
+ *
+ * </ul>
+ *
+ */
 
     public int doStartTag() throws JspException {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ assert (facesContext != null);
+
+
+ // flush out any content above the view tag
+ Object response = facesContext.getExternalContext().getResponse();
+ if (response instanceof ViewHandlerResponseWrapper) {
+ try {
+ pageContext.getOut().flush();
+ ((ViewHandlerResponseWrapper)response).flushContentToWrappedResponse();
+ }
+ catch (IOException e) {
+ throw new JspException("Can't write content above <f:view> tag"
+ + " " + e.getMessage());
+ }
+ }
+
         int rc = 0;
         try {
             rc = super.doStartTag();
@@ -131,104 +162,56 @@
             throw new JspException(t);
         }
 
- FacesContext facesContext = FacesContext.getCurrentInstance();
- assert (facesContext != null);
-
         // this must happen after our overriderProperties executes.
        
pageContext.getResponse().setLocale(facesContext.getViewRoot().getLocale());
-
- ResponseWriter writer = facesContext.getResponseWriter();
- assert (writer != null);
-
- try {
- writer.startDocument();
- } catch (IOException e) {
- throw new JspException(e);
- }
- return rc;
+ return rc;
     }
 
+ /**
+ * <p>Examine the body content of this tag. If it is
+ * non-<code>null</code>, non-zero length, and not an HTML comment,
+ * call {_at_link createVerbatimComponent}.</p>
+ *
+ * <p>Set the value of the verbatim component to be
+ * <code>content</code>.</p>
+ *
+ * <p>Add this child to the end of the child list for
+ * <code>UIViewRoot</code>.</p>
+ */
 
     public int doAfterBody() throws JspException {
+ int result = EVAL_PAGE;
         BodyContent bodyContent = null;
- String content = null;
- FacesContext context = FacesContext.getCurrentInstance();
- ResponseWriter responseWriter = context.getResponseWriter();
- StateManager stateManager = Util.getStateManager(context);
- Object view = null;
- int
- beginIndex = 0,
- markerIndex = 0,
- markerLen = RIConstants.SAVESTATE_FIELD_MARKER.length(),
- contentLen = 0;
-
- // get a writer that sends to the client
- responseWriter = responseWriter.cloneWithWriter(getPreviousOut());
-
- if (context == null) {
- throw new JspException(Util.getExceptionMessageString(
- Util.NULL_CONTEXT_ERROR_MESSAGE_ID));
- }
- context.setResponseWriter(responseWriter);
-
-
- if (null == (bodyContent = getBodyContent())) {
- Object params [] = {this.getClass().getName()};
- throw new JspException(Util.getExceptionMessageString(
- Util.NULL_BODY_CONTENT_ERROR_MESSAGE_ID, params));
- }
- content = bodyContent.getString();
-
- try {
- view = stateManager.saveView(context);
- } catch (IllegalStateException ise) {
- throw new JspException(ise);
- } catch (Exception ie) {
- // catch any exception thrown while saving the view in session.
- Object[] params = {"session", ie.getMessage()};
- throw new JspException(Util.getExceptionMessageString(
- Util.SAVING_STATE_ERROR_MESSAGE_ID, params), ie);
- }
- try {
- contentLen = content.length();
- do {
- // if we have no more markers
- if (-1 == (markerIndex =
- content.indexOf(RIConstants.SAVESTATE_FIELD_MARKER,
- beginIndex))) {
- // write out the rest of the content
- responseWriter.write(content.substring(beginIndex));
- } else {
- // we have more markers, write out the current chunk
- responseWriter.write(content.substring(beginIndex,
- markerIndex));
- stateManager.writeState(context, view);
- beginIndex = markerIndex + markerLen;
- }
- } while (-1 != markerIndex && beginIndex < contentLen);
- } catch (IOException iox) {
- // catch any thrown while saving state in response.
- Object[] params = {"client", iox.getMessage()};
- throw new JspException(Util.getExceptionMessageString(
- Util.SAVING_STATE_ERROR_MESSAGE_ID, params), iox);
- }
- return EVAL_PAGE;
+ UIViewRoot root = FacesContext.getCurrentInstance().getViewRoot();
+ UIOutput verbatim = null;
+ String content, trimContent;
+ int contentLen;
+
+ if (null == (bodyContent = getBodyContent()) ||
+ null == (content = bodyContent.getString()) ||
+ 0 == (contentLen = (trimContent = content.trim()).length()) ||
+ (trimContent.startsWith("<!--") && trimContent.endsWith("-->"))) {
+ return result;
+ }
+
+ bodyContent.clearBody();
+
+ verbatim = createVerbatimComponent();
+ verbatim.setValue(content);
+
+ root.getChildren().add(verbatim);
+
+ return result;
     }
 
+ /**
+ * <p>Exercise a contract with the {_at_link ViewHandler} to get the
+ * character encoding from the response and set it into the
+ * session.</p>
+ */
 
     public int doEndTag() throws JspException {
         int rc = super.doEndTag();
- // PENDING(): remove these getCurrentInstance calls, since we
- // have a facesContext ivar.
- FacesContext context = FacesContext.getCurrentInstance();
- ResponseWriter writer = context.getResponseWriter();
- assert (writer != null);
- try {
- writer.endDocument();
- } catch (IOException e) {
- throw new JspException(e);
- }
-
         // store the response character encoding
         HttpSession session = null;
 
@@ -243,7 +226,8 @@
     /**
      * This should never get called for PageTag.
      */
- public String getComponentType() {
+ public String getComponentType() {
+ assert (false);
         throw new IllegalStateException();
     }
 
Index: jsf-ri/src/com/sun/faces/util/DebugUtil.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/util/DebugUtil.java,v
retrieving revision 1.26
diff -u -r1.26 DebugUtil.java
--- jsf-ri/src/com/sun/faces/util/DebugUtil.java 17 Mar 2005 16:10:44 -0000 1.26
+++ jsf-ri/src/com/sun/faces/util/DebugUtil.java 20 Apr 2005 21:24:34 -0000
@@ -154,7 +154,7 @@
             }
             indentPrintln(out, " }");
         } else {
- if (root instanceof ValueHolder) {
+ if (null != root && (root instanceof ValueHolder)) {
                 value = ((ValueHolder)root).getValue();
             }
             indentPrintln(out, "value= " + value);
Index: jsf-ri/src/com/sun/faces/util/Util.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/util/Util.java,v
retrieving revision 1.154
diff -u -r1.154 Util.java
--- jsf-ri/src/com/sun/faces/util/Util.java 11 Apr 2005 18:03:57 -0000 1.154
+++ jsf-ri/src/com/sun/faces/util/Util.java 20 Apr 2005 21:24:36 -0000
@@ -54,6 +54,7 @@
 import java.util.StringTokenizer;
 import java.util.logging.Logger;
 import java.util.logging.Level;
+import java.text.MessageFormat;
 
 /**
  * <B>Util</B> is a class ...
@@ -399,6 +400,11 @@
         { "width", null }
     };
 
+ //NOTE - "type" was deliberately skipped from the list of passthru
+ //attrs above All renderers that need this attribute should manually
+ //pass it.
+
+
 
 //
 // Instance Variables
@@ -458,6 +464,10 @@
 
         if (null == result) {
             result = "null MessageFactory";
+ } else {
+ if ( params != null) {
+ result = MessageFormat.format(result, params);
+ }
         }
         return result;
     }
@@ -707,6 +717,7 @@
                 Util.getValueBinding(bundleName).getValue(context);
             if (locCtx != null) {
                 result = locCtx.getLocale();
+ assert (null != result);
             }
         }
         if (null == result) {



-- 
| ed.burns_at_sun.com  | {home: 407 869 9587, office: 408 884 9519 OR x31640}
| homepage:         | http://purl.oclc.org/NET/edburns/
| aim: edburns0sunw | iim: ed.burns_at_sun.com