/* MethodGenerator.java -- Generates methods for rmi compiler. Copyright (C) 2006 Free Software Foundation This file is part of GNU Classpath. GNU Classpath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Classpath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. */ package gnu.classpath.tools.rmic; import gnu.classpath.tools.rmic.AbstractMethodGenerator; import gnu.java.rmi.server.RMIHashes; import java.lang.reflect.Method; import java.util.Properties; /** * Keeps information about the single method and generates the code fragments, * related to that method. * * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org) */ public class RmiMethodGenerator implements AbstractMethodGenerator { /** * The method being defined. */ Method method; /** * The parent code generator. */ SourceRmicCompiler rmic; /** * Create the new method generator for the given method. * * @param aMethod the related method. * @param aRmic the Rmic generator instance, where more class - related * information is defined. */ public RmiMethodGenerator(Method aMethod, SourceRmicCompiler aRmic) { method = aMethod; rmic = aRmic; if (method.getParameterTypes().length == 0) rmic.addZeroSizeObjecArray = true; } /** * Get the method parameter declaration. * * @return the string - method parameter declaration. */ public String getArgumentList() { StringBuilder b = new StringBuilder(); Class[] args = method.getParameterTypes(); for (int i = 0; i < args.length; i++) { b.append(rmic.name(args[i])); b.append(" p" + i); if (i < args.length - 1) b.append(", "); } return b.toString(); } /** * Get the method parameter list only (no type declarations). This is used to * generate the method invocations statement. * * @return the string - method parameter list. */ public String getArgumentNames() { StringBuilder b = new StringBuilder(); Class[] args = method.getParameterTypes(); for (int i = 0; i < args.length; i++) { b.append(" p" + i); if (i < args.length - 1) b.append(", "); } return b.toString(); } /** * Get the list of exceptions, thrown by this method. * * @return the list of exceptions. */ public String getThrows() { StringBuilder b = new StringBuilder(); Class[] args = method.getExceptionTypes(); for (int i = 0; i < args.length; i++) { b.append(rmic.name(args[i])); if (i < args.length - 1) b.append(", "); } return b.toString(); } /** * Generate this method for the Stub class. * * @return the method body for the stub class. */ public String generateStubMethod() { String templateName; Properties vars = new Properties(rmic.vars); vars.put("#return_type", rmic.name(method.getReturnType())); vars.put("#method_name", method.getName()); vars.put("#method_hash", getMethodHashCode()); vars.put("#argument_list", getArgumentList()); vars.put("#object_arg_list", getArgListAsObjectArray()); vars.put("#declaring_class", rmic.name(method.getDeclaringClass())); vars.put("#class_arg_list", getArgListAsClassArray()); String thr = getThrows(); if (thr.length() > 0) vars.put("#throws", "\n throws " + thr); else vars.put("#throws", ""); if (method.getReturnType().equals(void.class)) templateName = "Stub_12MethodVoid.jav"; else { templateName = "Stub_12Method.jav"; vars.put("#return_statement", getReturnStatement()); } String template = rmic.getResource(templateName); String generated = rmic.replaceAll(template, vars); return generated; } /** * Generate sentences for Reading and Defining Arguments. * * @return the sequence of sentences for reading and defining arguments. */ public String getStaticMethodDeclarations() { StringBuilder b = new StringBuilder(); Class[] args = method.getParameterTypes(); for (int i = 0; i < args.length; i++) { b.append(" "); b.append(rmic.name(args[i])); b.append(" "); b.append("p" + i); b.append(" = "); if (i < args.length - 1) b.append("\n"); } return b.toString(); } /** * Get the write statement for writing parameters inside the stub. * * @return the write statement. */ public String getArgListAsObjectArray() { Class[] args = method.getParameterTypes(); if (args.length==0) return "NO_ARGS"; StringBuilder b = new StringBuilder("new Object[] {"); for (int i = 0; i < args.length; i++) { if (!args[i].isPrimitive()) b.append("p"+i); else { b.append("new "+rmic.name(WrapUnWrapper.getWrappingClass(args[i]))); b.append("(p"+i+")"); } if (i<args.length-1) b.append(", "); } b.append("}"); return b.toString(); } /** * Get the return statement, assuming that the returned object is placed into * the variable "result". */ public String getReturnStatement() { Class r = method.getReturnType(); if (r.equals(void.class)) return ""; else { if (r.isPrimitive()) { String wcd = rmic.name(WrapUnWrapper.getWrappingClass(r)); return "return ((" + wcd + ") result)." + WrapUnWrapper.getUnwrappingMethod(r) + ";"; } else return "return (" + rmic.name(r) + ") result;"; } } /** * Get argument list as class array. */ public String getArgListAsClassArray() { StringBuilder b = new StringBuilder(); Class[] args = method.getParameterTypes(); for (int i = 0; i < args.length; i++) { b.append(rmic.name(args[i])); b.append(".class"); if (i < args.length - 1) b.append(", "); } return b.toString(); } /** * RMI ties (previously named Skeletons) are no longer used since v 1.2. This * method should never be called. */ public String generateTieMethod() { throw new InternalError(); } /** * Get the method hash code. */ public String getMethodHashCode() { return RMIHashes.getMethodHash(method)+"L"; } /** * Additional processing of the stub name (nothing to do for JRMP stubs). */ public String convertStubName(String name) { return name; } }