Back

package com.futureshocked.classloader;

import java.util.HashMap;
import java.util.StringTokenizer;

/**
 * Small utility class that will parse a code style method declaration and
 *   populate instance variables with the class name, method, and description.
 * <br><br>
 * This is useful for generating the appropriate description, without having to
 *   know the correct format.
 */
public class MethodDescriptionUtil {
  /**
   * <tt>HashMap</tt> that maps code style tpyes to description types
   */
  private static HashMap types;

  /**
   * The full class name, including pacakge.
   */
  private String fullClassName;

  /**
   * The name of the method.
   */
  private String method;

  /**
   * The method description.
   */
  private String description;

  /**
   * Constructor that populates the instance variables based on the code
   *   style method declaration given in the constructor.
   * <br><br>
   * Example method declaration:<br>
   * <i>java.lang.String com.user.package.Class.testMethod(int arg1);</i>
   *
   * @param codeStyleMethod A method declaration
   */
  public MethodDescriptionUtil(String codeStyleMethod) {
    parseCodeStyleMethod(codeStyleMethod);
  }

  /**
   *  Parses a code style method declaration, and populates the instance
   *   variables.
   *
   * @param code A method declaration
   */
  public void parseCodeStyleMethod(String code) {
    StringBuffer descBuffer = new StringBuffer("(");
    StringTokenizer st = new StringTokenizer(code);
    String returnType = st.nextToken();
    String classAndMethod = st.nextToken("(");
    String methodParameters = st.nextToken(")").substring(1);

    // seperate the full class name from the method, and populate both members
    int lastDot = classAndMethod.lastIndexOf(".");
    fullClassName = classAndMethod.substring(0, lastDot).trim();
    method = classAndMethod.substring(lastDot + 1).trim();

    // build the description
    //based on the parameters to the method
    st = new StringTokenizer(methodParameters, ",");
    while (st.hasMoreTokens()) {
      // param can either be 'type,' or 'type varName,'
      String param = st.nextToken(",").trim();
      // ' ' is used in case the local variable names are included
      if (param.indexOf(' ') > -1)
        param = param.substring(0, param.indexOf(' '));

      descBuffer.append(getTypeDescriptor(param));
    }

    descBuffer.append(")");
    descBuffer.append(getTypeDescriptor(returnType));
    description = descBuffer.toString();
  }

  /**
   * Given a code style type, returns a description style type.
   *
   * @param type A type as would be declared in Java source code - ie: int,
   *   char, float, java.lang.String, etc.
   * @return The type as needed in descriptions.
   */
  public String getTypeDescriptor(String type) {
    String descriptor = null;

    if (types.containsKey(type))
      descriptor = (String) types.get(type);
    else {
      type = type.replace('.', '/');
      descriptor = "L" + type + ";";
    }

    return descriptor;
  }

  public String getClassName() {
    return fullClassName;
  }

  public String getMethodName() {
    return method;
  }

  public String getDescription() {
    return description;
  }

  /**
   * Static initializer that populates the types <tt>HashMap</tt>.
   */
  static {
    types = new HashMap();
    types.put("void", "V");
    types.put("boolean", "Z");
    types.put("char", "C");
    types.put("byte", "B");
    types.put("short", "S");
    types.put("int", "I");
    types.put("float", "F");
    types.put("long", "J");
    types.put("double", "D");
  }
}

Top