[轉]ant的模塊化以及java調用

所有的語言都有維護和代碼重用的壓力,目前爲止,Ant已經提供了很多的Task,可以幫助實現Ant腳本的模塊化。

 1. Property
  Property Task除了能夠定義單個的屬性,還可以從一個屬性定義文件定義多個property。把公用的屬性放到屬性文件中,各個build.xml中都載入此屬性文件,就可以避免在每個build.xml中重複定義這些屬性。

2. AntCall, Ant和SubAnt
  AntCall可以理解爲簡單的函數調用。舉一個例子就清楚了:
  <target name=”commonTarget”>
   <echo message=”${test.param}” />
  </target>
  
  <target name=”callingTarget”>
   <antcall target="commonTarget">
   <param name="test.param" value="Modulation" />
   </antcall>
  </target>

  從上面的例子可以看到,指明要調用的target,再通過<param>指明調用參數;在被調用的Target中,通過與引用property類似的方式即可引用param的值。
  至於Ant Target,也是調用別的Target,不過那個Target可以是在另外一個ant 文件中。

 3. MacroDef
  AntCall很好用,不過當參數很多時要寫很多的<param name=”” value=”” />起來很麻煩,如果你想偷懶,用MacroDef就行了。下面把上面的例子用MacroDef重寫:
   <macrodef name="showModule">這裏是macrodef的定義

   <attribute name="test.param1"/>這個是參數的定義,可以再macrodef外部調用
   <attribute name="test.param" default="NOT SET"/>內部參數
   <sequential>實際執行的內容都在sequential中
   <echo message="@{test.param}" />
   </sequential>
   </macrodef>
  
   <target name="testMacro">
   <showModule test.param="Modulation" />
   </target>

需要注意的是:

1,在整個build文件裏macrodef和target是平級的。

2,macrodef可以調用其他的macrodef,不可以調用target;target可以調用macrodef,也可以調用其他的target。

3,macrodef嵌套的時候,參數名稱必須不同。

我們可以象系統提供的其他Task一樣引用showModule,的確簡潔多了。定義一個Macro,首先定義此宏的attribute,包括attribute的name, default;然後在<sequential>標籤中定義此宏的所有操作。注意對attribute的引用是@{attr-name}!實際上,Ant還允許在attribute後面定義一組element,達到極高的動態性。

 

4. Import
  <antcall>和<marcodef>可以達到類似函數的效果,但是調用者和被調用者還是必須在同一個文件中。Ant從1.6開始引入Import Task,可以真正的實現代碼重用:屬性,Task 定義,Task, Macro。一個簡單的例子:
  
  common.xml:
  <?xml version="1.0" ?>
  <project>
   <property name="project.name" value="Ant Modulazation" />
  
   <target name="commonTarget">
   <echo message="${test.param}" />
   </target>
  
   <macrodef name="showModule">
   <attribute name="test.param" default="NOT SET"/>
   <sequential>
   <echo message="@{test.param}" />
   </sequential>
   </macrodef>
  
  </project>
  
  call.xml:
  <?xml version="1.0" ?>
  <project name="testCommon" default="callingTarget">
   <import file="common.xml" />
  
   <target name="callingTarget">
   <antcall target="commonTarget">
   <param name="test.param" value="Modulation" />
   </antcall>
   </target>
  
   <target name="testMacro">
   <showModule test.param="Modulation" />
   </target>
  </project>

注意:在common.xml中,不能對project元素設置屬性;另外,不要試圖使用重名的property,或target以獲取覆蓋的效果,因爲Ant畢竟不是編程語言。

 

自定義Ant Taskhttp://blog.csdn.net/pipisky2006/article/details/6680379

這裏只有task,也可以創建project對象,寫一個純code的build

1:基本環境,建議用Eclipse這個工具來做爲Java的基本開發工具,用Eclipse的嚮導新建一個Java工程test。


