2009年11月21日土曜日

GAEとDoCoMoのアドレス

GAEでメール受信を作りましたが、
初めに試してもらった人が「xxxxx.@docomo.ne.jp」てアドレスでした。

どうも@の前に「.」があるとダメみたいで
getFrom()をやると「local part invalid」ってエラーが出てました。

なのでヘッダーの情報を見て、

 Enumeration<?> enu = aMessage.getAllHeaderLines();  //データ数回繰り返す while ( enu.hasMoreElements() ) {  String line = (String)enu.nextElement();  if ( line.toLowerCase().indexOf("from") >= 0 ) {   //fromを検索して追加   fromAddress.add(line);  } else if ( line.toLowerCase().indexOf("to") >= 0 ) {   //toを検索して追加   toAddress.add(line);  } } 


って感じでFromやToを抜き出して、
そこからアドレスを抽出して処理してみました。

まぁシビアにはまずいかもしれませんが
一応これでメールアドレスを判定する事ができました。

2009年11月15日日曜日

TitleWindowをリサイズする

TitleWindowをリサイズ可能にしようと思い立ち


を元に作成したのだが、スクロールバーなどがあると
かなり挙動不審になりますね。。。

つうことで

onThis_mouseDown() 関数の初めに

    if ( event.target != this ) {     return;    }  

といれると結構安定します。

ちなみに私は
    private const SIZE_DRAGAREA:int = 10;   private const SIZE_MIN_WIDTH:int = 50;   private const SIZE_MIN_HEIGHT:int = 50; 

位で使います。

Blogger・・・トラックバックできない。。。
・・・なんかややこしいけどやり方はあるみたい。
やってみるかな。。。

2009年11月8日日曜日

GAEでメール受信

GAEにメール受信する機能が増えたんですね。
またまたやってくれます。。。。って思ってたら
やっぱり限定の機能なんですね。

・・・まぁそれだけでもすごい事です。
えーと、、、仕組みはここにあります。

string@appid.appspotmail.com

に送ると、

/_ah/mail/


に届くみたいですね。。。。
Cronとか駆使して、、、って考えてたんですけど、
開発環境でみる限り、メールを送信したら、サーブレットをPostしてくれるみたいです!
なんだ、、、色々楽ですね。。。

まず、appengine-web.xmlに


<inbound-services>
<service>mail</service>
</inbound-services>


を追加します。

その後web.xmlに


<servlet>
<servlet-name>mailHandle</servlet-name>
<servlet-class>bz.ziro.kanbe.servlet.MailHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mailHandle</servlet-name>
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>



<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>


を追加します。
servletの上はクラス名、下はURLです。
URLは固定ですね。

下のはセキュリティ設定です。
第三者が触れないようにadmin(アプリ管理者)のみ触れるようにしておきます。

その後HttpServletを派生したクラスを作成して
doPost()を実装します。


@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

try {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session, req.getInputStream());



} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}


これで、メールを受け取ったら動作します。
http://localhost:8080/_ah/admin/
にアクセスすると、inboundMailっていうのがあるので
開発環境ではここから送信できます。

先だって話したように、URLとメールアドレスが連動しているので
何のメールかとかをToで判断したりすればOKだと思います。

FlexのリリースビルドをAntで

Flexのリリースビルドを簡単にAntでやろうとしたらハマりました(>_<)


<project name="kanbeMng" default="release" basedir=".">


<taskdef resource="flexTasks.tasks" classpath="D:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0\ant\lib\flexTasks.jar"/>
<property name="FLEX_HOME" value="D:\Program Files\Adobe\Flex Builder 3\sdks\3.2.0"/>
<property name="APP_ROOT" value="C:\Documents and Settings\Administrator\My Documents\Flex Builder 3\kanbeMng"/>
<property name="SRC_ROOT" value="${APP_ROOT}\src"/>
<property name="mxmlc.jar" location="${FLEX_HOME}/lib/mxmlc.jar"/>

<property name="debugDir" value="bin-debug"/>
<property name="releaseDir" value="bin-release"/>

<property name="targetDir" value="D:/workspace/kanbe/war/mng"/>
<property name="targetBlankDir" value="D:/workspace/kanbe-blank/war/mng"/>

<property name="flashFile" value="KanbeMng.swf"/>

<target name="release" depends="release-build">
<move file="${SRC_ROOT}\${flashFile}" todir="${releaseDir}" overwrite="true"/>
<copy todir="${targetDir}" file="${debugDir}/${flashFile}" overwrite="true"/>
<copy todir="${targetBlankDir}" file="${releaseDir}/${flashFile}" overwrite="true"/>
</target>

<target name="release-build">

<mxmlc file="${SRC_ROOT}\KanbeMng.mxml"
debug="false"
actionscript-file-encoding="UTF-8"
keep-generated-actionscript="true"
incremental="true">

<compiler.library-path dir="${APP_ROOT}\libs" append="true">
<include name="Efflex_v0.03_fx3_fp9.swc" />
</compiler.library-path>

<compiler.source-path path-element="${SRC_ROOT}"/>

</mxmlc>

</target>
</project>


私のわかる程度に説明します。

まず、自分の環境に合わせて、設定をします。
なんか無駄なものもありそうですね。。。 ...mxmlc.jarはいらないっすね。

でmxmlcタグを作成します。
swcがある場合はそれを読み込みましょう!

ん~キャッシュがウンタラカンタラが難しかったです。
もう少しわかりすく書きたいっすけどね。

2009年10月8日木曜日

GAE+Flex+ファイルアップロード+認証

GAE上でFlexを使用してファイルアップロードを行っているのですが
どうもうまくいかない状態でした。
まぁオススメはできませんが回避策を一応書いておきます。

FireReference.uploadはセキュリティ系の問題なのか
クッキーを送信できません。
ここのにupload()のURLRequestHeaderのところに記述があります。

GAEでは認証アプリ内ではクッキーを使用して認証を確認しているようで
JSESSIONIDとACSIDを送信することが不可能なようです。

なのでGAE上でFileReferenceを利用してアップロードをすると
アップロード時に認証エラーでアップロードができないようです。

そこで、私の場合はアップロードのURLを認証から外して独自認証することで切り抜けました。
Flexが送信するRequestに引数をjsessionidを指定しておいて
認証のかかってないURLの処理上でSessionからIDを取得して同一かを判定して切り抜けました。

まぁセキュリティ上は微妙でしょうけど、
一応認証を受けてないと使えないようにはしました。



で、、、ここで気をつけなければいけないのは
FileReferenceで渡すURLRequest.dataをObjectではなく、
URLVariablesにすることです。
そうしないとRequestでmultipartにならず、
multipartで値を受け取れないからです。(slim3)

2009年8月28日金曜日

Redmineインストール(Linux)

やっぱwin32だと重いので、Linuxにインストールします。

まずRubyは
http://www.ruby-lang.org/ja/downloads/
から落としてきます。
バージョンは1.8系じゃないと何かとエラーになります。

んでそれを解凍して


./configure
make
make install


します。



# ruby -v

とやってインストールされたことを確認します。

