com.newrelic.weave.utils.ClassInformation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of newrelic-weaver Show documentation
Show all versions of newrelic-weaver Show documentation
The Weaver of the Java agent.
/*
*
* * Copyright 2020 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
package com.newrelic.weave.utils;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* Information about a class, generally used during validation of weave packages.
*/
public class ClassInformation {
/**
* Create a {@link ClassInformation} for the specified class byte[]
* @param classBytes binary class representation
* @return {@link ClassInformation} for the specified class byte[]
*/
public static ClassInformation fromClassBytes(byte[] classBytes) {
if (classBytes == null) {
return null;
}
ClassInformationExtractor extractor = new ClassInformationExtractor();
new ClassReader(classBytes).accept(extractor, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES
| ClassReader.SKIP_DEBUG);
return extractor.result;
}
/**
* Create a {@link ClassInformation} for the specified ASM {@link ClassNode}
* @param classNode ASM {@link ClassNode} class representation
* @return {@link ClassInformation} for the specified {@link ClassNode}
*/
public static ClassInformation fromClassNode(ClassNode classNode) {
if (classNode == null) {
return null;
}
ClassInformationExtractor extractor = new ClassInformationExtractor();
classNode.accept(extractor);
return extractor.result;
}
/**
* {@link ClassVisitor} that extracts {@link ClassInformation}.
*/
private static final class ClassInformationExtractor extends ClassVisitor {
/**
* {@link ClassInformation} information about the class that was visited.
*/
final ClassInformation result = new ClassInformation();
public ClassInformationExtractor() {
super(WeaveUtils.ASM_API_LEVEL);
}
@Override
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
final CollectAnnotationsVisitor collectAnnotationsVisitor = new CollectAnnotationsVisitor(this.api);
return new AnnotationVisitor(this.api, collectAnnotationsVisitor) {
@Override
public void visitEnd() {
super.visitEnd();
AnnotationNode annotationNode = collectAnnotationsVisitor.getAnnotationNode();
if (annotationNode != null) {
annotationNode.desc = desc;
result.classAnnotationNodes.add(annotationNode);
result.classAnnotationNames.add(Type.getType(annotationNode.desc).getClassName());
}
}
};
}
public void visit(int version, int access, String name, String signature, String superName,
String[] interfaces) {
result.className = name;
if (null != superName) {
result.superName = superName;
}
if (null != interfaces) {
Collections.addAll(result.interfaceNames, interfaces);
}
}
public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
result.fields.add(new MemberInformation(name, desc, access));
return null;
}
public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature, String[] exceptions) {
MethodVisitor methodVisitor = super.visitMethod(access, desc, name, signature, exceptions);
return new MethodVisitor(this.api, methodVisitor) {
final Set annotations = new HashSet<>();
@Override
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
final CollectAnnotationsVisitor collectAnnotationsVisitor = new CollectAnnotationsVisitor(this.api);
return new AnnotationVisitor(this.api, collectAnnotationsVisitor) {
@Override
public void visitEnd() {
super.visitEnd();
AnnotationNode annotationNode = collectAnnotationsVisitor.getAnnotationNode();
if (annotationNode != null) {
annotationNode.desc = desc;
annotations.add(annotationNode);
result.methodAnnotationNames.add(Type.getType(annotationNode.desc).getClassName());
}
}
};
}
@Override
public void visitEnd() {
result.methods.add(new MemberInformation(name, desc, access, annotations));
}
};
}
}
static class CollectAnnotationsVisitor extends org.objectweb.asm.AnnotationVisitor {
final List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy