[ 
https://issues.apache.org/jira/browse/MYFACES-1741?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12534438
 ] 

Leonardo Uribe commented on MYFACES-1741:
-----------------------------------------

The three binding properties from f:converter, f:validator and f:actionListener 
looks different,
so i will concentrate first on a possible <f:converter> solution.

Looking this issue in more deep, I have found some questions and answers:

The spec doc says the following about <f:converter>:

     "..... The implementation class for this action must meet the following 
requirements:

     * Must extend javax.faces.webapp.ConverterJspTag.

     * The createConverter() method must:

       If binding is non-null, call binding.getValue() to obtain a reference to 
the
       Converter instance. If there is no exception thrown, and 
binding.getValue()
       returned a non-null object that implements javax.faces.convert.Converter,
       register it by calling setConverter(). If there was an exception thrown, 
rethrow
       the exception as a JspException.Use the converterId attribute if the 
converter
       instance could not be created from the binding attribute. If the 
converterId
       attribute is set, call the createConverter() method of the Application
       instance for this application, passing converter id specified by their 
converterId
       attribute. If the binding attribute was also set, store the converter 
instance by calling
       binding.setValue(). Register the converter instance by calling
       setConverter(). If there was an exception thrown, rethrow the exception 
as a
       JspException. "

This is what myfaces do, implementing this behaviour on 
org.apache.myfaces.taglib.core.ConverterTag,
and the actual behaviour of myfaces (it's doing what the spec says to do). 

CONCLUSION 1: Maybe this implementation detail refers to 
javax.faces.webapp.ConverterTag, which is 
now deprecated(but looking on jsf1.1 spec doc doesn't appear this paragraph). 
The actual behaviour 
of f:converter in JSF RI is different to the spec says(that is what the test 
says), maybe because 
the addition of binding attribute. Looking on core tld of JSF RI they use 
another class
like myfaces, so I suppose that they are doing another thing there to do what 
actually does.

So, if the previous conclusion is true, What should do a solution that works 
like JSF RI behaviour? 
(this behaviour is the spected behaviour for binding attribute):

   1. The state of the converter must be restored (binding and converterId) in 
order to be called later
   in PROCESS_VALIDATIONS phase .

   Now, the tree saves something like this:

   <html.HtmlInputText id="bigint" ... converter="[EMAIL PROTECTED]" ....

   When the state is restored, this instace is called or recreated, so the 
binding is only assigned on ConverterTag.
   javax.faces.convert.BigIntegerConverter does not implement a StateHolder 
interface to save and
   restore the state, so I suppose that it is possible to create a class that 
implements Converter and StateHolder,
   and do something like a delegate pattern, to save converterId and binding 
values on the tree.


   2. Restore the binding when getConverter() is called or something like that.



> JSR-252 Issue 21 - Provided an additional "binding" attribute for the core 
> Converter, Listener and Validator tags has wrong behaviour
> -------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: MYFACES-1741
>                 URL: https://issues.apache.org/jira/browse/MYFACES-1741
>             Project: MyFaces Core
>          Issue Type: Bug
>          Components: JSR-252
>    Affects Versions:  1.2.0
>         Environment: Tomcat 6.0.14, Myfaces 1.2.1-SNAPSHOT (Oct 7 2007)
>            Reporter: Leonardo Uribe
>             Fix For: 1.2.1-SNAPSHOT
>
>
> There is a problem with the behaviour of binding attribute from 
> actionListeners, validators and converters.
> I have this test. The objective is explore how binding attribute is doing 
> things comparing jsf ri 1.2 and 
> myfaces 1.2.1-SNAPSHOT, trying to detect bugs on myfaces :) 
> bindingCLV.jsp
> <%@ page session="false" contentType="text/html;charset=utf-8"%>
> <%@ taglib uri="http://java.sun.com/jsf/html"; prefix="h"%>
> <%@ taglib uri="http://java.sun.com/jsf/core"; prefix="f"%>
> <html>
> <f:view beforePhase="#{bindingCLVBean.beforePhase}" 
>     afterPhase="#{bindingCLVBean.afterPhase}">
>       <[EMAIL PROTECTED] file="inc/head.inc"%>
>       <body>
>       <f:loadBundle
>               basename="org.apache.myfaces.examples.resource.example_messages"
>               var="example_messages" />
>       <h1>Myfaces Examples JSF 1.2 Additions</h1>
>       <h:messages></h:messages>
>       <h:form id="form">
>               <h:panelGrid id="grid" columns="3">
>                       <h:outputLabel value="BigInt" 
> for="bigint"></h:outputLabel>
>                       <h:inputText id="bigint" 
> binding="#{bindingCLVBean.input1}" value="#{bindingCLVBean.bigint}">
>                               <f:converter 
> converterId="javax.faces.BigInteger" 
> binding="#{bindingCLVBean.converterBigint}"/>
>                               <f:validator 
> validatorId="org.apache.myfaces.bindingCLV.DummyValidator" 
>                                   
> binding="#{bindingCLVBean.validatorBigint}"/>
>                       </h:inputText>
>                       <h:message for="bigint"></h:message>
>                       <h:outputLabel value="BigDecimal" 
> for="bigdecimal"></h:outputLabel>
>                       <h:inputText id="bigdecimal" 
> binding="#{bindingCLVBean.input2}" value="#{bindingCLVBean.bigdecimal}">
>                               <f:converter 
> converterId="javax.faces.BigDecimal" 
> binding="#{bindingCLVBean.converterBigdecimal}"/>
>                               <f:validator 
> validatorId="org.apache.myfaces.bindingCLV.DummyValidator" 
>                     binding="#{bindingCLVBean.validatorBigdecimal}"/>
>                       </h:inputText>
>                       <h:message for="bigdecimal"></h:message>
>               </h:panelGrid>
>               <h:commandButton id="button1" value="press me" 
> action="#{bindingCLVBean.update}" >
>                 <f:actionListener 
> type="org.apache.myfaces.bindingCLV.DummyActionListener" 
>                     binding="#{bindingCLVBean.listener}" />
>               </h:commandButton>
>       </h:form>
>       </body>
> </f:view>
> </html>
> Bean:
> package org.apache.myfaces.bindingCLV;
> import java.math.BigDecimal;
> import java.math.BigInteger;
> import javax.faces.application.FacesMessage;
> import javax.faces.component.html.HtmlInputText;
> import javax.faces.context.FacesContext;
> import javax.faces.convert.Converter;
> import javax.faces.event.ActionListener;
> import javax.faces.event.PhaseEvent;
> import javax.faces.validator.Validator;
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> public class BindingCLVBean {
>       private BigInteger bigint;
>       
>       private BigDecimal bigdecimal;
>       
>       private Converter converterBigint;
>       
>       private Converter converterBigdecimal;
>       
>       private Validator validatorBigint;
>       
>       private Validator validatorBigdecimal;
>       
>       private HtmlInputText input1;
>       
>       private HtmlInputText input2;
>       
>       private ActionListener listener;
>       
>       Log log = LogFactory.getLog(BindingCLVBean.class);
>       
>       public void beforePhase(PhaseEvent phaseEvent){         
>               FacesContext facesContext = FacesContext.getCurrentInstance();  
>         
>       
>               facesContext.addMessage(null, new FacesMessage("This is the 
> message for phase before "+phaseEvent.getPhaseId().toString()));
>               facesContext.addMessage(null, new 
> FacesMessage("Component:"+this.getInput1()));
>               facesContext.addMessage(null, new 
> FacesMessage("Validator:"+this.getValidatorBigdecimal()));
>               facesContext.addMessage(null, new 
> FacesMessage("Converter:"+this.getConverterBigdecimal()));
>               facesContext.addMessage(null, new 
> FacesMessage("ActionListener:"+this.getListener()));          
>               log.info("This is the message for phase before 
> "+phaseEvent.getPhaseId().toString()+" : ");
>       }
>       
>       public void afterPhase(PhaseEvent phaseEvent){
>               FacesContext facesContext = FacesContext.getCurrentInstance();  
>         
>               
>               facesContext.addMessage(null, new FacesMessage("This is the 
> message for phase after "+phaseEvent.getPhaseId().toString()));
>               facesContext.addMessage(null, new 
> FacesMessage("Component:"+this.getInput1()));
>               facesContext.addMessage(null, new 
> FacesMessage("Validator:"+this.getValidatorBigdecimal()));
>               facesContext.addMessage(null, new 
> FacesMessage("Converter:"+this.getConverterBigdecimal()));
>               facesContext.addMessage(null, new 
> FacesMessage("ActionListener:"+this.getListener()));
>               log.info("This is the message for phase after 
> "+phaseEvent.getPhaseId().toString()+" : ");              
>       }
>       
>       public BigInteger getBigint() {
>               return bigint;
>       }
>       public void setBigint(BigInteger bigint) {
>               this.bigint = bigint;
>       }
>       public BigDecimal getBigdecimal() {
>               return bigdecimal;
>       }
>       public void setBigdecimal(BigDecimal bigdecimal) {
>               this.bigdecimal = bigdecimal;
>       }
>       public Converter getConverterBigint() {
>               return converterBigint;
>       }
>       public void setConverterBigint(Converter converterBigint) {
>               this.converterBigint = converterBigint;
>       }
>       public Converter getConverterBigdecimal() {
>               return converterBigdecimal;
>       }
>       public void setConverterBigdecimal(Converter converterBigdecimal) {
>               this.converterBigdecimal = converterBigdecimal;
>       }
>       public Validator getValidatorBigint() {
>               return validatorBigint;
>       }
>       public void setValidatorBigint(Validator validatorBigint) {
>               this.validatorBigint = validatorBigint;
>       }
>       public Validator getValidatorBigdecimal() {
>               return validatorBigdecimal;
>       }
>       public void setValidatorBigdecimal(Validator validatorBigdecimal) {
>               this.validatorBigdecimal = validatorBigdecimal;
>       }
>       
>       public String update(){
>               FacesContext context = FacesContext.getCurrentInstance();
>               return "update";
>       }
>       public HtmlInputText getInput1() {
>               return input1;
>       }
>       public void setInput1(HtmlInputText input1) {
>               this.input1 = input1;
>       }
>       public HtmlInputText getInput2() {
>               return input2;
>       }
>       public void setInput2(HtmlInputText input2) {
>               this.input2 = input2;
>       }
>       public ActionListener getListener() {
>               return listener;
>       }
>       public void setListener(ActionListener listener) {
>               this.listener = listener;
>       }
> }
> When you call the page the first time, this is the output for <h:messages> 
> tag :
> JSF RI:
>     *  This is the message for phase before RENDER_RESPONSE 6
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null 
> Myfaces:
>     * This is the message for phase before RENDER_RESPONSE(6)
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:[EMAIL PROTECTED]
> QUESTION 1: Why do I create an object that I do not use?. Myfaces is wrong, 
> and JSF RI has the correct behaviour. 
> The first time that I load a page, it's unnecesary to create those objects.
> And when you press the button or submit the form:
> JSF RI:
>     *  This is the message for phase before APPLY_REQUEST_VALUES 2
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase after APPLY_REQUEST_VALUES 2
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase before PROCESS_VALIDATIONS 3
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase after PROCESS_VALIDATIONS 3
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:null
>     * This is the message for phase before UPDATE_MODEL_VALUES 4
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:null
>     * This is the message for phase after UPDATE_MODEL_VALUES 4
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:null
>     * This is the message for phase before INVOKE_APPLICATION 5
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:null
>     * This is the message for phase after INVOKE_APPLICATION 5
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:[EMAIL PROTECTED]
>     * This is the message for phase before RENDER_RESPONSE 6
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:[EMAIL PROTECTED] 
> Myfaces:
>     * This is the message for phase before APPLY_REQUEST_VALUES(2)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase after APPLY_REQUEST_VALUES(2)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase before PROCESS_VALIDATIONS(3)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase after PROCESS_VALIDATIONS(3)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase before UPDATE_MODEL_VALUES(4)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase after UPDATE_MODEL_VALUES(4)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase before INVOKE_APPLICATION(5)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase after INVOKE_APPLICATION(5)
>     * Component:[EMAIL PROTECTED]
>     * Validator:null
>     * Converter:null
>     * ActionListener:null
>     * This is the message for phase before RENDER_RESPONSE(6)
>     * Component:[EMAIL PROTECTED]
>     * Validator:[EMAIL PROTECTED]
>     * Converter:[EMAIL PROTECTED]
>     * ActionListener:[EMAIL PROTECTED]
> QUESTION 2: Why I not have bindings assigned before  INVOKE_APPLICATION ?(in 
> this time is of value have a binding attribute) .  
> Again JSF RI has the correct behaviour and Myfaces is wrong. Myfaces create 
> the validators, converters and
> actionListeners on correct time, but not assign bindings when is supposed to 
> do. If I assign a binding for
> converter, validator or actionListener, I should be assigned minimum before 
> INVOKE_APPLICATION, or better,
> converters and validators on PROCESS_VALIDATIONS, and actionListeners in 
> INVOKE_APPLICATION.
> Looks a little bit difficult but I will try to find a solution for this issue.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to