2:將ANT的以下幾個jar文件添加到剛纔新建的test工程的構建引用路徑下面,即添加到classpath中去:ant-lanucher.jar、ant.jar、ant-jakarta-log4j.jar這三個jar文件是最基本的,必須添加進去,如果要用到ANT的一些其它類,需要添加相應的jar文件,具體可以參考ANT的幫助文件。這三個文件簡單說明一下,ant-lanucher.jar裏面的類是ANT程序啓動時必須要用到的,在Java代碼中調ANT時,是需要通過這個包中的類來啓動ANT裏面的類去執行定義的動作,這個包是啓動入口類; ant.jar這個包裏面是ant定義的一些核心功能類的class,如copy文件,刪除文件,執行數據庫腳本,打包等等,即是具體的核心功能實現類,如果是一些附加的ant功能,則在其它jar包裏面,這個只有非常核心的類在裏面; ant-jakarta-log4j.jar是ant重新包裝了log4j的類,實現ANT自己格式的log4j的日誌文件記錄。


3:在test工程裏面新建一個類,類裏面增加一個Java的main方法,在main方法中添加如下代碼,並導入相關的package:
PrintStream logstream = null; //這裏是定義一個ANT執行時日誌文件的輸出流對象
Project pj=new Project(); //初始化一個ant的Project對象
pl.setName("ant_project"); //設置project的名稱,具體的值可以隨意改成其它字符串都可以
pj.init(); //ANT自己的方法初始化Project對象


DefaultLogger cl=new DefaultLogger();
//定義一個默認的日誌流,默認的日誌流是採用log4j來記錄的,所以在前面要求將ant-jakarta-log4j.jar這個文件加到classpath中去。
logstream=new PrintStream(new FileOutputStream("C:/test.log"),true);
//下面兩行是設置ANT執行過程中要輸出的一些信息流,必須設置,否則後面將得不到具體的日誌消息
cl.setErrorPrintStream(logstream);
cl.setOutputPrintStream(logstream);
//設置ANT記錄日誌的消息級別,MSG_VERBOSE是表示記錄詳細的日誌消息
cl.setMessageOutputLevel(Project.MSG_VERBOSE);
//將前面定義好的消息記錄器綁定到Project上
pj.addBuildListenter(cl);


//生成一個Target對象,爲後面添加具體的Task做準備
Target tg=new Target();
tg.setProject(pj); //設置target的Project歸屬,必須設置,Target必須屬於某一個Project
tg.setName("target1"); //設置Target的名稱
pj.addTarget(tg); //將Target添加到Project中


Copy cp=new Copy(); //具體生成一個功能Task類對象,複製文件的對象
cp.setTodir(new File("C:/bbb")); //設置要將文件複製的目的地
FileSet set=new FileSet(); //定義目錄集,這樣在後面可以自己定義一些規則
set.setDir(new File("C:/aaa")); //定義目錄集關聯的實際目錄路徑
set.createInclude().setName("**/*.txt"); //設置這個目錄集包括的規則,即這個目錄下面所有的.txt後綴的文件
cp.addFileset(set); //將目錄集綁定到具體的對象中
cp.setOverwrite(true);//設置在複製文件時,如果目標文件己經存在,將採用直接覆蓋的方式
cp.setFailOnError(true); //設置在複製文件過程中有文件複製失敗時,則中斷執行這個過程
cp.setPreserveLastModified(true); //設置複製文件時保留文件的最後修改時間
cp.setProject(pj); //設置Task的Project歸屬
cp.setTaskName("cp"); //設置Task的名稱
tg.addTask(cp); //將Task添加到Target中,Task不能單獨存在,也不能直接添加到Project中


Throwable ta=null;
try {
pj.executeTarget(tg.getName()); //開始執行Project中指定的Target
}catch (Exception e){
ta=e;
} finally {
/*    在日誌文件當中生成執行成功或失敗的消息,調用這個方法後,如果ANT的Project執行成功,則會在日誌文件當中生成一行“BUILD SUCCESSFUL”或"BUILD FAILED"這樣的字符串,在執行失敗時,同時會將異常消息打印在日誌文件中,所以這個方法比較重要   */
pj.fireBuildFinished(ta);
logstream.close();
}

 

(轉自: http://blog.csdn.net/pipisky2006/article/details/7101778

發佈了70 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章