use of org.apache.xbean.asm5.tree.ClassNode in project apex-core by apache.
the class ASMUtil method getPublicGetter.
/**
* Get a list of getter methods from classnode asmNode
* @param asmNode
* @return empty list if there is no getter method
*/
public static List<MethodNode> getPublicGetter(ClassNode asmNode) {
List<MethodNode> result = new LinkedList<>();
@SuppressWarnings("unchecked") List<MethodNode> mList = asmNode.methods;
for (MethodNode methodNode : mList) {
// and must be public
if ((Type.getArgumentTypes(methodNode.desc).length == 0 && Type.getReturnType(methodNode.desc) != Type.VOID_TYPE) && (methodNode.name.startsWith("get") || (methodNode.name.startsWith("is") && Type.getReturnType(methodNode.desc) == Type.BOOLEAN_TYPE)) && isPublic(methodNode.access)) {
result.add(methodNode);
}
}
return result;
}
use of org.apache.xbean.asm5.tree.ClassNode in project apex-core by apache.
the class CompactUtil method updateCompactClassPortInfo.
public static void updateCompactClassPortInfo(ClassNode cn, CompactClassNode ccn) {
List<FieldNode> fields = ASMUtil.getPorts(cn);
List<CompactFieldNode> ports = new LinkedList<>();
for (FieldNode fn : fields) {
ports.add(compactFieldNode(fn));
}
ccn.setPorts(ports);
}
use of org.apache.xbean.asm5.tree.ClassNode in project apex-malhar by apache.
the class BeanClassGenerator method createAndWriteBeanClass.
/**
* Creates a class from given field information and writes it to the output stream. Also returns byte[] of compiled
* class
*
* @param fqcn fully qualified class name
* @param fieldList field list describing the class
* @param outputStream stream to which the class is persisted
* @throws JSONException
* @throws IOException
*/
public static byte[] createAndWriteBeanClass(String fqcn, List<TupleSchemaRegistry.SQLFieldInfo> fieldList, FSDataOutputStream outputStream) throws JSONException, IOException {
ClassNode classNode = new ClassNode();
// generated class will only run on JRE 1.7 or above
classNode.version = Opcodes.V1_7;
classNode.access = Opcodes.ACC_PUBLIC;
classNode.name = fqcn.replace('.', '/');
classNode.superName = "java/lang/Object";
// add default constructor
addDefaultConstructor(classNode);
for (TupleSchemaRegistry.SQLFieldInfo fieldInfo : fieldList) {
String fieldName = fieldInfo.getColumnName();
String fieldType = fieldInfo.getType().getJavaType().getName();
String fieldJavaType = getJavaType(fieldType);
addPrivateField(classNode, fieldName, fieldJavaType);
String fieldNameForMethods = Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
if (fieldJavaType.equals(getJavaType("java.util.Date"))) {
addDateFields(classNode, fieldName, fieldNameForMethods, "java/util/Date");
} else {
addGetter(classNode, fieldName, fieldNameForMethods, fieldJavaType);
addSetter(classNode, fieldName, fieldNameForMethods, fieldJavaType);
}
}
addToStringMethod(classNode, fieldList);
addHashCodeMethod(classNode, fieldList);
addEqualsMethod(classNode, fieldList);
// Write the class
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
classNode.accept(cw);
cw.visitEnd();
byte[] classBytes = cw.toByteArray();
if (outputStream != null) {
outputStream.write(classBytes);
outputStream.close();
}
return classBytes;
}
use of org.apache.xbean.asm5.tree.ClassNode in project apex-malhar by apache.
the class BeanClassGenerator method addHashCodeMethod.
/**
* This will add a hashCode method for class being generated. <br>
* Algorithm is as follows: <br>
* <i><p>
* int hashCode = 7;
* for (field: all fields) {
* hashCode = 23 * hashCode + field.hashCode()
* }
* </p></i>
* <br>
* <b> For primitive field, hashcode implemenented is similar to the one present in its wrapper class. </b>
*
* @param classNode
* @param fieldList
* @throws JSONException
*/
@SuppressWarnings("unchecked")
private static void addHashCodeMethod(ClassNode classNode, List<TupleSchemaRegistry.SQLFieldInfo> fieldList) throws JSONException {
MethodNode hashCodeNode = new MethodNode(Opcodes.ACC_PUBLIC, "hashCode", "()I", null, null);
hashCodeNode.visitAnnotation("Ljava/lang/Override;", true);
hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 7));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
for (TupleSchemaRegistry.SQLFieldInfo fieldInfo : fieldList) {
String fieldName = fieldInfo.getColumnName();
String fieldType = fieldInfo.getType().getJavaType().getName();
String fieldJavaType = getJavaType(fieldType);
hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 23));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
hashCodeNode.instructions.add(new InsnNode(Opcodes.IMUL));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
switch(fieldType) {
case "boolean":
LabelNode falseNode = new LabelNode();
LabelNode trueNode = new LabelNode();
hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.IFEQ, falseNode));
hashCodeNode.instructions.add(new IntInsnNode(Opcodes.SIPUSH, 1231));
hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, trueNode));
hashCodeNode.instructions.add(falseNode);
hashCodeNode.instructions.add(new IntInsnNode(Opcodes.SIPUSH, 1237));
hashCodeNode.instructions.add(trueNode);
break;
case "byte":
case "char":
case "short":
case "int":
break;
case "float":
hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "floatToIntBits", "(F)I", false));
break;
case "long":
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 32));
hashCodeNode.instructions.add(new InsnNode(Opcodes.LUSHR));
hashCodeNode.instructions.add(new InsnNode(Opcodes.LXOR));
hashCodeNode.instructions.add(new InsnNode(Opcodes.L2I));
break;
case "double":
hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "doubleToLongBits", "(D)J", false));
hashCodeNode.instructions.add(new InsnNode(Opcodes.DUP2));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.LSTORE, 2));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.LLOAD, 2));
hashCodeNode.instructions.add(new IntInsnNode(Opcodes.BIPUSH, 32));
hashCodeNode.instructions.add(new InsnNode(Opcodes.LUSHR));
hashCodeNode.instructions.add(new InsnNode(Opcodes.LXOR));
hashCodeNode.instructions.add(new InsnNode(Opcodes.L2I));
break;
default:
String objectOwnerType = fieldType.replace('.', '/');
LabelNode nullNode = new LabelNode();
LabelNode continueNode = new LabelNode();
hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.IFNULL, nullNode));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
hashCodeNode.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, fieldName, fieldJavaType));
hashCodeNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, objectOwnerType, "hashCode", "()I", false));
hashCodeNode.instructions.add(new JumpInsnNode(Opcodes.GOTO, continueNode));
hashCodeNode.instructions.add(nullNode);
hashCodeNode.instructions.add(new InsnNode(Opcodes.ICONST_0));
hashCodeNode.instructions.add(continueNode);
break;
}
hashCodeNode.instructions.add(new InsnNode(Opcodes.IADD));
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ISTORE, 1));
}
hashCodeNode.instructions.add(new VarInsnNode(Opcodes.ILOAD, 1));
hashCodeNode.instructions.add(new InsnNode(Opcodes.IRETURN));
classNode.methods.add(hashCodeNode);
}
use of org.apache.xbean.asm5.tree.ClassNode 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);
}
Aggregations