mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-26 17:29:41 +08:00
18e1f2bd67
* HACKING, gnu/gcj/xlib/Pixmap.java, gnu/gcj/xlib/XException.java, gnu/java/rmi/rmic/RMIC.java, java/awt/Window.java, java/awt/AWTEvent.java, java/io/ByteArrayOutputStream.java, java/io/CharConversionException.java, java/io/PipedInputStream.java, java/io/PipedReader.java, java/io/PrintWriter.java, java/io/WriteAbortedException.java, java/io/natFileWin32.cc, java/lang/Class.h, java/lang/natClassLoader.cc, java/lang/natObject.cc, java/lang/Package.java, java/net/BindException.java, java/net/ConnectException.java, java/net/ProtocolException.java, java/net/SocketException.java, java/net/UnknownServiceException.java, java/security/cert/X509Certificate.java, java/security/interfaces/DSAKey.java, java/security/SecureRandom.java, java/security/SignedObject.java, java/sql/DatabaseMetaData.java, java/text/DecimalFormatSymbols.java, java/util/jar/Attributes.java, java/util/jar/JarEntry.java, java/util/jar/JarInputStream.java, java/util/jar/JarOutputStream.java, java/util/Calendar.java, java/util/Collections.java, java/util/GregorianCalendar.java, java/util/HashMap.java, java/util/List.java, java/util/Properties.java, java/util/Timer.java, java/util/Vector.java, java/util/WeakHashMap.java, javax/naming/NamingException.java, testsuite/libjava.lang/Thread_Wait.java, org/xml/sax/helpers/DefaultHandler.java, org/xml/sax/HandlerBase.java, org/xml/sax/SAXParseException.java, ChangeLog, acinclude.m4, aclocal.m4, posix-threads.cc: Fix spelling errors. * configure: Regenerate. From-SVN: r46665
978 lines
25 KiB
Java
978 lines
25 KiB
Java
/*
|
|
Copyright (c) 1996, 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU Classpath.
|
|
|
|
GNU Classpath is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU Classpath is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Classpath; see the file COPYING. If not, write to the
|
|
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
02111-1307 USA.
|
|
|
|
As a special exception, if you link this library with other files to
|
|
produce an executable, this library does not by itself cause the
|
|
resulting executable to be covered by the GNU General Public License.
|
|
This exception does not however invalidate any other reasons why the
|
|
executable file might be covered by the GNU General Public License.
|
|
*/
|
|
|
|
package gnu.java.rmi.rmic;
|
|
|
|
import java.io.File;
|
|
import java.io.FileWriter;
|
|
import java.io.PrintWriter;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.Modifier;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.Arrays;
|
|
import java.lang.Comparable;
|
|
import gnu.java.rmi.server.RMIHashes;
|
|
|
|
public class RMIC {
|
|
|
|
private String[] args;
|
|
private int next;
|
|
private Exception exception;
|
|
|
|
private boolean keep = false;
|
|
private boolean need11Stubs = true;
|
|
private boolean need12Stubs = true;
|
|
private boolean compile = true;
|
|
private boolean verbose;
|
|
private String destination;
|
|
|
|
private PrintWriter out;
|
|
private TabbedWriter ctrl;
|
|
|
|
private Class clazz;
|
|
private String classname;
|
|
private String fullclassname;
|
|
private MethodRef[] remotemethods;
|
|
private String stubname;
|
|
private String skelname;
|
|
|
|
public RMIC(String[] a) {
|
|
args = a;
|
|
}
|
|
|
|
public static void main(String args[]) {
|
|
RMIC r = new RMIC(args);
|
|
if (r.run() == false) {
|
|
Exception exception = r.getException();
|
|
if (exception != null) {
|
|
exception.printStackTrace();
|
|
}
|
|
else {
|
|
usage();
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean run() {
|
|
parseOptions();
|
|
if (next >= args.length) {
|
|
return (false);
|
|
}
|
|
for (int i = next; i < args.length; i++) {
|
|
try {
|
|
if (verbose) {
|
|
System.out.println("[Processing class " + args[i] + ".class]");
|
|
}
|
|
processClass(args[i]);
|
|
}
|
|
catch (Exception e) {
|
|
exception = e;
|
|
return (false);
|
|
}
|
|
}
|
|
return (true);
|
|
}
|
|
|
|
private boolean processClass(String classname) throws Exception {
|
|
analyzeClass(classname);
|
|
generateStub();
|
|
if (need11Stubs) {
|
|
generateSkel();
|
|
}
|
|
if (compile) {
|
|
compile(stubname + ".java");
|
|
if (need11Stubs) {
|
|
compile(skelname + ".java");
|
|
}
|
|
}
|
|
if (!keep) {
|
|
(new File(stubname + ".java")).delete();
|
|
if (need11Stubs) {
|
|
(new File(skelname + ".java")).delete();
|
|
}
|
|
}
|
|
return (true);
|
|
}
|
|
|
|
private void analyzeClass(String cname) throws Exception {
|
|
int p = cname.lastIndexOf('.');
|
|
if (p != -1) {
|
|
classname = cname.substring(p+1);
|
|
}
|
|
else {
|
|
classname = cname;
|
|
}
|
|
fullclassname = cname;
|
|
|
|
HashSet rmeths = new HashSet();
|
|
findClass();
|
|
for (Class cls = clazz; cls != null; cls = cls.getSuperclass()) {
|
|
// Keep going down the inheritence tree until we hit the system
|
|
if (cls.getName().startsWith("java.")) {
|
|
break;
|
|
}
|
|
|
|
Method[] meths = cls.getDeclaredMethods();
|
|
for (int i = 0; i < meths.length; i++) {
|
|
// Only include public methods
|
|
int mods = meths[i].getModifiers();
|
|
if (Modifier.isPublic(mods) && !Modifier.isStatic(mods)) {
|
|
// Should check exceptions here. - XXX
|
|
|
|
// Add this one in.
|
|
rmeths.add(meths[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Convert into a MethodRef array and sort them
|
|
remotemethods = new MethodRef[rmeths.size()];
|
|
int c = 0;
|
|
for (Iterator i = rmeths.iterator(); i.hasNext(); ) {
|
|
remotemethods[c++] = new MethodRef((Method)i.next());
|
|
}
|
|
Arrays.sort(remotemethods);
|
|
}
|
|
|
|
public Exception getException() {
|
|
return (exception);
|
|
}
|
|
|
|
private void findClass() throws ClassNotFoundException {
|
|
clazz = Class.forName(fullclassname);
|
|
}
|
|
|
|
private void generateStub() throws IOException {
|
|
stubname = classname + "_Stub";
|
|
ctrl = new TabbedWriter(new FileWriter(stubname + ".java"));
|
|
out = new PrintWriter(ctrl);
|
|
|
|
if (verbose) {
|
|
System.out.println("[Generating class " + stubname + ".java]");
|
|
}
|
|
|
|
out.println("// Stub class generated by rmic - DO NOT EDIT!");
|
|
out.println();
|
|
if (fullclassname != classname) {
|
|
String pname = fullclassname.substring(0, fullclassname.lastIndexOf('.'));
|
|
out.println("package " + pname + ";");
|
|
out.println();
|
|
}
|
|
|
|
out.print("public final class " + stubname);
|
|
ctrl.indent();
|
|
out.println("extends java.rmi.server.RemoteStub");
|
|
|
|
// Output interfaces we implement
|
|
out.print("implements ");
|
|
Class[] ifaces = clazz.getInterfaces();
|
|
for (int i = 0; i < ifaces.length; i++) {
|
|
out.print(ifaces[i].getName());
|
|
if (i+1 < ifaces.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
|
|
ctrl.unindent();
|
|
out.print("{");
|
|
ctrl.indent();
|
|
|
|
// UID
|
|
if (need12Stubs) {
|
|
out.println("private static final long serialVersionUID = 2L;");
|
|
out.println();
|
|
}
|
|
|
|
// InterfaceHash - don't know how to calculate this - XXX
|
|
if (need11Stubs) {
|
|
out.println("private static final long interfaceHash = " + RMIHashes.getInterfaceHash(clazz) + "L;");
|
|
out.println();
|
|
if (need12Stubs) {
|
|
out.println("private static boolean useNewInvoke;");
|
|
out.println();
|
|
}
|
|
|
|
// Operation table
|
|
out.print("private static final java.rmi.server.Operation[] operations = {");
|
|
|
|
ctrl.indent();
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
Method m = remotemethods[i].meth;
|
|
out.print("new java.rmi.server.Operation(\"");
|
|
out.print(getPrettyName(m.getReturnType()) + " ");
|
|
out.print(m.getName() + "(");
|
|
// Output signature
|
|
Class[] sig = m.getParameterTypes();
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print(getPrettyName(sig[j]));
|
|
if (j+1 < sig.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.print(")\")");
|
|
if (i + 1 < remotemethods.length) {
|
|
out.println(",");
|
|
}
|
|
}
|
|
ctrl.unindent();
|
|
out.println("};");
|
|
out.println();
|
|
}
|
|
|
|
// Set of method references.
|
|
if (need12Stubs) {
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
Method m = remotemethods[i].meth;
|
|
out.println("private static java.lang.reflect.Method $method_" + m.getName() + "_" + i + ";");
|
|
}
|
|
|
|
// Initialize the methods references.
|
|
out.println();
|
|
out.print("static {");
|
|
ctrl.indent();
|
|
|
|
out.print("try {");
|
|
ctrl.indent();
|
|
|
|
if (need11Stubs) {
|
|
out.println("java.rmi.server.RemoteRef.class.getMethod(\"invoke\", new java.lang.Class[] { java.rmi.Remote.class, java.lang.reflect.Method.class, java.lang.Object[].class, long.class });");
|
|
out.println("useNewInvoke = true;");
|
|
}
|
|
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
Method m = remotemethods[i].meth;
|
|
out.print("$method_" + m.getName() + "_" + i + " = ");
|
|
out.print(fullclassname + ".class.getMethod(\"" + m.getName() + "\"");
|
|
out.print(", new java.lang.Class[] {");
|
|
// Output signature
|
|
Class[] sig = m.getParameterTypes();
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print(getPrettyName(sig[j]) + ".class");
|
|
if (j+1 < sig.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.println("});");
|
|
}
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("catch (java.lang.NoSuchMethodException e) {");
|
|
ctrl.indent();
|
|
if (need11Stubs) {
|
|
out.print("useNewInvoke = false;");
|
|
}
|
|
else {
|
|
out.print("throw new java.lang.NoSuchMethodError(\"stub class initialization failed\");");
|
|
}
|
|
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.println();
|
|
}
|
|
|
|
// Constructors
|
|
if (need11Stubs) {
|
|
out.print("public " + stubname + "() {");
|
|
ctrl.indent();
|
|
out.print("super();");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
}
|
|
|
|
if (need12Stubs) {
|
|
out.print("public " + stubname + "(java.rmi.server.RemoteRef ref) {");
|
|
ctrl.indent();
|
|
out.print("super(ref);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
}
|
|
|
|
// Method implementations
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
Method m = remotemethods[i].meth;
|
|
Class[] sig = m.getParameterTypes();
|
|
Class returntype = m.getReturnType();
|
|
Class[] except = sortExceptions(m.getExceptionTypes());
|
|
|
|
out.println();
|
|
out.print("public " + getPrettyName(returntype) + " " + m.getName() + "(");
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print(getPrettyName(sig[j]));
|
|
out.print(" $param_" + j);
|
|
if (j+1 < sig.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.print(") ");
|
|
out.print("throws ");
|
|
for (int j = 0; j < except.length; j++) {
|
|
out.print(getPrettyName(except[j]));
|
|
if (j+1 < except.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.print(" {");
|
|
ctrl.indent();
|
|
|
|
out.print("try {");
|
|
ctrl.indent();
|
|
|
|
if (need12Stubs) {
|
|
if (need11Stubs) {
|
|
out.print("if (useNewInvoke) {");
|
|
ctrl.indent();
|
|
}
|
|
if (returntype != Void.TYPE) {
|
|
out.print("java.lang.Object $result = ");
|
|
}
|
|
out.print("ref.invoke(this, $method_" + m.getName() + "_" + i + ", ");
|
|
if (sig.length == 0) {
|
|
out.print("null, ");
|
|
}
|
|
else {
|
|
out.print("new java.lang.Object[] {");
|
|
for (int j = 0; j < sig.length; j++) {
|
|
if (sig[j] == Boolean.TYPE) {
|
|
out.print("new java.lang.Boolean($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Byte.TYPE) {
|
|
out.print("new java.lang.Byte($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Character.TYPE) {
|
|
out.print("new java.lang.Character($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Short.TYPE) {
|
|
out.print("new java.lang.Short($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Integer.TYPE) {
|
|
out.print("new java.lang.Integer($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Long.TYPE) {
|
|
out.print("new java.lang.Long($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Float.TYPE) {
|
|
out.print("new java.lang.Float($param_" + j + ")");
|
|
}
|
|
else if (sig[j] == Double.TYPE) {
|
|
out.print("new java.lang.Double($param_" + j + ")");
|
|
}
|
|
else {
|
|
out.print("$param_" + j);
|
|
}
|
|
if (j+1 < sig.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.print("}, ");
|
|
}
|
|
out.print(Long.toString(remotemethods[i].hash) + "L");
|
|
out.print(");");
|
|
|
|
if (returntype != Void.TYPE) {
|
|
out.println();
|
|
out.print("return (");
|
|
if (returntype == Boolean.TYPE) {
|
|
out.print("((java.lang.Boolean)$result).booleanValue()");
|
|
}
|
|
else if (returntype == Byte.TYPE) {
|
|
out.print("((java.lang.Byte)$result).byteValue()");
|
|
}
|
|
else if (returntype == Character.TYPE) {
|
|
out.print("((java.lang.Character)$result).charValue()");
|
|
}
|
|
else if (returntype == Short.TYPE) {
|
|
out.print("((java.lang.Short)$result).shortValue()");
|
|
}
|
|
else if (returntype == Integer.TYPE) {
|
|
out.print("((java.lang.Integer)$result).intValue()");
|
|
}
|
|
else if (returntype == Long.TYPE) {
|
|
out.print("((java.lang.Long)$result).longValue()");
|
|
}
|
|
else if (returntype == Float.TYPE) {
|
|
out.print("((java.lang.Float)$result).floatValue()");
|
|
}
|
|
else if (returntype == Double.TYPE) {
|
|
out.print("((java.lang.Double)$result).doubleValue()");
|
|
}
|
|
else {
|
|
out.print("(" + getPrettyName(returntype) + ")$result");
|
|
}
|
|
out.print(");");
|
|
}
|
|
|
|
if (need11Stubs) {
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("else {");
|
|
ctrl.indent();
|
|
}
|
|
}
|
|
|
|
if (need11Stubs) {
|
|
out.println("java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, " + i + ", interfaceHash);");
|
|
out.print("try {");
|
|
ctrl.indent();
|
|
out.print("java.io.ObjectOutput out = call.getOutputStream();");
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.println();
|
|
if (sig[j] == Boolean.TYPE) {
|
|
out.print("out.writeBoolean(");
|
|
}
|
|
else if (sig[j] == Byte.TYPE) {
|
|
out.print("out.writeByte(");
|
|
}
|
|
else if (sig[j] == Character.TYPE) {
|
|
out.print("out.writeChar(");
|
|
}
|
|
else if (sig[j] == Short.TYPE) {
|
|
out.print("out.writeShort(");
|
|
}
|
|
else if (sig[j] == Integer.TYPE) {
|
|
out.print("out.writeInt(");
|
|
}
|
|
else if (sig[j] == Long.TYPE) {
|
|
out.print("out.writeLong(");
|
|
}
|
|
else if (sig[j] == Float.TYPE) {
|
|
out.print("out.writeFloat(");
|
|
}
|
|
else if (sig[j] == Double.TYPE) {
|
|
out.print("out.writeDouble(");
|
|
}
|
|
else {
|
|
out.print("out.writeObject(");
|
|
}
|
|
out.print("$param_" + j + ");");
|
|
}
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("catch (java.io.IOException e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.MarshalException(\"error marshalling arguments\", e);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.println("ref.invoke(call);");
|
|
if (returntype != Void.TYPE) {
|
|
out.println(getPrettyName(returntype) + " $result;");
|
|
}
|
|
out.print("try {");
|
|
ctrl.indent();
|
|
out.print("java.io.ObjectInput in = call.getInputStream();");
|
|
boolean needcastcheck = false;
|
|
if (returntype != Void.TYPE) {
|
|
out.println();
|
|
out.print("$result = ");
|
|
if (returntype == Boolean.TYPE) {
|
|
out.print("in.readBoolean();");
|
|
}
|
|
else if (returntype == Byte.TYPE) {
|
|
out.print("in.readByte();");
|
|
}
|
|
else if (returntype == Character.TYPE) {
|
|
out.print("in.readChar();");
|
|
}
|
|
else if (returntype == Short.TYPE) {
|
|
out.print("in.readShort();");
|
|
}
|
|
else if (returntype == Integer.TYPE) {
|
|
out.print("in.readInt();");
|
|
}
|
|
else if (returntype == Long.TYPE) {
|
|
out.print("in.readLong();");
|
|
}
|
|
else if (returntype == Float.TYPE) {
|
|
out.print("in.readFloat();");
|
|
}
|
|
else if (returntype == Double.TYPE) {
|
|
out.print("in.readDouble();");
|
|
}
|
|
else {
|
|
if (returntype != Object.class) {
|
|
out.print("(" + getPrettyName(returntype) + ")");
|
|
}
|
|
else {
|
|
needcastcheck = true;
|
|
}
|
|
out.print("in.readObject();");
|
|
}
|
|
out.println();
|
|
out.print("return ($result);");
|
|
}
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("catch (java.io.IOException e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
if (needcastcheck) {
|
|
out.print("catch (java.lang.ClassNotFoundException e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
}
|
|
out.print("finally {");
|
|
ctrl.indent();
|
|
out.print("ref.done(call);");
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
|
|
if (need12Stubs && need11Stubs) {
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
}
|
|
}
|
|
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
|
|
boolean needgeneral = true;
|
|
for (int j = 0; j < except.length; j++) {
|
|
out.println();
|
|
out.print("catch (" + getPrettyName(except[j]) + " e) {");
|
|
ctrl.indent();
|
|
out.print("throw e;");
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
if (except[j] == Exception.class) {
|
|
needgeneral = false;
|
|
}
|
|
}
|
|
if (needgeneral) {
|
|
out.println();
|
|
out.print("catch (java.lang.Exception e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.UnexpectedException(\"undeclared checked exception\", e);");
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
}
|
|
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
out.println();
|
|
}
|
|
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
|
|
out.close();
|
|
}
|
|
|
|
private void generateSkel() throws IOException {
|
|
skelname = classname + "_Skel";
|
|
ctrl = new TabbedWriter(new FileWriter(skelname + ".java"));
|
|
out = new PrintWriter(ctrl);
|
|
|
|
if (verbose) {
|
|
System.out.println("[Generating class " + skelname + ".java]");
|
|
}
|
|
|
|
out.println("// Skel class generated by rmic - DO NOT EDIT!");
|
|
out.println();
|
|
if (fullclassname != classname) {
|
|
String pname = fullclassname.substring(0, fullclassname.lastIndexOf('.'));
|
|
out.println("package " + pname + ";");
|
|
out.println();
|
|
}
|
|
|
|
out.print("public final class " + skelname);
|
|
ctrl.indent();
|
|
|
|
// Output interfaces we implement
|
|
out.print("implements java.rmi.server.Skeleton");
|
|
|
|
ctrl.unindent();
|
|
out.print("{");
|
|
ctrl.indent();
|
|
|
|
// Interface hash - don't know how to calculate this - XXX
|
|
out.println("private static final long interfaceHash = " + RMIHashes.getInterfaceHash(clazz) + "L;");
|
|
out.println();
|
|
|
|
// Operation table
|
|
out.print("private static final java.rmi.server.Operation[] operations = {");
|
|
|
|
ctrl.indent();
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
Method m = remotemethods[i].meth;
|
|
out.print("new java.rmi.server.Operation(\"");
|
|
out.print(getPrettyName(m.getReturnType()) + " ");
|
|
out.print(m.getName() + "(");
|
|
// Output signature
|
|
Class[] sig = m.getParameterTypes();
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print(getPrettyName(sig[j]));
|
|
if (j+1 < sig.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.print("\")");
|
|
if (i + 1 < remotemethods.length) {
|
|
out.println(",");
|
|
}
|
|
}
|
|
ctrl.unindent();
|
|
out.println("};");
|
|
|
|
out.println();
|
|
|
|
// getOperations method
|
|
out.print("public java.rmi.server.Operation[] getOperations() {");
|
|
ctrl.indent();
|
|
out.print("return ((java.rmi.server.Operation[]) operations.clone());");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
|
|
out.println();
|
|
|
|
// Dispatch method
|
|
out.print("public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception {");
|
|
ctrl.indent();
|
|
|
|
out.print("if (opnum < 0) {");
|
|
ctrl.indent();
|
|
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
out.print("if (hash == " + Long.toString(remotemethods[i].hash) + "L) {");
|
|
ctrl.indent();
|
|
out.print("opnum = " + i + ";");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("else ");
|
|
}
|
|
out.print("{");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("else if (hash != interfaceHash) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
|
|
out.println();
|
|
|
|
out.println(fullclassname + " server = (" + fullclassname + ")obj;");
|
|
out.println("switch (opnum) {");
|
|
|
|
// Method dispatch
|
|
for (int i = 0; i < remotemethods.length; i++) {
|
|
Method m = remotemethods[i].meth;
|
|
out.println("case " + i + ":");
|
|
out.print("{");
|
|
ctrl.indent();
|
|
|
|
Class[] sig = m.getParameterTypes();
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print(getPrettyName(sig[j]));
|
|
out.println(" $param_" + j + ";");
|
|
}
|
|
|
|
out.print("try {");
|
|
boolean needcastcheck = false;
|
|
ctrl.indent();
|
|
out.println("java.io.ObjectInput in = call.getInputStream();");
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print("$param_" + j + " = ");
|
|
if (sig[j] == Boolean.TYPE) {
|
|
out.print("in.readBoolean();");
|
|
}
|
|
else if (sig[j] == Byte.TYPE) {
|
|
out.print("in.readByte();");
|
|
}
|
|
else if (sig[j] == Character.TYPE) {
|
|
out.print("in.readChar();");
|
|
}
|
|
else if (sig[j] == Short.TYPE) {
|
|
out.print("in.readShort();");
|
|
}
|
|
else if (sig[j] == Integer.TYPE) {
|
|
out.print("in.readInt();");
|
|
}
|
|
else if (sig[j] == Long.TYPE) {
|
|
out.print("in.readLong();");
|
|
}
|
|
else if (sig[j] == Float.TYPE) {
|
|
out.print("in.readFloat();");
|
|
}
|
|
else if (sig[j] == Double.TYPE) {
|
|
out.print("in.readDouble();");
|
|
}
|
|
else {
|
|
if (sig[j] != Object.class) {
|
|
out.print("(" + getPrettyName(sig[j]) + ")");
|
|
needcastcheck = true;
|
|
}
|
|
out.print("in.readObject();");
|
|
}
|
|
out.println();
|
|
}
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("catch (java.io.IOException e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
if (needcastcheck) {
|
|
out.print("catch (java.lang.ClassCastException e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
}
|
|
out.print("finally {");
|
|
ctrl.indent();
|
|
out.print("call.releaseInputStream();");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
|
|
Class returntype = m.getReturnType();
|
|
if (returntype != Void.TYPE) {
|
|
out.print(getPrettyName(returntype) + " $result = ");
|
|
}
|
|
out.print("server." + m.getName() + "(");
|
|
for (int j = 0; j < sig.length; j++) {
|
|
out.print("$param_" + j);
|
|
if (j + 1 < sig.length) {
|
|
out.print(", ");
|
|
}
|
|
}
|
|
out.println(");");
|
|
|
|
out.print("try {");
|
|
ctrl.indent();
|
|
out.print("java.io.ObjectOutput out = call.getResultStream(true);");
|
|
if (returntype != Void.TYPE) {
|
|
out.println();
|
|
if (returntype == Boolean.TYPE) {
|
|
out.print("out.writeBoolean($result);");
|
|
}
|
|
else if (returntype == Byte.TYPE) {
|
|
out.print("out.writeByte($result);");
|
|
}
|
|
else if (returntype == Character.TYPE) {
|
|
out.print("out.writeChar($result);");
|
|
}
|
|
else if (returntype == Short.TYPE) {
|
|
out.print("out.writeShort($result);");
|
|
}
|
|
else if (returntype == Integer.TYPE) {
|
|
out.print("out.writeInt($result);");
|
|
}
|
|
else if (returntype == Long.TYPE) {
|
|
out.print("out.writeLong($result);");
|
|
}
|
|
else if (returntype == Float.TYPE) {
|
|
out.print("out.writeFloat($result);");
|
|
}
|
|
else if (returntype == Double.TYPE) {
|
|
out.print("out.writeDouble($result);");
|
|
}
|
|
else {
|
|
out.print("out.writeObject($result);");
|
|
}
|
|
}
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("catch (java.io.IOException e) {");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.MarshalException(\"error marshalling return\", e);");
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.print("break;");
|
|
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
out.println();
|
|
}
|
|
|
|
out.print("default:");
|
|
ctrl.indent();
|
|
out.print("throw new java.rmi.UnmarshalException(\"invalid method number\");");
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
|
|
ctrl.unindent();
|
|
out.print("}");
|
|
|
|
ctrl.unindent();
|
|
out.println("}");
|
|
|
|
out.close();
|
|
}
|
|
|
|
private void compile(String name) throws Exception {
|
|
Compiler comp = Compiler.getInstance();
|
|
if (verbose) {
|
|
System.out.println("[Compiling class " + name + "]");
|
|
}
|
|
comp.setDestination(destination);
|
|
comp.compile(name);
|
|
}
|
|
|
|
private static String getPrettyName(Class cls) {
|
|
StringBuffer str = new StringBuffer();
|
|
for (int count = 0;; count++) {
|
|
if (!cls.isArray()) {
|
|
str.append(cls.getName());
|
|
for (; count > 0; count--) {
|
|
str.append("[]");
|
|
}
|
|
return (str.toString());
|
|
}
|
|
cls = cls.getComponentType();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sort exceptions so the most general go last.
|
|
*/
|
|
private Class[] sortExceptions(Class[] except) {
|
|
for (int i = 0; i < except.length; i++) {
|
|
for (int j = i+1; j < except.length; j++) {
|
|
if (except[i].isAssignableFrom(except[j])) {
|
|
Class tmp = except[i];
|
|
except[i] = except[j];
|
|
except[j] = tmp;
|
|
}
|
|
}
|
|
}
|
|
return (except);
|
|
}
|
|
|
|
/**
|
|
* Process the options until we find the first argument.
|
|
*/
|
|
private void parseOptions() {
|
|
for (;;) {
|
|
if (next >= args.length || args[next].charAt(0) != '-') {
|
|
break;
|
|
}
|
|
String arg = args[next];
|
|
next++;
|
|
|
|
if (arg.equals("-keep")) {
|
|
keep = true;
|
|
}
|
|
else if (arg.equals("-keepgenerated")) {
|
|
keep = true;
|
|
}
|
|
else if (arg.equals("-v1.1")) {
|
|
need11Stubs = true;
|
|
need12Stubs = false;
|
|
}
|
|
else if (arg.equals("-vcompat")) {
|
|
need11Stubs = true;
|
|
need12Stubs = true;
|
|
}
|
|
else if (arg.equals("-v1.2")) {
|
|
need11Stubs = false;
|
|
need12Stubs = true;
|
|
}
|
|
else if (arg.equals("-g")) {
|
|
}
|
|
else if (arg.equals("-depend")) {
|
|
}
|
|
else if (arg.equals("-nowarn")) {
|
|
}
|
|
else if (arg.equals("-verbose")) {
|
|
verbose = true;
|
|
}
|
|
else if (arg.equals("-nocompile")) {
|
|
compile = false;
|
|
}
|
|
else if (arg.equals("-classpath")) {
|
|
next++;
|
|
}
|
|
else if (arg.equals("-d")) {
|
|
destination = args[next];
|
|
next++;
|
|
}
|
|
else if (arg.charAt(1) == 'J') {
|
|
}
|
|
else {
|
|
System.err.println("Unknown option: " + arg);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void usage() {
|
|
System.out.println(
|
|
"usage: rmic [-options] classes\n" +
|
|
"Options are:\n" +
|
|
" -keep Don't delete any intermediate files\n" +
|
|
" -keepgenerated Same as -keep\n" +
|
|
" -v1.1 Java 1.1 style stubs only\n" +
|
|
" -vcompat Java 1.1 & Java 1.2 stubs\n" +
|
|
" -v1.2 Java 1.2 style stubs only\n" +
|
|
" -g * Generated debugging information\n" +
|
|
" -depend * Recompile out-of-date files\n" +
|
|
" -nowarn * Suppress warning messages\n" +
|
|
" -nocompile Don't compile the generated files\n" +
|
|
" -verbose Output what's going on\n" +
|
|
" -classpath <path> * Use given path as classpath\n" +
|
|
" -d <directory> Specify where to place generated classes\n" +
|
|
" -J<flag> * Pass flag to Java\n" +
|
|
" * Option currently ignored"
|
|
);
|
|
}
|
|
|
|
static class MethodRef
|
|
implements Comparable {
|
|
|
|
Method meth;
|
|
String sig;
|
|
long hash;
|
|
|
|
MethodRef(Method m) {
|
|
meth = m;
|
|
// We match on the name - but what about overloading? - XXX
|
|
sig = m.getName();
|
|
hash = RMIHashes.getMethodHash(m);
|
|
}
|
|
|
|
public int compareTo(Object obj) {
|
|
MethodRef that = (MethodRef)obj;
|
|
return (this.sig.compareTo(that.sig));
|
|
}
|
|
|
|
}
|
|
|
|
}
|