3 import java.lang.reflect.Method;
4 import java.util.Hashtable;
5 import java.util.Enumeration;
8 * Defines a factory for creating skeleton implementations of
9 * Java interfaces. The factory can be invoked from the command line
10 * or from another program. The factory can generate implementations for
11 * multiple interfaces when invoked from the command line.
13 * Copyright (C) 1998-2004 Eric D. Friedman . All Rights Reserved.
14 * Copyright (C) 1998-2002 Paul Kinnucan . All Rights Reserved.
16 * $Date: 2004/10/18 05:11:17 $
18 * InterfaceFactory is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2, or (at
21 * your option) any later version.
23 * InterfaceFactory is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
28 * To obtain a copy of the GNU General Public License write to the
29 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30 * Boston, MA 02111-1307, USA.
32 * @author Eric D. Friedman
33 * @author Paul Kinnucan
34 * @version $Revision: 1.9 $
36 public class MethodFactory implements ClassRegistry {
38 /** Unique storage of the classes to import */
39 protected Hashtable imports = new Hashtable();
41 /** A factory for generating parameter names */
42 protected NameFactory namefactory = null;
45 * Constructs a default method factory.
47 public MethodFactory() {
48 this(new DefaultNameFactory());
52 * Creates a method factory that uses the specified NameFactory
53 * for generating parameter names
55 * @param factory Factory for generating parameter names
57 public MethodFactory(NameFactory factory) {
58 namefactory = factory;
62 * Sets the factory for generating parameter names.
64 * @param factory Factory for generating parameter names.
66 public void setNameFactory(NameFactory factory) {
67 namefactory = factory;
71 * Gets the factory used to generating parameter names for
72 * methods generated by this interface factory.
74 * @return Name factory
76 public NameFactory getNameFactory() {
81 * Gets a table containing the classes that must be imported to
82 * implement an interface generated by this factory.
84 * @return Classes required to implement the current interface.
86 public Hashtable getImports() {
91 * Return the fully qualified names of classes that
92 * need to be imported to compile this interface
95 * @return Class names as elisp list of strings.
97 public String getImportsAsList() {
98 StringBuffer res = new StringBuffer ("(list ");
99 Enumeration i = imports.keys();
100 while (i.hasMoreElements()) {
101 Class c = (Class) i.nextElement();
102 String className = c.getName();
104 // The class to be imported may be an inner
105 // class. The interface implementation qualifies
106 // the inner class name with the outer class name.
107 // Thus the import statement need only reference the
108 // outer class. Therefore remove the inner class
109 // name, which is separated from the outer class name
111 int idx = className.indexOf('$');
113 className = className.substring(0, idx);
116 res.append ("\"" + className + "\" ");
119 return res.toString();
123 * Registers a class that needs to be imported by the interface
124 * implementation generated by this factory. Store the class in the
125 * import hashtable if it passes the shouldImport test.
126 * Arrays have to be handled differently here.
128 * @param register Imported class candidate
130 public void registerImport(Class register) {
131 if (register.isArray()) {
135 while (cl.isArray()) {
136 cl = cl.getComponentType();
140 } catch (Throwable t) {
141 throw new RuntimeException("Caught error walking up an Array object: "
146 if (shouldImport(register)) {
147 imports.put(register, "");
152 * Tests whether a specified class needs to be imported by the interface
153 * implementation generated by this factory.
154 * We don't import primitives.
156 * @param c the <code>Class</code> object to be tested
157 * @return <code>true</code> if the class should be imported
159 private final boolean shouldImport(Class c) {
160 return ! c.isPrimitive(); // import everything else
165 * Array of <code>String</> names of numeric types.
168 private String[] numericTypesArray = {"char", "byte",
169 "short", "int", "long",
173 * List of names of numeric types.
176 private java.util.List numericTypesList =
177 java.util.Arrays.asList(numericTypesArray);
180 * Return a default body for the implementation of the method described
181 * by <code>sig</code>.
183 * @param sig a <code>Signature</code> value
184 * @return a <code>String</code> value
186 protected String getDefaultBody (Signature sig) {
187 Method m = sig.getMethod();
188 Class cl = m.getReturnType();
189 if (numericTypesList.contains(cl.getName())) {
191 } else if (cl.getName().equals("boolean")) {
192 return "return false;";
193 } else if (!cl.getName().equals("void")) {
194 return "return null;";
200 * Get a Lisp form that generates a skeleton
201 * implementation of a specified method. The
202 * List form is of the form
204 * <code>(jde-wiz-gen-method ... )</code>
206 * where <code>jde-wiz-gen-method</code> is a
207 * function defined by the JDEE's jde-wiz package.
209 * @param sig a <code>Signature</code> value
210 * @return a <code>String</code> value
212 public String getMethodSkeletonExpression (Signature sig) {
213 StringBuffer res = new StringBuffer();
215 res.append ("(jde-wiz-gen-method");
216 res.append (" \"" + sig.getModifiers() + "\"");
217 res.append (" \"" + sig.getReturnBaseType() + "\"");
218 res.append (" \"" + sig.getMethod().getName() + "\"");
219 res.append (" \"" + sig.getParameters() + "\"");
220 res.append (" \"" + sig.getExceptionList() + "\"");
221 res.append (" \"" + getDefaultBody (sig) + "\")\n");
222 return res.toString();
226 * Clears the import hashtables for this factory so it
227 * can be re-used to process a new set of methods.
229 public void flush() {
234 * Print a string and flush the output buffer to
235 * ensure that the string reaches Emacs immediately.
237 * @param s a <code>String</code> value
239 public static void println(String s) {
240 System.out.print(s + "\n");
248 * $Log: MethodFactory.java,v $
249 * Revision 1.9 2004/10/18 05:11:17 paulk
252 * Revision 1.8 2003/09/07 05:29:12 paulk
253 * Check for duplicate methods defined by different classes or interfaces.
254 * Thanks to Martin Schwamberg.
256 * Revision 1.7 2002/12/04 07:16:37 paulk
259 * Revision 1.6 2002/12/04 07:06:47 paulk
260 * Updated to handle implementation of interfaces that reference inner classes.
262 * Revision 1.5 2002/05/14 06:38:44 paulk
263 * Enhances code generation wizards for implementing interfaces, abstract
264 * classes, etc., to use customizable templates to generate skeleton methods
265 * instead of hard-wired skeletons. Thanks to "Dr. Michael Lipp" <lipp@danet.de>
266 * for proposing and implementing this improvement.
268 * Revision 1.4 2001/08/04 03:24:12 paulk
269 * DefaultNameFactory.java
271 * Revision 1.3 2001/06/13 04:04:43 paulk
272 * Now returns a valid return value for methods that return a value.
273 * Thanks to "Craig McGeachie" <craig@rhe.com.au>.
277 // End of MethodFactory.java