📄 proxygenerator.java
字号:
}
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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -