package immibis.bon;
import java.util.*;
public class Mapping {
private Map<String, String> classes = new HashMap<String, String>();
private Map<String, String> methods = new HashMap<String, String>();
private Map<String, String> fields = new HashMap<String, String>();
private Map<String, List<String>> exceptions = new HashMap<String, List<String>>();
private Map<String, String> classPrefixes = new HashMap<String, String>();
private String defaultPackage = "";
public final NameSet fromNS, toNS;
public Mapping(NameSet fromNS, NameSet toNS) {
this.fromNS = fromNS;
this.toNS = toNS;
}
public void setClass(String in, String out) {
classes.put(in, out);
}
public void setMethod(String clazz, String name, String desc, String out) {
methods.put(clazz + "/" + name + desc, out);
}
public void setField(String clazz, String name, String out) {
fields.put(clazz + "/" + name, out);
}
public void setExceptions(String clazz, String method, String desc, List<String> exc) {
exceptions.put(clazz + "/" + method + desc, exc);
}
public String getClass(String in) {
if(in == null)
return null;
if(in.startsWith("[L") && in.endsWith(";"))
return "[L" + getClass(in.substring(2, in.length() - 1)) + ";";
if(in.startsWith("["))
return "[" + getClass(in.substring(1));
if(in.equals("B") || in.equals("C") || in.equals("D") || in.equals("F") || in.equals("I") || in.equals("J") || in.equals("S") || in.equals("Z"))
return in;
String ret = classes.get(in);
if(ret != null)
return ret;
for(Map.Entry<String, String> e : classPrefixes.entrySet())
if(in.startsWith(e.getKey()))
return e.getValue() + in.substring(e.getKey().length());
if(!in.contains("/"))
return defaultPackage + in;
return in;
}
public String getMethod(String clazz, String name, String desc) {
String ret = methods.get(clazz + "/" + name + desc);
return ret == null ? name : ret;
}
public String getField(String clazz, String name) {
String ret = fields.get(clazz + "/" + name);
return ret == null ? name : ret;
}
public List<String> getExceptions(String clazz, String method, String desc) {
List<String> ret = exceptions.get(clazz + "/" + method + desc);
return ret == null ? Collections.<String>emptyList() : ret;
}
public void addPrefix(String old, String new_) {
classPrefixes.put(old, new_);
}
// p must include trailing slash
public void setDefaultPackage(String p) {
defaultPackage = p;
}
public String mapMethodDescriptor(String desc) {
// some basic sanity checks, doesn't ensure it's completely valid though
if(desc.length() == 0 || desc.charAt(0) != '(' || desc.indexOf(")") < 1)
throw new IllegalArgumentException("Not a valid method descriptor: " + desc);
int pos = 0;
String out = "";
while(pos < desc.length())
{
switch(desc.charAt(pos))
{
case 'V': case 'Z': case 'B': case 'C':
case 'S': case 'I': case 'J': case 'F':
case 'D': case '[': case '(': case ')':
out += desc.charAt(pos);
pos++;
break;
case 'L':
{
int end = desc.indexOf(';', pos);
String obf = desc.substring(pos + 1, end);
pos = end + 1;
out += "L" + getClass(obf) + ";";
}
break;
default:
throw new RuntimeException("Unknown method descriptor character: " + desc.charAt(pos) + " (in " + desc + ")");
}
}
return out;
}
public String mapTypeDescriptor(String in) {
if(in.startsWith("["))
return "[" + mapTypeDescriptor(in.substring(1));
if(in.startsWith("L") && in.endsWith(";"))
return "L" + getClass(in.substring(1, in.length() - 1)) + ";";
return in;
}
}