On 01 Aug 2000, Raffael Herzog stated:
> I made a little extension to the delegate wizard. When I first used
> this feature I found myself in adding "@see Class#method" to every
> method of the generated generation. That's why added the generation
> of this to the delegate wizard.
> 
> Updated DelegateFactory.java and Signature.java are attached.

Think before you post! :-)

"@see HashMap#notify()" won't work! It should be "@see Object#notify()".

Updated code attached.


-- 
Raffael Herzog
[EMAIL PROTECTED]

May the penguin be with you!

/*
 * Copyright (c) Eric D. Friedman 2000. All Rights Reserved.
 * Copyright (c) Paul Kinnucan 2000. All Rights Reserved.
 * Copyright (c) Charles Hart 2000. All Rights Reserved.
 *
 * $Revision: 1.1 $ 
 * $Date: 2000/07/14 05:26:55 $ 
 *
 * DelegateFactory is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 *
 * DelegateFactory is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * To obtain a copy of the GNU General Public License write to the
 * Free Software Foundation, Inc.,  59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.  
 */

package jde.wizards;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;

/**
 * Defines a factory for creating  skeleton implementations of 
 * Java interfaces. The factory can be invoked from the command line
 * or from another program. The factory can generate implementations for
 * multiple interfaces when invoked from the command line.
 *
 * @author Charles Hart, Eric D. Friedman, and Paul Kinnucan
 * @version $Revision: 1.1 $
 */

public class DelegateFactory extends MethodFactory
{

  /** A table w/ declaring classes as keys and vectors of method
   * signatures as values */
  private Hashtable interfaces = new Hashtable();

  /** The interface factory. */
  static DelegateFactory delegateFactory;
  
  public DelegateFactory() {}

  /** 
   * Creates an DelegateFactory that uses the specified NameFactory
   * for generating parameter names 
   *
   * @param factory Factory for generating parameter names
   */
  public DelegateFactory(NameFactory factory)
  {
    super(factory);
  }

  /** 
   * Adds a signature to the signature table.
   * The signatures are stored in Vectors with their declaring
   * Classes as keys in a hashtable.  This allows them to be pulled
   * out in groups when we print, and keeping the declaring Class info
   * lets us put in comments about where the method (or method group)
   * comes from.  Signatures are not added if they're already registered
   * because we do not want duplicate method implementations even though
   * a class might implement interfaces that inherit from some common
   * super-interface. 
   *
   * @param sig Signature to be stored in the signature table.
   */
  private final void sortByDeclaringClass(Signature sig)
  {
    String declaring = sig.getDeclaringClass().getName();
    if (interfaces.containsKey( declaring ))
    {
      Vector v = (Vector)interfaces.get( declaring );
      if (! v.contains( sig ) ) // "There can be only one" - the Highlander
        v.addElement(sig);
    } // end of if (interfaces.containsKey( dec ))
    else
    {
      Vector v = new Vector();
      v.addElement(sig);
      interfaces.put( declaring, v );
    } // end of else
  }


  /** 
   * Clears the import and interface hashtables for this factory so they
   * can be re-used to process a new set of interfaces.
   */
  public void flush()
  {
    super.flush();
    interfaces.clear();
  }

  
  /**
   * Generates signatures based on introspection of the specified interface. 
   * Strips package specifiers from generated signatures.
   *
   * @param name the interface to process for signatures.
   * @exception java.lang.ClassNotFoundException the requested class cannot be loaded 
   */
  public void process(String interfaceName)
    throws ClassNotFoundException
  {
    process(interfaceName, true);
  }  
  
  /**
   * Generates signatures based on introspection of the specified class.
   *
   * @param name the interface to process for signatures.
   * @param truncate toggles truncation of package specifiers in signatures..
   *
   * @exception java.lang.ClassNotFoundException the requested class cannot be loaded 
  */
  public void process(String name, boolean truncate)
    throws ClassNotFoundException
  {
    if (null == namefactory)
      namefactory = new DefaultNameFactory();
    
    Class aclass = Class.forName( name );    

    Method[] methods = aclass.getMethods();
    for (int i = 0; i < methods.length; i++)
      sortByDeclaringClass( new Signature( methods[i], this, truncate, true ));
  }


  /**
   * Makes an implementation of an interface. This method delegates the creation
   * of the implementation to makeInterfaceInternal.
   *
   * @param name Name of interface to be implemented.
   * @param javadoc If <code>true</code> generate skeletal Javadoc for the 
implementation.
   * @param truncate If <code>true</code>, truncate package specifier when generating 
code.
   * @param newline If <code>true</code>, insert a newline after opening brace.
   * 
   */
  public static void makeDelegates(String attributeName,
                                   String className, 
                                   boolean javadoc,
                                   boolean truncate,
                                   boolean newline) {

    if (delegateFactory == null)
      delegateFactory = new DelegateFactory();

    delegateFactory.flush();
    delegateFactory.makeInterfaceInternal(attributeName, className, javadoc, 
                                          truncate, newline);

  }

