[[JAVAの記事一覧]]

&topicpath;

*目次 [#qb433e3e]
#contents

*はじめに [#gb128514]
設定ファイル地獄という言葉がある。
設定中心のフレームワークが、設定だらけになって
メンテナンスが地獄のように面倒になる現象だ。

ここで、アノテーションと呼ばれるものの登場である。

最初アノテーションと言う言葉を知ったときには、何につかうのか?と使い道が思いつかなかったのだが、どうやら、設定中心のフレームワークに応用すると、地獄から抜けられる。たとえば、Strutsに対するSAStrutsの登場である。

自分は、当初SAStrutsがあるんだから、それを使えばよいと思っていた。

しかしながら、SAStrutsは、独自の規約で作成しなくてはならないため、プロジェクトに応用できないということがわかってきた。

だったら、自分で道を切り開くのみである。

というわけで、以下アノテーションについてまとめてみた。

*目標 [#g2bd8ca1]
以下の方法を理解する。
-クラスにつけるアノテーションを定義
-メソッドにつけるアノテーションに定義


*作り方 [#i2262517]
**クラスにつけるアノテーションを定義 [#x6951bcb]
最小限の学習ですむように説明するならば、
たとえば、
 StringValueAnnotation
というアノテーションを作りたいとすると下記のようになる。
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 @interface StringValueAnnotation {
	String value() default "デフォルト値";
 }
その他は、固定値だと思って差しつかえない。


**メソッドにつけるアノテーションに定義 [#pd9b172f]
上記の例でTYPEとなっている箇所を
 FIELD
に置き換えるだけでよい。

*実装クラス一覧 [#h66a80f2]
知りたいのは、実装するクラスの一覧であるが、どういうわけか
Javaらしからず、そのような一覧取得のメソッドは用意されていない、
自分で道を切り開くのみである。

ソースフォルダを指定すると、クラス一覧を取得するメソッドを作製する。


*とりあえず作ったサンプル [#af600daa]
**ActionAnnotation [#a09f69ce]
 package kuniwiki;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
  
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 @interface ActionAnnotation {
	String value1() default "";
	String value2() default "";
	String value3() default "";
 
 }

**AnnoMain [#xd383d5e]
 package kuniwiki;
 
 import java.io.File;
 import java.io.IOException;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 
 public class AnnoMain {
	public static void main(String[] args) throws IOException {
		String basePath = "C:/bin/pleiades/workspace/prjAno/src";
 
		FileSearch search = new FileSearch();
		File[] files = search.listFiles(basePath, "*.java");
 
		for(File f : files){
			Class clazz = toClass(basePath, files[4]);
			HashMap<String, HashMap<String, String>> ano = toAnoHash(clazz);
			if (ano != null) {
 				System.out.println(ano.get("kuniwiki.ActionAnnotation").get("value1"));
 				System.out.println(ano.get("kuniwiki.ActionAnnotation").get("value2"));
 				System.out.println(ano.get("kuniwiki.ActionAnnotation").get("value3"));
			}
		}
 
 
	}
 
	private static HashMap toAnoHash(Class clazz) {
		HashMap ret = new HashMap<String, HashMap<String, String>>();
		Annotation[] as = clazz.getDeclaredAnnotations();
		for (Annotation a : as) {
			Class tp = a.annotationType();
 
			// アノテーション名を登録;
			HashMap<String, String> item = new HashMap<String, String>();
			ret.put(a.annotationType().getName(), item);
			// フィールドを追加
 
			ActionAnnotation an = (ActionAnnotation)a;
			//tp.getTypeParameters();
 
 
			Method[] ms = an.getClass().getMethods();
			//Annotation[][] ma = ms[0].getParameterAnnotations();
			try {
				Object[] param = {};
				item.put(ms[4].getName(),ms[4].invoke(an, param).toString());
			} catch (IllegalArgumentException e) {
				// TODO
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO
				e.printStackTrace();
			}
 
			// item.put("value1",Class.forName("kuniwiki.ActionAnnotation").cast(a).getClass().getFields()[0].toString());
 
		}
		return ret;
	}
 
	private static boolean hasActionAnnotation(Class clazz) {
		Class ano = ActionAnnotation.class;
 
		Annotation[] as = clazz.getDeclaredAnnotations();
		for (Annotation a : as) {
			if (a instanceof ActionAnnotation) {
				return true;
			}
		}
		return false;
	}
 
	private static Class toClass(String src, File fi) {
		// ソースのパスを置換用に置き換える
		String srcpath = src.replaceAll("/", "\\\\\\\\");
		// ファイルの親パスからソースパスをさっぴいて、フォルダを意味する記号をドットに置き換え、ファイル名をクラス名として連結する。
		String classname = fi.getParent().replaceFirst(srcpath, "")
				.replaceAll("\\\\", ".").replaceFirst("\\.", "")
				+ "." + fi.getName().replace(".java", "");
 
		try {
			System.out.println(classname);
			return Class.forName(classname);
		} catch (ClassNotFoundException e) {
			return null;
		}
	}
 
 }


*参考ページ [#o747b05f]
http://sattontanabe.blog86.fc2.com/blog-entry-55.html

**参考ページ [#sd08201e]
http://www.ne.jp/asahi/hishidama/home/tech/java/annotation.html

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS