jamonでコードを生成する

コード生成


さまざまな職場のいくつかのプロジェクトで、コード生成を使用しました。 なんで?

ほとんどの場合、これにより、変更時に正しいコードが保持されます。 たとえば、別のデータ型をドメインモデルに追加する場合、Javaのクラス、C ++のクラス、それらの間の変換コード、およびEnumの値を追加する必要があります。 コードを生成したりペンで作業したりしなければ、多くのことがあり、この一部を忘れる可能性が常にあります。

場合によっては、リフレクションをコード生成の代わりに使用できますが、そのようなコードでも生成用のテンプレートより読みにくくなります。

コードを生成するための初期情報は大きく異なる場合があります。リフレクションを介してプロパティを読み取り、C ++クラス、csvファイル、XMLなどを生成するJavaクラスです。



jamonフレームワークを使用してMavenプロジェクトでコードを生成する方法を説明します。



問題の声明


たとえば、私は長い間書いてきましたが、まだ書いていません。 エルサレムの地図上にポイントがあり、そのポイントが持つ可能性のあるプロパティのリストがあります。 たとえば、2番目の寺院の時間や、キリスト教またはイスラムの神殿であるビザンチウムなどを指します。

ソースファイルは次のようになります。

name,group christian, religion jewish, religion muslim, religion ancient, time firsttemple, time secondtemple, time hasmonean, time hordus, time roma, time byzantee, time arab, time ottoman, time persian, time crusaider, time pray, type museum, type restaurant, type other, type 
      





name,group christian, religion jewish, religion muslim, religion ancient, time firsttemple, time secondtemple, time hasmonean, time hordus, time roma, time byzantee, time arab, time ottoman, time persian, time crusaider, time pray, type museum, type restaurant, type other, type





name,group christian, religion jewish, religion muslim, religion ancient, time firsttemple, time secondtemple, time hasmonean, time hordus, time roma, time byzantee, time arab, time ottoman, time persian, time crusaider, time pray, type museum, type restaurant, type other, type





name,group christian, religion jewish, religion muslim, religion ancient, time firsttemple, time secondtemple, time hasmonean, time hordus, time roma, time byzantee, time arab, time ottoman, time persian, time crusaider, time pray, type museum, type restaurant, type other, type









これに基づいて、このタイプのファイルを作成します。

package org.citymap;



import java.io.Serializable;



public class PointAttributes implements Serializable {



    

      private boolean muslim;



      public boolean isMuslim () {

         return muslim;

     }



     public void setMuslim ( boolean value ) {

          muslim = value;

     }

   ....



        public boolean equals ( Object o ) {

         if ( this == o ) return true ;

         if ( o == null || getClass () != o.getClass ()) return false ;



         PointAttributes that = ( PointAttributes ) o;



         

          if ( muslim != that.muslim ) return false ;

         

          if ( christian != that.christian ) return false ;

         

         ...

         





         return true ;

     }



     public int hashCode () {

         int result = 0 ;

         

           result = 31 * result + ( muslim ? 1 : 0 ) ;

         

           result = 31 * result + ( christian ? 1 : 0 ) ;

         

          ....

         

         return result;

     }





}







package org.citymap;



import java.io.Serializable;



public class PointAttributes implements Serializable {



    

      private boolean muslim;



      public boolean isMuslim () {

         return muslim;

     }



     public void setMuslim ( boolean value ) {

          muslim = value;

     }

   ....



        public boolean equals ( Object o ) {

         if ( this == o ) return true ;

         if ( o == null || getClass () != o.getClass ()) return false ;



         PointAttributes that = ( PointAttributes ) o;



         

          if ( muslim != that.muslim ) return false ;

         

          if ( christian != that.christian ) return false ;

         

         ...

         





         return true ;

     }



     public int hashCode () {

         int result = 0 ;

         

           result = 31 * result + ( muslim ? 1 : 0 ) ;

         

           result = 31 * result + ( christian ? 1 : 0 ) ;

         

          ....

         

         return result;

     }





}











