1:
38:
39:
40: package ;
41:
42: import ;
43:
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61:
62:
63: public class RMIC
64: {
65: private String[] args;
66: private int next;
67: private Exception exception;
68: private boolean keep = false;
69: private boolean need11Stubs = true;
70: private boolean need12Stubs = true;
71: private boolean compile = true;
72: private boolean verbose;
73: private String destination;
74: private PrintWriter out;
75: private TabbedWriter ctrl;
76: private Class clazz;
77: private String classname;
78: private String fullclassname;
79: private String fullstubname;
80: private String fullskelname;
81: private MethodRef[] remotemethods;
82: private String stubname;
83: private String skelname;
84: private ClassLoader loader;
85: private String classpath;
86: private int errorCount = 0;
87: private List mRemoteInterfaces;
88:
89: public RMIC(String[] a)
90: {
91: args = a;
92: }
93:
94: public static void main(String[] args)
95: {
96: RMIC r = new RMIC(args);
97: if (r.run() == false)
98: {
99: Exception e = r.getException();
100: if (e != null)
101: e.printStackTrace();
102: else
103: System.exit(1);
104: }
105: }
106:
107: public boolean run()
108: {
109: parseOptions();
110: if (next >= args.length)
111: error("no class names found");
112: for (int i = next; i < args.length; i++)
113: {
114: try
115: {
116: if (verbose)
117: System.out.println("[Processing class " + args[i] + ".class]");
118: processClass(args[i].replace(File.separatorChar, '.'));
119: }
120: catch (Exception e)
121: {
122: exception = e;
123: return (false);
124: }
125: }
126: return (true);
127: }
128:
129: private boolean processClass(String cls) throws Exception
130: {
131:
132: clazz = null;
133: classname = null;
134: fullclassname = null;
135: remotemethods = null;
136: stubname = null;
137: fullstubname = null;
138: skelname = null;
139: fullskelname = null;
140: mRemoteInterfaces = new ArrayList();
141:
142: errorCount = 0;
143:
144: analyzeClass(cls);
145:
146: if (errorCount > 0)
147: System.exit(1);
148: generateStub();
149: if (need11Stubs)
150: generateSkel();
151: if (compile)
152: {
153: compile(fullstubname);
154: if (need11Stubs)
155: compile(fullskelname);
156: }
157: if (! keep)
158: {
159: (new File(fullstubname)).delete();
160: if (need11Stubs)
161: (new File(fullskelname)).delete();
162: }
163: return (true);
164: }
165:
166: private void analyzeClass(String cname) throws Exception
167: {
168: if (verbose)
169: System.out.println("[analyze class " + cname + "]");
170: int p = cname.lastIndexOf('.');
171: if (p != -1)
172: classname = cname.substring(p + 1);
173: else
174: classname = cname;
175: fullclassname = cname;
176:
177: findClass();
178: findRemoteMethods();
179: }
180:
181: public Exception getException()
182: {
183: return (exception);
184: }
185:
186: private void findClass() throws ClassNotFoundException
187: {
188: try
189: {
190: ClassLoader cl = (loader == null
191: ? ClassLoader.getSystemClassLoader()
192: : loader);
193: clazz = Class.forName(fullclassname, false, cl);
194: }
195: catch (ClassNotFoundException cnfe)
196: {
197: System.err.println(fullclassname + " not found in " + classpath);
198: throw new RuntimeException(cnfe);
199: }
200:
201: if (! Remote.class.isAssignableFrom(clazz))
202: {
203: logError("Class " + clazz.getName() + " is not a remote object. "
204: + "It does not implement an interface that is a "
205: + "java.rmi.Remote-interface.");
206: throw new RuntimeException
207: ("Class " + clazz.getName() + " is not a remote object. "
208: + "It does not implement an interface that is a "
209: + "java.rmi.Remote-interface.");
210: }
211: }
212:
213: private void generateStub() throws IOException
214: {
215: stubname = fullclassname + "_Stub";
216: String stubclassname = classname + "_Stub";
217: fullstubname = (destination == null ? "" : destination + File.separator)
218: + stubname.replace('.', File.separatorChar) + ".java";
219: File file = new File(fullstubname);
220: if (file.getParentFile() != null)
221: file.getParentFile().mkdirs();
222: ctrl =
223: new TabbedWriter(new FileWriter(file));
224: out = new PrintWriter(ctrl);
225:
226: if (verbose)
227: System.out.println("[Generating class " + stubname + ".java]");
228:
229: out.println("// Stub class generated by rmic - DO NOT EDIT!");
230: out.println();
231: if (fullclassname != classname)
232: {
233: String pname =
234: fullclassname.substring(0, fullclassname.lastIndexOf('.'));
235: out.println("package " + pname + ";");
236: out.println();
237: }
238:
239: out.print("public final class " + stubclassname);
240: ctrl.indent();
241: out.println("extends java.rmi.server.RemoteStub");
242:
243:
244: out.print("implements ");
245: Iterator iter = mRemoteInterfaces.iterator();
246: while (iter.hasNext())
247: {
248:
249: Class iface = (Class) iter.next();
250: out.print(iface.getName());
251:
252:
253: if (iter.hasNext())
254: out.print(", ");
255: }
256: ctrl.unindent();
257: out.print("{");
258: ctrl.indent();
259:
260:
261: if (need12Stubs)
262: {
263: out.println("private static final long serialVersionUID = 2L;");
264: out.println();
265: }
266:
267:
268: if (need11Stubs)
269: {
270: out.println("private static final long interfaceHash = "
271: + RMIHashes.getInterfaceHash(clazz) + "L;");
272: out.println();
273: if (need12Stubs)
274: {
275: out.println("private static boolean useNewInvoke;");
276: out.println();
277: }
278:
279:
280: out.print("private static final java.rmi.server.Operation[] operations = {");
281:
282: ctrl.indent();
283: for (int i = 0; i < remotemethods.length; i++)
284: {
285: Method m = remotemethods[i].meth;
286: out.print("new java.rmi.server.Operation(\"");
287: out.print(getPrettyName(m.getReturnType()) + " ");
288: out.print(m.getName() + "(");
289:
290: Class[] sig = m.getParameterTypes();
291: for (int j = 0; j < sig.length; j++)
292: {
293: out.print(getPrettyName(sig[j]));
294: if (j + 1 < sig.length)
295: out.print(", ");
296: }
297: out.print(")\")");
298: if (i + 1 < remotemethods.length)
299: out.println(",");
300: }
301: ctrl.unindent();
302: out.println("};");
303: out.println();
304: }
305:
306:
307: if (need12Stubs)
308: {
309: for (int i = 0; i < remotemethods.length; i++)
310: {
311: Method m = remotemethods[i].meth;
312: out.println("private static java.lang.reflect.Method $method_"
313: + m.getName() + "_" + i + ";");
314: }
315:
316:
317: out.println();
318: out.print("static {");
319: ctrl.indent();
320:
321: out.print("try {");
322: ctrl.indent();
323:
324: if (need11Stubs)
325: {
326: 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 });");
327: out.println("useNewInvoke = true;");
328: }
329:
330: for (int i = 0; i < remotemethods.length; i++)
331: {
332: Method m = remotemethods[i].meth;
333: out.print("$method_" + m.getName() + "_" + i + " = ");
334: out.print(m.getDeclaringClass().getName() + ".class.getMethod(\""
335: + m.getName() + "\"");
336: out.print(", new java.lang.Class[] {");
337:
338: Class[] sig = m.getParameterTypes();
339: for (int j = 0; j < sig.length; j++)
340: {
341: out.print(getPrettyName(sig[j]) + ".class");
342: if (j + 1 < sig.length)
343: out.print(", ");
344: }
345: out.println("});");
346: }
347: ctrl.unindent();
348: out.println("}");
349: out.print("catch (java.lang.NoSuchMethodException e) {");
350: ctrl.indent();
351: if (need11Stubs)
352: out.print("useNewInvoke = false;");
353: else
354: out.print("throw new java.lang.NoSuchMethodError(\"stub class initialization failed\");");
355:
356: ctrl.unindent();
357: out.print("}");
358:
359: ctrl.unindent();
360: out.println("}");
361: out.println();
362: }
363:
364:
365: if (need11Stubs)
366: {
367: out.print("public " + stubclassname + "() {");
368: ctrl.indent();
369: out.print("super();");
370: ctrl.unindent();
371: out.println("}");
372: }
373:
374: if (need12Stubs)
375: {
376: out.print("public " + stubclassname
377: + "(java.rmi.server.RemoteRef ref) {");
378: ctrl.indent();
379: out.print("super(ref);");
380: ctrl.unindent();
381: out.println("}");
382: }
383:
384:
385: for (int i = 0; i < remotemethods.length; i++)
386: {
387: Method m = remotemethods[i].meth;
388: Class[] sig = m.getParameterTypes();
389: Class returntype = m.getReturnType();
390: Class[] except = sortExceptions(m.getExceptionTypes());
391:
392: out.println();
393: out.print("public " + getPrettyName(returntype) + " " + m.getName()
394: + "(");
395: for (int j = 0; j < sig.length; j++)
396: {
397: out.print(getPrettyName(sig[j]));
398: out.print(" $param_" + j);
399: if (j + 1 < sig.length)
400: out.print(", ");
401: }
402: out.print(") ");
403: out.print("throws ");
404: for (int j = 0; j < except.length; j++)
405: {
406: out.print(getPrettyName(except[j]));
407: if (j + 1 < except.length)
408: out.print(", ");
409: }
410: out.print(" {");
411: ctrl.indent();
412:
413: out.print("try {");
414: ctrl.indent();
415:
416: if (need12Stubs)
417: {
418: if (need11Stubs)
419: {
420: out.print("if (useNewInvoke) {");
421: ctrl.indent();
422: }
423: if (returntype != Void.TYPE)
424: out.print("java.lang.Object $result = ");
425: out.print("ref.invoke(this, $method_" + m.getName() + "_" + i
426: + ", ");
427: if (sig.length == 0)
428: out.print("null, ");
429: else
430: {
431: out.print("new java.lang.Object[] {");
432: for (int j = 0; j < sig.length; j++)
433: {
434: if (sig[j] == Boolean.TYPE)
435: out.print("new java.lang.Boolean($param_" + j + ")");
436: else if (sig[j] == Byte.TYPE)
437: out.print("new java.lang.Byte($param_" + j + ")");
438: else if (sig[j] == Character.TYPE)
439: out.print("new java.lang.Character($param_" + j + ")");
440: else if (sig[j] == Short.TYPE)
441: out.print("new java.lang.Short($param_" + j + ")");
442: else if (sig[j] == Integer.TYPE)
443: out.print("new java.lang.Integer($param_" + j + ")");
444: else if (sig[j] == Long.TYPE)
445: out.print("new java.lang.Long($param_" + j + ")");
446: else if (sig[j] == Float.TYPE)
447: out.print("new java.lang.Float($param_" + j + ")");
448: else if (sig[j] == Double.TYPE)
449: out.print("new java.lang.Double($param_" + j + ")");
450: else
451: out.print("$param_" + j);
452: if (j + 1 < sig.length)
453: out.print(", ");
454: }
455: out.print("}, ");
456: }
457: out.print(Long.toString(remotemethods[i].hash) + "L");
458: out.print(");");
459:
460: if (returntype != Void.TYPE)
461: {
462: out.println();
463: out.print("return (");
464: if (returntype == Boolean.TYPE)
465: out.print("((java.lang.Boolean)$result).booleanValue()");
466: else if (returntype == Byte.TYPE)
467: out.print("((java.lang.Byte)$result).byteValue()");
468: else if (returntype == Character.TYPE)
469: out.print("((java.lang.Character)$result).charValue()");
470: else if (returntype == Short.TYPE)
471: out.print("((java.lang.Short)$result).shortValue()");
472: else if (returntype == Integer.TYPE)
473: out.print("((java.lang.Integer)$result).intValue()");
474: else if (returntype == Long.TYPE)
475: out.print("((java.lang.Long)$result).longValue()");
476: else if (returntype == Float.TYPE)
477: out.print("((java.lang.Float)$result).floatValue()");
478: else if (returntype == Double.TYPE)
479: out.print("((java.lang.Double)$result).doubleValue()");
480: else
481: out.print("(" + getPrettyName(returntype) + ")$result");
482: out.print(");");
483: }
484:
485: if (need11Stubs)
486: {
487: ctrl.unindent();
488: out.println("}");
489: out.print("else {");
490: ctrl.indent();
491: }
492: }
493:
494: if (need11Stubs)
495: {
496: out.println("java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject)this, operations, "
497: + i + ", interfaceHash);");
498: out.print("try {");
499: ctrl.indent();
500: out.print("java.io.ObjectOutput out = call.getOutputStream();");
501: for (int j = 0; j < sig.length; j++)
502: {
503: out.println();
504: if (sig[j] == Boolean.TYPE)
505: out.print("out.writeBoolean(");
506: else if (sig[j] == Byte.TYPE)
507: out.print("out.writeByte(");
508: else if (sig[j] == Character.TYPE)
509: out.print("out.writeChar(");
510: else if (sig[j] == Short.TYPE)
511: out.print("out.writeShort(");
512: else if (sig[j] == Integer.TYPE)
513: out.print("out.writeInt(");
514: else if (sig[j] == Long.TYPE)
515: out.print("out.writeLong(");
516: else if (sig[j] == Float.TYPE)
517: out.print("out.writeFloat(");
518: else if (sig[j] == Double.TYPE)
519: out.print("out.writeDouble(");
520: else
521: out.print("out.writeObject(");
522: out.print("$param_" + j + ");");
523: }
524: ctrl.unindent();
525: out.println("}");
526: out.print("catch (java.io.IOException e) {");
527: ctrl.indent();
528: out.print("throw new java.rmi.MarshalException(\"error marshalling arguments\", e);");
529: ctrl.unindent();
530: out.println("}");
531: out.println("ref.invoke(call);");
532: if (returntype != Void.TYPE)
533: out.println(getPrettyName(returntype) + " $result;");
534: out.print("try {");
535: ctrl.indent();
536: out.print("java.io.ObjectInput in = call.getInputStream();");
537: boolean needcastcheck = false;
538: if (returntype != Void.TYPE)
539: {
540: out.println();
541: out.print("$result = ");
542: if (returntype == Boolean.TYPE)
543: out.print("in.readBoolean();");
544: else if (returntype == Byte.TYPE)
545: out.print("in.readByte();");
546: else if (returntype == Character.TYPE)
547: out.print("in.readChar();");
548: else if (returntype == Short.TYPE)
549: out.print("in.readShort();");
550: else if (returntype == Integer.TYPE)
551: out.print("in.readInt();");
552: else if (returntype == Long.TYPE)
553: out.print("in.readLong();");
554: else if (returntype == Float.TYPE)
555: out.print("in.readFloat();");
556: else if (returntype == Double.TYPE)
557: out.print("in.readDouble();");
558: else
559: {
560: if (returntype != Object.class)
561: out.print("(" + getPrettyName(returntype) + ")");
562: else
563: needcastcheck = true;
564: out.print("in.readObject();");
565: }
566: out.println();
567: out.print("return ($result);");
568: }
569: ctrl.unindent();
570: out.println("}");
571: out.print("catch (java.io.IOException e) {");
572: ctrl.indent();
573: out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
574: ctrl.unindent();
575: out.println("}");
576: if (needcastcheck)
577: {
578: out.print("catch (java.lang.ClassNotFoundException e) {");
579: ctrl.indent();
580: out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling return\", e);");
581: ctrl.unindent();
582: out.println("}");
583: }
584: out.print("finally {");
585: ctrl.indent();
586: out.print("ref.done(call);");
587: ctrl.unindent();
588: out.print("}");
589:
590: if (need12Stubs && need11Stubs)
591: {
592: ctrl.unindent();
593: out.print("}");
594: }
595: }
596:
597: ctrl.unindent();
598: out.print("}");
599:
600: boolean needgeneral = true;
601: for (int j = 0; j < except.length; j++)
602: {
603: out.println();
604: out.print("catch (" + getPrettyName(except[j]) + " e) {");
605: ctrl.indent();
606: out.print("throw e;");
607: ctrl.unindent();
608: out.print("}");
609: if (except[j] == Exception.class)
610: needgeneral = false;
611: }
612: if (needgeneral)
613: {
614: out.println();
615: out.print("catch (java.lang.Exception e) {");
616: ctrl.indent();
617: out.print("throw new java.rmi.UnexpectedException(\"undeclared checked exception\", e);");
618: ctrl.unindent();
619: out.print("}");
620: }
621:
622: ctrl.unindent();
623: out.print("}");
624: out.println();
625: }
626:
627: ctrl.unindent();
628: out.println("}");
629:
630: out.close();
631: }
632:
633: private void generateSkel() throws IOException
634: {
635: skelname = fullclassname + "_Skel";
636: String skelclassname = classname + "_Skel";
637: fullskelname = (destination == null ? "" : destination + File.separator)
638: + skelname.replace('.', File.separatorChar) + ".java";
639: File file = new File(fullskelname);
640: if (file.getParentFile() != null)
641: file.getParentFile().mkdirs();
642: ctrl =
643: new TabbedWriter(new FileWriter(file));
644: out = new PrintWriter(ctrl);
645:
646: if (verbose)
647: System.out.println("[Generating class " + skelname + ".java]");
648:
649: out.println("// Skel class generated by rmic - DO NOT EDIT!");
650: out.println();
651: if (fullclassname != classname)
652: {
653: String pname =
654: fullclassname.substring(0, fullclassname.lastIndexOf('.'));
655: out.println("package " + pname + ";");
656: out.println();
657: }
658:
659: out.print("public final class " + skelclassname);
660: ctrl.indent();
661:
662:
663: out.print("implements java.rmi.server.Skeleton");
664:
665: ctrl.unindent();
666: out.print("{");
667: ctrl.indent();
668:
669:
670: out.println("private static final long interfaceHash = "
671: + RMIHashes.getInterfaceHash(clazz) + "L;");
672: out.println();
673:
674:
675: out.print("private static final java.rmi.server.Operation[] operations = {");
676:
677: ctrl.indent();
678: for (int i = 0; i < remotemethods.length; i++)
679: {
680: Method m = remotemethods[i].meth;
681: out.print("new java.rmi.server.Operation(\"");
682: out.print(getPrettyName(m.getReturnType()) + " ");
683: out.print(m.getName() + "(");
684:
685: Class[] sig = m.getParameterTypes();
686: for (int j = 0; j < sig.length; j++)
687: {
688: out.print(getPrettyName(sig[j]));
689: if (j + 1 < sig.length)
690: out.print(", ");
691: }
692: out.print("\")");
693: if (i + 1 < remotemethods.length)
694: out.println(",");
695: }
696: ctrl.unindent();
697: out.println("};");
698:
699: out.println();
700:
701:
702: out.print("public java.rmi.server.Operation[] getOperations() {");
703: ctrl.indent();
704: out.print("return ((java.rmi.server.Operation[]) operations.clone());");
705: ctrl.unindent();
706: out.println("}");
707:
708: out.println();
709:
710:
711: out.print("public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash) throws java.lang.Exception {");
712: ctrl.indent();
713:
714: out.print("if (opnum < 0) {");
715: ctrl.indent();
716:
717: for (int i = 0; i < remotemethods.length; i++)
718: {
719: out.print("if (hash == " + Long.toString(remotemethods[i].hash)
720: + "L) {");
721: ctrl.indent();
722: out.print("opnum = " + i + ";");
723: ctrl.unindent();
724: out.println("}");
725: out.print("else ");
726: }
727: out.print("{");
728: ctrl.indent();
729: out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
730: ctrl.unindent();
731: out.print("}");
732:
733: ctrl.unindent();
734: out.println("}");
735: out.print("else if (hash != interfaceHash) {");
736: ctrl.indent();
737: out.print("throw new java.rmi.server.SkeletonMismatchException(\"interface hash mismatch\");");
738: ctrl.unindent();
739: out.println("}");
740:
741: out.println();
742:
743: out.println(fullclassname + " server = (" + fullclassname + ")obj;");
744: out.println("switch (opnum) {");
745:
746:
747: for (int i = 0; i < remotemethods.length; i++)
748: {
749: Method m = remotemethods[i].meth;
750: out.println("case " + i + ":");
751: out.print("{");
752: ctrl.indent();
753:
754: Class[] sig = m.getParameterTypes();
755: for (int j = 0; j < sig.length; j++)
756: {
757: out.print(getPrettyName(sig[j]));
758: out.println(" $param_" + j + ";");
759: }
760:
761: out.print("try {");
762: boolean needcastcheck = false;
763: ctrl.indent();
764: out.println("java.io.ObjectInput in = call.getInputStream();");
765: for (int j = 0; j < sig.length; j++)
766: {
767: out.print("$param_" + j + " = ");
768: if (sig[j] == Boolean.TYPE)
769: out.print("in.readBoolean();");
770: else if (sig[j] == Byte.TYPE)
771: out.print("in.readByte();");
772: else if (sig[j] == Character.TYPE)
773: out.print("in.readChar();");
774: else if (sig[j] == Short.TYPE)
775: out.print("in.readShort();");
776: else if (sig[j] == Integer.TYPE)
777: out.print("in.readInt();");
778: else if (sig[j] == Long.TYPE)
779: out.print("in.readLong();");
780: else if (sig[j] == Float.TYPE)
781: out.print("in.readFloat();");
782: else if (sig[j] == Double.TYPE)
783: out.print("in.readDouble();");
784: else
785: {
786: if (sig[j] != Object.class)
787: {
788: out.print("(" + getPrettyName(sig[j]) + ")");
789: needcastcheck = true;
790: }
791: out.print("in.readObject();");
792: }
793: out.println();
794: }
795: ctrl.unindent();
796: out.println("}");
797: out.print("catch (java.io.IOException e) {");
798: ctrl.indent();
799: out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
800: ctrl.unindent();
801: out.println("}");
802: if (needcastcheck)
803: {
804: out.print("catch (java.lang.ClassCastException e) {");
805: ctrl.indent();
806: out.print("throw new java.rmi.UnmarshalException(\"error unmarshalling arguments\", e);");
807: ctrl.unindent();
808: out.println("}");
809: }
810: out.print("finally {");
811: ctrl.indent();
812: out.print("call.releaseInputStream();");
813: ctrl.unindent();
814: out.println("}");
815:
816: Class returntype = m.getReturnType();
817: if (returntype != Void.TYPE)
818: out.print(getPrettyName(returntype) + " $result = ");
819: out.print("server." + m.getName() + "(");
820: for (int j = 0; j < sig.length; j++)
821: {
822: out.print("$param_" + j);
823: if (j + 1 < sig.length)
824: out.print(", ");
825: }
826: out.println(");");
827:
828: out.print("try {");
829: ctrl.indent();
830: out.print("java.io.ObjectOutput out = call.getResultStream(true);");
831: if (returntype != Void.TYPE)
832: {
833: out.println();
834: if (returntype == Boolean.TYPE)
835: out.print("out.writeBoolean($result);");
836: else if (returntype == Byte.TYPE)
837: out.print("out.writeByte($result);");
838: else if (returntype == Character.TYPE)
839: out.print("out.writeChar($result);");
840: else if (returntype == Short.TYPE)
841: out.print("out.writeShort($result);");
842: else if (returntype == Integer.TYPE)
843: out.print("out.writeInt($result);");
844: else if (returntype == Long.TYPE)
845: out.print("out.writeLong($result);");
846: else if (returntype == Float.TYPE)
847: out.print("out.writeFloat($result);");
848: else if (returntype == Double.TYPE)
849: out.print("out.writeDouble($result);");
850: else
851: out.print("out.writeObject($result);");
852: }
853: ctrl.unindent();
854: out.println("}");
855: out.print("catch (java.io.IOException e) {");
856: ctrl.indent();
857: out.print("throw new java.rmi.MarshalException(\"error marshalling return\", e);");
858: ctrl.unindent();
859: out.println("}");
860: out.print("break;");
861:
862: ctrl.unindent();
863: out.println("}");
864: out.println();
865: }
866:
867: out.print("default:");
868: ctrl.indent();
869: out.print("throw new java.rmi.UnmarshalException(\"invalid method number\");");
870: ctrl.unindent();
871: out.print("}");
872:
873: ctrl.unindent();
874: out.print("}");
875:
876: ctrl.unindent();
877: out.println("}");
878:
879: out.close();
880: }
881:
882: private void compile(String name) throws Exception
883: {
884: Compiler comp = Compiler.getInstance();
885: if (verbose)
886: System.out.println("[Compiling class " + name + "]");
887: comp.setDestination(destination);
888: if (classpath != null)
889: comp.setClasspath(classpath);
890: comp.compile(name);
891: }
892:
893: private static String getPrettyName(Class cls)
894: {
895: StringBuffer str = new StringBuffer();
896: for (int count = 0;; count++)
897: {
898: if (! cls.isArray())
899: {
900: str.append(cls.getName());
901: for (; count > 0; count--)
902: str.append("[]");
903: return (str.toString());
904: }
905: cls = cls.getComponentType();
906: }
907: }
908:
909:
912: private Class[] sortExceptions(Class[] except)
913: {
914: for (int i = 0; i < except.length; i++)
915: {
916: for (int j = i + 1; j < except.length; j++)
917: {
918: if (except[i].isAssignableFrom(except[j]))
919: {
920: Class tmp = except[i];
921: except[i] = except[j];
922: except[j] = tmp;
923: }
924: }
925: }
926: return (except);
927: }
928:
929:
932: private void parseOptions()
933: {
934: for (;;)
935: {
936: if (next >= args.length || args[next].charAt(0) != '-')
937: break;
938: String arg = args[next];
939: next++;
940:
941:
942: if (arg.length() > 3 && arg.charAt(0) == '-' && arg.charAt(1) == '-')
943: arg = arg.substring(1);
944:
945: if (arg.equals("-keep"))
946: keep = true;
947: else if (arg.equals("-keepgenerated"))
948: keep = true;
949: else if (arg.equals("-v1.1"))
950: {
951: need11Stubs = true;
952: need12Stubs = false;
953: }
954: else if (arg.equals("-vcompat"))
955: {
956: need11Stubs = true;
957: need12Stubs = true;
958: }
959: else if (arg.equals("-v1.2"))
960: {
961: need11Stubs = false;
962: need12Stubs = true;
963: }
964: else if (arg.equals("-g"))
965: {
966: }
967: else if (arg.equals("-depend"))
968: {
969: }
970: else if (arg.equals("-nowarn"))
971: {
972: }
973: else if (arg.equals("-verbose"))
974: verbose = true;
975: else if (arg.equals("-nocompile"))
976: compile = false;
977: else if (arg.equals("-classpath"))
978: {
979: classpath = args[next];
980: next++;
981: StringTokenizer st =
982: new StringTokenizer(classpath, File.pathSeparator);
983: URL[] u = new URL[st.countTokens()];
984: for (int i = 0; i < u.length; i++)
985: {
986: String path = st.nextToken();
987: File f = new File(path);
988: try
989: {
990: u[i] = f.toURL();
991: }
992: catch (MalformedURLException mue)
993: {
994: error("malformed classpath component " + path);
995: }
996: }
997: loader = new URLClassLoader(u);
998: }
999: else if (arg.equals("-help"))
1000: usage();
1001: else if (arg.equals("-version"))
1002: {
1003: System.out.println("rmic (" + System.getProperty("java.vm.name")
1004: + ") " + System.getProperty("java.vm.version"));
1005: System.out.println();
1006: System.out.println("Copyright 2006 Free Software Foundation, Inc.");
1007: System.out.println("This is free software; see the source for copying conditions. There is NO");
1008: System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
1009: System.exit(0);
1010: }
1011: else if (arg.equals("-d"))
1012: {
1013: destination = args[next];
1014: next++;
1015: }
1016: else if (arg.charAt(1) == 'J')
1017: {
1018: }
1019: else
1020: error("unrecognized option `" + arg + "'");
1021: }
1022: }
1023:
1024: private void findRemoteMethods() {
1025: List rmeths = new ArrayList();
1026: for (Class cur = clazz; cur != null; cur = cur.getSuperclass())
1027: {
1028: Class[] interfaces = cur.getInterfaces();
1029: for (int i = 0; i < interfaces.length; i++)
1030: {
1031: if (java.rmi.Remote.class.isAssignableFrom(interfaces[i]))
1032: {
1033: Class remoteInterface = interfaces[i];
1034: if (verbose)
1035: System.out.println
1036: ("[implements " + remoteInterface.getName() + "]");
1037:
1038:
1039: Method[] meths = remoteInterface.getMethods();
1040: for (int j = 0; j < meths.length; j++)
1041: {
1042: Method m = meths[j];
1043: Class[] exs = m.getExceptionTypes();
1044:
1045: boolean throwsRemote = false;
1046: for (int k = 0; k < exs.length; k++)
1047: {
1048: if (exs[k].isAssignableFrom(RemoteException.class))
1049: throwsRemote = true;
1050: }
1051:
1052: if (! throwsRemote)
1053: {
1054: logError("Method " + m
1055: + " does not throw a RemoteException");
1056: continue;
1057: }
1058:
1059: rmeths.add(m);
1060: }
1061:
1062: mRemoteInterfaces.add(remoteInterface);
1063: }
1064: }
1065: }
1066:
1067:
1068: boolean[] skip = new boolean[rmeths.size()];
1069: for (int i = 0; i < skip.length; i++)
1070: skip[i] = false;
1071: List methrefs = new ArrayList();
1072: for (int i = 0; i < rmeths.size(); i++)
1073: {
1074: if (skip[i]) continue;
1075: Method current = (Method) rmeths.get(i);
1076: MethodRef ref = new MethodRef(current);
1077: for (int j = i+1; j < rmeths.size(); j++)
1078: {
1079: Method other = (Method) rmeths.get(j);
1080: if (ref.isMatch(other))
1081: {
1082: ref.intersectExceptions(other);
1083: skip[j] = true;
1084: }
1085: }
1086: methrefs.add(ref);
1087: }
1088:
1089:
1090: remotemethods = (MethodRef[])
1091: methrefs.toArray(new MethodRef[methrefs.size()]);
1092: Arrays.sort(remotemethods);
1093: }
1094:
1095:
1099: private void logError(String theError)
1100: {
1101: errorCount++;
1102: System.err.println("error:" + theError);
1103: }
1104:
1105: private static void error(String message)
1106: {
1107: System.err.println("rmic: " + message);
1108: System.err.println("Try `rmic --help' for more information.");
1109: System.exit(1);
1110: }
1111:
1112: private static void usage()
1113: {
1114: System.out.println("Usage: rmic [OPTION]... CLASS...\n" + "\n"
1115: + " -keep Don't delete any intermediate files\n"
1116: + " -keepgenerated Same as -keep\n"
1117: + " -v1.1 Java 1.1 style stubs only\n"
1118: + " -vcompat Java 1.1 & Java 1.2 stubs\n"
1119: + " -v1.2 Java 1.2 style stubs only\n"
1120: + " -g * Generated debugging information\n"
1121: + " -depend * Recompile out-of-date files\n"
1122: + " -nowarn * Suppress warning messages\n"
1123: + " -nocompile Don't compile the generated files\n"
1124: + " -verbose Output what's going on\n"
1125: + " -classpath <path> * Use given path as classpath\n"
1126: + " -d <directory> Specify where to place generated classes\n"
1127: + " -J<flag> * Pass flag to Java\n"
1128: + " -help Print this help, then exit\n"
1129: + " -version Print version number, then exit\n" + "\n"
1130: + " * Option currently ignored\n"
1131: + "Long options can be used with `--option' form as well.");
1132: System.exit(0);
1133: }
1134:
1135: private static class MethodRef
1136: implements Comparable
1137: {
1138: Method meth;
1139: long hash;
1140: List exceptions;
1141: private String sig;
1142:
1143: MethodRef(Method m)
1144: {
1145: meth = m;
1146: sig = m.getName();
1147: hash = RMIHashes.getMethodHash(m);
1148:
1149: exceptions = removeSubclasses(m.getExceptionTypes());
1150: }
1151:
1152: public int compareTo(Object obj)
1153: {
1154: MethodRef that = (MethodRef) obj;
1155: int name = this.meth.getName().compareTo(that.meth.getName());
1156: if (name == 0) {
1157: return this.sig.compareTo(that.sig);
1158: }
1159: return name;
1160: }
1161:
1162: public boolean isMatch(Method m)
1163: {
1164: if (!meth.getName().equals(m.getName()))
1165: return false;
1166:
1167: Class[] params1 = meth.getParameterTypes();
1168: Class[] params2 = m.getParameterTypes();
1169: if (params1.length != params2.length)
1170: return false;
1171:
1172: for (int i = 0; i < params1.length; i++)
1173: if (!params1[i].equals(params2[i])) return false;
1174:
1175: return true;
1176: }
1177:
1178: private static List removeSubclasses(Class[] classes)
1179: {
1180: List list = new ArrayList();
1181: for (int i = 0; i < classes.length; i++)
1182: {
1183: Class candidate = classes[i];
1184: boolean add = true;
1185: for (int j = 0; j < classes.length; j++)
1186: {
1187: if (classes[j].equals(candidate))
1188: continue;
1189: else if (classes[j].isAssignableFrom(candidate))
1190: add = false;
1191: }
1192: if (add) list.add(candidate);
1193: }
1194:
1195: return list;
1196: }
1197:
1198: public void intersectExceptions(Method m)
1199: {
1200: List incoming = removeSubclasses(m.getExceptionTypes());
1201:
1202: List updated = new ArrayList();
1203:
1204: for (int i = 0; i < exceptions.size(); i++)
1205: {
1206: Class outer = (Class) exceptions.get(i);
1207: boolean addOuter = false;
1208: for (int j = 0; j < incoming.size(); j++)
1209: {
1210: Class inner = (Class) incoming.get(j);
1211:
1212: if (inner.equals(outer) || inner.isAssignableFrom(outer))
1213: addOuter = true;
1214: else if (outer.isAssignableFrom(inner))
1215: updated.add(inner);
1216: }
1217:
1218: if (addOuter)
1219: updated.add(outer);
1220: }
1221:
1222: exceptions = updated;
1223: }
1224: }
1225: }