use of com.newrelic.weave.ClassWeave in project newrelic-java-agent by newrelic.
the class PackageValidationResult method getAnnotationMatchComposite.
private ClassNode getAnnotationMatchComposite(ClassNode targetNode, ClassNode weaveNode, ClassNode composite, Map<String, List<Method>> weavedMethods, ClassCache cache, Map<String, byte[]> annotationProxyClasses, Map<Method, Collection<String>> skipMethods) {
try {
boolean isInterfaceMatch = WeaveUtils.isWeaveWithAnnotationInterfaceMatch(weaveNode);
Map<String, PreparedMatch> results = new HashMap<>();
buildResults(cache, targetNode, weaveNode.name, weaveNode, results, isInterfaceMatch, weavePackage.getRequiredAnnotationClassesForAnnotationWeave(weaveNode.name), weavePackage.getRequiredAnnotationClassesForMethodAnnotationWeave(weaveNode.name), errorHandler, annotationProxyClasses);
if (!violations.isEmpty()) {
return composite;
}
for (Map.Entry<String, PreparedMatch> result : results.entrySet()) {
PreparedMatch prepared = result.getValue();
if (prepared != null) {
ClassWeave classWeave = ClassWeave.weave(prepared, composite, weavePackage, skipMethods);
composite = classWeave.getComposite();
// Key is only used for logging at the moment.
final String key = prepared.getWeaveName();
if (weavedMethods.containsKey(key)) {
weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
} else {
weavedMethods.put(key, classWeave.getWeavedMethods());
}
}
}
} catch (Exception ignored) {
}
return composite;
}
use of com.newrelic.weave.ClassWeave in project newrelic-java-agent by newrelic.
the class PackageValidationResult method weave.
/**
* Weave the target class and return a {@link PackageWeaveResult}.
*/
public PackageWeaveResult weave(String className, String[] superNames, String[] interfaceNames, ClassNode targetNode, ClassCache cache, Map<Method, Collection<String>> skipMethods) {
ClassNode composite = targetNode;
final Map<String, List<Method>> weavedMethods = new HashMap<>();
// Locks during weaving are due to the non-thread safe nature of {@link ClassNode}.
// first apply exact matches
{
PreparedMatch exactMatch = exactMatches.get(className);
if (null != exactMatch) {
ClassWeave classWeave;
classWeave = ClassWeave.weave(exactMatch, composite, weavePackage, skipMethods);
composite = classWeave.getComposite();
final String key = exactMatch.getOriginalName();
if (weavedMethods.containsKey(key)) {
weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
} else {
weavedMethods.put(key, classWeave.getWeavedMethods());
}
}
}
{
// matcher for abstract class
PreparedMatch exactMatch = baseMatches.get(className);
if (null != exactMatch) {
ClassWeave classWeave;
classWeave = ClassWeave.weave(exactMatch, composite, weavePackage, skipMethods);
composite = classWeave.getComposite();
final String key = exactMatch.getOriginalName();
if (weavedMethods.containsKey(key)) {
weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
} else {
weavedMethods.put(key, classWeave.getWeavedMethods());
}
}
}
// then apply super classes
for (int i = 0; i < superNames.length; ++i) {
PreparedMatch baseMatch = baseMatches.get(superNames[i]);
if (null != baseMatch) {
ClassWeave classWeave;
classWeave = ClassWeave.weave(baseMatch, composite, weavePackage, skipMethods);
composite = classWeave.getComposite();
final String key = baseMatch.getOriginalName();
if (weavedMethods.containsKey(key)) {
weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
} else {
weavedMethods.put(key, classWeave.getWeavedMethods());
}
}
}
// then apply interfaces
for (int i = 0; i < interfaceNames.length; ++i) {
PreparedMatch baseMatch = baseMatches.get(interfaceNames[i]);
if (null != baseMatch) {
ClassWeave classWeave;
classWeave = ClassWeave.weave(baseMatch, composite, weavePackage, skipMethods);
composite = classWeave.getComposite();
final String key = baseMatch.getOriginalName();
if (weavedMethods.containsKey(key)) {
weavedMethods.get(key).addAll(classWeave.getWeavedMethods());
} else {
weavedMethods.put(key, classWeave.getWeavedMethods());
}
}
}
final Map<String, byte[]> annotationProxyClasses = new HashMap<>();
// class annotation matches
if (!allAnnotationClasses.isEmpty()) {
Set<String> targetAnnotationsClasses = getAnnotationClasses(targetNode);
Set<String> targetInterfacesAnnotationClasses = Collections.emptySet();
if (!baseAnnotationClasses.isEmpty()) {
targetInterfacesAnnotationClasses = getAllInterfaceAnnotationClasses(targetNode, cache);
}
// check for exact annotation matches
for (Map.Entry<String, ClassNode> entry : allAnnotationClasses.entrySet()) {
if (targetAnnotationsClasses.contains(entry.getKey())) {
composite = getAnnotationMatchComposite(targetNode, entry.getValue(), composite, weavedMethods, cache, annotationProxyClasses, skipMethods);
}
}
// check for base annotation matches
for (Map.Entry<String, ClassNode> entry : baseAnnotationClasses.entrySet()) {
if (targetInterfacesAnnotationClasses.contains(entry.getKey())) {
composite = getAnnotationMatchComposite(targetNode, entry.getValue(), composite, weavedMethods, cache, annotationProxyClasses, skipMethods);
}
}
}
// method annotation matches
if (!allMethodAnnotationClasses.isEmpty()) {
Set<String> targetMethodAnnotationsClasses = getMethodAnnotationClasses(targetNode);
for (Map.Entry<String, ClassNode> entry : allMethodAnnotationClasses.entrySet()) {
if (targetMethodAnnotationsClasses.contains(entry.getKey())) {
composite = getAnnotationMatchComposite(targetNode, entry.getValue(), composite, weavedMethods, cache, annotationProxyClasses, skipMethods);
// due to having multiple matching annotations that have the same underlying weave code.
break;
}
}
}
if (weavePackage != null) {
// Run any postprocessors that were passed in. It's important that we do this before the inliner runs below
ClassNode result = new SynchronizedClassNode(WeaveUtils.ASM_API_LEVEL);
ClassVisitor postprocessChain = weavePackage.getConfig().getPostprocessor().postprocess(className, result, Collections.<String>emptySet(), weavePackage, false);
composite.accept(postprocessChain);
composite = result;
}
return new PackageWeaveResult(this, className, composite, weavedMethods, annotationProxyClasses);
}
Aggregations