 /**
   * Makes an implementation of an interface.
   *
   * @param name Name of interface to be implemented.
   * @param javadoc If <code>true</code> generate skeletal Javadoc for the 
implementation.
   * @param truncate If <code>true</code>, truncate package specifier when generating 
code.
   * @param newline If <code>true</code>, insert a newline after opening brace.
   * 
   */
  private void makeInterfaceInternal(String attributeName,
                                     String className,
                                     boolean javadoc,
                                     boolean truncate,
                                     boolean newline) {
    try {
      process(className, truncate);
    }
    catch (ClassNotFoundException e) {
      println("(error \"Error: could not find class named: " + className + ". "
              + "Note: name must be qualified.\")");
      return;
    }
    catch (Exception e) {
      println("(error \"Error: unknown type.\")");
      return;
    }

    dump(new PrintWriter( System.out, true),
         attributeName,
         javadoc,
         truncate,
         newline );
  }


  public static void getImportedClasses() {
    String res = "(list ";
    Enumeration i = delegateFactory.imports.keys();
    while (i.hasMoreElements()) {
      Class c = (Class) i.nextElement();
      res += "\"" + c.getName() + "\" ";
    }
    res += ")";
    println(res);
  }


  public String getMethodSkeleton(Signature sig,
                                  boolean javadoc,
                                  boolean newline,
                                  String attributeName)
  {
    String res = "";
    res += "\n" ;
    if (javadoc)
      res += sig.toJavaDoc() + "\n";
    if (newline)
      {
        res += sig  + "\n";
        res += "{\n";
      }
    else
      res += sig + " {\n";
          
    Method m = sig.getMethod();
    Class cl = m.getReturnType();

    if (! cl.getName().equals("void"))
      res += "  return "+attributeName+"."+m.getName()+
             "("+sig.getParameterNames(m.getParameterTypes())+");\n";
    else
      res += "  "+attributeName+"."+m.getName()+
             "("+sig.getParameterNames(m.getParameterTypes())+");\n";

    res += "}\n";
    return res;
  }

  public void dump(PrintWriter out,
                   String attributeName,
                   boolean javadoc,
                   boolean truncate,
                   boolean newline)
  {
    StringBuffer buf = new StringBuffer("\"");

    Enumeration declaring_classes = interfaces.keys();
    while (declaring_classes.hasMoreElements())
    {
      String interf = (String)declaring_classes.nextElement();
      Vector v = (Vector)interfaces.get(interf);
      buf.append("// Code for delegation of ");
      buf.append(interf);
      buf.append(" methods to ");
      buf.append(attributeName);
      buf.append("\n");
      Enumeration e = v.elements();
      while (e.hasMoreElements())
      {
        Signature sig = (Signature)e.nextElement();
        buf.append(getMethodSkeleton(sig, javadoc, newline, attributeName));
      } // end of while (e.hasMoreElements())
    }
    buf.append("\"");
    println(buf.toString());
  }
} // SignatureFactory

/*
 * $Log: DelegateFactory.java,v $
 * Revision 1.1  2000/07/14 05:26:55  paulk
 * Adds support for delegation wizard.
 *
 */

// End of DelegateFactory.java
/*
 * Copyright (c) Eric D. Friedman 1998. All Rights Reserved.
 * Copyright (c) Paul Kinnucan 1998. All Rights Reserved.
 *
 * $Revision: 1.6 $ 
 * $Date: 2000/07/14 05:26:56 $ 
 *
 * InterfaceFactory is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2, or (at
 * your option) any later version.
 *
 * InterfaceFactory is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * To obtain a copy of the GNU General Public License write to the
 * Free Software Foundation, Inc.,  59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.  
 */

package jde.wizards;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Defines a method signature.
 *
 * @author Eric D. Friedman
 * @version $Revision: 1.6 $
 */

public class Signature
{
  /** 
   * The method represented by this signature 
  */
  private Method method;

  /** 
   * the parameters in this signature 
   */
  private Class[] parameters;

  /** 
   * the exceptions thrown by this signature 
   */
  private Class[] exceptions;

  /** 
   * the return value 
   */
  private Class return_value;

  /** 
   * The Class that declared this signature
   */
  private Class declaring;

