2010-09-12 29 views
2

我試圖寫一個Ant <scriptfilter...>要改變字符串"__LINE__"的出現在Java源文件的正確的行號。使用Ant scriptfilter計算行

沒有人有使用JavaScript(或其他一些嵌入的腳本語言)來做到這一點的例子嗎?特別是,如何創建一個「全局」變量,該變量在腳本啓動時初始化爲1,並隨每個新行增加?

謝謝。

更新:剛剛嘗試過由Martin Clayton提供的解決方案(謝謝!),用Beanshell代替JavaScript,它的工作完美無缺。這裏是螞蟻的目標代碼:

<target name="preprocess" depends="ivy.resolve" description="Preprocess the source code"> 
    <mkdir dir="${target.source.dir}"/> 
    <copy todir="${target.source.dir}" includeemptydirs="true" failonerror="true" verbose="true"> 
     <fileset dir="${src.dir}"/> 
     <filterchain> 
      <tokenfilter> 
       <filetokenizer/> 
       <scriptfilter language="beanshell" byline="true" setbeans="true"><![CDATA[ 
        import java.io.BufferedReader; 
        import java.io.StringReader; 
        int count = 1; 
        BufferedReader br = new BufferedReader(new StringReader(self.getToken())); 
        StringBuilder builder = new StringBuilder(); 
        String line; 
        while ((line = br.readLine()) != null) { 
         builder.append(line.replace("\"__LINE__\"", Integer.toString(count))).append('\n'); 
         count++; 
        } 
        self.setToken(builder.toString()); 
       ]]></scriptfilter> 
      </tokenfilter> 
     </filterchain> 
    </copy> 
</target> 

回答

3

你可以使用一個ant屬性來保存'靜態'。

這裏是一個非常簡單的例子,對於一個文件

<property name="lineNumber" value="0" /> 
<copy file="input.txt" tofile="output.txt" > 
    <filterchain> 
     <scriptfilter language="javascript"> 
      project.setProperty("lineNumber", 
           parseInt(project.getProperty("lineNumber")) + 1); 

      if (self.getToken().indexOf("__LINE__") != -1) { 
       lineNumber = project.getProperty("lineNumber"); 
       self.setToken(self.getToken().replaceAll("__LINE__", lineNumber)); 
      }    
     </scriptfilter> 
    </filterchain> 
</copy> 

的問題是:不會擴展到多個文件 - lineNumber沒有重置文件之間的一個。

您可以使用一個filetokenizer來獲得整個文件轉換成JavaScript一氣呵成,然後處理文件中的行由行。 這裏有一個非常諾迪例如(我知道足夠的javascript是危險的)。我相信這有很多缺點(並非最不重要的一點:它不處理非換行符終止的文件;令人震驚的串連接)。 但是原理是通過將每個整個文件都放入腳本中,不需要任何信息在腳本調用之間持久化。

<copy todir="output"> 
<fileset dir="input"/> 
<filterchain> 
    <tokenfilter> 
    <filetokenizer/> 
     <scriptfilter language="javascript"><![CDATA[ 

      // Get the whole input file to one string. 
      inputContent = self.getToken(); 

      lineNum = 1; 
      fileEnd = inputContent.length(); 

      // Build the new file up line-by-line in this var. 
      outputContent = ""; 

      lineStart = 0; 
      lineEnd = inputContent.indexOf("\n"); 
      while (lineEnd < fileEnd) { 
       outputContent += inputContent 
           .substring(lineStart, lineEnd) 
           .replaceAll("__LINE__", lineNum) + "\n"; 
       lineStart = lineEnd + 1; 
       fc = inputContent.substring(lineStart); 
       lineEnd = fc.indexOf("\n"); 
       if (lineEnd == -1) 
        break; 
       lineEnd += lineStart; 
       lineNum++; 
      } 

      self.setToken(outputContent); 
      ]]></scriptfilter> 
    </tokenfilter> 
</filterchain> 
</copy> 
+0

提問後,我開始看豆殼。我對JavaScript的瞭解也很薄弱。然而,Beanshell讓我用類似Java的語法來做同樣的事情。我要仔細看看第二種可能性('filetokenizer')。看起來它可能會**完全**我所需要的。謝謝。 – Ralph 2010-09-13 11:22:09