その後rubygemsを落として来て解凍してそのディレクトリに入って、

# ruby setup.rb

とやります。
これでrubygemsはインストール完了(>_<)v

でその後にrailsを

# gem install rails -v 2.2.2

とやります。これで準備完了。

さて、いよいよredmineです。。。。
という前にDBをインストールしなければっ!

一番相性の良いMySQLにしますかね?

http://dev.mysql.com/downloads/mysql/5.0.html

に行って、V5.0を落としてきます。
V5.1でも良いんですけど、相性が悪いみたいです。


MySQLをインストールした後、データベースを作っておきましょう!
えーとそれは
http://secondarykey.blogspot.com/search/label/MySQL
この辺から作ってください!

create database redmine character set utf8;
データベースを作成する場合はUTF8を指定します。


でその後に

http://rubyforge.org/frs/?group_id=1850

ここから最新版の0.8.4を落としてきます。
で解凍して、config/database.yml を作成して


production:
adapter: mysql
database: redmine
host: localhost
username: red
password: mine
encoding: utf8


って感じで書き込みます。

# rake db:migrate RAILS_ENV=production

を行うとテーブルを作成してくれます。

# ruby script/server -e production

で実行して

http://~~~~:3000/

でアクセスしてadmin/adminでログインします。

※ruby installでプロキシがある場合は
[-p http://~~~~~]って付け加えると大丈夫です(--)ノシ

Redmine

・・・んーやっぱWin32よりLinuxが早いね(-.-;)

2009年7月25日土曜日

GAEでデータビュー

GoogleAppEngineのプラグイン1.2.2から。。。なのかは知りませんが
登録したデータをデータービューで見ることが可能になりました。
アプリケーションの起動中に

http://localhost:8080/_ah/admin/datastore

にアクセスすればOKです。
これでデータを見ることができますね。

2009年7月18日土曜日

GAEでメール送信

GAEでメール送信するにはJavaMailを使用します。
・・・特段技術的なことを書くまでもないのですが受信はできません。
送信時はアプリの管理者がFromになる必要があります。
って全部マニュアルに書いてありますけど。。。

少しメールに関連したサービスの立ち上げを
やろうとしたのですが頓挫したので一応参考まで。

2009年7月13日月曜日

ドメインの切り替え

HTTPサービスにアクセスする際に
ローカルで試す時と、デプロイした時の動作を変更したい。
そんな時にこの方法です。


var domain = "http://localhost:8080/";
var url:String = Application.application.url;
var httpExp:RegExp = new RegExp("http://[^/]*/");

if ( httpExp.test(url) ) {
domain = httpExp.exec(url).toString();
}


まぁ取得を外出しにすればよいのですが、
手軽にこういう感じもあるんですね。

Flexで開発している間は、
「file://」でアクセスするので
mx.core.Applicationが持ってるURLではif文には入らないです。
入った場合は変換を実行しています。

って感じです。

2009年7月12日日曜日

FlexのExplorer

Flex4を前にしてやるのもなんですが、
なかなか検索でトップに出ないの備忘録で。

Flex3のコンポーネント

Flex3のスタイル

2009年6月28日日曜日

GAEでVelocity

少しテンプレートエンジンを使いたいなぁ。。。って思ったので
Velocityを使うことにしたんだけど、
GAEはファイルシステムはないので、、、って思ってたら
メモリ上で展開できるみたい。


VelocityContext context = new VelocityContext();
StringWriter writer = new StringWriter();
String template =
"テンプレートのテストです[${name}]" +
"";
context.put("name", "なまえー");
Velocity.evaluate(context, writer, "vecocityTest", template);


これでwriterに設定できます。
テンプレートを「com.google.appengine.api.datastore.Text」で
保存すれば使えそうですね。

実行にはVelocity、commons-lang、commons-collectionが必要です。

2009年6月27日土曜日

GAEで派生データを登録


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト



少し前に試した時にダメだったので諦めていたのですが、
再度チャレンジしたらOKだったので投稿しておきます。

親クラスを準備します。

package bz.ziro.slim3.test.model;

import java.io.Serializable;
import java.util.Date;
import java.util.logging.Logger;

import javax.jdo.JDOHelper;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.Version;
import javax.jdo.annotations.VersionStrategy;

import com.google.appengine.api.users.User;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
@Version(strategy = VersionStrategy.VERSION_NUMBER)
public class Parent implements Serializable {

private static final long serialVersionUID = 1L;

@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(Parent.class.getName());

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String key;


@Persistent
private User creator;
@Persistent
private Date createDate;
@Persistent
private User editor;
@Persistent
private Date editDate;

/**
* @return the key
*/
public String getKey() {
return key;
}

/**
* @param key
* the key to set
*/
public void setKey(String key) {
this.key = key;
}
public User getCreator() {
return creator;
}

public void setCreator(User creator) {
this.creator = creator;
}

public Date getCreateDate() {
return createDate;
}

public void setCreateDate(Date createDate) {
this.createDate = createDate;
}

public User getEditor() {
return editor;
}

public void setEditor(User editor) {
this.editor = editor;
}

public Date getEditDate() {
return editDate;
}

public void setEditDate(Date editDate) {
this.editDate = editDate;
}

/**
* @return the version
*/
public long getVersion() {
return (Long) JDOHelper.getVersion(this);
}
}



でこのクラスを派生した子クラスを準備します。


package bz.ziro.slim3.test.model;

import java.io.Serializable;
import java.util.logging.Logger;

import javax.jdo.JDOHelper;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.Version;
import javax.jdo.annotations.VersionStrategy;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
@Version(strategy = VersionStrategy.VERSION_NUMBER)
public class Child extends Parent implements Serializable {

private static final long serialVersionUID = 1L;

@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(Child.class.getName());

@Persistent
private String name;
@Persistent
private String detail;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
/**
* @param detail セットする detail
*/
public void setDetail(String detail) {
this.detail = detail;
}
/**
* @return detail
*/
public String getDetail() {
return detail;
}
/**
* @return the version
*/
public long getVersion() {
return (Long) JDOHelper.getVersion(this);
}
}



これで準備完了です。
ChildオブジェクトをGAE(JDO,BigTable)で登録すれば
Parentの属性も登録できます。


実装の通り、登録ユーザや登録日付などテーブル内にある同一の属性を
親クラスを利用することにより、はしょることができます。
まぁ私の場合は更新時などにオブジェクトに都度同一の実装が必要になり
困っていたので助かります。

JDOを知った時に論理モデル(つうかUML記述?)をそのまま使えるなぁ。。。
って思ってやったらダメだったんですけど、やっぱできるんですね。

ちなみにDataNucleusでJDBC(HSQLDB)で同じようにやると
Parentテーブルがにもデータがあって。。。って感じになった記憶があります。
※同一のエンティティではないです。


ちなみにSlim3のDaoでMetaクラスを利用して検索式を作成しても
ChildMetaに存在しないのでエラーになります。
問い合わせるかはもう少し試してからにしようと思ってます。

2009/07/08 ※再度試したらSlim3でも動作しました。
2009/07/26 ※再度試したらSlim3で動作。。。っていうかGAEで動作しませんでした。
ので、Embeddedの話で記述します。

Slim3で開発を始める。


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト



Slim3はGAE用に最適化され開発されているフレームワークで
すごくシンプルに開発できるように工夫されています。


今回は現在のSlim3での開発をおさらいしてみましょう。
まだ開発中ですので違う手法になっている可能性もあるので
十分に気をつけていただければ幸いです。
※eclipseでの開発です。

まず、「http://slim3.googlecode.com/svn」にSVNでアクセスして
「trunk/slim3-blank」からチェックアウトを行います。
ライブラリを落とし込んで来て作成するのもよいのですが
genで使用しているaptの設定などがあるのでblankで作成しておくのが良いでしょう。

で現在、aptの設定がプロジェクト名に依存しているので
プロジェクト名を変更した場合それを変更する必要があります。
プロジェクトで右クリック「プロパティ」をクリック
「Javaコンパイラー」→「注釈処理」→「ファクトリーパス」において
編集で「lib/slim3-genEA1-SNAPSHOT.jar」を再度指定します。



war/WEB-INF/web.xmlの中にある

<context-param>
<param-name>slim3.rootPackage</param-name>
<param-value>slim3</param-value>
</context-param>
<context-param>
<param-name>slim3.staticPackages</param-name>
<param-value>model</param-value>
</context-param>


の部分をオリジナルの名前空間に変更します。
「slim3.rootPackage」が自分の作成するアプリケーションのルートパッケージで
指定した位置がHotReloadingの対象になります。
「slim3.staticPackages」がHOTの対象外のパッケージを設定します。
カンマ区切りで指定できます。(モデルのパッケージは必ず指定してください)

これで開発の準備は完了です。

プロジェクトのルートにあるbuild.xmlで必要なクラスは
自動生成をして開発を進めていきます。

「gen-model」:エンティティ,Daoとそれぞれのテストクラスを出力してくれます。
「gen-controller」:controller,jspとそれぞれのテストクラスを出力してくれます。
※それぞれを指定する場合、パッケージ名は必要ありません。


build.xmlのprojectタグにある「name="xxxx"」を
自分のプロジェクト名に変更してあげる必要があります。


「gen-controller」で「index」と指定すると
ひとまずアプリケーションとして動作できるようになります。
※既存のjspやcontrollerは消しておいた方が良いかな。。。

2009年6月21日日曜日

SVNの設定(認証)

さて、SVNのインストールが終わったので設定します。
Apacheのhttpd.confに

<Location /svn/mog>
DAV svn
SVNPath /home/svn/mog
</Location>

を追加します。


svnadmin create /home/svn/mog


を行うとリポジトリが作成されます。
これでクライアントからアクセスできるはずですが
apacheの起動ユーザに対して権限があることが条件です。


さてDIGEST認証を使うにはApacheにDIGEST認証モジュールが必要です。
※Apacheのモジュールでインストールしてあれば問題ありません。

ソースのmodules/aaaに移動して

/usr/local/apache2/bin/apxs -D DEV_RANDOM -c ./mod_auth_digest.c
/usr/local/apache2/bin/apxs -i -a -n auth_digest mod_auth_digest.la


と行うとhttpd.confにLoadModuleが追加されるはずです。
これで準備はOK

Apacheに

<Location /svn/test>

DAV svn
SVNPath /home/svn/test

AuthType Digest
AuthName "SVN AUTH"
AuthUserFile /home/svn/.htdigest
Require valid-user

</Location>


って感じで追加します。


htdigest -c /home/svn/.htdigest "SVN AUTH" username


でパスワードを入力してApacheを再起動します。
で再起動すればOKです。

2009年6月20日土曜日

SVNをインストール

ソースを管理していたCVSのディスクがぶっ飛び、
せっかくなんでSVNをインストールしようと思い立つ

前準備で

http://www.oracle.com/technology/software/products/berkeley-db/index.html
※ごめんなさい。。。後述しますが、、、いらないかも。

からBerkeleyDBをダウンロードしてきて

cd dist/build-unix
../dist/configure
make
make install

を行います。
build-unixに入ってからconfigureを行うのがポイントです。

/usr/local/BerkeleyDB.4.7
ができています。


echo "/usr/local/BerkeleyDB.4.7/lib" >> /etc/ld.so.conf
/sbin/ldconfig


を行って共有ライブラリに追加しておきます。

でApacheをインストールします。
http://www.apache.jp/misc/download.html
などから持ってきます。


./configure --enable-modules=most --enable-shared=max --enable-dav=yes --with-berkeley-db=/usr/local/BerkeleyDB.4.7
make
make install


を行います。
モジュールをすべて入れています。

次にいよいよSubversionです。
http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=74
からダウンロードしてきます。
sqlliteのソースなどがいるのでdepsもダウンロードしておきます。



./configure --with-apxs=/usr/local/apache2/bin/apxs \
--with-apr=/usr/local/apache2/bin/apr-1-config \
--with-apr-util=/usr/local/apache2/bin/apu-1-config
make
make install


一応これで完了です。
・・・んーと。。。文献だとberkeleyを
configureに設定していたんですけど。。。
なんかうまくいかなかったので外しました。

2009年6月13日土曜日

ガツンとSlim3

はてさて「Seasar Conference 2009 Spring」行ってきました。
行ってきたというより、ひがさんの話を聞いただけですけど。

まぁ単純に感想を言うと、為になったというか。。。
バイトを連れて言ったのですがわかりやすくてとても
参考になったというところでしょうか。


「ガツン」の節で始まるとは少し予想してませんでしたけど。

で、ひがさんに感化されたわけではないのですが
あんまりこういうことは書かんのようにしていますが一応言っておきます。


まぁ言語はなんでも良いんですよ。
ようは作るものだとか作りたいものに対してどうなのか?

Perlでも優れたシステムはあるし、RoRでもへなちょこなシステムはある。
※あくまでPerlは古いって意味合いだけ使ってますし
RoRは言語じゃないですけど、新しいって意味で使ってます。

言語は言語屋さんにお任せして(もちろん要望等は出しましょう)
私らはシステムを向きましょう。

だから私は「システムに絶対はない」と言うとるわけでして。

2009年5月31日日曜日

Slim3でおーだーばい。


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト




ShopMeta shopMeta = new ShopMeta();
List<Shop> list = from(Shop.class).range(0,10).orderBy(shopMeta.createDate.desc()).getResultList();
List<BeanMap> shopList = new ArrayList<BeanMap>();
for (Shop b : list) {
BeanMap m = new BeanMap();
BeanUtil.copy(b, m);
shopList.add(m);
}
requestScope("newShopList", shopList);


んー。。。エクセレント。なんかきれいです。
なんか直感的なソースが良いですね。

Slim3でユーザの検索


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト




UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();

ShopMeta shopMeta = new ShopMeta();
List<Shop> list = from(Shop.class).where(shopMeta.creator.eq(user)).getResultList();


ShopMetaは自動的に作られます。(aptとかをプロジェクトで設定します)
creatorはJDOで保存しているカラムの一部です。
※aptについては今勉強中です。後日設定方法を書きます。

なんかおしゃれになってきましたね。
もし私がゴクウだったら「おらワクワクしてきたぞ状態」です。

2009年5月26日火曜日

Slim3でリソース表示(訂正)


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト



※以下コメントを受けまして、少し訂正を入れています。
 訂正と言うか注釈ですね。。。

Slim3を触っています。
構築中っていうことでまだ単純な機能が足りません。
※訂正:単純な機能ではなく、私のスキルが足りなかったようです。

ん。。。JSPにリソースを表示したい。。。
ってことでオリジナルで作ってみました。
おそらく近日本家で実装されますんで
※訂正:コメントより、作られるのではなくJSTLで既にあるようです。


taglib作成の参考として読んでください。

まずtldファイルを作成します。


<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">

<description>Mog resource library</description>
<display-name>Mog resource</display-name>
<tlib-version>1.1</tlib-version>
<short-name>res</short-name>
<uri>http://mog.ziro.bz/resource</uri>

<function>
<description>
resource bundle get
</description>
<name>get</name>
<function-class>bz.ziro.mog.jsp.Resource</function-class>
<function-signature>java.lang.String get(java.lang.String)</function-signature>
<example>
${f:get(param)}
</example>
</function>

</taglib>


で作成したところにあるfunction-classを生成します。


package bz.ziro.mog.jsp;

import java.util.ResourceBundle;

public final class Resource {

private static ResourceBundle resources = ResourceBundle.getBundle("application");

public static String get(String aKey) {
return resources.getString(aKey);
}
}


ResourceBundleの生成に使っている"application"はクラスパス+名称になります。
のでこの設定だとクラスパス直下にapplication.propertiesやapplication_ja.propertiesを
作成しておきます。※ResourceBundleは国際化されています。



<%@taglib prefix="res" uri="http://mog.ziro.bz/resource"%>

${res:get("mog.l.title")}


で表示することができます。
uriに指定するのはtldのuriに記述したURIです。
こういうtaglib作成があるんですね。Slim3のFunctionを参考にさせてもらいました。

TDDってもんを完全に守ったこともない僕にはまだまだ。。。
それでもコミッタを夢見るの巻きでした。

2009年5月25日月曜日

Slim3Struts廃止・・・

Struts本命の僕には悲しいニュースです。

ただ。。。

Seasar Conference 2009 Spring - 6/13(SAT), Tokyo

ここで面白い話が聞けそうです!
ちょっくら行く予定です。

2009年5月23日土曜日

HTMLにFlashを埋め込む

http://code.google.com/p/swfobject/

からswfobject.jsを取ってきて読み込みます。


<script type="text/javascript" src="assets/js/swfobject.js"></script>
<div id="flashcontent_container">
FlashPlayerがない
</div>


JavaSctiprなどで埋め込みます。


var so = new SWFObject("MogPlayer.swf", "MogPlayer", "260", "400", "9");
so.addParam("allowScriptAccess", "always");
so.addParam("menu", "false");
so.addParam("scale", "noscale");
so.setAttribute("id", "playerWrapper");
so.write("flashcontent_container");

SWFID = "playerWrapper";

FlexでRadioButton

Flexでラジオボタンを設定します。


<mx:RadioButtonGroup id="answer"/>
<mx:RadioButton id="answer1" groupName="answer" value="1" label="選択肢1" width="100%"/>
<mx:RadioButton id="answer2" groupName="answer" value="2" label="選択肢2" width="100%"/>
<mx:RadioButton id="answer3" groupName="answer" value="3" label="選択肢3" width="100%"/>
<mx:RadioButton id="answer4" groupName="answer" value="4" label="選択肢4" width="100%"/>


でラジオボタンを作成します。
その後スクリプトなどでRadioButtonGroupで指定したIDのselectedValueを利用して
どれが選択されているかがわかります。


if ( nowAnswer == answer.selectedValue ) {
Alert.show("正解!");
} else {
Alert.show("ブー");
}

2009年5月16日土曜日

Javaでセッション管理

JavaのWebアプリでオブジェクトをセッションに
登録、削除した時にイベントを発生する場合
HttpSessionBindingListenerをimplementするとイベントを発生することができます。


public class Account implements HttpSessionBindingListener {

@Override
public void valueBound(HttpSessionBindingEvent arg0) {
}

@Override
public void valueUnbound(HttpSessionBindingEvent arg0) {
}
}


って感じです。

DataNucleusでJDBC接続

datanucleus.propertiesを作成して

javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.jdo.JDOPersistenceManagerFactory

javax.jdo.option.ConnectionDriverName=org.hsqldb.jdbcDriver
javax.jdo.option.ConnectionURL=jdbc:hsqldb:hsql://localhost/sealion_db
javax.jdo.option.ConnectionUserName=sa
javax.jdo.option.ConnectionPassword=
javax.jdo.option.Mapping=hsql


クラスパスのトップにおいて

private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("datanucleus.properties");
public static PersistenceManagerFactory get() {
return pmfInstance;
}

でPersistenceManagerFactoryを取得します。

これと同様にMETA-INF/jdoconfig.xmlを作成して

<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">

<persistence-manager-factory name="transactions-optional">
<property name="javax.jdo.PersistenceManagerFactoryClass"
value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>


と行います。
その場合は

private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
public static PersistenceManagerFactory get() {
return pmfInstance;
}

って感じになります。
何個もセッションを用意する場合は、指定子(transactions-optional)を
変更して追加します。

2009年5月15日金曜日

HSQLDBとDataNucleus

hsqldb-1.9.0-alpha2を使ってたら
スキーマを作成するところで

java.sql.SQLException: unexpected token: NULL

と出ます。
DataNucleusのせいだと思っていたのですが
良く調べたら、create tableで

"NAME" VARCHAR(256) NULL,

みたいな指定ができないようです。
何か久々に無駄につかれた。
※同時に2個調査しようとするのが悪い

2009年5月11日月曜日

DataNucleusをEclipseで使う

GAEだと勝手にEnhancerが動作していますが
JDOを単独で使うと都度「実行」を行っていました。
・・・しかしなんかあるだろうと思ったら本家にありました。

http://sourceforge.net/project/showfiles.php?group_id=222750&package_id=273215

ここからJARをダウンロードしてきて
Eclipseのpluginディレクトリに追加します。
Eclipseを再起動するとプロジェクトの右クリックに
「DataNucleus」が追加されます。




この画像の通り、AddするとDataNucleusがサポートされます。
その後Autoを設定しておくと更新ごとにEnhanceしてくれます。
※プロジェクトの設定でLog4Jのファイルを変更しないとエラーが出ます。

スキーマなどもここで動作します。
これで少し開発が簡単にいくかな?
※POJOからxmlファイルの作成もしてくれそうですね。

2009年5月9日土曜日

DataNucleusを動かしてみる

GAEやSlim3を動作させてきました。
せっかくなのでSlim3を生で使いたいと思い立ちました。
Hibernate,S2DAOなどを使って。。。と思いましたが
せっかくなのでDataNucleusを使ってHSQLDBにアクセスしたと思います。
※とは言ってもサンプルです。

まず、DataNucleusのページから
http://sourceforge.net/project/showfiles.php?group_id=222750

・core
・rdbms
・enhancer
・sample

をダウンロードしてきます。

ObjectWebのASMサイトから
http://forge.ow2.org/project/download.php?group_id=23&file_id=9309

・asm

をダウンロードしてきて

Log4Jから
http://logging.apache.org/log4j/1.2/download.html

・Log4J

をダウンロードしてきます。
ApacheJDOから。。。といきたいところですが
JDOの2.3が必要ですので
http://www.datanucleus.org/downloads/maven2/javax/jdo/jdo2-api/

・JDO

をダウンロードしてきます。
HSQLDBから
http://sourceforge.net/project/platformdownload.php?group_id=23316&sel_platform=14519

・HSQLDB

をダウンロードしてきます。

JDOの2.3ってGAEでも使ってるんですけど良いんでしょうね。
※SNAPSHOTからea(アーリーアクセス?)に代わってますね。

解凍してきたHSQLDBの
demo/runServer.bat実行してDBを立ち上げます。


で、DataNucleusのsampleを解凍してeclipseに展開します。
でダウンロードしてきたそれぞれのjarをlibディレクトリなどに展開。
jarをクラスパスに追加してMainを実行します!



・・・・あれ?うごかない。。。
って調べていたら
JDOの設定ファイル「package.jdo」がない。。。
あれ?ormファイルならある。。。なんかの仕様変更ですかね。。。


http://www.datanucleus.org/products/accessplatform_1_0/guides/jdo/tutorial.html

にあるjdoファイルをコピーして作成します。
・・・それでも実行してもダメでした。

buildファイルなら実行可能なんですが、、、
GAEで見たことあるような、、、

おー!Enhancerですね。


「org.datanucleus.enhancer.DataNucleusEnhancer」を
「src\java\org\datanucleus\samples\jdo\tutorial\package.jdo」を引数にして
実行する必要があります。


・・・これで実行できますがこれは何の為にやってるんだか。。。

ひとまずこれで実行可能になります。
さぁ開発開始だぁー!

2009年5月7日木曜日

JDO関連のデプロイ後の遅延



GAEのアプリケーション管理画面の
「DataStore」→「Indexes」を見ると画像のような画面が出ます。
ここの「Serving」が「Building」ってなってると
パーシスタントクラスの関連を構築中だって意味になります。

こないだやった時は半日(途中睡眠があるのでもう少し早いかも)かかりました。
デプロイした後試せるのは結構時間がかかります。

http://code.google.com/intl/ja/appengine/kb/general.html#indexes

ここにいろいろ書いてあります。

Slim3でディレクトリを表現

Slim3では設定ファイル「slim3_configuration.properties」に


slim3.controllerPackage=bz.ziro.mog.slim3.controller
slim3.viewPrefix=/WEB-INF/jsp


という風にパッケージとJSPのディレクトリを記述して
URL(ディレクトリ)を表現していきます。
デモアプリにもあるように。。。なんかいっぱいコントローラーが出来上がってくると

・管理が煩雑になるのでは。。。
・いやいやきっと抜け道がある。。。


・・・後者でした。
「mng」というディレクトリを作ってその下に
アプリケーションを画像の通りに構築します。




「/mng/」にアクセスすると、MngControllerが動作してくれます。
※JSPは「mng下にファイルです」
「/mng/shop/」にアクセスすると mng.ShopControllerが動作してくれます。
※JSPは「mng/shop下にファイルです」

やっぱこのくらいのことは考えてあるんですね。

GAEにデータを保存


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト



さて、Slim3を手に入れ、Strutsでアップロードを可能にした私は
ついにデータを保存するということに挑戦。
っていうか簡単なんですけどね。

単純にBlobデータを使いました。
ファイルをアップロードして
FormFileからInputStreamを取り出して
ByteArrayOutputStreamを利用して


ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream stream = aFile.getInputStream();
byte[] buffer = new byte[8192];
//終了まで読み込み続ける
while (stream.read(buffer) != -1) {
baos.write(buffer);
}
Blob imageBlob = new Blob(baos.toByteArray());


[com.google.appengine.api.datastore.Blob]ですね。
を生成します。

これをJDOで永続化してBigTableに保存します。

でそれを検索して


Image image = getPersistentImage(Long.valueOf(shopId),Long.valueOf(imageId));
Blob blob = image.getImage();
rtnByte = blob.getBytes();


※ImageってのはBlobを保存したパーシスタントクラスです。

取得します。
これをストリームに描きだしたりすると画像が出ます!

Blobを見た時からこれをやりたかったんですけどね。
Slim3の力を借りてここまでたどり着きました!

2009年5月5日火曜日

ひとまずGAEでSlim3を動かしてみよう!


すでにこの設定などは古くなっている可能性があります。

Slim3の開発はこんなブログより正式ドキュメントが有効です。
Slim3サイト
非公式と言われていますが充実した日本語サイトもあります。
Slim3日本語サイト



GAEでSlim3の使い方をやってみます!

みなさん。SVNでアクセスは可能ですか?
http://slim3.googlecode.com/svn
だったら上記にリポジトリパスを設定しましょう。
※eclipseっす。



ここから「slim3-demo」チェックアウトして、
後はGAEでデプロイするだけです。

※アプリケーションIDは自分のアプリケーションに設定して、
 バージョンも1つにしましょう。


思いのほかデプロイが簡単でびっくりしています!

2009年5月4日月曜日

押してもだめならSlim3化

GAEにてファイルアップロードを行っていました。

ひがやすを氏がStrutsでのファイルアップロードを成功したようで
オープンソースらしいので少しお知恵を拝借しようと。。。
http://d.hatena.ne.jp/higayasuo/20090411/1239460908

と思い少しソース(+ブログ)を眺めていたら。。。
「俺は一体何をしているのだろうと。。。」
と思ってしまいました。
※ちなみに「S3MultipartRequestHandler」を利用して
 やっているみたいですね。
久々にソース(+ブログ)に感動しました。

Seasarには結構前にトライしましたが
客先に乗せるのは困難だと判断して少し離れていましたが
Slim3の考えには賛同できる気がします。


ってことでソースを借りるのではなく「On」させてもらおうと。。。
まぁ挫折の可能性は高いですが。。。

2009年4月30日木曜日

久し振りの間隔

最近JDOを触っています。
GAEを触ることがきっかけで行い始めましたけど、
電子工学を習ったころ、
プログラミング初のオブジェクト指向、
Webを触り始めた頃、
ハードウェアを触り始めたころ。。。
その辺りの新鮮さを感じているところです。

新しいというより、、、
なんか今まで習ってきたことを復習させられていて
楽しい感じに近いです。

ん。。。いいっすね。

2009年4月29日水曜日

GAEのバージョン管理

ローカルでの動作確認もありますが
デプロイした状況での確認も必要になります。

そこでデプロイのバージョニングを行います。

http://appengine.google.com/にアクセスすると
自分のアプリケーションの管理画面になると思います。
対象のアプリケーションを選択して
右にあるVersionsをクリックすると




という画面が出力されます。
ここのバージョンはeclipseのプロジェクトの設定で
[Google]→[App Engine]でデプロイメントのバージョンになります。
※1~の整数を指定します。

指定したバージョンでデプロイして
上記画面で右にあるURLでテストが行えます。
ちなみに初めて試した時に例外を見事発生させました。

JDOの1対多

結構はまりました。
ここにあるようにバグにより
親のオブジェクト、子のオブジェクトのキーはKeyにする必要があるようです。
※子は仕様にも記述してありますけどね。

まず親側のクラスを


class Shop {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;

@Persistent(mappedBy = "shop")
private List<Image> imageList;

・・・getter,setterは未記述

}


と記述します。
Keyは通常のIDENTITY(Longで自動設定した場合)と同一で、特に登録などの際に
設定する必要はありません。

そして子のクラスを


class Image {

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;

@Persistent
private Shop shop;
・・・getter,setterは未記述
}


というように記述します。

で登録は以下のようにします。


PersistenceManager pm = SessionManager.get().getPersistenceManager();
Transaction tx = null;
try {
String id = mogForm.getId();
Long lngId = Long.valueOf(id);

tx = pm.currentTransaction();
tx.begin();

log.warning(id);
Shop oldShop = pm.getObjectById(Shop.class, lngId);

List<Image> imageList = oldShop.getImageList();
if ( imageList == null ) {
imageList = new ArrayList<Image>();
}

imageList.add(image);
image.setShop(oldShop);

tx.commit();
} finally {
if ( tx != null && tx.isActive() ) {
tx.rollback();
}
pm.close();
}


Shopを検索してImageListを取得して
そこに追加を行ってコミットをかけています。
トランザクションをかけてあげないとエラーになります。
このクラスを登録するというより、親に追加して更新しているイメージです。
※子の追加でも可能かは検証してません。

扱っているShopクラスのidの値は
KeyクラスのgetId()により取得したLong値(Stringで使ってる)になります。
そのまま使用すると"Shop(4)"みたいな値になって検索の際にエラーになります。


・・・あぁ。。。やっとこさ関連が実装できた!

2009年4月26日日曜日

JDOで削除

JDOのオブジェクトを削除します。


PersistenceManager pm = SessionManager.get().getPersistenceManager();
try {
Shop oldShop = pm.getObjectById(Shop.class, Long.valueOf(id));
pm.deletePersistent(oldShop);
} finally {
pm.close();
}


更新時と同じくgetObjectById()でオブジェクトを取得して
deletePersistent()で削除を行います。

簡単ですね。

JDOで更新

JDOで更新を行います。



String id = mogForm.getId();
PersistenceManager pm = SessionManager.get().getPersistenceManager();
try {
Shop oldShop = pm.getObjectById(Shop.class, Long.valueOf(id));

String name = mogForm.getName();
String detail = mogForm.getDetail();
String url = mogForm.getUrl();

oldShop.setName(name);
oldShop.setDetail(detail);
oldShop.setUrl(url);
oldShop.setEditor(user);
oldShop.setEditDate(new Date());

} finally {
pm.close();
}


getObjectById()を利用して検索を行います。

取得してきたオブジェクトを更新してclose()するだけです。
簡単ですね。

Keyを利用した検索もあるみたい。※それは後日

2009年4月25日土曜日

GAEでオブジェクト比較

GAEでログインしたユーザだけのデータを表示したい。

そう思い立ちました。。。がっ!
JDOのオブジェクト比較にSQLってどうするんだろ?
と思い立ちしばし、、、

でできました。


UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();

PersistenceManager pm = SessionManager.get().getPersistenceManager();
Query query = pm.newQuery(Shop.class);

query.setFilter("creator == crrentUser");
query.declareParameters("com.google.appengine.api.users.User crrentUser");

try {
List<Shop> shopList = (List<Shop>)query.execute(user);
for ( Shop oldShop : shopList ) {
Shop newShop = new Shop(oldShop);
shopForm.addShop(newShop);
}
} finally {
query.closeAll();
}


Query::setFilter()でSQLイメージを作って
Query::declareParameters()で型を宣言します。
Query::execute()で比較するオブジェクトを設定しておきます。

これでOKですね!
ログインしたユーザのみの機能もこれでOKですね。

ひとまずSingleton!

さぁ、ひとまず、GoogleAppEngineの
データベースを使うにはSingletonパターンを勉強しましょう!

データベースのリソースを極力使わないのが
システム設計の基本なんですが
まず最初に行わなければいけないのは


package bz.ziro.test.jdo;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

public class SessionManager {
private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
public static PersistenceManagerFactory get() {
return pmfInstance;
}
}




です。
こうすることで


PersistenceManagerFactory pmf = SessionManager.get();


使うことができます。



いやぁ。。。JDOを真面目に勉強してたらびっくりしました。
JDOってJavaの規格なんですね。。。
それでjarを拾いにいったらApacheで
そのjarだけでは実装できませんって言われて
やばっ!って思ってたら
googleもdatanucleusっていうやつを使ってるんですね。
※ってよく見たらreferenceにも書いてありました!!

ん~やっぱGoogleさんの考えてることはわからん、、、

2009年4月23日木曜日

GAEでStruts

さて我が心のフレームワークStruts1.3を
GAEで展開したいと思います。

えーと。。。ひとまずblankアプリからですかね?
まずStrutsのappをおとしてきて、blankのwarを展開します。

で、、、展開したディレクトリから
jspはプロジェクトのwar下に置きます。

index.jspとpages/Welcome.jsp

WEB-INF下のlibとxmlファイル3つ。。。
web.xmlは上書きするかはお任せします。

これらを展開します。

でsrc下にある「MessageResources.properties」をsrcにコピーします。

でappengine-web.xmlに

<sessions-enabled>true</sessions-enabled>

を追記します。


でデプロイ。これで動作します。


。。。素直にGWTにするべきか悩ましい。。。

2009年4月21日火曜日

JDOで保存と検索

さぁGAEでデータベースを取り扱ってみましょう!

JDOを利用して行うことができるようです。
JDOは。。。平たく言うとオブジェクトを保存できる仕組みとでもいいましょうか。。。

下準備は「src/META-INF」に
jdoconfig.xmlを準備する必要があります。

これはeclipseのプラグインでプロジェクトを作成した場合に
勝手にできあがってるみたいです。


それとパーシスタントクラスを準備する必要があります。
このクラスはPOJOと呼ばれる単純なクラスを準備します。


import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.users.User;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Project {

@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@PrimaryKey
private Long id;
@Persistent
private String name;
@Persistent
private String detail;
@Persistent
private User creator;
@Persistent
private User editor;

・・・・(getter と setterも準備)
}


残したいデータを準備するのですが
大事なのは「@~」っていう記述方法です。
アノテーションと呼ばれるコメントにより、特性を決める技術です。


@PersistenceCapable(identityType = IdentityType.APPLICATION)
でこのアプリケーションで一意であるデータということ

@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
保存対象でありIDENTITY(一意)であるということ

@PrimaryKey
プライマリーであるということ

@Persistent
保存対象である

ということを意味します。


さぁこれで保存する準備はできました。
画面を作成して保存して一覧に出すようにしてみましょう!

まず実行するJSPを準備


<form name="testForm" action="./JDOServlet" method="post">
<input type="text" name="name">
<textarea name="detail"></textarea>
<input type="submit">
</form>


まぁ普通のHTMLファイルでもOKですね。
でJDOServletをweb.xmlに記述します。


<servlet>
<servlet-name>JDOTestServlet</servlet-name>
<servlet-class>bz.ziro.test.servlet.JDOServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>JDOTestServlet</servlet-name>
<url-pattern>/secure/JDOServlet</url-pattern>
</servlet-mapping>

※servletタグとservlet-mappigタグは順番に並べてください。

で少し長いですがサーブレットは以下のようになります。
※折りたたんであるので広げてください。


public class JDOServlet extends HttpServlet {

/**
*
*/
private static final long serialVersionUID = 1234131818439520488L;

private static PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional");
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();

String name = req.getParameter("name");
String detail = req.getParameter("detail");

Project project = new Project();
project.setName(name);
project.setDetail(detail);
project.setCreator(user);

PersistenceManager pm = pmfInstance.getPersistenceManager();
try {
pm.makePersistent(project);
} finally {
pm.flush();
}

Query query = pm.newQuery(Project.class);
try {
List<Project> projectList = (List<Project>)query.execute();
PrintWriter writer = resp.getWriter();
resp.setContentType("text/html");
if (projectList.iterator().hasNext()){
writer.println("<table>");
writer.println("<tr>");
writer.println("<td>id</td>");
writer.println("<td>name</td>");
writer.println("<td>detail</td>");
writer.println("</tr>");
for ( Project pro : projectList ) {
writer.println("<tr>");
writer.println("<td>" + pro.getId() + "</td>");
writer.println("<td>" + pro.getName() + "</td>");
writer.println("<td>" + pro.getDetail() + "</td>");
writer.println("</tr>");
}
writer.println("</table>");
} else {
}
} finally {
query.closeAll();
}
}
}


