dain        2005/06/20 21:22:13

  Added:       modules/core/src/java/org/openejb/corba/compiler
                        IiopOperation.java PortableStubCompiler.java
                        PortableStubGenerator.java
  Log:

  Moved portable stub compiler from geronimo interop
  
  Revision  Changes    Path
  1.1                  
openejb/modules/core/src/java/org/openejb/corba/compiler/IiopOperation.java
  
  Index: IiopOperation.java
  ===================================================================
  /**
   * Redistribution and use of this software and associated documentation
   * ("Software"), with or without modification, are permitted provided
   * that the following conditions are met:
   *
   * 1. Redistributions of source code must retain copyright
   *    statements and notices.  Redistributions must also contain a
   *    copy of this document.
   *
   * 2. Redistributions in binary form must reproduce the
   *    above copyright notice, this list of conditions and the
   *    following disclaimer in the documentation and/or other
   *    materials provided with the distribution.
   *
   * 3. The name "OpenEJB" must not be used to endorse or promote
   *    products derived from this Software without prior written
   *    permission of The OpenEJB Group.  For written permission,
   *    please contact [EMAIL PROTECTED]
   *
   * 4. Products derived from this Software may not be called "OpenEJB"
   *    nor may "OpenEJB" appear in their names without prior written
   *    permission of The OpenEJB Group. OpenEJB is a registered
   *    trademark of The OpenEJB Group.
   *
   * 5. Due credit should be given to the OpenEJB Project
   *    (http://openejb.sf.net/).
   *
   * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
   *
   * $Id: IiopOperation.java,v 1.1 2005/06/21 01:22:13 dain Exp $
   */
  package org.openejb.corba.compiler;
  
  import java.lang.reflect.Method;
  
  /**
   * @version $Rev$ $Date: 2005/06/21 01:22:13 $
   */
  public class IiopOperation {
      private final String name;
      private final Method method;
  
      public IiopOperation(String name, Method method) {
          assert name != null;
          assert method != null;
          this.method = method;
          this.name = name;
      }
  
      public String getName() {
          return name;
      }
  
      public Method getMethod() {
          return method;
      }
  
      public int hashCode() {
          return name.hashCode();
      }
  
      public boolean equals(Object other) {
          if (other instanceof IiopOperation) {
              IiopOperation iiopOperation = (IiopOperation) other;
              return name.equals(iiopOperation.name);
          }
          return false;
      }
  }
  
  
  
  1.1                  
