JETの概要

jet_overview.png
  1. JET(Java Emitter Templates)は、図のようにプログラムを生成するプログラムを生成するための仕組みです。
  2. 処理の流れ
    1. Templateファイル(*.*jet)は、JSPと似た文法で書かれるソースコードのひな形です
    2. JETは、Templateファイルをファイルを生成するJavaプログラムに変換します
    3. 変換されたJavaプログラムを public static void main() 関数からなり、Antタスクからなり呼んでやれば、アプリケーションのプログラムが出来るという仕組み
  3. なんでJETを使うか?
    1. アプリケーションで必要な定型的なファイルを量産したい
      アプリ内で似たような処理をするプログラムが沢山必要なとき、ロジックを組んで一つのクラスでいろいろな処理に対応するよりも、自動生成で別資産をたくさん作った方が幸せな場合が多い
      1. 設定ファイル(XML)
      2. DAO(Data Access Object)
      3. 定型的なJSP
    2. 量産が出来たらうれしいけど、VBAマクロやPerlでプログラムを作るのはめんどくさいし、ましてやJavaでなんか作るのは工数かかりすぎ
    3. そこで、JSPライクな文法でTemplateを書けるJETの出番というわけです

開発環境準備

  1. JDK1.5のインストール?
  2. Eclipse3.1.1のインストール?
  3. JETは、EMF(Eclipse Modeling Framework)の一部なのでEMFをインストールします。インストールは、
    http://www.eclipse.org/
    より以下をダウンロードしてきて、C:\eclipse に上書きします
    • emf-sdo-xsd-SDK-2.1.1.zip
    • NLpack1-emf-sdo-SDK-2.1.1.zip
    • NLpack1_FeatureOverlay?-emf-sdo-SDK-2.1.1.zip

