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;The output from the testcase in the previous post:
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;
}
}
status code -> enum:A third approach is to combine the above 2 approaches by building the mapping inside
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
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;
}