Main Contents
2008年4月21日
BeanUtils の使い方
かなり前に書いた記事を, ちゃんとまとめてみました.
BeanUtils の使い方サンプルです.
JUnit4 のテストケースとして書いてみました.
/*
* $Id$
*/
package net.nanasess.examples;
import static org.junit.Assert.*;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.junit.Before;
import org.junit.Test;
/**
* BeanUtils の使い方.
*
* 基本的に, データ型を String に変換して返します.
* 変換したくない場合は, {@link PropertyUtils} を使います.
*
* @author Kentaro Ohkouchi
* @version $Revision$ $Date$
*/
public class BeanUtilsTest {
private FooBar fooBar;
@Before
public void before() {
fooBar = new FooBar();
}
/**
* {@link BeanUtils#cloneBean(java.lang.Object)} の使い方.
*
* Cloneable を implements してなくても Bean の複製ができます.
*/
@Test
public final void testCloneBean() throws Exception {
Bar bar = new Bar("bar");
String excepted = "bar";
// bar を複製する
Bar actual = (Bar) BeanUtils.cloneBean(bar);
assertEquals(excepted, actual.getExample());
}
/**
* {@link BeanUtils#copyProperties(java.lang.Object, java.lang.Object)} の使い方
*
* 同じプロパティ名のデータを orig から dest へコピーします.
* この場合, example というプロパティが双方に存在するので, example のデータがコピーされます.
*/
@Test
public final void testCopyProperties() throws Exception {
Bar orig = new Bar();
ExampleClass dest = new ExampleClass();
// 同じプロパティ名のデータを orig から dest へコピーする.
BeanUtils.copyProperties(dest, orig);
// orig が Map の場合は, プロパティ名と Map の key が一致した場合コピーされる.
Map map = new HashMap();
map.put("foo", "foo");
BeanUtils.copyProperties(dest, map);
// example の内容がコピーされる
assertEquals(orig.getExample(), dest.getExample());
// Map の内容もコピーされる
assertEquals(map.get("foo"), dest.getFoo());
// baz は null のまま
assertNull(dest.getBaz());
}
/**
* {@link BeanUtils#copyProperty(java.lang.Object, java.lang.String, java.lang.Object)} の使い方.
*
* 指定したプロパティのデータをコピーします.
* ネストしたプロパティもコピーできます.
*/
@Test
public final void testCopyProperty() throws Exception {
Bar bar = new Bar();
ExampleClass bean = new ExampleClass();
// 指定したプロパティのデータを bean にコピーします.
BeanUtils.copyProperty(bean, "foo", "foo");
// ネストした Bean もコピーできます.
BeanUtils.copyProperty(bean, "bar", bar);
assertEquals("foo", bean.getFoo());
assertEquals("example", bean.getBar().getExample());
}
/**
* {@link BeanUtils#describe(java.lang.Object)} の使い方.
*
* bean のプロパティ名を key, プロパティのデータを value とした Map を返します.
* プロパティのデータ型に関わらず, value は String になります...
*/
@Test
public final void testDescribe() throws Exception {
// value に格納されるデータを String にキャストして Map で返します.
Map map = BeanUtils.describe(fooBar);
assertEquals("foo", map.get("foo"));
}
/**
* {@link BeanUtils#getArrayProperty(java.lang.Object, java.lang.String)} の使い方.
*
* プロパティ名を指定して, プロパティの値を String の配列で返します.
* プロパティのデータ型が配列の場合は, String の配列に変換して返します.
* コレクションの場合も, String の配列に変換して返します.
* それ以外のデータ型の場合は, {@link Object#toString()} の値を String の配列に格納して返します.
*/
@Test
public final void testGetArrayProperty() throws Exception {
// プロパティ名を指定して, String の配列を返します.
String[] strings = BeanUtils.getArrayProperty(fooBar, "strings");
assertArrayEquals(fooBar.getStrings(), strings);
// プロパティが配列では無い場合も String の配列が返ってきます.
String[] foo = BeanUtils.getArrayProperty(fooBar, "foo");
assertArrayEquals(new String[]{"foo"}, foo);
}
/**
* {@link BeanUtils#getIndexedProperty(java.lang.Object, java.lang.String)} の使い方.
*
* プロパティ名[インデックス番号] のように, インデックスを保持するプロパティから, インデックス番号を指定して
* 値を String で返します.
* インデックスを保持しないプロパティは, {@link IllegalArgumentException} になります.
*/
@Test(expected=IllegalArgumentException.class)
public final void testGetIndexedPropertyObjectString() throws Exception {
// プロパティ名とインデックス番号を指定して String の値を返します.
String actual = BeanUtils.getIndexedProperty(fooBar, "strings[2]");
assertEquals("ghi", actual);
// インデックスを保持しないプロパティは IllegalArgumentException になります.
String foo = BeanUtils.getIndexedProperty(fooBar, "foo[0]");
}
/**
* {@link BeanUtils#getIndexedProperty(java.lang.Object, java.lang.String, int)} の使い方.
*
* {@link BeanUtils#getIndexedProperty(java.lang.Object, java.lang.String)} に
* 似ていますが, インデックス番号を int で指定するところが異なります.
*/
@Test
public final void testGetIndexedPropertyObjectStringInt() throws Exception {
// プロパティ名とインデックス番号を指定して, String の値を取得します.
String actual = BeanUtils.getIndexedProperty(fooBar, "strings", 2);
assertEquals("ghi", actual);
}
/**
* {@link BeanUtils#getMappedProperty(java.lang.Object, java.lang.String)} の使い方.
*
* プロパティが Map の場合, プロパティ名(key) のように指定して, 値を String で返します.
* プロパティが Map 以外の場合は, null を返します.
*/
@Test
public final void testGetMappedPropertyObjectString() throws Exception {
// プロパティ名と key を指定して, String の値を返します.
String actual = BeanUtils.getMappedProperty(fooBar, "map(abc)");
assertEquals("abc of value", actual);
// プロパティが Map 以外の場合は, null を返します.
assertNull(BeanUtils.getMappedProperty(fooBar, "foo(key)"));
}
/**
* {@link BeanUtils#getMappedProperty(java.lang.Object, java.lang.String, java.lang.String)} の使い方.
*
* {@link BeanUtils#getMappedProperty(java.lang.Object, java.lang.String)} に
* 似ていますが, key を第3引数で指定するところが異なります.
*/
@Test
public final void testGetMappedPropertyObjectStringString() throws Exception {
// プロパティ名と key を指定して, String の値を返します.
String actual = BeanUtils.getMappedProperty(fooBar, "map", "abc");
assertEquals("abc of value", actual);
}
/**
* {@link BeanUtils#getNestedProperty(java.lang.Object, java.lang.String)} の使い方.
*
* ネストした Bean のプロパティをドットシンタックスで取得できます.
* 値は String で返します.
*/
@Test
public final void testGetNestedProperty() throws Exception {
// ネストしたプロパティを取得します.
String actual = BeanUtils.getNestedProperty(fooBar, "bar.example");
assertEquals("example", actual);
}
/**
* {@link BeanUtils#getProperty(java.lang.Object, java.lang.String)} の使い方.
*
* 便利屋さんです.
* プロパティのデータ型に合わせた方法で, プロパティ名やインデックスを指定することで, プロパティの値を
* String で取得できます.
*/
@Test
public final void testGetProperty() throws Exception {
// プロパティ名を指定して String の値を返します.
String foo = BeanUtils.getProperty(fooBar, "foo");
assertEquals("foo", foo);
// プロパティ名とインデックス番号を指定して String の値を返します.
String strings = BeanUtils.getProperty(fooBar, "strings[2]");
assertEquals("ghi", strings);
// プロパティ名と key を指定して, String の値を返します.
String map = BeanUtils.getProperty(fooBar, "map(abc)");
assertEquals("abc of value", map);
// ネストしたプロパティを取得します.
String actual = BeanUtils.getProperty(fooBar, "bar.example");
assertEquals("example", actual);
}
/**
* {@link BeanUtils#getSimpleProperty(java.lang.Object, java.lang.String)} の使い方.
*
* プロパティ名を指定して, String の値を返します.
* {@link BeanUtils#getProperty(java.lang.Object, java.lang.String)} とは挙動が
* 異なるため, 単純な Bean の値を取得するのに適しています.
*/
@Test(expected=IllegalArgumentException.class)
public final void testGetSimpleProperty() throws Exception {
// プロパティ名を指定して String の値を返します.
String foo = BeanUtils.getSimpleProperty(fooBar, "foo");
assertEquals("foo", foo);
// プロパティが配列の場合は先頭の値を返します.
String strings = BeanUtils.getSimpleProperty(fooBar, "strings");
assertEquals("abc", strings);
// プロパティが Map の場合はMap#toString() の値を返します.
String map = BeanUtils.getSimpleProperty(fooBar, "map");
assertEquals("{abc=abc of value, ghi=ghi of value, def=def of value}", map);
// ネストしたプロパティは取得できません...
try {
BeanUtils.getSimpleProperty(fooBar, "bar.example");
} catch (IllegalArgumentException e) {
throw e;
}
}
/**
* {@link BeanUtils#populate(java.lang.Object, java.util.Map)} の使い方.
*
* Map に格納した値を key に対応する Bean のプロパティに設定します.
* 値は, String にキャストして設定します.
*/
@Test
public final void testPopulate() throws Exception {
Map map = new HashMap();
map.put("foo", "foo of value");
map.put("bar.example", new Integer(1000));
// Map の key に対応するプロパティに値を設定します.
BeanUtils.populate(fooBar, map);
assertEquals("foo of value", fooBar.getFoo());
// Integer などの値も String にキャストされます.
assertEquals("1000", fooBar.getBar().getExample());
}
/**
* {@link BeanUtils#setProperty(java.lang.Object, java.lang.String, java.lang.Object)} の使い方.
*
* {@link BeanUtils#getProperty(java.lang.Object, java.lang.String)} と同様の方法で,
* プロパティ名を指定することで, 任意のオブジェクトを String にキャストして Bean に設定します.
*/
@Test
public final void testSetProperty() throws Exception {
// プロパティ名を指定して String の値を設定します.
BeanUtils.setProperty(fooBar, "foo", "foo of value");
assertEquals("foo of value", fooBar.getFoo());
// プロパティ名とインデックス番号を指定して String の値を設定します.
BeanUtils.setProperty(fooBar, "strings[2]", "strings of two");
String[] strings = fooBar.getStrings();
assertEquals("strings of two", strings[2]);
// プロパティ名と key を指定して, String の値を設定します.
BeanUtils.setProperty(fooBar, "map(abc)", new Integer(1000));
assertEquals("1000", fooBar.getMap().get("abc"));
// ネストしたプロパティを設定します.
BeanUtils.setProperty(fooBar, "bar.example", "bar of example");
assertEquals("bar of example", fooBar.getBar().getExample());
}
}
Bean は下記のものを使っています.
/*
* $Id$
*/
package net.nanasess.examples;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* FooBar クラス.
*
* 内部で Bar クラスをネストしている.
*
* @author Kentaro Ohkouchi
* @version $Revision$ $Date$
*/
public class FooBar {
private String foo;
private Bar bar;
private String[] strings;
private List bars;
private Map map;
public FooBar() {
this.foo = "foo";
bar = new Bar();
strings = new String[]{"abc", "def", "ghi"};
bars = new ArrayList();
map = new HashMap();
for (String string : strings) {
bars.add(new Bar(string));
map.put(string, string + " of value");
}
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public Bar getBar() {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
public String[] getStrings() {
return strings;
}
public void setStrings(String[] strings) {
this.strings = strings;
}
public List getBars() {
return bars;
}
public void setBars(List bars) {
this.bars = bars;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
}
/*
* $Id$
*/
package net.nanasess.examples;
import java.sql.Timestamp;
/**
* Bar クラス.
*
* @author Kentaro Ohkouchi
* @version $Revision$ $Date$
*/
public class Bar {
private String example;
private Timestamp created;
public Bar() {
this.example = "example";
this.created = new Timestamp(System.currentTimeMillis());
}
public Bar(String example) {
this.example = example;
this.created = new Timestamp(System.currentTimeMillis());
}
public String getExample() {
return example;
}
public void setExample(String example) {
this.example = example;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
}
/*
* $Id$
*/
package net.nanasess.examples;
import java.sql.Timestamp;
/**
* ExampleClass クラス.
*
* @author Kentaro Ohkouchi
* @version $Revision$ $Date$
*/
public class ExampleClass {
private String foo;
private String baz;
private String example;
private Bar bar;
private Timestamp created;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
public String getBaz() {
return baz;
}
public void setBaz(String baz) {
this.baz = baz;
}
public String getExample() {
return example;
}
public void setExample(String example) {
this.example = example;
}
public Bar getBar() {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
public Timestamp getCreated() {
return created;
}
public void setCreated(Timestamp created) {
this.created = created;
}
}
以前の記事にも書いたのですが, BeanUtils は, 基本的に値を String にキャストします.
PropertyUtils は, 型変換せずに扱います.
それ以外の振舞いは, 基本的に同じです.
これらの API を使いこなすと非常に強力ですが, 最近はフレームワークがサポートしている場合が多いようです.
(Seasar の S2BeanUtils など)
今回ひさびさに,
- Permalink
- Comments (0)
- Trackbacks (2)
- by みそ
- at 01:47
- in Java
2008年4月20日
JUnit4 ことはじめ
ずっと食わず嫌いだった JUnit4 を使ってみたので, コードを晒しておきます...
/*
* $Id$
*/
package net.nanasess.examples;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* HelloWorld のテスト.
*
* @author Kentaro Ohkouchi
* @version $Revision$ $Date$
*/
public class HelloWorldTest {
private static String expected;
private String actual;
private static int counter;
/**
* すべてのテスト前に実行するメソッド.
*
* static にして {@link @beforeClass} アノテーションをつける.
*/
@BeforeClass
public static void beforeClass() {
System.out.println("HelloWorld テストを始めます.");
counter = 0;
System.out.println("カウンターを初期化しました.");
}
/**
* すべてのテストを終了した後に実行するメソッド.
*
* static にして {@link @AfterClass} アノテーションをつける.
*/
@AfterClass
public static void afterClass() {
System.out.println(counter + " 個のテストを実行しました.");
System.out.println("HelloWorld テストを終了します.");
}
/**
* 各テストをする前に実行するメソッド.
*
* {@link @Before} アノテーションをつける.
*/
@Before
public void before(){
expected = "HelloWorld";
System.out.println("expected を初期化しました.");
}
/**
* 各テストの後に実行するメソッド.
*
* {@link @After} アノテーションをつける.
*/
@After
public void after() {
counter++;
System.out.println(String.valueOf(counter) + " 番目のテストを実行しました.");
}
/**
* HelloWorld のテスト.
*/
@Test
public void helloWorld() {
actual = "HelloWorld";
assertEquals(expected, actual);
}
/**
* ちゃんと ClassNotFoundException になるかどうかのテスト.
*
* @throws Exception エラーが発生した場合.
*/
@Test(expected = ClassNotFoundException.class)
public void classForNameFailure() throws Exception {
Class.forName("org.postgresql.Driver");
}
/**
* スタブなので, スキップするテスト.
*
* {@link @Ignore} アノテーションをつけると, そのメソッドはテストしない.
*/
@Ignore("スタブなのでテストしません...")
@Test
public void testStub() {
assertEquals("test", "stub");
}
/**
* 配列を比較するテスト.
*
* {@link org.junit.Assert#assertArrayEquals(String[], String[])} を使ってます.
* 配列や, List のテストも楽になったものです(しみじみ)
*/
@Test
public void arrays() {
String[] expecteds = { "1", "2", "3" };
List actuals = new ArrayList();
actuals.add("1");
actuals.add("2");
actuals.add("3");
assertArrayEquals(expecteds, actuals.toArray(new String[actuals.size()]));
}
}
個人的には, 配列や例外のテストが解りやすく楽になったのが良い感じ.
JUnit4 の関連ライブラリも充実してきたので, そろそろ乗り替え時かな...
ついでに, Eclipse 3.4M6a を Celeron 600MHz, メモリ 384MB という非力なノートPCで使ってみましたが, 思ったよりサクサクで良い感じでした☆
- Permalink
- Comments (0)
- Trackbacks (1)
- by みそ
- at 16:05
- in Java
2008年4月11日
JIS X 0213:2004(JIS2004) と Java と PHP と RDBMS
ずいぶん前に, EC-CUBE の ML へ投稿した話題ですが, どうも過去ログに埋もれているので, 再度まとめてみます...
Windows Vista で, 日本語の文字集合に, JIS X 0213:2004(JIS2004) が採用されました.
このため, 扱える漢字が増えたり, 字体が変化したりして, さまざまな影響があります.
EC-CUBE を代表する PHP のアプリケーションや, Java の場合, どのような影響が考えられるでしょうか.
以前, Windows Vista での影響調査をする機会があり, いろいろ調べましたので, ちょっとまとめてみます.
文字集合と文字エンコーディングについて
文字のまとまりを規格化できるよう, 各文字に対して一連のコード(文字コード)を割り当てたものを「文字集合(文字セット)」と言います.
これには, Unicode や, JISX 0213:2004 などがあたります.
この文字集合をコンピュータで扱えるよう, 文字コードをバイトコードへ変換する仕組み(文字符号化方式)を文字エンコーディングと言います.
これには, Shift_JIS や, EUC-JP, UTF-8, UTF-16 などがあります.
文字コードと文字エンコーディングと文字セットを混同してしまいがちですが, それぞれの意味は別物です.
UTF-8 というのは, 正確に言うと Unicode という文字セットで規定されている文字エンコーディングの一つです.
Unicode で規定されている文字エンコーディングの抜粋
- UTF-1 - 8bit
- UTF-5 - 利用されていない
- UTF-7 - UTF-16 で表した Unicode を Base64 で変換して表す方式. 非推奨
- UTF-8 - 8bit 単位の可変長コードにエンコードする方式
- 1バイト - すべての ASCII
- 2バイト - JIS X 0208の非漢字の一部
- 3バイト - Windows-31J の拡張文字エリア全て, 第3・4水準漢字の一部
- 4バイト - JIS X 0213:2004 の第3・4水準漢字の一部, UnicodeのBMP 面以外すべて
- UTF-16 - Windows XP, Vista の内部エンコーディング. Vista では, JIS X 0213:2004 の文字集合が採用された. 16bit 単位の可変長. 16bit のみで表現される BMP面と, 16bit + 16bit で表現される「サロゲート・ペア」から構成される.
- UTF-32 - Unicode の全コードを単一長のコードとして 32bit で指定するコード. 実際に使用されるのは 21bit までの範囲.
Unicode における BMP(Basic Multilingual Plane)面とは, UTF-16 にて, 16bit のみで表現できる領域の文字のことを言い, 16bit + 16bit で表現する文字の範囲を 「サロゲート・ペア」と言います.
Unicode 以外の文字集合としては, UCS-4 (ISO/IEC 1064)という良く似た別物があり, UCS-4 で規定されている文字エンコーディングにも UTF-8 があったりします.
UCS-4 と Unicode は 21bit までの範囲で互換性があります. UCS-4 は4バイトを基本とし, 31bit までの領域を使用します. ややこしい...
一方, JIS X 0213:2004 では, 文字エンコーディングとして, ISO-2202-JP-2004, EUC-JP-2004, Shift_JIS-2004 などがありますが, IANA に登録されていないため, あくまでも参考となっています.
Windows Vista での問題
Windows Vista では, 使用する文字セットに, JIS X 0213:2004 を採用したため, UTF-16 でエンコーディングされる場合, BMP面以外の文字(16bit + 16bit で表現される文字)までサポートされることとなりました.
このため, UTF-8 でエンコーディングされる場合は, 1文字が4バイトで表現される文字も含まれます.
PHPでの扱い
http://jp.php.net/mbstring を見るかぎりは, mbstring 関数を使用することで, サロゲート・ペアの文字が入力されても, うまく対応できそうです.
文字エンコーディングは, UTF-8 が無難でしょう.
MySQL での問題
http://www.mysql.gr.jp/mysqlml/mysql/msg/13823
これを見ると, DBエンコーディングに UTF-8 を使用した場合でも, 扱えるのは, 1文字3バイトまでの範囲に限られるようです...
つまり, Windows Vista で採用されたサロゲート・ペアの文字が入力された場合は, 確実に文字化けします(苦笑)
PostgreSQL での扱い
8.1.7以降、8.2.2以降であれば, UTF-8 で問題なく扱えるようです.
それ以前のバージョンは, 1文字4バイトで表現される文字を使用した場合に問題がでる可能性あります.
http://mlog.euqset.org/archives/pgsql-jp.ml.postgresql.jp/38404.html
Oracle は?
Oracle は 10.1.0以降で対応とのことです.
Java での問題
char が 16bit であるため, 16bit + 16bit のサロゲート・ペアは正常に扱えません...
具体的には, String#length() や, String#substring() が正常に動作しません(苦笑)
プロパティファイルなど, \uXXXX で表わすものは 16bit なので, サロゲート・ペアの文字は使えません.
プロパティファイルを XML で書けば, 任意のエンコーディングを使用できるので, サロゲート・ペアの文字も使用できます.
Java でサロゲート・ペアの文字列を扱うには, Java SE 5.0 以降で追加された API を使います.
サロゲート・ペアが含まれる文字数を正確に数えるには,
文字列のソートとかも工夫が必要です. 手前味噌ですが, 下記にサンプルがあります.
http://d.hatena.ne.jp/nanasess/20070819/1187700166
さらに...
http://itpro.nikkeibp.co.jp/99/vista/index.html
これを見ると, Vista で入力できても, XP 以前では対応していない文字が183字あり, この中には人名漢字も含まれます.
仮にWebアプリケーション側が Vista にフル対応したとしても, XP では表示できないというトラブルも発生します.
XP に JIS2004対応フォントをインストールしたりすることで回避できますが, 対応をクライアント側に任せるのもどうかと...
いちばん良いのは, Vista で問題の文字を入力した場合に警告を出すことでしょうかねえ...
参考
J2SE 5.0 Tiger 虎の穴 Unicode 4.0 の補助文字のサポート
JIS X 0213:2004(JIS2004) と Java と PHP と RDBMSの続きを読む
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 01:01
- in Java
2007年3月 8日
新しいプログラミング言語を習得するための15の方法
新しいプログラミング言語を習得するための15の方法
http://d.hatena.ne.jp/kajidai/20061025/1161711473
hanoimania!
http://www.kernelthread.com/hanoi/
で、紹介されている言語すべてで、この15の方法が書けるようになったらすごいだろうなーと。
sendmail.cf で書くとかはさすがに無理かもしれないけれど、少しずつでもいいからやってみようかなと思ったりする(笑)
続かなかったらスミマセン。
まずは Java からかなぁ。
新しいプログラミング言語を習得するための15の方法の続きを読む
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 20:57
- in Java
2007年3月 3日
Subversion でモジュールを管理する
Java に限らず、アプリケーションを開発する場合において、いくつかのアプリケーションで共通的に使用するモジュールを作成すると思います。
Subversion の svn:externals 属性を使用すると、これらの共通モジュールを管理するのが非常に楽になります。
ディレクトリ単位でしか使用できませんが、かなり重宝します。
使い方は簡単。
svn:externals という属性をディレクトリに対してセットしてやるだけで、そこで指定したリポジトリのディレクトリを update した時にコピーしてくれます。
詳しくは下記参照
Subversion - 外部定義
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 22:44
- in Java
2006年11月 4日
Eclipse から GWT を起動する for Mac
GWT が Mac OS X にネイティブ対応 したので、早速導入。
基本的には projectCreator で Eclipse のプロジェクトを作って、 Terminal から applicationCreator でデバックしながら開発という感じになるんでしょうけど、これだと Eclipse の デバックモードが使えず、ちょっと不便。
ということで、 Eclipse から起動させる方法を模索。
最初は、googlipse というプラグインを使ってみたのだけど、--XstartOnFirstThread の引数がないと怒られる。
あいにく、googlipse は、 任意の引数を与えることができないらしい。
試行錯誤のあげく、起動構成から直接 GWTShell をたたくことで成功。
具体的には、
1. 実行→構成および実行を選択。
2. メインタブで任意のプロジェクト(GWTTest)を選択、メインクラスは com.google.gwt.dev.GWTShell を指定
3. 引数のタブで、 プログラムの引数に下記を追加
-port 8888 -out "www" jp.example.GWTTest/GWTTest.html
4. VM引数に下記を追加
-XstartOnFirstThread
5. クラスパスのタブで、拡張をクリック、プロジェクトのディレクトリである src と bin をクラスパスに追加
これで実行をクリックすると、 Eclipse から GWT の hosted mode が立ち上がります!
さあ、ばりばりやるぞー
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 09:39
- in Java
2006年9月18日
Google Web Toolkit (GWT) を Mac OS X で開発する
記事は少し前に見つけていたのですが、なかなか時間が無く、やっと試すことができたのでまとめてみます。
Java で Ajax の開発ができる!という Google Web Toolkit (GWT)が大変注目を集めています。
が、開発環境としてサポートしているのが、Linux (GTK+ 2.2.1+) と、 Windows XP/2000 のみということなので、 Mac OS X ユーザーは非常につらいところ。
この開発環境を何とか Mac OS X で動かすことができないかと, いろいろ調べてみたところ, Google Code に Issue #7480804 - Mac OS X support for Google Web Toolkit というのを発見.
そこに, Using GWT on Mac OS X: How To Guide という Google Group の記事があったので試してみました.
- まず, http://www.eclipse.org/swt/ から, Mac OS X の SWT をダウンロードし, ‾/Library/Java/swt 等へ展開.
- Linux 版の GWT をダウンロードし展開.
- GWT を展開したディレクトリへ移動し, 下記のコマンドを実行. GWT プロジェクトを作成.
% ./projectCreator -eclipse GWTTest -out ‾/Documents/workspace/GWTTest
こうすることにより, Eclipse のプロジェクトが作成されます. プロジェクト名と, workspace のパスは, 環境に応じて書き変えてください.
- 次に, 下記コマンドで必要なファイルを生成.
% ./applicationCreator -eclipse GWTTest -out ‾/Documents/workspace/GWTTest jp.example.gwttest.client.GWTExample
GWT アプリケーションは, 必ず client パッケージを指定する必要があるようです.
- 生成したプロジェクトのディレクトリへ移動すると, GWTExample-shell や GWTExample-compile といった shell スクリプトが生成されていると思うので, GWTExample-shell を下記のように編集.
#!/bin/bash
APPDIR=`dirname $0`;
java ¥
-XstartOnFirstThread ¥
-cp "$APPDIR/src:$APPDIR/bin:/foo/bar/gwt-linux-1.1.10/gwt-user.jar:/foo/bar/swt/swt.jar:/foo/bar/gwt-linux-1.1.10/gwt-dev-linux.jar" ¥
-Djava.library.path=/foo/bar/swt ¥
com.google.gwt.dev.GWTShell -out "$APPDIR/www" "$@" jp.example.gwttest.GWTExample/GWTExample.html;
具体的には, 次のオプションを追加.
-Djava.library.path には, SWT を展開したパスを指定して下さい.-XstartOnFirstThread -Djava.library.path=/foo/bar/swt
クラスパスの gwt-dev-linux.jar の前に, swt.jar のクラスパスを追加しました.
- 編集した GWTExample-shell を Terminal 等から実行すると, GWT アプリケーションがホステッドモードで立ちあがります.
しかし, GWTExample-compile でWebモードへコンパイルしないと, GWTアプリケーションが動作しないようです..(苦笑)
Compile/Browse ボタンも動作しないようです..
つまり, JavaScript へコンパイルしないと動作しない模様..
ホステッドモードで debug 可能なのが GWT の良さでもあるので, 魅力半減..
でも, いちいちブラウザを立ちあげて確認するよりも, 少しは手間が省けるので, Mac OS X が正式にサポートされるまでの繋ぎとして使うのにはこれで我慢ですね..
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 03:07
- in Java
2006年8月11日
trac
2ヶ月ほど前から、プロジェクト管理を GForge から trac に乗り換えました。
Wiki ベースのプロジェクト管理ツールで、Subversion との連携は抜群。バグトラッカであるチケットシステムもシンプルでなじみやすいです。
乗り換えた最大の理由は、 trac が Python で書かれていること。
GForge は PHP4 で書かれており、GForge を使うためだけに サーバーに mod_php4 を入れていました。
apache2.0.x を使っているので、mod_php4 の使用は推奨されてないんですよね。。
また、最近は PHP で開発することもほとんど無くなり。。。必要性がかなり薄れておりました。
とりあえず、すっきり PHP とオサラバしたかったのです(笑)
最近は、 trac で開発を行っているプロジェクトもよく見られるようになってきました。国内では Meadow とか、 Namazu など。
WWDC 2006で存在明らかにされたMac OS Xの次バージョン「Leopard」に搭載予定のカレンダーサーバーである、 Darwin Calendar Server も trac で開発が行われるようです。
日本語の情報が、まだまだ少ないようなので、時間があったら少しずつでも、ノウハウまとめていきたいと思っておりますが。。。
できるのか?(汗)
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 03:01
- in Java
2006年6月19日
Java で Ajax が書ける!
これすごい。
Java 使いにとっては朗報。
いまのところ、実行環境が Windows と Linux のみのサポートだそうで、 Mac 使いにはちょっとツライ。
でも、しつこく試してみたところ、実行環境は動かないけど、 Java のソースコードから、 HTML と JavaScript のコードは生成出来る模様。
このあたりは Java で動いているみたいです。
もちろん、それをブラウザで開けばちゃんと動きます。
試してないけど、 Debugging in Hosted Mode なんてものもあるので、 Eclipse 使えば動くのかな?
使い方覚えれば、かなり使えるかなと。
いま使っている、 Struts ベースのフレームワークと、どう連携させようか・・・。
落ち着いたらまた書きます(汗)
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 00:16
- in Java
2006年4月23日
基本。
フォームに入力すると、見積書とか、請求書が PDF で自動的にできるソフト作ってくれーとの依頼入る。
Webベースにして、Java で作ることに。
Webベースにすることで、PCにインストールする手間が無くなり、ブラウザなら誰でも簡単に扱えるという利点がある。
ていうか、以前作ったことあるので、ちょっとカスタマイズするだけでできるのだが、くそまじめに作ろうと思い立ち、設計書から作ることに。
大規模なプロジェクトになると、概要設計→基本設計→詳細設計→製造→結合テスト→Quality Assurance(品質保証テスト) という流れは必須なのだが、小規模なアプリなら、ざっとER図とかクラス図を書いたりして、簡単に設計して、コーディングというように省略してしまう。
しかし、今回は、ちょっと基本をみっちりやろうと、概要設計から作っております。
設計書は、Excel、Word、PowerPoint等で作ることが多いと思いますが、僕はテキストベースで、Subversion 使って管理したいのです。
テキストベースにすることによって、プラットホームやバージョンの依存性が無くなり、Excel が入ってないからみれないとか、長い年月が経ち、作ったソフトが廃止され、ファイルが開けないということもなくなります。
いまやってるプロジェクトでは、APT(Almost Plain Text)というのを使っており、
Aptconvert is a command-line tool that can be used to convert the APT format to HTML, XHTML, PDF, PostScript, (MS Word loadable) RTF, DocBook SGML and DocBook XML.
ということで、かなりいろいろなフォーマットへ変換でき、大変優秀であります。
ベースとなるテキストファイルも Wiki に似た文法で、そのままでも読みやすい。
しかし欠点がただ一つ。
表が非常に書きにくいこと。
*+-:|を駆使して、表を書かねばならんのです。
*----------+--------:
|こんな | 感じ |
*----------+--------:
これ、超面倒(ーー;
かといって、LaTeX で書くほどのものでもないし・・・。
なんか良いツールは無いかと探していたところ、 SmartDoc はっけん。
前から知っていたのだけど、業界標準と言うほど使われておらず、デザインの柔軟性がちょっと乏しいかなと思い、敬遠しておりました。
また、僕は XHTML で出力したいので、これがないのがネックでした。
でも、それは、まだ SmartDoc が0.6とかのバージョンだった頃のお話。
現在、1.2b となって、かなり使えるツールになっております。
-html4.xhtml:true というオプションをつけると、XHTML で出力できるし、オプションと CSS を駆使すれば、かなり柔軟に HTML出力可能。
また、 PureSmartDoc 形式で書き出せば、XML DB と連携したり、 Java と連携したりと汎用性抜群。
ということで、いま、 SmartDoc を使ってごそごそ基本設計書を作っております。
で、いま作ってる帳票アプリは、機能が安定してきたらオープンソースで公開しても良いかなぁと思ってます。
PDFに出力する部分は、 JasperReports 使います。
こういうのは、一度作ってしまえば、割と楽なんですが、最初はなかなか敷居が高いですからねえ。。
とりあえず、基本に返って地道に頑張ります。。
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 01:06
- in Java
2005年12月11日
ソースコードとドキュメントの管理
僕の開発環境(いちばん多用しているもの)
- OS
- Mac OS X 10.4
- 開発言語
- Java SE 5.0
- IDE
- Eclipse 3.1.1
- モデリングツール
- Jude
- SCM
- Subversion
と、こんな感じなのですが、最近頭を悩ませているのは、ドキュメントの管理です。
いままで、適当にテキストファイルを作ってまとめていたのですが、どうも効率が悪い。
かといって、Wordみたいにバイナリファイルができるのは、バージョン管理しにくいのであまり好きじゃない。
Subversion を使っているので、バイナリでも差分でバージョン管理できるのだけも、diffつかって差分とれないから、あまり好きじゃないのです。
開発の上流行程の鍵を握るのは、ユースケース記述だったりするので、このあたりをしっかりまとめたいのです。
- テキストファイルで管理できること
- 大規模になり、大量の文書を抱えるようになってもメンテが楽なこと
- 視覚的にわかりやすいこと
- バージョン管理できること
- 変更に強いこと
- できれば、独自実装ではなく、すでに作られたもの。オープンソースで管理されているもの
- Emacs で書けること
条件をあげると、これくらいでしょうか。
UMLモデリングツール Jude Professional には、ユースケース図にユースケース記述を連携させて記述することが可能です。
しかし、ASCIIファイルで管理できないことが難点です。XMIに出力するとASCIIで管理できますが、ユースケース記述はサポート外となってしまいます。
いま、XMLでうまく管理できないか考えてます。
XSLスタイルシートを使えば、見やすく表形式にもできますし。
DocBookもいいかなぁ。
この辺はもっと勉強せねば。。。
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 01:07
- in Java
2005年11月 3日
Eclipse Web Tools Platform(WTP)
なにやらいろいろつまっていて便利そうです。
以前は、インストールが大変そうだったので、敬遠していたのですが、eclipse.org の更新サイトからダウンロードできるようだったのでインストールしてみました。
- JSP、XML、HTML、CSS、DTD、JavaScript Editor
- XML Schema のグラフィカル編集
- Webブラウザ、TCP/IP Monitor、Tomcat Debug
- データベース操作、SQL Editor
と、いろいろ便利そうです。
でも、データベースや、SQLはまだまだみたいね。。
JSPとか、HTML、CSSは、Dreamweaver 8がすこぶる快適だし、XML関連は、XMLStudio2(開発テストに参加していただいたもの)があるので、WTPはほとんど使わなかったりする^^;
でも、TCP/IPモニタやデバッガなんかは便利そうなので、いろいろ使ってみようかと思います。
DreamweaverでJSFが使えるようになると強いんだけどなぁ。
Eclipse Web Tools Platform(WTP)の続きを読む
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 00:42
- in Java
2005年10月28日
ファイルアップロードの罠
お昼頃、「画像がアップ出来ないんだけど」というクライアントさんからのお問い合わせ。
ちゃんとテストしたのになと思いつつ、こちらからはアップできることを確認。
でも、「できないんですよ」とのお答え。
よく調べてみると、Windows の IE からはアップできない事を確認。Safari からは OKだったのに。。。
ソースとにらめっこしていると、 form タグの enctype が、 multipart/form-data でなくてはいけないのに、 application/form-data になっているのをはっけん(自爆)
そりゃアップできないわ。。でも、Safariってこれでもアップできちゃうのね。。
あと、画像の縦横サイズ取得のために、 InputStream#mark(0) して、ImageInputStream を取得し、 ImageReader から width と height を取得した後、 InputStream#reset() して、ファイルをアップロードしています。
でも、画像のサイズが大きいと、 InputStream#mark(0) not support って例外が発生するケースを発見。
この辺どうにかしなきゃな。。
以下、そのあたりのコードです。
public ILargeObjectImage add(InputStream inputStream,
ILargeObjectImage iLobj) throws SQLException {
Connection conn = getDataSource().getConnection();
conn.setAutoCommit(false);
int oid = 0;
if (iLobj.getContentType() != null) {
if (iLobj.getContentType().equals("image/pjpeg")) {
iLobj.setContentType("image/jpeg");
}
Iterator iter = ImageIO.getImageReadersByMIMEType(iLobj
.getContentType());
if (iter.hasNext()) {
ImageReader reader = (ImageReader) iter.next();
try {
inputStream.mark(0);
ImageInputStream iis = ImageIO
.createImageInputStream(inputStream);
reader.setInput(iis, true);
iLobj.setWidth(new Integer(reader.getWidth(0)));
iLobj.setHeight(new Integer(reader.getHeight(0)));
inputStream.reset();
} catch (IOException e) {
conn.rollback();
throw new SQLException(e.getMessage());
}
}
}
try {
long image_id = SQLOptions.getNextId(conn, getSequenceName());
iLobj.setImageId(new Long(image_id));
iLobj.setFlags(Boolean.TRUE);
oid = addLargeObject(conn, inputStream);
iLobj.setOid(new Integer(oid));
addMaster(conn, iLobj);
conn.commit();
return iLobj;
} catch (SQLException e) {
conn.rollback();
throw e;
} finally {
DbUtils.close(conn);
}
}
もうちょっとリファクタリングしたいな。。ていうか、仕事しよ(汗)
- Permalink
- Comments (1)
- Trackbacks (0)
- by みそ
- at 01:01
- in Java
2005年10月27日
JavaMail + velocity + ActionForm で「〜」が文字化け
Struts で メールフォームを作って、 velocity を使ってメールの本文を生成、 JavaMail で送信という処理をする際、 Windows から入力した 「〜」などの一部の特殊記号が文字化けしてしまうことがあります。
ちなみに、エンコーディングは、 Java や JSP、velocity のテンプレートがすべて utf-8、メールは iso-2022-jpです。
Mac からの入力は問題なし。
Windows から入力された「〜」等の一部の特殊記号は、 Windows-31J のエンコーディングで送信され、 Servlet で utf-8 に変換、 JavaMail で MimeMessage に入力する際、 iso-2022-jp に変換されます。
このとき、 Windows から入力された「〜」の character code は、 iso-2022-jp や、SJIS、EUC での「〜」である、\u301c とは違い、 \uff5e であるため、コード変換が出来ずに文字化けしてしまいます。
参考 - Javaの日本語関連コンバータにおけるマッピングの違い
http://www.ingrid.org/java/i18n/encoding/ja-conv.htmlこの問題を対処するため、 Windows-31J や MS932 といったコードで入力した際、文字化けを起こす特殊文字の character code を iso-2022-jp や EUC で使用されている character code へ変換するメソッドを作りました。
public static String winToJIS(String input) {
StringBuffer sb = new StringBuffer();
char c;
for (int i = 0; i < input.length(); i++) {
c = input.charAt(i);
switch (c) {
case 0xff3c: // 「\」 を変換
c = 0x005c;
break;
case 0xff5e: // 「〜」を変換
c = 0x301c;
break;
case 0x2225: // 「‖」を変換
c = 0x2016;
break;
case 0xff0d: // 「−」を変換
c = 0x2212;
break;
case 0xffe0: // 「¢」を変換
c = 0x00a2;
break;
case 0xffe1: // 「£」を変換
c = 0x00a3;
break;
case 0xffe2: // 「¬」 を変換
c = 0x00ac;
break;
}
sb.append(c);
}
return sb.toString();
}
これで文字化け解消です。
2008-03-23 追記
古い記事で恐縮...はてなとリンクするテスト.
http://d.hatena.ne.jp/nanasess/20080323/1206255766
- Permalink
- Comments (2)
- Trackbacks (1)
- by みそ
- at 01:31
- in Java
2005年10月25日
JavaMail の SendFailedException について
こんなことしてる場合でもないのだが、忘れないうちに書いておこう。。
JavaMail をつかって、フォーム等からメール送信する際、To: やCc:、Bcc: に無効なメールアドレス(User unknownなど)が入っていると、SendFailedException になります。
これがでても、正常なその他のアドレスには、メールが送信されるようになっているようなのだが、
To: 無効なアドレス
Bcc: 無効なアドレスと有効なアドレスの混在
となったとき、メールが送信されないらしい。
To: のアドレスを有効にすると、送信できるようになりました。
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 03:16
- in Java
2004年12月22日
RSSParser for Java
自前で実装してもいいんだけど、あるものはどんどん使っちゃえということで、
Informaというのを試してみました。
バージョンは 0.6.0 です。
import java.net.URL; import java.util.Iterator;import de.nava.informa.core.ChannelIF;
import de.nava.informa.core.ItemIF;
import de.nava.informa.impl.basic.ChannelBuilder;
import de.nava.informa.parsers.FeedParser;
import junit.framework.TestCase;public class RSSParseTest extends TestCase {
public static void main(String[] args) {
junit.swingui.TestRunner.run(RSSParseTest.class);
}
public void testRssParse() throws Exception {
// URL を指定
URL feed = new URL("http://naoya.dyndns.org/~naoya/mt/atom-03.xml");
// (RSS|Atom) のバージョンを自動認識し、 ChannelIF に読み込む。
ChannelIF channel = FeedParser.parse(new ChannelBuilder(), feed);
// タイトルを出力
System.out.println(channel.getTitle());
// Description を出力
System.out.println(channel.getDescription());
// 最終更新時間を出力
System.out.println(channel.getPubDate().toString());
// Item を Iterator でまわして、各タイトルとリンク先を出力
for (Iterator iter = channel.getItems().iterator(); iter.hasNext();) {
ItemIF items = (ItemIF) iter.next();
System.out.println(items.getTitle() + ": " + items.getLink().toString());
}
}
}
ざっとこんな感じで簡単にできてしまいました。
ここでは、JUnit の TestCase を使っていますが、実際は Servlet とかでやってやれば OK でしょう。
複数バージョンの RSS 、 Atom を自動認識してくれるスグレモノ。
とっても楽ちんです
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 18:14
- in Java
2004年12月 9日
UML チュートリアル
http://www.ogis-uml-university.com/tutorial/index.htm
オージス総研
とてもわかりやすい。
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 18:13
- in Java
2004年11月29日
BeanUtils の使い方
2008-04-21 追記
BeanUtils について, 下記にもうちょっとちゃんとしたエントリーを書きました.以下は古いエントリーです...
Jakarta commons-beanutils は、使いこなすと非常に便利です。
が、Web上に日本語の情報がちょっと乏しいかなと思うので、よく使う API を簡単にまとめてみました。
PropertyUtils
BeanUtils
この2種類のクラスがあります。
どちらも同じようなメソッドが並んでいて、どう違うんやーって感じですが、簡単にいうと、
PropertyUtils は、 Object を返す。
BeanUtils は、 String を返す。
と、覚えておくといいと思います。
つまり、 String を返す Bean を扱う場合は、 BeanUtils を使い、それ以外は、 PropertyUtils を使って Cast するというような使い方でいいと思います。
例。
Struts の Action クラスで、 ActionForm から 自作の Bean にプロパティをコピーするのに、非常に重宝します。
MyBean myBean = new MyBean();
PropertyUtils.copyProperties(myBean, actionForm);
これだけで、 ActionForm のプロパティを、別の Bean にコピーしてしまうことができます。
ActionForm のなかから、一つだけプロパティを変数に代入したい場合は、
Object object = PropertyUtils.getSimpleProperty(actionForm, "propertyName");
この1行だけで済んでしまいます。
propertyName を配列にしておいて、 for とかでループさせて、まとめて validate させたりできますね。
このとき、 プロパティの getter が String を返す場合は、
String string = BeanUtils.getSimpleProperty(actionForm, "propertyName");
と、 BeanUtils を使ってあげると、 Cast しなくてすみます。
逆に、 set する場合は、
PropertyUtils.setSimpleProperty(myBean, "propertyName", object);
としてあげるといいでしょう。
Action クラスの引数の ActionForm を、キャストせずに直接扱えるのが便利なところですね。
PropertyUtils#(set|get)Property を使うと、もっと複雑なことができますが、また機会があったら書きます。。
相変わらず、仕事が火を吹いていますので。。(汗
また、 BeanUtils のソースは、 とっても勉強になるので、難しくても読んでおくと
いいと思います。
英語のドキュメントを読むより、ソースを読んだ方が理解しやすいこともありますし。
- Permalink
- Comments (0)
- Trackbacks (0)
- by みそ
- at 18:11
- in Java
This weblog is licensed under a Creative Commons License.