Hello JET

  1. JETプロジェクトの作成
    1. 最初に通常のJavaプロジェクトを作ります*1。っここでは、JETExamプロジェクトとしました。
    2. 次にJETExamプロジェクトをJETプロジェクトに変更します。
      1. JETExamプロジェクトを右クリックして、[新規]-[その他]を選択します
        change_jet_prj1.png
      2. そして、[プロジェクトのJETプロジェクトへの変換」を選択します
        change_jet_prj2.png
      3. すると、プロジェクトがJET対応プロジェクトになり、templateディレクトリが生成されました。
        change_jet_prj3.png
      4. このままだと、Templateファイルから生成されたJavaコードは、\JETExam 配下に直接できてしまいます。\JETExam\src 配下にコードを生成させるためには、プロジェクトのプロパティ*2で、[ソースコンテナ]に、src と記入します。
        change_jet_prj4.png
  2. テンプレートファイルの作成
    いつもの通り、Hello JET を出力するプログラムを作ります。
    \JETExam\template\HelloJET.txtjet に以下のようなTemplateを作成します。
    <%@ jet package="com.foo.jet.generated" class="HelloJet" %>
    Hello, JET.
    1. ファイル名について
      ファイル名は、拡張子の末尾がjetである必要があります。JET Tutorialによると、以下のように最終的に生成されるファイル形式に従った拡張子つけると良いらしい
      Template種別推奨拡張子
      テキストを作るTemplate*.txtjet
      XMLを作るTemplate*.xmljet
      Javaソースを作るTemplate*.javajet
      JSPを作るTemplate*.jspjet
    2. @jetディレクティブについて
      @jetディレクティブにはJSPの@pageディレクティブのように以下のパラメータを設定できます。
      directive意味
      package生成されるGeneratorのpackage名com.foo.jet.generated
      class生成されるGeneratorのclass名HelloJET
      imports利用するクラス。スペース区切りで指定java.util.* java.math.*
      startTagJET内にプログラムを書くときの開始タグ。省略時は"<%""[%"など
      endTagJET内にプログラムを書くときの終了タグ。省略時は"%>""%]"など
      skelton生成されるGeneratorクラスのひな形クラス
      nlStringnl=new line。改行文字。省略時は System.getProperties*().getProperty("line.separator")
  3. Generatorの作成
    1. Generatorの生成は特に必要ありません。HelloJET.txtjet をセーブ(ctrl+s)すると、JETビルダーが動いて自動的に、\JETExam\src 以下にJavaプログラムが生成されます。
      HelloJET.png
    2. 生成されたソースコードは以下のようになっています
      package com.foo.jet.generated;
      
      public class HelloJet
      {
        protected static String nl;
        public static synchronized HelloJet create(String lineSeparator)
        {
          nl = lineSeparator;
          HelloJet result = new HelloJet();
          nl = null;
          return result;
        }
      
        protected final String NL 
          = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
        protected final String TEXT_1 = "Hello, JET.";
      
        public String generate(Object argument)
        {
          StringBuffer stringBuffer = new StringBuffer();
          stringBuffer.append(TEXT_1);
          return stringBuffer.toString();
        }
      }
  4. Generatorの実行
    作成された、com.foo.jet.generated.HelloJET を動かすプログラムを作ってみます。
    package com.foo.jet;
    
    import com.foo.jet.generated.HelloJet;
    
    public class HelloJetInvoker {
    
      public static void main(String[] args) {
        HelloJet generator = HelloJet.create(null);
        String result = generator.generate(null);
        System.out.println(result);
      }
    }
  5. Generatorから生成されたテキスト
    Hello, JET.

テンプレートにパラメータを埋め込む

  1. JETへの引数と予約語について
    1. JETテンプレートにプログラムから与えられるのは、生成された HelloJET#generate(Object argument) の引数 argumentです。
      • 従って、argument は、JETの予約語です。<% %>内で勝手に argument という名のオブジェクトを定義してはいけません。
    2. また、HelloJET#generate(Object argment) 内では、stringBufferオブジェクトに対して、文字列が追記されていっています。
      • 従って、stringBuffer は、JETの予約語です。<% %>内で勝手に stringBUffer という名のオブジェクトを定義してはいけません。
      • 逆に言うと、<% %>内で stringBuffer に対して操作を行えば、HelloJET#generate(Object argment)の返値のStringに影響を与えることが出来ます。
  2. 単純なパラメータ
    argumentを呼び出し元から受け取り表示するようにします
    1. HelloJET.txtjet
      <%@ jet package="com.foo.jet.generated" class="HelloJet" %>
      Hello, <%= argument%>.
    2. 呼び出し
      package com.foo.jet;
      
      import com.foo.jet.generated.HelloJet;
      
      public class HelloJetInvoker {
      
        public static void main(String[] args) {
          HelloJet generator = HelloJet.create(null);
          String result = generator.generate("Taro");
          System.out.println(result);
        }
      }
    3. 実行結果
      Hello, Taro.
  3. JET内にJavaコードを埋め込む(複雑なパラメータ)
    argumentにCollectionを渡して表示します。
    1. HelloJET.txtjet
      <%@ jet 
         package="com.foo.jet.generated"
         class="HelloJet"
         imports="java.util.*" %>
         
      Hello, 
      <% 
        // 引数の内容を列挙
        Collection col = (Collection)argument;
        for( Iterator it = col.iterator() ; it.hasNext() ; ){
          stringBuffer.append(it.next());
          stringBuffer.append(",");
        }
        // 最後のピリオドを消す
        stringBuffer.deleteCharAt(stringBuffer.length()-1);
      %>.
    2. 呼び出し
      package com.foo.jet;
      
      import com.foo.jet.generated.HelloJet;
      
      public class HelloJetInvoker {
      
        public static void main(String[] args) {
          HelloJet generator = HelloJet.create(null);
          Collection students = new LinkedList();
          students.add("Taro");
          students.add("Jiro");
          students.add("Sabro");
          String result = generator.generate(students);     
          System.out.println(result);
        }
      }
    3. 実行結果
      Hello, Taro,Jiro,Sabro.

日本語を使うには

  1. Eclipseの文字コードセットは、Widows環境だとMS932 が標準設定です。
  2. ところが、*.*jet を MS932 で記述すると、生成される Javaソースコード は文字化けしてしまいます
  3. そこで、これを防ぐために、文字コードを UTF-8 に変更する必要があります。
    1. *.*jetファイルを右クリックして、プロパティをクリックします。
    2. 出てきたファイルプロパティWindowで、文字コードを変更します。
    3. この際、JETプロジェクトやEclipseの環境自体の標準文字コードセットを UTF-8 にするのも良いかも知れません。
      Charset.png

JSPの生成

JSPの生成の場合、JSPタグの"<%","%>"と、JETの"<%","%>"が混ざってしまいます。このようなときのためにJETではタグを変更できるようになっています。ここでは"[%","%]"を使います。

  1. HelloJET.txtjet
    <%@ jet 
        package="com.foo.jet.generated"
        class="HelloJSP"
        imports="java.util.*"
        startTag="[%"
        endTag="%]" %>
    
    [%
      String pageName = (String)((Map)argument).get("PAGE_NAME");
      String actionName = (String)((Map)argument).get("ACTION_NAME");
    %]
    
    <%@page contentType="text/html;charset=Shift_JIS" session="true" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    
    <html>
    
    <head>
      <title>[%=pageName%]</title>
    </head>
    
    <body>
      <html:form action="[%=actionName%]">
        <table>
          <tr><td>注文番号</td><td>:</td><td><html:text parameter="orderNo"/></td></tr>
          <tr><td>注文個数</td><td>:</td><td><html:text parameter="orderAmount"/></td></tr>
          <tr><td colspan="3" align="right"><html:submit/></td><tr>
        </table>
      </html:form>
    </body>
    
    </html>
  2. 呼び出し
    package com.foo.jet;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import com.foo.jet.generated.HelloJSP;
    
    public class HelloJSPInvoker {
      public static void main(String[] args) {
        HelloJSP generator = HelloJSP.create(null);
        Map<String,String> argMap = new HashMap<String,String>();
        	
        argMap.put("PAGE_NAME","Order1.jsp");
        argMap.put("ACTION_NAME","/OrderAction1");
        
        System.out.println( generator.generate(argMap));   
      }
    }
  3. 実行結果
    
    <%@page contentType="text/html;charset=Shift_JIS" session="true" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    
    <html>
    
    <head>
      <title>Order1.jsp</title>
    </head>
    
    <body>
      <html:form action="/OrderAction1">
        <table>
          <tr><td>注文商品</td><td>:</td><td><html:text parameter="orderNo"/></td></tr>
          <tr><td>注文個数</td><td>:</td><td><html:text parameter="orderAmount"/></td></tr>
          <tr><td colspan="3" align="right"><html:submit/></td><tr>
        </table>
      </html:form>
    </body>
    
    </html>

帳票出力

JETで生成されるGeneratorは普通のPOJOで特定のライブラリに依存しないので、プログラムのGeneratorとしてだけではなく、アプリ中での帳票のGeneratorとして使うことも出来る。

<%@ jet 
   package="com.foo.jet.generated"
   class="ExpReultGenerator"
   imports="java.util.*" %>
試料番号,経過時間,温度,電圧
<% 
  Collection col = (Collection)argument;
  for( Iterator it = col.iterator() ; it.hasNext() ; ){
    ExamResult res = (ExamResult)it.next());
%>
<%= res.getId() %>,<%= res.getTime() %>,<%= res.getTemp() %>,<%= res.getVol() %>
<%
  }
%>

参考文献

  1. 志田, Eclipse JETを使用した簡単なコード生成の実例, Code Zine, http://codezine.jp/a/article.aspx?aid=111
  2. JET Tutorial Part 1 (Introduction to JET) , http://www.eclipse.org/articles/Article-JET/jet_tutorial1.html
  3. JET Tutorial Part 2 (Write Code that Writes Code), http://www.eclipse.org/articles/Article-JET2/jet_tutorial2.html

Java


*1 [ファイル]-[新規]-[プロジェクト]
*2 [JETExamを右クリック]-[プロパティ]

添付ファイル: filechange_jet_prj4.png 849件 [詳細] fileCharset.png 847件 [詳細] filechange_jet_prj1.png 1048件 [詳細] filechange_jet_prj3.png 950件 [詳細] filejet_overview.png 798件 [詳細] fileHelloJET.png 980件 [詳細] filechange_jet_prj2.png 759件 [詳細] fileeclipse_install.PNG 482件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS   sitemap
Last-modified: 2006-02-18 (土) 01:15:14 (3948d)
ISBN10
ISBN13
9784061426061