Search in sources :

Example 1 with ClassWriter

use of org.glassfish.hk2.external.org.objectweb.asm.ClassWriter in project Payara by payara.

the class BtraceClientGenerator method generateBtraceClientClassData.

public static byte[] generateBtraceClientClassData(int clientID, Collection<FlashlightProbe> probes) {
    // create a unique name.  It does not matter what the name is.
    String generatedClassName = "com/sun/btrace/flashlight/BTrace_Flashlight_" + clientID;
    // Start of writing a class using ASM, which will be our BTrace Client
    int cwFlags = ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS;
    ClassWriter cw = new ClassWriter(cwFlags);
    // Define the access identifiers for the BTrace Client class
    int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
    cw.visit(Opcodes.V1_5, access, generatedClassName, null, "java/lang/Object", null);
    // Need a @OnMethod annotation, so prepare your Annotation Visitor for that
    cw.visitAnnotation("Lcom/sun/btrace/annotations/BTrace;", true);
    // Iterate through the probes, so you will create one method for each probe
    int methodCounter = 0;
    for (FlashlightProbe probe : probes) {
        // Preparing the class method header and params (type) for @OnMethod annotation
        StringBuilder typeDesc = new StringBuilder("void ");
        StringBuilder methodDesc = new StringBuilder("void __");
        methodDesc.append(probe.getProviderJavaMethodName()).append("__");
        methodDesc.append(clientID).append("_").append(methodCounter).append("_");
        methodDesc.append("(");
        typeDesc.append("(");
        String delim = "";
        String typeDelim = "";
        Class[] paramTypes = probe.getParamTypes();
        for (int index = 0; index < paramTypes.length; index++) {
            Class paramType = paramTypes[index];
            methodDesc.append(delim).append(paramType.getName());
            // Dont add the param type for type desc, if self is the first index
            if (!(probe.hasSelf() && (index == 0))) {
                typeDesc.append(typeDelim).append(paramType.getName());
                typeDelim = ",";
            }
            delim = ", ";
        }
        methodDesc.append(")");
        typeDesc.append(")");
        // Creating the class method
        Method m = Method.getMethod(methodDesc.toString());
        GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, m, null, null, cw);
        // Add the @Self annotation
        if (probe.hasSelf()) {
            String[] paramNames = probe.getProbeParamNames();
            for (int index = 0; index < paramNames.length; index++) {
                if (paramNames[index].equalsIgnoreCase(FlashlightProbe.SELF)) {
                    AnnotationVisitor paramVisitor = gen.visitParameterAnnotation(index, "Lcom/sun/btrace/annotations/Self;", true);
                    paramVisitor.visitEnd();
                }
            }
        }
        // Add the @OnMethod annotation to this method
        AnnotationVisitor av = gen.visitAnnotation("Lcom/sun/btrace/annotations/OnMethod;", true);
        av.visit("clazz", "" + probe.getProviderClazz().getName());
        av.visit("method", probe.getProviderJavaMethodName());
        av.visit("type", typeDesc.toString());
        av.visitEnd();
        // Add the body
        gen.push(probe.getId());
        gen.loadArgArray();
        gen.invokeStatic(Type.getType(ProbeRegistry.class), Method.getMethod("void invokeProbe(int, Object[])"));
        gen.returnValue();
        gen.endMethod();
        methodCounter++;
    }
    BtraceClientGenerator.generateConstructor(cw);
    cw.visitEnd();
    byte[] classData = cw.toByteArray();
    writeClass(classData, generatedClassName);
    return classData;
}
Also used : FlashlightProbe(org.glassfish.flashlight.provider.FlashlightProbe) ProbeRegistry(org.glassfish.flashlight.provider.ProbeRegistry) Method(org.glassfish.hk2.external.org.objectweb.asm.commons.Method) ClassWriter(org.glassfish.hk2.external.org.objectweb.asm.ClassWriter) AnnotationVisitor(org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor) GeneratorAdapter(org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter)

Example 2 with ClassWriter

use of org.glassfish.hk2.external.org.objectweb.asm.ClassWriter in project Payara by payara.

the class ProviderImplGenerator method generateClassData.

