Cubby+Guiceでアクションの自動登録
これやってたから
http://d.hatena.ne.jp/shin/20090720/p1
に気がついたともいえる。
全部ソース乗せる。パッケージが適当すぎるとか言わない。
package hoge; import com.google.inject.AbstractModule; import com.google.inject.Binder; import com.google.inject.servlet.ServletModule; import java.io.File; import java.io.FilenameFilter; import java.lang.reflect.Modifier; import javax.servlet.ServletContext; import org.seasar.cubby.action.Action; import org.seasar.cubby.action.ActionClass; public class ActionAutoBindModule extends AbstractModule { File root; FilenameFilter nFilter; public ActionAutoBindModule(ServletContext sc) { root = new File(sc.getRealPath("WEB-INF/classes")); nFilter = new FilenameFilter() { public boolean accept(File dir, String name) { if (new File(dir, name).isDirectory()) { return true; } if (name.endsWith(".class")) { return true; } return false; } }; } @Override protected void configure() { install(new ServletModule()); search(root, binder()); } private void search(File parent, Binder binder) { for (File file : parent.listFiles(nFilter)) { if (file.isDirectory()) { search(file, binder); } else { bindClass(file, binder); } } } private void bindClass(File file, Binder binder) { String fileName = file.getAbsolutePath(); String name = fileName.substring( root.getAbsolutePath().length() + 1, fileName.length() - ".class".length()); name = name.replace(File.separatorChar, '.'); try { Class c = Class.forName(name); //アノテーションがついてるか? if (c.isAnnotationPresent(ActionClass.class) == false) { try { //Actionのサブクラスか? c.asSubclass(Action.class); } catch (Exception ex) { return; } } //publicなコンクリートクラス以外ははねる if(c.isInterface()){ return; } if(Modifier.isAbstract(c.getModifiers())){ return; } if(Modifier.isPublic(c.getModifiers()) == false){ return; } //ここで登録する System.out.println(name); binder.bind(c); } catch (ClassNotFoundException ex) { } } }
ちなみにCubby以外でも自動登録が出来てハッピー!かとおもいきや、実はこのクラス名のみのbindはCubby以外では役に立たない。
理由はCubby以外のWebフレームワークは全て自分でアクションクラスの管理をしているから。T2FrameworkでもStrutsでもJSFでもなんでもそう。これはあくまでもCubby+Guiceでも他のWebフレームワークと同等の使い勝手にするための設定。