Hi,

i have a web application running in the following environment:

JBoss 4.2.2
myfaces 1.1.5
jsf-facelets 1.1.13
trinidad 1.0.11

I have 2 different enum types:
Enum1 {A, B}
Enum2 {A1, A2, A3, B1, B2}

And I have 2 
<tr:selectOneListbox><http://myfaces.apache.org/trinidad/trinidad-api/tagdoc/tr_selectOneListbox.html>
 (also tested with 
<tr:selectOneChoice><http://myfaces.apache.org/trinidad/trinidad-api/tagdoc/tr_selectOneChoice.html>,
 same effects):

                  <tr:selectOneListbox
                        id="selection1"
                        label="selection1"
                        value="#{selected1}"
                        immediate="true"
                        required="false"
                        autoSubmit="true" >
                        <f:selectItems value="#{enum1values" />
                        <f:valueChangeListener 
type="de.tccproducts.Enum1ValueChanged " />
                  </tr:selectOneListbox>
                  <tr:selectOneListbox
                        id="selection2"
                        label="selection2"
                        value="#{selected2}"
                        required="true"
                        partialTriggers="selection1">
                        <f:selectItems value="#{enum2values}" />
                  </tr:selectOneListbox>

enum1values is a Map of String and the values of Enum1
enum2values is null at the beginning and gets changed by the valueChangeListener

The ValueChangeListener does the following:

-          when event.newValue is null, selectedEnumValues = null AND selected2 
= null

-          when event.newValue is Enum1.A, selectedEnumValues = Map of String 
and values of Enum2 (A1, A2, A3) AND selected2 = null

-          when event.newValue is Enum1.B, selectedEnumValues = Map of String 
and values of Enum2 (B1, B2) AND selected2 = null

Now to my first problem:
If I select A in the first listbox, than select A1 in the second listbox, than 
select B in the first listbox, the value B1 is selected in the second listbox.
Looks like the selected2 = null is not used, the component remembers that index 
1 is selected, and so the "new" item on index 1 is selected.

This is getting worse if I do the following:
Select A in the first listbox, than select A3 in the second listbox, than 
select B in the first listbox
The second listbox still "remember" that index 3 was selected, but there are 
only 2 selectable values, causing an ArrayIndexOutOfBounceException in Trinidad 
code (See below: StackTrace1)
Is this an trinidad bug or something general with the JSF livecycle I'm missing?

To work around this I have changed the second listbox to have
      valuePassThru="true"
and use a custom converter
<dps:enumConverter type="de.tccproducts.Enum2" />

The EnumConverter is initizied with the full qualified class name of the enum.
In the getAsString it simply returns paramObject.toString();
In the getAsObject it returns Enum.valueOf(type, paramsString) to get the 
EnumInsttance for the given String
(for SourceCode see below:EnumConverterSource)

The converter is registered in the facesConfig.xml:
      <converter>
            <converter-id>tccEntityConverter</converter-id>
            
<converter-class>de.tccproducts.dps.web.utils.converter.EntityConverter</converter-class>
            <property>
                  <property-name>type</property-name>
                  <property-class>java.lang.Class</property-class>
            </property>
      </converter>
And the tag for the converter is registered in the facelets tag lib:
<tag>
      <tag-name>enumConverter</tag-name>
            <converter>
         <converter-id>tccEnumConverter</converter-id>
            </converter>
      </tag>

This all works as wanted and no more index out of bounce exceptions are 
occurring, but when Trinidad updates the listbox in the ppr, always this log 
message occurs:
Time

Thread

Level

Category

Message

612234

http-0.0.0.0-8080-2

ERROR

org.apache.myfaces.application.ApplicationImpl

Initializing converter : de.tccproducts.dps.web.utils.converter.EnumConverter 
with property : type and value : null failed.

So looks like the converter is not initialized correctly, but it is working 
correctly, type is set, no Null pointer occurs.
So what's the problem with this log message?

Hope someone can help me

Regards
Markus


StackTrace1:
javax.servlet.ServletException: SelectOne submittedValue''s index 3 is out of 
bounds. It should be between 0 and 0
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:154)
      at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at 
org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._invokeDoFilter(TrinidadFilterImpl.java:262)
      at 
org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl._doFilterImpl(TrinidadFilterImpl.java:219)
      at 
org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:173)
      at 
org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92)
      at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at 
de.tccproducts.dps.web.utils.lifecycle.ExceptionFilter.doFilter(ExceptionFilter.java:35)
      at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at 
org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      at 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      at 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
      at 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      at 
org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
      at 
org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
      at 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      at 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at 
org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
      at 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
      at 
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      at 
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
      at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.IndexOutOfBoundsException: SelectOne submittedValue''s 
index 3 is out of bounds. It should be between 0 and 0
      at 
org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SimpleSelectOneRenderer.__getIndex(SimpleSelectOneRenderer.java:414)
      at 
org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SimpleSelectOneRenderer._convertIndexedSubmittedValue(SimpleSelectOneRenderer.java:214)
      at 
org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SimpleSelectOneRenderer.getConvertedValue(SimpleSelectOneRenderer.java:181)
      at 
org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.InputLabelAndMessageRenderer.getConvertedValue(InputLabelAndMessageRenderer.java:65)
      at 
org.apache.myfaces.trinidad.component.UIXEditableValue.getConvertedValue(UIXEditableValue.java:421)
      at 
org.apache.myfaces.trinidad.component.UIXEditableValue.validate(UIXEditableValue.java:163)
      at 
org.apache.myfaces.trinidad.component.UIXEditableValue._executeValidate(UIXEditableValue.java:488)
      at 
org.apache.myfaces.trinidad.component.UIXEditableValue.processValidators(UIXEditableValue.java:269)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXSubform.processValidators(UIXSubform.java:143)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
org.apache.myfaces.trinidad.component.UIXForm.processValidators(UIXForm.java:82)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildrenImpl(UIXComponentBase.java:939)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.validateChildren(UIXComponentBase.java:923)
      at 
org.apache.myfaces.trinidad.component.UIXComponentBase.processValidators(UIXComponentBase.java:758)
      at 
javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:627)
      at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:149)
      at 
org.apache.myfaces.lifecycle.ProcessValidationsExecutor.execute(ProcessValidationsExecutor.java:32)
      at 
org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:95)
      at 
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:70)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:139)
      ... 27 more


EnumConverterSource:
package de.tccproducts.dps.web.utils.converter;

import javax.faces.component.*;
import javax.faces.context.*;
import javax.faces.convert.*;

import org.apache.commons.lang.*;

public class EnumConverter implements Converter {
                private Class<? extends Enum> type;

                public Class<? extends Enum> getType() {
                               return type;
                }

                public void setType(Class<? extends Enum> type) {
                               this.type = type;
                }

                @SuppressWarnings("unchecked")
                public Object getAsObject(FacesContext context, UIComponent 
component, String paramString) throws ConverterException {
                               if(StringUtils.isBlank(paramString)) {
                                               return null;
                               }
                               return Enum.valueOf(type, paramString);
                }

                public String getAsString(FacesContext context, UIComponent 
component, Object paramObject) throws ConverterException {
                               if(paramObject == null) {
                                               return "";
                               }
                               return paramObject.toString();
                }
}

Reply via email to