Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / wizards / DelegateFactory.java
1 /*
2  * Copyright (c) Eric D. Friedman 2000. All Rights Reserved.
3  * Copyright (c) Paul Kinnucan 2000. All Rights Reserved.
4  * Copyright (c) Charles Hart 2000. All Rights Reserved.
5  *
6  * $Revision: 1.6 $ 
7  * $Date: 2003/09/07 05:29:12 $ 
8  *
9  * DelegateFactory is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2, or (at
12  * your option) any later version.
13  *
14  * DelegateFactory is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * To obtain a copy of the GNU General Public License write to the
20  * Free Software Foundation, Inc.,  59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.  
22  */
23
24 package jde.wizards;
25
26 import java.lang.reflect.Method;
27 import java.lang.reflect.Modifier;
28 import java.io.PrintWriter;
29
30 /**
31  * Defines a factory for generating methods that delegate tasks
32  * to be performed by an instance of one class (the delegator)
33  * to an instance of another class (the delegee. The delegator
34  * must have a field that references the delegee.
35  *
36  * @author Charles Hart, Eric D. Friedman, and Paul Kinnucan
37  * @version $Revision: 1.6 $
38  */
39
40 public class DelegateFactory extends MethodFactory {
41
42   /** A container for the signatures of the delegation methods
43    * to be generated by this factory. */
44   private SignatureContainer signatures = new SignatureContainer();
45
46   /** The delegate factory. */
47   private static DelegateFactory delegateFactory;
48
49   /**
50    * Name of the delegator field that references the delegee.
51    *
52    */
53   private String delegee;
54   
55   /**
56    * Creates a new <code>DelegateFactory</code> instance.
57    *
58    */
59   public DelegateFactory() { }
60
61   /** 
62    * Creates a DelegateFactory that uses the specified NameFactory
63    * for generating parameter names 
64    *
65    * @param factory Factory for generating parameter names
66    */
67   public DelegateFactory(NameFactory factory) {
68     super(factory);
69   }
70
71   
72   /**
73    * Gets a container containing the signatures of the delegation
74    * methods.
75    *
76    * @return the value of signatures
77    */
78   public SignatureContainer getSignatures()  {
79     return this.signatures;
80   }
81
82   /**
83    * Specifies a container to hold the signatures of the
84    * delegator methods.
85    *
86    * @param argSignatures signature container
87    */
88   public void setSignatures(SignatureContainer argSignatures) {
89     this.signatures = argSignatures;
90   }
91
92   /**
93    * Gets the Delegate Factory
94    *
95    * @return the Delegate Factory
96    */
97   public static DelegateFactory getTheFactory()  {
98     return DelegateFactory.delegateFactory;
99   }
100
101   /**
102    * Sets the Delegate Factory
103    *
104    * @param argDelegateFactory the Delegate Factory
105    */
106   public static void setTheFactory(DelegateFactory argDelegateFactory) {
107     DelegateFactory.delegateFactory = argDelegateFactory;
108   }
109
110   /**
111    * Gets the name of the delegator field that references the delegee.
112    *
113    * @return name of the delegee
114    */
115   public String getDelegee()  {
116     return this.delegee;
117   }
118
119   /**
120    * Specifies the name of the delegator field that references the delegee.
121    *
122    * @param argDelegee the delegee
123    */
124   public void setDelegee(String argDelegee) {
125     this.delegee = argDelegee;
126   }
127
128
129   /** 
130    * Clears the method signatures container.
131    */
132   public void flush() {
133     super.flush();
134     signatures.clear();
135   }
136
137   
138   /**
139    * Generates method signatures based on introspection of the
140    * specified interface. Strips package specifiers from generated
141    * signatures.
142    *
143    * @param interfaceName the interface to process for signatures.
144    * @exception ClassNotFoundException Cannot find interface 
145    */
146   public void process(String interfaceName)
147     throws ClassNotFoundException {
148     process(interfaceName, true);
149   }  
150   
151   /**
152    * Generates signatures for the public methods of the delegee
153    * class. 
154    *
155    * @param delegeeClassName name of the delegee's class
156    * @param truncate toggles truncation of package specifiers in signatures.
157    *
158    * @exception ClassNotFoundException the requested class cannot
159    * be loaded 
160    */
161   public void process(String delegeeClassName, boolean truncate)
162     throws ClassNotFoundException {
163     
164     if (null == namefactory) {
165       namefactory = new DefaultNameFactory();
166     }
167     
168     Class aclass = Class.forName(delegeeClassName);
169     
170     Method[] methods = aclass.getMethods();
171     for (int i = 0; i < methods.length; i++) {
172       if (!(methods[i].getDeclaringClass().getName().equals("java.lang.Object")
173             && Modifier.isFinal(methods[i].getModifiers()))) {
174         signatures.add(new Signature(methods[i], this, truncate, true));
175       }
176     }
177   }
178
179   /**
180    * Generate delegator methods.
181    *
182    * @param delegeeFieldName Name of delagator field that reference
183    * the delegee.
184    * @param delegeeClassName  Name of delegee class.
185    * @param truncate If <code>true</code>, truncate package specifier
186    * when generating code.
187    * 
188    */
189   private void makeDelegatorMethodsInternal(String delegeeFieldName,
190                                             String delegeeClassName,
191                                             boolean truncate) {
192     delegee = delegeeFieldName;
193     
194     try {
195       process(delegeeClassName, truncate);
196     } catch (ClassNotFoundException e) {
197       println("(error \"Error: could not find class named: "
198               + delegeeClassName + ". "
199               + "Note: name must be qualified.\")");
200       return;
201     } catch (Exception e) {
202       println("(error \"Error: unknown type.\")");
203       return;
204     }
205
206     outputMethods(new PrintWriter(System.out, true), truncate);
207   }
208
209
210   /**
211    * Generates delegator methods.
212    *
213    * @param delegeeFieldName Name of delegator field that
214    * references the delegee.
215    * @param delegeeClassName Name of delegee's class.
216    * @param truncate If <code>true</code>, truncate package specifier
217    * when generating code.
218    */
219   public static void makeDelegatorMethods(String delegeeFieldName,
220                                           String delegeeClassName, 
221                                           boolean truncate) {
222
223     if (delegateFactory == null) {
224       delegateFactory = new DelegateFactory();
225     }
226
227     delegateFactory.flush();
228     delegateFactory.makeDelegatorMethodsInternal(delegeeFieldName,
229                                                  delegeeClassName,
230                                                  truncate);
231   }
232
233
234
235   /**
236    * Describe <code>getImportedClasses</code> method here.
237    *
238    */
239   public static void getImportedClasses() {
240     println(delegateFactory.getImportsAsList());
241   }
242
243   /**
244    * Return a default body for the implementation of the method described
245    * by <code>sig</code>.
246    *
247    * @param sig a <code>Signature</code> value
248    * @return a <code>String</code> value
249    */
250   protected String getDefaultBody (Signature sig) {
251     Method m = sig.getMethod();
252     Class cl = m.getReturnType();
253     String defBody = "";
254
255     defBody = delegee + "." + m.getName() 
256       + "(" + sig.getParameterNames() + ");";
257     if (!cl.getName().equals("void")) {
258       defBody = "return " + defBody;
259     }
260     return defBody;
261   }
262
263   /**
264    * Prints delegator methods to the standard out of
265    * the current process, i.e., to Emacs.
266    *
267    * @param out a <code>PrintWriter</code> value
268    * @param truncate a <code>boolean</code> value
269    */
270   public void outputMethods(PrintWriter out, boolean truncate) {
271     final StringBuffer buf = new StringBuffer
272       ("(jde-wiz-gen-delegation-methods (list ");
273
274     signatures.visit(new SignatureVisitor() {
275         public void visit(Signature sig , boolean firstOfClass) {
276           if (firstOfClass) {
277             buf.append ("(quote ");
278             buf.append("\"Code for delegation of ");
279             buf.append(sig.getDeclaringClass().getName());
280             buf.append(" methods to ");
281             buf.append(delegee);
282             buf.append("\")");
283           }
284           buf.append ("(quote ");
285           buf.append(getMethodSkeletonExpression(sig));
286           buf.append (")");
287         }
288       });
289     
290     buf.append("))");
291     println(buf.toString());
292   }
293 } // DelegateFactory
294
295 /*
296  * $Log: DelegateFactory.java,v $
297  * Revision 1.6  2003/09/07 05:29:12  paulk
298  * Check for duplicate methods defined by different classes or interfaces.
299  * Thanks to Martin Schwamberg.
300  *
301  * Revision 1.5  2002/06/06 05:12:44  paulk
302  * DefaultNameFactory now generates meaningful method parameter names based
303  * on the parameter type or the method name. Thanks to Ole Arndt.
304  *
305  * Revision 1.4  2002/05/14 06:38:44  paulk
306  * Enhances code generation wizards for implementing interfaces, abstract
307  * classes, etc., to use customizable templates to generate skeleton methods
308  * instead of hard-wired skeletons. Thanks to "Dr. Michael Lipp" <lipp@danet.de>
309  * for proposing and implementing this improvement.
310  *
311  * Revision 1.3  2000/08/03 04:31:20  paulk
312  * Add support for generating a see secton in the Javadoc comment for a method.
313  * Thanks to raffael.herzog@comartis.com
314  *
315  * Revision 1.2  2000/08/01 08:19:25  paulk
316  * Fixes bug in dump method .Thanks to eric@hfriedman.rdsl.lmi.net.
317  *
318  * Revision 1.1  2000/07/14 05:26:55  paulk
319  * Adds support for delegation wizard.
320  *
321  */
322
323 // End of DelegateFactory.java