/*
* Copyright 2015 the original author or authors.
* @https://github.com/scouter-project/scouter
*
* 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 scouter.agent.asm.util;
import scouter.util.StrMatch;
import scouter.util.StringUtil;
import java.util.*;
import java.util.Map.Entry;
public class HookingSet {
public byte xType = 0;
public StrMatch classMatch = null;
protected Map<String,Object> inner = new HashMap<String,Object>();
private boolean all_flag = false;
private int all_flag_value;
public boolean isA(String method, String desc) {
if (all_flag)
return true;
else if (this.contains(method))
return true;
else if (this.contains(method + desc))
return true;
return false;
}
public boolean contains(String name) {
return inner.containsKey(name);
}
public void add(String mname) {
if ("*".equals(mname)) {
this.all_flag = true;
} else {
inner.put(mname, "");
}
}
public void add(String mname, int idx) {
if ("*".equals(mname)) {
this.all_flag = true;
this.all_flag_value = idx;
} else {
this.inner.put(mname, idx);
}
}
public int get(String method, String desc) {
if (all_flag)
return all_flag_value;
Integer i = (Integer) this.inner.get(method);
if (i != null) {
return i.intValue();
}
i = (Integer) this.inner.get(method);
if (i != null) {
return i.intValue();
}
return -1;
}
public static Map<String, HookingSet> getHookingSet(String arg) {
String[] c = StringUtil.split(arg, ',');
Map<String, HookingSet> classMap = new HashMap<String, HookingSet>();
for (int i = 0; i < c.length; i++) {
String s = c[i];
int x = s.lastIndexOf(".");
if (x <= 0)
continue;
String cname = s.substring(0, x).replace('.', '/');
String mname = s.substring(x + 1);
HookingSet methodSet = classMap.get(cname);
if (methodSet == null) {
methodSet = new HookingSet();
classMap.put(cname, methodSet);
}
methodSet.add(mname);
}
return classMap;
}
public static List<HookingSet> getHookingMethodSet(String patterns) {
String[] methodPatterns = StringUtil.split(patterns, ',');
Map<String, HookingSet> classMap = new HashMap<String, HookingSet>();
for (int i = 0; i < methodPatterns.length; i++) {
String pattern = methodPatterns[i];
int dotPos = pattern.lastIndexOf(".");
if (dotPos <= 0)
continue;
String cname = pattern.substring(0, dotPos).replace('.', '/').trim();
String mname = pattern.substring(dotPos + 1).trim();
HookingSet methodSet = classMap.get(cname);
if (methodSet == null) {
methodSet = new HookingSet();
classMap.put(cname, methodSet);
}
methodSet.add(mname);
}
List<HookingSet> list = new ArrayList<HookingSet>();
Iterator<Entry<String, HookingSet>> itr = classMap.entrySet().iterator();
while (itr.hasNext()) {
Entry<String, HookingSet> e = itr.next();
e.getValue().classMatch = new StrMatch(e.getKey());
list.add(e.getValue());
}
return list;
}
public static void setHookingMethod(Map<String, HookingSet> classSet, String cname, String mname) {
HookingSet methodSet = classSet.get(cname);
if (methodSet == null) {
methodSet = new HookingSet();
classSet.put(cname, methodSet);
}
methodSet.add(mname);
}
public static void add(List<HookingSet> list, String classname, String method) {
add(list, classname, method, (byte) 0);
}
public static void add(List<HookingSet> list, String classname, String method, byte serviceType) {
for (int i = 0; i < list.size(); i++) {
HookingSet m = list.get(i);
if (m.classMatch.include(classname)) {
m.add(method);
return;
}
}
HookingSet m = new HookingSet();
m.xType = serviceType;
m.classMatch = new StrMatch(classname);
m.add(method);
list.add(m);
}
public static HashSet<String> getHookingClassSet(String arg) {
String[] c = StringUtil.tokenizer(arg, ",");
HashSet<String> classSet = new HashSet<String>();
if(c ==null)
return classSet;
for (int i = 0; i < c.length; i++) {
classSet.add(c[i].replace('.', '/').trim());
}
return classSet;
}
public static Map<String, String> getClassFieldSet(String arg) {
String[] c = StringUtil.split(arg, ',');
Map<String, String> m = new HashMap<String, String>();
for (int i = 0; i < c.length; i++) {
String s = c[i];
int x = s.lastIndexOf(".");
if (x <= 0)
continue;
String cname = s.substring(0, x).replace('.', '/').trim();
String mname = s.substring(x + 1).trim();
m.put(cname, mname);
}
return m;
}
public static Set<String> getClassSet(String arg) {
String[] c = StringUtil.split(arg, ',');
Set<String> m = new HashSet<String>();
for (int i = 0; i < c.length; i++) {
String s = c[i];
m.add(s.replace('.', '/'));
}
return m;
}
public static String buildPatterns(String patterns, List<String> patternsList) {
for(int i=0; i<patternsList.size(); i++) {
if(StringUtil.isNotEmpty(StringUtil.trim(patterns))) {
patterns = patterns + "," + patternsList.get(i);
} else {
patterns = patternsList.get(i);
}
}
return patterns;
}
public static String classPattrensToMethodPatterns(String classPatterns, String method) {
String[] classes = StringUtil.split(classPatterns, ',');
List<String> classMethodPatterns = new ArrayList<String>();
for (int i = 0; i < classes.length; i++) {
String s = classes[i];
classMethodPatterns.add(s + "." + method);
}
return buildPatterns("", classMethodPatterns);
}
}