/* 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.rmi.rmic;

import gnu.classpath.tools.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.
   */
  RmicCompiler 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, RmicCompiler 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()
  {
    StringBuffer b = new StringBuffer();

    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()
  {
    StringBuffer b = new StringBuffer();

    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()
  {
    StringBuffer b = new StringBuffer();

    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()
  {
    StringBuffer b = new StringBuffer();
    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";
    
    StringBuffer b = new StringBuffer("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()
  {
    StringBuffer b = new StringBuffer();
    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;
  }
  
}
