Maven2 で native2ascii コマンドを実行するプラグイン.
<plugins>
<plugin>
<groupId>com.jakubpawlowicz.maven.plugins</groupId>
<artifactId>maven-ant-plugins</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>native2ascii</goal>
</goals>
<configuration>
<encoding>shift_jis</encoding>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
みたいなのを pom.xml に追加すれば native2ascii がかけられる.ただし,tools.jar にクラスパスを通しておく必要がある.
困った点
- filter を見事に無視してくれる.
- 拡張子が properties なものが全て対象になるようだ.
filter が無視されるのはイタイ.properties ファイル中に ${pom.version}とか ${pom.artifactId} などを参照することが多いと思うんだが.これさえ OK ならある拡張子を全て処理の対象になっても良いんだがなぁ.ただし,拡張子が properties 決めうちはイマイチだ.
ついカッとなって作ってしまった.拡張子についてはまだ未対応だけど,まぁ,よしなに.ライセンスは 無償・無保証・著作権放棄 です.
まずは maven-resources-plugin をチェックアウトする.
svn co https://svn.apache.org/repos/asf/maven/plugins/tags/maven-resources-plugin-2.2
で,以下の Native2AsciiWriter を適当な場所に置く.置く場所により package 名は変更する必要がある.以下のコードでは ResourcesMojo.java と同じ場所に置いている.
package org.apache.maven.plugin.resources;
import java.io.FilterWriter;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.*;
/**
* FilterWriter for `native2ascii' command.
*
* @author Haruaki TAMADA
* @version 1.0 2006/09/11
*/
public class Native2AsciiWriter extends FilterWriter{
/**
* constructor
*/
public Native2AsciiWriter(Writer out){
super(out);
}
/**
* write encoded code (exclude ASCII code)
*/
public void write(char[] data, int offset, int length) throws IOException{
StringBuffer sb = new StringBuffer();
for(int i = 0; i < length; i++){
int value = (int)data[i + offset];
if(value <= 0xff && (value & 0x80) == 0){
sb.append(data[i + offset]);
}
else{
sb.append("\\u");
String characterCodeString = Integer.toString(value & 0xffffffff, 16);
for(int j = characterCodeString.length(); j < 4; j++){
sb.append("0");
}
sb.append(characterCodeString);
}
}
out.write(new String(sb).toCharArray());
}
}
次に,チェックアウトした maven-resources-plugin-2.2 に以下のパッチを当てる.
Index: src/test/java/org/apache/maven/plugin/resources/ResourcesMojoTest.java
===================================================================
--- src/test/java/org/apache/maven/plugin/resources/ResourcesMojoTest.java (revision 442118)
+++ src/test/java/org/apache/maven/plugin/resources/ResourcesMojoTest.java (working copy)
@@ -418,6 +418,41 @@
assertTrue( fileContains( resourcesDir + "/file4.properties", checkString ) );
}
+ /**
+ * @throws Exception
+ */
+ public void testPropertyFiles_FilteringAndNative2Ascii()
+ throws Exception
+ {
+ File testPom = new File( getBasedir(), defaultPomFilePath );
+ ResourcesMojo mojo = (ResourcesMojo) lookupMojo( "resources", testPom );
+ MavenProjectResourcesStub project = new MavenProjectResourcesStub( "resourcePropertyFiles_FilteringAndNative2Ascii" );
+ List resources = project.getBuild().getResources();
+ LinkedList filterList = new LinkedList();
+
+ assertNotNull( mojo );
+
+ project.addFile( "file4.properties", "current working directory=${dir}" );
+ project.addFile( "filter.properties", "dir:testdir" );
+ project.setResourceFiltering( 0, true );
+ project.setupBuildEnvironment();
+ filterList.add( project.getResourcesDirectory() + "filter.properties" );
+
+ //setVariableValueToObject(mojo,"encoding","UTF-8");
+ setVariableValueToObject( mojo, "native2ascii", Boolean.TRUE );
+ setVariableValueToObject( mojo, "project", project );
+ setVariableValueToObject( mojo, "resources", resources );
+ setVariableValueToObject( mojo, "outputDirectory", project.getBuild().getOutputDirectory() );
+ setVariableValueToObject( mojo, "filters", filterList );
+ mojo.execute();
+
+ String resourcesDir = project.getOutputDirectory();
+ String checkString = "current working directory=testdir";
+
+ assertTrue( FileUtils.fileExists( resourcesDir + "/file4.properties" ) );
+ assertTrue( fileContains( resourcesDir + "/file4.properties", checkString ) );
+ }
+
// reads the first line of the file and compares it
// with data. returns true if equal
private boolean fileContains( String fileName, String data )
Index: src/main/java/org/apache/maven/plugin/resources/ResourcesMojo.java
===================================================================
--- src/main/java/org/apache/maven/plugin/resources/ResourcesMojo.java (revision 442118)
+++ src/main/java/org/apache/maven/plugin/resources/ResourcesMojo.java (working copy)
@@ -77,6 +77,13 @@
private List resources;
/**
+ *
+ *
+ * @parameter
+ */
+ private boolean native2ascii;
+
+ /**
* @parameter expression="${project}"
* @required
* @readonly
@@ -250,6 +257,9 @@
fileWriter = new OutputStreamWriter( outstream, encoding );
}
+ if(native2ascii){
+ fileWriter = new Native2AsciiWriter(fileWriter);
+ }
// support ${token}
Reader reader = new InterpolationFilterReader( fileReader, filterProperties, "${","}" );
ユニットテストは別に追加せんでもええけど.これで mvn install してローカルリポジトリに maven-resources-plugin を登録する.
次に,native2ascii をかけたいプロジェクトの pom.xml を編集.
<build>
<plugins>
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<native2ascii>true</native2ascii>
</configuration>
</plugin>
:
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
これで mvn package を実行すると src/main/resources 以下のファイルがフィルタリングされつつ native2ascii もかけられる.
ただ,native2ascii とか言っているけど,内部では全く native2ascii を呼んでいない.なので,tools.jar にクラスパスを通す必要もない.その代わりどんな場合でも動くかどうかはわかんない.
native2ascii は要するに utf-8 のコードを全て ascii コードの数値で表しているだけなので,char 型を int 型に変換すれば同じことだと思う.要するに,「あ」は utf-8 コードでは 0x3042 なのだが,これを native2ascii にかけると "\u3042" という 6 文字になる.これで大丈夫だと思う.んでもって,ascii コードに含まれる文字列(0x00〜0x7f)だけ処理を行わないようにすればいいかなぁ,なんて.ASCII コードと utf-8 の ASCII コードに相当する部分は同じコード体系だったと思うし,ASCII コードまでエンコードされたんじゃ見にくいし.