commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hamm...@apache.org
Subject cvs commit: jakarta-commons-sandbox/armi/src/java/org/apache/commons/armi/server/impl BCELClassRetriever.java
Date Fri, 04 Jan 2002 13:17:32 GMT
hammant     02/01/04 05:17:31

  Added:       armi/src/java/org/apache/commons/armi/server/impl
                        BCELClassRetriever.java
  Log:
  Start of BCEL proxy
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/armi/src/java/org/apache/commons/armi/server/impl/BCELClassRetriever.java
  
  Index: BCELClassRetriever.java
  ===================================================================
  
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/armi/src/java/org/apache/commons/armi/server/impl/BCELClassRetriever.java,v
1.1 2002/01/04 13:17:31 hammant Exp $
   * $Revision: 1.1 $
   * $Date: 2002/01/04 13:17:31 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 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 end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Commons", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``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 APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */
  package org.apache.commons.armi.server.impl;
  
  
  
  import org.apache.commons.armi.server.ArmiClassRetrievalException;
  import org.apache.commons.armi.server.ClassRetriever;
  import org.apache.commons.armi.common.AbstractMethodHandler;
  import org.apache.bcel.classfile.JavaClass;
  import org.apache.bcel.Constants;
  import org.apache.bcel.generic.ClassGen;
  import org.apache.bcel.generic.InstructionList;
  import org.apache.bcel.generic.ConstantPoolGen;
  
  import java.net.URLClassLoader;
  import java.net.URL;
  import java.net.MalformedURLException;
  
  import java.io.File;
  import java.io.InputStream;
  import java.io.ByteArrayInputStream;
  import java.io.PrintWriter;
  import java.util.HashMap;
  import java.util.Vector;
  import java.lang.reflect.Method;
  
  
  /**
   * Class BCELClassRetriever
   *
   *
   * @author Paul Hammant <a href="mailto:Paul_Hammant@yahoo.com">Paul_Hammant@yahoo.com</a>
   * @version $Revision: 1.1 $
   */
  public class BCELClassRetriever extends AbstractMethodHandler implements ClassRetriever
{
  
      private HashMap mClasses = new HashMap();
  
      PrintWriter mClassSource = null; // TODO delete this from source when completed
  
      public void generate(String asName, Class[] interfacesToPublish) {
          String[] interfaces = new String[interfacesToPublish.length];
          for (int i = 0; i < interfacesToPublish.length; i++) {
              interfaces[i] = interfacesToPublish[i].getClass().getName();
          }
          ClassGen        cg = new ClassGen("ArmiGenerated" + asName, "org.apache.commons.armi.client.impl.BaseServedObject",
  				      "<generated>", Constants.ACC_PUBLIC |
  				      Constants.ACC_SUPER,
  				      interfaces);
  
          ConstantPoolGen cp = cg.getConstantPool(); // cg creates constant pool
          InstructionList il = new InstructionList();
          cg.addEmptyConstructor(Constants.ACC_PUBLIC);
  
          Vector methodsDone = new Vector();
  
          for (int x = 0; x < interfacesToPublish.length; x++) {
  
              Method[] methods = interfacesToPublish[x].getMethods();
              for (int i = 0; i < methods.length; i++) {
                  Method method = methods[i];
                  String methodSignature = super.getMethodSignature(method);
                  if (!methodsDone.contains(methodSignature)) {
                      methodsDone.add(methodSignature);
                      generate(methodSignature, asName, cg, cp, il, method);
                  }
              }
          }
  
          mClasses.put(asName, cg.getJavaClass().getBytes());
  
      }
  
      // Much of the following taken from PrimarySourceGenerator.
      // Lots to convert before this will work.
  
      private void generate(String methodSignature, String asName, ClassGen cg, ConstantPoolGen
cpg, InstructionList il, Method method) {
  
                      String rClass = method.getReturnType().getName();
                      String mName = method.getName();
  
                      mClassSource.print("  public " + rClass + " " + mName + " (");
  
                      Class[] argTypes = method.getParameterTypes();
  
                      for (int i = 0; i < argTypes.length; i++) {
                          String cn = argTypes[i].getName();
  
                          generateParameter(cn, argTypes, i);
                      }
  
                      mClassSource.print(") ");
  
                      Class[] throwsTypes = method.getExceptionTypes();
  
                      for (int i = 0; i < throwsTypes.length; i++) {
                          generateThrows(i, throwsTypes);
                      }
  
                      mClassSource.println("{");
                      mClassSource.println("    Object[] args = new Object[" + argTypes.length
                                           + "];");
  
                      for (int i = 0; i < argTypes.length; i++) {
                          String cn = argTypes[i].getName();
  
                          generateAssignLine(cn, i);
                      }
  
                      mClassSource.println("    try {");
  
                      if (rClass.equals("void")) {
                          mClassSource.println("      armiProcessVoidRequest(\""
                                               + methodSignature.toString() + "\",args);");
                      } else {
                          mClassSource.println("      Object retVal = armiProcessObjectRequest(\""
                                               + methodSignature.toString() + "\",args);");
                          generateReturnLine(rClass);
                      }
  
                      mClassSource.println("    } catch (Throwable t) {");
  
                      throwsTypes = method.getExceptionTypes();
  
                      for (int i = 0; i < throwsTypes.length; i++) {
                          generateThrowHandler(i, throwsTypes);
                      }
  
                      mClassSource.println("      if (t instanceof RuntimeException) { ");
                      mClassSource.println("        throw (RuntimeException) t;");
                      mClassSource.println("      } else if (t instanceof Error) { ");
                      mClassSource.println("        throw (Error) t;");
                      mClassSource.println("      } else { ");
                      mClassSource.println(
                          "        throw new org.apache.commons.armi.common.ArmiInvocationException(\"Should
never get here\" + t.getMessage()); ");
                      mClassSource.println("      }");
                      mClassSource.println("    }");
                      mClassSource.println("  }");
  
      }
  
