/* RMIC.java --
   Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006
   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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.rmi.rmic;

import gnu.java.rmi.server.RMIHashes;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;


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 String fullstubname;
  private String fullskelname;
  private MethodRef[] remotemethods;
  private String stubname;
  private String skelname;
  private ClassLoader loader;
  private String classpath;
  private int errorCount = 0;
  private List mRemoteInterfaces;

  public RMIC(String[] a)
  {
    args = a;
  }

  public static void main(String[] args)
  {
    RMIC r = new RMIC(args);
    if (r.run() == false)
      {
	Exception e = r.getException();
	if (e != null)
	  e.printStackTrace();
	else
	  System.exit(1);
      }
  }

  public boolean run()
  {
    parseOptions();
    if (next >= args.length)
      error("no class names found");
    for (int i = next; i < args.length; i++)
      {
	try
	  {
	    if (verbose)
	      System.out.println("[Processing class " + args[i] + ".class]");
	    processClass(args[i].replace(File.separatorChar, '.'));
	  }
	catch (Exception e)
	  {
	    exception = e;
	    return (false);
	  }
      }
    return (true);
  }

  private boolean processClass(String cls) throws Exception
  {
    // reset class specific vars
    clazz = null;
    classname = null;
    fullclassname = null;
    remotemethods = null;
    stubname = null;
    fullstubname = null;
    skelname = null;
    fullskelname = null;
    mRemoteInterfaces = new ArrayList();

    errorCount = 0;

    analyzeClass(cls);

    if (errorCount > 0)
      System.exit(1);
    generateStub();
    if (need11Stubs)
      generateSkel();
    if (compile)
      {
	compile(fullstubname);
	if (need11Stubs)
	  compile(fullskelname);
      }
    if (! keep)
      {
	(new File(fullstubname)).delete();
	if (need11Stubs)
	  (new File(fullskelname)).delete();
      }
    return (true);
  }

  private void analyzeClass(String cname) throws Exception
  {
    if (verbose)
      System.out.println("[analyze class " + cname + "]");
    int p = cname.lastIndexOf('.');
    if (p != -1)
      classname = cname.substring(p + 1);
    else
      classname = cname;
    fullclassname = cname;

    findClass();
    findRemoteMethods();
  }

  public Exception getException()
  {
    return (exception);
  }

  private void findClass() throws ClassNotFoundException
  {
    try
      {
        ClassLoader cl = (loader == null
                          ? ClassLoader.getSystemClassLoader()
                          : loader);
        clazz = Class.forName(fullclassname, false, cl);
      }
    catch (ClassNotFoundException cnfe)
      {
        System.err.println(fullclassname + " not found in " + classpath);
        throw new RuntimeException(cnfe);
      }

    if (! Remote.class.isAssignableFrom(clazz))
      {
        logError("Class " + clazz.getName() + " is not a remote object. "
                 + "It does not implement an interface that is a "
                 + "java.rmi.Remote-interface.");
        throw new RuntimeException
          ("Class " + clazz.getName() + " is not a remote object. "
           + "It does not implement an interface that is a "
           + "java.rmi.Remote-interface.");
      }
  }

  private void generateStub() throws IOException
  {
    stubname = fullclassname + "_Stub";
    String stubclassname = classname + "_Stub";
    fullstubname = (destination == null ? "" : destination + File.separator)
      + stubname.replace('.', File.separatorChar) + ".java";
    File file = new File(fullstubname);
    if (file.getParentFile() != null)
      file.getParentFile().mkdirs();
    ctrl =
      new TabbedWriter(new FileWriter(file));
    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 " + stubclassname);
    ctrl.indent();
    out.println("extends java.rmi.server.RemoteStub");

    // Output interfaces we implement
    out.print("implements ");
    Iterator iter = mRemoteInterfaces.iterator();
    while (iter.hasNext())
      {
	/* Print remote interface. */
	Class iface = (Class) iter.next();
	out.print(iface.getName());

	/* Print ", " if more remote interfaces follow. */
	if (iter.hasNext())
	  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(m.getDeclaringClass().getName() + ".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 " + stubclassname + "() {");
	ctrl.indent();
	out.print("super();");
	ctrl.unindent();
	out.println("}");
      }

    if (need12Stubs)
      {
	out.print("public " + stubclassname
	          + "(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 = fullclassname + "_Skel";
    String skelclassname = classname + "_Skel";
    fullskelname = (destination == null ? "" : destination + File.separator)
      + skelname.replace('.', File.separatorChar) + ".java";
    File file = new File(fullskelname);
    if (file.getParentFile() != null)
      file.getParentFile().mkdirs();
    ctrl =
      new TabbedWriter(new FileWriter(file));
    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 " + skelclassname);
    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);
    if (classpath != null)
      comp.setClasspath(classpath);
    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++;

	// Accept `--' options if they look long enough.
	if (arg.length() > 3 && arg.charAt(0) == '-' && arg.charAt(1) == '-')
	  arg = arg.substring(1);

	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"))
          {
            classpath = args[next];
            next++;
            StringTokenizer st =
              new StringTokenizer(classpath, File.pathSeparator);
            URL[] u = new URL[st.countTokens()];
            for (int i = 0; i < u.length; i++)
              {
                String path = st.nextToken();
                File f = new File(path);
                try
                  {
                    u[i] = f.toURL();
                  }
                catch (MalformedURLException mue)
                  {
                    error("malformed classpath component " + path);
                  }
              }
            loader = new URLClassLoader(u);
          }
	else if (arg.equals("-help"))
	  usage();
	else if (arg.equals("-version"))
	  {
	    System.out.println("rmic (" + System.getProperty("java.vm.name")
	                       + ") " + System.getProperty("java.vm.version"));
	    System.out.println();
	    System.out.println("Copyright 2006 Free Software Foundation, Inc.");
	    System.out.println("This is free software; see the source for copying conditions.  There is NO");
	    System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
	    System.exit(0);
	  }
	else if (arg.equals("-d"))
	  {
	    destination = args[next];
	    next++;
	  }
	else if (arg.charAt(1) == 'J')
	  {
	  }
	else
	  error("unrecognized option `" + arg + "'");
      }
  }

  private void findRemoteMethods() {
    List rmeths = new ArrayList();
    for (Class cur = clazz; cur != null; cur = cur.getSuperclass())
      {
        Class[] interfaces = cur.getInterfaces();
        for (int i = 0; i < interfaces.length; i++)
          {
            if (java.rmi.Remote.class.isAssignableFrom(interfaces[i]))
              {
                Class remoteInterface = interfaces[i];
                if (verbose)
                  System.out.println
                    ("[implements " + remoteInterface.getName() + "]");

                // check if the methods declare RemoteExceptions
                Method[] meths = remoteInterface.getMethods();
                for (int j = 0; j < meths.length; j++)
                  {
                    Method m = meths[j];
                    Class[] exs = m.getExceptionTypes();

                    boolean throwsRemote = false;
                    for (int k = 0; k < exs.length; k++)
                      {
                        if (exs[k].isAssignableFrom(RemoteException.class))
                          throwsRemote = true;
                      }

                    if (! throwsRemote)
                      {
                        logError("Method " + m
                                 + " does not throw a RemoteException");
                        continue;
                      }

                    rmeths.add(m);
                  }

                mRemoteInterfaces.add(remoteInterface);
              }
          }
      }

    // intersect exceptions for doubly inherited methods
    boolean[] skip = new boolean[rmeths.size()];
    for (int i = 0; i < skip.length; i++)
      skip[i] = false;
    List methrefs = new ArrayList();
    for (int i = 0; i < rmeths.size(); i++)
      {
        if (skip[i]) continue;
        Method current = (Method) rmeths.get(i);
        MethodRef ref = new MethodRef(current);
        for (int j = i+1; j < rmeths.size(); j++)
          {
            Method other = (Method) rmeths.get(j);
            if (ref.isMatch(other))
              {
                ref.intersectExceptions(other);
                skip[j] = true;
              }
          }
        methrefs.add(ref);
      }

    // Convert into a MethodRef array and sort them
    remotemethods = (MethodRef[])
      methrefs.toArray(new MethodRef[methrefs.size()]);
    Arrays.sort(remotemethods);
  }

