reflector.java
来自「Hecl编程语言是一个高层次的脚本语言的Java实现。其用意是要小」· Java 代码 · 共 619 行 · 第 1/2 页
JAVA
619 行
selected.getName() + " with arguments: "; for (Thing t : argv) { msg += t.toString() + " "; } msg += " (Translated to:) "; for (Object eo : args) { msg += eo.toString() + " "; } msg += " " + e.getTargetException().toString(); throw new HeclException(msg); } catch (Exception e) { throw new HeclException("Reflector evaluate error :" + e.toString()); } } /** * The <code>mapParams</code> method is where a series of Hecl * types/values are mapped onto Java types/values. * * @param retval an <code>Object</code> value * @param outparams a <code>Class</code> value * @param argv a <code>Thing</code> value * @param offset an <code>int</code> value - where to start * looking in argv. * @return an <code>Object[]</code> value * @exception HeclException if an error occurs */ protected boolean mapParams(Object[] retval, Class[] outparams, Thing[] argv, int offset) throws HeclException { if(outparams.length != argv.length - offset) { return false; } boolean matched = true; Object[] outobjs = new Object[outparams.length]; Class c = null; for (int i = 0; i < outparams.length; i++) { Thing inparam = argv[i + offset]; Class outparam = outparams[i]; String javaclassname = outparam.getSimpleName(); /* Tweak inparam according to the constant table we've * been passed - if someone passes us a CONSTANT_NAME * that's in our table, we use its value. */ String val = inparam.toString(); if (constnames.containsKey(val)) { inparam = (Thing)constnames.get(val); } String heclparmt = inparam.getVal().thingclass(); if (heclTypeToJavaType(return_value, outparam, inparam)) { outobjs[i] = return_value[0]; matched = true; } else { matched = false; } } retval[0] = outobjs; return matched; } /** * The <code>mapRetval</code> method is the "opposite" of the * mapParams method - it maps a returned Java value onto a Hecl * Thing, which it then returns. * * @param m a <code>Method</code> value * @param o an <code>Object</code> value * @return a <code>Thing</code> value */ private Thing mapRetval(Method m, Object o) { Class rtype = m.getReturnType(); return javaTypeToHeclType(rtype, o); } /** * The <code>heclTypeToJavaType</code> method takes a Class and a * Hecl Thing, turns the Thing into an Object based on the Class * type, and returns the Object. * * @param retval an <code>Object</code> value * @param rtype a <code>Class</code> value * @param heclparm a <code>Thing</code> value * @return an <code>Object</code> value * @exception HeclException if an error occurs */ public boolean heclTypeToJavaType(Object[] retval, Class rtype, Thing heclparm) throws HeclException { boolean foundmatch = false; String heclparmt = heclparm.getVal().thingclass(); String javaclassname = rtype.getSimpleName(); /* null is always going to match. */ if (heclparmt.equals("object") && ObjectThing.get(heclparm) == null) { foundmatch = true; retval[0] = null; } else if (rtype == boolean.class || rtype == Boolean.class) { if (heclparmt.equals("int")) { retval[0] = IntThing.get(heclparm) != 0; foundmatch = true; } } else if (rtype == int.class || rtype == Integer.class) { if (heclparmt.equals("int")) { retval[0] = IntThing.get(heclparm); foundmatch = true; } } else if (rtype == long.class) { if (heclparmt.equals("long")) { retval[0] = LongThing.get(heclparm); foundmatch = true; } } else if (rtype == float.class || rtype == Float.class) { if (heclparmt.equals("double")) { retval[0] = (float)DoubleThing.get(heclparm); foundmatch = true; } } else if (rtype == double.class || rtype == Double.class) { if (heclparmt.equals("double")) { retval[0] = DoubleThing.get(heclparm); foundmatch = true; } } else if (rtype == CharSequence.class || rtype == String.class) { if (heclparmt.equals("string")) { retval[0] = heclparm.toString(); foundmatch = true; } } else if (javaclassname.equals("byte[]")) { if (heclparmt.equals("string")) { try { retval[0] = heclparm.toString().getBytes("ISO8859_1"); foundmatch = true; } catch (java.io.UnsupportedEncodingException e) { throw new HeclException(e.toString()); } } } else if (javaclassname.equals("int[]")) { /* This is a hack - we need to look and see if it's an * array, and then recursively deal with the various ints * in the array. */ Vector v = ListThing.get(heclparm); int[] ints = new int[v.size()]; for (int j = 0; j < v.size(); j++) { ints[j] = IntThing.get((Thing)v.elementAt(j)); } retval[0] = ints; foundmatch = true; } else if (javaclassname.equals("Object[]")) { Thing[] things = ListThing.getArray(heclparm); Object[] objects = new Object[things.length]; int j = 0; for (Thing t : things) { /* This is a bit of a hack. If they're objects, move * them on through as objects, otherwise, as * strings. */ if (t.getVal().thingclass().equals("object")) { objects[j] = ObjectThing.get(t); } else { objects[j] = t.toString(); } j++; } retval[0] = objects; foundmatch = true; } else if (rtype == Thing.class) { /* We can use this to pass Things around directly, to * classes that support it. */ retval[0] = heclparm; foundmatch = true; } else if (heclparmt.equals("object")) { /* We are getting an ObjectThing from Hecl... */ retval[0] = ObjectThing.get(heclparm); foundmatch = true; } else if (rtype == Object.class) { /* We're not getting an ObjectThing from Hecl, but Java * can take any Object. Give it Things directly. This is * sort of a last resort as more specific is better. */ retval[0] = heclparm; foundmatch = true; } /* No match. */ return foundmatch; } /** * The <code>javaTypeToHeclType</code> method takes a Java type, * and a Java Object, and returns a Thing. * * @param rtype a <code>Class</code> value * @param o an <code>Object</code> value * @return a <code>Thing</code> value */ public Thing javaTypeToHeclType(Class rtype, Object o) { String rtypename = rtype.getSimpleName(); if (o == null) { return null; } else if (rtype == void.class) { return null; } else if (rtype == int.class) { return IntThing.create(((Integer)o).intValue()); } else if (rtype == boolean.class) { boolean val = ((Boolean)o).equals(Boolean.TRUE); return IntThing.create(val ? 1 : 0); } else if (rtype == long.class) { return LongThing.create(((Long)o).longValue()); } else if (rtype == String.class || rtype == CharSequence.class) { return new Thing((String)o); } else if (rtype == List.class) { List lo = (List)o; Vector v = new Vector(); for (int j = 0; j < lo.size(); j++) { Object elem = lo.get(j); v.add(javaTypeToHeclType(elem.getClass(), elem)); } return ListThing.create(v); } else if (rtypename.equals("String[]")) { Vector v = new Vector(); String[] retval = (String [])o; for (String s : retval) { v.add(new Thing(s)); } return ListThing.create(v); } else if (rtypename.equals("int[]")) { Vector v = new Vector(); int[] retval = (int [])o; for (int i : retval) { v.add(IntThing.create(i)); } return ListThing.create(v); } else if (rtypename.equals("byte[]")) { /* Let's use this encoding for now... */ String s = null; try { s = new String((byte[])o, "ISO8859_1"); } catch (java.io.UnsupportedEncodingException e) { /* FIXME - this should never happen. */ } return new Thing(s); } else if (rtype == Object.class) { if (o.getClass() == Thing.class) { /* If we've managed to stash a thing somewhere. */ return (Thing)o; } } return ObjectThing.create(o); } /** * The <code>methods</code> method returns a Hecl list of method * signatures in the form methodName type type type. * * @return a <code>Thing</code> value * @exception HeclException if an error occurs */ public Thing methods() throws HeclException { Vector retval = new Vector(); if (methodnames == null) { fillMethods(); } for (Enumeration e = methodnames.keys(); e.hasMoreElements();) { Vector signature = new Vector(); String key = (String)e.nextElement(); signature.add(new Thing(key)); Vector<Method> v = (Vector)methodnames.get(key); Method[] methods = v.toArray(new Method[v.size()]); Class[] javaparams = null; for (Method m : methods) { javaparams = m.getParameterTypes(); for (Class c : javaparams) { signature.add(new Thing(c.getSimpleName())); } } retval.add(ListThing.create(signature)); } return ListThing.create(retval); } /** * The <code>constructors</code> method returns a Hecl list of * types that would work as constructors for this object type. * * @return a <code>Thing</code> value */ public Thing constructors() { Vector retval = new Vector(); Constructor[] constructors = forclass.getConstructors(); for (Constructor c : constructors) { Vector paramnames = new Vector(); Class[] params = c.getParameterTypes(); for (Class p : params) { paramnames.add(new Thing(p.getSimpleName())); } retval.add(ListThing.create(paramnames)); } return ListThing.create(retval); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?