まずProjectのオブジェクトを準備しています。
でPersistenceManagerでmakeします。
これがinsert行為になります。

まだpmは使うのでflushだけして
Queryクラスで一覧を取得してきます。
このQueryクラスでwhere文やlimit文、Order文などを記述します。

でPrintWriterでHTMLに記述をしています。


さぁベタな文法ですがいかがだったでしょうか?
※PMFなどをSingletonパターンを利用しないと
 もう一回インスタンスを取得するとExceptionになります。

http://gae.ziro.bz/secure/test.jsp

でお試しできます。
※ごめんなさい。Creatorユーザでユーザを保存していますので
 試すとアカウントの情報が残ります。
 間違っても何かに使ったりしませんのでお試しください。

※ごめんなさい。現在はStrutsによる実装になってしまいました。

・・・さてトランザクションとかもやらんとな。。。

2009年4月20日月曜日

GAEで認証アプリケーション(続)

さて情報の取得方法は前項でやりました。

大事なのはアプリケーションを認証で守ることです。
※前項では認証を行っただけ

日頃からJ2EEの認証JAAS使っといてよかった。


<security-constraint>
<web-resource-collection>
<url-pattern>/secure/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>


とweb.xmlに記述すると
/secure/~というURLは認証を通らないといけなくなります。

