ER図 作成ツール Erviz
テキストでテーブル定義を書いて、それを図に変換するという面白いツールを発見
http://www.ab.auone-net.jp/~simply/ja/index.html
http://d.hatena.ne.jp/simply-k/20100702/1278052011
テキストの記述方法がシンプルで出力される図もきれいなので、なかなかよさそう
このテキスト定義をもとにExcelでテーブル定義とか出力できると定義の一元管理ができるのでいいんだけど・・・
JRuby+POIで作れるかな?
Rubyのリファレンスはわかりづらい
http://www.ruby-lang.org/ja/man/html/index.html
言語自体はいいのにドキュメントがだめなせいで損していると思う。
まだRailsのリファレンスのほうがわかりやすいというのはどういうことなんだろ・・・
Redmine0.9.5はキャンセル?
http://www.redmine.org/projects/redmine/roadmap
0.9.5が6/1リリース予定だったのがキャンセルされた模様
また1.0が7/3リリース予定になってるがほんとに出るかなあ
Hibernate Validator
http://www.hibernate.org/subprojects/validator.html
JSR 303: Bean ValidationのRI(Reference Implementation)にもなっている。
アノテーションで制約を設定するようで、かなり使いやすそうな印象
Hibernateの名前が入っているがHibernateなしでも使用できる。
Spring MVCでは、コレを使うことが標準になっているみたい
Tomcat 7 リリース間近
Tomcat 7 RC4まで出てるようですね
http://www.theserverside.com/news/thread.tss?thread_id=60295
Servlet3.0対応とか
JSPからRailsの機能を使う
制御構造にはJSTLが使えるからいいけど、フォームやリンクを生HTMLで書くのは不便なのでカスタムタグを用いて記述したいところ。
いろいろ考えたが、Railsの機能を使いつつタグファイルによるカスタムタグ作成ができたのでメモ。
JSPのエスケープシーケンスを使う
<%や%>はRailsでも使うがJSPでもスクリプトレットとして解釈されてしまう。
これをJSPで解釈されずにRailsに解釈させたい。
そこでエスケープシーケンスを用いて<\%と\%>にすることで、JSPでの解釈を回避できた。
JSPにそのまま書く場合はこんな感じ
<\%= link_to "linkName", :action => "add", :v1 => 3, :v2 => 8 \%>
タグファイルの作成
JSP2.0からは便利なタグファイルの機能があるので、それを使ってカスタムタグを作成する。
まずは/WEB-INF/tags/railsディレクトリを作成し、その中にlink.tagファイルを作成する。
こうすることでJSPの中で以下のようにしてタグを使える。
<%@ taglib tagdir="/WEB-INF/tags/rails" prefix="r"%> <r:link 〜〜〜/>
link.tagの中身をこんな感じで書けば
<%@ tag pageEncoding="UTF-8"%> <%@ attribute name="action" required="true"%> <%@ attribute name="params"%> <%@ attribute name="attrs"%> <\%= link_to "<jsp:doBody/>", {:action => "${action}"<% if(params != null) out.print(", "+ params); %>}<% if(attrs != null) out.print(", "+ attrs); %> \%>
JSPではこうして使える
<r:link action="add" params=":v1 => 11, :v2 => 12" attrs=":id => :someId, :style => 'font-weight:bold'">Link</r:link>
RailsのController実装をJavaで作る
前回でViewにJSPを使えるようになったので今回はController。
とりあえず以下のようなJavaのActionクラスをRailsのControllerにマッピングすることを考える。
package sample; public class SampleAction { public Integer result; public String v1; public String v2; public String index(){ return "test.jsp"; } public String add(){ result = Integer.parseInt(v1) + Integer.parseInt(v2); return "test.jsp"; } }
publicメソッドがRailsのControllerで定義したのと同じような感じで使えるようになればいい。
publicフィールドは入出力に使うこととする。
Rails Controller
JavaActionというJRubyの自作Moduleをjava_action_module.rbファイルとして作成しておいて、RailsのControllerではそれを利用してJavaのクラスで宣言されたメソッドを自動的にマッピングすることを考える。
(このコード自体をJavaで作ることも可能かもしれないが、めんどいのでやめておく)
require 'java_action_module' class PollsController < ApplicationController include JavaAction def initialize add_methods("sample.SampleAction") end end
module JavaAction
さてここからが本題。
Javaクラスのメソッド情報を取得して、Rubyでメソッドを動的に定義できればよい。
また、JavaクラスのフィールドをViewとの入出力で使えるようにする必要がある。
まずは、後でpublicメソッド・フィールドを取得するときのためにMemberにpublic?メソッドを定義しておく。(Javaの既存クラスにメソッドを追加定義するにはJavaUtilities.extend_proxyを使う)
module JavaAction JavaUtilities.extend_proxy "java.lang.reflect.Member" do def public? java.lang.reflect.Modifier.isPublic(self.getModifiers) end end
Method,FieldはMemberインターフェースを実装しているので、Method,Fieldでもpublic?メソッドが使えるようになった。
Javaのインターフェースにもメソッドを追加定義できるのがJRubyの面白いところ。
次は、ViewにJSPを使うためのコード(JSP実行結果の取得)。前回のとほぼ同じ
def jsp(path) writer = java.io.StringWriter.new req = request.env['java.servlet_request'] resp = javax.servlet.http.HttpServletResponse.impl do |method| case method when :getWriter java.io.PrintWriter.new(writer) else logger.warn "method:#{method} called" end end $servlet_context.getRequestDispatcher(path).include(req, resp) writer.toString end
そして、メソッドを動的追加するためのメソッド。
まずは、Javaクラス内で宣言されたpublicメソッド・フィールドの配列を取得する
(.select &:public? の部分でpublicなものだけ取るようにしている)
def add_methods(java_class) clazz = java.lang.Class.forName(java_class) methods = clazz.declared_methods.select &:public? fields = clazz.declared_fields.select &:public?
次に呼び出し元のファイルパスからViewファイルが入ったディレクトリのパスを取ってくる。
(RequestDispatcherに渡すときのパスに使うので/WEB-INF/から始まる文字列になる)
path = caller[0].sub(%r!.*(/WEB-INF/.*/app/).*/(.*)_controller.rb.*!, '\1views/\2/')
Javaクラスのメソッドごとにdefine_methodで動的にメソッドを作成する。
define_methodはModuleのコンテキストで呼ぶ必要があるのでmodule_eval内で呼ぶこととなる。
methods.each do |m| JavaAction.module_eval do define_method(m.name) do
define_methodの中では、まずHttpServletRequestの取得とJavaクラスのインスタンス化をして、
インスタンスのフィールドにリクエストのパラメータを入れて、
インスタンスのメソッド実行をする
req = request.env['java.servlet_request'] instance = clazz.newInstance fields.each do |f| instance.send("#{f.name}=", params[f.name]) unless params[f.name].nil? end page = instance.send(m.name)
最後にリクエストのAttributeにフィールドの名前と値を入れて、JSP呼び出しを行って完了。
fields.each{|f| req.setAttribute(f.name, f.get(instance))} render :inline => jsp(path + page), :layout => true end end end end end
これでとりあえずJavaでのController実装ができることがわかった。
ただし、まだいろいろ課題がある。
バリデーションとかリダイレクトの対応も必要だし、JSPでカスタムタグ使いたいよね
何かフレームワークとか使えるのあるだろうか・・・