Tbpgr Blog

Employee Experience Engineer tbpgr(てぃーびー) のブログ

Java | Setterに値をセットするコードを自動生成

パンくず

Java
Setterに値をセットするコードを自動生成

概要

Setterに値をセットするコードを自動生成について

内容

大量のSetterに値を設定するようなコードは度々登場します。
このような場合に手でコードを書くと地味に時間がかかるものです。

今回はSetterのコードを自動生成して標準出力してみます。

サンプルコード

SetterGenerator(変換処理本体)

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

public class SetterGenerator {

  /**
   * Setterを生成する。
   *
   * @param clazz
   *          Setter生成対象オブジェクト
   * @param useSpace
   *          スペースで間隔を変えるかどうか
   * @throws IntrospectionException
   */
  public static void generateSetterCode(Class<?> clazz, boolean useSpace) throws IntrospectionException {
    PropertyDescriptor[] properties = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
    String className = clazz.getSimpleName();
    String variableName = SetterGenerator.getVariableNameFromUpperName(clazz.getSimpleName());
    outputInstance(className, variableName);
    outputSetter(useSpace, properties, variableName);
  }

  /**
   * Setter部の出力。
   *
   * @param useSpace
   *          スペースで間隔を変えるかどうか
   * @param properties
   *          Setterの配列
   * @param variableName
   *          インスタンス変数名
   */
  private static void outputSetter(boolean useSpace, PropertyDescriptor[] properties, String variableName) {
    for (PropertyDescriptor property : properties) {
      if (property.getWriteMethod() == null) {
        continue;
      }
      System.out.print(property.getPropertyType().getSimpleName());
      System.out.print(" ");
      String paramName = SetterGenerator.getVariableNameFromUpperName(property.getName());
      System.out.print(paramName);
      System.out.println(SetterGenerator.getInitializeCode(property.getPropertyType().getSimpleName()));
      System.out.print(variableName + ".");
      System.out.print(property.getWriteMethod().getName());
      System.out.println("(" + paramName + ");");
      if (useSpace) {
        System.out.println("");
      }
    }
  }

  /**
   * インスタンス生成部の出力。
   *
   * @param className
   *          クラス名
   * @param variableName
   *          インスタンス変数名
   */
  private static void outputInstance(String className, String variableName) {
    System.out.print(className);
    System.out.print(" ");
    System.out.print(variableName);
    System.out.print(" = new ");
    System.out.print(className);
    System.out.println("();");
    System.out.println("");
  }

  /**
   * 先頭大文字の名称から先頭のみ小文字に変更して変数名にする。
   *
   * @param upperName
   *          先頭大文字の変数名の元にする名前
   * @return 変数名
   */
  public static String getVariableNameFromUpperName(String upperName) {
    return upperName.substring(0, 1).toLowerCase() + upperName.substring(1);
  }

  /**
   * 初期化用文字列の取得。<br />
   * ※取り扱うデータを増やす場合はifの要素を追加。
   * 現状ベタ書きだがStrategyなどで分割が望ましいか。
   * @param type
   * @return
   */
  private static String getInitializeCode(String type) {
    if (type.equals("String")) {
      return " = \"\";";
    } else if (type.equals("BigDecimal")) {
      return " = new " + type + "(\"0\");";
    } else if (type.equals("List")) {
      return " = new Array" + type + "();";
    } else if (type.equals("Map")) {
      return " = new Hash" + type + "();";
    } else if (type.contains("Enum")) {
      return ";";
    } else if (type.equals("int")) {
      return " = 0;";
    } else {
      return " = new " + type + "();";
    }
  }
}

SetterCodeGenerator(読み込み実行用クラス)

import java.beans.IntrospectionException;

/**
 * Setterのコードを生成呼び出し確認用。
 *
 */
public class SetterCodeGenerator {

  /**
   * @param args
   * @throws IntrospectionException
   */
  public static void main(String[] args) throws IntrospectionException {
    SetterGenerator.generateSetterCode(SetterClass.class, true);
  }

}

SetterClass(読み込み対象クラス本体)

import java.math.BigDecimal;
import java.util.List;

public class SetterClass {
  private String str1 = null;
  private String str2 = null;
  private BigDecimal bigDecimal1 = null;
  private BigDecimal bigDecimal2 = null;
  private SetterChildEnum hogeCls1 = null;
  private SetterChildEnum hogeCls2 = null;
  private List<SetterChildClass> lineList = null;
  private int int1 = 0;

  // 以下のアクセサは省略
}

SetterChildClass(読み込み対象クラスから参照しているリストの中の型)

import java.math.BigDecimal;

public class SetterChildClass {
  private String str1 = null;
  private String str2 = null;
  private BigDecimal bigDecimal1 = null;
  private BigDecimal bigDecimal2 = null;
  private SetterChildEnum hogeCls1 = null;
  private SetterChildEnum hogeCls2 = null;

  // 以下のアクセサは省略
}

SetterEnum(読み込み対象クラスから参照しているEnumの型)

public enum SetterChildEnum {
	HOGE("1"),HOO("2"),BAR("3");

	private String type;
	private SetterChildEnum(final String type) {
		this.type = type;
	}
	public String toValue() {
		return this.type;
	}
	 public SetterChildEnum fromValue(String value) throws Exception {
	    if (value.equals("1")) {
	      return HOGE;
	    } else if (value.equals("2")) {
	      return HOO;
	    } else if (value.equals("3")) {
	      return BAR;
	    } else {
	      throw new Exception();
	    }
	  }
}

出力結果

改行フラグfalse版

SetterClass setterClass = new SetterClass();

BigDecimal bigDecimal1 = new BigDecimal("0");
setterClass.setBigDecimal1(bigDecimal1);
BigDecimal bigDecimal2 = new BigDecimal("0");
setterClass.setBigDecimal2(bigDecimal2);
SetterChildEnum hogeCls1;
setterClass.setHogeCls1(hogeCls1);
SetterChildEnum hogeCls2;
setterClass.setHogeCls2(hogeCls2);
int int1 = 0;
setterClass.setInt1(int1);
List lineList = new ArrayList();
setterClass.setLineList(lineList);
String str1 = "";
setterClass.setStr1(str1);
String str2 = "";
setterClass.setStr2(str2);

改行フラグtrue版

SetterClass setterClass = new SetterClass();

BigDecimal bigDecimal1 = new BigDecimal("0");
setterClass.setBigDecimal1(bigDecimal1);

BigDecimal bigDecimal2 = new BigDecimal("0");
setterClass.setBigDecimal2(bigDecimal2);

SetterChildEnum hogeCls1;
setterClass.setHogeCls1(hogeCls1);

SetterChildEnum hogeCls2;
setterClass.setHogeCls2(hogeCls2);

int int1 = 0;
setterClass.setInt1(int1);

List lineList = new ArrayList();
setterClass.setLineList(lineList);

String str1 = "";
setterClass.setStr1(str1);

String str2 = "";
setterClass.setStr2(str2);