This discussion is archived
3 Replies Latest reply: May 6, 2008 5:10 AM by 797177 RSS

What's the best way to use an enum to validate statuses

807601 Newbie
Currently Being Moderated
I am trying to write and use an enum to represent a status code and validate status code values. Ultimately the input data from another system and the database will be 1 or 2 i.e.the indexes and the java code will use the LIVE and CANCELLED when referring to the status. The code I have written
public class TestEntityStatus {

     private static EntityStatusImpl es;
     
     public static void main(final String args[]){
          
                es =  new EntityStatusImpl();   
                es.setStatusCode("1"); // valid test
                es.setStatusCode("3"); // invalid test
     }
}
The EntityStatusImpl class:
public class EntityStatusImpl {

    private String statusCode;

    public EntityStatusImpl() {
    }

    public final String getStatusCode() {
        return statusCode;
    }

    public final void setStatusCode(final String statusCode) {

         String allStsIndexesAsRegExpr = "[";                                                                                 //
            EntityStatus allStatuses [] = EntityStatus.values();                                                     // would like to  
            for(EntityStatus e : allStatuses)                                                                                // put this code
                allStsIndexesAsRegExpr = allStsIndexesAsRegExpr + e.getStatusCode();   // in the enum 
            allStsIndexesAsRegExpr = allStsIndexesAsRegExpr + "]";                                        // EntityStatus
            System.out.println(" allStsIndexesAsRegExpr = " + allStsIndexesAsRegExpr);           // 
       
             if (statusCode.matches(allStsIndexesAsRegExpr)) {
                 this.statusCode = statusCode;          
             }
             else {
                  throw new IllegalArgumentException("Entity status " + statusCode + " is invalid");     
             }
       }           
}
The EntityStatus enum has a method "getAllIndexesAsRegex" which I would like to call. However, my understanding of enums is preventing me from doing so.

If I declared an EntityStatus, I expected that I would be able to get all of the indexes back as follows in

EntityStatus x;

x.getAllIndexesAsRegex();


Instead I have to copied the code from the enum into the setStatusCode method above, where it works but does not seem to be in the right place.
public enum EntityStatus {

                 LIVE(1), CANCELLED(2); 
 
                 private int index; 

             private EntityStatus(int index) { 
                 this.index = index; 

                 } 

     
              public int getStatusCode(){
                       return index;  
                 } 
              
              public String getAllIndexesAsRegex(){
                   String output = "[";
                   PromiseStatus allStatuses [] = PromiseStatus.values();
                   for(PromiseStatus p : allStatuses)
                        output = output + p.getStatusCode();
                   output = output + "]";
                   return output;
              }
        
     }
The java tutorial doesn't seem to throw much light on this type of application of enums for me, neither does Herbert Schilt's excellent book on Java 5.

Can anyone spot any flaws in my logic or suggest better ways of achieving this?
  • 1. Re: What's the best way to use an enum to validate statuses
    797177 Newbie
    Currently Being Moderated
    If you want to ensure type safety and retrict the user to a range of values it seems to me you are over complicating
    the implementation. Simply change your Impl class accessor and mutator methods to accept and return the enum
    type respectively. For example:
    private EntityStatus entityStatus;
    
    public EntityStatus getEntityStatus()
    {
       return entityStatus;
    }
    
    public void setEntityStatus(EntityStatus entityStatus)
    {
      if (entityStatus == null)
      {
        throw new IllegalArgumentException("Invalid entity status!");
      }
       
      this.entityStatus = entityStatus;
    }
    The one downside is that you are retrieving the actual underlying enum values from external source systems which you need to map back to your
    enum types. Unfortunately the Enum class does not have a method that will return what you need (the valueOf method returns the enum type
    based on the enum name). However you can provide a method in your enum class that will map the external source values to the enum. Below is
    one such implemetation.
    import java.util.HashMap;
    import java.util.Map;
    
    public enum EntityStatus
    {
      LIVE("1"),
      CANCELLED("2");
    
      private String statusCode;
    
      private static Map<String,EntityStatus> enumMap = new HashMap<String,EntityStatus>(EntityStatus.values().length);
    
      static
      {
        enumMap.put(LIVE.getStatusCode(),LIVE);
        enumMap.put(CANCELLED.getStatusCode(),CANCELLED);
      }
    
      private EntityStatus(String statusCode)
      {
        this.statusCode = statusCode;
      }
    
      public String getStatusCode()
      {
        return statusCode;
      }
    
      public static synchronized EntityStatus deriveObject(String statusCode)
      {
        return enumMap.get(statusCode);
      }
    }
    Below is a usage example:
      public static void main(String args[])
      {
        EntityStatus status1 = EntityStatus.deriveObject("1");
        EntityStatus status2 = EntityStatus.deriveObject("2");
        EntityStatus status3 = EntityStatus.deriveObject("3");
    
        System.out.println(status1);
        System.out.println(status2);
        System.out.println(status3);
      }
  • 2. Re: What's the best way to use an enum to validate statuses
    807601 Newbie
    Currently Being Moderated
    Thank you paternostro for the solution.

    If I have understood the code correctly, to pass in an EntityStatus and retrieve the corresponding status values, another HashMap could be added to the enum:
    private static Map<EntityStatus, String> enumMap2 = new HashMap<EntityStatus,String>(EntityStatus.values().length);
                         
                     static
                     {
                       enumMap2.put(EntityStatus.LIVE,"1");
                       enumMap2.put(EntityStatus.KEPT, "2");
                     }
    
    public static synchronized String deriveStatusCode(EntityStatus entityStatus)
                     {
                       return enumMap2.get(entityStatus);
                     }
  • 3. Re: What's the best way to use an enum to validate statuses
    797177 Newbie
    Currently Being Moderated
    Actually that map wouldn't be necessary as you can simply call the enum's getStatusCode method to retrieve the
    underlying value. For example:
    String liveStatusCode = EntityStatus.LIVE.getStatusCode();