use of org.apache.xbean.asm5.Type in project apex-malhar by apache.
the class BeanClassGenerator method addToStringMethod.
/**
* Adds a toString method to underlying class. Uses StringBuilder to generate the final string.
*
* @param classNode
* @param fieldList
* @throws JSONException
*/
@SuppressWarnings("unchecked")
private static void addToStringMethod(ClassNode classNode, List<TupleSchemaRegistry.SQLFieldInfo> fieldList) throws JSONException {
MethodNode toStringNode = new MethodNode(Opcodes.ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
toStringNode.visitAnnotation("Ljava/lang/Override;", true);
toStringNode.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/lang/StringBuilder"));
toStringNode.instructions.add(new InsnNode(Opcodes.DUP));
toStringNode.instructions.add(new LdcInsnNode(classNode.name + "{"));
toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false));
toStringNode.instructions.add(new VarInsnNode(Opcodes.ASTORE, 1));
toStringNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
for (int i = 0; i < fieldList.size(); i++) {
TupleSchemaRegistry.SQLFieldInfo info = fieldList.get(i);
String fieldName = info.getColumnName();
String fieldType = info.getType().getJavaType().getName();
String fieldJavaType = getJavaType(fieldType);
if (i != 0) {
toStringNode.instructions.add(new LdcInsnNode(", "));
toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
}
toStringNode.instructions.add(new LdcInsnNode(fieldName + "="));
toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
toStringNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
toStringNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
// There is no StringBuilder.append method for short and byte. It takes it as int.
if (fieldJavaType.equals(Character.toString(typeIdentifierShort)) || fieldJavaType.equals(Character.toString(typeIdentifierByte))) {
fieldJavaType = "I";
}
Character pchar = PRIMITIVE_TYPES.get(fieldType);
if (pchar == null) {
// It's not a primitive type. StringBuilder.append method signature takes Object type.
fieldJavaType = "Ljava/lang/Object;";
}
toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(" + fieldJavaType + ")Ljava/lang/StringBuilder;", false));
}
toStringNode.instructions.add(new LdcInsnNode("}"));
toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
toStringNode.instructions.add(new InsnNode(Opcodes.POP));
toStringNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
toStringNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false));
toStringNode.instructions.add(new InsnNode(Opcodes.ARETURN));
classNode.methods.add(toStringNode);
}
use of org.apache.xbean.asm5.Type in project apex-malhar by apache.
the class BeanClassGenerator method addPrivateField.
/**
* Add private field to the class
* @param classNode ClassNode which needs to be populated with private field.
* @param fieldName Name of the field
* @param fieldJavaType Java ASM type of the field
*/
@SuppressWarnings("unchecked")
private static void addPrivateField(ClassNode classNode, String fieldName, String fieldJavaType) {
FieldNode fieldNode = new FieldNode(Opcodes.ACC_PRIVATE, fieldName, fieldJavaType, null, null);
classNode.fields.add(fieldNode);
}
use of org.apache.xbean.asm5.Type in project tomee by apache.
the class Cmp2Generator method createCmrSetter.
/**
* Generate a setter method for a CMR field. The
* setter method will delegate the setting responsibility
* to the accessor object store the associated Cmr field.
*
* @param cmrField The field we're generating the setter for.
*/
private void createCmrSetter(final CmrField cmrField) {
// no back reference. We don't generate a getter method for this
if (cmrField.isSynthetic()) {
return;
}
final String methodName = setterName(cmrField.getName());
final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "(" + cmrField.getProxyDescriptor() + ")V", null, null);
mv.visitCode();
// the Set with the new values from the new value source.
if (cmrField.getCmrStyle() != CmrStyle.SINGLE) {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName() + "Cmr", cmrField.getAccessorDescriptor());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, cmrField.getAccessorInternalName(), "set", cmrField.getCmrStyle().getSetterDescriptor(), false);
mv.visitInsn(RETURN);
} else {
// this is a single value. We pass the existing value and the old value to
// the accessor, then must cast the accessor return value to the target type
// so we can store it in the real CMR field.
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName() + "Cmr", cmrField.getAccessorDescriptor());
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, cmrField.getAccessorInternalName(), "set", cmrField.getCmrStyle().getSetterDescriptor(), false);
mv.visitTypeInsn(CHECKCAST, cmrField.getType().getInternalName());
mv.visitFieldInsn(PUTFIELD, implClassName, cmrField.getName(), cmrField.getDescriptor());
mv.visitInsn(RETURN);
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
use of org.apache.xbean.asm5.Type in project tomee by apache.
the class Cmp2Generator method createGetter.
/**
* Generate a concrete getter field for a CMP field.
* At this point, we're just generating a simple
* accessor for the field, given the type. The
* JPA engine when it makes this implementation class
* a managed class define whatever additional logic
* might be required.
*
* @param cmpField The CMP field backing this getter method.
*/
private void createGetter(final CmpField cmpField) {
final String methodName = cmpField.getGetterMethod().getName();
final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()" + cmpField.getDescriptor(), null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, cmpField.getName(), cmpField.getDescriptor());
mv.visitInsn(cmpField.getType().getOpcode(IRETURN));
mv.visitMaxs(0, 0);
mv.visitEnd();
}
use of org.apache.xbean.asm5.Type in project tomee by apache.
the class Cmp2Generator method createSimplePrimaryKeyGetter.
/**
* Create a simple internal method for obtaining the
* primary key. There are 2 possibilities for handling
* the primary key here:
* <p/>
* 1) There is a defined primary key field. The
* contents of that field are returned.
* <p/>
* 2) The primary key is provided by the container.
* This is a long value stored in a private, generated
* field. This field is returned as a generated
* wrappered Long.
* <p/>
* 3) A primary key class has been provided. An instance
* of this class is instantiated, and code is generated
* that will copy all of the CMP fields from the EJB
* into the primary key instance.
*/
private void createSimplePrimaryKeyGetter() {
final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "OpenEJB_getPrimaryKey", "()Ljava/lang/Object;", null, null);
mv.visitCode();
// the primary key is identifed as a field. We just return that value directly.
if (pkField != null) {
// push the pk field
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, pkField.getName(), pkField.getDescriptor());
// return the pk field (from the stack)
mv.visitInsn(pkField.getType().getOpcode(IRETURN));
} else if (Object.class.equals(primKeyClass)) {
// this is a container-generated primary key. It's a long value stored in
// a generated field. We return that value, wrappered in a Long instance.
// push the pk field
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, UNKNOWN_PK_NAME, UNKNOWN_PK_TYPE.getDescriptor());
// return the pk field (from the stack)
mv.visitInsn(UNKNOWN_PK_TYPE.getOpcode(IRETURN));
} else {
// We have a primary key class defined. For every field that matches one of the
// defined CMP fields, we generate code to copy that value into the corresponding
// field of the primary key class.
final String pkImplName = primKeyClass.getName().replace('.', '/');
// new Pk();
mv.visitTypeInsn(NEW, pkImplName);
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, pkImplName, "<init>", "()V", false);
mv.visitVarInsn(ASTORE, 1);
mv.visitVarInsn(ALOAD, 1);
// copy each field from the ejb to the pk class
for (final Field field : primKeyClass.getFields()) {
final CmpField cmpField = cmpFields.get(field.getName());
// only process the cmp fields
if (cmpField == null) {
continue;
}
// check again since generated code is so hard to debug
if (!cmpField.getType().getClassName().equals(field.getType().getName())) {
throw new IllegalArgumentException("Primary key " + cmpField.getName() + " is type " + cmpField.getType().getClassName() + " but CMP field is type " + field.getType().getName());
}
// push the value from the cmp bean
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, implClassName, cmpField.getName(), cmpField.getDescriptor());
// set matching field in the pk class to the value on the stack
mv.visitFieldInsn(PUTFIELD, pkImplName, cmpField.getName(), cmpField.getDescriptor());
mv.visitVarInsn(ALOAD, 1);
}
// return the Pk();
mv.visitInsn(ARETURN);
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
Aggregations