  /**
   * the InterfaceFactory processing this signature 
   */
  private ClassRegistry registry;

  /**
   * Toggles truncation of package information in signatures 
   */
  private boolean truncate;

  /**
   * Toggles generation of see
   */
  private boolean see;

  /** 
   * Creates a signature for the specified method and register
   * its types with the specified registry (which may be null).
   * Removes package info from generated signatures.
   *
   * @param meth Method represented by this signature
   * @param aregistry Registry containing this signature
   */
  public Signature (Method meth, ClassRegistry aregistry)
  {
    this(meth,aregistry,true);
  }

  /** 
   * Creates a signature for the specified method and register its
   * types with the specified registry (which may be null).
   *
   * @param meth Method represented by thi signature
   * @param aregistry Registry containing this signature
   * @param truncate toggles removal of package info from generated signatures 
   */
  public Signature (Method meth, ClassRegistry aregistry, boolean truncate)
  {
    this(meth,aregistry,true, false);
  }

  /** 
   * Creates a signature for the specified method and register its
   * types with the specified registry (which may be null).
   *
   * @param meth Method represented by thi signature
   * @param aregistry Registry containing this signature
   * @param truncate toggles removal of package info from generated signatures 
   * @param see Class to link the see section to or null, if no see section should be 
created
   */
  public Signature (Method meth, ClassRegistry aregistry, boolean truncate, boolean 
see)
  {
    this.method   = meth;
    this.registry = aregistry;
    this.truncate = truncate;
    this.see = see;
    
    parameters   = method.getParameterTypes();
    exceptions   = method.getExceptionTypes();
    return_value = method.getReturnType();
    declaring    = method.getDeclaringClass();

    register();
  }

  /** 
   * Toggles truncation of package info .
   * 
   * @param b Truncation toggle
   */
  public void setTruncating( boolean b )
  {
    truncate = b;
  }

  /** 
   * Sets the registry used to register this signature's types.
   * 
   * @param registry Registry used to register this signature's type.
   */
  public void setRegistry(ClassRegistry registry )
  {
    this.registry = registry;
  }

  /** 
   * Gets the class that declared the method represented by this signature.
   *
   * @return The class this method was declared in 
   */
  public Class getDeclaringClass ()
  {
    return declaring;
  }

  /** 
   * Generates a javadoc string for this signature.
   * 
   * @return A javadoc for this method
   */
  public String toJavaDoc()
  {
    NameFactory factory = registry.getNameFactory();
    StringBuffer buf = new StringBuffer("/**\n *\n *");
    for (int i = 0; i < parameters.length; i++)
      buf.append(" @param " +
                 factory.getParameterName(parameters[i],
                                 i + 1,
                                 parameters.length) +
                 " <description>\n *");

    if (! "void".equals(return_value.getName()))
      buf.append(" @return <description>" + "\n *");
    for (int i = 0; i < exceptions.length; i++)
      buf.append(" @exception " + exceptions[i].getName() + " <description>\n *");
    if (see) {
      buf.append(" @see ");
      buf.append(method.getDeclaringClass().getName());
      buf.append('#');
      buf.append(method.getName());
      buf.append('(');
      buf.append(getParameters(method.getParameterTypes(), false));
      buf.append(')');
      buf.append("\n *");
    }
    buf.append("/");
    return buf.toString();
  }

  /** 
   * Gets the signature as a string.
   *
   * @return Signature of this method.
   */
  public String toString()
  {
    String m    = getModifiers();
    String r    = baseName( return_value );
    String meth = method.getName();

    String p    = getParameters( parameters );
    String e    = getExceptions( exceptions );

    return m + " " + r + " " + meth + "(" + p + ")" + e;
  }

  public boolean paramsEqual(Class[] p) {
    int n = parameters.length;
    boolean res = (p.length == n);
    if (res) 
      for (int i = 0; i < n; ++i) 
        if (! p[i].equals(parameters[i])) {
          res = false;
          break;
        }
    return res;
  }

  /**
   * Tests whether a given object equals this signature.
   * The object is considered equal if it is a signature
   * and it has the same method name and parameter list.
   *
   * @param compare Test object
   * @return <code>true</code> if the test object equals this signature.
   */
  public boolean equals(Object compare)
  {
    if (compare instanceof Signature)
    {
      Signature sig = (Signature)compare;
      return method.getName().equals( sig.getMethod().getName() ) &&
             paramsEqual(sig.getMethod().getParameterTypes());
    }
    return false;
  }

  /**
   * Gets the method of which this is a signature.
   *
   * @return Method of which this is a signature.
   */
  public Method getMethod()
  {
    return method;
  }
    
