*/
private static void buildEnumValueMethods(boolean exists, String type,
String evmeth) throws JiBXException {
// set up for adding serialize/deserialize methods to enum class
BoundClass bndclas = BoundClass.getInstance(type, null);
ClassFile ecf = bndclas.getClassFile();
String typesig = ecf.getSignature();
String evfull = type + '.' + evmeth;
String sersig = "(" + typesig + ")Ljava/lang/String;";
String dsersig = "(Ljava/lang/String;)" + typesig;
// check verify vs. add
if (exists) {
// just verify existing methods
if (ecf.getMethod(CUSTOM_ENUM_SERIALIZER_NAME,
new String[] { sersig }) == null) {
throw new JiBXException("Expected serializer method " +
CUSTOM_ENUM_SERIALIZER_NAME + " not found in enum class " +
type);
}
if (ecf.getMethod(CUSTOM_ENUM_DESERIALIZER_NAME,
new String[] { dsersig }) == null) {
throw new JiBXException("Expected deserializer method " +
CUSTOM_ENUM_DESERIALIZER_NAME +
" not found in enum class " + type);
}
} else {
// build the serializer method (just delegates to value method)
ClassFile cf = bndclas.getMungedFile();
ExceptionMethodBuilder smeth = new ExceptionMethodBuilder
(CUSTOM_ENUM_SERIALIZER_NAME, sersig, cf,
Constants.ACC_PUBLIC | Constants.ACC_STATIC);
smeth.appendLoadLocal(0);
BranchWrapper nonnull = smeth.appendIFNONNULL(smeth);
smeth.appendACONST_NULL();
smeth.appendReturn("java.lang.String");
smeth.targetNext(nonnull);
smeth.appendLoadLocal(0);
smeth.appendCallVirtual(evfull, "()Ljava/lang/String;");
smeth.appendReturn("java.lang.String");
bndclas.getUniqueNamed(smeth);
// create the deserializer method
ExceptionMethodBuilder dmeth = new ExceptionMethodBuilder
(CUSTOM_ENUM_DESERIALIZER_NAME, dsersig, cf,
Constants.ACC_PUBLIC | Constants.ACC_STATIC);
dmeth.addException(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
// start by handling the null string case
dmeth.appendLoadLocal(0);
nonnull = dmeth.appendIFNONNULL(dmeth);
dmeth.appendACONST_NULL();
dmeth.appendReturn(type);
dmeth.targetNext(nonnull);
// set up locals for array of values and decrementing index
dmeth.appendCallStatic(type + ".values", "()[" + typesig);
dmeth.appendDUP();
int arraylocal = dmeth.addLocal("values",
ClassItem.typeFromName(type + "[]"));
dmeth.appendARRAYLENGTH();
int arrayindex = dmeth.addLocal("index",
ClassItem.typeFromName("int"));
// start comparison loop with check for off bottom of array
BranchTarget start = dmeth.appendTargetNOP();
dmeth.appendIncrementLocal(-1, arrayindex);
dmeth.appendLoadLocal(arrayindex);
BranchWrapper loadnext = dmeth.appendIFGE(dmeth);
// throw an exception for value not found
dmeth.appendCreateNew("java.lang.StringBuffer");
dmeth.appendDUP();
dmeth.appendLoadConstant("No match found for value '");
dmeth.appendCallInit("java.lang.StringBuffer",
"(Ljava/lang/String;)V");
dmeth.appendLoadLocal(0);
dmeth.appendCallVirtual("java.lang.StringBuffer.append",
"(Ljava/lang/String;)Ljava/lang/StringBuffer;");
dmeth.appendLoadConstant("' in enum class " + type);
dmeth.appendCallVirtual("java.lang.StringBuffer.append",
"(Ljava/lang/String;)Ljava/lang/StringBuffer;");
dmeth.appendCallVirtual("java.lang.StringBuffer.toString",
"()Ljava/lang/String;");
dmeth.appendCreateNew(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS);
dmeth.appendDUP_X1();
dmeth.appendSWAP();
dmeth.appendCallInit(MethodBuilder.FRAMEWORK_EXCEPTION_CLASS,
MethodBuilder.EXCEPTION_CONSTRUCTOR_SIGNATURE1);
dmeth.appendThrow();
// load and compare the value
dmeth.targetNext(loadnext);
dmeth.appendLoadLocal(0);
dmeth.appendLoadLocal(arraylocal);
dmeth.appendLoadLocal(arrayindex);
dmeth.appendALOAD(type);
dmeth.appendCallVirtual(evfull, "()Ljava/lang/String;");
dmeth.appendCallVirtual("java.lang.Object.equals",
"(Ljava/lang/Object;)Z");
BranchWrapper tonext = dmeth.appendIFEQ(dmeth);
tonext.setTarget(start, dmeth);
// return the matching instance
dmeth.appendLoadLocal(arraylocal);
dmeth.appendLoadLocal(arrayindex);
dmeth.appendALOAD(type);
dmeth.appendReturn(type);
// add completed method to class
bndclas.getUniqueNamed(dmeth);
}
}