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 + -
显示快捷键?