1 Reply Latest reply on Jun 2, 2007 11:26 AM by Chris Lowe

    Getting selectitems from the generated EntityList object

    amitdk Newbie

      Read some posts about how one can do this and wasn't satisfied with the solutions. I wanted one that was generic enough and one that used in the JSF read like an OO syntax.

      Here's the JSF code:

      <h:selectOneMenu id="division">
       <f:selectItems value="#{entitylist.selectItems[divisionList]}"/>
      </h:selectOneMenu>
      


      Next is the entitylist class that allows a parameter to be passed into it. Though EL syntax does not allow for parameter passing, there is technique around it. That technique is posted at http://wiki.apache.org/myfaces/Parameters_In_EL_Functions.
      Based on this I created the entitylist class as:

      public class EntityList
      {
       public SelectItems getSelectItems()
       {
       return new SelectItems();
       }
      }
      


      Then comes the core piece of code for the SelectItems class:
      import java.lang.reflect.Method;
      import java.util.List;
      import java.util.Vector;
      import javax.faces.model.SelectItem;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.framework.EntityQuery;
      
      @Name("selectitems")
      public class SelectItems<T extends EntityQuery> extends DummyMap
      {
       public SelectItems()
       {
       }
      
       public Object get(Object obj)
       {
       T list = (T) obj;
       return getItems(list.getResultList());
       }
      
       public List<SelectItem> getItems(List entities)
       {
       List<SelectItem> items = new Vector<SelectItem>();
       try
       {
       Method idMthd = null, nameMthd = null;
       for ( int i=0; i<entities.size(); i++ )
       {
       Object entity = entities.get(i);
       // On the first run, initialize reflection methods for object
       if ( idMthd==null )
       {
       Class entityClass = entity.getClass();
       idMthd = entityClass.getMethod("getId", new Class[]{});
       nameMthd = entityClass.getMethod("getName", new Class[]{});
       }
       // Retrieve values on the
       Integer id = (Integer)idMthd.invoke(entity, new Object[]{});
       String name = (String)nameMthd.invoke(entity, new Object[]{});
      
       // Add key information to select item list
       SelectItem item = new SelectItem();
       item.setLabel(name);
       item.setValue(id.toString());
       items.add(item);
       }
       }
       catch (Exception e)
       {
       // TODO Auto-generated catch block
       e.printStackTrace();
       }
       return items;
       }
      }
      


      Note here, the above method expects your domain/entity objects to have a getId() and getName() method. You can change that based upon how your domain objects are designed or add other values on that. I played around with the idea of an interface identifying these methods on the domain objects instead of the reflection route, however I did not want to impose that and felt the solution of reflection worked better. However, I'll leave that up for your judgment.

      Hope this will help folks out there that have come across this same issue.

      Regards
      Amit Karandikar
      Sun Certified Architect

        • 1. Re: Getting selectitems from the generated EntityList object
          Chris Lowe Apprentice

          What's wrong with Seam's solution?

          <h:selectOneMenu value="#{sysUsersHome.instance.tbCompany}" required="true">
           <s:selectItems value="#{companies}" var="company" label="#{company.descr}" noSelectionLabel="Select..." hideNoSelectionLabel="true"/>
           <s:convertEntity />
          </h:selectOneMenu>


          convertEntity looks for an entity's @Id field as the option id and the label comes from selectItem.label. Very flexible and no need to adhere to getId() and getName() conventions. The noSelectionLabel functionality is also very handy.

          Best Regards,

          Chris.