メイヴン


Mavenでプロジェクトを作成します。 それをマルチモジュールにします。そうしないと、コードを美しく生成することができません。 dadモジュールには、サブモジュールがリストされています。

<modules> <module>util</module> <module>codegen</module> <module>common</module> <module>persistency</module> <module>web</module> </modules> 
      





<modules> <module>util</module> <module>codegen</module> <module>common</module> <module>persistency</module> <module>web</module> </modules>





<modules> <module>util</module> <module>codegen</module> <module>common</module> <module>persistency</module> <module>web</module> </modules>





<modules> <module>util</module> <module>codegen</module> <module>common</module> <module>persistency</module> <module>web</module> </modules>









そして彼自身は「pom」として指定されています



codegenモジュールには生成コードがあり、共通モジュールで生成します。

org.citymap.CommonTemplatesRunnerクラスは実際に生成します

したがって、共通モジュールでは、次のものを割り当てます。

<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase> generate-sources </phase> <configuration> <target> <java classname="org.citymap.CommonTemplatesRunner"> <classpath refid="maven.dependency.classpath" /> <arg value="${project.build.directory}"/> </java> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 
      





<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase> generate-sources </phase> <configuration> <target> <java classname="org.citymap.CommonTemplatesRunner"> <classpath refid="maven.dependency.classpath" /> <arg value="${project.build.directory}"/> </java> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> </build>





<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase> generate-sources </phase> <configuration> <target> <java classname="org.citymap.CommonTemplatesRunner"> <classpath refid="maven.dependency.classpath" /> <arg value="${project.build.directory}"/> </java> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> </build>





<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.6</version> <executions> <execution> <phase> generate-sources </phase> <configuration> <target> <java classname="org.citymap.CommonTemplatesRunner"> <classpath refid="maven.dependency.classpath" /> <arg value="${project.build.directory}"/> </java> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> </build>







ご覧のとおり、ターゲットに酸味のあるディレクトリを追加しました。 これは、mvn cleanで生成されたコードが消去されるようにするために必要です(すべてのコンパイル製品と同様)。 また、antaを使用して、コードソースをgenerate-sourcesステージで実行します。 引数として、コードを生成するディレクトリをジェネレーターに渡します(現在のディレクトリは、Mavenがこのプロジェクトで起動されたか、父親で起動されたかによって異なります)



ハモン




生成には、maven用の優れたプラグインがあるため、 jamonフレームワークを使用します。

次のようにcodegenプロジェクトに追加します。

<dependencies> <dependency> <groupId>org.jamon</groupId> <artifactId>jamon-runtime</artifactId> <version>2.3.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.jamon</groupId> <artifactId>jamon-maven-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>translate</goal> </goals> <configuration> <templateSourceDir>src/main/jamon</templateSourceDir> <templateOutputDir>target/gencode</templateOutputDir> </configuration> </execution> </executions> </plugin> </plugins> </build> 
      









<dependencies> <dependency> <groupId>org.jamon</groupId> <artifactId>jamon-runtime</artifactId> <version>2.3.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.jamon</groupId> <artifactId>jamon-maven-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>translate</goal> </goals> <configuration> <templateSourceDir>src/main/jamon</templateSourceDir> <templateOutputDir>target/gencode</templateOutputDir> </configuration> </execution> </executions> </plugin> </plugins> </build>









<dependencies> <dependency> <groupId>org.jamon</groupId> <artifactId>jamon-runtime</artifactId> <version>2.3.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.jamon</groupId> <artifactId>jamon-maven-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>translate</goal> </goals> <configuration> <templateSourceDir>src/main/jamon</templateSourceDir> <templateOutputDir>target/gencode</templateOutputDir> </configuration> </execution> </executions> </plugin> </plugins> </build>









