Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / wizards / AbstractClassFactory.java
1 package jde.wizards;
2
3 import java.io.PrintWriter;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Modifier;
6 import java.util.Vector;
7
8 /**
9  * Defines a factory for creating skeleton implementations of the abstract
10  * methods of Abstract Java classes. The factory can be invoked from the
11  * command line or from another program.
12  *
13  * 
14  * This class extends the interface factory to handle Abstract classes
15  * Copyright (c) Javier Lopez 2001. All Rights Reserved.
16  *
17  * AbstractClassFactory is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU General Public License as
19  * published by the Free Software Foundation; either version 2, or (at
20  * your option) any later version.
21  *
22  * AbstractClassFactory is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * General Public License for more details.
26  *
27  * To obtain a copy of the GNU General Public License write to the
28  * Free Software Foundation, Inc.,  59 Temple Place - Suite 330,
29  * Boston, MA 02111-1307, USA.  
30  *
31  * @author Javier Lopez
32  * @version $Revision: 1.7 $
33  */
34 public class AbstractClassFactory extends InterfaceFactory {
35
36     /** The interface factory. */
37     static AbstractClassFactory abstractClassFactory;
38   
39     public AbstractClassFactory() {}
40
41     /** 
42      * Creates an AbstractClassFactory that uses the specified NameFactory for
43      * generating parameter names
44      *
45      * @param factory Factory for generating parameter names
46      */
47     public AbstractClassFactory(NameFactory factory) {
48         super(factory);
49     }
50
51     /**
52      * Generates signatures based on introspection of the specified interface.
53      * Strips package specifiers from generated signatures.
54      *
55      * @param argAbstracClassName the abstract class to process for signatures.
56      * @exception NotAnAbstractClassException the requested class isn't an
57      * abstract class
58      * @exception java.lang.ClassNotFoundException the requested class cannot
59      * be loaded
60      */
61     public void process(String argAbstracClassName)
62         throws ClassNotFoundException, NotAnAbstractClassException {
63         process(argAbstracClassName, true);
64     }  
65   
66     /**
67      * Generates signatures based on introspection of the specified class.
68      *
69      * @param name the abstract class to process for signatures.
70      * @param truncate toggles truncation of package specifiers in signatures.
71      *
72      * @exception NotAnAbstractClassException the requested class isn't an
73      * abstract class
74      * @exception java.lang.ClassNotFoundException the requested class cannot
75      * be loaded
76      */
77     public void process(String name, boolean truncate)
78         throws ClassNotFoundException, NotAnAbstractClassException {
79         if (null == namefactory)
80             namefactory = new DefaultNameFactory();
81     
82         Class aclass = Class.forName(name);
83         int iModifiers = aclass.getModifiers();
84         if (!Modifier.isAbstract(iModifiers))
85             throw new NotAnAbstractClassException(name);
86     
87         Vector methods = new Vector();
88         getAbstractMethods(aclass, methods);
89         int size = methods.size();
90         for (int i = 0; i < size; i++)
91             sortByDeclaringClass(new Signature((Method)methods.get(i),
92                                                this,
93                                                truncate));
94     }
95
96     /**
97      * Creates a list of the abstract methods in argClass
98      *
99      * @param argClass Class to obtained the abstract methods from
100      * @param abstractMethods Contains a list of the abstract methods.
101      * @return a <code>Methods[]</code> containing abstract methods
102      */
103     private void getAbstractMethods(Class argClass, Vector abstractMethods) {
104         Method[] methods = argClass.getMethods();
105         Method[] declaredMethods = argClass.getDeclaredMethods();
106         addMethods(methods, abstractMethods);
107         addMethods(declaredMethods, abstractMethods);
108     }
109
110     /**
111      * Adds the abstract methods in <code>methods</code> into abstractMethods.
112      *
113      * @param methods a <code>Method[]</code> to be added
114      * @param abstractMethods a <code>Vector</code> to add abstract methods.
115      */
116     private void addMethods(Method[] methods, Vector abstractMethods) {
117         Method method;
118         int modifiers;
119         for (int i = 0; i < methods.length; i++) {
120             method = methods[i];
121             modifiers = method.getModifiers();
122             
123             if (Modifier.isAbstract(modifiers)
124                 && !abstractMethods.contains(method)) {
125                 abstractMethods.add(method);
126             } // end of if (method)
127         } // end of for (int i = 0; i < methods.length; i++)
128     }
129
130     public static void getImportedClasses() {
131         println(abstractClassFactory.getImportsAsList());
132     }
133   
134     /**
135      * Makes an implementation of the abstract methods of an abstract class.
136      * This method delegates the creation of the implementation to
137      * makeAbstractClassInternal.
138      *
139      * @param name Name of abstract class to be implemented.
140      * @param truncate If <code>true</code>, truncate package specifier
141      * when generating code.
142      */
143     public static void makeAbstractClassExpression 
144         (String name, boolean truncate) {
145     
146         if (abstractClassFactory == null)
147             abstractClassFactory = new AbstractClassFactory();
148     
149         abstractClassFactory.flush();
150         abstractClassFactory.makeAbstractClassExpressionInternal(name,
151                                                                  truncate);
152     }
153
154     /**
155      * Makes an implementation of the abstract methods of an abstract class.
156      *
157      * @param name Name of abstract class to be implemented.
158      * @param truncate If <code>true</code>, truncate package specifier
159      * when generating code.
160      */
161     private void makeAbstractClassExpressionInternal 
162         (String name, boolean truncate) {
163         try {
164             process(name, truncate);
165         } catch (ClassNotFoundException e) {
166             println("(error \"Error: could not find abstract class named: " 
167                     + name + ". " + "Note: name must be qualified.\")");
168             return;
169         } catch (NotAnAbstractClassException e) {
170             println("(error \"Error: " + name
171                     + " is not an abstract class.\")");
172             return;
173         } catch (Exception e) {
174             e.printStackTrace();
175             println("(error \"Error: unknown type.\")");
176             return;
177         }
178
179         dumpExpression(new PrintWriter(System.out, true), truncate);
180     }
181
182     public static void main(String[] args) {
183         AbstractClassFactory.makeAbstractClassExpression
184             ("javax.swing.AbstractAction", false);
185     }
186 }
187
188 class NotAnAbstractClassException extends NotAnInterfaceException {
189     NotAnAbstractClassException (String name) {
190         super(name);
191     }
192 }// End of AbstractClassFactory
193
194 /*
195  * $Log: AbstractClassFactory.java,v $
196  * Revision 1.7  2003/10/19 14:45:30  jslopez
197  * Fixes getAbstractMethods to get the methods included by getDeclaredMethods and
198  * getMethods.
199  *
200  * Revision 1.6  2003/10/10 12:51:12  jslopez
201  * Fixes generating skeleton for all methods declared by superclass including
202  * those that the class or superclass provides an implementation.
203  *
204  * Revision 1.5  2002/12/04 07:16:38  paulk
205  * Cosmetic changes.
206  *
207  * Revision 1.4  2002/08/30 12:50:10  jslopez
208  * Fixes regression bug.
209  * Now methods defined in super classes and interfaces are as well
210  * added.
211  *
212  * Revision 1.3  2002/08/30 12:29:58  jslopez
213  * Fixes bug generating abstract class skeletons.
214  *
215  * Revision 1.2  2002/05/14 06:38:44  paulk
216  * Enhances code generation wizards for implementing interfaces, abstract
217  * classes, etc., to use customizable templates to generate skeleton methods
218  * instead of hard-wired skeletons. Thanks to "Dr. Michael Lipp"
219  * <lipp@danet.de> for proposing and implementing this improvement.
220  * Revision 1.1  2001/08/04 03:14:06  paulk
221  * Initial revision.
222  *
223  */
224
225