/* * Copyright 2014 NAVER Corp. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.navercorp.pinpoint.bootstrap.instrument; import java.util.Arrays; /** * @author Jongho Moon * */ public class MethodFilters { public static final int SYNTHETIC = 0x00001000; private MethodFilters() { } public static final MethodFilter ACCEPT_ALL = new MethodFilter() { @Override public boolean accept(InstrumentMethod method) { return ACCEPT; } }; public static MethodFilter name(String... names) { return new MethodNameFilter(null, names); } public static MethodFilter modifier(int required) { return modifier(required, 0); } public static MethodFilter modifierNot(int rejected) { return modifier(0, rejected); } public static MethodFilter modifier(int required, int rejected) { return new ModifierFilter(required, rejected); } public static MethodFilter argAt(int index, String type) { return new ArgAtFilter(index, type); } public static MethodFilter args(String... types) { return new ArgsFilter(types); } public static MethodFilter chain(MethodFilter... methodFilters) { return new ChaninFilter(methodFilters); } private static final class MethodNameFilter implements MethodFilter { private final String[] names; public MethodNameFilter(int[] rejectModifiers, String[] names) { this.names = names; } @Override public boolean accept(InstrumentMethod method) { if (names == null) { return REJECT; } for (String name : names) { if (name != null && name.equals(method.getName())) { return ACCEPT; } } return REJECT; } } private static final class ModifierFilter implements MethodFilter { private final int required; private final int rejected; public ModifierFilter(int required, int rejected) { this.required = required; this.rejected = rejected; } @Override public boolean accept(InstrumentMethod method) { int modifier = method.getModifiers(); return ((required & modifier) == required) && ((rejected & modifier) == 0); } } private static final class ArgAtFilter implements MethodFilter { private final int index; private final String type; public ArgAtFilter(int index, String type) { this.index = index; this.type = type; } @Override public boolean accept(InstrumentMethod method) { String[] paramTypes = method.getParameterTypes(); if (paramTypes.length < index + 1) { return REJECT; } return type != null && type.equals(paramTypes[index]); } } private static final class ArgsFilter implements MethodFilter { private final String[] types; public ArgsFilter(String[] types) { this.types = types; } @Override public boolean accept(InstrumentMethod method) { String[] paramTypes = method.getParameterTypes(); return Arrays.equals(paramTypes, types); } } private static final class ChaninFilter implements MethodFilter { private final MethodFilter[] methodFilters; public ChaninFilter(MethodFilter[] methodFilters) { this.methodFilters = methodFilters; } @Override public boolean accept(InstrumentMethod method) { if (methodFilters == null) { return REJECT; } for (MethodFilter methodFilter : methodFilters) { if (methodFilter == null || !methodFilter.accept(method)) { return REJECT; } } return ACCEPT; } } }