You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by jk...@locus.apache.org on 2000/09/20 23:14:29 UTC

cvs commit: xml-xalan/java/src/synthetic Class.java SynthesisException.java TestDriver.java

jkesselm    00/09/20 14:14:28

  Added:       java/src/synthetic Class.java SynthesisException.java
                        TestDriver.java
  Log:
  synthetic.Class: IBM-developed "reverse reflection" wrappers,
  used in the compiled-Template experiment. These are
  also experimental and are known to have some holes, and
  for the simple compilations now being attempted they don't
  have huge advantages over generating directly into a stringbuffer,
  but I had 'em on hand and we've been planning to publish 'em anyway.
  
  Revision  Changes    Path
  1.1                  xml-xalan/java/src/synthetic/Class.java
  
  Index: Class.java
  ===================================================================
  // Synthetic Class descriptors ("reverse reflection")
  // Copyright �2000 International Business Machines Corportation
  // All rights reserved.
  package synthetic;
  
  import synthetic.SynthesisException;
  import synthetic.reflection.Constructor;
  import synthetic.reflection.Method;
  import synthetic.reflection.Field;
  import java.lang.reflect.Modifier;
  
  /* ***** WORK NEEDED:
      Factories/Libraries: We currently have forClass and
      forName(request reified, complain if no real class), 
      and declareClass (request unreified, create unreified
      if it doesn't exist). What about ther user expectations
      -- should we have a full matrix, rather than asking 
      users to write wrappers?
      
      Reflection doesn't tell us about deprecation. If we want
      that info, MFC advises mousing our way into the bytecodes.
      (Ugh). Should we at least model that for synthetics?
  */
  
  
  /**
    synthetic.Class is a mutable equivalent of java.lang.Class.
    Instances represent classes and interfaces in a running Java
    application, or class descriptions under construction. In the
    former case, synthetic.Class operates as a proxy for the
    "real" java.lang.Class object; in the latter, it consults 
    data structures defined in the synthetic.reflection.* package.
    <p>
    Unlike java.lang.Class, synthetic.Class has a pair of factories
    (fromName and fromClass). It can also be switched from synthetic
    to proxy operation after construction, by setting the realClass 
    property; this is intended to allow these definitions to be 
    "compiled in place".
    <p>
    For convenient use, synthetic.Class implements an extended
    version of the java.lang.Class API -- but is not a subclass
    thereof, since java.lang.Class is Final (presumably for
    security reasons).
    <p>
    DEVELOPMENT NOTE: Methods not yet implemented will throw 
    IllegalStateException
    <p>
      I've added code to convert primitive names into their TYPEs,
      to accept foo[] as a synonym for [Lfoo, and to generate 
      the right thing on output (getJava[Short]Name).
      Useful extension for code generation from Java-like
      source. We may want to factor these and toSource out, making
      synthetic.Class addess only the JVM level and providing
      subclasses or access tools that handle language syntax
      (Java source, NetRexx source, etc.)
  
    @since  2000/2/10
    @see    java.lang.class
    @see    defineClass 
    */
  
  public class Class extends Object implements java.io.Serializable
  {
    /** Class descriptions currently existing.*/
    private static java.util.Hashtable global_classtable=new java.util.Hashtable();
    
    /**fully-qualified path.classname */
    private java.lang.String name;
    
    /** Actual Java class object. When present, all interactions
      are redirected to it. Allows our Class to function as a
      wrapper for the Java version (in lieu of subclassing or
      a shared Interface), and allows BSC or similar 
      compilation to replace a generated description with an
      directly runnable class.
      */
    private java.lang.Class realclass = null;
    
    private int modifiers;
    private boolean isInterface=false;
    private Class superclass=null;
    private Class declaringclass=null;
    private Class[] interfaces=new Class[0];
    private Class[] allclasses=new Class[0];
    private Class[] declaredclasses=new Class[0];
    private Constructor[] allconstructors=new Constructor[0];
    private Constructor[] declaredconstructors=new Constructor[0];
    private Method[] allmethods=new Method[0];
    private Method[] declaredmethods=new Method[0];
    private Field[] allfields=new Field[0];
    private Field[] declaredfields=new Field[0];
    private Class[] innerclasses=new Class[0];
    
    /**
     * Construct a synthetic class as proxy/wrapper for an existing 
     * Java Class. Non-public; most folks should use
     * .forName and .forClass to request these wrappers, so they
     * get the shared instances.
     * <p>
     * Creation date: (12-25-99 12:16:15 PM)
     * @param realclass java.lang.Class
     */
    Class(java.lang.Class realclass)
    {
      this(realclass.getName());
      try
        {
  	setRealClass(realclass);
        } 
      catch(SynthesisException e)
        {
  	e.printStackTrace();
        }
    }
    
    /**
     * Construct a named-but-empty synthetic Class object.
     * Non-public; most folks should use
     * .forName and .forClass to request these wrappers, so they
     * get the shared instances.
     * <p>
     * Creation date: (12-25-99 12:15:23 PM)
     * @param name java.lang.String
     */
    Class(String fullname)
    {
      this.name=fullname;
      global_classtable.put(fullname,this);
    }
    
    /**
      Returns the synthetic Class object associated with the "real"
      class specified, creating one if it didn't already exist.
      <p>
      For example, the following code fragment returns
      the runtime Class descriptor for the class named
      mypackage.MyClass.
      <code>
      Class t =
      Class.forName(java.lang.Class.forName("mypackage.MyClass"))
      </code>
      <p>
      Note that if the user has manually created a synthetic.Class
      with the same name before this call is issued, that object
      will be found instead. See also the declareClass call.
      <p>
      ***** We need a better way to declare/define array classes,
      given a class object (synthetic or not).
     
      @param cls the desired Java class. 
      @return the synthetic Class descriptor for the specified class. 
      */
    public static Class forClass(java.lang.Class cls)
    {
      if(cls==null)
        return null;
      Class ret=(Class)(global_classtable.get(cls.getName()));
      if(null==ret)
        ret=new Class(cls);
      return ret;
    }
  
    /** Like forName, but if the classname doesn't have a package
      prefix we first attempt to look it up as one of our own
      inner clases. As with forName, if this can not be resolved
      we throw an exception.
    */
    public Class forNameInContext(String classname)
    throws ClassNotFoundException
    {
      for(int i=innerclasses.length-1;i>=0;--i)
          if(classname.equals(innerclasses[i].getShortName()) )
              return innerclasses[i];
      return forName(classname);
    }
    
    /**
      Returns the synthetic Class object associated with the class
      with the given fully-qualified name. If there isn't one, this
      method attempts to locate, load and link the standard java Class.
      If it succeeds, it returns a wrapped version of the Class object 
      representing the class. If it fails, the method throws a
      ClassNotFoundException. 
      <p>
      For example, the following code fragment returns
      the runtime Class descriptor for the class named
      mypackage.MyClass -- either as a synthetic or as
      a standard Java class.
      <code>
      Class t =
      Class.forName("mypackage.MyClass")
      </code>
      <p>
      ***** I've added support for arrays -- assuming any name
      that ends with ']' is an array. It probably needs to be
      made smarter, possibly via a subclass of synthetic.Class.
      
      @param className the fully qualified name of the desired class. 
      @return the synthetic Class descriptor for the class with the specified name. 
      @throws ClassNotFoundException if the class could not be found. 
      */
    public static Class forName(String className) throws ClassNotFoundException
    {
      // ***** Experimental support for array syntax expressed
      // per Java source rather than per JVM type formalism.
      // Simpleminded, asssumes balanced []'s.
      if(className.endsWith("]"))
      {
        StringBuffer arrayname=new StringBuffer();
        for(int i=className.indexOf('[');
            i!=-1;
            i=className.indexOf('[',i+1) )
            arrayname.append('[');
            
        // Convert the classname to array-formalism
        // Primitives have letters; objects are Lname;
        // (Don't ask why long is spelled with a J and
        // object is spelled with an L...)
        String classname=className.substring(0,className.indexOf('['));
        
        if("byte".equals(classname))
          arrayname.append('B');
        else if("char".equals(classname))
          arrayname.append('C');
        else if("double".equals(classname))
          arrayname.append('D');
        else if("float".equals(classname))
          arrayname.append('F');
        else if("int".equals(classname))
          arrayname.append('I');
        else if("long".equals(classname))
          arrayname.append('J');
        else if("short".equals(classname))
          arrayname.append('S');
        else if("boolean".equals(classname))
          arrayname.append('Z');
        else
          arrayname.append('L')
                .append(classname)
              .append(';');
              
        // Tail-call.
        return forName(arrayname.toString());
      }
      
      Class ret=(Class)(global_classtable.get(className));
      if(null==ret)
      {
        // ***** Experimental support for Java primitives
        // Seems to me that mapping them into the "Type" is
        // probably most useful
        if("boolean".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Boolean.TYPE;
        }
        else if("byte".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Byte.TYPE;
        }
        else if("char".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Character.TYPE;
        }
        else if("short".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Short.TYPE;
        }
        else if("int".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Integer.TYPE;
        }
        else if("long".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Long.TYPE;
        }
        else if("float".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Float.TYPE;
        }
        else if("double".equals(className))
        {
          ret=new Class(className);
          ret.realclass=java.lang.Double.TYPE;
        }
        else if("void".equals(className))
        {
  	// ***** Void is an "absence of type". We might want to create
  	// a special object to represent it. This is a placeholder.
          ret=new Class(className);
          ret.realclass=java.lang.Class.forName("java.lang.Object");
        }
   
        // Other classes are just wrappered. Unknown classes throw a
        // ClassNotFoundException; the user can switch to declareClass()
        // if they're sure that an unreified class is OK. 
        else
          ret=new Class(java.lang.Class.forName(className));
      }
  
      return ret;
    }
    /** Start to create a synthetic Class with the given fully-qualified
      name.  If a Class by that name already exists, and it is not
      reified, it will be returned instead. If a reified Class _does_
      exist, we throw a synthesis exception.
      
      @param className the fully qualified name of the desired class. 
      @return the synthetic Class descriptor for the class with the specified name. 
      @throws SynthesisException
      if the class has been reified.  */
    public static Class declareClass(String className) throws SynthesisException
    {
      Class ret=(Class)(global_classtable.get(className));
      if(null==ret)
        ret=new Class(className);
      if(ret.realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      
      return ret;
    }
    /** Start to create a synthetic Class with the given fully-qualified
      name.  If a Class by that name already exists,whether reified or
      not, it will be removed from the table and replaced by the new synthesis.
      
      ***** NOTE THAT the replacement will not affect classes which
      have already refernced the old version. We could change that by
      having everyone reference everyone else via an indirection table.
      
      @param className the fully qualified name of the desired class. 
      @return the synthetic Class descriptor for the class with the specified name. 
    */
    public static Class reallyDeclareClass(String className)
    {
      Class ret=(Class)(global_classtable.get(className));
      if(null!=ret)
        global_classtable.remove(ret);
      ret=new Class(className);
      return ret;
    }
    /**
      Returns an array containing Class objects
      representing all the public classes and interfaces
      that are members of the class represented by this
      Class object. This includes public class and
      interface members inherited from superclasses and
      public class and interface members declared by the
      class. Returns an array of length 0 if the class has
      no public member classes or interfaces, or if this
      Class object represents a primitive type. 
      <p>
      NOTE: In a significant number of existing Java environments,
      this method is not implemented by the official Class object
      and always returns an empty array. So if you don't get any
      useful information from a proxied java.lang.Class, don't
      be surprised. I'm not sure if someone decided it was a 
      potential security issue, or if Sun was lazy and everyone
      else followed suit.
      <p>
      ALSO NOTE: The above spec, as taken from java.lang.Class,
      doesn't provide any good way to distinguish the immediate
      superclass from all other superclasses. That makes it only
      marginally useful, which is no doubt one of the reasons folks
      have declined to implement it. 
      */
    public Class[] getClasses()
    {
      if(realclass!=null && allclasses==null)
        {
  	java.lang.Class[] realDE=realclass.getClasses();
  	allclasses=new Class[realDE.length];
  	for(int i=0;i<realDE.length;++i)
  	  allclasses[i]=forClass(realDE[i]);
        }
      
      return allclasses;
    }
    /**
      Determines the class loader for the class. 
      
      @return
      the class loader that created the class or
      interface represented by this object, or null
      if the synthetic.Class was not created by a class loader. 
      @see
      ClassLoader
      */
    public ClassLoader getClassLoader()
    {
      return (realclass==null) ? null : realclass.getClassLoader();
    }
    /**
      If this class represents an array type, returns the
      Class object representing the component type of
      the array; otherwise returns null. 
      <p>
      NOTE: Since synthetic.Class doesn't yet attempt to model array
      types, this will currently return false unless we are
      proxying such a type.
      
      @see  Array 
      */
    public Class getComponentType()
    {
      return realclass == null ? null : new Class(realclass.getComponentType());
    }
    /**
      Returns a Constructor object that reflects the
      specified public constructor of the class
      represented by this Class object. The
      parameterTypes parameter is an array of Class
      objects that identify the constructor's formal
      parameter types, in declared order. 
      <p>
      The constructor to reflect is located by searching
      all the constructors of the class represented by this
      Class object for a public constructor with the
      exactly the same formal parameter types. 
      
      @throws NoSuchMethodException 
      if a matching method is not found. 
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Constructor 
      */
    public Constructor getConstructor(Class parameterTypes[]) 
         throws NoSuchMethodException, SecurityException, SynthesisException
    {
      if(realclass==null)
        throw new SynthesisException(SynthesisException.UNREIFIED);
      java.lang.Class[] real=new java.lang.Class[parameterTypes.length];
      for(int i=0;i<parameterTypes.length;++i)
          if( (real[i]=parameterTypes[i].getRealClass()) == null)
            throw new SynthesisException(SynthesisException.UNREIFIED);
      return new Constructor(realclass.getConstructor(real),this);
    }
    /**
      Returns an array containing Constructor objects
      reflecting all the public constructors of the class
      represented by this Class object. An array of length
      0 is returned if the class has no public
      constructors. 
      
      @throws SecurityException 
      if access to the information is denied. 
      @see
      Constructor 
      */
    public Constructor[] getConstructors() throws SecurityException
    {
      if(realclass!=null && allconstructors==null)
        {
  	java.lang.reflect.Constructor[] realDC=realclass.getConstructors();
  	allconstructors=new Constructor[realDC.length];
  	for(int i=0;i<realDC.length;++i)
  	  allconstructors[i]=new Constructor(realDC[i],this);
        }
      
      return allconstructors;
    }
    /**
      This method is not implemented in VAJAVA 3.0
      <p>
      Returns an array of Class objects reflecting all the
      classes and interfaces declared as members of the
      class represented by this Class object. This
      includes public, protected, default (package)
      access, and private classes and interfaces declared
      by the class, but excludes inherited classes and
      interfaces. Returns an array of length 0 if the class
      declares no classes or interfaces as members, or if
      this Class object represents a primitive type. 
      
      @throws SecurityException 
      if access to the information is denied. 
      */
    public Class[] getDeclaredClasses() throws SecurityException
    {
      // ***** This should really be a single class plus declared interfaces.
      
      if(realclass!=null && declaredclasses==null)
        {
  	java.lang.Class[] realDE=realclass.getDeclaredClasses();
  	declaredclasses=new Class[realDE.length];
  	for(int i=0;i<realDE.length;++i)
  	  {
  	    declaredclasses[i]=forClass(realDE[i]);
  	    if(!realDE[i].isInterface())
  	      superclass=declaredclasses[i];
  	  }
        }
      return declaredclasses;
    }
    
    /**
      Adds an "extends" description for the class or
      interface represented by this Class object
      
      @throws SynthesisException
      if the class has been reified.
      @see 
      class 
      */
    public void addExtends(Class newclass) 
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      Class[] scratch=new Class[declaredclasses.length+1];
      System.arraycopy(declaredclasses,0,scratch,0,declaredclasses.length);
      scratch[declaredclasses.length]=newclass;
      declaredclasses=scratch;
    }
    
    
    /**
      Returns a Constructor object that reflects the
      specified declared constructor of the class or
      interface represented by this Class object. The
      parameterTypes parameter is an array of Class
      objects that identify the constructor's formal
      parameter types, in declared order. 
      
      @throws NoSuchMethodException 
      if a matching method is not found. 
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Constructor 
      */
    public Constructor getDeclaredConstructor(Class parameterTypes[]) throws NoSuchMethodException, SecurityException
    {
      throw new java.lang.IllegalStateException();
    }
    
    /**
      Adds a Constructor description for  the class or
      interface represented by this Class object
      
      @throws SynthesisException
      if the class has been reified.
      @see 
      Constructor 
      */
    public Constructor declareConstructor() 
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      Constructor newctor=new Constructor(this);
      
      Constructor[] scratch=new Constructor[declaredconstructors.length+1];
      System.arraycopy(declaredconstructors,0,scratch,0,declaredconstructors.length);
      scratch[declaredconstructors.length]=newctor;
      declaredconstructors=scratch;
      
      scratch=new Constructor[allconstructors.length+1];
      System.arraycopy(allconstructors,0,scratch,0,allconstructors.length);
      scratch[allconstructors.length]=newctor;
      allconstructors=scratch;
      
      return newctor;
    }
    
    /**
     * State that this class implements a specified interface.
     * This does not yet update allMethods or otherwise
     * attempt to inherit data.
     * 
     * @param newifce synthetic.Class representing the interface we want to add.
     * @exception synthetic.SynthesisException if the Class isn't an interface
     * @see setSuperClass
     * @see declareConstructor
     * @see declareMethod
     * @see declareField
     */
    public Class declareInterface(Class newifce) 
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      if(!newifce.isInterface())
        throw new SynthesisException(SynthesisException.SYNTAX,newifce.getName()+" isn't an interface");
        
      Class[] scratch=new Class[interfaces.length+1];
      System.arraycopy(interfaces,0,scratch,0,interfaces.length);
      scratch[interfaces.length]=newifce;
      interfaces=scratch;
      
      scratch=new Class[allclasses.length+1];
      System.arraycopy(allclasses,0,scratch,0,allclasses.length);
      scratch[allclasses.length]=newifce;
      allclasses=scratch;
      
      return newifce;
    }
    
    
    /**
      Returns an array of Constructor objects reflecting
      all the constructors declared by the class
      represented by this Class object. These are public,
      protected, default (package) access, and private
      constructors. Returns an array of length 0 if this
      Class object represents an interface or a primitive
      type. 
      <p>
      See The Java Language Specification, section 8.2. 
      
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Constructor 
      */
    public Constructor[] getDeclaredConstructors() throws SecurityException
    {
      if(realclass!=null && declaredconstructors==null)
        {
  	java.lang.reflect.Constructor[] realDC=realclass.getDeclaredConstructors();
  	declaredconstructors=new Constructor[realDC.length];
  	for(int i=0;i<realDC.length;++i)
  	  declaredconstructors[i]=new Constructor(realDC[i],this);
        }
      
      return declaredconstructors;
    }
    /**
      Returns a Field object that reflects the specified
      declared field of the class or interface represented
      by this Class object. The name parameter is a
      String that specifies the simple name of the desired
      field. 
      
      @throws NoSuchFieldException 
      if a field with the specified name is not found. 
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Field 
      */
    public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException
    {
      throw new java.lang.IllegalStateException();
    }
    
    /**
      Adds a Field description for  the class or
      interface represented by this Class object
      
      @throws SynthesisException
      if the class has been reified.
      @see 
      Constructor 
      */
    public Field declareField(String name) 
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      Field newfield=new Field(name,this);
      
      Field[] scratch=new Field[declaredfields.length+1];
      System.arraycopy(declaredfields,0,scratch,0,declaredfields.length);
      scratch[declaredfields.length]=newfield;
      declaredfields=scratch;
      
      scratch=new Field[allfields.length+1];
      System.arraycopy(allfields,0,scratch,0,allfields.length);
      scratch[allfields.length]=newfield;
      allfields=scratch;
      
      return newfield;
    }
    
    /**
      Returns an array of Field objects reflecting all the
      fields declared by the class or interface represented
      by this Class object. This includes public,
      protected, default (package) access, and private
      fields, but excludes inherited fields. Returns an
      array of length 0 if the class or interface declares
      no fields, or if this Class object represents a
      primitive type. See The Java Language
      Specification, sections 8.2 and 8.3. 
      
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Field 
      */
    public Field[] getDeclaredFields() throws SecurityException
    {
      if(realclass!=null && declaredfields==null)
        {
  	java.lang.reflect.Field[] realDF=realclass.getDeclaredFields();
  	declaredfields=new Field[realDF.length];
  	for(int i=0;i<realDF.length;++i)
  	  declaredfields[i]=new Field(realDF[i],this);
        }
      
      return declaredfields;
    }
    /**
      Returns a Method object that reflects the specified
      declared method of the class or interface
      represented by this Class object. The name
      parameter is a String that specifies the simple
      name of the desired method, and the
      parameterTypes parameter is an array of Class
      objects that identify the method's formal parameter
      types, in declared order. 
      
      @throws NoSuchMethodException 
      if a matching method is not found. 
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Method 
      */
    public Method getDeclaredMethod(String name, Class parameterTypes[]) 
         throws NoSuchMethodException, SecurityException
    {
      throw new java.lang.IllegalStateException();
    }
    
    
    /**
      Adds a Method description for  the class or
      interface represented by this Class object
      
      @throws SynthesisException
      if the class has been reified.
      @see 
      Constructor 
      */
    public Method declareMethod(String name) 
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      Method newMethod=new Method(name,this);
      
      Method[] scratch=new Method[declaredmethods.length+1];
      System.arraycopy(declaredmethods,0,scratch,0,declaredmethods.length);
      scratch[declaredmethods.length]=newMethod;
      declaredmethods=scratch;
      
      scratch=new Method[allmethods.length+1];
      System.arraycopy(allmethods,0,scratch,0,allmethods.length);
      scratch[allmethods.length]=newMethod;
      allmethods=scratch;
      
      return newMethod;
    }
    
    /**
      Returns an array of Method objects reflecting all
      the methods declared by the class or interface
      represented by this Class object. This includes
      public, protected, default (package) access, and
      private methods, but excludes inherited methods.
      Returns an array of length 0 if the class or interface
      declares no methods, or if this Class object
      represents a primitive type. 
      <p>
      See The Java Language Specification, section 8.2. 
      
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Method 
      */
    public Method[] getDeclaredMethods() throws SecurityException
    {
      if(realclass!=null && declaredmethods==null)
        {
  	java.lang.reflect.Method[] realDM=realclass.getDeclaredMethods();
  	declaredmethods=new Method[realDM.length];
  	for(int i=0;i<realDM.length;++i)
  	  declaredmethods[i]=new Method(realDM[i],this);
        }
      
      return declaredmethods;
    }
    /**
      This method is not implemented in VAJava 3.0
      <p>
      If the class or interface represented by this Class
      object is a member of another class, returns the
      Class object representing the class of which it is a
      member (its declaring class). Returns null if this
      class or interface is not a member of any other
      class.
      */
    public Class getDeclaringClass()
    {
      if(realclass!=null && declaringclass==null)
      {
        java.lang.Class dc=realclass.getDeclaringClass();
        if(dc==null)
          declaringclass=null;
        else
          declaringclass=forClass(dc);
      }
      return declaringclass;
    }
      
    /**
      Declare that this class is an inner class of another.
      */
    private void addInnerClass(Class newclass)
         throws SynthesisException
    {
      if (realclass != null)
        throw new SynthesisException(SynthesisException.REIFIED);
      
      if(newclass.getDeclaringClass()!=this)
          throw new SynthesisException(SynthesisException.WRONG_OWNER);
      
      Class[] scratch=new Class[innerclasses.length+1];
      System.arraycopy(innerclasses,0,scratch,0,innerclasses.length);
      scratch[innerclasses.length]=newclass;
      innerclasses=scratch;
    }
    
    /**
     * Declare a class contained within this class. This doesn't
     * address anonymous classes (those go inside method bodies
     * and similar code), just local classes.
     * <p>
     * ***** This requires lookup methods that operate in the
     * context of a specific class, and per-class registries!
     * 
     * @param className Local name of inner class to create. This should _not_ be a
     * qualified name, unlike the normal forName() call. Its
     * hierarchy is established by the class within which it is
     * created.
     * @return synthetic.Class object for the contained class.
     * @exception synthetic.SynthesisException if class could not be created.
     * @since 2/2000
     * @see forName
     */
    public Class declareInnerClass(String className)
         throws SynthesisException
    {
      if (realclass != null)
        throw new SynthesisException(SynthesisException.REIFIED);
        
      String relativeName=getName()+"$"+className;
      Class newclass=(Class)(global_classtable.get(relativeName));
      if(newclass!=null)
          throw new SynthesisException(SynthesisException.SYNTAX,"Inner class "+name+" already exists");
      newclass=new Class(className);
      newclass.declaringclass=this;
  
      Class[] scratch=new Class[innerclasses.length+1];
      System.arraycopy(innerclasses,0,scratch,0,innerclasses.length);
      scratch[innerclasses.length]=newclass;
      innerclasses=scratch;
      return newclass;
    }
    
    /**
     * Fetch a list of classes contained within this class. 
     * This doesn't address anonymous classes (those go 
     * inside method bodies and similar code), just local classes.
     * 
     * @return synthetic.Class[] object for the contained classes.
     * This may be empty if none such exist, or if the class is
     * reified (since reflection doesn't report this information).
     * @since 3/2000
     * @see forName
     */
    public Class[] getInnerClasses()
    {
      return innerclasses;
    }
    
    /**
      Returns a Field object that reflects the specified
      public member field of the class or interface
      represented by this Class object. The name
      parameter is a String specifying the simple name of
      the desired field. 
      <p>
      The field to be reflected is located by searching all
      the member fields of the class or interface
      represented by this Class object for a public field
      with the specified name. 
      <p>
      See The Java Language Specification, sections 8.2
      and 8.3. 
      
      @throws NoSuchFieldException 
      if a field with the specified name is not
      found. 
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Field 
      */
    public Field getField(String name) throws NoSuchFieldException, SecurityException
    {
      throw new java.lang.IllegalStateException();
    }
    /**
      Returns an array containing Field objects
      reflecting all the accessible public fields of the
      class or interface represented by this Class object.
      Returns an array of length 0 if the class or interface
      has no accessible public fields, or if it represents
      an array type or a primitive type. 
      <p>
      Specifically, if this Class object represents a class,
      returns the public fields of this class and of all its
      superclasses. If this Class object represents an
      interface, returns the fields of this interface and of
      all its superinterfaces. If this Class object
      represents an array type or a primitive type, returns
      an array of length 0. 
      <p>
      The implicit length field for array types is not
      reflected by this method. User code should use the
      methods of class Array to manipulate arrays. 
      <p>
      See The Java Language Specification, sections 8.2
      and 8.3. 
      
      @throws SecurityException 
      if access to the information is denied. 
      @see Field 
      */
    public Field[] getFields() throws SecurityException
    {
      if(realclass!=null && allfields==null)
        {
  	java.lang.reflect.Field[] realDF=realclass.getFields();
  	allfields=new Field[realDF.length];
  	for(int i=0;i<realDF.length;++i)
  	  allfields[i]=new Field(realDF[i],this);
        }
      
      return allfields;
    }
    /**
      Determines the interfaces implemented by the
      class or interface represented by this object. 
      <p>
      If this object represents a class, the return value is
      an array containing objects representing all
      interfaces implemented by the class. The order of
      the interface objects in the array corresponds to the
      order of the interface names in the implements
      clause of the declaration of the class represented by
      this object. 
      <p>
      If this object represents an interface, the array
      contains objects representing all interfaces
      extended by the interface. The order of the
      interface objects in the array corresponds to the
      order of the interface names in the extends clause
      of the declaration of the interface represented by
      this object. 
      <p>
      If the class or interface implements no interfaces,
      the method returns an array of length 0. 
      
      @return
      an array of interfaces implemented by this
      class. 
      */
    public Class[] getInterfaces()
    {
      if(realclass!=null && interfaces==null)
        {
  	java.lang.Class[] realI=realclass.getInterfaces();
  	interfaces=new Class[realI.length];
  	for(int i=0;i<realI.length;++i)
  	  interfaces[i]=forClass(realI[i]);
        }
      
      return interfaces;
    }
    
    /**
      Adds an "implements" description for the class or
      interface represented by this Class object
      
      @throws SynthesisException
      if the class has been reified.
      @see 
      class 
      */
    public void addImplements(Class newclass) 
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      Class[] scratch=new Class[interfaces.length+1];
      System.arraycopy(interfaces,0,scratch,0,interfaces.length);
      scratch[interfaces.length]=newclass;
      interfaces=scratch;
    }
    
    
    
    /**
      Returns a Method object that reflects the specified
      public member method of the class or interface
      represented by this Class object. The name
      parameter is a String specifying the simple name
      the desired method, and the parameterTypes
      parameter is an array of Class objects that identify
      the method's formal parameter types, in declared
      order. 
      <p>
      The method to reflect is located by searching all
      the member methods of the class or interface
      represented by this Class object for a public
      method with the specified name and exactly the
      same formal parameter types. 
      <p>
      See The Java Language Specification, sections 8.2
      and 8.4. 
      
      @throws NoSuchMethodException 
      if a matching method is not found. 
      @throws SecurityException 
      if access to the information is denied. 
      @see 
      Method 
      */
    public Method getMethod(String name, Class parameterTypes[]) throws NoSuchMethodException, SecurityException
    {
      throw new java.lang.IllegalStateException();
    }
    /**
      Returns an array containing Method objects
      reflecting all the public member methods of the
      class or interface represented by this Class object,
      including those declared by the class or interface
      and and those inherited from superclasses and
      superinterfaces. Returns an array of length 0 if the
      class or interface has no public member methods. 
      <p>
      See The Java Language Specification, sections 8.2
      and 8.4. 
      
      @throws SecurityException 
      if access to the information is denied. 
      @see Method 
      **/
    public Method[] getMethods() throws SecurityException
    {
      if(realclass!=null && allmethods==null)
        {
  	java.lang.reflect.Method[] realDM=realclass.getMethods();
  	allmethods=new Method[realDM.length];
  	for(int i=0;i<realDM.length;++i)
  	  allmethods[i]=new Method(realDM[i],this);
        }
      
      return allmethods;
    }
    /**
      Returns the Java language modifiers for this class
      or interface, encoded in an integer. The modifiers
      consist of the Java Virtual Machine's constants for
      public, protected, private, final, and interface; they
      should be decoded using the methods of class
      Modifier. 
      
      The modifier encodings are defined in The Java
      Virtual Machine Specification, table 4.1. 
      
      See Also: 
      java.lang.reflect.Modifier 
      */
    public int getModifiers()
    {
      return modifiers;
    }
  /**
      Set the Java language modifiers for this class
      or interface, encoded in an integer. The modifiers
      consist of the Java Virtual Machine's constants for
      public, protected, private, final, and interface; they
      should be decoded using the methods of class
      Modifier. 
      
      The modifier encodings are defined in The Java
      Virtual Machine Specification, table 4.1. 
      
      See Also: 
      java.lang.reflect.Modifier 
      */
    public void setModifiers(int modifiers) throws SynthesisException
    {
      if(this.realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      this.modifiers=modifiers;
    }
    
    /**
     * Retrieve the fully-qualified classname. If it's an array,
     * it will be returned in JVM syntax, not Java syntax.
     * 
     * @return java.lang.String
     * @since 12/95
     * @see getShortName
     * @see getJavaName
     * @see getJavaShortName
     */
    public java.lang.String getName() {
      return name;
    }
    
    /**
     * Like getName, but back-convert array notation escapes.
     * ***** DOESN'T YET HANDLE ARRAYS OF PRIMITIVES!
     * 
     * @return java.lang.String
     * @since 3/2000
     * @see getName
     * @see getJavaShortName
     */
    public java.lang.String getJavaName() {
      if(name.charAt(0)!='[')
          return name;
      
      // Object array syntax is [Ltypename; 
      // add another [ for each level of array
      int count=name.lastIndexOf('[');
      StringBuffer jname=new StringBuffer(name.substring(count+2));
      // Trim the trailing ';'
      jname.setLength(jname.length()-1);
      while(count-->=0)
         jname.append("[]");
      return jname.toString();
    }
    
    /**
     * Extract just the local name of this class, minus the package
     * prefix.
     * 
     * ***** I don't think this handles array types properly yet.
     * 
     * @return java.lang.String
     * @since 12/99
     * @see getName
     * @see getPackageName
     * @see getJavaName
     * @see getJavaShortName
     */
    public java.lang.String getShortName() {
      int start=name.lastIndexOf(".");
      if(start!=0 || name.charAt(0)=='.')
        ++start;
        
      if(declaringclass!=null)
      {
          int d=name.lastIndexOf('$', start);
          if(d!=0)
              start=d+1;
      }
      return name.substring(start);
    }
    /**
     * Like getShortName, but back-convert array notation escapes.
     * ***** DOESN'T YET HANDLE ARRAYS OF PRIMITIVES!
     * 
     * @return java.lang.String
     * @since 3/2000
     * @see getJavaName
     * @see getShortName
     */
    public java.lang.String getJavaShortName() {
      String shortname=getShortName();
      if(shortname.charAt(0)!='[')
          return shortname;
      
      // Object array syntax is [Ltypename; 
      // add another [ for each level of array
      int count=shortname.lastIndexOf('[');
      StringBuffer jname=new StringBuffer(shortname.substring(count+2));
      // Trim the trailing ';'
      jname.setLength(jname.length()-1);
      while(count-->=0)
         jname.append("[]");
      return jname.toString();
    }
    
    
    
    /**
     * Extract the package name for this class.
     * ***** I don't think this handles array classes properly yet.
     * 
     * @return java.lang.String
     * @since 12/95
     * @see getName
     * @see getShortName
     * @see getJavaName
     * @see getJavaShortName
     */
    public java.lang.String getPackageName() {
      int start=name.lastIndexOf(".");
      return name.substring(0,start);
    }
    
    
    /**
     * If this synthetic class is a wrapper for a "real" 
     * java.lang.Class -- either because it was instantiated as such
     * or because it has been compiled -- this method will return
     * that class. Otherwise it returns null.
     * Creation date: (12-25-99 12:26:01 PM)
     * @return synthetic.Class
     */
    public java.lang.Class getRealClass() {
      return realclass;
    }
    
    /**
     * This call is intended to allow an existing synthetic.Class
     * to be switched from purely descriptive mode to proxy mode
     * ("reified").
     * The primary intent is to allow a synthetic.Class to be
     * "compiled in place", eg by BSC.
     * <p>
     * This should have the side-effect of limiting further mutation
     * of the synthetic.Class to things which can not be obtained
     * from the real Class object, to avoid "lying" to the user
     * <p>
     * NOTE: Not all information defined by the Java libraries is
     * in fact available in all Java environments. We assume the
     * calls will work; if they return null or empty lists, there's
     * nothing we can do about it. Note that this may mean that a
     * reified class tells us less about itself than the
     * synthetic description used to generate it.
     * <p>
     * Creation date: (12-25-99 12:26:01 PM)
     * @param java.lang.class realclass nonsynthetic Class object to proxy
     */
    public void setRealClass(java.lang.Class realclass) 
         throws SynthesisException
    {
      if(this.realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      
      this.realclass=realclass;
      this.modifiers=realclass.getModifiers();
      this.isInterface=realclass.isInterface();
      
      // DEFERRED -- set them null now, reconstruct when requested
      this.declaringclass=null;
      this.interfaces=null;
      this.declaredconstructors=null;
      this.allconstructors=null;
      this.declaredmethods=null;
      this.allmethods=null;
      this.declaredfields=null;
      this.allfields=null;
      this.declaredclasses=null;
      this.allclasses=null;
      this.superclass=null;
    }
    
    
    
    /**
     * Set the superclass for this synthetic class.
     * Object is equivalent to Null.
     * Creation date: (12-25-99 12:26:01 PM)
     * @return synthetic.Class
     */
    public void setSuperClass(Class superclass)
         throws SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      this.superclass=superclass;
    }
    /**
     * Set the superclass for this synthetic class.
     * Creation date: (12-25-99 12:26:01 PM)
     * @return synthetic.Class
     */
    public void setSuperClass(java.lang.Class superclass) 
         throws ClassNotFoundException,SynthesisException
    {
      if(realclass!=null)
        throw new SynthesisException(SynthesisException.REIFIED);
      this.superclass=Class.forClass(superclass);
    }
    
    /**
      Finds a resource with the specified name. The
      rules for searching for resources associated with a
      given class are implemented by the class loader of
      the class. 
      <p>
      The Class methods delegate to ClassLoader
      methods, after applying a naming convention: if
      the resource name starts with "/", it is used as is.
      Otherwise, the name of the package is prepended,
      after converting "." to "/". 
      
      @param 
      name - the string representing the resource to
      be found. 
      @return 
      the URL object having the specified name, or
      null if no resource with the specified name
      is found. 
      @see  ClassLoader  
      @see  getResourceAsStream 
      */
    public java.net.URL getResource(String name)
    {
      throw new java.lang.IllegalStateException();
    }
    /**
      Finds a resource with a given name. Will return
      null if no resource with this name is found. The
      rules for searching a resources associated with a
      given class are implemented by the ClassLoader of
      the class.
      <p>
      The Class methods delegate to ClassLoader
      methods, after applying a naming convention: if
      the resource name starts with "/", it is used as is.
      Otherwise, the name of the package is prepended,
      after converting "." to "/". 
      
      @param 
      name - the string representing the resource to
      be found 
      @return 
      the InputStream object having the
      specified name, or null if no resource with
      the specified name is found. 
      @see ClassLoader  
      @see  getResource 
      */
    public java.io.InputStream getResourceAsStream(String name)
    {
      throw new java.lang.IllegalStateException();
    }
    /**
      Get the signers of this class.
      */
    public Object[] getSigners()
    {
      throw new java.lang.IllegalStateException();
    }
    /**
      If this object represents any class other than the
      class Object, then the object that represents the
      superclass of that class is returned. 
      <p>
      If this object is the one that represents the class
      Object or this object represents an interface, null is
      returned. 
      
      @return
      the superclass of the class represented by this
      object. 
      */
    public Class getSuperclass()
    {
     if(realclass!=null && superclass==null)
     {
          superclass=forClass(realclass.getSuperclass()); 
      	// getDeclaredClasses(); // Sets superclass as a side-effect
     }
     if(superclass==null)
      superclass=forClass(Object.class);
     return superclass;
    }
    /**
      If this Class object represents an array type, returns
      true, otherwise returns false.
      */
    public boolean isArray()
    {
      return realclass!=null && realclass.isArray();
    }
    /**
      Determines if the class or interface represented by
      this Class object is either the same as, or is a
      superclass or superinterface of, the class or
      interface represented by the specified Class
      parameter. It returns true if so, false otherwise. If
      this Class object represents a primitive type,
      returns true if the specified Class parameter is
      exactly this Class object, false otherwise. 
      <p>
      Specifically, this method tests whether the type
      represented by the specified Class parameter can
      be converted to the type represented by this Class
      object via an identity conversion or via a widening
      reference conversion. See The Java Language
      Specification, sections 5.1.1 and 5.1.4 , for details. 
      
      @throws NullPointerException if the specified Class parameter is null.
      */
    public boolean isAssignableFrom(Class cls)
    {
      if(realclass!=null && cls.realclass!=null)
        return realclass.isAssignableFrom(cls.realclass);
      
      throw new java.lang.IllegalStateException ();
    }
    /**
      Determines if the class or interface represented by
      this Class object is either the same as, or is a
      superclass or superinterface of, the class or
      interface represented by the specified Class
      parameter. It returns true if so, false otherwise. If
      this Class object represents a primitive type,
      returns true if the specified Class parameter is
      exactly this Class object, false otherwise. 
      <p>
      Specifically, this method tests whether the type
      represented by the specified Class parameter can
      be converted to the type represented by this Class
      object via an identity conversion or via a widening
      reference conversion. See The Java Language
      Specification, sections 5.1.1 and 5.1.4 , for details. 
      
      @throws NullPointerException if the specified Class parameter is null.
      */
    public boolean isAssignableFrom(java.lang.Class cls)
    {
      if(realclass!=null)
        return realclass.isAssignableFrom((java.lang.Class)cls);
      
      throw new java.lang.IllegalStateException ();
    }
    /**
      This method is the dynamic equivalent of the Java
      language instanceof operator. The method
      returns true if the specified Object argument is
      non-null and can be cast to the reference type
      represented by this Class object without raising a
      ClassCastException. It returns false otherwise. 
      <p>
      Specifically, if this Class object represents a
      declared class, returns true if the specified Object
      argument is an instance of the represented class (or
      of any of its subclasses); false otherwise. If this
      Class object represents an array class, returns true
      if the specified Object argument can be converted
      to an object of the array type by an identity
      conversion or by a widening reference conversion;
      false otherwise. If this Class object represents an
      interface, returns true if the class or any superclass
      of the specified Object argument implements this
      interface; false otherwise. If this Class object
      represents a primitive type, returns false. 
      
      @param obj The object to check 
      */
    public boolean isInstance(Object obj)
    {
      if (realclass!=null) 
        return realclass.isInstance(obj);
      
      // Scan inheritances? (reliable).
      // Check name? (not reliable).
      throw new java.lang.IllegalStateException();
    }
    /**
      Determines if the specified Class object represents
      an interface type. 
      
      @return
      true if this object represents an interface;
      false otherwise. 
      */
    public boolean isInterface()
    {
      return (realclass != null) ? realclass.isInterface() : isInterface;
    }
    /**
      Assert that the specified Class object represents
      an interface type. Can't be changed after real class loaded.
      
      @param
      true if this object represents an interface;
      false otherwise. 
      */
    public void isInterface(boolean isInterface)
    throws SynthesisException
    {
      if(realclass == null)
        this.isInterface=isInterface;
      else if (realclass.isInterface()!=isInterface)
        throw new SynthesisException(SynthesisException.REIFIED);
    }
    /**
      Determines if the specified Class object represents
      a primitive Java type. 
      <p>
      There are nine predefined Class objects to
      represent the eight primitive Java types and void.
      These are created by the Java Virtual Machine, and
      have the same names as the primitive types that
      they represent, namely boolean, byte, char, short,
      int, long, float, and double, and void. 
      <p>
      These objects may only be accessed via the
      following public static final variables, and are the
      only Class objects for which this method returns
      true. 
      */
    public boolean isPrimitive()
    {
      return realclass!=null && realclass.isPrimitive();
    }
    /**
      Creates a new instance of a class. 
      
      @return 
      a newly allocated instance of the class
      represented by this object. This is done
      exactly as if by a new expression with an
      empty argument list. 
      @throws IllegalAccessException 
      if the class or initializer is not accessible. 
      @throws InstantiationException 
      if an application tries to instantiate an
      abstract class or an interface, or if the
      instantiation fails for some other reason. 
      */
    public Object newInstance() throws InstantiationException, IllegalAccessException
    {
      throw new java.lang.IllegalStateException();
    }
    /**
      Converts the object to a string. The string
      representation is the string "class" or
      "interface" followed by a space and then the
      fully qualified name of the class. If this Class
      object represents a primitive type, returns the
      name of the primitive type.
      <p>
      ***** Should this say "synthetic" as well as "class" or
      "interface"? Or should that be gated on whether we're proxy
      to a realclass?
      
      @return a string representation of this class object. 
      */
    public String toString()
    {
      if (realclass != null)
        return realclass.toString();
      else
        if (isInterface())
  	return "interface " + name;
        else
  	return "class " + name;
    }
    
    /** Convenience for writing to, eg, System.out */
    public void toSource(java.io.OutputStream out,int depth)
    {
      java.io.PrintWriter writer=new java.io.PrintWriter(out);
      toSource(writer,depth);
    }
    
    /**
      Converts the object to a Java code stream. The string
      representation is as full a Java definition of the class
      as we are able to achieve. If this Class
      object represents a primitive type, returns the
      name of the primitive type.
      */
    public void toSource(java.io.PrintWriter out,int depth)
    {
      String tab=tabset(depth);
      
      if (realclass != null)
        out.println(tab+"/** Code back-generated from a \"real\" Class; accuracy limited by reflection APIs. */");
      else
        out.println(tab+"/** Code generated via synthetic.Class */");
      
      /* Package should not be printed for inner classes */
      if (getDeclaringClass()==null)
          out.println(tab+"package "+getPackageName()+";");
  
      out.print(tab+Modifier.toString(getModifiers()));
      if (isInterface())
        out.print(" interface ");
      else
        out.print(" class ");
      out.println(getJavaShortName());
      if(superclass!=null)
        {
  	out.print('\n'+tab+" extends "+superclass.getJavaName());
        }
      Class[] ext=getInterfaces();
      if(ext!=null & ext.length>0)
        {
  	// Interfaces extend other interfaces,
  	// Classes implement interfaces.
  	out.print('\n'+tab+
  		  (isInterface ? " extends " : " implements ")+
  		  ext[0].getName());
  	for(int i=1;i<ext.length;++i)
  	  {
  	    out.print(", "+ext[i].getJavaName());
  	  }
  	out.print("\n");
        }
  
      out.print(tab+"{\n");
      tab=tabset(++depth);
      
      // Fields--------------------------------
      Field[] fields=null;
      try
        {
  	fields=getDeclaredFields();
        } catch(SecurityException e)
  	{ out.println(tab+"//SecurityException retrieving fields"); }
        if(fields!=null)
  	{
  	  for(int i=0;i<fields.length;++i)
  	    out.println(tab+fields[i].toSource());
  	}
        
        // Constructors--------------------------
        Constructor[] ctors=null;
        try
  	{
  	  ctors=getDeclaredConstructors();
  	} catch(SecurityException e)
  	  { out.println(tab+"//SecurityException retrieving ctors"); }
  	if(ctors!=null)
  	  {
  	    for(int i=0;i<ctors.length;++i)
  	      out.print(ctors[i].toSource(tab));
  	  }
  	
  	// Methods-------------------------------
  	Method[] methods=null;
  	try
  	  {
  	    methods=getDeclaredMethods();
  	  } catch(SecurityException e)
  	    { out.println(tab+"//SecurityException retrieving methods"); }
  	  if(methods!=null)
  	    {
  	      for(int i=0;i<methods.length;++i)
  	      {
      	    out.print('\n');
  	    	out.print(methods[i].toSource(tab));
  	      }
  	    }
  	  
  	  // Inner classes --------------------------------
  	  Class[] inners=getInnerClasses();
  	  if(inners!=null)
  	  {
  	      for(int i=0;i<inners.length;++i)
  	      {
      	    out.print('\n');
  	    	inners[i].toSource(out,depth);
  	      }
  	  }
  	  
  	  // Done------------------------------
  	  tab=tabset(--depth);
  	  out.print(tab+"}\n");
  	  out.flush();
    }
    
    private String tabset(int depth)
    {
      StringBuffer t=new StringBuffer();
      while(depth-- >0)
        t.append("    ");
      return t.toString();
    }
  
    // Ignores any keywords we don't recognize
    static final int[] val=
      {Modifier.ABSTRACT,Modifier.FINAL,Modifier.INTERFACE,
      Modifier.NATIVE,Modifier.PRIVATE,Modifier.PROTECTED,
      Modifier.PUBLIC,Modifier.STATIC,Modifier.SYNCHRONIZED,
      Modifier.TRANSIENT,Modifier.VOLATILE};
    static final String[] kwd=
      {"abstract","final","interface",
      "native","private","protected",
      "public","static","synchronized",
      "transient","volatile"};
    static public int modifierFromString(String t)
    {
          for(int i=0;i<kwd.length;++i)
              if(kwd[i].equals(t))
                  return val[i];
          return 0;
    }
    static public int modifiersFromString(String s)
    {
      int mods=0;
      java.util.StringTokenizer parts=new java.util.StringTokenizer(s);
      while(parts.hasMoreTokens())
      {
          String t=parts.nextToken();
          mods|=modifierFromString(t);
      }
      return mods;
    }
  }
  
  
  
  1.1                  xml-xalan/java/src/synthetic/SynthesisException.java
  
  Index: SynthesisException.java
  ===================================================================
  // Synthetic Class descriptors ("reverse reflection")
  // Copyright �2000 International Business Machines Corportation
  // All rights reserved.
  package synthetic;
  
  public class SynthesisException
  extends Exception
  {
      int code;
      
      // Manefest constants
      public static final int SYNTAX=0;
      public static final int UNSUPPORTED=1;
      public static final int REIFIED=2;
      public static final int UNREIFIED=3;
      public static final int WRONG_OWNER=4;
      public static final String[] errToString = 
      { 
          "(Syntax error; specific message should be passed in)",
          "Feature not yet supported",
          "Can't change features of 'real' class",
          "Can't yet instantiate/invoke without 'real' class",
          "Can't add Member to an object other than its declarer",
      };
      
      
      public SynthesisException(int code)
      {
          super(errToString[code]);
          this.code=code;
      }
      
      public SynthesisException(int code, String msg)
      {
          super(msg);
          this.code=code;
      }
  
      int getCode() {return code;}
      
  }
  
  
  
  1.1                  xml-xalan/java/src/synthetic/TestDriver.java
  
  Index: TestDriver.java
  ===================================================================
  // Synthetic Class descriptors ("reverse reflection")
  // Copyright �2000 International Business Machines Corportation
  // All rights reserved.
  
  /** Test driver for com.ibm.synthetic
      <p>
      DEVELOPMENT NOTES:
      Defer construction of reified data. Probably don't need
      it all, and it builds up a significant-sized tree.
  
      toSource should probably be factored out into a separate
      java generator class, sharing an API with a BSC generator
      class.
  */
  
  package com.ibm.synthetic;
  import com.ibm.synthetic.Class;
  import com.ibm.synthetic.reflection.*;
  
  public class TestDriver
  {
      public static int sampleField=32;
      private boolean inTest=false;
      
      public static void main(String[] args)
      {
          // Proxy a class
          try
          {
              System.out.println("Proxying java.awt.Frame...");
              Class myC=Class.forName("java.awt.Frame");
              myC.toSource(System.out,0);
              System.out.println("\nProxying synthetic.TestDriver...");
              myC=Class.forName("com.ibm.synthetic.TestDriver");
              myC.toSource(System.out,0);
          }
          catch(ClassNotFoundException e)
          {
              System.out.println("Couldn't proxy: ");
              e.printStackTrace();
          }
  
          
          // Start getting serious
          try
          {
              System.out.println("\nBuild a new beast...");
              Class myC=Class.declareClass("com.ibm.synthetic.BuildMe");
              Class inner=myC.declareInnerClass("island");
              inner.addExtends(Class.forName("java.lang.String"));
              Method m=inner.declareMethod("getValue");
              m.setReturnType(Class.forName("java.lang.String"));
              m.getBody().append("return toString();");
              myC.toSource(System.out,0);
          }
          catch(ClassNotFoundException e)
          {
              e.printStackTrace();
          }
          catch(SynthesisException e)
          {
              e.printStackTrace();
          }
          catch(IllegalStateException e)
          {
              System.out.println("Unwritten function: "+e);
              e.printStackTrace();
          }
      }
  
      public static void dumpClass(Class C)
      {
          System.out.println("toString(): "+C);
          System.out.println("\tisPrimitive(): "+C.isPrimitive());
          System.out.println("\tisInterface(): "+C.isInterface());
          System.out.println("\tisInstance(\"foo\"): "+C.isInstance("foo"));
          System.out.println("\tisArray(): "+C.isArray());
          System.out.println("\tgetRealClass(): "+C.getRealClass());
      }
  
      /* Test for something we plan to do in BSC */
      public void quickcheck()
      {
          Inner a=new Inner();
          a.setTest(!a.getTest());
      }
      private class Inner
      {
          public boolean getTest()
          {
              return inTest;
          }
          public void setTest(boolean test)
          {
              inTest=test;
          }
      }
      
  }