WicketでHTMLとJavaソースの場所を別々にする方法メモ。

馬鹿の一つ覚えのように(というか、馬鹿の一つ覚え以外の何者でもないのですが)MVC!!MVC!!と脳内のアホ中枢から指令がきたのでやってみた。




まずはWicketのWikiからサンプルを。
HTMLの参照先ディレクトリを/WEB-INF/html/にするサンプル。
1.最初にIResourceStreamLocatorを作る。

public class PathStripperLocator extends ResourceStreamLocator
{
  public PathStripperLocator()
  {
  }

  public IResourceStream locate(final Class clazz, final String path)
  {
    IResourceStream located = super.locate(clazz, trimFolders(path));
    if (located != null) {
      return located;
    }
    return super.locate(clazz, path);
  }

  private String trimFolders(String path)
  {
    return path.substring(path.lastIndexOf("/") + 1);
  }
}

後は上記クラスをアプリケーションの中のinit()で動かしてあげればOK。(当然ながらHTMLの名前はクラス名と同じにする必要あり)

@Override
protected void init() {
  super.init();
  IResourceSettings resourceSettings = getResourceSettings();
  resourceSettings.addResourceFolder("src/main/webapp"); //検索先ディレクトリパスを追加
  resourceSettings.setResourceStreamLocator(new PathStripperLocator());
}


サンプルで最初に作ったクラスの中ではソースパスからファイル名だけを取り出してHTMLの名前候補を作っていた。
(*hogehoge.javaから hogehoge.htmlだけじゃなくてhogehoge_ja.html等も作ってた。propertiesファイルだけじゃなくてHTMLも言語ごとに作れるってこと(?) 相変わらずWicket抜かりが無くてステキ)
通常動作時はファイル名だけを取り出す動作がなくて、直接パスから候補を作っているみたい。
そして、サンプルではアプリケーションのイニシャライズ内で検索するディレクトリを追加。
自分としては二箇所でファイルの場所を設定しているのがちょっと気に食わなかった。




自分がやりたかったイメージ↓。

Class
--Model
----BlogTable.java
--View
----TestBlog.html
--Controller
----TestBlog.java

これだったらパスのセグメント"controller"を"view"に書き換えるだけだから簡単だし、init()でファイルを検索する場所を定義しなくていい。
こんな感じになった(StringUtils使用)

public class PathStripperLocator extends ResourceStreamLocator
{
  public PathStripperLocator()
  {
  }

  @Override
  public IResourceStream locate(final Class< ? > clazz, final String path)
  {
    IResourceStream located = super.locate(clazz, viewDirPath(path));
    if (located != null)
    {
      return located;
    }
    return super.locate(clazz, path);
  }

  private String viewDirPath(String path) {
    String[] segmentArray = path.split("/");
    segmentArray[ segmentArray.length - 2 ] = "view";
    return StringUtils.join(segmentArray, "/");
  }
}

これならinit()に追加する行が二行ですむ

IResourceSettings resourceSettings = getResourceSettings();
resourceSettings.setResourceStreamLocator(new PathStripperLocator());

Mr.PersisterでAUTO_INCREMENTさせるメモ

1.マッピングからAUTO_INCREMENTのカラムを消して返すクラス

public class EmployeeCustomMapper
  extends CustomObjectMapperBase
{
  @Override
  public void modify(Object objectMappingKey, IObjectMapping mapping)
  throws PersistenceException
  {
    /*
     * AUTO_INCREMENTのカラム"ID"のセッターを削除
     */
    mapping.removeSetterMapping("ID");
  }
}


2. 1で作ったクラス(EmployeeCustomMapper.class)とテーブルマッピング用のクラス(Employee.class)でマッピングキーを作る

IObjectMappingKey mappingKey =
  ObjectMappingKey.createInstance(
    Employee.class, new EmployeeCustomMapper()
  );


3. インサート時には2で作ったマッピングキーを使う

employee.setName("Steve");
dao.insert(mappingKey, employee);