JSPなどにこのURLに関係するリンクを貼り、押下してみると
認証されないと行けないことがわかります。

なお、role-nameで「*」を指定していますが
アプリケーションの設定で管理者になっている「admin」というロールと
世間一般のGoogleアカウントがあるようです。(こっちは不明)

GAEでGroovy!

はてさて知人がGroovyを使いたいということだったので
何となくですがやってしまいました。

まずweb.xmlに

<servlet>
<servlet-name>GroovyServlet</servlet-name>
<servlet-class>groovy.servlet.GroovyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>GroovyServlet</servlet-name>
<url-pattern>*.groovy</url-pattern>
</servlet-mapping>



を追加します。
って独自クラスを作ろうとしてたら
GroovyにServletてびっくりしました。

servletとservlet-mappingは
まとめて記述する必要があるので
独自のサーブレットがある場合は気をつけて編集しましょう。

でwar/WEB-INF/groovyというディレクトリを作成して
test.groovyファイルを作成します。


html.html {
head {
title "Hello"
}
body {
p "Hello Groovy World!"
}
}




これでデプロイして「ドメイン/test.groovy」でアクセスすれば
Groovy動作が完了しますね。簡単です。


このソースの前にScriptEngineManagerを使って
文字列実行できるかテストしたんですけど。。。。
ScriptEngineManagerってJava6標準なんですね。驚きました。