openejb/modules/core/src/java/org/openejb/corba/compiler/PortableStubCompiler.java
  
  Index: PortableStubCompiler.java
  ===================================================================
  /**
   * Redistribution and use of this software and associated documentation
   * ("Software"), with or without modification, are permitted provided
   * that the following conditions are met:
   *
   * 1. Redistributions of source code must retain copyright
   *    statements and notices.  Redistributions must also contain a
   *    copy of this document.
   *
   * 2. Redistributions in binary form must reproduce the
   *    above copyright notice, this list of conditions and the
   *    following disclaimer in the documentation and/or other
   *    materials provided with the distribution.
   *
   * 3. The name "OpenEJB" must not be used to endorse or promote
   *    products derived from this Software without prior written
   *    permission of The OpenEJB Group.  For written permission,
   *    please contact [EMAIL PROTECTED]
   *
   * 4. Products derived from this Software may not be called "OpenEJB"
   *    nor may "OpenEJB" appear in their names without prior written
   *    permission of The OpenEJB Group. OpenEJB is a registered
   *    trademark of The OpenEJB Group.
   *
   * 5. Due credit should be given to the OpenEJB Project
   *    (http://openejb.sf.net/).
   *
   * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
   *
   * $Id: PortableStubCompiler.java,v 1.1 2005/06/21 01:22:13 dain Exp $
   */
  package org.openejb.corba.compiler;
  
  import java.io.Serializable;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.rmi.RemoteException;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  import org.apache.geronimo.interop.generator.GenException;
  import org.apache.geronimo.interop.generator.GenOptions;
  import org.apache.geronimo.interop.generator.JCatchStatement;
  import org.apache.geronimo.interop.generator.JClass;
  import org.apache.geronimo.interop.generator.JCodeStatement;
  import org.apache.geronimo.interop.generator.JExpression;
  import org.apache.geronimo.interop.generator.JField;
  import org.apache.geronimo.interop.generator.JIfStatement;
  import org.apache.geronimo.interop.generator.JLocalVariable;
  import org.apache.geronimo.interop.generator.JMethod;
  import org.apache.geronimo.interop.generator.JPackage;
  import org.apache.geronimo.interop.generator.JParameter;
  import org.apache.geronimo.interop.generator.JReturnType;
  import org.apache.geronimo.interop.generator.JTryCatchFinallyStatement;
  import org.apache.geronimo.interop.generator.JTryStatement;
  import org.apache.geronimo.interop.generator.JType;
  import org.apache.geronimo.interop.generator.JVariable;
  import org.apache.geronimo.interop.generator.JavaGenerator;
  import org.omg.CORBA.SystemException;
  import org.omg.CORBA.portable.ApplicationException;
  import org.omg.CORBA.portable.IDLEntity;
  import org.omg.CORBA.portable.RemarshalException;
  
  public class PortableStubCompiler {
      private HashMap packages = new HashMap();
      private final GenOptions genOptions;
      private final ClassLoader classLoader;
  
      public PortableStubCompiler(GenOptions genOptions, ClassLoader 
classLoader) {
          this.genOptions = genOptions;
          this.classLoader = classLoader;
      }
  
      public void generate() throws GenException {
          JavaGenerator javaGenerator = new JavaGenerator(genOptions);
  
          List interfaces = genOptions.getInterfaces();
          for (Iterator iterator = interfaces.iterator(); iterator.hasNext();) {
              String interfaceName = (String) iterator.next();
  
              // load the interface class
              Class interfaceClass = null;
              try {
                  interfaceClass = classLoader.loadClass(interfaceName);
              } catch (Exception ex) {
                  throw new GenException("Generate Stubs Failed:", ex);
              }
  
              // get the package object
              String packageName = getPackageName(interfaceName);
              if (packageName.length() > 0) {
                  packageName = "org.omg.stub." + packageName;
              } else {
                  packageName = "org.omg.stub";
              }
              JPackage jpackage = (JPackage) packages.get(packageName);
              if (jpackage == null) {
                  jpackage = new JPackage(packageName);
                  packages.put(packageName, jpackage);
              }
  
              // build the basic class object
              String className = "_" + getClassName(interfaceClass) + "_Stub";
              JClass jclass = jpackage.newClass(className);
              jclass.addImport("javax.rmi.CORBA", "Stub");
              jclass.setExtends("Stub");
              jclass.addImplements(interfaceClass.getName());
              jclass.addImplements("org.openejb.corba.ClientContextHolder");
  
              addClientContextMethods(jclass);
              addIdsMethod(jclass, interfaceName);
  
              IiopOperation[] iiopOperations = 
createIiopOperations(interfaceClass);
              for (int i = 0; iiopOperations != null && i < 
iiopOperations.length; i++) {
                  addMethod(iiopOperations[i], jclass);
              }
          }
  
          for (Iterator iterator = packages.entrySet().iterator(); 
iterator.hasNext();) {
              Map.Entry entry = (Map.Entry) iterator.next();
              String packageName = (String) entry.getKey();
              JPackage jpackage = (JPackage) entry.getValue();
  
              System.out.println("Generating Package: " + packageName);
              javaGenerator.generate(jpackage);
          }
      }
  
      private static String getClassName(Class type) {
          if (type.isArray()) {
              throw new IllegalArgumentException("type is an array: " + type);
          }
  
          // get the classname
          String typeName = type.getName();
          int endIndex = typeName.lastIndexOf('.');
          if (endIndex < 0) {
              return typeName;
          }
          return typeName.substring(endIndex + 1);
      }
  
      private static String getPackageName(String interfaceName) {
          int endIndex = interfaceName.lastIndexOf('.');
          if (endIndex < 0) {
              return "";
          }
          return interfaceName.substring(0, endIndex);
      }
  
      public static Method[] getAllMethods(Class intfClass) {
          LinkedList methods = new LinkedList();
  
          LinkedList stack = new LinkedList();
          stack.addFirst(intfClass);
  
          Set visited = new HashSet();
          while (!stack.isEmpty()) {
              Class intf = (Class) stack.removeFirst();
              methods.addAll(Arrays.asList(intf.getDeclaredMethods()));
              visited.add(intf);
  
              Class myInterfaces[] = intfClass.getInterfaces();
              for (int i = 0; i < myInterfaces.length; i++) {
                  Class myInterface = myInterfaces[i];
                  if (!visited.contains(myInterface)) {
                      stack.addFirst(myInterface);
                  }
              }
          }
  
          return (Method[]) methods.toArray(new Method[methods.size()]);
      }
  
      public static IiopOperation[] createIiopOperations(Class intfClass) {
          Method[] methods = getAllMethods(intfClass);
  
          // index the methods by name... used to determine which methods are 
overloaded
          HashMap overloadedMethods = new HashMap(methods.length);
          for (int i = 0; i < methods.length; i++) {
              String methodName = methods[i].getName();
              List methodList = (List) overloadedMethods.get(methodName);
              if (methodList == null) {
                  methodList = new LinkedList();
                  overloadedMethods.put(methodName, methodList);
              }
              methodList.add(methods[i]);
          }
  
          // index the methods by lower case name... used to determine which 
methods differ only by case
          HashMap caseCollisionMethods = new HashMap(methods.length);
          for (int i = 0; i < methods.length; i++) {
              String lowerCaseMethodName = methods[i].getName().toLowerCase();
              Set methodSet = (Set) 
caseCollisionMethods.get(lowerCaseMethodName);
              if (methodSet == null) {
                  methodSet = new HashSet();
                  caseCollisionMethods.put(lowerCaseMethodName, methodSet);
              }
              methodSet.add(methods[i].getName());
          }
  
          String className = getClassName(intfClass);
          List overloadList = new ArrayList(methods.length);
          for (int i = 0; i < methods.length; i++) {
              Method method = methods[i];
  
              String iiopName = method.getName();
  
              if (((Set) 
caseCollisionMethods.get(method.getName().toLowerCase())).size() > 1) {
                  iiopName += upperCaseIndexString(iiopName);
              }
  
              // if we have a leading underscore prepend with J
              if (iiopName.charAt(0) == '_') {
                  iiopName = "J" + iiopName;
              }
  
              // if this is an overloaded method append the parameter string
              if (((List) overloadedMethods.get(method.getName())).size() > 1) {
                  iiopName += 
buildOverloadParameterString(method.getParameterTypes());
              }
  
              // if we have a leading underscore prepend with J
              iiopName = replace(iiopName, '$', "U0024");
  
              // if we have matched a keyword prepend with an underscore
              if (keywords.contains(iiopName.toLowerCase())) {
                  iiopName = "_" + iiopName;
              }
  
              // if the name is the same as the class name, append an underscore
              if (iiopName.equalsIgnoreCase(className)) {
                  iiopName += "_";
              }
  
              overloadList.add(new IiopOperation(iiopName, method));
          }
  
          return (IiopOperation[]) overloadList.toArray(new 
IiopOperation[overloadList.size()]);
      }
  
      private static String upperCaseIndexString(String iiopName) {
          StringBuffer stringBuffer = new StringBuffer();
          for (int i = 0; i < iiopName.length(); i++) {
              char c = iiopName.charAt(i);
              if (Character.isUpperCase(c)) {
                  stringBuffer.append('_').append(i);
              }
          }
          return stringBuffer.toString();
      }
  
      public static String replace(String source, char oldChar, String 
newString) {
          StringBuffer stringBuffer = new StringBuffer(source.length());
          for (int i = 0; i < source.length(); i++) {
              char c = source.charAt(i);
              if (c == oldChar) {
                  stringBuffer.append(newString);
              } else {
                  stringBuffer.append(c);
              }
          }
          return stringBuffer.toString();
      }
  
      public static String buildOverloadParameterString(Class[] parameterTypes) 
{
          String name = "";
          if (parameterTypes.length ==0) {
              name += "__";
          } else {
              for (int i = 0; i < parameterTypes.length; i++) {
                  Class parameterType = parameterTypes[i];
                  name += buildOverloadParameterString(parameterType);
              }
          }
          return name.replace('.', '_');
      }
  
      public static String buildOverloadParameterString(Class parameterType) {
          String name = "_";
  
          int arrayDimensions = 0;
          while (parameterType.isArray()) {
              arrayDimensions++;
              parameterType = parameterType.getComponentType();
          }
  
          // arrays start with org_omg_boxedRMI_
          if (arrayDimensions > 0) {
              name += "_org_omg_boxedRMI";
          }
  
          // IDLEntity types must be prefixed with org_omg_boxedIDL_
          if (IDLEntity.class.isAssignableFrom(parameterType)) {
              name += "_org_omg_boxedIDL";
          }
  
          // add package... some types have special mappings in corba
          String packageName = (String) 
specialTypePackages.get(parameterType.getName());
          if (packageName == null) {
              packageName = getPackageName(parameterType.getName());
          }
          if (packageName.length() > 0) {
              name += "_" + packageName;
          }
  
          // arrays now contain a dimension indicator
          if (arrayDimensions > 0) {
              name += "_" + "seq" + arrayDimensions;
          }
  
          // add the class name
          String className = (String) 
specialTypeNames.get(parameterType.getName());
          if (className == null) {
              className = buildClassName(parameterType);
          }
          name += "_" + className;
  
          return name;
      }
  
      private static String buildClassName(Class type) {
          if (type.isArray()) {
              throw new IllegalArgumentException("type is an array: " + type);
          }
  
          // get the classname
          String typeName = type.getName();
          int endIndex = typeName.lastIndexOf('.');
          if (endIndex < 0) {
              return typeName;
          }
          StringBuffer className = new StringBuffer(typeName.substring(endIndex 
+ 1));
  
          // for innerclasses replace the $ separator with two underscores
          // we can't just blindly replace all $ characters since class names 
can contain the $ character
          if (type.getDeclaringClass() != null) {
              String declaringClassName = 
getClassName(type.getDeclaringClass());
              assert className.toString().startsWith(declaringClassName + "$");
              className.replace(declaringClassName.length(), 
declaringClassName.length() + 1, "__");
          }
  
          // if we have a leading underscore prepend with J
          if (className.charAt(0) == '_') {
              className.insert(0, "J");
          }
          return className.toString();
      }
  
      private void addMethod(JClass jclass, String iiopMethodName, JReturnType 
jreturnType, String name, JParameter[] jparameters, Class[] exceptions) {
          //
          // Method Template:
          //
          // if (!Util.isLocal(this)) {
          //     org.openejb.corba.ClientContext saved = 
org.openejb.corba.ClientContextManager.getClientContext();
          //     try {
          //         org.omg.CORBA_2_3.portable.InputStream in = null;
          //         try {
          //             org.omg.CORBA_2_3.portable.OutputStream out =
          //                 (org.omg.CORBA_2_3.portable.OutputStream)
          //                 
_request("passAndReturnCheese__org_apache_geronimo_interop_rmi_iiop_compiler_Cheese",
 true);
          //             out.write_value((Serializable)arg0,Cheese.class);
          //             in = 
(org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
          //
          //             Object result = javax.rmi.PortableRemoteObject.narrow( 
_input.read_Object(), Cheese.class );
          //             if (result instanceof 
org.openejb.corba.ClientContextHolder) {
          //                 
((org.openejb.corba.ClientContextHolder)result).setClientContext(_context);
          //             }
          //             return (Cheese) result;
          //         } catch (ApplicationException ex) {
          //             in = (org.omg.CORBA_2_3.portable.InputStream) 
ex.getInputStream();
          //             String id = in.read_string();
          //             throw new UnexpectedException(id);
          //         } catch (RemarshalException ex) {
          //             return passAndReturnCheese(arg0);
          //         } finally {
          //             _releaseReply(in);
          //         }
          //     } catch (SystemException ex) {
          //         throw Util.mapSystemException(ex);
          //     }
          // } else {
          //     ServantObject so = 
_servant_preinvoke("passAndReturnCheese__org_apache_geronimo_interop_rmi_iiop_compiler_Cheese",Foo.class);
          //     if (so == null) {
          //         return passAndReturnCheese(arg0);
          //     }
          //     try {
          //         Cheese arg0Copy = (Cheese) Util.copyObject(arg0,_orb());
          //         Cheese result = 
((Foo)so.servant).passAndReturnCheese(arg0Copy);
          //         return (Cheese)Util.copyObject(result,_orb());
          //     } catch (Throwable ex) {
          //         Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
          //         throw Util.wrapException(exCopy);
          //     } finally {
          //         _servant_postinvoke(so);
          //     }
          // }
  
          JMethod jmethod = jclass.newMethod(jreturnType, name, jparameters, 
exceptions);
  
          JVariable saved = 
jmethod.newLocalVariable(org.openejb.corba.ClientContext.class, "saved", new 
JExpression(new JCodeStatement(
                  
"org.openejb.corba.ClientContextManager.getClientContext()")));
  
  
          JTryCatchFinallyStatement outerTryCatchFinally = new 
JTryCatchFinallyStatement();
          jmethod.addStatement(outerTryCatchFinally);
          JTryStatement outerTry = outerTryCatchFinally.getTryStatement();
  
          JLocalVariable inVar = 
outerTry.newLocalVariable(org.omg.CORBA_2_3.portable.InputStream.class,
                  "in",
                  new JExpression(new JCodeStatement("null")));
  
          outerTry.addStatement(new 
JCodeStatement("org.openejb.corba.ClientContextManager.setClientContext(_context);"));
  
          JTryCatchFinallyStatement innterTryCatchFinally = new 
JTryCatchFinallyStatement();
          outerTry.addStatement(innterTryCatchFinally);
          JTryStatement innerTry = innterTryCatchFinally.getTryStatement();
  
          JLocalVariable outVar = 
innerTry.newLocalVariable(org.omg.CORBA_2_3.portable.OutputStream.class,
                  "out",
                  new JExpression(new JCodeStatement("(" + 
org.omg.CORBA_2_3.portable.OutputStream.class.getName() + ") _request(\"" + 
iiopMethodName + "\", true)")));
  
          // Write the variables
          for (int i = 0; i < jparameters.length; i++) {
              JParameter jparameter = jparameters[i];
  
              String writeMethod = getWriteMethod(jparameter);
              String writeCall;
              if (writeMethod != null) {
                  writeCall = writeMethod + "( " + jparameter.getName() + " )";
              } else {
                  String cast = "";
                  if 
(!Serializable.class.isAssignableFrom(jparameter.getType())) {
                      cast = "(java.io.Serializable)";
                  }
                  writeCall = "write_value(" + cast + jparameter.getName() + ", 
" + jparameter.getTypeDecl() + ".class)";
              }
  
              innerTry.addStatement(new JCodeStatement(outVar.getName() + "." + 
writeCall + ";"));
          }
  
          // invoke the method
          String invoke = "_invoke(" + outVar.getName() + ");";
          if (jreturnType.getType() != Void.TYPE) {
              invoke = inVar.getName() + " = (" + inVar.getTypeDecl() + ")" + 
invoke;
          }
          innerTry.addStatement(new JCodeStatement(invoke));
  
          // read the return value
          if (jreturnType.getType() != Void.TYPE) {
              String readMethod = getReadMethod(jreturnType);
              if (readMethod != null) {
                  String readCall = inVar.getName() + "." + readMethod + "()";
                  innerTry.addStatement(new JCodeStatement("return " + readCall 
+ ";"));
              } else {
                  // Object result = javax.rmi.PortableRemoteObject.narrow( 
_input.read_Object(), Cheese.class );
                  // if (result instanceof 
org.openejb.corba.ClientContextHolder) {
                  //     
((org.openejb.corba.ClientContextHolder)result).setClientContext(_context);
                  // }
                  // return (Cheese) result;
  //                String readCall = "(" + jreturnType.getTypeDecl() + ")" + 
inVar.getName() + ".read_value( " + jreturnType.getTypeDecl() + ".class)";
  
                  // can not use a local variable here since the java generator 
will reorder the fields
                  String resultName = "result";
                  innerTry.addStatement(new JCodeStatement("Object " + 
resultName + " = " +
                          "javax.rmi.PortableRemoteObject.narrow(" + 
inVar.getName() + ".read_Object(), " + jreturnType.getTypeDecl() + ".class);"
                  ));
  
                  JIfStatement jif = new JIfStatement(new JExpression(new 
JCodeStatement(resultName + " instanceof 
org.openejb.corba.ClientContextHolder")));
                  jif.addStatement(new 
JCodeStatement("((org.openejb.corba.ClientContextHolder)" + resultName + 
").setClientContext(_context);"));
                  innerTry.addStatement(jif);
  
                  innerTry.addStatement(new JCodeStatement("return (" + 
jreturnType.getTypeDecl() + ") " + resultName + ";"));
              }
          }
  
          JVariable exVar = new JVariable(ApplicationException.class, "ex");
          JCatchStatement jcatchStatement = 
innterTryCatchFinally.newCatch(exVar);
  
          jcatchStatement.addStatement(new JCodeStatement(inVar.getName() + " = 
(" + inVar.getTypeDecl() + ") " + exVar.getName() + ".getInputStream();"));
          JLocalVariable idVar = jcatchStatement.newLocalVariable(String.class,
                  "id",
                  new JExpression(new JCodeStatement(inVar.getName() + 
".read_string()")));
  //        if 
(id.equals("IDL:org/apache/geronimo/interop/rmi/iiop/compiler/other/BlahEx:1.0"))
 {
  //            throw (BlahException) in.read_value(BlahException.class);
  //        }
  //        if 
(id.equals("IDL:org/apache/geronimo/interop/rmi/iiop/compiler/BooEx:1.0")) {
  //            throw (BooException) in.read_value(BooException.class);
  //        }
          for (int i = 0; i < exceptions.length; i++) {
              Class exception = exceptions[i];
              if (RemoteException.class.isAssignableFrom(exception) ||
                      RuntimeException.class.isAssignableFrom(exception) ) {
                  continue;
              }
              String exceptionName = exception.getName().replace('.', '/');
              if (exceptionName.endsWith("Exception")) {
                  exceptionName = exceptionName.substring(0, 
exceptionName.length() - "Exception".length());
              }
              exceptionName += "Ex";
              JIfStatement jif = new JIfStatement(new JExpression(new 
JCodeStatement(idVar.getName() + ".equals(\"IDL:" + exceptionName + 
":1.0\")")));
              jif.addStatement(new JCodeStatement("throw (" + 
exception.getName() + ") in.read_value(" + exception.getName() + ".class);"));
              jcatchStatement.addStatement(jif);
  
          }
          jcatchStatement.addStatement(new JCodeStatement("throw new 
java.rmi.UnexpectedException(" + idVar.getName() + ");"));
  
          //         } catch (RemarshalException ex) {
          //             return passAndReturnCheese(arg0);
          exVar = new JVariable(RemarshalException.class, "ex");
          jcatchStatement = innterTryCatchFinally.newCatch(exVar);
  
          String remarshal = name + "(";
          for (int i = 0; i < jparameters.length; i++) {
              JParameter jparameter = jparameters[i];
              if (i > 0) {
                  remarshal += ", ";
              }
              remarshal += jparameter.getName();
          }
          remarshal += ");";
          if (jreturnType.getType() != Void.TYPE) {
              remarshal = "return " + remarshal;
          }
          jcatchStatement.addStatement(new JCodeStatement(remarshal));
  
          //         } finally {
          //             _releaseReply(in);
          innterTryCatchFinally.addFinallyStatement(new 
JCodeStatement("org.openejb.corba.ClientContextManager.setClientContext(" + 
saved.getName() + ");"));
          innterTryCatchFinally.addFinallyStatement(new 
JCodeStatement("_releaseReply(" + inVar.getName() + ");"));
  
          //     } catch (SystemException ex) {
          //         throw Util.mapSystemException(ex);
          exVar = new JVariable(SystemException.class, "ex");
          jcatchStatement = outerTryCatchFinally.newCatch(exVar);
          jcatchStatement.addStatement(new JCodeStatement("throw 
javax.rmi.CORBA.Util.mapSystemException(" + exVar.getName() + ");"));
      }
  
      private void addClientContextMethods(JClass jclass) {
          //
          // Method Template:
          //
          // private org.openejb.corba.ClientContext _context;
          //
          // public org.openejb.corba.ClientContext getClientContext() {
          //     return _context;
          // }
          //
          // public void setClientContext(org.openejb.corba.ClientContext 
context) {
          //     _context = context;
          // }
  
          JField typesField = 
jclass.newField(org.openejb.corba.ClientContext.class, "_context");
          typesField.setModifiers(Modifier.PRIVATE);
  
          JMethod getterMethod = jclass.newMethod(new 
JReturnType(org.openejb.corba.ClientContext.class), "getClientContext", null, 
null);
          getterMethod.addStatement(new JCodeStatement("return " + 
typesField.getName() + ";"));
  
          JParameter jparameter = new 
JParameter(org.openejb.corba.ClientContext.class, typesField.getName());
          JMethod setterMethod = jclass.newMethod(new JReturnType(Void.TYPE), 
"setClientContext", new JParameter[] {jparameter}, null);
          setterMethod.addStatement(new JCodeStatement("this." + 
typesField.getName() + " = " + jparameter.getName() +  ";"));
      }
  
      private void addIdsMethod(JClass jclass, String interfaceName) {
          //
          // Method Template:
          //
          // private static final String[] _type_ids = {
          //     "RMI:org.openejb.corba.compiler.Foo:0000000000000000"
          // };
          //
          // public String[] getIds()
          // {
          //     return _type_ids;
          // }
          //
  
          JField typesField = jclass.newField(String[].class, "_type_ids", new 
JExpression(new JCodeStatement("{ \"RMI:" + interfaceName + 
":0000000000000000\" }")));
          typesField.setModifiers(Modifier.PRIVATE | Modifier.STATIC | 
Modifier.FINAL);
  
          JMethod jmethod = jclass.newMethod(new JReturnType(String[].class), 
"_ids", null, null);
          jmethod.addStatement(new JCodeStatement("return _type_ids;"));
      }
  
  
      private void addMethod(IiopOperation iiopOperation, JClass jclass) {
          Method method = iiopOperation.getMethod();
  
          JReturnType jreturnType = new JReturnType(method.getReturnType());
  
          Class[] parameterTypes = method.getParameterTypes();
          JParameter[] jparameters = new JParameter[parameterTypes.length];
          for (int i = 0; i < parameterTypes.length; i++) {
              jparameters[i] = new JParameter(parameterTypes[i], "arg" + i);
          }
  
          addMethod(jclass,
                  iiopOperation.getName(),
                  jreturnType,
                  method.getName(),
                  jparameters,
                  method.getExceptionTypes());
      }
  
      private static final Map readMethods;
      private static final Map writeMethods;
      private static final Map specialTypeNames;
      private static final Map specialTypePackages;
      private static final Set keywords;
  
      static {
          readMethods = new HashMap();
          readMethods.put("boolean", "read_boolean");
          readMethods.put("char", "read_wchar");
          readMethods.put("byte", "read_octet");
          readMethods.put("short", "read_short");
          readMethods.put("int", "read_long");
          readMethods.put("long", "read_longlong");
          readMethods.put("float", "read_float");
          readMethods.put("double", "read_double");
          readMethods.put("org.omg.CORBA.Object", "read_Object");
  
          writeMethods = new HashMap();
          writeMethods.put("boolean", "write_boolean");
          writeMethods.put("char", "write_wchar");
          writeMethods.put("byte", "write_octet");
          writeMethods.put("short", "write_short");
          writeMethods.put("int", "write_long");
          writeMethods.put("long", "write_longlong");
          writeMethods.put("float", "write_float");
          writeMethods.put("double", "write_double");
          writeMethods.put("org.omg.CORBA.Object", "write_Object");
  
          specialTypeNames = new HashMap();
          specialTypeNames.put("boolean", "boolean");
          specialTypeNames.put("char", "wchar");
          specialTypeNames.put("byte", "octet");
          specialTypeNames.put("short", "short");
          specialTypeNames.put("int", "long");
          specialTypeNames.put("long", "long_long");
          specialTypeNames.put("float", "float");
          specialTypeNames.put("double", "double");
          specialTypeNames.put("java.lang.Class", "ClassDesc");
          specialTypeNames.put("java.lang.String", "WStringValue");
          specialTypeNames.put("org.omg.CORBA.Object", "Object");
  
          specialTypePackages = new HashMap();
          specialTypePackages.put("boolean", "");
          specialTypePackages.put("char", "");
          specialTypePackages.put("byte", "");
          specialTypePackages.put("short", "");
          specialTypePackages.put("int", "");
          specialTypePackages.put("long", "");
          specialTypePackages.put("float", "");
          specialTypePackages.put("double", "");
          specialTypePackages.put("java.lang.Class", "javax.rmi.CORBA");
          specialTypePackages.put("java.lang.String", "CORBA");
          specialTypePackages.put("org.omg.CORBA.Object", "");
  
          keywords = new HashSet();
          keywords.add("abstract");
          keywords.add("any");
          keywords.add("attribute");
          keywords.add("boolean");
          keywords.add("case");
          keywords.add("char");
          keywords.add("const");
          keywords.add("context");
          keywords.add("custom");
          keywords.add("default");
          keywords.add("double");
          keywords.add("enum");
          keywords.add("exception");
          keywords.add("factory");
          keywords.add("false");
          keywords.add("fixed");
          keywords.add("float");
          keywords.add("in");
          keywords.add("inout");
          keywords.add("interface");
          keywords.add("long");
          keywords.add("module");
          keywords.add("native");
          keywords.add("object");
          keywords.add("octet");
          keywords.add("oneway");
          keywords.add("out");
          keywords.add("private");
          keywords.add("public");
          keywords.add("raises");
          keywords.add("readonly");
          keywords.add("sequence");
          keywords.add("short");
          keywords.add("string");
          keywords.add("struct");
          keywords.add("supports");
          keywords.add("switch");
          keywords.add("true");
          keywords.add("truncatable");
          keywords.add("typedef");
          keywords.add("union");
          keywords.add("unsigned");
          keywords.add("valuebase");
          keywords.add("valuetype");
          keywords.add("void");
          keywords.add("wchar");
          keywords.add("wstring");
      }
  
      protected String getWriteMethod(JVariable jvariable) {
          if (jvariable != null) {
              return (String) writeMethods.get(jvariable.getTypeDecl());
          }
          return null;
      }
  
      protected String getReadMethod(JType jtype) {
          if (jtype != null) {
              return (String) readMethods.get(jtype.getTypeDecl());
          }
          return null;
      }
  
  }
  
  
  
  1.1                  
openejb/modules/core/src/java/org/openejb/corba/compiler/PortableStubGenerator.java
  
  Index: PortableStubGenerator.java
  ===================================================================
  /**
   * Redistribution and use of this software and associated documentation
   * ("Software"), with or without modification, are permitted provided
   * that the following conditions are met:
   *
   * 1. Redistributions of source code must retain copyright
   *    statements and notices.  Redistributions must also contain a
   *    copy of this document.
   *
   * 2. Redistributions in binary form must reproduce the
   *    above copyright notice, this list of conditions and the
   *    following disclaimer in the documentation and/or other
   *    materials provided with the distribution.
   *
   * 3. The name "OpenEJB" must not be used to endorse or promote
   *    products derived from this Software without prior written
   *    permission of The OpenEJB Group.  For written permission,
   *    please contact [EMAIL PROTECTED]
   *
   * 4. Products derived from this Software may not be called "OpenEJB"
   *    nor may "OpenEJB" appear in their names without prior written
   *    permission of The OpenEJB Group. OpenEJB is a registered
   *    trademark of The OpenEJB Group.
   *
   * 5. Due credit should be given to the OpenEJB Project
   *    (http://openejb.sf.net/).
   *
   * THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   * THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
   *
   * $Id: PortableStubGenerator.java,v 1.1 2005/06/21 01:22:13 dain Exp $
   */
  package org.openejb.corba.compiler;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Properties;
  import java.util.Set;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.geronimo.gbean.GBeanInfo;
  import org.apache.geronimo.gbean.GBeanInfoBuilder;
  import org.apache.geronimo.gbean.GBeanLifecycle;
  import org.apache.geronimo.interop.generator.GenOptions;
  import org.openejb.corba.compiler.PortableStubCompiler;
  import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
  import org.apache.geronimo.system.main.ToolsJarHack;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.taskdefs.Jar;
  import org.openejb.util.FileUtils;
  import org.openejb.util.JarUtils;
  
  
  /**
   * @version $Revision: 1.1 $ $Date: 2005/06/21 01:22:13 $
   */
  public class PortableStubGenerator implements StubGenerator, GBeanLifecycle {
      private static Log log = LogFactory.getLog(PortableStubGenerator.class);
  
      private boolean verbose;
      private Properties props = new Properties();
      private Compiler compiler;
      private boolean saveStubCode;
  
      public boolean isVerbose() {
          return verbose;
      }
  
      public void setVerbose(boolean verbose) {
          this.verbose = verbose;
      }
  
      public Properties getProps() {
          return props;
      }
  
      public void setProps(Properties props) {
          this.props = props;
      }
  
      public Compiler getCompiler() {
          return compiler;
      }
  
      public void setCompiler(Compiler compiler) {
          this.compiler = compiler;
      }
  
      public boolean isSaveStubCode() {
          return saveStubCode;
      }
  
      public void setSaveStubCode(boolean saveStubCode) {
          this.saveStubCode = saveStubCode;
      }
  
      public void generateStubs(Set interfaces, File destination, ClassLoader 
classLoader) throws CompilerException {
          ClassLoader savedLoader = 
Thread.currentThread().getContextClassLoader();
          File TEMPDIR = null;
          try {
              Thread.currentThread().setContextClassLoader(classLoader);
  
              if (log.isDebugEnabled()) log.debug("ClassLoader: " + 
classLoader);
  
              TEMPDIR = FileUtils.createTempDirectory();
              File SRCDIR = new File(TEMPDIR, "stubs");
              File CLASSESDIR = new File(TEMPDIR, "stubs");
              SRCDIR.mkdirs();
              CLASSESDIR.mkdirs();
  
              GenOptions genOptions = new GenOptions();
              genOptions.setClasspath(SRCDIR.getAbsolutePath());
              genOptions.setCompile(false);
              genOptions.setGenSrcDir(SRCDIR.getAbsolutePath());
              genOptions.setGenerate(true);
              genOptions.setInterfaces(new ArrayList(interfaces));
              genOptions.setLoadclass(true);
              genOptions.setOverwrite(true);
              genOptions.setSimpleIdl(false);
              genOptions.setVerbose(verbose);
  
              PortableStubCompiler stubCompiler = new 
PortableStubCompiler(genOptions, classLoader);
  
              stubCompiler.generate();
  
              Set classpath = new HashSet();
              for (Iterator iterator = interfaces.iterator(); 
iterator.hasNext();) {
                  Class iface = classLoader.loadClass((String) iterator.next());
                  collectClasspaths(classpath, iface);
              }
  
              compiler.compileDirectory(SRCDIR, CLASSESDIR, classpath);
  
              // delete this file since someone may be holding on to it.
              if (!saveStubCode) {
                  destination.delete();
              }
  
              Project project = new Project();
              Jar jar = new Jar();
              jar.setProject(project);
              jar.setDestFile(destination);
              jar.setBasedir(CLASSESDIR);
              jar.setUpdate(true);
              jar.execute();
          } catch (Exception e) {
              logAndThrow(e);
          } finally {
              Thread.currentThread().setContextClassLoader(savedLoader);
              FileUtils.recursiveDelete(TEMPDIR);
          }
      }
  
      protected void collectClasspaths(Set set, Class iface) throws 
CompilerException {
          set.add(iface.getProtectionDomain().getCodeSource().getLocation());
  
          Class[] classes = iface.getDeclaredClasses();
          for (int i = 0; i < classes.length; i++) {
              collectClasspaths(set, classes[i]);
          }
      }
  
      private static void logAndThrow(Exception e) throws CompilerException {
          boolean shouldLog = true;
          StackTraceElement[] stackTrace = e.getStackTrace();
          for (int i = 0; i < stackTrace.length; i++) {
              StackTraceElement stackTraceElement = stackTrace[i];
              if 
(stackTraceElement.getClassName().equals("org.omg.CosNaming.NamingContextExtPOA")
                  && stackTraceElement.getMethodName().equals("_invoke")) {
                  shouldLog = false;
                  break;
              }
          }
          if (shouldLog) {
              log.error("Unable to generate stub", e);
          }
  
          /**
           * Convert the msg to string so that we don't try to serialize
           * anything that is unserializable in a cause exception
           */
          throw new CompilerException("Unable to generate stub: " + 
e.toString());
      }
  
      public void doStart() throws Exception {
          if (compiler == null) {
              compiler = new AntCompiler();
          }
      }
  
      public void doStop() throws Exception {
      }
  
      public void doFail() {
      }
  
      public static final GBeanInfo GBEAN_INFO;
  
      static {
          JarUtils.setHandlerSystemProperty();
          // Install the lame tools jar hack
          ToolsJarHack.install();
  
          GBeanInfoBuilder infoFactory = new 
GBeanInfoBuilder(PortableStubGenerator.class, NameFactory.CORBA_SERVICE);
          infoFactory.addInterface(StubGenerator.class);
          infoFactory.addAttribute("verbose", Boolean.TYPE, true);
          infoFactory.addAttribute("props", Properties.class, true);
          infoFactory.addAttribute("saveStubCode", Boolean.TYPE, true);
          infoFactory.addReference("Compiler", Compiler.class, 
NameFactory.CORBA_SERVICE);
  
          GBEAN_INFO = infoFactory.getBeanInfo();
      }
  
      public static GBeanInfo getGBeanInfo() {
          return GBEAN_INFO;
      }
  }
  
  
  

Reply via email to