<dependencies> <dependency> <groupId>org.jamon</groupId> <artifactId>jamon-runtime</artifactId> <version>2.3.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.jamon</groupId> <artifactId>jamon-maven-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>translate</goal> </goals> <configuration> <templateSourceDir>src/main/jamon</templateSourceDir> <templateOutputDir>target/gencode</templateOutputDir> </configuration> </execution> </executions> </plugin> </plugins> </build>









<dependencies> <dependency> <groupId>org.jamon</groupId> <artifactId>jamon-runtime</artifactId> <version>2.3.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.5</version> <executions> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>target/gencode</source> </sources> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.jamon</groupId> <artifactId>jamon-maven-plugin</artifactId> <version>2.3.2</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>translate</goal> </goals> <configuration> <templateSourceDir>src/main/jamon</templateSourceDir> <templateOutputDir>target/gencode</templateOutputDir> </configuration> </execution> </executions> </plugin> </plugins> </build>













彼は自分でコードを生成します-src / main / jamonのテンプレートに基づいて、ターゲット/ gencodeのテンプレートによって生成できるファイルを生成します。 私は誰もジェネレーターの生成と混同しないことを望みます:)



私のテンプレートは次のようになります。

<% import >

   java.util.*;

   org.citymap.*;

  org.apache.commons.lang.StringUtils;

</% import >

<%args>

   Map<String, PointProperty> pojos;

</%args>

package org.citymap;



import java.io.Serializable;



public class PointAttributes implements Serializable {



     <% for String name:pojos.keySet () %>

       private boolean <% name%>;



      public boolean is<% StringUtils.capitalize ( name ) %> () {

         return <% name%>;

     }



       public boolean get<% StringUtils.capitalize ( name ) %> () {

         return <% name%>;

     }



       public void set<% StringUtils.capitalize ( name ) %> ( boolean value ) {

          <% name%> = value;

     }





     </% for >



     public boolean equals ( Object o ) {

         if ( this == o ) return true ;

         if ( o == null || getClass () != o.getClass ()) return false ;



         PointAttributes that = ( PointAttributes ) o;



          <% for String name:pojos.keySet () %>

          if ( <% name%> != that.<% name%> ) return false ;

          </% for >





         return true ;

     }



     public int hashCode () {

         int result = 0 ;

          <% for String name:pojos.keySet () %>

           result = 31 * result + ( <% name%> ? 1 : 0 ) ;

          </% for >

         return result;

     }



}










そして、私はこれを次のように呼び出します:

public class CommonTemplatesRunner {

     public static void main ( String [] args ) throws IOException {

         String targetDir = args [ 0 ] ;

         final Reader csv = new InputStreamReader ( CodeGen. class .getClassLoader () .getResourceAsStream ( "properties.csv" )) ;

         final ObjectCSVMapper<PointProperty> csvProcessor = new ObjectCSVMapper<PointProperty> ( PointProperty.class, csv ) ;

         final Map<String, PointProperty> pojos = csvProcessor.getEntities () ;

         File dir = new File ( targetDir+ "/gencode/org/citymap" ) ;

         dir.mkdirs () ;

         FileWriter fw = new FileWriter ( new File ( dir, "PointAttributes.java" )) ;

         new PointAttributesTemplate () .render ( fw, pojos ) ;



     }

}










そのための引数を作成するために残ります-これと同じMap <String、PointProperty>。

これを行うには、 supercsvライブラリを使用し、最初に示したproperty.csvからPointProperty型のオブジェクトを生成します。



そのため、プロセスを繰り返します。



codegenモジュールでは何も始まりません。コードジェネレーターのみが作成されます。

PointAttributesTemplate.jamonテンプレートに基づいて、PointAttributesTemplateクラスが作成されます



共通モジュールでは、CommonTemplatesRunnerが起動します。



1. properties.csvから、PointPropertyタイプのオブジェクトを作成します。

2.それらを引数としてPointAttributesTemplateに渡すと、PointAttributes.javaが生成されます



ふう。 それだけです

ご質問は?




All Articles