・・・あー忘れてました。Groovyのjarが必要ですね。
Groovyの本家からバイナリでもダウンロードして
jarをクラスライブラリに追加しないと動作しません。

2009年4月19日日曜日

GAEでJDO

すっごい!!!JDOまで行っちゃうなんて!!!

PersistenceManagerFactoryをSingletonで作成して


・・・ってこれをパッケージングして
自分のクラス構造してたらQueryがあった。。。スゴイ。



うん。すごい。
またJDOについては書きます!

GAEで認証アプリケーション

GoogleAppEngineで認証できるアプリケーションを作成してみましょう!

サンプルにもある通り、

UserService userService = UserServiceFactory.getUserService();
User user = userService.getCurrentUser();


と行うとユーザがログインしているかどうかがわかります。
userがnullの場合はログインしてない状況です。


userService.createLogoutURL(request.getRequestURI()
userService.createLoginURL(request.getRequestURI())


と行うとログイン、ログアウトのパスを取得できるので
それに対してAタグを書いてあげます。

引数の「request.getRequestURI()」は
ログイン後に戻るページですので変更すれば画面の遷移を変えることができます。


ここで彷徨ってしまったのは
独自ドメイン時のログイン画面です。
私の作ったアプリケーションの認証を作成しようとしたら
GoogleAppsの認証画面が出てきました。

「えー独自ドメインは自分のドメインの認証なのっ!」


・・・と勘違いしちゃいましたが違いました。
どうやらアプリケーションを作成した時に


でドメイン認証をチェックしたみたいです。
・・・1時間位さまよいました。。。
逆に考えれば独自認証のアプリも作れるってことですね!




はてさて情報の取得やログインへの遷移は可能になりましたが
大事なのはアプリケーションのセキュリティです。

・・・ってJAASを使用した方なら簡単ですね。
web.xmlを設定してあげればOKです。


ほぼ
ここと同じだと思いますが
server.xmlはいらないし「manage」っていうロールはないですね。
adminはアプリの管理者がそういう扱いになりそうです。

GoogleAppEngine for Java

先日一部公開されましたGoogleAppEngineのJava版を使ってみましょう。

まずEclipseにプラグインをインストールします。
3.4の場合は以下のサイトでOKです。
http://dl.google.com/eclipse/plugin/3.4

GAEのサイトに行って登録を行います。
※最新情報だとJavaは2万5千人先着?
 まぁどんどん増やしそうですけど。

GAEのサイトで「CreateProject」を行います。
ここで登録するIDはアプリケーションIDとして唯一ですが
後で独自ドメインでの運用も可能になりますので
唯一なら何でもよいでしょう。


その後eclipseでGoogleのアイコンの

「Web Application Project」を作成します。


その次の画面でプロジェクト名はeclipse上での名称、
Packageは作成を行うパッケージを指定します。

GWTを使う時と使わない時で下のチェックボックスをはずして
作成を行います。GWTかGAEのどちらかは必須のようです。
GAEを使わないと。。。多分ただのWebアプリケーションになります。


その後「Deploy App Engine Project」で
公開するわけですが、プロジェクトの設定で
アプリケーションIDを指定して開始する必要があります。
「アプリケーションID」はGAEのサイトで発行したIDです。
認証にはプロジェクトを作成した時のGoogleのIDを指定します。

これだけで完了です。

StrutsのBlankApplicationは動作しましたけど、
Tilesを組み入れたアプリはいまのところ動作を確認していません。
load-on-startupが効かないみたいだからその辺なのかな?

log4jなのも少しダサい気もしますけど。。。
JDOも触ってみましょう!



月間500万PVまで大丈夫。。。って
どれだけのものを作らせようとしているのか。。。
まぁ今のところ使い道はないですけど
何か作りたいですね。

2009年4月10日金曜日

忘れそうなコマンド

ファイルの中身を検索して探すコマンドです。


find ./ -type f | xargs grep localhost


ファイル内部にlocalhostの記述があるファイルを探しています。

2009年3月11日水曜日

Intalioを触ってみる

http://bpms.intalio.com/

少し触ってみます!

2009年1月31日土曜日

OpenLDAPのインストール

ActiveDirectoryでユーザ管理しようと思ったのですが
お金がなかったのでOpenLDAPでユーザ管理しようと思いましたので
インストールを行います。

えーと、、、
OpenSSLとCyrus SASLをインストールする
必要があるようですね。

OpenSSLは
http://www.openssl.org/source/
からダウンロードして解凍して

./config shared
make
make install


でインストールされます。

Cyrus SASLはすでにインストールされている可能性があるので
RPMコマンドで確認して、存在したら2行目のコマンドで削除します。

rpm -qa | grep cyrus
rpm -e --nodeps パッケージ名


CyrusSASLは
ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
からダウンロードして解凍します。

./configure --enable-login --with-openssl=/usr/local/ssl/lib
make
make install

を行います。


でOpenLDAPのインストールは
http://www.openldap.org/software/download/
からダウンロードして解凍します。

./configure --with-cyrus-sasl --with-tls
make depend
make
make test
make install


で行います。
test時にコネクトエラーで「test000-rootdse 255」みたいなエラーが出ました。
これは「/etc/hosts」の記述がおかしいかららしいです。

192.168.*.* localhost localhost

※*は端末のIPです。
で解決しました。

さて使ってみましょうかね。。。

2009年1月23日金曜日

JSPで画像を表示

簡易的にJSPで画像を作成してみました。


<%@ page contentType="image/jpeg" %>
<%@ page import="java.awt.Color" %>
<%@ page import="java.awt.Font" %>
<%@ page import="java.awt.Graphics2D" %>
<%@ page import="java.awt.image.BufferedImage" %>
<%@ page import="javax.imageio.ImageIO" %>
<%@ page import="java.net.*" %>
<%@ page import="java.io.*" %>
<%

int width=180;
int height=24;

BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setColor(Color.white);
graphics.fillRect(0,0,width,height);
Font font = new Font("SansSerif", Font.BOLD,14);
graphics.setFont(font);
graphics.setColor(Color.black);
graphics.drawString("TEST",5,19);
graphics.dispose();
ServletOutputStream objSos=response.getOutputStream();
try {
ImageIO.write(image, "jpeg",objSos);
} catch (IOException e) {
e.printStackTrace();
} finally {
objSos.close();
}
%>


とあるサービスにアクセスして
文字列を表示する際にJavaScriptだとクロスドメインでエラーになるので
JSPで画像出しちゃえ!みたいな感じの方法です。

2009年1月10日土曜日

PostgreSQLでSQLを取得する


pg_dump -D test_db > /tmp/test_db.sql


これでデータベースの作成されたSQLを取得できます。

PostgreSQLのネットワーク設定

クライアント等からアクセスするとコネクトを拒否されます。

データフォルダにある
「pg_hba.conf」にアクセスするIPを設定。 


#内部からはフルアクセス
host all all 192.168.0.1 255.255.255.0 trust
#アプリケーションサーバからはアクセス可!)
host all all 192.168.0.230 255.255.255.255 trust


と設定し「postgresql.conf」の接続フラグを立てます。


#tcpip_socket = false
    ↓
tcpip_socket = true 

PostgreSQLでデータベースの作成

データベースを作成するには


//データベースを作成
createdb <データベース名>
//データベースを確認
psql -l
//コンソールでログイン
psql <データベース名>


と行います。

PostgreSQLの起動

postmasterでも起動できるみたいなのですが


//起動
pg_ctl -w start
//終了
pg_ctl stop
//強制終了
pg_ctl -m f stop


などで操作します。

2009年1月9日金曜日

MySQLでテーブルのカラムを表示


DESCRIBE mst_image;


でテーブルのカラム一覧を表示します。

MySQLでファイルを実行する


mysql -u root -p "データベース名" < "ファイル名"


でファイルに記述してあるSQLを発行します。

MySQLでパスワード変更

以下でパスワードの変更を行います。


mysqladmin --user=root -p old_root_passward password new_root_password


JDBCなどでアクセスした場合


Client does not support authentication protocol requested
by server; consider upgrading MySQL client


と出る場合があります。
これはサーバとクライアントのバージョンが違う場合に起こります。

その場合、rootなどでmysqlデータベースで

//Hostを使い分けている場合、hostも条件に入れてください。
UPDATE user SET Password = OLD_PASSWORD('password') WHERE User = 'username';
FLUSH PRIVILEGES;

とします。

MySQLをシャットダウンする

以下でMySQLをシャットダウンします。

mysqladmin --u root -password shutdown

2009年1月4日日曜日

MySQLでのユーザ追加

MySQLにユーザを追加します。
Linuxなどでmakeしてインストールすると
サーバ以外の端末で何もできない場合があります。

それはrootユーザのlocalhostアクセスしかできないからです。
よってMySQLのコンソールで以下でユーザを追加します。


GRANT ALL PRIVILEGES ON *.* TO username@localhost
IDENTIFIED BY 'password' WITH GRANT OPTION;
FLUSH PRIVILEGES;


これは「username」というユーザを作成して、
そのユーザはlocalhostから'password'でアクセスする
っていう意味になります。

ALLの部分は全権限を与えるって意味で
*.*の部分はDBやテーブルを指定して行うことができます。
よって細かく指定するには


GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON dbname.* TO 
username@'192.168.24.%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;


って感じで行います。