処理器に与えられたクラスの名前を出力するだけの Processor を作成します.
まず,Generator のページの Generate BytecodeProcessor project を参照し,nameprinter を作成してください.
作成されるデフォルトの Java ソースファイルは以下のようなものです.
// this class is generated by Rocinante 1.0
package jp.cafebabe.donquixote.plugins.nameprinter;
import java.io.PrintWriter;
import java.net.URL;
import org.apache.bcel.classfile.JavaClass;
import jp.cafebabe.donquixote.rocinante.Summary;
import jp.cafebabe.donquixote.rocinante.processors.AbstractBytecodeProcessor;
import jp.cafebabe.donquixote.rocinante.summary.FormattedSummary;
public class ClassNamePrinter extends AbstractBytecodeProcessor{
private FormattedSummary summary;
private PrintWriter out;
private int index = 0;
@Override
public void initialize(){
summary = new FormattedSummary(getName());
out = summary.getWriter();
}
@Override
public void perform(JavaClass target, URL location){
index++;
out.println(index + ": " + target.getClassName());
}
@Override
protected Summary summarize(){
return summary;
}
}
これは perform が実行されるたびに,クラス名を Summary に書き出し,最 後に処理対象となったクラス名が Summary の出力によってユーザに提示され るという処理器です.
また,src/main/resources/META-INF/plugins.xml も必要に応じて修正して ください.author-information や properties,そして,description が主な 修正箇所となると思います.
<?xml version="1.0" encoding="euc-jp"?>
<!--
This configuration file is generated by Rocinante 1.0
-->
<donquixote-plugins>
<author-information>
<organizations>
<organization>
<name>cafebabe.jp</name>
<url>http://www.cafebabe.jp/</url>
</organization>
</organizations>
<authors>
<author>
<name>Haruaki TAMADA</name>
<email>tamada[ at ]cafebabe.jp</email>
<organization-name>cafebabe.jp</organization-name>
</author>
</authors>
</author-information>
<plugins>
<plugin>
<name>nameprinter</name>
<description>Sample BytecodeProcessor</description>
<processor>jp.cafebabe.donquixote.plugins.nameprinter.ClassNamePrinter</processor>
<!--
<properties>
<property>
<name>property.name</name>
<description>Description of this property</description>
<value>Default value of this property</value>
</property>
</properties>
-->
</plugin>
</plugins>
</donquixote-plugins>
続いて,FilterBytecodeProcessor の例を示します.
先ほどの例と同じく,Generator のページの Generate FilterBytecodeProcessor project を参照し,deletenop を作成してくださ い.
NOP を削除するために,BCUL を用 います.BCUL のサンプルに NopDeleteInstructionUpdateHandler がありますので,これを使うことにします.依存ライブラリが増えるため, pom.xml に以下の記述を追加します.
:
<dependency>
<groupId>jp.cafebabe.commons</groupId>
<artifactId>bcul</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
:
BCUL サンプルにあ るNopDeleteInstructionUpdateHandler を以下のように少し修正します.いく つの NOP を削除したのかを得るためです.
package jp.cafebabe.donquixote.plugins.deletenop;
import org.apache.bcel.generic.Instruction;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.NOP;
import jp.cafebabe.commons.bcul.updater.AbstractInstructionUpdateHandler;
import jp.cafebabe.commons.bcul.updater.UpdateData;
import jp.cafebabe.commons.bcul.updater.UpdateType;
class NopDeleteInstructionUpdateHandler extends AbstractInstructionUpdateHandler{
private int count = 0; // add new field
/**
* add new method.
*/
public void reset(){
count = 0;
}
/**
* add new method
*/
public int getCount(){
return count;
}
public boolean isTarget(InstructionHandle i, UpdateData data){
return i.getInstruction() instanceof NOP;
}
public UpdateType getUpdateType(InstructionHandle i){
return UpdateType.REPLACE;
}
public InstructionList updateInstruction(InstructionHandle i, UpdateData data){
count++; // add
return null;
}
}
次に Generator により作成された NopDeleteProcessor を修正します.
// this class is generated by Rocinante 1.0
package jp.cafebabe.donquixote.plugins.deletenop;
import java.io.PrintWriter;
import java.net.URL;
import org.apache.bcel.classfile.JavaClass;
import jp.cafebabe.commons.bcul.updater.BytecodeUpdater;
import jp.cafebabe.donquixote.rocinante.Summary;
import jp.cafebabe.donquixote.rocinante.processors.FilterBytecodeProcessor;
import jp.cafebabe.donquixote.rocinante.summary.FormattedSummary;
public class NopDeleteProcessor extends FilterBytecodeProcessor{
private FormattedSummary summary;
private PrintWriter out;
private BytecodeUpdater updater;
private DeleteNopInstructionUpdateHandler handler;
private int total = 0;
public NopDeleteProcessor(BytecodeProcessor processor){
super(processor);
}
@Override
public void initialize(){
updater = new BytecodeUpdater();
updater.addHandler(handler = new NopDeleteInstructionUpdateHandler());
summary = new FormattedSummary(getName());
out = summary.getWriter();
total = 0;
}
@Override
public void perform(JavaClass target, URL location){
ClassGen newClass = updater.update(new ClassGen(target));
JavaClass modifiedTarget = newClass.getJavaClass();
int count = handler.getCount();
total += count;
if(count > 0) out.println(target.getClassName() + ": " + count + " NOP deleted.");
processor.perform(modifiedTarget, location);
}
@Override
public Summary summarize(){
out.println();
out.println("Total: " + total + " NOP deleted.");
out.close();
}
}
最後に,src/main/resources/META-INF/plugins.xml も必要に応じて修正し てください.author-information や properties,そして,description が主 な修正箇所となると思います.
ここまで修正した後,Maven2 を使ってパッケージングすると DonQuixote プ ラグインとして動作します.