/* * 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