diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java index 9b72d5fcda8e503146c9dcc777e6eb67e01ece05..e2e2a83ad7f8a34ce2f1f159a859f04fe2c49529 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java @@ -1,6 +1,10 @@ package org.skywalking.apm.agent.core.plugin.match; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.description.type.TypeList; import net.bytebuddy.matcher.ElementMatcher; import static net.bytebuddy.matcher.ElementMatchers.hasSuperType; @@ -28,24 +32,54 @@ public class HierarchyMatch implements IndirectMatch { ElementMatcher.Junction junction = null; for (String superTypeName : parentTypes) { if (junction == null) { - junction = buildEachAnnotation(superTypeName); + junction = buildSuperClassMatcher(superTypeName); } else { - junction = junction.and(buildEachAnnotation(superTypeName)); + junction = junction.and(buildSuperClassMatcher(superTypeName)); } } junction = junction.and(not(isInterface())); return junction; } - private ElementMatcher.Junction buildEachAnnotation(String superTypeName) { + private ElementMatcher.Junction buildSuperClassMatcher(String superTypeName) { return hasSuperType(named(superTypeName)); } @Override public boolean isMatch(TypeDescription typeDescription) { + List parentTypes = new ArrayList(Arrays.asList(this.parentTypes)); + + TypeList.Generic implInterfaces = typeDescription.getInterfaces(); + for (TypeDescription.Generic implInterface : implInterfaces) { + matchHierarchyClass(implInterface, parentTypes); + } + + matchHierarchyClass(typeDescription.getSuperClass(), parentTypes); + + if (parentTypes.size() == 0) { + return true; + } + return false; } + private void matchHierarchyClass(TypeDescription.Generic clazz, List parentTypes) { + parentTypes.remove(clazz.getTypeName()); + if (parentTypes.size() == 0) { + return; + } + + for (TypeDescription.Generic generic : clazz.getInterfaces()) { + matchHierarchyClass(generic, parentTypes); + } + + TypeDescription.Generic superClazz = clazz.getSuperClass(); + if (superClazz != null && !clazz.getTypeName().equals("java.lang.Object")) { + matchHierarchyClass(superClazz, parentTypes); + } + + } + public static ClassMatch byHierarchyMatch(String[] parentTypes) { return new HierarchyMatch(parentTypes); }