HTMLエンコードツールに、native2ascii機能も追加しようと思っていろいろ調べてみました。
とりあえず検索してみたんだけどライブラリは見つかんない。直接native2ascii.exeを呼び出すのはあんまりやりたくなかったので、native2asciiタスクを持っているAntの実装をパクッて参考にしてみることにしました。
検索してsun.tools.native2ascii.Mainというクラスを使っているところを発見。しかし、なぜかインスタンスを直接生成せずリフレクションを使ってクラスを取得しています。このクラスはtools.jarに含まれているそうなので、とりあえずプロジェクトでtools.jarを参照してみました。
でも、なぜかインテリセンスに上記クラスが現れません。無理矢理宣言してもコンパイルエラーになります。どうやらこういうことらしいです。sunパッケージ以下のクラスは将来的に動作が変更される可能性があるから使わないでくださいとのこと。それで、Antでもリフレクションで呼んでたのか。っていうかAntはこの注意事項を守ってないんですね。ある意味男らしいです。
まずはリフレクションのgetDeclaredMethodsメソッドでsun.tools.native2ascii.Mainが持っているメソッドの一覧を取得してみました。publicなメソッドが3個しかありません。
public static void sun.tools.native2ascii.Main.main(java.lang.String[])
private static java.nio.charset.Charset sun.tools.native2ascii.Main.lookupCharset(java.lang.String)
private void sun.tools.native2ascii.Main.error(java.lang.String)
public synchronized boolean sun.tools.native2ascii.Main.convert(java.lang.String[])
public static boolean sun.tools.native2ascii.Main.canConvert(char)
private java.lang.String sun.tools.native2ascii.Main.formatMsg(java.lang.String,java.lang.String)
private java.io.BufferedReader sun.tools.native2ascii.Main.getA2NInput(java.lang.String) throws java.lang.Exception
private java.io.Writer sun.tools.native2ascii.Main.getA2NOutput(java.lang.String) throws java.lang.Exception
private java.lang.String sun.tools.native2ascii.Main.getMsg(java.lang.String)
private java.io.BufferedReader sun.tools.native2ascii.Main.getN2AInput(java.lang.String) throws java.lang.Exception
private java.io.BufferedWriter sun.tools.native2ascii.Main.getN2AOutput(java.lang.String) throws java.lang.Exception
private static void sun.tools.native2ascii.Main.initializeConverter() throws java.io.UnsupportedEncodingException
private void sun.tools.native2ascii.Main.usage()
convert関数の引数に、入力ファイルパスと出力ファイルパスを渡すことで一応変換は出来ました。以下動作したコードです。
Class n2aMain = Class.forName("sun.tools.native2ascii.Main");
Method convert = n2aMain.getDeclaredMethod("convert",new Class[]{String[].class});
Object o = n2aMain.newInstance();
convert.invoke(o,new Object[]{new String[]{"C:\input.txt","C:\output.txt"}});ファイル経由以外ではダメみたいでした。しかも、エンコードは出来てもデコードができません。(なんかデコードに使われてそうなprivateメソッドはもってるのに。)
メモリ内で処理完結できて、デコードにも対応する方法がないかもう少し探してみることにします。