org.quilt.cl
Class ClassFactory

java.lang.Object
  |
  +--org.quilt.cl.ClassFactory

public class ClassFactory
extends java.lang.Object

Class synthesizer. Currently intended for debugging Quilt development and limited to instantiating classes with a no-argument constructor and a single method whose bytecode depends upon the base name of the class. By default classes whose name begins with test.data.Test will be synthesized. This can be set to a different string by a QuiltClassLoader method.

Author:
David Dixon-Peugh, Jim Dixon -- major changes to the original code.
See Also:
QuiltClassLoader.

Method Summary
static ClassFactory getInstance()
          Use this method to get to the ClassFactory singleton.
 java.io.InputStream getResourceAsStream(java.lang.String resName)
          Get the bytecode for a synthesized class.
 org.apache.bcel.generic.ClassGen makeClass(java.lang.String className, java.lang.String fileName)
          Generate a class with a single no-arg constructor and a runTest method.
 org.apache.bcel.generic.MethodGen makeConstructor(org.apache.bcel.generic.ClassGen clazz)
          Creates the constructor for the synthesized class.
 org.apache.bcel.generic.MethodGen makeMethod(org.apache.bcel.generic.ClassGen clazz)
          Creates a method with bytecode determined by the name of the class.
 org.apache.bcel.generic.MethodGen mgDefault(org.apache.bcel.generic.ClassGen clazz)
          Generates bytecode for a method which simply returns 2.
 org.apache.bcel.generic.MethodGen mgIfThen(org.apache.bcel.generic.ClassGen clazz)
          Generates instructions for a method consisting of a single if-then clause.
 org.apache.bcel.generic.MethodGen mgNPENoCatch(org.apache.bcel.generic.ClassGen clazz)
          Creates bytecode which will throw a NullPointerException without a catch block.
 org.apache.bcel.generic.MethodGen mgNPEWithCatch(org.apache.bcel.generic.ClassGen clazz)
          Returns bytecode which will throw a NullPointerException, but it will catch the NPE.
 org.apache.bcel.generic.MethodGen mgSelect(org.apache.bcel.generic.ClassGen clazz)
          Generates bytecode for a switch statement:
 org.apache.bcel.generic.MethodGen mgWhile(org.apache.bcel.generic.ClassGen clazz)
          Generates code for a while loop.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

getInstance

public static ClassFactory getInstance()
Use this method to get to the ClassFactory singleton.

XXX Is there any benefit to this being a singleton?


getResourceAsStream

public java.io.InputStream getResourceAsStream(java.lang.String resName)
Get the bytecode for a synthesized class. The name passed looks like "test/data/TestMyStuff.class". This is converted to "test.data.TestMyStuff". The "test.data.Test" prefix will later be stripped off and the base name, "MyStuff" in this case, used to determine which version of the runTest method to generate.

Parameters:
resName - Name of the class to be synthesized.

makeClass

public org.apache.bcel.generic.ClassGen makeClass(java.lang.String className,
                                                  java.lang.String fileName)
Generate a class with a single no-arg constructor and a runTest method. By convention, if there is an underscore (_) in the class name, the underscore and everything after it are ignored in choosing method code. For example, if the class name is testWhile_1, then the method code comes from mgWhile

Methods available at this time are:

Parameters:
className - Name of the class to be constructed.
fileName - Associated file name (??? XXX)

makeConstructor

public org.apache.bcel.generic.MethodGen makeConstructor(org.apache.bcel.generic.ClassGen clazz)
Creates the constructor for the synthesized class. It is a no-arg constructor that calls super.

Parameters:
clazz - Template for the class being synthesized.
Returns:
Method template for the constructor.

makeMethod

public org.apache.bcel.generic.MethodGen makeMethod(org.apache.bcel.generic.ClassGen clazz)
Creates a method with bytecode determined by the name of the class. If we have class test.data.TestBogus, then we strip off the "test.data.Test" prefix and call mgBogus() to get an instruction list. In the current version, if there is an underscore in the class name, then the underscore and everything following it will be ignored. So test.data.TestBogus_27 would result in a call to mgBogus(), not mgBogus_27(). If the method (mgBogus in this case) doesn't exist, then we call mgDefault() to generate the bytecode.

Parameters:
clazz - Template for the class being produced.
Returns:
Template method with bytecode.

mgDefault

public org.apache.bcel.generic.MethodGen mgDefault(org.apache.bcel.generic.ClassGen clazz)
Generates bytecode for a method which simply returns 2. This is the method used if the class name is test.data.TestDefault. This method is also used if ClassFactory doesn't recognize the name; for example, if the class name is test.data.TestBogus, because there is no mgBogus method, this default method is used to generate the bytecode.
 public int runTest( int x ) {
   return 2;
 }
 


mgIfThen

public org.apache.bcel.generic.MethodGen mgIfThen(org.apache.bcel.generic.ClassGen clazz)
Generates instructions for a method consisting of a single if-then clause.
   public int runTest( int x ) {
     if (x > 0) {
       return 3;
     } else {
       return 5;
     }
   }
 


mgNPENoCatch

public org.apache.bcel.generic.MethodGen mgNPENoCatch(org.apache.bcel.generic.ClassGen clazz)
Creates bytecode which will throw a NullPointerException without a catch block.
     public int runTest(int x) {
         null.runTest( 0 );
         return 0;
     }
 


mgNPEWithCatch

public org.apache.bcel.generic.MethodGen mgNPEWithCatch(org.apache.bcel.generic.ClassGen clazz)
Returns bytecode which will throw a NullPointerException, but it will catch the NPE.
     try {
         null.runTest( 0 );
         return -1;
     } catch (NullPointerException npe) {
         return 3;
     }
 


mgSelect

public org.apache.bcel.generic.MethodGen mgSelect(org.apache.bcel.generic.ClassGen clazz)
Generates bytecode for a switch statement:
 int runTest (int x) {
     switch (x) {
     case 1:  return 1;
     case 2:  return 3;
     case 3:  return 5;
     default: return 2;
     }
 }
 


mgWhile

public org.apache.bcel.generic.MethodGen mgWhile(org.apache.bcel.generic.ClassGen clazz)
Generates code for a while loop. The while loop returns 0 if the parameter x is greater than or equal to zero, but x otherwise.
 int runTest(int x) {
     while (x > 0) {
         x --;
     }
     return x;
 }
 

The actual bytecode produced is:

LabelInstruction Stack
ILOAD _ -> I
if: DUP I -> II
IFLE (ret) II -> I
loop:ICONST_1 I -> II
ISUB II -> I
GOTO (if) I -> I
ret: IRETURN I -> _



Copyright © 2001-2003 Apache Software Foundation. All Rights Reserved.