dev@javaserverfaces.java.net

Re: Seeking Review: 447 Make FacesEvent optional in two cases

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Wed, 27 Aug 2008 08:35:32 -0700

r=rlubke

Ed Burns wrote:
> Issue: 447
>
> Applying for retroactive review.
>
> Rather than make a change at the EL level, I think it is more
> appropriate to handle this issue here, in the classes that implement
> ActionListener or ValueChangeListener and call a MethodExpression when
> the appropriate method is called by the JSF runtime.
>
> All automated tests still pass on my local machine.
>
> SECTION: API Changes
>
> M jsf-api/doc/actionsource-props.xml
> M jsf-api/doc/editable-props.xml
>
> - Make it so that the FacesEvent argument to an actionListener
> MethodExpression or valueChangeListener MethodExpression is optional.
>
> M jsf-api/doc/standard-html-renderkit.xml
>
> - re-generate the standard renderkit
>
> M jsf-api/src/javax/faces/event/MethodExpressionActionListener.java
> M jsf-api/src/javax/faces/event/MethodExpressionValueChangeListener.java
>
> - Accomodate for the zero arg version of the targets.
>
> SECTION: Impl changes
>
> M nbproject/project.xml
>
> - Add compile time dependencies for systest
>
> M jsf-ri/build.xml
>
> - make prepare.test.webapp depend on init.test
>
> - make prepare.test.webapp also build the systest war
>
> M jsf-ri/systest/build.xml
>
> - Unpack the jsf-systest.war so I can deploy it with deploydir
> for local testing.
>
> - Add a passthru that I can use to call a test target.
>
> A jsf-ri/systest/src/com/sun/faces/methodref/TagAttributeListenerMethodExpressionNoArgTestCase.java
>
> - Exercise new code
>
> M jsf-ri/systest/src/com/sun/faces/systest/model/TestBean.java
>
> - Add a no-arg processAction and processValueChange.
>
> A jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.xhtml
> A jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.jsp
>
> - Show off the first systest that uses both Facelets and JSP.
>
> SECTION: Diffs
>
> Index: nbproject/project.xml
> ===================================================================
> --- nbproject/project.xml (revision 5209)
> +++ nbproject/project.xml (working copy)
> @@ -140,7 +140,7 @@
> <package-root>jsf-api/test</package-root>
> <package-root>jsf-ri/test</package-root>
> <package-root>jsf-ri/systest/src</package-root>
> - <classpath mode="compile">jsf-api/build/classes:lib/jsf-extensions-test-time.jar:dependencies/glassfish/lib/appserv-rt.jar:dependencies/glassfish/lib/javaee.jar:dependencies/jars/com-sun-commons-beanutils.jar:dependencies/jars/com-sun-commons-collections.jar:dependencies/jars/com-sun-commons-digester-1.5.jar:dependencies/jars/com-sun-commons-digester.jar:dependencies/jars/com-sun-commons-logging-1.0.4.jar:dependencies/jars/com-sun-commons-logging-api.jar:dependencies/jars/commons-codec-1.3.jar:dependencies/jars/commons-collections-3.2.jar:dependencies/jars/commons-httpclient-3.1.jar:dependencies/jars/commons-io-1.3.1.jar:dependencies/jars/commons-lang-2.3.jar:dependencies/jars/commons-logging-1.1.jar:dependencies/jars/cssparser-0.9.4.jar:dependencies/jars/htmlunit-1.14.jar:dependencies/jars/ivy-2.0.0-beta1.jar:dependencies/jars/jaxen-1.1.1.jar:dependencies/jars/js-1.6R7.jar:dependencies/jars/jsp-api-2.1.jar:dependencies/jars/jsr250-api-1.0.jar:dependencies/jars/jstl-1.2.jar:dependencies/jars/junit-3.8.1.jar:dependencies/jars/maven-repository-importer-1.2.jar:dependencies/jars/nekohtml-0.9.5.jar:dependencies/jars/portlet-api-1.0.jar:dependencies/jars/servlet-api-2.5.jar:dependencies/jars/tlddoc-1.3.jar:dependencies/jars/xercesImpl-2.6.2.jar:dependencies/jars/xmlParserAPIs-2.6.2.jar:dependencies/jars/com-sun-commons-beanutils-1.6.1.jar:dependencies/apache-tomcat-6.0.13/lib/catalina.jar:dependencies/jars/com-sun-commons-collections-2.1.jar:dependencies/jetty-6.1.4rc0/lib/annotations/jetty-annotations-6.1.4rc0.jar:dependencies/jetty-6.1.4rc0/lib/plus/jetty-plus-6.1.4rc0.jar:dependencies/glassfish/lib/ant/lib/ant.jar:lib/cactus-1.7.1-javaee5.jar:dependencies/jars/groovy-all-1.5.5.jar</classpath>
> + <classpath mode="compile">jsf-api/build/classes:lib/jsf-extensions-test-time.jar:dependencies/glassfish/lib/appserv-rt.jar:dependencies/glassfish/lib/javaee.jar:dependencies/htmlunit-1.10/lib/commons-httpclient-3.0.1.jar:dependencies/htmlunit-1.10/lib/htmlunit-1.10.jar:dependencies/jars/com-sun-commons-beanutils.jar:dependencies/jars/com-sun-commons-collections.jar:dependencies/jars/com-sun-commons-digester-1.5.jar:dependencies/jars/com-sun-commons-digester.jar:dependencies/jars/com-sun-commons-logging-1.0.4.jar:dependencies/jars/com-sun-commons-logging-api.jar:dependencies/jars/commons-codec-1.3.jar:dependencies/jars/commons-collections-3.2.jar:dependencies/jars/commons-io-1.3.1.jar:dependencies/jars/commons-lang-2.3.jar:dependencies/jars/commons-logging-1.1.jar:dependencies/jars/cssparser-0.9.4.jar:dependencies/jars/ivy-2.0.0-beta1.jar:dependencies/jars/jaxen-1.1.1.jar:dependencies/jars/js-1.6R7.jar:dependencies/jars/jsp-api-2.1.jar:dependencies/jars/jsr250-api-1.0.jar:dependencies/jars/jstl-1.2.jar:dependencies/jars/junit-3.8.1.jar:dependencies/jars/maven-repository-importer-1.2.jar:dependencies/jars/nekohtml-0.9.5.jar:dependencies/jars/portlet-api-1.0.jar:dependencies/jars/servlet-api-2.5.jar:dependencies/jars/tlddoc-1.3.jar:dependencies/jars/xercesImpl-2.6.2.jar:dependencies/jars/xmlParserAPIs-2.6.2.jar:dependencies/jars/com-sun-commons-beanutils-1.6.1.jar:dependencies/apache-tomcat-6.0.13/lib/catalina.jar:dependencies/jars/com-sun-commons-collections-2.1.jar:dependencies/jetty-6.1.4rc0/lib/annotations/jetty-annotations-6.1.4rc0.jar:dependencies/jetty-6.1.4rc0/lib/plus/jetty-plus-6.1.4rc0.jar:dependencies/glassfish/lib/ant/lib/ant.jar:lib/cactus-1.7.1-javaee5.jar:dependencies/jars/groovy-all-1.5.5.jar</classpath>
> <source-level>1.5</source-level>
> </compilation-unit>
> </java-data>
> Index: jsf-api/doc/actionsource-props.xml
> ===================================================================
> --- jsf-api/doc/actionsource-props.xml (revision 5207)
> +++ jsf-api/doc/actionsource-props.xml (working copy)
> @@ -74,10 +74,19 @@
>
> <property>
> <description>
> - MethodExpression representing an action listener method that will be
> - notified when this component is activated by the user. The
> - expression must evaluate to a public method that takes an
> - ActionEvent parameter, with a return type of void.
> + <![CDATA[<p>
> +
> + MethodExpression representing an action listener method that
> + will be notified when this component is activated by the user.
> + The expression must evaluate to a public method that takes an
> + ActionEvent parameter, with a return type of void, <span
> + class="changed_added_2_0">or to a public method that takes no
> + arguments with a return type of void. In the latter case, the
> + method has no way of easily knowing where the event came from,
> + but this can be useful in cases where a notification is needed
> + that "some action happened".</span>
> +
> +</p>]]>
> </description>
> <display-name>Action Listener</display-name>
> <icon></icon>
> @@ -87,6 +96,13 @@
> <method-signature>
> void actionListener(javax.faces.event.ActionEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void actionListener()
> + </method-signature>
> +-->
> </property-extension>
> </property>
>
> Index: jsf-api/doc/standard-html-renderkit.xml
> ===================================================================
> --- jsf-api/doc/standard-html-renderkit.xml (revision 5207)
> +++ jsf-api/doc/standard-html-renderkit.xml (working copy)
> @@ -352,12 +352,19 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing an action listener method that will be
> - notified when this component is activated by the user. The
> - expression must evaluate to a public method that takes an
> - ActionEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing an action listener method that
> + will be notified when this component is activated by the user.
> + The expression must evaluate to a public method that takes an
> + ActionEvent parameter, with a return type of void, <span
> + class="changed_added_2_0">or to a public method that takes no
> + arguments with a return type of void. In the latter case, the
> + method has no way of easily knowing where the event came from,
> + but this can be useful in cases where a notification is needed
> + that "some action happened".</span>
> +
> +</p>]]></description>
> <display-name>Action Listener</display-name>
> <icon/>
> <property-name>actionListener</property-name>
> @@ -366,6 +373,13 @@
> <method-signature>
> void actionListener(javax.faces.event.ActionEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void actionListener()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -1290,12 +1304,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -1304,6 +1326,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -2653,12 +2682,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -2667,6 +2704,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -3358,12 +3402,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -3372,6 +3424,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -3704,12 +3763,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -3718,6 +3785,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -4287,12 +4361,19 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing an action listener method that will be
> - notified when this component is activated by the user. The
> - expression must evaluate to a public method that takes an
> - ActionEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing an action listener method that
> + will be notified when this component is activated by the user.
> + The expression must evaluate to a public method that takes an
> + ActionEvent parameter, with a return type of void, <span
> + class="changed_added_2_0">or to a public method that takes no
> + arguments with a return type of void. In the latter case, the
> + method has no way of easily knowing where the event came from,
> + but this can be useful in cases where a notification is needed
> + that "some action happened".</span>
> +
> +</p>]]></description>
> <display-name>Action Listener</display-name>
> <icon/>
> <property-name>actionListener</property-name>
> @@ -4301,6 +4382,13 @@
> <method-signature>
> void actionListener(javax.faces.event.ActionEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void actionListener()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -4869,12 +4957,19 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing an action listener method that will be
> - notified when this component is activated by the user. The
> - expression must evaluate to a public method that takes an
> - ActionEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing an action listener method that
> + will be notified when this component is activated by the user.
> + The expression must evaluate to a public method that takes an
> + ActionEvent parameter, with a return type of void, <span
> + class="changed_added_2_0">or to a public method that takes no
> + arguments with a return type of void. In the latter case, the
> + method has no way of easily knowing where the event came from,
> + but this can be useful in cases where a notification is needed
> + that "some action happened".</span>
> +
> +</p>]]></description>
> <display-name>Action Listener</display-name>
> <icon/>
> <property-name>actionListener</property-name>
> @@ -4883,6 +4978,13 @@
> <method-signature>
> void actionListener(javax.faces.event.ActionEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void actionListener()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -7165,12 +7267,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -7179,6 +7289,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -7505,12 +7622,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -7519,6 +7644,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -8236,12 +8368,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -8250,6 +8390,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -8951,12 +9098,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -8965,6 +9120,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -12857,12 +13019,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -12871,6 +13041,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -13532,12 +13709,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -13546,6 +13731,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -14255,12 +14447,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -14269,6 +14469,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -14962,12 +15169,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -14976,6 +15191,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -15659,12 +15881,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -15673,6 +15903,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -16353,12 +16590,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -16367,6 +16612,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> @@ -17037,12 +17289,20 @@
> </property-extension>
> </property>
> <property>
> - <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> - </description>
> + <description><![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]></description>
> <display-name>Value Change Listener</display-name>
> <icon/>
> <property-name>valueChangeListener</property-name>
> @@ -17051,6 +17311,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
> <property>
> Index: jsf-api/doc/editable-props.xml
> ===================================================================
> --- jsf-api/doc/editable-props.xml (revision 5207)
> +++ jsf-api/doc/editable-props.xml (working copy)
> @@ -161,10 +161,20 @@
>
> <property>
> <description>
> - MethodExpression representing a value change listener method that will be
> - notified when a new value has been set for this input component. The
> - expression must evaluate to a public method that takes a
> - ValueChangeEvent parameter, with a return type of void.
> + <![CDATA[<p>
> +
> + MethodExpression representing a value change listener method
> + that will be notified when a new value has been set for this
> + input component. The expression must evaluate to a public
> + method that takes a <code>ValueChangeEvent</code> parameter,
> + with a return type of void, <span class="changed_added_2_0">or
> + to a public method that takes no arguments with a return type
> + of void. In the latter case, the method has no way of easily
> + knowing what the new value is, but this can be useful in cases
> + where a notification is needed that "this value
> + changed".</span>
> +
> +</p>]]>
> </description>
> <display-name>Value Change Listener</display-name>
> <icon></icon>
> @@ -174,6 +184,13 @@
> <method-signature>
> void valueChange(javax.faces.event.ValueChangeEvent)
> </method-signature>
> +<!-- PENDING modify tlddoc to handle an OR of method signatures
> +as required by
> +https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=447
> + <method-signature>
> + void valueChange()
> + </method-signature>
> +-->
> </property-extension>
> </property>
>
> Index: jsf-api/src/javax/faces/event/MethodExpressionActionListener.java
> ===================================================================
> --- jsf-api/src/javax/faces/event/MethodExpressionActionListener.java (revision 5207)
> +++ jsf-api/src/javax/faces/event/MethodExpressionActionListener.java (working copy)
> @@ -50,11 +50,15 @@
> import java.util.logging.Logger;
> import java.io.StringWriter;
> import java.io.PrintWriter;
> +import javax.el.MethodNotFoundException;
>
> /**
> - * <p><strong>MethodExpressionActionListener</strong> is an {_at_link ActionListener} that
> - * wraps a {_at_link MethodExpression}. When it receives a {_at_link ActionEvent}, it executes
> - * a method on an object identified by the {_at_link MethodExpression}.</p>
> + * <p><strong><span
> + * class="changed_modified_2_0">MethodExpressionActionListener</span></strong>
> + * is an {_at_link ActionListener} that wraps a {_at_link
> + * MethodExpression}. When it receives a {_at_link ActionEvent}, it
> + * executes a method on an object identified by the {_at_link
> + * MethodExpression}.</p>
> */
>
> public class MethodExpressionActionListener implements ActionListener,
> @@ -66,56 +70,121 @@
>
> // ------------------------------------------------------ Instance Variables
>
> - private MethodExpression methodExpression = null;
> + private MethodExpression methodExpressionOneArg = null;
> + private MethodExpression methodExpressionZeroArg = null;
> private boolean isTransient;
> + private final static Class[] ACTION_LISTENER_ZEROARG_SIG = new Class[] { };
>
> public MethodExpressionActionListener() { }
>
> /**
> - * <p>Construct a {_at_link ValueChangeListener} that contains a {_at_link MethodExpression}.</p>
> + * <p><span class="changed_modified_2_0">Construct<span
> + * class="changed_modified_2_0"> a {_at_link ValueChangeListener} that
> + * contains a {_at_link MethodExpression}. <span
> + * class="changed_added_2_0">To accomodate method expression targets
> + * that take no arguments instead of taking an {_at_link ActionEvent}
> + * argument</span>, the implementation of this class must take the
> + * argument <code>methodExpressionOneArg</code>, extract its
> + * expression string, and create another
> + * <code>MethodExpression</code> whose expected param types match
> + * those of a zero argument method. The usage requirements for both
> + * of these <code>MethodExpression</code> instances are described in
> + * {_at_link #processAction}.</span></p>
> + *
> + * @param methodExpressionOneArg a <code>MethodExpression</code>
> + * that points to a method that returns <code>void</code> and takes
> + * a single argument of type {_at_link ActionEvent}.
> */
> - public MethodExpressionActionListener(MethodExpression methodExpression) {
> + public MethodExpressionActionListener(MethodExpression methodExpressionOneArg) {
>
> super();
> - this.methodExpression = methodExpression;
> + this.methodExpressionOneArg = methodExpressionOneArg;
> + FacesContext context = FacesContext.getCurrentInstance();
> + ELContext elContext = context.getELContext();
> + this.methodExpressionZeroArg = context.getApplication().
> + getExpressionFactory().createMethodExpression(elContext,
> + methodExpressionOneArg.getExpressionString(), Void.class,
> + ACTION_LISTENER_ZEROARG_SIG);
>
> }
>
> + public MethodExpressionActionListener(MethodExpression methodExpressionOneArg,
> + MethodExpression methodExpressionZeroArg) {
>
> + super();
> + this.methodExpressionOneArg = methodExpressionOneArg;
> + this.methodExpressionZeroArg = methodExpressionZeroArg;
> +
> + }
> +
> // ------------------------------------------------------- Event Method
>
> /**
> + * <p><span class="changed_modified_2_0">Call</span> through to the
> + * {_at_link MethodExpression} passed in our constructor. <span
> + * class="changed_added_2_0">First, try to invoke the
> + * <code>MethodExpression</code> passed to the constructor of this
> + * instance, passing the argument {_at_link ActionEvent} as the
> + * argument. If a {_at_link MethodNotFoundException} is thrown, call
> + * to the zero argument <code>MethodExpression</code> derived from
> + * the <code>MethodExpression</code> passed to the constructor of
> + * this instance. If that fails for any reason, throw an {_at_link
> + * AbortProcessingException}, including the cause of the
> + * failure.</span></p>
> + *
> * @throws NullPointerException {_at_inheritDoc}
> * @throws AbortProcessingException {_at_inheritDoc}
> */
> public void processAction(ActionEvent actionEvent) throws AbortProcessingException {
>
> + boolean throwException = false;
> + Throwable cause = null;
> + Throwable thrown = null;
> if (actionEvent == null) {
> throw new NullPointerException();
> }
> + FacesContext context = FacesContext.getCurrentInstance();
> + ELContext elContext = context.getELContext();
> try {
> - FacesContext context = FacesContext.getCurrentInstance();
> - ELContext elContext = context.getELContext();
> - methodExpression.invoke(elContext, new Object[] {actionEvent});
> + methodExpressionOneArg.invoke(elContext, new Object[] {actionEvent});
> + } catch (MethodNotFoundException mnfe) {
> + if (null != methodExpressionZeroArg) {
> + try {
> + // try to invoke a no-arg version
> + methodExpressionZeroArg.invoke(elContext, new Object[]{});
> + }
> + catch (ELException ee) {
> + cause = ee.getCause();
> + thrown = ee;
> + throwException = true;
> + }
> +
> + }
> } catch (ELException ee) {
> - Throwable eeCause = ee.getCause();
> + cause = ee.getCause();
> + thrown = ee;
> + throwException = true;
> + }
> + if (throwException) {
> if (LOGGER.isLoggable(Level.SEVERE)) {
> LOGGER.log(Level.SEVERE,
> "severe.event.exception_invoking_processaction",
> new Object[]{
> - eeCause == null ? ee.getClass().getName() : eeCause.getClass().getName(),
> - methodExpression.getExpressionString(),
> + cause == null ? thrown.getClass().getName() : cause.getClass().getName(),
> + methodExpressionOneArg.getExpressionString(),
> actionEvent.getComponent().getId()
> });
> StringWriter writer = new StringWriter(1024);
> - if (eeCause == null) {
> - ee.printStackTrace(new PrintWriter(writer));
> + if (cause == null) {
> + thrown.printStackTrace(new PrintWriter(writer));
> } else {
> - eeCause.printStackTrace(new PrintWriter(writer));
> + cause.printStackTrace(new PrintWriter(writer));
> }
> LOGGER.severe(writer.toString());
> }
> - throw eeCause == null ? new AbortProcessingException(ee.getMessage(), ee) : new AbortProcessingException(ee.getMessage(), eeCause);
> + throw cause == null ? new AbortProcessingException(thrown.getMessage(),
> + thrown) : new AbortProcessingException(thrown.getMessage(), cause);
> +
> }
> }
>
> @@ -123,16 +192,25 @@
> // ------------------------------------------------ Methods from StateHolder
>
>
> + /**
> + * <p class="changed_modified_2_0">Both {_at_link MethodExpression}
> + * instances described in the constructor must be saved.</p>
> + */
> public Object saveState(FacesContext context) {
>
> - return new Object[] { methodExpression };
> + return new Object[] { methodExpressionOneArg, methodExpressionZeroArg };
>
> }
>
>
> + /**
> + * <p class="changed_modified_2_0">Both {_at_link MethodExpression}
> + * instances described in the constructor must be restored.</p>
> + */
> public void restoreState(FacesContext context, Object state) {
>
> - methodExpression = (MethodExpression) ((Object[]) state)[0];
> + methodExpressionOneArg = (MethodExpression) ((Object[]) state)[0];
> + methodExpressionZeroArg = (MethodExpression) ((Object[]) state)[1];
>
> }
>
> Index: jsf-api/src/javax/faces/event/MethodExpressionValueChangeListener.java
> ===================================================================
> --- jsf-api/src/javax/faces/event/MethodExpressionValueChangeListener.java (revision 5207)
> +++ jsf-api/src/javax/faces/event/MethodExpressionValueChangeListener.java (working copy)
> @@ -43,13 +43,17 @@
> import javax.el.ELContext;
> import javax.el.ELException;
> import javax.el.MethodExpression;
> +import javax.el.MethodNotFoundException;
> import javax.faces.context.FacesContext;
> import javax.faces.component.StateHolder;
>
> /**
> - * <p><strong>MethodExpressionValueChangeListener</strong> is a {_at_link ValueChangeListener} that
> - * wraps a {_at_link MethodExpression}. When it receives a {_at_link ValueChangeEvent}, it executes
> - * a method on an object identified by the {_at_link MethodExpression}.</p>
> + * <p><strong><span
> + * class="changed_modified_2_0">MethodExpressionValueChangeListener</span></strong>
> + * is a {_at_link ValueChangeListener} that wraps a {_at_link
> + * MethodExpression}. When it receives a {_at_link ValueChangeEvent}, it
> + * executes a method on an object identified by the {_at_link
> + * MethodExpression}.</p>
> */
>
> public class MethodExpressionValueChangeListener implements ValueChangeListener,
> @@ -58,25 +62,71 @@
>
> // ------------------------------------------------------ Instance Variables
>
> - private MethodExpression methodExpression = null;
> + private MethodExpression methodExpressionOneArg = null;
> + private MethodExpression methodExpressionZeroArg = null;
> private boolean isTransient;
> + private final static Class[] VALUECHANGE_LISTENER_ZEROARG_SIG = new Class[] { };
> +
>
> public MethodExpressionValueChangeListener() { }
>
> /**
> + * <p><span class="changed_modified_2_0">Construct</span> a {_at_link
> + * ValueChangeListener} that contains a {_at_link
> + * MethodExpression}.<span
> + * class="changed_added_2_0">To accomodate method expression targets
> + * that take no arguments instead of taking a {_at_link
> + * ValueChangeEvent} argument</span>, the implementation of this
> + * class must take the argument <code>methodExpressionOneArg</code>,
> + * extract its expression string, and create another
> + * <code>MethodExpression</code> whose expected param types match
> + * those of a zero argument method. The usage requirements for both
> + * of these <code>MethodExpression</code> instances are described in
> + * {_at_link #processValueChange}.</span></p>
> + *
> + * @param methodExpressionOneArg a <code>MethodExpression</code>
> + * that points to a method that returns <code>void</code> and takes
> + * a single argument of type {_at_link ValueChangeEvent}.
> + */
> + public MethodExpressionValueChangeListener(MethodExpression methodExpressionOneArg) {
> +
> + super();
> + this.methodExpressionOneArg = methodExpressionOneArg;
> + FacesContext context = FacesContext.getCurrentInstance();
> + ELContext elContext = context.getELContext();
> + this.methodExpressionZeroArg = context.getApplication().
> + getExpressionFactory().createMethodExpression(elContext,
> + methodExpressionOneArg.getExpressionString(), Void.class,
> + VALUECHANGE_LISTENER_ZEROARG_SIG);
> + }
> +
> + /**
> * <p>Construct a {_at_link ValueChangeListener} that contains a {_at_link MethodExpression}.</p>
> */
> - public MethodExpressionValueChangeListener(MethodExpression methodExpression) {
> + public MethodExpressionValueChangeListener(MethodExpression methodExpressionOneArg,
> + MethodExpression methodExpressionZeroArg) {
>
> super();
> - this.methodExpression = methodExpression;
> + this.methodExpressionOneArg = methodExpressionOneArg;
> + this.methodExpressionZeroArg = methodExpressionZeroArg;
>
> }
>
> -
> // ------------------------------------------------------- Event Method
>
> /**
> + * <p><span class="changed_modified_2_0">Call</span> through to the
> + * {_at_link MethodExpression} passed in our constructor. <span
> + * class="changed_added_2_0">First, try to invoke the
> + * <code>MethodExpression</code> passed to the constructor of this
> + * instance, passing the argument {_at_link ValueChangeEvent} as the
> + * argument. If a {_at_link MethodNotFoundException} is thrown, call
> + * to the zero argument <code>MethodExpression</code> derived from
> + * the <code>MethodExpression</code> passed to the constructor of
> + * this instance. If that fails for any reason, throw an {_at_link
> + * AbortProcessingException}, including the cause of the
> + * failure.</span></p>
> + *
> * @throws NullPointerException {_at_inheritDoc}
> * @throws AbortProcessingException {_at_inheritDoc}
> */
> @@ -85,10 +135,24 @@
> if (valueChangeEvent == null) {
> throw new NullPointerException();
> }
> + FacesContext context = FacesContext.getCurrentInstance();
> + ELContext elContext = context.getELContext();
> + // PENDING: The corresponding code in MethodExpressionActionListener
> + // has an elaborate message capture, logging, and rethrowing block.
> + // Why not here?
> try {
> - FacesContext context = FacesContext.getCurrentInstance();
> - ELContext elContext = context.getELContext();
> - methodExpression.invoke(elContext, new Object[] {valueChangeEvent});
> + methodExpressionOneArg.invoke(elContext, new Object[] {valueChangeEvent});
> + } catch (MethodNotFoundException mnf) {
> + if (null != methodExpressionZeroArg) {
> +
> + try {
> + // try to invoke a no-arg version
> + methodExpressionZeroArg.invoke(elContext, new Object[]{});
> + }
> + catch (ELException ee) {
> + throw new AbortProcessingException(ee.getMessage(), ee.getCause());
> + }
> + }
> } catch (ELException ee) {
> throw new AbortProcessingException(ee.getMessage(), ee.getCause());
> }
> @@ -98,16 +162,25 @@
> // ------------------------------------------------ Methods from StateHolder
>
>
> + /**
> + * <p class="changed_modified_2_0">Both {_at_link MethodExpression}
> + * instances described in the constructor must be saved.</p>
> + */
> public Object saveState(FacesContext context) {
>
> - return new Object[] { methodExpression };
> + return new Object[] { methodExpressionOneArg, methodExpressionZeroArg };
>
> }
>
>
> + /**
> + * <p class="changed_modified_2_0">Both {_at_link MethodExpression}
> + * instances described in the constructor must be restored.</p>
> + */
> public void restoreState(FacesContext context, Object state) {
>
> - methodExpression = (MethodExpression) ((Object[]) state)[0];
> + methodExpressionOneArg = (MethodExpression) ((Object[]) state)[0];
> + methodExpressionZeroArg = (MethodExpression) ((Object[]) state)[1];
>
> }
>
> Index: jsf-ri/build.xml
> ===================================================================
> --- jsf-ri/build.xml (revision 5207)
> +++ jsf-ri/build.xml (working copy)
> @@ -463,9 +463,11 @@
> <ant antfile="build-tests.xml" target="force.execute.cactus.tests"/>
> </target>
>
> - <target name="prepare.test.webapp">
> + <target name="prepare.test.webapp" depends="init.test">
> <echo>Invoking target prepare.test.webapp</echo>
> <ant antfile="build-tests.xml" target="prepare.test.webapp"/>
> + <echo>Invoking target build.war in systest</echo>
> + <ant dir="${basedir}/systest" inheritall="false" target="build.war"/>
> </target>
>
> <!--
> Index: jsf-ri/systest/src/com/sun/faces/methodref/TagAttributeListenerMethodExpressionNoArgTestCase.java
> ===================================================================
> --- jsf-ri/systest/src/com/sun/faces/methodref/TagAttributeListenerMethodExpressionNoArgTestCase.java (revision 0)
> +++ jsf-ri/systest/src/com/sun/faces/methodref/TagAttributeListenerMethodExpressionNoArgTestCase.java (revision 0)
> @@ -0,0 +1,100 @@
> +/*
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
> + *
> + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
> + *
> + * The contents of this file are subject to the terms of either the GNU
> + * General Public License Version 2 only ("GPL") or the Common Development
> + * and Distribution License("CDDL") (collectively, the "License"). You
> + * may not use this file except in compliance with the License. You can obtain
> + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
> + * language governing permissions and limitations under the License.
> + *
> + * When distributing the software, include this License Header Notice in each
> + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
> + * Sun designates this particular file as subject to the "Classpath" exception
> + * as provided by Sun in the GPL Version 2 section of the License file that
> + * accompanied this code. If applicable, add the following below the License
> + * Header, with the fields enclosed by brackets [] replaced by your own
> + * identifying information: "Portions Copyrighted [year]
> + * [name of copyright owner]"
> + *
> + * Contributor(s):
> + *
> + * If you wish your version of this file to be governed by only the CDDL or
> + * only the GPL Version 2, indicate your decision by adding "[Contributor]
> + * elects to include this software in this distribution under the [CDDL or GPL
> + * Version 2] license." If you don't indicate a single choice of license, a
> + * recipient has the option to distribute your version of this file under
> + * either the CDDL, the GPL Version 2 or to extend the choice of license to
> + * its licensees as provided above. However, if you add GPL Version 2 code
> + * and therefore, elected the GPL Version 2 license, then the option applies
> + * only if the new code is made subject to such option by the copyright
> + * holder.
> + */
> +
> +
> +package com.sun.faces.methodref;
> +
> +
> +import com.gargoylesoftware.htmlunit.html.HtmlForm;
> +import com.sun.faces.htmlunit.AbstractTestCase;
> +import com.gargoylesoftware.htmlunit.html.HtmlPage;
> +import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
> +import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
> +import java.io.IOException;
> +import junit.framework.Test;
> +import junit.framework.TestSuite;
> +
> +/**
> + * Validate resource re-location of scripts and stylesheets
> + */
> +public class TagAttributeListenerMethodExpressionNoArgTestCase extends AbstractTestCase {
> +
> +
> + public TagAttributeListenerMethodExpressionNoArgTestCase() {
> + this("TagAttributeListenerMethodExpressionNoArgTestCase");
> + }
> +
> +
> + public TagAttributeListenerMethodExpressionNoArgTestCase(String name) {
> + super(name);
> + }
> +
> + public static Test suite() {
> + return (new TestSuite(TagAttributeListenerMethodExpressionNoArgTestCase.class));
> + }
> +
> +
> + // ------------------------------------------------------------ Test Methods
> +
> +
> + public void testResourceRelocation() throws Exception {
> +
> + HtmlPage page = getPage("/faces/TestValueChangeAndActionListenerNoArg.jsp");
> + executeTest(page);
> + page = getPage("/faces/TestValueChangeAndActionListenerNoArg.xhtml");
> + executeTest(page);
> + }
> +
> +
> + // --------------------------------------------------------- Private Methods
> +
> + private void executeTest(HtmlPage page) throws IOException {
> + HtmlTextInput usernameField = (HtmlTextInput) page.getHtmlElementById("username");
> + usernameField.setValueAttribute("newValue, not oldValue");
> + HtmlForm form = getFormById(page, "form");
> + HtmlSubmitInput button = (HtmlSubmitInput) form.getInputByName("loginEvent");
> + page = (HtmlPage) button.click();
> + String text = page.asText();
> + boolean hasExpectedValue =
> + (-1 != text.indexOf("valueChange0Called:true")) ||
> + (-1 != text.indexOf("valueChange0Called: true"));
> + assertTrue(hasExpectedValue);
> + hasExpectedValue =
> + (-1 != text.indexOf("actionListener0Called:true")) ||
> + (-1 != text.indexOf("actionListener0Called: true"));
> + assertTrue(hasExpectedValue);
> + }
> +}
> Index: jsf-ri/systest/src/com/sun/faces/systest/model/TestBean.java
> ===================================================================
> --- jsf-ri/systest/src/com/sun/faces/systest/model/TestBean.java (revision 5207)
> +++ jsf-ri/systest/src/com/sun/faces/systest/model/TestBean.java (working copy)
> @@ -558,7 +558,18 @@
> }
> newList1.add(newValue);
> }
> +
> + public void valueChange0() {
> + FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("valueChange0Called",
> + "true");
> + }
> +
> + public void actionListener0() {
> + FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("actionListener0Called",
> + "true");
> + }
>
> +
> public void valueChange2(ValueChangeEvent vce) {
> String newValue = vce.getNewValue().toString();
> if (newList2.size() == 3){
> Index: jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.xhtml
> ===================================================================
> --- jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.xhtml (revision 0)
> +++ jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.xhtml (revision 0)
> @@ -0,0 +1,41 @@
> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> +<html xmlns="http://www.w3.org/1999/xhtml"
> + xmlns:h="http://java.sun.com/jsf/html"
> + xmlns:f="http://java.sun.com/jsf/core">
> + <h:head>
> + <title>Test that method expressions pointing to no-arg methods work for valueChangeListener and actionListener</title>
> + </h:head>
> +
> + <h:body>
> + <h1>Test that method expressions pointing to no-arg methods work for valueChangeListener and actionListener</h1>
> +
> +
> +<f:view>
> + <h:form id="form" prependId="false">
> +
> + <p>
> +
> + <h:inputText id="username" value="#{test1.stringProperty}"
> + required="true"
> + valueChangeListener="#{test1.valueChange0}"/>
> +
> + </p>
> +
> + <p>
> +
> + <h:commandButton id="loginEvent" value="Login"
> + actionListener="#{test1.actionListener0}">
> +
> + </h:commandButton>
> +
> + </p>
> +
> +<p>valueChange0Called: <h:outputText value="#{valueChange0Called}" /></p>
> +
> +<p>actionListener0Called: <h:outputText value="#{actionListener0Called}" /></p>
> +
> + </h:form>
> +</f:view>
> +
> + </h:body>
> +</html>
> Index: jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.jsp
> ===================================================================
> --- jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.jsp (revision 0)
> +++ jsf-ri/systest/web/TestValueChangeAndActionListenerNoArg.jsp (revision 0)
> @@ -0,0 +1,41 @@
> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
> +<html>
> + <head>
> + <title>Test that method expressions pointing to no-arg methods work for valueChangeListener and actionListener</title>
> + <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
> + <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
> + </head>
> +
> + <body>
> + <h1>Test that method expressions pointing to no-arg methods work for valueChangeListener and actionListener</h1>
> +
> +
> +<f:view>
> + <h:form id="form" prependId="false">
> +
> + <p>
> +
> + <h:inputText id="username" value="#{test1.stringProperty}"
> + required="true"
> + valueChangeListener="#{test1.valueChange0}"/>
> +
> + </p>
> +
> + <p>
> +
> + <h:commandButton id="loginEvent" value="Login"
> + actionListener="#{test1.actionListener0}">
> +
> + </h:commandButton>
> +
> + </p>
> +
> +<p>valueChange0Called: <h:outputText value="#{valueChange0Called}" /></p>
> +
> +<p>actionListener0Called: <h:outputText value="#{actionListener0Called}" /></p>
> +
> + </h:form>
> +</f:view>
> +
> + </body>
> +</html>
> Index: jsf-ri/systest/build.xml
> ===================================================================
> --- jsf-ri/systest/build.xml (revision 5207)
> +++ jsf-ri/systest/build.xml (working copy)
> @@ -99,6 +99,10 @@
> <zipfileset dir="${web.dir}"/>
> </archive-elements>
> </jsf.war>
> + <mkdir dir="${build.dir}/target/jsf-systest" />
> + <unjar src="${build.dir}/jsf-systest.war" overwrite="true"
> + dest="${build.dir}/target/jsf-systest" />
> +
> </target>
>
> <target name="compile" depends=""
> @@ -160,5 +164,14 @@
> <undeploy.artifact artifact="${build.dir}/jsf-systest.war"
> appName="jsf-systest"/>
> </target>
> +
> + <target name="passthru"
> + description="useful for running one test">
> +
> + <ant antfile="build-tests.xml" target="test"/>
> +
>
> + </target>
> +
> +
> </project>
>
>
>