Java Source Attacherプラグインは便利。

あと忘れないように。。

今はEclipseで実装をしている。JavaAPIを解析したり理解する場合はEclipseでバシバシ飛べた方が便利だから。
で、非常に便利な良いツールを見つけた。


Java Source Attacher」なるプラグインなのだが、選択したライブラリのソースコードを自動ダウンロードしてアタッチしてくれる。
正しいカラクリはわからんけど、Mavenあたりに問い合わせてダウンロードしてくれるんかね?
これ使ってからSWTとJFaceの解析がはかどる。覚えておこう。

clominalで使うGUIツールキットを変えようと思う。

久しぶりのブログということで近況を。(実装や調査に極端に集中し始めるとメモを残すのを忘れてしまうのはなんとかしないと。。)

最後のブログ更新をした後、PaperWorkerはGUIの実装に入った。
が、そこで「あ、clominal使ってみよう!」と思ったのが失敗。
再びclominalをいじり始めたのだが、LinuxIMEの日本語変換ウィンドウがおかしな位置(JFrameの左下)に表示されるのがどうしても我慢できなくなってきてしまった。。
何度か触れているけども、当初、clominalはJavaの標準ライブラリでのみ実装しようと考えていたが、もう限界。。

ではこれをどうやって是正するか。思いつく方法は2つ。

  1. JavaVM側のソースを調査し、パッチを作成、Oracle?とOpenJDKのコミュニティに送付。正式に修正されるのを待つ。
  2. IMEの変換ウィンドウが正しい位置に表示されるGUIツールキットを使用する。


…1は、次のような問題がある。ほとんど過程の話だけど。

  • このバグは大分前から既知の問題としてコミュニティに認識されているにも関わらず修正がなされない。
  • 何かの理由で、修正が難しいのかもしれない。
  • 調査したいけれども、そもそも俺にそこまでガッツリとしたスキルがない。
  • 仮にパッチ作成ができたとしても、どこの馬の骨か分からん人間が送付してきたパッチが採用されるのか?
  • 更に更に仮にめでたく採用されるにしても、正式に反映されるまでにものすごい時間がかかるのではないか。

どう考えても2の方が現実的なので、2つほど試してみた。

まずはJavaFX
Swingの後継として標準ライブラリに組み込まれることもあって、期待をしながらサンプルを作ってみた。
そして俺の期待は見事に裏切られた。
一体全体、Oracleさんはやる気があるんだろうか。。

ないんだろうなぁ。という事で見限り、IBMに擦り寄ることにした。

IBMと言えばEclipseEclipseと言えばSWT/JFace。
このGUIツールキットはIME変換候補ウィンドウを正しい位置に表示してくれた。
まぁネタは割れてたんだけど、それでも今までclominalに採用しなかったのは、やっぱり標準でない事と、OS毎に異なるライブラリが必要になるという点。Deployが大事(おおごと)になりそうなのが嫌だった。Eclipseで必要なライブラリをゴソッと抜き出したら20MBもあるし。。
正直「これでいいのか?」と自問自答してしまうけれども、とりあえずこれで行ってみる。
まぁこうなった以上、Swingよりいいところを探したほうが精神衛生上いいかもしれない。

Import/Export機能を実装した。

場所マスタ(純粋に場所の情報だけを格納するテーブル)、場所データ(場所と人を紐付けているテーブル)を分離したデータ構造を考えていたんだが、やってると次から次へと修正したい事が出てきて困る。

今回も、pw.standard.action.*系のクラスをpw.action.*に、pw.standard.item.*系のクラスをpw.item.*に変更した。
クラスパスが変わるから、当然actionsettingsマスタテーブルに記述されているクラスパスも変更しなきゃならんので、面倒くさいけどアホみたいに手作業でUpdate文を書いて変更していた。
んが、そのうちactionsettingsテーブルのカラムの一つである、argumentsカラムの名称が気にくわなくなってきたのでparametersにしようとしたんだけども、それをやるには一回テーブル削除してもう一回全部のデータを登録しなおしになる。
いや、SQL文でカラム名の変更とかできるんだろうけども、今後のことを考えたら、やっぱりこのタイミングでImport/Exportができるようにしとくのがよかろうと思い、結局PWExportCsvActionとPWImportCsvActionを実装することに。

