/*
* 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.6 $
* $Date: 2003/09/07 05:29:12 $
*
* 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;
/**
* Defines a factory for generating methods that delegate tasks
* to be performed by an instance of one class (the delegator)
* to an instance of another class (the delegee. The delegator
* must have a field that references the delegee.
*
* @author Charles Hart, Eric D. Friedman, and Paul Kinnucan
* @version $Revision: 1.6 $
*/
public class DelegateFactory extends MethodFactory {
/** A container for the signatures of the delegation methods
* to be generated by this factory. */
private SignatureContainer signatures = new SignatureContainer();
/** The delegate factory. */
private static DelegateFactory delegateFactory;
/**
* Name of the delegator field that references the delegee.
*
*/
private String delegee;
/**
* Creates a new DelegateFactory
instance.
*
*/
public DelegateFactory() { }
/**
* Creates a DelegateFactory that uses the specified NameFactory
* for generating parameter names
*
* @param factory Factory for generating parameter names
*/
public DelegateFactory(NameFactory factory) {
super(factory);
}
/**
* Gets a container containing the signatures of the delegation
* methods.
*
* @return the value of signatures
*/
public SignatureContainer getSignatures() {
return this.signatures;
}
/**
* Specifies a container to hold the signatures of the
* delegator methods.
*
* @param argSignatures signature container
*/
public void setSignatures(SignatureContainer argSignatures) {
this.signatures = argSignatures;
}
/**
* Gets the Delegate Factory
*
* @return the Delegate Factory
*/
public static DelegateFactory getTheFactory() {
return DelegateFactory.delegateFactory;
}
/**
* Sets the Delegate Factory
*
* @param argDelegateFactory the Delegate Factory
*/
public static void setTheFactory(DelegateFactory argDelegateFactory) {
DelegateFactory.delegateFactory = argDelegateFactory;
}
/**
* Gets the name of the delegator field that references the delegee.
*
* @return name of the delegee
*/
public String getDelegee() {
return this.delegee;
}
/**
* Specifies the name of the delegator field that references the delegee.
*
* @param argDelegee the delegee
*/
public void setDelegee(String argDelegee) {
this.delegee = argDelegee;
}
/**
* Clears the method signatures container.
*/
public void flush() {
super.flush();
signatures.clear();
}
/**
* Generates method signatures based on introspection of the
* specified interface. Strips package specifiers from generated
* signatures.
*
* @param interfaceName the interface to process for signatures.
* @exception ClassNotFoundException Cannot find interface
*/
public void process(String interfaceName)
throws ClassNotFoundException {
process(interfaceName, true);
}
/**
* Generates signatures for the public methods of the delegee
* class.
*
* @param delegeeClassName name of the delegee's class
* @param truncate toggles truncation of package specifiers in signatures.
*
* @exception ClassNotFoundException the requested class cannot
* be loaded
*/
public void process(String delegeeClassName, boolean truncate)
throws ClassNotFoundException {
if (null == namefactory) {
namefactory = new DefaultNameFactory();
}
Class aclass = Class.forName(delegeeClassName);
Method[] methods = aclass.getMethods();
for (int i = 0; i < methods.length; i++) {
if (!(methods[i].getDeclaringClass().getName().equals("java.lang.Object")
&& Modifier.isFinal(methods[i].getModifiers()))) {
signatures.add(new Signature(methods[i], this, truncate, true));
}
}
}
/**
* Generate delegator methods.
*
* @param delegeeFieldName Name of delagator field that reference
* the delegee.
* @param delegeeClassName Name of delegee class.
* @param truncate If true
, truncate package specifier
* when generating code.
*
*/
private void makeDelegatorMethodsInternal(String delegeeFieldName,
String delegeeClassName,
boolean truncate) {
delegee = delegeeFieldName;
try {
process(delegeeClassName, truncate);
} catch (ClassNotFoundException e) {
println("(error \"Error: could not find class named: "
+ delegeeClassName + ". "
+ "Note: name must be qualified.\")");
return;
} catch (Exception e) {
println("(error \"Error: unknown type.\")");
return;
}
outputMethods(new PrintWriter(System.out, true), truncate);
}
/**
* Generates delegator methods.
*
* @param delegeeFieldName Name of delegator field that
* references the delegee.
* @param delegeeClassName Name of delegee's class.
* @param truncate If true
, truncate package specifier
* when generating code.
*/
public static void makeDelegatorMethods(String delegeeFieldName,
String delegeeClassName,
boolean truncate) {
if (delegateFactory == null) {
delegateFactory = new DelegateFactory();
}
delegateFactory.flush();
delegateFactory.makeDelegatorMethodsInternal(delegeeFieldName,
delegeeClassName,
truncate);
}
/**
* Describe getImportedClasses
method here.
*
*/
public static void getImportedClasses() {
println(delegateFactory.getImportsAsList());
}
/**
* Return a default body for the implementation of the method described
* by sig
.
*
* @param sig a Signature
value
* @return a String
value
*/
protected String getDefaultBody (Signature sig) {
Method m = sig.getMethod();
Class cl = m.getReturnType();
String defBody = "";
defBody = delegee + "." + m.getName()
+ "(" + sig.getParameterNames() + ");";
if (!cl.getName().equals("void")) {
defBody = "return " + defBody;
}
return defBody;
}
/**
* Prints delegator methods to the standard out of
* the current process, i.e., to Emacs.
*
* @param out a PrintWriter
value
* @param truncate a boolean
value
*/
public void outputMethods(PrintWriter out, boolean truncate) {
final StringBuffer buf = new StringBuffer
("(jde-wiz-gen-delegation-methods (list ");
signatures.visit(new SignatureVisitor() {
public void visit(Signature sig , boolean firstOfClass) {
if (firstOfClass) {
buf.append ("(quote ");
buf.append("\"Code for delegation of ");
buf.append(sig.getDeclaringClass().getName());
buf.append(" methods to ");
buf.append(delegee);
buf.append("\")");
}
buf.append ("(quote ");
buf.append(getMethodSkeletonExpression(sig));
buf.append (")");
}
});
buf.append("))");
println(buf.toString());
}
} // DelegateFactory
/*
* $Log: DelegateFactory.java,v $
* Revision 1.6 2003/09/07 05:29:12 paulk
* Check for duplicate methods defined by different classes or interfaces.
* Thanks to Martin Schwamberg.
*
* Revision 1.5 2002/06/06 05:12:44 paulk
* DefaultNameFactory now generates meaningful method parameter names based
* on the parameter type or the method name. Thanks to Ole Arndt.
*
* Revision 1.4 2002/05/14 06:38:44 paulk
* Enhances code generation wizards for implementing interfaces, abstract
* classes, etc., to use customizable templates to generate skeleton methods
* instead of hard-wired skeletons. Thanks to "Dr. Michael Lipp"
* for proposing and implementing this improvement.
*
* Revision 1.3 2000/08/03 04:31:20 paulk
* Add support for generating a see secton in the Javadoc comment for a method.
* Thanks to raffael.herzog@comartis.com
*
* Revision 1.2 2000/08/01 08:19:25 paulk
* Fixes bug in dump method .Thanks to eric@hfriedman.rdsl.lmi.net.
*
* Revision 1.1 2000/07/14 05:26:55 paulk
* Adds support for delegation wizard.
*
*/
// End of DelegateFactory.java