概要
流れるようなデータクラス生成ツールについて
要件
定義用クラスに以下の内容を指定
・データクラス名
・データクラスJavaDoc
・データクラスJavaDoc用author
・フィールドコメントのリスト
・フィールドデータ型のリスト
・フィールド変数名のリスト
上記の内容を元に任意のクラス名で、任意の数のフィールドと流れるようなインターフェースを持つ
データクラスを生成する。
クラス構成
develop_util.fluentifgen
│ FluentIfGenerator.java
│ FluentIfGeneratorExecutor.java
│
├─conf(設定ファイル)
│ FluentIfDefinitionIntf.java
│ HogeTestFixture.java
│
└─sample(出力サンプル)
Hoge.java
コード
自動生成処理本体
FluentIfGenerator.java
package develop_util.fluentifgen; import develop_util.fluentifgen.conf.FluentIfDefinitionIntf; public class FluentIfGenerator { private static String template = ""; public static final String CLASS_NAME = "$CLASS_NAME$"; public static final String JAVADOC_CLASS_NAME = "$class_comment$"; public static final String JAVADOC_AUTHOR = "$author$"; public static final String FIELDS = "$fields$"; public static final String SETTERS = "$setters$"; static { template += "/**\n"; template += "* " + FluentIfGenerator.JAVADOC_CLASS_NAME + "\n"; template += "* \n"; template += "* @author " + FluentIfGenerator.JAVADOC_AUTHOR + "\n"; template += "* \n"; template += "*/\n"; template += "public static class " + FluentIfGenerator.CLASS_NAME + " {\n"; template += FluentIfGenerator.FIELDS + "\n"; template += FluentIfGenerator.SETTERS + "\n"; template += " public String toString() {\n"; template += " // Fixtureの内容を一括出力\n"; template += " return CommonUtil.getAllFiledInfo(Fixture.class, this);\n"; template += " }\n"; template += "}\n"; } public static void generate(FluentIfDefinitionIntf definition) { String out = template; out = out.replace(FluentIfGenerator.CLASS_NAME, definition.getOutputClassName()); out = out.replace(FluentIfGenerator.JAVADOC_CLASS_NAME, definition.getOutputClassJavaDoc()); out = out.replace(FluentIfGenerator.JAVADOC_AUTHOR, definition.getAuthor()); StringBuilder field = new StringBuilder(); // Fieldの生成 for (int i = 0; i < definition.getFieldComments().size(); i++) { field.append("/** "); field.append(definition.getFieldComments().get(i)); field.append(". */\n"); field.append(definition.getTypes().get(i) + " "); field.append(definition.getFieldNames().get(i) + ";\n"); } out = out.replace(FluentIfGenerator.FIELDS, field); StringBuilder setter = new StringBuilder(); // Setterの生成 for (int i = 0; i < definition.getFieldNames().size(); i++) { String fieldName = definition.getFieldNames().get(i); setter.append("public " + definition.getOutputClassName() + " " + fieldName + "(" + definition.getTypes().get(i) + " " + fieldName + ") {\n"); setter.append("this." + fieldName + "=" + fieldName + ";\n"); setter.append("return this;\n"); setter.append("}\n"); } out = out.replace(FluentIfGenerator.SETTERS, setter); System.out.println(out); } }
自動生成機能呼び出しコード
FluentIfGeneratorExecutor
package develop_util.fluentifgen; import develop_util.fluentifgen.conf.HogeTestFixture; public class FluentIfGeneratorExecutor { public static void main(String args[]) { FluentIfGenerator.generate(new HogeTestFixture()); } }
自動生成内容定義用インターフェース
FluentIfDefinitionIntf
package develop_util.fluentifgen.conf; import java.util.List; public interface FluentIfDefinitionIntf { static final String DEFAULT_CLASS_NAME = "Fixture"; /** * 出力クラス名を指定する。 * @return 出力クラス名 */ String getOutputClassName(); /** * 出力クラスJavaDoc概要を指定する。 * @return 出力クラスJavaDoc概要 */ String getOutputClassJavaDoc(); /** * 作成者を指定する。 * @return 作成者 */ String getAuthor(); /** * フィールドのコメントを列挙する。 * * @return フィールドのコメントリスト */ List<String> getFieldComments(); /** * フィールドのデータ型を列挙する。 * * @return フィールドのデータ型のリスト */ List<String> getTypes(); /** * フィールドの変数名を列挙する。 * * @return フィールド名のリスト */ List<String> getFieldNames(); }
自動生成内容定義ファイル(Fixture出力設定例)
HogeTestFixture
package develop_util.fluentifgen.conf; import java.util.Arrays; import java.util.List; public class HogeTestFixture implements FluentIfDefinitionIntf { @Override public String getOutputClassName() { return FluentIfDefinitionIntf.DEFAULT_CLASS_NAME; } @Override public String getOutputClassJavaDoc() { return "HogeTestのFixture"; } @Override public String getAuthor() { return "tbpgr"; } @Override public List<String> getFieldComments() { List<String> fieldComments = Arrays.asList("ケース番号","年齢","名前"); return fieldComments; } @Override public List<String> getTypes() { List<String> fieldTypes = Arrays.asList("int","int","String"); return fieldTypes; } @Override public List<String> getFieldNames() { List<String> fieldNames = Arrays.asList("caseNo","age","name"); return fieldNames; } }
出力
※出力内容をフォーマットした内容
/** * HogeTestのFixture * * @author tbpgr * */ public static class Fixture { /** ケース番号. */ int caseNo; /** 年齢. */ int age; /** 名前. */ String name; public Fixture caseNo(int caseNo) { this.caseNo = caseNo; return this; } public Fixture age(int age) { this.age = age; return this; } public Fixture name(String name) { this.name = name; return this; } public String toString() { // Fixtureの内容を一括出力 return CommonUtil.getAllFiledInfo(Fixture.class, this); } }
出力内容を適用
出力されたデータクラスをHogeクラスに貼り付けて利用してみます。
package develop_util.fluentifgen.sample; import gr.java_conf.tb.tbpg_util.common.CommonUtil; import java.util.Arrays; import java.util.List; public class Hoge { public static void main(String args[]) { Fixture tanaka = new Fixture().caseNo(1).age(20).name("田中"); Fixture sato = new Fixture().caseNo(2).age(24).name("佐藤"); Fixture suzuki = new Fixture().caseNo(3).age(100).name("鈴木"); List<Fixture> fixtures = Arrays.asList(tanaka, sato, suzuki); for (Fixture fixture : fixtures) { System.out.println(CommonUtil.getAllFiledInfo(Fixture.class, fixture)); } } /** * HogeTestのFixture * * @author tbpgr * */ public static class Fixture { /** ケース番号. */ int caseNo; /** 年齢. */ int age; /** 名前. */ String name; public Fixture caseNo(int caseNo) { this.caseNo = caseNo; return this; } public Fixture age(int age) { this.age = age; return this; } public Fixture name(String name) { this.name = name; return this; } public String toString() { // Fixtureの内容を一括出力 return CommonUtil.getAllFiledInfo(Fixture.class, this); } } }
利用例の出力
int|caseNo|1 int|age|20 class java.lang.String|name|田中 int|caseNo|2 int|age|24 class java.lang.String|name|佐藤 int|caseNo|3 int|age|100 class java.lang.String|name|鈴木