2009年10月22日木曜日

近い人はご存知と思いますが、ワタクシは紙が大っ嫌いです。なのに、起業してからというもの、すっかり役所周りの紙で埋もれてしまっています。
ペーパーレスと言われて久しいですが、減るどころか世界の紙の需要は増えるばかり。
謄本とかオンラインで取得できるんですが、届くのは紙が郵送で送られてきます。
登記するときも電子認証できるんですが、結局1部は紙の定款を残すことになります。

必要な紙とそうでない紙があると思いますが、特に役所周りでペーパーレス化が進むことを切に望みます。

どーでも良い内容でごめんなさい。

2009年10月16日金曜日

Weld

Web Beansが改名されました。
http://www.seamframework.org/Weld

で、1.0.0.CR1がリリースされました。名前変わっちゃうと翻訳大変そうです・・・。

Weldって溶接とか密着とか。
どうしてもSeamじゃ駄目なんだね。w

2009年10月9日金曜日

Amazon EC2 お試し

前から気になってたので、今更ですが試してみました。
http://aws.amazon.com/ec2/

細かいやり方は他の方が沢山書いてるのでパスするとして、僕が気になっていたのは

1) Smallの1.7GBでメモリが足りるかどうか
2) JBossがまともな速度で動くのかどうか
3) 回線スピードがどうなのか

と言う点なんですが、

1) 小規模ならギリギリ・・・・セーフ?中規模以上ならLarge以上のスペックにしないと厳しい。
2) JBoss (Microcontainer) [5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 2m:9s:265ms
だったので、一応は我慢できるレベル。これもLargeにすれば問題無さそう。
3) 正直遅い。他の人も書いてるけど、画像とかを国内サーバーに置けば我慢できるかも?

安いのは安いと思うけど、やっぱり「うーん」となってしまう感じ。Sunのクラウドが気になるところ。

2009年10月7日水曜日

Rails環境作成

新しいノートに環境作成をしていて丁度良かったので、今日は、Railsの環境作成について書いてみようかと。ほぼ自分のためのメモなのであしからず。

http://rubyforge.org/projects/rubyinstaller/

から、One-Click Installerをダウンロード&インストールする。RubyGemsを一緒に入れるのを忘れないように。
# 1.8.6かぁ・・・・まぁいっか。

インストール後、
> gem install rubygems-update
> update_rubygems
> gem update

で、構成をバージョンアップしてから、Railsを入れる。
> gem install rails
> gem install sqlite3-ruby 窶錀-version ‘= 1.2.3′

として完了。SQLiteのDLLを別途落としてRubyのパスに突っ込んでおきます。

関係ないけど、gem updateされたものを見るだけで、One-Click Installerには余計なものがたくさん入ってる・・・・まぁいっか。
さくっと動作確認だけしておこう。
> rails bookmark
> cd bookmark
> rake db:create:all
> ruby script/generate scaffold bookmark url:string
> rake db:migrate
> ruby script/server

で、Bookmarkプログラムのインストールが完了。動作確認します。

最後に、開発環境としてNetBeansを入れます。Ruby版でオーケー。

# Javaとは違ってWindows上で検証したものが本番環境(Linuxとかの別OSのサーバー)上で同じように動くかどうかは別問題なので、注意。

authenticator

さて、もうひとつ早めに説明しておいた方が良いですかね。忘れそうだし。苦笑

Seam標準のログイン認証機能の説明です。

C:\Projects\myproject\src\hot\com\mydomain\myproject\action\AuthenticatorBean.java を見てみましょう。(import文はもう省略)
@Stateless
@Name("authenticator")
public class AuthenticatorBean implements Authenticator {
@Logger
private Log log;

@In
Identity identity;
@In
Credentials credentials;

public boolean authenticate() {
log.info("authenticating {0}", credentials.getUsername());
//write your authentication logic here,
//return true if the authentication was
//successful, false otherwise
if ("admin".equals(credentials.getUsername())) {
identity.addRole("admin");
return true;
}
return false;
}

}

Seamコンポート名として、authenticatorが宣言されていますので、JSF等からこのインスタンス名でアクセスされます。
C:\Projects\myproject\resources\WEB-INF\components.xml に
<security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>

という宣言があり、ログインされたときは #{authenticator.authenticate} を実行し、戻り値がtrueであればログイン成功だよ、という事です。

で、このサンプルの場合はauthenticate()で何をしているかというと、C:\Projects\myproject\view\login.xhtml のツꀀUsernameの値が「admin」だったらログイン成功・・・・なるほど。w
まぁ、そんなわけで実際の開発時にはこのauthenticate()をカスタマイズするだけで、DBと普通に認証しても良いし、LDAPと認証しても良いし、ActiveDirectoryと認証しても良いし、という具合になります。便利。