public byte[] generateClassData(FlashlightProbeProvider provider, Class providerClazz, String generatedClassName) {
    Type classType = Type.getType(providerClazz);
    if (logger.isLoggable(Level.FINE)) {
        logger.fine("** classType: " + classType);
        logger.fine("** classDesc: " + Type.getDescriptor(providerClazz));
        logger.fine("Generating for: " + generatedClassName);
    }
    generatedClassName = generatedClassName.replace('.', '/');
    int cwFlags = ClassWriter.COMPUTE_FRAMES + ClassWriter.COMPUTE_MAXS;
    ClassWriter cw = new ClassWriter(cwFlags);
    int access = Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL;
    String[] interfaces = new String[] { providerClazz.getName().replace('.', '/') };
    cw.visit(Opcodes.V1_5, access, generatedClassName, null, "java/lang/Object", interfaces);
    for (FlashlightProbe probe : provider.getProbes()) {
        Type probeType = Type.getType(FlashlightProbe.class);
        int fieldAccess = Opcodes.ACC_PUBLIC;
        String fieldName = "_flashlight_" + probe.getProbeName();
        cw.visitField(fieldAccess, fieldName, probeType.getDescriptor(), null, null);
    }
    Type probeType = Type.getType(FlashlightProbe.class);
    for (FlashlightProbe probe : provider.getProbes()) {
        StringBuilder methodDesc = new StringBuilder();
        methodDesc.append("void ").append(probe.getProviderJavaMethodName());
        methodDesc.append("(");
        String delim = "";
        for (Class paramType : probe.getParamTypes()) {
            methodDesc.append(delim).append(paramType.getName());
            delim = ", ";
        }
        methodDesc.append(")");
        Method m = Method.getMethod(methodDesc.toString());
        GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw);
        String fieldName = "_flashlight_" + probe.getProbeName();
        gen.loadThis();
        gen.visitFieldInsn(Opcodes.GETFIELD, generatedClassName, fieldName, probeType.getDescriptor());
        int index = gen.newLocal(probeType);
        gen.storeLocal(index);
        gen.loadLocal(index);
        gen.invokeVirtual(probeType, Method.getMethod("boolean isEnabled()"));
        gen.push(true);
        Label enabledLabel = new Label();
        Label notEnabledLabel = new Label();
        gen.ifCmp(Type.getType(boolean.class), GeneratorAdapter.EQ, enabledLabel);
        gen.goTo(notEnabledLabel);
        gen.visitLabel(enabledLabel);
        gen.loadLocal(index);
        gen.loadArgArray();
        gen.invokeVirtual(probeType, Method.getMethod("void fireProbe(Object[])"));
        gen.visitLabel(notEnabledLabel);
        gen.returnValue();
        gen.endMethod();
    }
    generateConstructor(cw, generatedClassName, provider);
    cw.visitEnd();
    byte[] classData = cw.toByteArray();
    int index = generatedClassName.lastIndexOf('.');
    String clsName = generatedClassName.substring(index + 1);
    if (Boolean.parseBoolean(System.getenv("AS_DEBUG"))) {
        if (logger.isLoggable(Level.FINE))
            logger.fine("Generated ClassDATA " + clsName);
        // the path is horribly long.  Let's just write t directly into the
        // lib dir.  It is not for loading as a class but just for us humans
        // to decompile to figure out what is going on.  No need to make it even harder!
        clsName = clsName.replace('.', '/');
        // just in case Windows?  unlikely...
        clsName = clsName.replace('\\', '/');
        index = clsName.lastIndexOf("/");
        if (index >= 0)
            clsName = clsName.substring(index + 1);
        FileOutputStream fos = null;
        try {
            String rootPath = System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY) + File.separator + "lib" + File.separator;
            String fileName = rootPath + clsName + ".class";
            if (logger.isLoggable(Level.FINE))
                logger.fine("ClassFile: " + fileName);
            File file = new File(fileName);
            if (FileUtils.mkdirsMaybe(file.getParentFile())) {
                fos = new FileOutputStream(file);
                fos.write(classData);
                fos.flush();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                if (fos != null)
                    fos.close();
            } catch (Exception e) {
            // nothing can be done...
            }
        }
    }
    return classData;
}
Also used : FlashlightProbe(org.glassfish.flashlight.provider.FlashlightProbe) Label(org.glassfish.hk2.external.org.objectweb.asm.Label) Method(org.glassfish.hk2.external.org.objectweb.asm.commons.Method) ClassWriter(org.glassfish.hk2.external.org.objectweb.asm.ClassWriter) PrivilegedActionException(java.security.PrivilegedActionException) InvocationTargetException(java.lang.reflect.InvocationTargetException) Type(org.glassfish.hk2.external.org.objectweb.asm.Type) FileOutputStream(java.io.FileOutputStream) GeneratorAdapter(org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter) File(java.io.File)

Example 3 with ClassWriter

use of org.glassfish.hk2.external.org.objectweb.asm.ClassWriter in project Payara by payara.

the class CompositeUtil method createConstructor.

/**
 * This method creates the default constructor for the class. Default values are set for any @Attribute defined with
 * a defaultValue.
 */
