Created
November 10, 2012 00:12
-
-
Save LB--/4049179 to your computer and use it in GitHub Desktop.
Java Reflection Interactive
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.lang.reflect.*; | |
public class LiveScript | |
{ | |
private LiveScript() throws UnsupportedOperationException | |
{ | |
throw new UnsupportedOperationException(); | |
} | |
public static void main(String[] args_unused) | |
{ | |
Scanner in = new Scanner(System.in); | |
HashMap<String, Object> objs = new HashMap<String, Object>(); | |
objs.put("null", null); | |
CommandLoop: | |
for(;;) try | |
{ | |
System.out.print(">"); | |
String s = in.next(); | |
Scanner ln = new Scanner(in.nextLine()); | |
if(s.equals("Exit")) break; | |
else if(s.equalsIgnoreCase("Help") || s.equals("?")) | |
{ | |
System.out.println("Exit - exit this program"); | |
System.out.println("Set a b - sets a to the same as b"); | |
System.out.println("New class name constructor_args... - create a new object and assign it to name"); | |
System.out.println("Call name class method args... - invoke a method on name (or class if name is null)"); | |
System.out.println("Invoke a b class method args... - invoke a method on b (or class if name is null) and assign it to a"); | |
System.out.println("Use #name in argument lists to use name as its primitive type"); | |
} | |
else if(s.equals("Set")) | |
{ | |
String a = ln.next(); | |
if(!objs.containsKey(a)) | |
{ | |
System.out.println("No such object: "+a); | |
continue CommandLoop; | |
} | |
else if(a.equals("null")) | |
{ | |
System.out.println("Cannot assign to null"); | |
continue CommandLoop; | |
} | |
String b = ln.next(); | |
if(!objs.containsKey(b)) | |
{ | |
System.out.println("No such object: "+b); | |
continue CommandLoop; | |
} | |
objs.put(a, a.getClass().cast(objs.get(b))); | |
} | |
else if(s.equals("New")) | |
{ | |
String clazz = ln.next(); | |
Class c = Class.forName(clazz); | |
String name = ln.next(); | |
if(name.equals("null")) | |
{ | |
System.out.println("Cannot assign to null"); | |
continue CommandLoop; | |
} | |
String[] args = new String[0]; | |
if(ln.hasNext()) | |
{ | |
args = ParseArgs(ln.nextLine().substring(1)); | |
} | |
Class[] types = ParseClasses(args, objs); | |
Constructor ctor = c.getDeclaredConstructor(types); | |
Object[] params = ParseParams(args, objs); | |
objs.put(name, ctor.newInstance(params)); | |
} | |
else if(s.equals("Call")) | |
{ | |
String name = ln.next(); | |
if(!objs.containsKey(name)) | |
{ | |
System.out.println("No such object: "+name); | |
continue CommandLoop; | |
} | |
Class c = Class.forName(ln.next()); | |
String method = ln.next(); | |
String[] args = new String[0]; | |
if(ln.hasNext()) | |
{ | |
args = ParseArgs(ln.nextLine().substring(1)); | |
} | |
Class[] types = ParseClasses(args, objs); | |
Method m = c.getDeclaredMethod(method, types); | |
Object[] params = ParseParams(args, objs); | |
Object o = m.invoke(objs.get(name), params); | |
if(m.getReturnType().equals(Void.TYPE)) | |
{ | |
System.out.println("Returned"); | |
} | |
else if(o == null) | |
{ | |
System.out.println("Returned null reference to "+m.getReturnType()); | |
} | |
else | |
{ | |
System.out.println("Returned "+m.getReturnType()+": \""+o+"\""); | |
} | |
} | |
else if(s.equals("Invoke")) | |
{ | |
String a = ln.next(); | |
if(a.equals("null")) | |
{ | |
System.out.println("Cannot assign to null"); | |
continue CommandLoop; | |
} | |
String name = ln.next(); | |
if(!objs.containsKey(name)) | |
{ | |
System.out.println("No such object: "+name); | |
continue CommandLoop; | |
} | |
Class c = Class.forName(ln.next()); | |
String method = ln.next(); | |
String[] args = new String[0]; | |
if(ln.hasNext()) | |
{ | |
args = ParseArgs(ln.nextLine().substring(1)); | |
} | |
Class[] types = ParseClasses(args, objs); | |
Method m = c.getDeclaredMethod(method, types); | |
if(m.getReturnType().equals(Void.TYPE)) | |
{ | |
System.out.println("Cannot assign void"); | |
continue CommandLoop; | |
} | |
Object[] params = ParseParams(args, objs); | |
Object o = m.invoke(objs.get(name), params); | |
objs.put(a, o); | |
} | |
else | |
{ | |
System.out.println("Unkown Command, use Help or ? for help"); | |
} | |
} | |
catch(NoSuchObjectException e){} | |
catch(NotConvertibleToPrimitiveException e){} | |
catch(Throwable t){ t.printStackTrace(); } | |
} | |
static class NoSuchObjectException extends Exception {} | |
static class NotConvertibleToPrimitiveException extends Exception {} | |
static String[] ParseArgs(String line) | |
{ | |
ArrayList<String> arr = new ArrayList<String>(); | |
String tok = ""; | |
boolean inq = false; | |
for(char c : (line+' ').toCharArray()) | |
{ | |
if(c == '"') | |
{ | |
if(inq) | |
{ | |
arr.add(' '+tok); | |
tok = ""; | |
} | |
inq = !inq; | |
} | |
else if(c == ' ' && !inq) | |
{ | |
if(!tok.equals("")) | |
{ | |
arr.add(tok); | |
tok = ""; | |
} | |
} | |
else | |
{ | |
tok += c; | |
} | |
} | |
return (String[])arr.toArray(new String[0]); | |
} | |
static HashMap<Class, Class> primitives = new HashMap<Class, Class>(); | |
static | |
{ | |
primitives.put(Boolean.class, Boolean.TYPE); | |
primitives.put(Byte.class, Byte.TYPE); | |
primitives.put(Short.class, Short.TYPE); | |
primitives.put(Character.class, Character.TYPE); | |
primitives.put(Integer.class, Integer.TYPE); | |
primitives.put(Long.class, Long.TYPE); | |
primitives.put(Float.class, Float.TYPE); | |
primitives.put(Double.class, Double.TYPE); | |
} | |
static Class[] ParseClasses(String[] args, HashMap<String, Object> objs) throws NoSuchObjectException, NotConvertibleToPrimitiveException | |
{ | |
Class[] types = new Class[args.length]; | |
for(int i = 0; i < args.length; ++i) | |
{ | |
if(args[i].charAt(0) == ' ') | |
{ | |
types[i] = String.class; | |
} | |
else if(args[i].charAt(0) == '#') | |
{ | |
String name = args[i].substring(1); | |
if(!objs.containsKey(name)) | |
{ | |
System.out.println("No such object: "+args[i]); | |
throw new NoSuchObjectException(); | |
} | |
else if(!primitives.containsKey(objs.get(name).getClass())) | |
{ | |
System.out.println("Not convertible to primitive: "+name); | |
throw new NotConvertibleToPrimitiveException(); | |
} | |
types[i] = primitives.get(objs.get(name).getClass()); | |
args[i] = name; | |
} | |
else if(!objs.containsKey(args[i])) | |
{ | |
System.out.println("No such object: "+args[i]); | |
throw new NoSuchObjectException(); | |
} | |
else | |
{ | |
types[i] = objs.get(args[i]).getClass(); | |
} | |
} | |
return types; | |
} | |
static Object[] ParseParams(String[] args, HashMap<String, Object> objs) | |
{ | |
Object[] params = new Object[args.length]; | |
for(int i = 0; i < args.length; ++i) | |
{ | |
if(args[i].charAt(0) == ' ') | |
{ | |
params[i] = args[i].substring(1); | |
} | |
else | |
{ | |
params[i] = objs.get(args[i]); | |
} | |
} | |
return params; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment