3/23/2008

Enum wrapper for javax.transaction.Status (2)

In this previous post, I wrote about a enum type wrapper around javax.transaction.Status. It uses a static map to hold the mapping between integer status code and enum type. Here is a slightly shorter (better) implementation without using a static mapping. The commented lines are original code:
package javahowto;
import java.util.EnumSet;
import javax.transaction.Status;

public enum TransactionStatusEnum {
STATUS_ACTIVE (Status.STATUS_ACTIVE),
STATUS_COMMITTED (Status.STATUS_COMMITTED),
STATUS_COMMITTING (Status.STATUS_COMMITTING),
STATUS_MARKED_ROLLBACK (Status.STATUS_MARKED_ROLLBACK),
STATUS_NO_TRANSACTION (Status.STATUS_NO_TRANSACTION),
STATUS_PREPARED (Status.STATUS_PREPARED),
STATUS_PREPARING (Status.STATUS_PREPARING),
STATUS_ROLLEDBACK (Status.STATUS_ROLLEDBACK),
STATUS_ROLLING_BACK (Status.STATUS_ROLLING_BACK),
STATUS_UNKNOWN (Status.STATUS_UNKNOWN);

// private static Map<Integer, TransactionStatusEnum> codeToEnums
// = new HashMap<Integer, TransactionStatusEnum>();
//
// static {
// codeToEnums.put(Status.STATUS_ACTIVE, STATUS_ACTIVE);
// codeToEnums.put(Status.STATUS_COMMITTED, STATUS_COMMITTED);
// codeToEnums.put(Status.STATUS_COMMITTING, STATUS_COMMITTING);
// codeToEnums.put(Status.STATUS_MARKED_ROLLBACK, STATUS_MARKED_ROLLBACK);
// codeToEnums.put(Status.STATUS_NO_TRANSACTION, STATUS_NO_TRANSACTION);
// codeToEnums.put(Status.STATUS_PREPARED, STATUS_PREPARED);
// codeToEnums.put(Status.STATUS_PREPARING, STATUS_PREPARING);
// codeToEnums.put(Status.STATUS_ROLLEDBACK, STATUS_ROLLEDBACK);
// codeToEnums.put(Status.STATUS_ROLLING_BACK, STATUS_ROLLING_BACK);
// codeToEnums.put(Status.STATUS_UNKNOWN, STATUS_UNKNOWN);
// }

private Integer statusCode;

public Integer getStatusCode() {
return statusCode;
}

public static TransactionStatusEnum getEnumFor(Integer i) {
// return codeToEnums.get(i);
for(TransactionStatusEnum t : EnumSet.allOf(TransactionStatusEnum.class)) {
if(t.statusCode == i) {
return t;
}
}
throw new IllegalArgumentException("Invalid transaction status code: " + i);
}

@Override public String toString() {
return super.toString() + "(" + statusCode + ")";
}

private TransactionStatusEnum(int statusCode) {
this.statusCode = statusCode;
}
}
The output from the testcase in the previous post:
status code -> enum:
STATUS_ACTIVE(0)
STATUS_MARKED_ROLLBACK(1)
STATUS_PREPARED(2)
STATUS_COMMITTED(3)
STATUS_ROLLEDBACK(4)
STATUS_UNKNOWN(5)
STATUS_NO_TRANSACTION(6)
STATUS_PREPARING(7)
STATUS_COMMITTING(8)
STATUS_ROLLING_BACK(9)

enum -> status code:
STATUS_ACTIVE(0) 0
STATUS_COMMITTED(3) 3
STATUS_COMMITTING(8) 8
STATUS_MARKED_ROLLBACK(1) 1
STATUS_NO_TRANSACTION(6) 6
STATUS_PREPARED(2) 2
STATUS_PREPARING(7) 7
STATUS_ROLLEDBACK(4) 4
STATUS_ROLLING_BACK(9) 9
STATUS_UNKNOWN(5) 5
A third approach is to combine the above 2 approaches by building the mapping inside getEnumFor method so that subsequent calls may not need to iterate over all elements. This can be useful if the enum type has many elements. getEnumFor can be rewritten as:
public static synchronized TransactionStatusEnum getEnumFor(Integer i) {
TransactionStatusEnum en = codeToEnums.get(i);
if (en == null) {
for (TransactionStatusEnum t : values()) {
if (t.statusCode == i) {
en = t;
codeToEnums.put(i, t);
break;
}
}
}
if (en == null) {
throw new IllegalArgumentException("Invalid transaction status code: " + i);
}
return en;
}

4 comments:

Anonymous said...

Why not do the mapping in the constructor?

javahowto said...

The mapping belongs to the whole enum (class) level, not instance level. So make it static variable, and a static block is a good place for initializing static variables.

If done inside the constructor, it will be done once for each element.

The static block is invoked at classloading time, before calling any constructor.

Anonymous said...

for(TransactionStatusEnum t : EnumSet.allOf(TransactionStatusEnum.class))
should be written as
for(TransactionStatusEnum t : TransactionStatusEnum.values())

Anna said...

Great and Useful Article.

Online Java Course

Java Online Training

Java Course Online

J2EE training

online J2EE training

Best Recommended books for Spring framework

Java Interview Questions












Java Training Institutes in Chennai

Java Training in Chennai

J2EE Training in Chennai

java j2ee training institutes in chennai