さらにDroolsを使ってロールの概念を持たせると権限の概念の定義も可能です。これはもっと先の話。(そこまで書く元気があるのかしら)

login.xhtmlやmenu.xhtmlを見るとログインしているかどうかで表示を分けていたりするので、参考にしてください。
また、フレームワークとしてログインしているかどうかというのがちゃんと認識されていますので、特定のメソッドをログインしてなかったら実行できないようにする、というような事がアノテーション一行で定義可能です。これもどこかで説明したいと思います。

最後に、恒例(うそ)のアノテーション解説して終わります。新出だけね。
@Stateless: ステートレスセッションBeanであることを示します。ちなみに、SeamでステートレスセッションBeanを使うのは一般的にはログイン画面と(層を作りたい場合に)純粋なDAOを作るような場合くらいですかね。通常ステートフルセッションBeanを使うことになります。
@Logger: org.jboss.seam.log.Logのインスタンスを使います。これを書いておくと、Log4Jを使うときの非常に冗長なif文を書かなくてもSeamがよしなにしてくれることになっています。
@In: インジェクション。画面からの値をクラスの属性で受け取るのに使います。ログイン画面の例なので最初はしんどいかもしれませんが、logins.xhtmlと見比べれば分かると思います。

generate-entitiesにより作られたクラス2

続いて、C:\Projects\myproject\src\hot\com\mydomain\myproject\action\MyprojectList.java
これは所謂セッションBeanに相当するものです。MyprojectはエンティティBeanだったので、これに対するビジネスロジックを定義する場所と考えてください。
相当するものと書いたのは、EntityQueryを継承してしまうことで、一般的なセッションBeanの書き方とは異なるから。
セッションBeanを使う場合は、EntityManagerに関する記述を書いたり、セッションBeanであることを宣言したりすることが必要。

package com.mydomain.myproject.action;
import com.mydomain.myproject.model.*;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.framework.EntityQuery;
import java.util.Arrays;
@Name("myprojectList")
public class MyprojectList extends EntityQuery<Myproject> {
private static final String EJBQL = "select myproject from Myproject myproject";
private static final String[] RESTRICTIONS = {"lower(myproject.val) like lower(concat(#{myprojectList.myproject.val},'%'))",};
private Myproject myproject = new Myproject();
public MyprojectList() {
setEjbql(EJBQL);
setRestrictionExpressionStrings(Arrays.asList(RESTRICTIONS));
setMaxResults(25);
}
public Myproject getMyproject() {
return myproject;
}
}
ここでもアノテーションが出てくるので、簡単に。
@Name: これはSeamアノテーションで、Seamコンポート名というのを指定します。とか書くと分からないのですが、ここで宣言した名前でJSFから直接呼び出せることになっています。要はその時のクラスのインスタンス名を書いてって事なので、普通はクラス名の先頭を小文字にしたのを書いとけば十分です。

あれ?SQL変じゃね?って思った人がいるかもしれませんが、これはEJB3.0規格のEJB-QLという独自のSQL文になっています。何でそんなことを・・・と思うかもしれませんが、EJB-QLが間に挟まっているおかげで開発者はその先にあるデータベースの方言について一切意識する必要が無いのです。それは本来開発者の仕事ではなく、フレームワークの仕事だろってのがEJB3.0の思想になるわけです。

#{myprojectList.myproject.val}はJSF側の該当パラメータが直接入ります。どこにあるかというと、C:\Projects\myproject\view\MyprojectList.xhtml つまり、部分一致検索の条件パラメータが入ります。
普段、何層にも層を作って開発をされている方には気持ち悪いですが、本来これくらいシンプルじゃないと。

setMaxResults(25);

は検索結果の最大件数が25行までですよ、と宣言しています。こんなこともSQLだけでやろうと思うと、あれ?このDBの場合はどうやるんだっけ?って絶対迷うので、EJB-QLの場合そういうのが無いだけで精神衛生上良いです。(EJB-QLでどう書くんだっけ?とはなるわけだけど・・・・それは仕方ない。苦笑)

C:\Projects\myproject\src\hot\com\mydomain\myproject\action\MyprojectHome.java も同様にEntityQueryを継承していますが、こちらは今見てもさっぱり意味が分からないと思うので、スルーしましょう。(ぉぃ)

