Hatena::Grouparaistudy

czk-htnの日記

2009-12-30

[] wicket-auth-roles-1.3.7 と JDK-1.4 06:45

もしかして wicket-auth-roles-1.3.7 って JDK-1.4 で使えない?Java5必須ですか。

トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20091230

2009-06-03

[] IConverterを実装して独自の文字変換を行う(ResourceModel版) 06:45

教えていただいた方法で実装してみた。

wicket
item.add(new Label("bloodType") {
    private static final long serialVersionUID = 1L;
    @Override
    public IConverter getConverter(Class<?> type) {
        return new EnumerationConverter(BloodType.class);
    }
});
EnumerationConverter
package buzool.wicket;

import java.util.Locale;

import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.util.convert.converters.AbstractConverter;

public class EnumerationConverter extends AbstractConverter implements IConverter {
	private static final long serialVersionUID = 1L;
	
	private Class<? extends Enum<?>> clazz;

	public EnumerationConverter(Class<? extends Enum<?>> clazz) {
		this.clazz = clazz;
	}
	
	@Override
	public Object convertToObject(String value, Locale locale) {
		return null;
	}

	/**
	 * 
	 * Enumを文字列表現に変換する
	 * 
	 * clazz.getName() でFQCNをキーとし、アプリケーションプロパティファイルから引っ張る
	 * value.getClass.getName() だと $ が含まれてプロパティキーとしては扱いづらい
	 */
	@Override
	public String convertToString(Object value, Locale locale) {
		return new ResourceModel(clazz.getName() + "." + value).getObject();
	}

	@Override
	protected Class<?> getTargetType() {
		return clazz;
	}
}
BloodType.java

データクラスのフィールドとして定義するよりも、ファイルを切り出した方がFQCNに$が含まれなくてきれい。

public enum BloodType {
	A { public String toString() { return "A"; }},
	B { public String toString() { return "B"; }},
	O { public String toString() { return "O"; }},
	AB { public String toString() { return "AB"; }},
	Unknown { public String toString() { return "Unknown"; }};
};
Application.properties

最初 "表示するページ名.properties" というファイルに書いてあげても、キーがみつからないというエラーがでてしまい、なんでだろう??と小一時間悩んだ。アプリケーション(WebApplicationを継承したクラス)のプロパティファイルに書きましょう。

buzool.list.data.BloodType.A=A型
buzool.list.data.BloodType.B=B型
buzool.list.data.BloodType.O=O型
buzool.list.data.BloodType.AB=AB型
buzool.list.data.BloodType.Unkown=不明
トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20090603

2009-05-04

[] IConverterを実装して独自の文字変換を行う 06:45

先日の続き。Date, Integer, Booleanでアプリケーション固有の文字列表現に変換するやり方をまとめてみる。

java.util.Dateを文字列に変換
item.add(new Label("birthDay") {
    private static final long serialVersionUID = 1L;
    final DateFormat df = new SimpleDateFormat("yyyy/MM/dd");

    @Override
    public IConverter getConverter(Class<?> type) {
        IConverter converter = new DateConverter() {
            private static final long serialVersionUID = 1L;
            @Override
            public DateFormat getDateFormat(Locale locale) {
                return df;
            }
        };
        return converter;
    }
});
enumを血液型の文字列に変換
public enum BloodType { A, B, O, AB, Unknown };

item.add(new Label("bloodType") {
    private static final long serialVersionUID = 1L;
    @Override
    public IConverter getConverter(Class<?> type) {
        IConverter converter = new IntegerConverter() {
            private static final long serialVersionUID = 1L;
            @Override
            public String convertToString(Object value, Locale locale) {
                BloodType type = (BloodType) value;
                switch (type) {
                case A:
                    return "A型";
                case B:
                    return "B型";
                case O:
                    return "O型";
                case AB:
                    return "AB型";
                default:
                    return "不明";
                }
            }
        };
        return converter;
    }
});
booleanを既婚・未婚の文字列に変換
item.add(new Label("married") {
    private static final long serialVersionUID = 1L;
    @Override
    public IConverter getConverter(Class<?> type) {
        IConverter converter = new BooleanConverter() {
            private static final long serialVersionUID = 1L;

            @Override
            public String convertToString(Object value,
                    Locale locale) {
                if (value != null && ((Boolean) value) == true) {
                    return "既婚";
                }
                return "未婚";
            }
        };
        return converter;
    }
});