      private void generateParameter(String cn, Class[] argTypes, int i) {
  
          if (cn.startsWith("L")) {
              mClassSource.print(argTypes[i].getName());
          } else if (cn.startsWith("[L")) {
              mClassSource.print(argTypes[i].getName() + "[]");
          } else if (cn.equals("[B")) {
              mClassSource.print("byte[]");
          } else if (cn.equals("[C")) {
              mClassSource.print("char[]");
          } else if (cn.equals("[D")) {
              mClassSource.print("double[]");
          } else if (cn.equals("[F")) {
              mClassSource.print("float[]");
          } else if (cn.equals("[I")) {
              mClassSource.print("int[]");
          } else if (cn.equals("[J")) {
              mClassSource.print("long[]");
          } else if (cn.equals("[S")) {
              mClassSource.print("short[]");
          } else if (cn.equals("[Z")) {
              mClassSource.print("boolean[]");
          } else {
              mClassSource.print(cn);
          }
  
          mClassSource.print(" v" + i);
  
          if (i + 1 < argTypes.length) {
              mClassSource.print(", ");
          }
      }
  
      private void generateAssignLine(String cn, int i) {
  
          if (cn.equals("int")) {
              mClassSource.println("    args[" + i + "] = new Integer(v" + i + ");");
          } else if (cn.equals("short")) {
              mClassSource.println("    args[" + i + "] = new Short(v" + i + ");");
          } else if (cn.equals("float")) {
              mClassSource.println("    args[" + i + "] = new Float(v" + i + ");");
          } else if (cn.equals("double")) {
              mClassSource.println("    args[" + i + "] = new Double(v" + i + ");");
          } else if (cn.equals("long")) {
              mClassSource.println("    args[" + i + "] = new Long(v" + i + ");");
          } else if (cn.equals("char")) {
              mClassSource.println("    args[" + i + "] = new Character(v" + i + ");");
          } else if (cn.equals("boolean")) {
              mClassSource.println("    args[" + i + "] = new Boolean(v" + i + ");");
          } else if (cn.equals("byte")) {
              mClassSource.println("    args[" + i + "] = new Byte(v" + i + ");");
          } else {
              mClassSource.println("    args[" + i + "] = v" + i + ";");
          }
      }
  
      private void generateReturnLine(String rClass) {
  
          if (rClass.equals("boolean")) {
              mClassSource.println("      return ((Boolean) retVal).booleanValue();");
          } else if (rClass.equals("integer")) {
              mClassSource.println("      return ((Integer) retVal).intValue();");
          } else if (rClass.equals("short")) {
              mClassSource.println("      return ((Short) retVal).shortValue();");
          } else if (rClass.equals("float")) {
              mClassSource.println("      return ((Float) retVal).floatValue();");
          } else if (rClass.equals("double")) {
              mClassSource.println("      return ((Double) retVal).doubleValue();");
          } else if (rClass.equals("long")) {
              mClassSource.println("      return ((Long) retVal).longValue();");
          } else if (rClass.equals("char")) {
              mClassSource.println("      return ((Character) retVal).charValue();");
          } else if (rClass.equals("byte")) {
              mClassSource.println("      return ((Byte) retVal).byteValue();");
          } else {
              mClassSource.println("      return (" + rClass + ") retVal;");
          }
      }
  
      private void generateThrowHandler(int i, Class[] throwsTypes) {
  
          if (i == 0) {
              mClassSource.println("      if (t instanceof " + throwsTypes[i].getName() +
") { ");
          } else {
              mClassSource.println("      } else if (t instanceof " + throwsTypes[i].getName()
                                   + ") { ");
          }
  
          mClassSource.println("        throw (" + throwsTypes[i].getName() + ") t;");
  
          if (i + 1 == throwsTypes.length) {
              mClassSource.print("      } else");
          }
      }
  
      private void generateThrows(int i, Class[] throwsTypes) {
  
          if (i == 0) {
              mClassSource.print("throws ");
          }
  
          mClassSource.print(throwsTypes[i].getName());
  
          if (i + 1 < throwsTypes.length) {
              mClassSource.print(", ");
          }
      }
  
       /**
       * Method getBytes
       *
       *
       * @param publishedName
       *
       * @return
       *
       * @throws ArmiClassRetrievalException
       *
       */
      public byte[] getBytes(String publishedName) throws ArmiClassRetrievalException {
          byte[] bytes = (byte[]) mClasses.get(publishedName);
          if (bytes == null) {
              throw new ArmiClassRetrievalException("Generated class not found in BCEL respoisitory
on server");
          }
          return bytes;
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message