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