coberturaに日本語パッチをあてる
以前の日記でコードカバレッジで、djUnitを使用するように書きましたが、
Antから実行するのがどうにも厄介そう*1なので、急遽jcoverageの後継であるcoberturaを使用するように変更しました。
しかし、このツールも他のツールと同様、お米の国の方が作成したツール同様マルチバイト文字に関する扱いはぞんざいで、UTF-8以外の文字コードを使用したコードの場合は見事に文字化けさせてくれちゃいます。*2
最初は、まぁいいやとも思ってたのですが、若干客先対応で時間が空いたのでパッチをあててみました。
ベースとなるバージョンは現時点で最新の1.9を利用します。
なお、パッチ適用済みのcobertura.jarはこちらから入手可能です。
coberturaは、GPLライセンスでの提供ですので、公開したソースに対しても当然動作保障はしませんのであしからず。
ただし、質問は受け付けますので、本日記にコメントでも入れてくださいな。
通常antから、coberturaのレポートを作成する場合は、
と記述するのですが、
<cobertura-report srcdir="..." destdir="..." sourceEncoding="..." />
と書けば、その文字コードでソースコードを読み込むようにします。
net.sourceforge.cobertura.ant.ReportTask
085: public void execute() throws BuildException { 086: CommandLineBuilder builder = null; 087: try { 088: builder = new CommandLineBuilder(); 089: if (dataFile != null) 090: builder.addArg("--datafile", dataFile); 091: if (destDir != null) 092: builder.addArg("--destination", destDir.getAbsolutePath()); 093: if (format != null) 094: builder.addArg("--format", format); 095: if(sourceEncoding != null) //(2) 096: builder.addArg("--sourceEncoding", sourceEncoding); 097: if (srcDir != null) 098: builder.addArg(srcDir); 099: : : どっか適当な位置に。。。 private String sourceEncoding = "UTF-8"; //(1) public void setSourceEncoding(String sourceEncoding) { this.sourceEncoding = sourceEncoding; }
- Antのタスクに属性を増やしたので、そのセッターメソッドと対応プロパティを追加。デフォルト動作は変えたくないので、省略時は「UTF-8」とする。
- レポート生成のスタートクラス(net.sourceforge.cobertura.reporting.Main)へのコマンドライン引数にsourceEncodingを渡すようにする。多分nullの事は無いと思うけどとりあえずnullチェックもしてる
net.sourceforge.cobertura.reporting.Main
047: private void parseArguments(String[] args) throws Exception { 048: FileFinder finder = new FileFinder(); 049: String baseDir = null; 050: String sourceEncoding = "UTF-8"; //(1) 051: for (int i = 0; i < args.length; i++) { 052: if (args[i].equals("--basedir")) { 053: baseDir = args[++i]; 054: } else if (args[i].equals("--sourceEncoding")) { 055: sourceEncoding = args[++i]; //(2) 056: } else if (args[i].equals("--datafile")) { : 102: if (format.equalsIgnoreCase("html")) { 103: new HTMLReport(projectData, destinationDir, finder, complexity, sourceEncoding); //(3) 104: } else if (format.equalsIgnoreCase("xml")) { 105: //TODO XMLの方は未対応 //(4) 106: new XMLReport(projectData, destinationDir, finder, complexity); 107: } :
net.sourceforge.cobertura.reporting.html.HTMLReport
074: private String sourceEncoding = "UTF-8"; //(1) : 079: public HTMLReport(ProjectData projectData, File outputDir, 080: FileFinder finder, ComplexityCalculator complexity, String sourceEncoding) 081: throws Exception //(2) 082: { 083: this.destinationDir = outputDir; 084: this.finder = finder; 085: this.complexity = complexity; 086: this.projectData = projectData; 087: this.sourceEncoding = sourceEncoding; //(3) : 540: private String generateHtmlizedJavaSource(SourceFileData sourceFileData) : 553: BufferedReader br = null; 554: try 555: { 556: br = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), this.sourceEncoding));//(4) 557: } 558: catch (UnsupportedEncodingException e) 559: { 560: return "<p>Unable to open " + sourceFile.getAbsolutePath() 561: + ": The encoding '"+ this.sourceEncoding + "' is not supported by your JVM.</p>"; //(5) 562: } :
- 例によって文字コードを退避するメンバ変数の定義
- 引数を当然のごとく増やす
- そして、当然退避する
- オブジェクト生成時に渡された文字コードでBufferedReaderを生成する。元のコードは「UTF-8」とべたに書いてある
- エラーメッセージも一応直しておいた。元のコードは当然「UTF-8」と直書きされている
これだけで、対応可能でした。思ったより楽チンでよかった。