/**
 * Prints an error to System.err and increases the error count.
 * @param theError
 */
  private void logError(String theError)
  {
    errorCount++;
    System.err.println("error:" + theError);
  }

  private static void error(String message)
  {
    System.err.println("rmic: " + message);
    System.err.println("Try `rmic --help' for more information.");
    System.exit(1);
  }

  private static void usage()
  {
    System.out.println("Usage: rmic [OPTION]... CLASS...\n" + "\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"
                       + "	-help			Print this help, then exit\n"
                       + "	-version		Print version number, then exit\n" + "\n"
                       + "  * Option currently ignored\n"
                       + "Long options can be used with `--option' form as well.");
    System.exit(0);
  }

  private static class MethodRef
    implements Comparable
  {
    Method meth;
    long hash;
    List exceptions;
    private String sig;

    MethodRef(Method m)
    {
      meth = m;
      sig = m.getName(); // XXX should be full signature used to compute hash
      hash = RMIHashes.getMethodHash(m);
      // add exceptions removing subclasses
      exceptions = removeSubclasses(m.getExceptionTypes());
    }

    public int compareTo(Object obj)
    {
      MethodRef that = (MethodRef) obj;
      int name = this.meth.getName().compareTo(that.meth.getName());
      if (name == 0) {
        return this.sig.compareTo(that.sig);
      }
      return name;
    }

    public boolean isMatch(Method m)
    {
      if (!meth.getName().equals(m.getName()))
        return false;

      Class[] params1 = meth.getParameterTypes();
      Class[] params2 = m.getParameterTypes();
      if (params1.length != params2.length)
        return false;

      for (int i = 0; i < params1.length; i++)
        if (!params1[i].equals(params2[i])) return false;

      return true;
    }

    private static List removeSubclasses(Class[] classes)
    {
      List list = new ArrayList();
      for (int i = 0; i < classes.length; i++)
        {
          Class candidate = classes[i];
          boolean add = true;
          for (int j = 0; j < classes.length; j++)
            {
              if (classes[j].equals(candidate))
                continue;
              else if (classes[j].isAssignableFrom(candidate))
                add = false;
            }
          if (add) list.add(candidate);
        }

      return list;
    }

    public void intersectExceptions(Method m)
    {
      List incoming = removeSubclasses(m.getExceptionTypes());

      List updated = new ArrayList();

      for (int i = 0; i < exceptions.size(); i++)
        {
          Class outer = (Class) exceptions.get(i);
          boolean addOuter = false;
          for (int j = 0; j < incoming.size(); j++)
            {
              Class inner = (Class) incoming.get(j);

              if (inner.equals(outer) || inner.isAssignableFrom(outer))
                addOuter = true;
              else if (outer.isAssignableFrom(inner))
                updated.add(inner);
            }

          if (addOuter)
            updated.add(outer);
        }

      exceptions = updated;
    }
  }
}
