struts2 enum值相关
public enum Dimension implements Serializable, IntegerValuedEnum { LARGE(234, 60, 0), SMALL(125, 125, 1); private final int width; private final int height; private final int code; private Dimension(int width, int height, int code) { this.width = width; this.height = height; this.code = code; } public int getWidth() { return width; } public int getHeight() { return height; } @Override public int getCode() { return code; } public String getDisplay() { return "" + this.width + "*" + this.height; }}
?
public class IntegerValuedEnumType<T extends Enum & IntegerValuedEnum> implements EnhancedUserType, ParameterizedType { /** * Enum class for this particular user type. */ private Class<T> enumClass; /** * Value to use if null. */ private Integer defaultValue; public IntegerValuedEnumType() { } public void setParameterValues(Properties parameters) { String enumClassName = parameters.getProperty("enum"); try { enumClass = (Class<T>) Class.forName(enumClassName).asSubclass(Enum.class) .asSubclass(IntegerValuedEnum.class); } catch (ClassNotFoundException e) { throw new HibernateException("Enum class not found", e); } String defaultValueStr = parameters.getProperty("defaultValue"); if (defaultValueStr != null && !defaultValueStr.isEmpty()) { try { setDefaultValue(Integer.parseInt(defaultValueStr)); } catch (NumberFormatException e) { throw new HibernateException("Invalid default value", e); } } } public Integer getDefaultValue() { return defaultValue; } public void setDefaultValue(Integer defaultValue) { this.defaultValue = defaultValue; } /** * The class returned by <tt>nullSafeGet()</tt>. * * @return Class */ public Class returnedClass() { return enumClass; } public int[] sqlTypes() { return new int[] { Types.TINYINT }; } public boolean isMutable() { return false; } /** * Retrieve an instance of the mapped class from a JDBC resultset. * Implementors should handle possibility of null values. * * @param rs a JDBC result set * @param names the column names * @param owner the containing entity * @return Object * @throws HibernateException * @throws SQLException */ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException { Integer value = rs.getInt(names[0]); if (value == null) { value = getDefaultValue(); if (value == null) { // no default value return null; } } String name = IntegerValuedEnumReflect.getNameFromValue(enumClass, value); if (rs.wasNull() || name == null || name.isEmpty()) { return null; } else { return Enum.valueOf(enumClass, name); } } /** * Write an instance of the mapped class to a prepared statement. * Implementors should handle possibility of null values. A multi-column * type should be written to parameters starting from <tt>index</tt>. * * @param st a JDBC prepared statement * @param value the object to write * @param index statement parameter index * @throws HibernateException * @throws SQLException */ public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException { if (value == null) { st.setNull(index, Types.TINYINT); } else { st.setInt(index, ((T) value).getCode()); } } public Object assemble(Serializable cached, Object owner) { return cached; } public Serializable disassemble(Object value) { return (Enum) value; } public Object deepCopy(Object value) { return value; } public boolean equals(Object x, Object y) { return x == y; } public int hashCode(Object x) { return x.hashCode(); } public Object replace(Object original, Object target, Object owner) { return original; } public String objectToSQLString(Object value) { return '\'' + String.valueOf(((T) value).getCode()) + '\''; } public String toXMLString(Object value) { return String.valueOf(((T) value).getCode()); } public Object fromXMLString(String xmlValue) { Integer value = Integer.parseInt(xmlValue); String name = IntegerValuedEnumReflect.getNameFromValue(enumClass, value); if (name == null || name.isEmpty()) { return null; } else { return Enum.valueOf(enumClass, name); } }}?
public final class IntegerValuedEnumReflect { /** * Don't let anyone instantiate this class. * * @throws UnsupportedOperationException * Always. */ private IntegerValuedEnumReflect() { throw new UnsupportedOperationException("This class must not be instanciated."); } /** * All Enum constants (instances) declared in the specified class. * * @param enumClass Class to reflect * @return Array of all declared EnumConstants (instances). */ private static <T extends Enum> T[] getValues(Class<T> enumClass) { return enumClass.getEnumConstants(); } /** * All possible string values of the string valued enum. * * @param enumClass Class to reflect. * @return Available integer values. */ public static <T extends Enum & IntegerValuedEnum> int[] getStringValues( Class<T> enumClass) { T[] values = getValues(enumClass); int[] result = new int[values.length]; for (int i = 0; i < values.length; i++) { result[i] = values[i].getCode(); } return result; } /** * Name of the enum instance which hold the respecified string value. If * value has duplicate enum instances than returns the first occurrence. * * @param enumClass Class to inspect. * @param value The int value. * @return name of the enum instance. */ public static <T extends Enum & IntegerValuedEnum> String getNameFromValue( Class<T> enumClass, int value) { T[] values = getValues(enumClass); for (int i = 0; i < values.length; i++) { if (values[i].getCode() == value) { return values[i].name(); } } return null; }}?
public class IntegerValuedEnumSetType<T extends Enum<T> & IntegerValuedEnum> implements EnhancedUserType, ParameterizedType { /** * Enum class for this particular user type. */ private Class<T> enumClass; public IntegerValuedEnumSetType() { } public void setParameterValues(Properties parameters) { String enumClassName = parameters.getProperty("enum"); try { enumClass = (Class<T>) Class.forName(enumClassName).asSubclass(Enum.class) .asSubclass(IntegerValuedEnum.class); } catch (ClassNotFoundException e) { throw new HibernateException("Enum class not found", e); } } /** * The class returned by <tt>nullSafeGet()</tt>. * * @return Class */ public Class returnedClass() { return enumClass; } public int[] sqlTypes() { return new int[] { Types.TINYINT }; } public boolean isMutable() { return false; } /** * Retrieve an instance of the mapped class from a JDBC resultset. * Implementors should handle possibility of null values. * * @param rs a JDBC result set * @param names the column names * @param owner the containing entity * @return Object * @throws HibernateException * @throws SQLException */ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException { Integer value = rs.getInt(names[0]); if (value == null) { return null; } return decode(value); } /** * Write an instance of the mapped class to a prepared statement. * Implementors should handle possibility of null values. A multi-column * type should be written to parameters starting from <tt>index</tt>. * * @param st a JDBC prepared statement * @param value the object to write * @param index statement parameter index * @throws HibernateException * @throws SQLException */ public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException { if (value == null) { st.setNull(index, Types.TINYINT); } else { st.setInt(index, encode((EnumSet<T>)value)); } } public Object assemble(Serializable cached, Object owner) { return cached; } public Serializable disassemble(Object value) { return (Enum) value; } public Object deepCopy(Object value) { return value; } public boolean equals(Object x, Object y) { return x == y; } public int hashCode(Object x) { return x.hashCode(); } public Object replace(Object original, Object target, Object owner) { return original; } public String objectToSQLString(Object value) { return '\'' + String.valueOf(encode((EnumSet<T>)value)) + '\''; } public String toXMLString(Object value) { return String.valueOf(encode((EnumSet<T>)value)); } public Object fromXMLString(String xmlValue) { try { Integer value = Integer.parseInt(xmlValue); return decode(value); } catch (NumberFormatException e) { return EnumSet.noneOf(enumClass); } } /* * Encode the EnumSet into an integer based on bit on/off */ private int encode(EnumSet<T> set) { int ret = 0; for (T val : set) { ret |= 1 << val.getCode(); } return ret; } /* * Decode the integer back to a EnumSet based on bit on/off */ private EnumSet<T> decode(int code) {Map<Integer, T> codeMap = new HashMap<Integer, T>();for (T val : EnumSet.allOf(enumClass)) {codeMap.put(val.getCode(), val);} EnumSet<T> result = EnumSet.noneOf(enumClass); while (code != 0) { int ordinal = Integer.numberOfTrailingZeros(code); code ^= Integer.lowestOneBit(code); result.add(codeMap.get(ordinal)); } return result; }}?
?
?
?
?
?
public interface IntegerValuedEnum {???
???
??? /**
???? * Current int value stored in the enum.
???? * @return int value.
???? */
??? int getCode();
???
}
?
?
maping.xml
<property name="dimension" column="DIMENSION"> <type name="com.xxx.bbb.hibernate.IntegerValuedEnumType"> <param name="enum">com.xxx.bbb.beans.Dimension</param> </type> </property>
?存到数据库只是 0? 1 2
?
?
?
转换器
public class DimensionConverter extends StrutsTypeConverter { @Override public Object convertFromString(Map arg0, String[] values, Class clazz) { if (values != null && values.length > 0 && values[0] != null && !values[0].isEmpty()) { String value = values[0]; if (value.equals("0")) { return Dimension.LARGE; } else if (value.equals("1")) { return Dimension.SMALL; } } return null; } @Override public String convertToString(Map arg0, Object o) { System.out.println(o.toString()); Dimension dimension = (Dimension) o; return String.valueOf(dimension.getCode()); }}
?
?
?
?
?
?
js
$("#dimensionSelect").val(${request.dimension.code});
?
?
<s:select id="dimensionSelect" name="dimension" list="#{@beans.Dimension@LARGE.code:@beans.Dimension@LARGE.display, @beans.Dimension@SMALL.code:@beans.Dimension@SMALL.display}" tabindex="4"/>