proxygenerator.java

来自「OpenJMS是一个开源的Java Message Service API 1.」· Java 代码 · 共 676 行 · 第 1/2 页

JAVA
676
字号
            }            String argClass = ClassHelper.getQualifiedName(argTypes[i]);            writer.write(argClass + " arg" + i);        }        writer.write(")");        // generate throws clause        if (exceptionTypes.length > 0) {            writer.writelnInc();            writer.write("throws ");            for (int i = 0; i < exceptionTypes.length; ++i) {                if (i > 0) {                    writer.write(", ");                }                writer.write(exceptionTypes[i].getName());            }            writer.writeln(" { ");        } else {            writer.writelnInc(" {");        }        // generate the invocation arguments, if the method takes arguments        String argValue = null;        if (argTypes.length > 0) {            argValue = "args";            writer.write("Object[] " + argValue + " = new Object[] {");            for (int i = 0; i < argTypes.length; ++i) {                if (i > 0) {                    writer.write(", ");                }                Class arg = argTypes[i];                String name = "arg" + i;                writer.write(wrapArgument(arg, name));            }            writer.writeln("};");        } else {            argValue = "null";        }        // generate the invoke() call        boolean hasReturn = (returnType != void.class);        if (hasReturn) {            writer.writeln("Object result;");        }        writer.writelnInc("try {");        if (hasReturn) {            writer.write("result = ");        }        long methodId = MethodHelper.getMethodID(method);        writer.writelnDec("invoke(" + getMethodVarName(method) + ", "                          + argValue + ", 0x" + Long.toHexString(methodId)                          + "L);");        boolean caughtRIE = false;        boolean rethrowRIE = false;        if (!declaresThrowable && !declaresException                && !declaresRuntimeException                && !declaresRemoteInvocationException) {            rethrowRIE = true;        }        for (int i = 0; i < catchTypes.length; ++i) {            Class catchType = catchTypes[i];            if (rethrowRIE && !caughtRIE) {                if (catchType.equals(Throwable.class)                    || catchType.equals(Exception.class)                    || catchType.equals(RuntimeException.class)) {                    generateRethrow(writer, REMOTE_INVOCATION_EXCEPTION);                    caughtRIE = true;                }            }            generateRethrow(writer, catchType.getName());        }        if (rethrowRIE && !caughtRIE) {            generateRethrow(writer, REMOTE_INVOCATION_EXCEPTION);        }        if (!declaresThrowable) {            writer.writelnInc("} catch (java.lang.Throwable exception) {");            if (adaptThrowable) {                Class adapter = (Class) _adapters.get(adaptType);                String instance = getAdapterInstanceName(adapter);                writer.writeln(adaptType.getName() + " error = ("                        + adaptType.getName() + ") " + instance                               + ".adapt(exception);");                writer.writelnDec("throw error;");            } else if (declaresRemoteException) {                writer.writelnDec("throw new "                                  + RemoteException.class.getName()                                  + "(exception.getMessage(), exception);");            } else {                writer.writelnDec("throw new " + REMOTE_INVOCATION_EXCEPTION                                  + "(exception);");            }        }        writer.writeln("}");        if (hasReturn) {            writer.writelnDec("return " + unwrapReturn(method.getReturnType(),                                                       "result"));        } else {            writer.writelnDec();        }        writer.writeln("}");    }    /**     * Generates the class static initialiser.     *     * @param writer the writer to write to     * @throws IOException for any I/O error     */    protected void generateStaticInitialiser(SourceWriter writer)            throws IOException {        if (_methods.length > 0) {            writer.writeln();            writer.writelnInc("static {");            writer.writelnInc("try {");            for (int i = 0; i < _methods.length; ++i) {                Method method = _methods[i];                String name = getMethodVarName(method);                Class clazz = method.getDeclaringClass();                writer.write(name + " = " + clazz.getName()                             + ".class.getMethod(\"" + method.getName()                             + "\", " + "new Class[] {");                Class[] args = method.getParameterTypes();                for (int j = 0; j < args.length; ++j) {                    if (j > 0) {                        writer.write(", ");                    }                    writer.write(ClassHelper.getQualifiedName(args[j]) + ".class");                }                writer.writeln("});");            }            writer.decIndent();            writer.writelnInc("} catch (NoSuchMethodException exception) {");            writer.writelnDec(                    "throw new NoSuchMethodError(exception.getMessage());");            writer.writelnDec("}");            writer.writeln("}");        }    }    /**     * Generates a catch/rethrow clause.     *     * @param writer the writer to write to     * @param name   the type name catch     * @throws IOException for any I/O error     */    protected void generateRethrow(SourceWriter writer, String name)        throws IOException {        writer.writelnInc("} catch (" + name + " exception) {");        writer.writelnDec("throw exception;");    }    /**     * Wraps primitive arguments into their objectified equivalents.     *     * @param clazz the argument class type     * @param name  the argument name     * @return the wrapped argument name, or <code>name</code> if     *         <code>clazz</code> isn't a primitive type     */    protected String wrapArgument(Class clazz, String name) {        String result;        if (clazz.isPrimitive()) {            Class wrapper = null;            for (int i = 0; i < MAPPINGS.length; ++i) {                if (MAPPINGS[i][0] == clazz) {                    wrapper = MAPPINGS[i][1];                }            }            result = "new " + ClassHelper.getQualifiedName(wrapper)                    + "(" + name + ")";        } else {            result = name;        }        return result;    }    /**     * Generates code to unwrap a return type If the return class type is a     * primitve, generates code to unbox the objectified primitve. If the return     * class type is an object, generates code to cast the variable name to that     * type.     *     * @param clazz the return class type     * @param name  the variable name     * @return code to unwrap the return type     */    protected String unwrapReturn(Class clazz, String name) {        String result = null;        if (clazz.isPrimitive()) {            Class wrapper = null;            for (int i = 0; i < MAPPINGS.length; ++i) {                if (MAPPINGS[i][0] == clazz) {                    wrapper = MAPPINGS[i][1];                    break;                }            }            result = "((" + wrapper.getName() + ") " + name + ")."                    + clazz.getName() + "Value();";        } else {            result = "(" + ClassHelper.getQualifiedName(clazz) + ") " + name +                    ";";        }        return result;    }    /**     * Generates a name for a static Method variable.     *     * @param method the method     * @return a name for the variable     */    protected String getMethodVarName(Method method) {        return method.getName().toUpperCase() + "_"                + Long.toHexString(MethodHelper.getMethodID(method));    }    /**     * Generates a unique instance name for an adapter.     * @param adapter the adapter class     * @return a unique instance name     */    protected String getAdapterInstanceName(Class adapter) {        // determine the class name, minus its package        String name;        String qualifiedName = adapter.getName();        int lastDot = qualifiedName.lastIndexOf(".");        if (lastDot != -1) {            name = qualifiedName.substring(lastDot + 1);        } else {            name = qualifiedName;        }        StringBuffer result = new StringBuffer(name.toUpperCase());        result.append("_");        result.append(Long.toHexString(qualifiedName.hashCode()));        return result.toString();    }    /**     * Returns a set of <code>ThrowableAdapter</code>s.     */    private HashMap getAdapters(Class[] adapterClasses)            throws Exception {        HashMap result = new HashMap();        for (int i = 0; i < adapterClasses.length; ++i) {            Class adapterClass = adapterClasses[i];            Object adapter = adapterClass.newInstance();            Method method = adapterClass.getMethod("getTarget", new Class[0]);            Class exceptionType = (Class) method.invoke(adapter, new Object[0]);            if (!Throwable.class.isAssignableFrom(exceptionType)) {                throw new Exception(                        "Invalid exception class " + exceptionType.getName()                        + ": class doesn't extend " + Throwable.class);            }            result.put(exceptionType, adapterClass);        }        return result;    }    /**     * Returns the proxy superclass name for a given class.     *     * @param clazz the class     * @return the proxy superclass name     */    private static String getSuperclassProxy(Class clazz) {        String name = PROXY;        Class superClass = clazz.getSuperclass();        if (superClass != null) {            if (superClass.getInterfaces().length != 0) {                name = superClass.getName() + PROXY_SUFFIX;            } else {                name = getSuperclassProxy(superClass);            }        }        return name;    }    /**     * Helper class to compare two classes.     */    private static class ClassComparator implements Comparator {        /**         * Compare two classes.         *         * @param o1 the first class         * @param o2 the second class         * @return a negative integer, zero, or a positive integer if the first         *         class is less than, equal to, or greater than the second.         */        public int compare(Object o1, Object o2) {            int result;            Class c1 = (Class) o1;            Class c2 = (Class) o2;            if (c1 == c2) {                result = 0;            } else if (c1.isAssignableFrom(c2)) {                result = 1;            } else {                result = -1;            }            return result;        }    }    /**     * Helper to compare two methods on their names.     */    private static class MethodComparator implements Comparator {        /**         * Compare two methods.         *         * @param o1 the first method         * @param o2 the second method         * @return a negative integer, zero, or a positive integer if the first         *         method is less than, equal to, or greater than the second.         */        public int compare(Object o1, Object o2) {            Method m1 = (Method) o1;            Method m2 = (Method) o2;            return m1.getName().compareTo(m2.getName());        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?