001: /*
002: * Copyright (c) 1998-2000 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.iiop;
030:
031: import com.caucho.java.AbstractGenerator;
032: import com.caucho.server.util.CauchoSystem;
033: import com.caucho.vfs.MergePath;
034: import com.caucho.vfs.Path;
035:
036: import javax.ejb.EJBHome;
037: import javax.ejb.EJBObject;
038: import java.io.IOException;
039: import java.lang.reflect.Method;
040:
041: public class IiopStubCompiler extends AbstractGenerator {
042: private Class _cl;
043:
044: public IiopStubCompiler(Class cl) {
045: _cl = cl;
046:
047: String name = cl.getName();
048:
049: // XXX:
050: //name = "org.omg.stub." + name;
051:
052: int p = name.lastIndexOf('.');
053: if (p > 0) {
054: String pkg = name.substring(0, p);
055: String tail = name.substring(p + 1);
056: setFullClassName(pkg + "._" + tail + "_Stub");
057: } else
058: setFullClassName("_" + name + "_Stub");
059: }
060:
061: /**
062: * Starts generation of the Java code
063: */
064: public void generateJava() throws Exception {
065: printHeader();
066:
067: Method[] methods = _cl.getMethods();
068: for (int i = 0; i < methods.length; i++) {
069: Method method = methods[i];
070:
071: if (method.getDeclaringClass().isAssignableFrom(
072: EJBHome.class)
073: || method.getDeclaringClass().isAssignableFrom(
074: EJBObject.class))
075: continue;
076:
077: printMethod(method);
078: }
079:
080: printFooter();
081: }
082:
083: /**
084: * Prints the header
085: */
086: private void printHeader() throws IOException {
087: println("/*");
088: println(" * Generated by Resin-EJB IiopStubCompiler");
089: println(" */");
090: println();
091:
092: if (getPackageName() != null)
093: println("package " + getPackageName() + ";");
094:
095: println();
096: print("public class " + getClassName());
097: if (EJBHome.class.isAssignableFrom(_cl))
098: println(" extends com.caucho.iiop.client.IiopHomeStub");
099: else
100: println(" extends com.caucho.iiop.client.IiopStub");
101: println(" implements " + _cl.getName() + " {");
102: pushDepth();
103:
104: println("private static final String[] _type_ids = {");
105: println(" \"RMI:" + _cl.getName() + ":0000000000000000\"");
106: println("};");
107:
108: println();
109: println("public String[] _ids()");
110: println("{");
111: println(" return _type_ids;");
112: println("}");
113: }
114:
115: /**
116: * Prints a method
117: */
118: private void printMethod(Method method) throws IOException {
119: printMethodHeader(method);
120: println("{");
121: pushDepth();
122:
123: println("org.omg.CORBA_2_3.portable.OutputStream os = null;");
124: println("try {");
125: pushDepth();
126:
127: println("os = (org.omg.CORBA_2_3.portable.OutputStream) _request(\""
128: + method.getName() + "\", true);");
129:
130: Class[] args = method.getParameterTypes();
131: for (int i = 0; i < args.length; i++) {
132: printSetValue(args[i], "a" + i);
133: }
134:
135: println("org.omg.CORBA_2_3.portable.InputStream is;");
136: println("is = (org.omg.CORBA_2_3.portable.InputStream) _invoke(os);");
137:
138: Class returnType = method.getReturnType();
139:
140: if (returnType.equals(void.class)) {
141: } else {
142: print("return ");
143: printGetValue(returnType);
144: println(";");
145: }
146:
147: popDepth();
148: println("} catch (org.omg.CORBA.portable.ApplicationException e) {");
149: // XXX: handle types
150: println(" org.omg.CORBA_2_3.portable.InputStream in = (org.omg.CORBA_2_3.portable.InputStream) e.getInputStream();");
151: println(" String name = in.read_string();");
152: println(" Throwable ex = (Throwable) in.read_value();");
153: for (Class ex : method.getExceptionTypes()) {
154: println(" if (ex instanceof " + ex.getName() + ")");
155: println(" throw (" + ex.getName() + ") ex;");
156: }
157: println(" throw new java.rmi.RemoteException(ex.getMessage(), ex);");
158: println("} catch (Exception e) {");
159: println(" e.printStackTrace();");
160: println(" throw new java.rmi.RemoteException(e.getMessage(), e);");
161: println("}");
162:
163: popDepth();
164: println("}");
165: }
166:
167: private void printGetValue(Class type) throws IOException {
168: if (type.equals(boolean.class))
169: print("is.read_boolean()");
170: else if (type.equals(byte.class))
171: print("is.read_octet()");
172: else if (type.equals(short.class))
173: print("is.read_short()");
174: else if (type.equals(int.class))
175: print("is.read_long()");
176: else if (type.equals(long.class))
177: print("is.read_longlong()");
178: else if (type.equals(float.class))
179: print("is.read_float()");
180: else if (type.equals(double.class))
181: print("is.read_double()");
182: else if (type.equals(char.class))
183: print("is.read_wchar()");
184: else if (javax.ejb.EJBObject.class.isAssignableFrom(type)
185: || java.rmi.Remote.class.isAssignableFrom(type)) {
186: // Note that if sender/receiver have mismatched types, one
187: // possible result is a Java OOM
188: // ejb/114t
189: print("(");
190: printJavaClass(type);
191: print(") is.read_Object(");
192: printJavaClass(type);
193: print(".class)");
194: } else {
195: print("(");
196: printJavaClass(type);
197: print(") is.read_value(");
198: printJavaClass(type);
199: print(".class)");
200: }
201: }
202:
203: void printJavaClass(Class type) throws IOException {
204: if (type.isArray()) {
205: printJavaClass(type.getComponentType());
206: print("[]");
207: } else
208: print(type.getName());
209: }
210:
211: private void printSetValue(Class type, String value)
212: throws IOException {
213: if (type.equals(boolean.class))
214: println("os.write_boolean(" + value + ");");
215: else if (type.equals(byte.class))
216: println("os.write_octet(" + value + ");");
217: else if (type.equals(short.class))
218: println("os.write_short(" + value + ");");
219: else if (type.equals(int.class))
220: println("os.write_long(" + value + ");");
221: else if (type.equals(long.class))
222: println("os.write_longlong(" + value + ");");
223: else if (type.equals(float.class))
224: println("os.write_float(" + value + ");");
225: else if (type.equals(double.class))
226: println("os.write_double(" + value + ");");
227: else if (type.equals(char.class))
228: println("os.write_wchar(" + value + ");");
229: else
230: println("os.write_value((java.io.Serializable) " + value
231: + ");");
232: }
233:
234: /**
235: * Prints the footer
236: */
237: private void printFooter() throws IOException {
238: popDepth();
239: println("}");
240: }
241:
242: public static Class create(String className) throws Exception {
243: Class cl = CauchoSystem.loadClass(className);
244:
245: MergePath mergePath = new MergePath();
246: mergePath.addClassPath();
247:
248: Path classPath = mergePath.lookup(className.replace('.', '/')
249: + ".class");
250: classPath = ((MergePath) classPath).getBestPath();
251:
252: Path dir = classPath.getParent();
253: int i = 0;
254: while ((i = className.indexOf('.', i + 1)) >= 0) {
255: dir = dir.getParent();
256: }
257:
258: dir.mkdirs();
259:
260: IiopStubCompiler compiler = new IiopStubCompiler(cl);
261: compiler.setClassDir(dir);
262: Class gen = compiler.preload();
263: if (gen != null)
264: return gen;
265:
266: compiler.generate();
267:
268: return compiler.compile();
269: }
270:
271: /**
272: * Compiles the stub
273: */
274: public static void main(String[] argv) throws Exception {
275: String className = argv[0];
276:
277: System.out.println(create(className));
278: }
279: }
|