Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / gnu / java / rmi / rmic / RMIC.java
blob0976cd279b2a275375b0da6b82d334212c7c4fb0
1 /* RMIC.java --
2 Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA.
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package gnu.java.rmi.rmic;
42 import gnu.java.rmi.server.RMIHashes;
44 import java.io.File;
45 import java.io.FileWriter;
46 import java.io.IOException;
47 import java.io.PrintWriter;
48 import java.lang.reflect.Method;
49 import java.rmi.RemoteException;
50 import java.util.Arrays;
51 import java.util.HashSet;
52 import java.util.Iterator;
53 import java.util.Set;
56 public class RMIC
58 private String[] args;
59 private int next;
60 private Exception exception;
61 private boolean keep = false;
62 private boolean need11Stubs = true;
63 private boolean need12Stubs = true;
64 private boolean compile = true;
65 private boolean verbose;
66 private String destination;
67 private PrintWriter out;
68 private TabbedWriter ctrl;
69 private Class clazz;
70 private String classname;
71 private String fullclassname;
72 private MethodRef[] remotemethods;
73 private String stubname;
74 private String skelname;
75 private int errorCount = 0;
76 private Class mRemoteInterface;
78 public RMIC(String[] a)
80 args = a;
83 public static void main(String[] args)
85 RMIC r = new RMIC(args);
86 if (r.run() == false)
88 Exception e = r.getException();
89 if (e != null)
90 e.printStackTrace();
91 else
92 System.exit(1);
96 public boolean run()
98 parseOptions();
99 if (next >= args.length)
100 error("no class names found");
101 for (int i = next; i < args.length; i++)
105 if (verbose)
106 System.out.println("[Processing class " + args[i] + ".class]");
107 processClass(args[i].replace(File.separatorChar, '.'));
109 catch (Exception e)
111 exception = e;
112 return (false);
115 return (true);
118 private boolean processClass(String classname) throws Exception
120 errorCount = 0;
121 analyzeClass(classname);
122 if (errorCount > 0)
123 System.exit(1);
124 generateStub();
125 if (need11Stubs)
126 generateSkel();
127 if (compile)
129 compile(stubname.replace('.', File.separatorChar) + ".java");
130 if (need11Stubs)
131 compile(skelname.replace('.', File.separatorChar) + ".java");
133 if (! keep)
135 (new File(stubname.replace('.', File.separatorChar) + ".java")).delete();
136 if (need11Stubs)
137 (new File(skelname.replace('.', File.separatorChar) + ".java"))
138 .delete();
140 return (true);
143 private void analyzeClass(String cname) throws Exception
145 if (verbose)
146 System.out.println("[analyze class " + cname + "]");
147 int p = cname.lastIndexOf('.');
148 if (p != -1)
149 classname = cname.substring(p + 1);
150 else
151 classname = cname;
152 fullclassname = cname;
154 HashSet rmeths = new HashSet();
155 findClass();
157 // get the remote interface
158 mRemoteInterface = getRemoteInterface(clazz);
159 if (mRemoteInterface == null)
160 return;
161 if (verbose)
162 System.out.println("[implements " + mRemoteInterface.getName() + "]");
164 // check if the methods of the remote interface declare RemoteExceptions
165 Method[] meths = mRemoteInterface.getDeclaredMethods();
166 for (int i = 0; i < meths.length; i++)
168 Class[] exceptions = meths[i].getExceptionTypes();
169 int index = 0;
170 for (; index < exceptions.length; index++)
172 if (exceptions[index].equals(RemoteException.class))
173 break;
175 if (index < exceptions.length)
176 rmeths.add(meths[i]);
177 else
178 logError("Method " + meths[i]
179 + " does not throw a java.rmi.RemoteException");
182 // Convert into a MethodRef array and sort them
183 remotemethods = new MethodRef[rmeths.size()];
184 int c = 0;
185 for (Iterator i = rmeths.iterator(); i.hasNext();)
186 remotemethods[c++] = new MethodRef((Method) i.next());
187 Arrays.sort(remotemethods);
190 public Exception getException()
192 return (exception);
195 private void findClass() throws ClassNotFoundException
197 clazz =
198 Class.forName(fullclassname, true, ClassLoader.getSystemClassLoader());
201 private void generateStub() throws IOException
203 stubname = fullclassname + "_Stub";
204 String stubclassname = classname + "_Stub";
205 ctrl =
206 new TabbedWriter(new FileWriter((destination == null ? ""
207 : destination
208 + File.separator)
209 + stubname.replace('.',
210 File.separatorChar)
211 + ".java"));
212 out = new PrintWriter(ctrl);
214 if (verbose)
215 System.out.println("[Generating class " + stubname + ".java]");
217 out.println("// Stub class generated by rmic - DO NOT EDIT!");
218 out.println();
219 if (fullclassname != classname)
221 String pname =
222 fullclassname.substring(0, fullclassname.lastIndexOf('.'));
223 out.println("package " + pname + ";");
224 out.println();
227 out.print("public final class " + stubclassname);
228 ctrl.indent();
229 out.println("extends java.rmi.server.RemoteStub");
231 // Output interfaces we implement
232 out.print("implements ");
233 /* Scan implemented interfaces, and only print remote interfaces. */
234 Class[] ifaces = clazz.getInterfaces();
235 Set remoteIfaces = new HashSet();
236 for (int i = 0; i < ifaces.length; i++)
238 Class iface = ifaces[i];
239 if (java.rmi.Remote.class.isAssignableFrom(iface))
240 remoteIfaces.add(iface);
242 Iterator iter = remoteIfaces.iterator();
243 while (iter.hasNext())
245 /* Print remote interface. */
246 Class iface = (Class) iter.next();
247 out.print(iface.getName());
249 /* Print ", " if more remote interfaces follow. */
250 if (iter.hasNext())
251 out.print(", ");
253 ctrl.unindent();
254 out.print("{");
255 ctrl.indent();
257 // UID
258 if (need12Stubs)
260 out.println("private static final long serialVersionUID = 2L;");
261 out.println();
264 // InterfaceHash - don't know how to calculate this - XXX
265 if (need11Stubs)
267 out.println("private static final long interfaceHash = "
268 + RMIHashes.getInterfaceHash(clazz) + "L;");
269 out.println();
270 if (need12Stubs)
272 out.println("private static boolean useNewInvoke;");
273 out.println();
276 // Operation table
277 out.print("private static final java.rmi.server.Operation[] operations = {");
279 ctrl.indent();
280 for (int i = 0; i < remotemethods.length; i++)
282 Method m = remotemethods[i].meth;
283 out.print("new java.rmi.server.Operation(\"");
284 out.print(getPrettyName(m.getReturnType()) + " ");
285 out.print(m.getName() + "(");
286 // Output signature
287 Class[] sig = m.getParameterTypes();
288 for (int j = 0; j < sig.length; j++)
290 out.print(getPrettyName(sig[j]));
291 if (j + 1 < sig.length)
292 out.print(", ");
294 out.print(")\")");
295 if (i + 1 < remotemethods.length)
296 out.println(",");
298 ctrl.unindent();
299 out.println("};");
300 out.println();
303 // Set of method references.
304 if (need12Stubs)
306 for (int i = 0; i < remotemethods.length; i++)
308 Method m = remotemethods[i].meth;
309 out.println("private static java.lang.reflect.Method $method_"
310 + m.getName() + "_" + i + ";");
313 // Initialize the methods references.
314 out.println();
315 out.print("static {");
316 ctrl.indent();
318 out.print("try {");
319 ctrl.indent();
321 if (need11Stubs)
323 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 });");
324 out.println("useNewInvoke = true;");
327 for (int i = 0; i < remotemethods.length; i++)
329 Method m = remotemethods[i].meth;
330 out.print("$method_" + m.getName() + "_" + i + " = ");
331 out.print(mRemoteInterface.getName() + ".class.getMethod(\""
332 + m.getName() + "\"");
333 out.print(", new java.lang.Class[] {");
334 // Output signature
335 Class[] sig = m.getParameterTypes();
336 for (int j = 0; j < sig.length; j++)
338 out.print(getPrettyName(sig[j]) + ".class");
339 if (j + 1 < sig.length)
340 out.print(", ");
342 out.println("});");
344 ctrl.unindent();
345 out.println("}");
346 out.print("catch (java.lang.NoSuchMethodException e) {");
347 ctrl.indent();
348 if (need11Stubs)
349 out.print("useNewInvoke = false;");
350 else
351 out.print("throw new java.lang.NoSuchMethodError(\"stub class initialization failed\");");
353 ctrl.unindent();
354 out.print("}");
356 ctrl.unindent();
357 out.println("}");
358 out.println();
361 // Constructors
362 if (need11Stubs)
364 out.print("public " + stubclassname + "() {");
365 ctrl.indent();
366 out.print("super();");
367 ctrl.unindent();
368 out.println("}");
371 if (need12Stubs)
373 out.print("public " + stubclassname
374 + "(java.rmi.server.RemoteRef ref) {");
375 ctrl.indent();
376 out.print("super(ref);");
377 ctrl.unindent();
378 out.println("}");
381 // Method implementations
382 for (int i = 0; i < remotemethods.length; i++)
384 Method m = remotemethods[i].meth;
385 Class[] sig = m.getParameterTypes();
386 Class returntype = m.getReturnType();
387 Class[] except = sortExceptions(m.getExceptionTypes());
389 out.println();
390 out.print("public " + getPrettyName(returntype) + " " + m.getName()
391 + "(");
392 for (int j = 0; j < sig.length; j++)
394 out.print(getPrettyName(sig[j]));
395 out.print(" $param_" + j);
396 if (j + 1 < sig.length)
397 out.print(", ");
399 out.print(") ");
400 out.print("throws ");
401 for (int j = 0; j < except.length; j++)
403 out.print(getPrettyName(except[j]));
404 if (j + 1 < except.length)
405 out.print(", ");
407 out.print(" {");
408 ctrl.indent();
410 out.print("try {");
411 ctrl.indent();
413 if (need12Stubs)
415 if (need11Stubs)
417 out.print("if (useNewInvoke) {");
418 ctrl.indent();
420 if (returntype != Void.TYPE)
421 out.print("java.lang.Object $result = ");
422 out.print("ref.invoke(this, $method_" + m.getName() + "_" + i
423 + ", ");
424 if (sig.length == 0)
425 out.print("null, ");
426 else
428 out.print("new java.lang.Object[] {");
429 for (int j = 0; j < sig.length; j++)
431 if (sig[j] == Boolean.TYPE)
432 out.print("new java.lang.Boolean($param_" + j + ")");
433 else if (sig[j] == Byte.TYPE)
434 out.print("new java.lang.Byte($param_" + j + ")");
435 else if (sig[j] == Character.TYPE)
436 out.print("new java.lang.Character($param_" + j + ")");
437 else if (sig[j] == Short.TYPE)
438 out.print("new java.lang.Short($param_" + j + ")");
439 else if (sig[j] == Integer.TYPE)
440 out.print("new java.lang.Integer($param_" + j + ")");
441 else if (sig[j] == Long.TYPE)
442 out.print("new java.lang.Long($param_" + j + ")");
443 else if (sig[j] == Float.TYPE)
444 out.print("new java.lang.Float($param_" + j + ")");
445 else if (sig[j] == Double.TYPE)
446 out.print("new java.lang.Double($param_" + j + ")");
447 else
448 out.print("$param_" + j);
449 if (j + 1 < sig.length)
450 out.print(", ");
452 out.print("}, ");
454 out.print(Long.toString(remotemethods[i].hash) + "L");
455 out.print(");");
457 if (returntype != Void.TYPE)
459 out.println();
460 out.print("return (");
461 if (returntype == Boolean.TYPE)
462 out.print("((java.lang.Boolean)$result).booleanValue()");
463 else if (returntype == Byte.TYPE)
464 out.print("((java.lang.Byte)$result).byteValue()");
465 else if (returntype == Character.TYPE)
466 out.print("((java.lang.Character)$result).charValue()");
467 else if (returntype == Short.TYPE)
468 out.print("((java.lang.Short)$result).shortValue()");
469 else if (returntype == Integer.TYPE)
470 out.print("((java.lang.Integer)$result).intValue()");
471 else if (returntype == Long.TYPE)
472 out.print("((java.lang.Long)$result).longValue()");
473 else if (returntype == Float.TYPE)
474 out.print("((java.lang.Float)$result).floatValue()");
475 else if (returntype == Double.TYPE)
476 out.print("((java.lang.Double)$result).doubleValue()");
477 else
478 out.print("(" + getPrettyName(returntype) + ")$result");
479 out.print(");");
482 if (need11Stubs)
484 ctrl.unindent();
485 out.println("}");
486 out.print("else {");
487 ctrl.indent();
491 if (need11Stubs)
493 out.println("java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, "
494 + i + ", interfaceHash);");
495 out.print("try {");
496 ctrl.indent();
497 out.print("java.io.ObjectOutput out = call.getOutputStream();");
498 for (int j = 0; j < sig.length; j++)
500 out.println();
501 if (sig[j] == Boolean.TYPE)
502 out.print("out.writeBoolean(");
503 else if (sig[j] == Byte.TYPE)
504 out.print("out.writeByte(");
505 else if (sig[j] == Character.TYPE)
506 out.print("out.writeChar(");
507 else if (sig[j] == Short.TYPE)
508 out.print("out.writeShort(");
509 else if (sig[j] == Integer.TYPE)
510 out.print("out.writeInt(");
511 else if (sig[j] == Long.TYPE)
512 out.print("out.writeLong(");
513 else if (sig[j] == Float.TYPE)
514 out.print("out.writeFloat(");
515 else if (sig[j] == Double.TYPE)
516 out.print("out.writeDouble(");
517 else
518 out.print("out.writeObject(");
519 out.print("$param_" + j + ");");
521 ctrl.unindent();
522 out.println("}");
523 out.print("catch (java.io.IOException e) {");
524 ctrl.indent();
525 out.print("throw new java.rmi.MarshalException(\"error marshalling arguments\", e);");
526 ctrl.unindent();
527 out.println("}");
528 out.println("ref.invoke(call);");
529 if (returntype != Void.TYPE)
530 out.println(getPrettyName(returntype) + " $result;");
531 out.print("try {");
532 ctrl.indent();
533 out.print("java.io.ObjectInput in = call.getInputStream();");
534 boolean needcastcheck = false;
535 if (returntype != Void.TYPE)
537 out.println();
538 out.print("$result = ");
539 if (returntype == Boolean.TYPE)
540 out.print("in.readBoolean();");
541 else if (returntype == Byte.TYPE)
542 out.print("in.readByte();");
543 else if (returntype == Character.TYPE)
544 out.print("in.readChar();");
545 else if (returntype == Short.TYPE)
546 out.print("in.readShort();");
547 else if (returntype == Integer.TYPE)
548 out.print("in.readInt();");
549 else if (returntype == Long.TYPE)
550 out.print("in.readLong();");
551 else if (returntype == Float.TYPE)
552 out.print("in.readFloat();");
553 else if (returntype == Double.TYPE)
554 out.print("in.readDouble();");
555 else
557 if (returntype != Object.class)
558 out.print("(" + getPrettyName(returntype) + ")");
559 else
560 needcastcheck = true;
561 out.print("in.readObject();");
563 out.println();
564 out.print("return ($result);");
566 ctrl.unindent();
567 out.println("}");
568 out.print("catch (java.io.IOException e) {");
569 ctrl.indent();
570 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
571 ctrl.unindent();
572 out.println("}");
573 if (needcastcheck)
575 out.print("catch (java.lang.ClassNotFoundException e) {");
576 ctrl.indent();
577 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
578 ctrl.unindent();
579 out.println("}");
581 out.print("finally {");
582 ctrl.indent();
583 out.print("ref.done(call);");
584 ctrl.unindent();
585 out.print("}");
587 if (need12Stubs && need11Stubs)
589 ctrl.unindent();
590 out.print("}");
594 ctrl.unindent();
595 out.print("}");
597 boolean needgeneral = true;
598 for (int j = 0; j < except.length; j++)
600 out.println();
601 out.print("catch (" + getPrettyName(except[j]) + " e) {");
602 ctrl.indent();
603 out.print("throw e;");
604 ctrl.unindent();
605 out.print("}");
606 if (except[j] == Exception.class)
607 needgeneral = false;
609 if (needgeneral)
611 out.println();
612 out.print("catch (java.lang.Exception e) {");
613 ctrl.indent();
614 out.print("throw new java.rmi.UnexpectedException(\"undeclared checked exception\", e);");
615 ctrl.unindent();
616 out.print("}");
619 ctrl.unindent();
620 out.print("}");
621 out.println();
624 ctrl.unindent();
625 out.println("}");
627 out.close();
630 private void generateSkel() throws IOException
632 skelname = fullclassname + "_Skel";
633 String skelclassname = classname + "_Skel";
634 ctrl =
635 new TabbedWriter(new FileWriter((destination == null ? ""
636 : destination
637 + File.separator)
638 + skelname.replace('.',
639 File.separatorChar)
640 + ".java"));
641 out = new PrintWriter(ctrl);
643 if (verbose)
644 System.out.println("[Generating class " + skelname + ".java]");
646 out.println("// Skel class generated by rmic - DO NOT EDIT!");
647 out.println();
648 if (fullclassname != classname)
650 String pname =
651 fullclassname.substring(0, fullclassname.lastIndexOf('.'));
652 out.println("package " + pname + ";");
653 out.println();
656 out.print("public final class " + skelclassname);
657 ctrl.indent();
659 // Output interfaces we implement
660 out.print("implements java.rmi.server.Skeleton");
662 ctrl.unindent();
663 out.print("{");
664 ctrl.indent();
666 // Interface hash - don't know how to calculate this - XXX
667 out.println("private static final long interfaceHash = "
668 + RMIHashes.getInterfaceHash(clazz) + "L;");
669 out.println();
671 // Operation table
672 out.print("private static final java.rmi.server.Operation[] operations = {");
674 ctrl.indent();
675 for (int i = 0; i < remotemethods.length; i++)
677 Method m = remotemethods[i].meth;
678 out.print("new java.rmi.server.Operation(\"");
679 out.print(getPrettyName(m.getReturnType()) + " ");
680 out.print(m.getName() + "(");
681 // Output signature
682 Class[] sig = m.getParameterTypes();
683 for (int j = 0; j < sig.length; j++)
685 out.print(getPrettyName(sig[j]));
686 if (j + 1 < sig.length)
687 out.print(", ");
689 out.print("\")");
690 if (i + 1 < remotemethods.length)
691 out.println(",");
693 ctrl.unindent();
694 out.println("};");
696 out.println();
698 // getOperations method
699 out.print("public java.rmi.server.Operation[] getOperations() {");
700 ctrl.indent();
701 out.print("return ((java.rmi.server.Operation[]) operations.clone());");
702 ctrl.unindent();
703 out.println("}");
705 out.println();
707 // Dispatch method
708 out.print("public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception {");
709 ctrl.indent();
711 out.print("if (opnum < 0) {");
712 ctrl.indent();
714 for (int i = 0; i < remotemethods.length; i++)
716 out.print("if (hash == " + Long.toString(remotemethods[i].hash)
717 + "L) {");
718 ctrl.indent();
719 out.print("opnum = " + i + ";");
720 ctrl.unindent();
721 out.println("}");
722 out.print("else ");
724 out.print("{");
725 ctrl.indent();
726 out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
727 ctrl.unindent();
728 out.print("}");
730 ctrl.unindent();
731 out.println("}");
732 out.print("else if (hash != interfaceHash) {");
733 ctrl.indent();
734 out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
735 ctrl.unindent();
736 out.println("}");
738 out.println();
740 out.println(fullclassname + " server = (" + fullclassname + ")obj;");
741 out.println("switch (opnum) {");
743 // Method dispatch
744 for (int i = 0; i < remotemethods.length; i++)
746 Method m = remotemethods[i].meth;
747 out.println("case " + i + ":");
748 out.print("{");
749 ctrl.indent();
751 Class[] sig = m.getParameterTypes();
752 for (int j = 0; j < sig.length; j++)
754 out.print(getPrettyName(sig[j]));
755 out.println(" $param_" + j + ";");
758 out.print("try {");
759 boolean needcastcheck = false;
760 ctrl.indent();
761 out.println("java.io.ObjectInput in = call.getInputStream();");
762 for (int j = 0; j < sig.length; j++)
764 out.print("$param_" + j + " = ");
765 if (sig[j] == Boolean.TYPE)
766 out.print("in.readBoolean();");
767 else if (sig[j] == Byte.TYPE)
768 out.print("in.readByte();");
769 else if (sig[j] == Character.TYPE)
770 out.print("in.readChar();");
771 else if (sig[j] == Short.TYPE)
772 out.print("in.readShort();");
773 else if (sig[j] == Integer.TYPE)
774 out.print("in.readInt();");
775 else if (sig[j] == Long.TYPE)
776 out.print("in.readLong();");
777 else if (sig[j] == Float.TYPE)
778 out.print("in.readFloat();");
779 else if (sig[j] == Double.TYPE)
780 out.print("in.readDouble();");
781 else
783 if (sig[j] != Object.class)
785 out.print("(" + getPrettyName(sig[j]) + ")");
786 needcastcheck = true;
788 out.print("in.readObject();");
790 out.println();
792 ctrl.unindent();
793 out.println("}");
794 out.print("catch (java.io.IOException e) {");
795 ctrl.indent();
796 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
797 ctrl.unindent();
798 out.println("}");
799 if (needcastcheck)
801 out.print("catch (java.lang.ClassCastException e) {");
802 ctrl.indent();
803 out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
804 ctrl.unindent();
805 out.println("}");
807 out.print("finally {");
808 ctrl.indent();
809 out.print("call.releaseInputStream();");
810 ctrl.unindent();
811 out.println("}");
813 Class returntype = m.getReturnType();
814 if (returntype != Void.TYPE)
815 out.print(getPrettyName(returntype) + " $result = ");
816 out.print("server." + m.getName() + "(");
817 for (int j = 0; j < sig.length; j++)
819 out.print("$param_" + j);
820 if (j + 1 < sig.length)
821 out.print(", ");
823 out.println(");");
825 out.print("try {");
826 ctrl.indent();
827 out.print("java.io.ObjectOutput out = call.getResultStream(true);");
828 if (returntype != Void.TYPE)
830 out.println();
831 if (returntype == Boolean.TYPE)
832 out.print("out.writeBoolean($result);");
833 else if (returntype == Byte.TYPE)
834 out.print("out.writeByte($result);");
835 else if (returntype == Character.TYPE)
836 out.print("out.writeChar($result);");
837 else if (returntype == Short.TYPE)
838 out.print("out.writeShort($result);");
839 else if (returntype == Integer.TYPE)
840 out.print("out.writeInt($result);");
841 else if (returntype == Long.TYPE)
842 out.print("out.writeLong($result);");
843 else if (returntype == Float.TYPE)
844 out.print("out.writeFloat($result);");
845 else if (returntype == Double.TYPE)
846 out.print("out.writeDouble($result);");
847 else
848 out.print("out.writeObject($result);");
850 ctrl.unindent();
851 out.println("}");
852 out.print("catch (java.io.IOException e) {");
853 ctrl.indent();
854 out.print("throw new java.rmi.MarshalException(\"error marshalling return\", e);");
855 ctrl.unindent();
856 out.println("}");
857 out.print("break;");
859 ctrl.unindent();
860 out.println("}");
861 out.println();
864 out.print("default:");
865 ctrl.indent();
866 out.print("throw new java.rmi.UnmarshalException(\"invalid method number\");");
867 ctrl.unindent();
868 out.print("}");
870 ctrl.unindent();
871 out.print("}");
873 ctrl.unindent();
874 out.println("}");
876 out.close();
879 private void compile(String name) throws Exception
881 Compiler comp = Compiler.getInstance();
882 if (verbose)
883 System.out.println("[Compiling class " + name + "]");
884 comp.setDestination(destination);
885 comp.compile(name);
888 private static String getPrettyName(Class cls)
890 StringBuffer str = new StringBuffer();
891 for (int count = 0;; count++)
893 if (! cls.isArray())
895 str.append(cls.getName());
896 for (; count > 0; count--)
897 str.append("[]");
898 return (str.toString());
900 cls = cls.getComponentType();
905 * Sort exceptions so the most general go last.
907 private Class[] sortExceptions(Class[] except)
909 for (int i = 0; i < except.length; i++)
911 for (int j = i + 1; j < except.length; j++)
913 if (except[i].isAssignableFrom(except[j]))
915 Class tmp = except[i];
916 except[i] = except[j];
917 except[j] = tmp;
921 return (except);
925 * Process the options until we find the first argument.
927 private void parseOptions()
929 for (;;)
931 if (next >= args.length || args[next].charAt(0) != '-')
932 break;
933 String arg = args[next];
934 next++;
936 // Accept `--' options if they look long enough.
937 if (arg.length() > 3 && arg.charAt(0) == '-' && arg.charAt(1) == '-')
938 arg = arg.substring(1);
940 if (arg.equals("-keep"))
941 keep = true;
942 else if (arg.equals("-keepgenerated"))
943 keep = true;
944 else if (arg.equals("-v1.1"))
946 need11Stubs = true;
947 need12Stubs = false;
949 else if (arg.equals("-vcompat"))
951 need11Stubs = true;
952 need12Stubs = true;
954 else if (arg.equals("-v1.2"))
956 need11Stubs = false;
957 need12Stubs = true;
959 else if (arg.equals("-g"))
962 else if (arg.equals("-depend"))
965 else if (arg.equals("-nowarn"))
968 else if (arg.equals("-verbose"))
969 verbose = true;
970 else if (arg.equals("-nocompile"))
971 compile = false;
972 else if (arg.equals("-classpath"))
973 next++;
974 else if (arg.equals("-help"))
975 usage();
976 else if (arg.equals("-version"))
978 System.out.println("rmic (" + System.getProperty("java.vm.name")
979 + ") " + System.getProperty("java.vm.version"));
980 System.out.println();
981 System.out.println("Copyright 2005 Free Software Foundation, Inc.");
982 System.out.println("This is free software; see the source for copying conditions. There is NO");
983 System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
984 System.exit(0);
986 else if (arg.equals("-d"))
988 destination = args[next];
989 next++;
991 else if (arg.charAt(1) == 'J')
994 else
995 error("unrecognized option `" + arg + "'");
1000 * Looks for the java.rmi.Remote interface that that is implemented by theClazz.
1001 * @param theClazz the class to look in
1002 * @return the Remote interface of theClazz or null if theClazz does not implement a Remote interface
1004 private Class getRemoteInterface(Class theClazz)
1006 Class[] interfaces = theClazz.getInterfaces();
1007 for (int i = 0; i < interfaces.length; i++)
1009 if (java.rmi.Remote.class.isAssignableFrom(interfaces[i]))
1010 return interfaces[i];
1012 logError("Class " + theClazz.getName()
1013 + " is not a remote object. It does not implement an interface that is a java.rmi.Remote-interface.");
1014 return null;
1018 * Prints an error to System.err and increases the error count.
1019 * @param theError
1021 private void logError(String theError)
1023 errorCount++;
1024 System.err.println("error:" + theError);
1027 private static void error(String message)
1029 System.err.println("rmic: " + message);
1030 System.err.println("Try `rmic --help' for more information.");
1031 System.exit(1);
1034 private static void usage()
1036 System.out.println("Usage: rmic [OPTION]... CLASS...\n" + "\n"
1037 + " -keep Don't delete any intermediate files\n"
1038 + " -keepgenerated Same as -keep\n"
1039 + " -v1.1 Java 1.1 style stubs only\n"
1040 + " -vcompat Java 1.1 & Java 1.2 stubs\n"
1041 + " -v1.2 Java 1.2 style stubs only\n"
1042 + " -g * Generated debugging information\n"
1043 + " -depend * Recompile out-of-date files\n"
1044 + " -nowarn * Suppress warning messages\n"
1045 + " -nocompile Don't compile the generated files\n"
1046 + " -verbose Output what's going on\n"
1047 + " -classpath <path> * Use given path as classpath\n"
1048 + " -d <directory> Specify where to place generated classes\n"
1049 + " -J<flag> * Pass flag to Java\n"
1050 + " -help Print this help, then exit\n"
1051 + " -version Print version number, then exit\n" + "\n"
1052 + " * Option currently ignored\n"
1053 + "Long options can be used with `--option' form as well.");
1054 System.exit(0);
1057 static class MethodRef
1058 implements Comparable
1060 Method meth;
1061 String sig;
1062 long hash;
1064 MethodRef(Method m)
1066 meth = m;
1067 // We match on the name - but what about overloading? - XXX
1068 sig = m.getName();
1069 hash = RMIHashes.getMethodHash(m);
1072 public int compareTo(Object obj)
1074 MethodRef that = (MethodRef) obj;
1075 return (this.sig.compareTo(that.sig));