追記(2009-05-04

そもそもenumはIntegerで変換していいものか?と考え調べたところ、toStringをオーバーライドしてやればいいんじゃないかと思いついた。enumについてはこれが正当なやり方、たぶん。

"wicket IConverter"でググってみても件数が少ない上「文字列オブジェクト」のためにやっていることが多数。文字列変換について、なんか根本的なところで勘違いしているような気がしてきた・・・

wicket
/*
 * ふつうにLabelをaddすればよろし
 */
item.add(new Label("bloodType"));
enum定義
public enum BloodType {
    A, B, O, AB, Unknown;
    @Override
    public String toString() {
        switch (this) {
        case A:
            return "A型";
        case B:
            return "B型";
        case O:
            return "O型";
        case AB:
            return "AB型";
        default:
            return "不明";
        }
    }
};

nagaseyasuhitonagaseyasuhito2009/06/02 12:42自分はenumのFQCNをキーにしてプロパティファイルから引っ張ってくるConverterを書いて使ってますー。

public class EnumerationConverter extends AbstractConverter {
private static final long serialVersionUID = 1L;

private Class<? extends Enum<?>> clazz;

public EnumerationConverter(Class<? extends Enum<?>> clazz) {
this.clazz = clazz;
}

@Override
public Object convertToObject(String value, Locale locale) {
return null;
}

@Override
public String convertToString(Object value, Locale locale) {
return new ResourceModel(this.clazz.getName() + "." + value).getObject();
}

@Override
protected Class<? extends Enum<?>> getTargetType() {
return this.clazz;
}
}
こんな感じで、プロパティファイルには
net.nagaseyasuhito.sandbox.enumeration.Role.USER = ユーザー
net.nagaseyasuhito.sandbox.enumeration.Role.GUEST = ゲスト
こういう記述。
参考までにー。

czkczk2009/06/03 06:58なるほど、それならコードに日本語埋め込まなくていいですね。
試してみます。ありがとうございますー。

トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20090504

2009-04-26

[][] Dateを自分好みの書式でラベルにする 06:45

掲示板を作りながらWicketコンポーネントの使い方を学んでいる。

掲示板の書き込み日付(java.util.Date)を任意の書式で表示したい時にどうしたらいいのか?Wicketソースコードを追ってIConverterを実装してあげるのが良さそうだ。

package buzool.bbs;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.util.convert.converters.DateConverter;

import buzool.bbs.data.BBSData;
import buzool.bbs.data.DummyBBSDataService;
import buzool.bbs.data.IBBSDataService;

public class Home extends WebPage {
    public Home() {
        add(homePageLink("goTop"));
        IBBSDataService service = new DummyBBSDataService();
        add(new ListView<BBSData>("bbsListView", service.findAll()) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(ListItem<BBSData> item) {
                BBSData data = item.getModelObject();
                item.add(new Label("bbsSeq", new PropertyModel<String>(data, "seq")));
                item.add(new Label("bbsTitle", new PropertyModel<String>(data, "title")));
                //
                //ロケールを基に日付を文字列にフォーマットする
                //自分好みの書式にするにはどうしたらいいんだろう・・・
                //
                //item.add(new Label("bbsModifiedAt", new PropertyModel<Date>(data, "modifiedAt")));
                
                //
                //あらかじめ日付を文字列にフォーマットしてからLabelに設定する
                //コンポーネントがLabelならこれでもいいんだろうけど・・・
                //
                //DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                //Date modifiedAt = data.getModifiedAt();
                //item.add(new Label("bbsModifiedAt", df.format(modifiedAt)));
                
                //Labelを継承してgetConverterをオーバーライド
                //これが正しい作法?
                //毎回インスタンスを作るのは無駄なのでアプリケーションで使いまわすべきか
                item.add(new Label("bbsModifiedAt", new PropertyModel<Date>(data, "modifiedAt")) {
                    @Override
                    public IConverter getConverter(Class<?> type) {
                        final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                        IConverter converter = new DateConverter() {
                            @Override
                            public DateFormat getDateFormat(Locale locale) {
                                return df;
                            }
                        };
                        return converter;
                    }
                });
            }
        });
    }
}
トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20090426

2009-04-11

[][] オープンソース徹底活用WicketによるWebアプリケーション開発 - 14日目(第9章 DIコンテナ06:45

IoCコンテナ/DIコンテナ

これが最終章。ちょうど2週間かかったわけだ。本の題名を「2週間で覚えるApache Wicket」に変えてもいいかもしれない。余計なお世話ですね。

日本ではDIコンテナDependency Injection:依存性注入)と呼ぶ機会が多いけど、海外ではIoCコンテナと呼ぶらしい。IoCはInversion of Contorol(制御の反転)という意味。

一般的にはオブジェクトを使う側(アプリケーション)がオブジェクトを管理する側(コンテナ)からオブジェクトを取得する(プル方式)わけだけど、IoC「制御を反転」することでコンテナからアプリケーションオブジェクトを注入する(プッシュ方式)ことになる。

これによりアプリケーションJavaインターフェース中心のプログラムを行い、インターフェースを実装している具体的なクラスおよび実体の管理はコンテナに任せる(疎結合)ことができる。

代表的なDIコンテナ

こう見るとWicket哲学にあっているのはGuiceみたい。今後Webアプリケーション開発する際に基本Javaのみでシステムを制御したい時の選択肢は「Wicket + Guice + S2JDBC?」S2JDBCってSeasarなしで単体で使える?ORマッパーでXMLレスを謳っているのは他にあったっけ?

参考URL

トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20090411