MetaClassを使う

http://metaclass.codehaus.org/
codehaus製の、メタデータに動的にアクセスするためのライブラリ。
ソースからJavaDocコメントの情報を吸い上げて、classファイルに埋め込んでいるみたい。


対象のクラスをこんな感じで作成。


/**
* @foo ふー
* @bar ばー
*/
public class Foo {

/**
* @foo.foo ふーふー
* @bar.bar ばーばー
*/
public void func() {
System.out.println("hello, MetaClass");
}

public void func2() {
System.out.println("hello, MetaClass");
}

}

メタ情報表示クラスはこんな感じ。


public class Main {

public static void main(String args) {
Attribute
class_attrs = Attributes.getAttributes(Foo.class);
printAttributes(Foo.class, class_attrs);
Method methods = Foo.class.getMethods();

for (int i = 0; i < methods.length; i++) {
Attribute method_attrs = Attributes.getAttributes(methods[i]);
printAttributes(methods[i], method_attrs);
}
}

private static void printAttributes(Object object, Attribute[] attributes) {
System.out.println(object);

for (int i = 0; i < attributes.length; i++)
System.out.println(" " + attributes[i].getName() + "=" + attributes[i].getValue());
}

}

で、以下のようなAntスクリプトを実行。


<?xml version="1.0" ?>
<project default="all">
<property name="project.dir" value="C:/eclipse/workspace/metameta" />
<property name="bin.dir" value="${project.dir}/bin" />
<property name="src.dir" value="${project.dir}/src" />
<property name="lib.dir" value="${project.dir}/lib" />

<path id="classpath">
<pathelement location="${bin.dir}" />
<fileset dir="${lib.dir}" includes="**/*" />
</path>

<taskdef name="metaclassGen" classname="org.codehaus.metaclass.tools.tasks.GenerateClassDescriptorsTask">
<classpath refid="classpath" />
</taskdef>

<target name="all">
<antcall target="compile" />
<antcall target="gen.meta" />
<antcall target="run" />
</target>

<target name="compile">
<javac destdir="${bin.dir}">
<src path="${src.dir}" />
<classpath refid="classpath" />
</javac>
</target>

<target name="gen.meta">
<metaclassGen destDir="${bin.dir}" namespaceTagsOnly="false">
<fileset dir="${src.dir}" />
</metaclassGen>
</target>

<target name="run">
<java classname="foo.Main" classpathref="classpath" />
</target>
</project>

実行結果は次のとおり。


Buildfile: C:\eclipse\workspace\metameta\build.xml
all:
compile:
gen.meta:
[metaclassGen] MetaClass Attributes Compiler writing 1 binary descriptors.
run:
[java] class foo.Foo
[java] foo=ふー
[java] bar=ばー
[java] public void foo.Foo.func()
[java] foo.foo=ふーふー
[java] bar.bar=ばーばー
[java] public void foo.Foo.func2()
[java] public native int java.lang.Object.hashCode()
[java] public final native java.lang.Class java.lang.Object.getClass()
[java] public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
[java] public final void java.lang.Object.wait() throws java.lang.InterruptedException
[java] public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
[java] public boolean java.lang.Object.equals(java.lang.Object)
[java] public final native void java.lang.Object.notify()
[java] public final native void java.lang.Object.notifyAll()
[java] public java.lang.String java.lang.Object.toString()
BUILD SUCCESSFUL
Total time: 1 second