use of com.shulie.instrument.simulator.api.filter.MethodDescriptor in project LinkAgent by shulieTech.
the class TraceListener method addNextLevelTrace.
/**
* 添加下一级的 trace
*
* @param traceNode
*/
private void addNextLevelTrace(final TraceNode traceNode) {
if (traceNode != null && level > 0 && traceMethods.add(traceNode.getClassName() + "." + traceNode.getMethodName()) && !traceNode.isSkip(stopInMills)) {
/**
* 如果是接口则找出所有的实现类并增强
*/
if (traceNode.isInterface()) {
Set<Class<?>> classes = loadedClassDataSource.find(new ExtFilter() {
@Override
public boolean isIncludeSubClasses() {
return false;
}
@Override
public boolean isIncludeBootstrap() {
return true;
}
@Override
public boolean doClassNameFilter(String javaClassName) {
return true;
}
@Override
public boolean doClassFilter(ClassDescriptor classDescriptor) {
String[] interfaces = classDescriptor.getInterfaceTypeJavaClassNameArray();
return ArrayUtils.contains(interfaces, traceNode.getClassName());
}
@Override
public List<BuildingForListeners> doMethodFilter(MethodDescriptor methodDescriptor) {
return Collections.EMPTY_LIST;
}
@Override
public List<BuildingForListeners> getAllListeners() {
return Collections.EMPTY_LIST;
}
});
if (CollectionUtils.isNotEmpty(classes)) {
/**
* 增强所有接口的实现类
*/
for (Class clazz : classes) {
if (Proxy.isProxyClass(clazz)) {
Class[] interfaces = clazz.getInterfaces();
if (ArrayUtils.isNotEmpty(interfaces)) {
for (final Class interfaceClass : interfaces) {
Set<Class<?>> implClasses = loadedClassDataSource.find(new ExtFilter() {
@Override
public boolean isIncludeSubClasses() {
return false;
}
@Override
public boolean isIncludeBootstrap() {
return true;
}
@Override
public boolean doClassNameFilter(String javaClassName) {
return true;
}
@Override
public boolean doClassFilter(ClassDescriptor classDescriptor) {
String[] interfaces = classDescriptor.getInterfaceTypeJavaClassNameArray();
return ArrayUtils.contains(interfaces, interfaceClass.getName());
}
@Override
public List<BuildingForListeners> doMethodFilter(MethodDescriptor methodDescriptor) {
return Collections.EMPTY_LIST;
}
@Override
public List<BuildingForListeners> getAllListeners() {
return Collections.EMPTY_LIST;
}
});
for (Class implClass : implClasses) {
final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(implClass.getName()).includeSubClasses().onBehavior(traceNode.getMethodName()).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { false, latch, traceViews, traceMethods, eventWatchers, condition, express, level - 1, limits, stopInMills })).onClass().onWatch();
eventWatchers.add(watcher);
}
}
}
} else {
final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(clazz.getName()).includeSubClasses().onBehavior(traceNode.getMethodName()).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { false, latch, traceViews, traceMethods, eventWatchers, condition, express, level - 1, limits, stopInMills })).onClass().onWatch();
eventWatchers.add(watcher);
}
}
}
} else {
final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(traceNode.getClassName()).includeSubClasses().onBehavior(traceNode.getMethodName()).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { false, latch, traceViews, traceMethods, eventWatchers, condition, express, level - 1, limits, stopInMills })).onClass().onWatch();
eventWatchers.add(watcher);
}
}
}
use of com.shulie.instrument.simulator.api.filter.MethodDescriptor in project LinkAgent by shulieTech.
the class ClassMatchBuilder method toEventWatchCondition.
private EventWatchCondition toEventWatchCondition() {
final List<Filter> filters = new ArrayList<Filter>();
final Filter filter = new ExtFilter() {
@Override
public boolean isIncludeSubClasses() {
return isIncludeSubClasses;
}
@Override
public boolean isIncludeBootstrap() {
return isIncludeBootstrap;
}
@Override
public boolean doClassNameFilter(String javaClassName) {
return patternMatching(javaClassName, pattern, patternType);
}
@Override
public boolean doClassFilter(ClassDescriptor classDescriptor) {
if ((classDescriptor.getAccess() & getWithAccess()) != getWithAccess()) {
return false;
}
if (!patternMatching(classDescriptor.getClassName(), pattern, patternType)) {
return false;
}
if (!patternMatching(classDescriptor.getSuperClassTypeJavaClassName(), superPatterns, patternType)) {
return false;
}
if (getHasInterfaceTypes().isNotEmpty()) {
if (!getHasInterfaceTypes().patternWith(classDescriptor.getInterfaceTypeJavaClassNameArray())) {
return false;
}
}
if (getHasAnnotationTypes().isNotEmpty()) {
if (!getHasAnnotationTypes().patternWith(classDescriptor.getAnnotationTypeJavaClassNameArray())) {
return false;
}
}
return true;
}
@Override
public List<BuildingForListeners> doMethodFilter(MethodDescriptor methodDescriptor) {
// nothing to matching
if (bfBehaviors.isEmpty()) {
return Collections.EMPTY_LIST;
}
List<BuildingForListeners> list = new ArrayList<BuildingForListeners>();
// matching any behavior
for (final BehaviorMatchBuilder bfBehavior : bfBehaviors) {
final boolean matches = matches(methodDescriptor, bfBehavior);
if ((bfBehavior.isWithNot() && matches) || (!bfBehavior.isWithNot() && !matches)) {
continue;
}
list.addAll(bfBehavior.getListeners());
}
// non matched
return list;
}
private boolean matches(MethodDescriptor methodDescriptor, BehaviorMatchBuilder bfBehavior) {
if ((methodDescriptor.getAccess() & bfBehavior.getWithAccess()) != bfBehavior.getWithAccess()) {
return false;
}
if (!patternMatching(methodDescriptor.getMethodName(), bfBehavior.getPattern(), patternType)) {
return false;
}
if (!bfBehavior.getWithParameterTypes().matching(methodDescriptor.getParameterTypeJavaClassNameArray())) {
return false;
}
if (bfBehavior.getHasExceptionTypes().isNotEmpty()) {
if (!bfBehavior.getHasExceptionTypes().patternWith(methodDescriptor.getThrowsTypeJavaClassNameArray())) {
return false;
}
}
if (bfBehavior.getHasAnnotationTypes().isNotEmpty()) {
if (!bfBehavior.getHasAnnotationTypes().patternWith(methodDescriptor.getAnnotationTypeJavaClassNameArray())) {
return false;
}
}
return true;
}
@Override
public List<BuildingForListeners> getAllListeners() {
List<BuildingForListeners> listeners = new ArrayList<BuildingForListeners>();
for (BehaviorMatchBuilder buildingForBehavior : bfBehaviors) {
listeners.addAll(buildingForBehavior.getListeners());
}
return listeners;
}
};
// filter
filters.add(filter);
return new EventWatchCondition() {
@Override
public Filter[] getOrFilterArray() {
return filters.toArray(new Filter[0]);
}
};
}
Aggregations