PWExportCsvActionは、paramtersにSQLファイルを指定しておき、実行時には出力先CSVファイルパスを指定してデータをExportする。

PWImportCsvActionは、paramtersに対象テーブルとマップするPWItemのクラスパスを指定しておき、実行時には入力元CSVファイルのパスを指定してデータを目当てのテーブルにImportする。

実際に動かしてみて、めでたくarguments→parametersに名称変更したテーブルにデータをImportすることができた。

対応しているデータ型はまだ少ない。Int型のカラムとかあったら多分例外で落ちると思うw
といっても、PWConverterインタフェースを各データ型に対応する形で実装したクラスを追加すればそれほど悩むことなく対応できるような作りにしてあるので、必要に応じて増やしていけばいいやと思っている。
エラーはわかりやすく出力された方がいいと思うけども。

さて、住所関連の実装をしていてコマンドラインが少々厳しくなってきた。
そろそろGUIについて考えていこうと思う。

あ。あと、マスタ系に対して「それ以外のテーブル」の呼称も考えないといかんなぁ。みなさん普通はなんてSuffixをつけてるのかねぇ?

PWViewActionの実装完了。

PWViewAction関連の実装完了!Bugfixは随時。
てか、PWListActionじゃなくて、PWViewActionに名前変えた。

そして、やっぱり丁寧語面倒だから書きなぐりでいこう。
なんか自分で読んでて気持ち悪いや。

しかしもっと簡単かと思ってたけど、大分時間がかかったなぁ。
どうしても汎用性を持たせたかった(俺の脳みそで考えられるレベルで)んで、
設定時パラメータ、実行時パラメータの使い方で悩んだ感じ。

さて今後だけども、更にいくつかやりたいことが浮かんできた。
以前書いた帳票やらコメントやらリマインダーやらに追加される。


○「社員マスタ」→「ユーザーマスタ」に変更。

○「住所」について
ユーザーマスタから「住所」カラムを分離する。
もともとPaperWorkerを年賀状の宛名印刷でも使いたいと考えていたのだが、
いざ本格的にこの用途で考えてみると今の構成は適切ではないという結論に至った。
「住所」というデータの性質は「人」に付くべきものではなく、
「住所」は「場所」に付くべき情報であり「場所」に複数の「人」がぶら下がるモデルであるべきだ。
そう考えると「場所マスタ(純粋に場所に関するの情報のみ)」「場所データ(場所と人の紐付け)」
という構成になる必要がある。

<場所マスタ>
UUID(Primary Key)
郵便番号(Unique Key)
郵便番号で特定できない情報(含む番地、部屋番号)(Unique Key)
郵便番号で特定できる情報(Webアクセスできない場合こちらを使用)
建屋名称
責任者・世帯主名(ユーザID)
場所区分(個人宅、企業建屋等)←これも場所区分マスタが必要か?

<場所データ>
場所マスタUUID
ユーザID

こんなイメージか。

PWListActionへの絞り込み機能の方針

ひとまず承認系の依頼・承認・却下の各Actionの実装が終わりました。
相変わらずコマンドラインなので使い勝手が悪いですが。

さて、前回記載した、PWListAction(BasicListActionから名前が変わりました)の条件絞り込み機能について更に考え、真逆に舵を取ることに。

・PaperWorker専用の絞り込みDSLは作らず、SQLのselect文を使う。
・但し、1つのselect文のみ実行するような仕組みを作る。
・このselect文は、ActionSettingsテーブルのargumentsに記述する。
・このselect文にはいくつかの特殊な変数を埋め込むことができるものとする。
 (ex: ログインユーザーID)

何故最終的にSQL文を採用したかというと、機能を追加する人の使い勝手を考えた結果です。
PaperWorker用の絞り込み用DSLを作ったとしても、それは恐らく複雑さに関してスケールしない不完全なDSLになり、どうせ「ここでSQLが使えれば・・・」となるケースが出てくることが目に見えたからです。
柔軟性が何より大事な本機能に関して言えば、制約だらけになるであろうそんなDSLに存在意義はないことに気がつきました。

