SAStrutsのチュートリアルが1.0.3から結構変わっている

出羽ブログで話題になっていたことが、SAStrutsチュートリアルに反映されています。

例えば、EmployeeActionが

	@Execute(validator = false)
	public String index() {
		empItems = jdbcManager
			.from(Employee.class)
			.orderBy("id")
			.getResultList();
		return "index.jsp";
	}

だったのが、

	@Execute(validator = false)
	public String index() {
		empItems = employeeService.findAll();
		return "index.jsp";
	}

となっています。jdbcManagerがなくなって、employeeServiceが処理をしています。
で、employeeService(EmployeeService)は以下のようになっています。

package tutorial.service;

import org.seasar.extension.jdbc.service.S2AbstractService;

import tutorial.entity.Employee;

public class EmployeeService extends S2AbstractService<Employee> {

}

S2AbstractServiceの型引数にEmployee(エンティティ)を渡して処理を委譲しています。
で、S2AbstractServiceは以下のとおり。

public abstract class S2AbstractService<T> {

    /**
     * JDBCマネージャです。
     */
    @Resource
    protected JdbcManager jdbcManager;

    /**
     * エンティティのクラスです。
     */
    protected Class<T> entityClass;

    /**
     * SQLファイルのパスのプレフィックスです。
     */
    protected String sqlFilePathPrefix;

    /**
     * コンストラクタです。
     * 
     */
    @SuppressWarnings("unchecked")
    public S2AbstractService() {
        Map<TypeVariable<?>, Type> map = GenericUtil
                .getTypeVariableMap(getClass());
        for (Class<?> c = getClass(); c != Object.class; c = c.getSuperclass()) {
            if (c.getSuperclass() == S2AbstractService.class) {
                Type type = c.getGenericSuperclass();
                Type[] arrays = GenericUtil.getGenericParameter(type);
                setEntityClass((Class<T>) GenericUtil.getActualClass(arrays[0],
                        map));
                break;
            }
        }
    }

コンストラクタ内でgetClass()で取得した情報をもとにS2AbstractService における T のクラス型を取得して entityClassへセットしています。
マ、マジカルだ。。。

employeeService.findAll(Employee.class);

のように引数にエンティティのクラスオブジェクトを渡すのではなく、エンティティの情報を型引数としてフレームワークのクラスに渡してやることにより、

employeeService.findAll();

を実現しているわけですね。勉強になります。ハイ。