Seamで別windowを開きたい

親画面にリストがあって、その中から1つを選択すると詳細画面に遷移する。
この時、子画面を別windowにしたい場合にどうすれば良いでしょうか。

のtarget属性を_blankにする、というのが一般的でしょうか。
しかし、この方法だと「aタグのonclickイベントでアクション(或いは目的のページ)を呼び出し、レスポンスをtargetで指定したブラウザで受ける」事になります。
つまり、

  • 子画面のサイズや表示位置を指定できない
  • IEの場合、子画面に配置した[閉じる]ボタンでwindow.closeのスクリプトを動作させると確認メッセージが表示される

という事になります。これはおもしろくないです。
を使う限りはこの制約から逃れられないので、Seamのタグに変えてみるとナイスな方向に進みます。但し、注意点が1つあり、「はGETメソッド」なのでリクエストパラメータで値を渡すという事です。
普通にこれを意識して実装してみて、「ありゃ?リクエストパラメータが渡ってない??」という事態になった方もおられるのではないでしょうか。

親画面のリンク押下 -- GET --> サーバ処理受付
                                     |
        +------- redirect指示 -------+
        |
        +------- 子画面GET -> サーバ処理受付
                                     |
 子画面表示 <------ レスポンス -------+

上記のような動作になる為、2回目のGET要求でリクエストパラメータを判定する処理を組み込んだ場合に「リクエストパラメータが渡ってない」ように見えてしまうのです。
Filterを自作してPOST要求が来るまでGETパラメータをひきまわす事でも解決できますが、考慮すべき問題が増えるので控えた方がよいでしょう。

では、本題の対処方法について。

親画面のXHTML

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:s="http://jboss.com/products/seam/taglib"
      xmlns:rich="http://richfaces.org/rich">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>home</title>
  <link href="stylesheet/theme.css" rel="stylesheet" type="text/css" />
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" />
  <script type="text/javascript">
    $(document).ready( function () {
      $('.popup').click(function(){
        window.open(this.href, '');
        return false;
      });
    });
  </script>
</head>
<body>
  <f:view>
    <h:form>
      <rich:dataList var="u" value="#{users}">
        <s:link styleClass="popup" action="#{register.disp}" value="#{u.name}" />
      </rich:dataList>
    </h:form>
  </f:view>
</body>
</html>

子画面のXHTML

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:s="http://jboss.com/products/seam/taglib"
      xmlns:rich="http://richfaces.org/rich">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>registForm</title>
  <link href="stylesheet/theme.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <f:view>
    <h:form>
      <h:panelGrid columns="2">
        <h:outputLabel value="name" />
        <h:inputText value="#{user.name}" />
        <h:outputLabel value="sex" />
        <h:inputText value="#{user.sex}" />
        <h:outputLabel value="age" />
        <h:inputText value="#{user.age}" />
      </h:panelGrid>
      <s:button value="close" onclick="window.close();" />
    </h:form>
  </f:view>
</body>
</html>

pages.xml(抜粋)

<page view-id="*">
  <navigation>
    <rule if-outcome="disp">
      <redirect view-id="/registForm.xhtml"/>
    </rule>
  </navigation>
</page>

action

package test.action;

import static test.bean.Sex.MAN;
import static test.bean.Sex.WOMAN;
import java.util.ArrayList;
import java.util.List;
import static org.jboss.seam.ScopeType.SESSION;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import test.bean.User;

@Scope(SESSION)
@Name("register")
public class RegisterAction {
  @DataModel
  private List<User> users;
  @DataModelSelection
  private User selectedUser;
  @In(create=true)@Out
  private User user;

  @Factory("users")
  public void getUsers() {
    users = new ArrayList<User>();
    {
      for (User user : new User[]{
            new User("taro", MAN, 40),
            new User("hana", WOMAN, 20)
      }) users.add(user);
    }
  }
  public String disp(){
    user = selectedUser;
    return "disp";
  }
}

bean

package test.bean;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import static org.jboss.seam.ScopeType.SESSION;

@Scope(SESSION)
@Name("user")
public class User {
  private String name;
  private Sex sex;
  private int age;

  public User(){}
  public User(String name, Sex sex, int age){
    this.name = name;
    this.sex = sex;
    this.age = age;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  public Sex getSex() {
      return sex;
  }
  public void setSex(Sex sex) {
      this.sex = sex;
  }
  public int getAge() {
      return age;
  }
  public void setAge(int age) {
      this.age = age;
  }
}

package test.bean;

public enum Sex {
  MAN,
  WOMAN
}

これで前述の問題は全て解決されました。
JQUERYとの親和性にも問題ないところがご覧いただけたと思います。別windowのサイズ指定は親画面XHTMLの「window.open(this.href, '');」を書き換えてもらえば良いです。
親画面でなぜを使っているかという点については、また後日の日記にて。