とはいえ、select文以外が実行されたりすると非常にまずいので、そこら辺はうまく作らないとなぁと思います。
てか、単にPreparedStatementクラスのexecuteQuery()メソッドを実行すればOKなんかな??試してみよっと。

BasicListActionに条件絞り込み機能が欲しい。

承認依頼actionの実装が完了し、現在承認actionを実装中ですが、その過程でBasicListActionに条件絞り込み機能の必要性を感じてきました。
後回しにしてたんですけども。
マスタ一覧のように全部取得するケースは稀で、業務actionになってくるとログインユーザーに該当するデータしか表示しないというケースの方がはるかに多いわけで。

というわけで、BasicListActionに機能を追加するつもりなのですが、標準機能としてどこまで実装するのが適切なのか、そのボーダーラインを探っています。
(「検索」を「動的な絞り込み」と表現するならば、ここで触れているのは設定で持たせる「静的な絞り込み」と言えます。)

柔軟性があればそれに越したことはないのですが、一体どこまで柔軟性を持たせるか。

PaperWorker自体がRDBの使用を前提とした作りになっていますので、もの凄〜く単純に考えればSQL文をそのまま使用すれば事足りるっちゃあ事足りるんですが、おっかないです。
現在、BasicListActionは1つのBeanに紐付く形で実装されていますので、テーブル同士の連結は考えても意味がありません。
なので、単純に条件式だけを記述できればそれでいいのではないかと。

で、その条件式はDSLっぽさが出てくるわけですが、javaDSLは面倒ですね。。

演算子は等号、不等号ぐらいで。あと、AndとOrに相当する演算子も必要か。
個々のトークンは必ずBeanのメンバー変数名であることをチェックしてから使うようなスタイルにすれば・・・大丈夫かな?


承認依頼中の休暇申請の一覧を出したい場合で考えると、

(creatorId=$userId & status='Request')

みたいな感じでしょうか。優先順位の為に括弧は使えるようにしたいなあ。
ちなみにありがちですが、$が付いてるトークンは条件式中で使用できる変数にしたいです。
$nowとか$todayとかも必要になるか。

いや〜、でっかい機能追加だなぁ。やっぱり先に不便だけど承認と却下を実装してしまおうか・・・

承認依頼について

承認機能は「承認依頼」「承認」「却下」の3種のactionがあれば一周回ると思います。
大事なのは、「承認ルート」の扱い方かと。

で、承認依頼ですが、一度実装してみたところなんとなく考えるべき要素が見えてきました。

カスタマイズ可能にするのであれば、承認ルートを作り出すロジックをクラス化しておき、
そのクラスパスを設定で指定する、というスタイルがよろしいかと。
ただし、「標準機能」として提供する場合どういったパターンを用意しておくべきか考えねばなりません。
思いつくのは次のパターンです。

完全自由指定承認してもらいたい人物を選択させるパターン。
回数ベース遡る回数をパラメータ指定し、その回数分上司を遡って承認してもらうパターン。
ロールベース直属の上司から最終承認権限を持っている上司まで遡って承認してもらうパターン。

書いてみて気づきましたが、実行時パラメータは1番目の完全自由指定でいいような気がしてきました。
ただし、設定パラメータ(DBにactionを登録する際のパラメータ)として入力支援としてルートを計算するクラスを指定できる、みたいな。

実際には、指定されたクラスを使って初期値を設定しておき、画面側では必要に応じて承認者の変更を可能にする、という感じになります。

これで行ってみます。

でもま、結局は業務毎に承認ルートを計算するクラスは必要になるんじゃないでしょうかね〜。


※追記(2013/10/14)
とんでもない間違いをしてました。
「承認依頼」と「承認ルート取得」は独立させるべきですね。なんでこんな事に気がつかなかったのか・・・
というわけで、「承認ルート取得」Actionを追加します。
1アクションはシンプルに。