  /** 
   *  Computes the basename of the specified class.  This returns
   *  "Object" from "java.lang.Object."  It returns the "single"
   *  form of an Array object. 
   *
   * @param type Class whose basename is required
   * 
   * @return basename
   */
  public final String baseName(Class type)
  {
    String name = null;
    if (type.isArray())
    {
      try
      {
        Class cl       = type;
        int dimensions = 0;
        while (cl.isArray())
        {
          cl = cl.getComponentType();
          dimensions++;
        }
        StringBuffer sb = new StringBuffer();
        sb.append(cl.getName());
        for (int i = 0; i < dimensions; i++)
          sb.append("[]");
        name = sb.toString();
      }
      catch (Throwable e)
      {
        name = type.getName();
      }
    }
    else
      name = type.getName();
      
    if (truncate)
    {
      int idx = name.lastIndexOf( '.' );
      if (idx > -1)
        return name.substring( idx + 1 );
    } // end of if (truncate)

    return name;
  }

  /** 
   * Gets a throw clause listing the exceptions thrown by this method.
   * 
   * @param except Vector of exceptions
   *
   * @return Exceptions thrown by this method.
   */
  private final String getExceptions(Class[] except)
  {
    if ((null == except) || (except.length == 0))
      return "";
    StringBuffer buf = new StringBuffer(" throws ");

    for (int i = 0; i < except.length; i++)
    {
      String type = baseName( except[i] );

      buf.append( type );
      if (i < except.length - 1)
        buf.append(", ");
    } // end of for (int i = 0; i < except.length; i++)
    return buf.toString();
  }

  /** 
   * Gets a parameter list for this method; parameters are named
   * by the NameFactory whose default implementation uses param1
   * .. paramn 
   *
   * @param params Parameters of this method
   *
   * @return Parameter list in string form
   */
  public final String getParameters (Class[] params)
  {
    return getParameters(params, true);
  }

  /** 
   * Gets a parameter list for this method; parameters are named
   * by the NameFactory whose default implementation uses param1
   * .. paramn 
   *
   * @param params Parameters of this method
   * @param withName toggles parameter names
   *
   * @return Parameter list in string form
   */
  public final String getParameters (Class[] params, boolean withName)
  {
    if ((null == params) || (params.length == 0))
      return "";
    StringBuffer buf = new StringBuffer();
    NameFactory factory = registry.getNameFactory();

    for (int i = 0; i < params.length; i++)
    {
      String type = baseName( params[i] );
      String name = factory.getParameterName(params[i], i + 1, params.length );

      buf.append( type );
      if ( withName ) {
        buf.append(' ');
        buf.append( name );
      }

      if (i < params.length - 1)
        buf.append(", ");
    } // end of for (int i = 0; i < params.length; i++)

    return buf.toString();
  }

  /** 
   * Gets a list of parameter names for this method; parameters are
   * named by the NameFactory whose default implementation uses param1
   * .. paramn.  Class type names are not included in the result
   * Contributed by Charles Hart <[EMAIL PROTECTED]>
   *
   * @param params Parameters of this method
   *
   * @return Parameter list in string form */
  public final String getParameterNames (Class[] params)
  {
    if ((null == params) || (params.length == 0))
      return "";
    StringBuffer buf = new StringBuffer();
    NameFactory factory = registry.getNameFactory();

    for (int i = 0; i < params.length; i++)
    {
      String type = baseName( params[i] );
      String name = factory.getParameterName(params[i], i + 1, params.length );

      buf.append( name );

      if (i < params.length - 1)
        buf.append(", ");
    } // end of for (int i = 0; i < params.length; i++)

    return buf.toString();
  }

  /** 
   * Gets list of modifiers for this method.
   * Interface methods are always public and may be synchronized 
   */ 
  private final String getModifiers ()
  {
    StringBuffer buf = new StringBuffer("public");
    int mod = method.getModifiers();

    if ( Modifier.isSynchronized( mod ) )
      buf.append(" synchronized");
    return buf.toString();
  }

  /** 
   * Register this Signature's types with the SignatureRegistry
   */
  private final void register()
  {
    if (null != registry)
    {
      registry.registerImport( declaring );
      registry.registerImport( return_value );
    
      for (int i = 0; i < parameters.length; i++)
        registry.registerImport( parameters[i] );

      for (int i = 0; i < exceptions.length; i++)
        registry.registerImport( exceptions[i] );
    }
  }

} // end of Signature class

/*
 * $Log: Signature.java,v $
 * Revision 1.6  2000/07/14 05:26:56  paulk
 * Adds support for delegation wizard.
 *
 */

// End of Signature.java

Reply via email to