追いたい人は、C:\Projects\myproject\view\MyprojectEdit.xhtml からMyprojectHomeがどのように使われているのかを見ておくと良いです。ものすごくすっきりしてますが、正直何やってるか分かんないというのが実情ではないかと。

たった一行のDDL(create table)からgenerate-entitiesで出力されたCRUDするためのコードがどのように動いているのか、もう少し上手に説明したいところですが、余り使われてないEntityQueryのせいでちょっと分かりにくくなってしまっているんです。一通り全体が分かるようになったところでもう一度おさらいしてみて下さい。

2009年10月6日火曜日

generate-entitiesにより作られたクラス1

前回の投稿からだいぶ時間が空いてしまいました。誰も観てないからいいか。

ノートを買いました。なので、ここから先は当面ローカルホストで動かすことを前提とします。(ごめんっ)

さて、generate-entitiesによりテーブルから自動的にクラスとJSFを作成して貰うことで、前回はプログラムコーディングが1行も無しでCRUDできてしまいました。
RailsにしてもSeamにしてもここまでは皆さん喜ぶんですが、当然これでは仕事にはなりません。
なので、少しずつ深みに嵌らないといけませんが、今回はまずgenerate-entitiesで作成されたクラスを見ていきましょう。
一度にたくさん書くと続かないので、今回は、エンティティBeanの C:\Projects\myproject\src\main\com\mydomain\myproject\model\Myproject.java です。
エンティティBeanというのは、DBのテーブルとのインターフェースに使うマッピングクラスのようなものです。EJB3.0ではエンティティBeanPOJOでなければいけません。POJOってのはただのJava Beans。
EJB3.0の事を知りたくなければこういうのを作るんだ位で読み流してよいでしょう。要はSeamで開発できるようになることが大事。
package com.mydomain.myproject.model;

// Generated 2009/10/06 12:43:58 by Hibernate Tools 3.2.4.GA

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.validator.NotNull;

/**
* Myproject generated by hbm2java
*/

@Entity
@Table(name = "myproject", schema = "public")
public class Myproject implements java.io.Serializable {

private int id;
private String val;

public Myproject() {
}

public Myproject(int id, String val) {
this.id = id;
this.val = val;
}

@Id
@Column(name = "id", unique = true, nullable = false)
public int getId() {
return this.id;
}

public void setId(int id) {
this.id = id;
}

@Column(name = "val", nullable = false)
@NotNull
public String getVal() {
return this.val;
}

public void setVal(String val) {
this.val = val;
}
}

んんんん?アットマーク(アノテーション)は何だ?という人の為に、

@Entity: 注釈されたクラスがEJB3のエンティティBeanであることを示します。
@Table: 注釈されたエンティティBeanがDB側のテーブルに関連付けられることを示します。ここでは、public.myprojectに対するエンティティBeanであるという宣言。省略したら「エンティティBeanのクラス名 = DBのテーブル名」と見なされます。
@Id: 注釈された属性がテーブルの主キーに関連付けられることを示します。基本的にはエンティティBeanに毎に1回しか使えません。また、エンティティBean毎に必ず一度利用しなければなりません。複数キーに対応する方法はありますが、複雑なので今は割愛します。特に理由が無ければ単一カラムで主キーを宣言しておいたほうが楽です。属性のゲッターに付与することもできます。
@Column: 注釈された属性がテーブルの項目に関連付けられることを示します。ここでは、属性idとpublic.myproject.idが関連付けられ、idはユニークで、NULLは許容されない、という意味です。省略したら「属性 = テーブルの項目名」と見なされますが、実際には、どのみちnullableを書かないといけないので都度都度宣言が必要です。属性のゲッターに付与することもできます。
@NotNull: 注釈された属性がNULL許容されないことを示します。これはJPAのアノテーションではないので、Hibernate環境でなければ使えませんが、SeamにはHibernateが同梱されているのでほかの環境に乗り換える予定が無ければ付けておきます。属性のゲッターに付与することもできます。
アノテーションを理解すれば何が書かれているかが何となくわかります。便利。

自動生成だけあって、いくつか問題があります。

・シーケンスに対応されていない。

・アノテーションが冗長でメンテしづらい。
前者については問題ありありなので、解決しなければなりません。
後者については、常にテーブルからエンティティBeanを作るという一方通行なら無視して良いでしょう。逆にエンティティBeanからテーブルを作るという一方通行が好みなら何とかしないと生産性に響きます。僕の場合は後者ですが、話をできるのは少し先。

エンティティBeanはシンプルですが、奥が深いので都度都度追加で説明しますが、1つのテーブルにこのようなものを1つ作ることになるんだというのを今回は押さえてください。 それではまた次回。