2 * Copyright (c) Paul Kinnucan 1998, 1999, 2000, 2001. All Rights Reserved.
5 * $Date: 2004/03/18 05:28:36 $
7 * MethodOverrideFactory is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2, or (at
10 * your option) any later version.
12 * MethodOverrideFactory is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * To obtain a copy of the GNU General Public License write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
24 import java.lang.reflect.Method;
25 import java.lang.reflect.Modifier;
26 import java.io.PrintWriter;
27 import java.util.Hashtable;
28 import java.util.Vector;
29 import java.util.Enumeration;
31 import jde.util.DynamicClassLoader;
34 * Defines a factory for creating an override of a method defined in a
37 * @author Paul Kinnucan
38 * @version $Revision: 1.14 $
41 public class MethodOverrideFactory extends MethodFactory
45 static MethodOverrideFactory overrideFactory;
47 Vector candidates = new Vector();
53 public MethodOverrideFactory() {}
56 * Creates a MethodOverrideFactory that uses the specified NameFactory
57 * for generating parameter names
59 * @param factory Factory for generating parameter names
61 public MethodOverrideFactory(NameFactory factory)
67 * Return a <code>Vector</code> containing all <code>Method</code>
68 * objects for the argument class and methodName which can be
71 * @param cl the <code>Class</code> for which all methods that can
72 * be overridden will be returned.
73 * @param methodName the name of the Method to be returned.
74 * @return a <code>Vector</code> of <code>Method</code> objects.
76 private Vector getOverrideableMethods(Class cl, String methodName) {
78 Vector m = new Vector();
81 while (baseClass != null) {
82 Method[] methods = baseClass.getDeclaredMethods();
83 for (int i = 0; i < methods.length; i++) {
84 if (methods[i].getName().equals(methodName)) {
85 int methodModifiers = methods[i].getModifiers();
86 if ((Modifier.isPublic(methodModifiers) ||
87 Modifier.isProtected(methodModifiers)) &&
88 !Modifier.isFinal(methodModifiers))
89 m.addElement(methods[i]);
92 baseClass = baseClass.getSuperclass();
101 * Get a list of signatures for all methods of a specified name defined
102 * or inherited by a specified class. The signatures returned by this method
103 * including only the types of the method parameters as the generated names
104 * are unnecessary for signature matching. This method prints the signature
105 * list to standard out as a Lisp list form.
107 * @param baseClassName a <code>String</code> value that specifies the name of
108 * the class that defines or inherits the methods whose signatures are to be
110 * @param methodName a <code>String</code> value that specifies the name of the
111 * methods whose signatures are to be returned.
113 public static void getCandidateSignatures(String baseClassName, String methodName) {
115 if (overrideFactory == null)
116 overrideFactory = new MethodOverrideFactory();
118 overrideFactory.flush();
120 overrideFactory.baseClassName = baseClassName;
121 overrideFactory.methodName = methodName;
125 DynamicClassLoader dcl = new DynamicClassLoader();
126 Vector methods = overrideFactory.getOverrideableMethods
127 (dcl.loadClass(baseClassName), methodName);
129 for (int i = 0; i < methods.size(); ++i) {
130 Method m = (Method) methods.elementAt(i);
131 Signature s = new Signature(m, overrideFactory);
132 boolean containsSignature = false;
133 for (int j = 0; j < overrideFactory.candidates.size(); ++j)
134 if (s.equals(overrideFactory.candidates.elementAt(j))) {
135 containsSignature = true;
138 if (! containsSignature)
139 overrideFactory.candidates.addElement(s);
142 int n = overrideFactory.candidates.size();
145 String res = "(list ";
146 for (int i = 0; i < n; ++i) {
147 Signature s = (Signature) overrideFactory.candidates.elementAt(i);
148 s.setTruncating(false);
149 String p = s.getParameters(s.getMethod().getParameterTypes(), false);
150 s.setTruncating(true);
151 res = res + "\"" + methodName + "(" + p + ")\" ";
157 println("(error \"Could not find any method named " +
158 methodName + " in " + baseClassName +
159 " or any of its superclasses.\")");
162 catch (ClassNotFoundException ee) {
163 println("(error \"Could not find class " +
164 baseClassName + "\")");
169 public static void getMethodSkeletonExpression(int variant) {
170 Signature s = (Signature) overrideFactory.candidates.elementAt(variant);
171 String skel = overrideFactory.getMethodSkeletonExpression(s);
174 // Register imported classes.
175 overrideFactory.imports.clear();
176 Method m = s.getMethod();
178 Class[] types = m.getParameterTypes();
179 for (int i = 0; i < types.length; ++i)
180 overrideFactory.registerImport(types[i]);
182 types = m.getExceptionTypes();
183 for (int i = 0; i < types.length; ++i)
184 overrideFactory.registerImport(types[i]);
186 overrideFactory.registerImport(m.getReturnType());
190 public static void getImportedClasses() {
191 println(overrideFactory.getImportsAsList());
195 * Clears the import and candidate hashtables for this factory so they
196 * can be re-used to process a new set of interfaces.
201 candidates.removeAllElements();
205 * Gets the candidate signatures for the class and method
206 * passed as arguments on the command line.
208 * @param args a <code>String[]</code> value
210 public static void main (String[] args) {
212 String className = "javax.swing.AbstractAction";
213 String methodName = "actionPerformed";
215 if (args.length == 2) {
218 methodName = args[1];
222 System.out.println("Class: " + className);
223 System.out.println("Method: " + methodName);
225 getCandidateSignatures(className, methodName);
234 } // MethodOverrideFactory
238 * $Log: MethodOverrideFactory.java,v $
239 * Revision 1.14 2004/03/18 05:28:36 paulk
240 * Now overrides protected as well as public methods and does not override final methods.
241 * Thanks to David Esterkin <desterkin@sciquest.com>.
243 * Revision 1.13 2004/02/19 06:27:44 paulk
244 * Fixes bug that caused the override wizard to fail to match the method designated by the user to be overriden. Thanks to David Esterkin <desterkin@sciquest.com>.
246 * Revision 1.12 2003/10/20 05:39:24 paulk
247 * Update the getMethods() method to get all the methods of a class
248 * whether declared by the class or inherited by the class, including
251 * Revision 1.11 2003/07/23 04:40:07 paulk
252 * main method now accepts class and method name for testing purpose. Added comment
253 * noting the change in behavior of getDeclaredMethods from JDK 1.3 to JDK 1.4.
255 * Revision 1.10 2003/05/04 05:50:52 paulk
256 * Document the getCandidateSignatures method.
258 * Revision 1.9 2003/05/04 05:42:22 paulk
259 * Change getCandidateSignatures to return signatures with parameter
260 * types only (i.e., without parameter nams). This fixes a
261 * signature-matching bug on the Lisp side where the method override
262 * wizard was inadvertently trying to matching a signature without
263 * parameter names to a list of signatures with parameter names.
265 * Revision 1.8 2002/06/03 18:12:27 mnl
266 * Use DynamicClassLoader instead of simple Class.forName to avoid class
267 * resolving (linking).
269 * Revision 1.7 2002/05/14 06:38:44 paulk
270 * Enhances code generation wizards for implementing interfaces, abstract
271 * classes, etc., to use customizable templates to generate skeleton methods
272 * instead of hard-wired skeletons. Thanks to "Dr. Michael Lipp" <lipp@danet.de>
273 * for proposing and implementing this improvement.
275 * Revision 1.6 2001/08/14 05:15:03 paulk
276 * Miscellaneous updates.
278 * Revision 1.5 2001/08/11 06:52:31 paulk
279 * Adds javadoc parameter to getMethodSkeleton. Thanks to Javier Lopez.
284 // End of MethodOverrideFactory.java