private void createConstructor(ClassWriter cw, String className, Map<String, Map<String, Object>> properties) {
    MethodVisitor method = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    method.visitCode();
    method.visitVarInsn(ALOAD, 0);
    method.visitMethodInsn(INVOKESPECIAL, "org/glassfish/admin/rest/composite/RestModelImpl", "<init>", "()V");
    for (Map.Entry<String, Map<String, Object>> property : properties.entrySet()) {
        String fieldName = property.getKey();
        String defaultValue = (String) property.getValue().get("defaultValue");
        if (defaultValue != null && !defaultValue.isEmpty()) {
            setDefaultValue(method, className, fieldName, (Class<?>) property.getValue().get("type"), defaultValue);
        }
    }
    method.visitInsn(RETURN);
    method.visitMaxs(1, 1);
    method.visitEnd();
}
Also used : JsonString(javax.json.JsonString) Map(java.util.Map) ParameterMap(org.glassfish.api.admin.ParameterMap) HashMap(java.util.HashMap) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) MethodVisitor(org.glassfish.hk2.external.org.objectweb.asm.MethodVisitor)

Example 4 with ClassWriter

use of org.glassfish.hk2.external.org.objectweb.asm.ClassWriter in project Payara by payara.

the class CompositeUtil method getModel.

/**
 * This method will return a generated concrete class that implements the interface requested, as well as any
 * interfaces intended to extend the base model interface.  Model extensions must be annotated with
 *
 * @param modelIface   The base interface for the desired data model
 * @return An instance of a concrete class implementing the requested interfaces
 * @throws Exception
 * @RestModelExtension, and must be compiled with rest-annotation-processor library on the compile classpath
 * for metadata generation.
 */
public synchronized <T> T getModel(Class<T> modelIface) {
    String className = modelIface.getName() + "Impl";
    if (!generatedClasses.containsKey(className)) {
        Map<String, Map<String, Object>> properties = new HashMap<String, Map<String, Object>>();
        Set<Class<?>> interfaces = getModelExtensions(modelIface);
        interfaces.add(modelIface);
        for (Class<?> iface : interfaces) {
            analyzeInterface(iface, properties);
        }
        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        visitClass(classWriter, className, interfaces, properties);
        for (Map.Entry<String, Map<String, Object>> entry : properties.entrySet()) {
            String name = entry.getKey();
            final Map<String, Object> property = entry.getValue();
            Class<?> type = (Class<?>) property.get("type");
            createField(classWriter, name, type);
            createGettersAndSetters(classWriter, modelIface, className, name, property);
        }
        createConstructor(classWriter, className, properties);
        classWriter.visitEnd();
        Class<?> newClass;
        try {
            newClass = defineClass(modelIface, className, classWriter.toByteArray());
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        generatedClasses.put(className, newClass);
    }
    try {
        return (T) generatedClasses.get(className).newInstance();
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}
Also used : HashMap(java.util.HashMap) JsonString(javax.json.JsonString) ClassWriter(org.glassfish.hk2.external.org.objectweb.asm.ClassWriter) JsonException(javax.json.JsonException) WebApplicationException(javax.ws.rs.WebApplicationException) IOException(java.io.IOException) JsonObject(javax.json.JsonObject) Map(java.util.Map) ParameterMap(org.glassfish.api.admin.ParameterMap) HashMap(java.util.HashMap) MultivaluedMap(javax.ws.rs.core.MultivaluedMap)

Example 5 with ClassWriter

use of org.glassfish.hk2.external.org.objectweb.asm.ClassWriter in project Payara by payara.

the class BtraceClientGenerator method generateConstructor.

private static void generateConstructor(ClassWriter cw) {
    Method m = Method.getMethod("void <init> ()");
    GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, m, null, null, cw);
    gen.loadThis();
    gen.invokeConstructor(Type.getType(Object.class), m);
    // return the value from constructor
    gen.returnValue();
    gen.endMethod();
}
Also used : GeneratorAdapter(org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter) Method(org.glassfish.hk2.external.org.objectweb.asm.commons.Method)

Aggregations

JsonString (javax.json.JsonString)5 GeneratorAdapter (org.glassfish.hk2.external.org.objectweb.asm.commons.GeneratorAdapter)4 Method (org.glassfish.hk2.external.org.objectweb.asm.commons.Method)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 MultivaluedMap (javax.ws.rs.core.MultivaluedMap)3 ParameterMap (org.glassfish.api.admin.ParameterMap)3 FlashlightProbe (org.glassfish.flashlight.provider.FlashlightProbe)3 AnnotationVisitor (org.glassfish.hk2.external.org.objectweb.asm.AnnotationVisitor)3 ClassWriter (org.glassfish.hk2.external.org.objectweb.asm.ClassWriter)3 JsonObject (javax.json.JsonObject)2 MethodVisitor (org.glassfish.hk2.external.org.objectweb.asm.MethodVisitor)2 Type (org.glassfish.hk2.external.org.objectweb.asm.Type)2 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 PrivilegedActionException (java.security.PrivilegedActionException)1 JsonException (javax.json.JsonException)1 WebApplicationException (javax.ws.rs.WebApplicationException)1