package jde.wizards; import java.io.PrintWriter; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Vector; /** * Defines a factory for creating skeleton implementations of the abstract * methods of Abstract Java classes. The factory can be invoked from the * command line or from another program. * * * This class extends the interface factory to handle Abstract classes * Copyright (c) Javier Lopez 2001. All Rights Reserved. * * AbstractClassFactory 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. * * AbstractClassFactory 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. * * @author Javier Lopez * @version $Revision: 1.5 $ */ public class AbstractClassFactory extends InterfaceFactory { /** The interface factory. */ static AbstractClassFactory abstractClassFactory; /** * Creates a new AbstractClassFactory instance. * */ public AbstractClassFactory() { } /** * Creates an AbstractClassFactory that uses the specified NameFactory for * generating parameter names * * @param factory Factory for generating parameter names */ public AbstractClassFactory(NameFactory factory) { super(factory); } /** * Generates signatures based on introspection of the specified interface. * Strips package specifiers from generated signatures. * * @param argAbstracClassName the abstract class to process for signatures. * @exception NotAnAbstractClassException the requested class isn't an * abstract classes * @exception ClassNotFoundException the requested class cannot * be loaded */ public void process(String argAbstracClassName) throws ClassNotFoundException, NotAnAbstractClassException { process(argAbstracClassName, true); } /** * Generates signatures based on introspection of the specified class. * * @param name the abstract class to process for signatures. * @param truncate toggles truncation of package specifiers in signatures. * * @exception NotAnAbstractClassException the requested class isn't an * abstract class * @exception ClassNotFoundException the requested class cannot * be loaded */ public void process(String name, boolean truncate) throws ClassNotFoundException, NotAnAbstractClassException { if (null == namefactory) { namefactory = new DefaultNameFactory(); } Class aclass = Class.forName(name); int iModifiers = aclass.getModifiers(); if (!Modifier.isAbstract(iModifiers)) { throw new NotAnAbstractClassException(name); } Vector methods = new Vector(); getAbstractMethods(aclass, methods); int size = methods.size(); for (int i = 0; i < size; i++) { sortByDeclaringClass(new Signature((Method) methods.get(i), this, truncate)); } } /** * Creates a list of the abstract methods in argClass * * @param argClass Class to obtained the abstract methods from * @param abstractMethods Contains a list of the abstract methods. */ private void getAbstractMethods(Class argClass, Vector abstractMethods) { Method[] methods = argClass.getDeclaredMethods(); Method method; int modifiers; for (int i = 0; i < methods.length; i++) { method = methods[i]; modifiers = method.getModifiers(); // if the method is abstract and public or protected if (Modifier.isAbstract(modifiers) && (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers))) { abstractMethods.add(method); } } //Check the super class. Class superClass = argClass.getSuperclass(); if (superClass != null) { getAbstractMethods(superClass, abstractMethods); } //Adds methods defined in implemented interfaces. Class[] interfaces = argClass.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { getAbstractMethods(interfaces[i], abstractMethods); } } /** * Prints the imports required to extend the abstract class. * */ public static void getImportedClasses() { println(abstractClassFactory.getImportsAsList()); } /** * Makes an implementation of the abstract methods of an abstract class. * This method delegates the creation of the implementation to * makeAbstractClassInternal. * * @param name Name of abstract class to be implemented. * @param truncate If true, truncate package specifier * when generating code. */ public static void makeAbstractClassExpression (String name, boolean truncate) { if (abstractClassFactory == null) { abstractClassFactory = new AbstractClassFactory(); } abstractClassFactory.flush(); abstractClassFactory.makeAbstractClassExpressionInternal(name, truncate); } /** * Makes an implementation of the abstract methods of an abstract class. * * @param name Name of abstract class to be implemented. * @param truncate If true, truncate package specifier * when generating code. */ private void makeAbstractClassExpressionInternal (String name, boolean truncate) { try { process(name, truncate); } catch (ClassNotFoundException e) { println("(error \"Error: could not find abstract class named: " + name + ". " + "Note: name must be qualified.\")"); return; } catch (NotAnAbstractClassException e) { println("(error \"Error: " + name + " is not an abstract class.\")"); return; } catch (Exception e) { e.printStackTrace(); println("(error \"Error: unknown type.\")"); return; } dumpExpression(new PrintWriter(System.out, true), truncate); } /** * Test this class. * * @param args a String[] value */ public static void main(String[] args) { AbstractClassFactory.makeAbstractClassExpression("java.net.SocketImpl", false); } } /** * The specified class is not an abstract class. * * @author Paul Kinnucan * @version 1.0 */ class NotAnAbstractClassException extends NotAnInterfaceException { /** * Creates a new NotAnAbstractClassException instance. * * @param name a String value */ NotAnAbstractClassException (String name) { super(name); } }// End of AbstractClassFactory /* * $Log: AbstractClassFactory.java,v $ * Revision 1.5 2002/12/04 07:16:38 paulk * Cosmetic changes. * * Revision 1.4 2002/08/30 12:50:10 jslopez * Fixes regression bug. * Now methods defined in super classes and interfaces are as well * added. * * Revision 1.3 2002/08/30 12:29:58 jslopez * Fixes bug generating abstract class skeletons. * * Revision 1.2 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.1 2001/08/04 03:14:06 paulk * Initial revision. * */