Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: gnu/classpath/tools/rmi/rmic/RmiMethodGenerator.java


1   /* MethodGenerator.java -- Generates methods for rmi compiler.
2    Copyright (C) 2006 Free Software Foundation
3   
4    This file is part of GNU Classpath.
5   
6    GNU Classpath is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10  
11   GNU Classpath is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   General Public License for more details.
15  
16   You should have received a copy of the GNU General Public License
17   along with GNU Classpath; see the file COPYING.  If not, write to the
18   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19   02110-1301 USA.
20  
21   Linking this library statically or dynamically with other modules is
22   making a combined work based on this library.  Thus, the terms and
23   conditions of the GNU General Public License cover the whole
24   combination.
25  */
26  
27  
28  package gnu.classpath.tools.rmi.rmic;
29  
30  import gnu.classpath.tools.AbstractMethodGenerator;
31  import gnu.java.rmi.server.RMIHashes;
32  
33  import java.lang.reflect.Method;
34  import java.util.Properties;
35  
36  /**
37   * Keeps information about the single method and generates the code fragments,
38   * related to that method.
39   * 
40   * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org)
41   */
42  public class RmiMethodGenerator
43      implements AbstractMethodGenerator
44  {
45    /**
46     * The method being defined.
47     */
48    Method method;
49  
50    /**
51     * The parent code generator.
52     */
53    RmicCompiler rmic;
54    
55    /**
56     * Create the new method generator for the given method.
57     * 
58     * @param aMethod the related method.
59     * @param aRmic the Rmic generator instance, where more class - related
60     *          information is defined.
61     */
62    public RmiMethodGenerator(Method aMethod, RmicCompiler aRmic)
63    {
64      method = aMethod;
65      rmic = aRmic;
66      if (method.getParameterTypes().length == 0)
67        rmic.addZeroSizeObjecArray = true;
68    }
69  
70    /**
71     * Get the method parameter declaration.
72     * 
73     * @return the string - method parameter declaration.
74     */
75    public String getArgumentList()
76    {
77      StringBuffer b = new StringBuffer();
78  
79      Class[] args = method.getParameterTypes();
80  
81      for (int i = 0; i < args.length; i++)
82        {
83          b.append(rmic.name(args[i]));
84          b.append(" p" + i);
85          if (i < args.length - 1)
86            b.append(", ");
87        }
88      return b.toString();
89    }
90  
91    /**
92     * Get the method parameter list only (no type declarations). This is used to
93     * generate the method invocations statement.
94     * 
95     * @return the string - method parameter list.
96     */
97    public String getArgumentNames()
98    {
99      StringBuffer b = new StringBuffer();
100 
101     Class[] args = method.getParameterTypes();
102 
103     for (int i = 0; i < args.length; i++)
104       {
105         b.append(" p" + i);
106         if (i < args.length - 1)
107           b.append(", ");
108       }
109     return b.toString();
110   }
111 
112   /**
113    * Get the list of exceptions, thrown by this method.
114    * 
115    * @return the list of exceptions.
116    */
117   public String getThrows()
118   {
119     StringBuffer b = new StringBuffer();
120 
121     Class[] args = method.getExceptionTypes();
122 
123     for (int i = 0; i < args.length; i++)
124       {
125         b.append(rmic.name(args[i]));
126         if (i < args.length - 1)
127           b.append(", ");
128       }
129     return b.toString();
130   }
131 
132   /**
133    * Generate this method for the Stub class.
134    * 
135    * @return the method body for the stub class.
136    */
137   public String generateStubMethod()
138   {
139     String templateName;
140 
141     Properties vars = new Properties(rmic.vars);
142     vars.put("#return_type", rmic.name(method.getReturnType()));
143     vars.put("#method_name", method.getName());
144     vars.put("#method_hash", getMethodHashCode());
145     vars.put("#argument_list", getArgumentList());
146     vars.put("#object_arg_list", getArgListAsObjectArray());
147     vars.put("#declaring_class", rmic.name(method.getDeclaringClass()));
148     vars.put("#class_arg_list", getArgListAsClassArray());
149 
150     String thr = getThrows();
151     if (thr.length() > 0)
152       vars.put("#throws", "\n    throws " + thr);
153     else
154       vars.put("#throws", "");
155 
156     if (method.getReturnType().equals(void.class))
157       templateName = "Stub_12MethodVoid.jav";
158     else
159       {
160         templateName = "Stub_12Method.jav";
161         vars.put("#return_statement", getReturnStatement());
162       }
163 
164     String template = rmic.getResource(templateName);
165     String generated = rmic.replaceAll(template, vars);
166     return generated;
167   }
168 
169   /**
170    * Generate sentences for Reading and Defining Arguments.
171    * 
172    * @return the sequence of sentences for reading and defining arguments.
173    */
174   public String getStaticMethodDeclarations()
175   {
176     StringBuffer b = new StringBuffer();
177     Class[] args = method.getParameterTypes();
178 
179     for (int i = 0; i < args.length; i++)
180       {
181         b.append("            ");
182         b.append(rmic.name(args[i]));
183         b.append(" ");
184         b.append("p" + i);
185         b.append(" = ");
186         if (i < args.length - 1)
187           b.append("\n");
188       }
189     return b.toString();
190   }
191 
192   /**
193    * Get the write statement for writing parameters inside the stub.
194    * 
195    * @return the write statement.
196    */
197   public String getArgListAsObjectArray()
198   {
199     Class[] args = method.getParameterTypes();
200     
201     if (args.length==0)
202       return "NO_ARGS";
203     
204     StringBuffer b = new StringBuffer("new Object[] {");
205 
206     for (int i = 0; i < args.length; i++)
207       {
208         if (!args[i].isPrimitive())
209           b.append("p"+i);
210         else
211           {
212             b.append("new "+rmic.name(WrapUnWrapper.getWrappingClass(args[i])));
213             b.append("(p"+i+")");
214           }
215         if (i<args.length-1)
216           b.append(", ");
217       }
218     b.append("}");
219     return b.toString();
220   }
221   
222   /**
223    * Get the return statement, assuming that the returned object is placed into
224    * the variable "result".
225    */
226   public String getReturnStatement()
227   {
228     Class r = method.getReturnType();
229     if (r.equals(void.class))
230       return "";
231     else
232       {
233         if (r.isPrimitive())
234           {
235             String wcd = rmic.name(WrapUnWrapper.getWrappingClass(r));
236             return "return ((" + wcd + ") result)."
237                    + WrapUnWrapper.getUnwrappingMethod(r) + ";";
238           }
239         else
240           return "return (" + rmic.name(r) + ") result;";
241       }
242   }
243   
244   /**
245    * Get argument list as class array.
246    */
247   public String getArgListAsClassArray()
248   {
249     StringBuffer b = new StringBuffer();
250     Class[] args = method.getParameterTypes();
251 
252     for (int i = 0; i < args.length; i++)
253       {
254         b.append(rmic.name(args[i]));
255         b.append(".class");
256         if (i < args.length - 1)
257           b.append(", ");
258       }
259     return b.toString();
260   }
261 
262   /**
263    * RMI ties (previously named Skeletons) are no longer used since v 1.2. This
264    * method should never be called.
265    */
266   public String generateTieMethod()
267   {
268     throw new InternalError();
269   }
270 
271   /**
272    * Get the method hash code.
273    */
274   public String getMethodHashCode()
275   {
276     return RMIHashes.getMethodHash(method)+"L";
277   }
278   
279   /**
280    * Additional processing of the stub name (nothing to do for JRMP stubs).
281    */
282   public String convertStubName(String name)
283   {
284     return name;
285   }
286   
287 }