5 Replies Latest reply on Aug 22, 2006 11:05 AM by perwik

    Cast Problem I dont understand ... Converter / SelectItems

    paper

      I tried to merge a Converter and a List to have one flexible component to use for different Entity-Classes to be used in a JSF-Select. I no get populated the List once, but abfter I get te following Exception:

      22:23:04,392 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
      java.lang.ClassCastException: java.util.ArrayList
       at javax.faces.component.UIOutput.restoreState(UIOutput.java:92)
       at javax.faces.component.UIInput.restoreState(UIInput.java:384)
       at javax.faces.component.html.HtmlSelectOneMenu.restoreState(HtmlSelectOneMenu.java:406)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:511)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:502)
       at javax.faces.component.UIComponentBase.processRestoreState(UIComponentBase.java:502)
       at org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreComponentState(JspStateManagerImpl.java:129)
       at org.apache.myfaces.application.jsp.JspStateManagerImpl.restoreView(JspStateManagerImpl.java:185)
       at org.jboss.seam.jsf.SeamPhaseListener$StateManagerInterceptor.restoreView(SeamPhaseListener.java:205)
       at org.apache.myfaces.application.jsp.JspViewHandlerImpl.restoreView(JspViewHandlerImpl.java:255)
       at com.sun.facelets.FaceletViewHandler.restoreView(FaceletViewHandler.java:319)
       at org.apache.myfaces.lifecycle.LifecycleImpl.restoreView(LifecycleImpl.java:124)
       at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:66)
       at javax.faces.webapp.FacesServlet.service(FacesServlet.java:106)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:23)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
       at org.jboss.web.tomcat.security.CustomPrincipalValve.invoke(CustomPrincipalValve.java:54)
       at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:174)
       at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
       at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
       at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
       at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
       at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:112)
       at java.lang.Thread.run(Thread.java:595)


      I've the following Code:

      package org.termtimer.controller;
      
      import static org.jboss.seam.InterceptionType.ALWAYS;
      import static org.jboss.seam.ScopeType.CONVERSATION;
      
      import java.util.Collection;
      import java.util.HashMap;
      import java.util.Iterator;
      import java.util.LinkedList;
      import java.util.List;
      import java.util.Map;
      
      import javax.ejb.Interceptors;
      import javax.ejb.Remove;
      import javax.faces.component.UIComponent;
      import javax.faces.context.FacesContext;
      import javax.faces.convert.ConverterException;
      import javax.faces.model.SelectItem;
      
      import org.jboss.logging.Logger;
      import org.jboss.seam.annotations.Create;
      import org.jboss.seam.annotations.Destroy;
      import org.jboss.seam.annotations.Intercept;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Scope;
      import org.jboss.seam.ejb.SeamInterceptor;
      import org.termtimer.model.Lookup;
      
      
      @Scope(CONVERSATION)
      @Name("flexSelectItems")
      @Interceptors(SeamInterceptor.class)
      @Intercept (ALWAYS)
      public class FlexSelectItemsBean extends LinkedList<SelectItem>
       implements List<SelectItem>, javax.faces.convert.Converter{
      
       private static final long serialVersionUID = -1611564525004318869L;
       private static final Logger log = Logger.getLogger(FlexSelectItemsBean.class);
       private Map<String, Object> items;
      
       public FlexSelectItemsBean() {
       super();
       items = new HashMap<String, Object>();
       log.info("SelectItemArrayList(c) called"+this);
       }
      
       public FlexSelectItemsBean(Collection<SelectItem> c) {
       super(c);
       items = new HashMap<String, Object>();
       log.info("SelectItemArrayList(c) called"+this);
       }
      
       public void convertIn(List list) {
       log.info("convertIn() called"+this);
       Iterator i = list.iterator();
       this.clear();
       while(i.hasNext()){
       log.info("outer while");
       Object o = i.next();
       try{
       log.info("inner while");
       Lookup l = (Lookup) o;
       SelectItem item = new SelectItem(o, l.getShowName());
       items.put(l.getKey(), o);
       this.add(item);
      
       }catch(Exception E){
       log.info("Exception");
       }
       }
       log.info("size:"+this.size());
      
       }
      
       @Create
       public void create(){
       log.info("create() called"+this);
       }
      
       @Destroy @Remove
       public void destroy() {
       log.info("destroy() called"+this);
       }
      
       //Converter Methods
       public Object getAsObject(FacesContext arg0, UIComponent arg1, String str) throws ConverterException {
       log.info("getAsObject() called"+this);
       if(items.containsKey(str)){
       return items.get(str);
       }
       return null;
       }
      
       public String getAsString(FacesContext arg0, UIComponent arg1, Object obj) throws ConverterException {
       log.info("getAsString() called"+this);
       if(obj instanceof Lookup){
       Lookup l = (Lookup)obj;
       log.info("ausgabe: "+l.getKey()+" "+l.getShowName());
       return l.getKey();
       }
       return null;
       }
      }
      


      In the SFSB which controls the view, I inject the "flexSelectItems", fill it an outject it.

      @In(value="flexSelectItems" ,create=true)
      @Out
      public FlexSelectItemsBean flexSelectItems;
      
      flexSelectItems.convertIn(facultyAPI.getAll());


      <div class="input">
       <h:selectOneMenu id="facult" value="lecturer.faculty" converter="#{flexSelectItems}">
       <f:selectItems value="#{flexSelectItems}" />
       </h:selectOneMenu>
       </div>




      I see that this is a strange concept, but I'd like to know where the Problem lies. Tried a lot and am thankful fur any help.

      Dennis

        • 1. Re: Cast Problem I dont understand ... Converter / SelectIte
          gavin.king

          Um, I guess this is not a Seam-related problem, right?

          • 2. Re: Cast Problem I dont understand ... Converter / SelectIte
            paper

            I think so, the exception occurs in a jsf component, but I m not sure. Will try again tomorrow. Its late now in Germany.

            Thx
            Dennis

            • 3. Re: Cast Problem I dont understand ... Converter / SelectIte
              paper

              didn't work like that. I use now a concept simular to the lookup converter you ca find in this post:
              http://www.jboss.com/index.html?module=bb&op=viewtopic&t=71182

              For all who are looking fon such a solution ill post my code here.

              Dennis

              The Lookup Base Class, with a static method to convert Lists with Objects that implement Lookup to Select items:

              @Name("LookupConverter")
              @Intercept(InterceptionType.ALWAYS)
              public abstract class LookupConverter<T extends Lookup>
              implements javax.faces.convert.Converter
              {
               private Class<T> entityClass ;
              
               public LookupConverter (Class<T> entityClass)
               {
               this.entityClass = entityClass ;
               }
              
               public String getAsString (FacesContext context, UIComponent component, Object object)
               {
               if (object == null)
               return null ;
              
               T lookup = (T) object ;
               return lookup.getKey () ;
               }
              
               public Object getAsObject (FacesContext context, UIComponent component, String value) throws ConverterException{
               EntityManager termtimerData = (EntityManager)Component.getInstance("termtimerEM", true);
               Object o = (Object)(T) termtimerData.find(entityClass, value);
               return o;
               }
              
               public static List<SelectItem> convertIn(List<? extends Lookup> list) {
               Iterator i = list.iterator();
               List<SelectItem> selectlist = new LinkedList<SelectItem>();
               while(i.hasNext()){
               Object o = i.next();
               try{
               Lookup l = (Lookup) o;
               SelectItem item = new SelectItem(o, l.getShowName(), l.getKey());
               selectlist.add(item);
              
               }catch(Exception E){
               }
               }
               return selectlist;
               }
              
              }


              The Lookup Interface:
              public interface Lookup {
               public String getShowName () ;
               public String getKey () ;
              }


              A concrete Converter for an Entity Class:
              @Name("FacultyConverter")
              @Scope(ScopeType.APPLICATION)
              @Intercept(InterceptionType.ALWAYS)
              public class FacultyConverter
              extends LookupConverter<Faculty>
              {
              
               public FacultyConverter ()
               {
               super (Faculty.class) ;
               }
              
              }


              In the BakingBean:
              @Out(scope=CONVERSATION)
              private List<SelectItem> facultySelect;
              
              //in the create method
              facultySelect = LookupConverter.convertIn(facultyDAO.getAll());
              


              and finaly the part in the facelet:
              <h:selectOneListbox id="faculty" value="#{lecturer.faculty}" converter="#{FacultyConverter}">
               <f:selectItems value="#{facultySelect}" />
              </h:selectOneListbox>


              and its improtant to implement toString() and equals(Object o) in all entities.

              • 4. Re: Cast Problem I dont understand ... Converter / SelectIte

                where and how is "termtimerEM" defined?

                • 5. Re: Cast Problem I dont understand ... Converter / SelectIte
                  perwik

                   

                  "paper" wrote:

                  The Lookup Interface:
                  public interface Lookup {
                   public String getShowName () ;
                   public String getKey () ;
                  }



                  I think a better solution would be to use annotations for these two properties, like @SelectItemName and @SelectItemKey. And if @SelectItemKey is missing from the entity the default action could be to use toString() on the @Id property.