• astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その2


    embed-astah.png
    なんとなくアイデアを書いてからもう4カ月。書いたっきり手つかずで放置してたけど、突然やる気になってみた。

    astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その1

    ソースはgithubに。例によって無保証です。
    tckz's redmine_wiki_astah at master - GitHub

    前のエントリに書いたように、astaファイルから図をエクスポートするのは非常に時間がかかる。だから、wikiマクロでは、エクスポート対象astaファイルをDBに記録するだけにした。そして別途cronなどを使ってエクスポート処理を動かす、という流れ。

    主なfeature

    • wikiマクロ、{{astah_diagram}}を追加。
    • astaファイルは、public配下に置いたものまたは、リポジトリに入れたものを指定できる。
    {{astah_diagram}}マクロ

        {{astah_diagram(public:foo.asta, namespace/diagram)}}
    {{astah_diagram(source:/repo/path/foo.asta, namespace/diagram)}}
    {{astah_diagram(option=value...,public:foo.asta, namespace/diagram)}}

    • astaファイル:
      • public:path/to/.asta
        • RAILS_ROOT/public/配下に置いた.astaを指定する。
        • RAILS_ROOT/public/sample.astaなら、指定する値はpublic:sample.asta
      • source:repo/path/to/.asta
        • リポジトリに格納したastaを指定する。プロジェクトにリポジトリがないと意味がない。
        • wikiのsourceリンク展開と同じように記述。
        • リポジトリの直下にあるsample.astaなら、source:sample.asta
    • 図のpath:
      • Asta*で図をエクスポートした際のpathに準ずる。
      • 図や名前空間に「/」が含まれると、エクスポートの際に「_」に変換される。ので、マクロに指定する値も「_」に変換した値とする。他にもあるかもしれないが不明。
    オプション:
    • align=value
      • 埋め込まれた図のIMG要素に追加するalign属性
      • 例:right, left
    • width=value
      • 埋め込まれた図のIMG要素に追加するwidth属性
      • 例:100px, 100%
    • height=value
      • 埋め込まれた図のIMG要素に追加するheight属性
      • 例:100px, 100%
    • target={_blank|any}
      • 埋め込まれた図のIMG要素に追加するtarget属性
      • 別ウィンドウで開くなら_blank

    インストール

    事前に、astah(のGUI)を実行可能な状態に。↓のエントリで書いたように、図のエクスポートにはGUIが動くように、DISPLAYとライセンスを適切に設定する必要がある。
    astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その1

    1. プラグインをRAILS_ROOT/vendor/plugins/配下に置く。

        #{RAILS_ROOT}/vendor/
          plugins/
            redmine_wiki_astah/
    2. redmine_wiki_astah/run-astah.shを環境に合わせて編集する。
        ASTAH_HOME : Astah*を展開したディレクトリを設定。astah-pro.jarがあるディレクトリ。
        DISPLAY    : 当該環境のディスプレイをポイントする。自分ところでは前のエントリのとおり、vncserverを使っている。
    3. プラグインが使うテーブルを準備。
      rake db:migrate:plugins RAILS_ENV=production
    4. Redmineを再起動
    5. 管理者でredmineにログインする。
    6. プラグインの設定画面で'secret key'に適当な文字列を設定する。
    7. 図のエクスポートを定期的に行うようセットアップする。

    図をエクスポートする

    wikiに埋め込まれたastaをエクスポートして実際の図イメージを作成する。
    Astah.export_diagrams()を定期的に実行する必要がある。

    こんな感じで。
    #{RAILS_ROOT}/script/runner Astah.export_diagrams -e production

    エクスポートしたイメージをredmineを実行しているユーザから参照できるよう、実行ユーザに注意。


    おわり


    astaにたくさん図が含まれるとエクスポートに何分もかかってしまう。
    図のID(astaファイル中の内部的なID。APIで取得できる)があらかじめわかっていれば、特定の図だけをエクスポートすることで短縮もできるが・・・・。
    先のエントリに書いたように、大き目の図が多いせいでwikiに埋め込むと小さい。widthを付けることで収まりはよくなるが、リンクをクリックして図だけを表示しないと読み取るのは難しいかも。

    環境:
      CentOS 5.5 i386
        ruby-1.8.7-p299(from source)
          redmine-1.0.0
          sqlite3-ruby (1.3.1)
        sqlite-3.7.0-1
        astah* pro 6.2




  • astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その1

    uc.png

    UMLその他モデルの作図にJudeを愛用している。
    ・・・というかastah*か。

    astah*で書いた図を、emfで(拡大縮小しても綺麗だから)ワードに張り付けるなどしているが、redmineのwikiに埋め込めるといいのにな~と思っていた。
    もちろん画像で出力してからアップロードすることはできるが面倒。
    せっかくリポジトリにastahのファイルを保管しているのだから、最新の図をwikiに自動反映できたら便利そう。

    最近知ったのだけど、PlantUMLというのがあって、一定の記法で書いたUMLを画像にしてくれるOSSがあるそうだ。じゃあ、astah APIでモデルの情報を抜き出してPlantUML記法で吐きだしたらどうか?と一瞬考えたものの、レンダリング結果がastah上の図とはかなり変わってしまうし、APIで取得できない情報が多数あるのでそもそも再現度が低い。

    やはり図の出力はastah*に任せたい。

    jude時代から、コマンドラインで図出力を実行することができるので、これを呼び出したらいいだろう。
    ※細かいことは、インストール先のCommandRunner.htmlに書いてある。

    自分ところで使っているredmineはどれもlinux上で動いているので、できればlinuxサーバで完結させたい。ということでまずは「linux上でコマンドラインで図出力」する手順を検討した。

    ポイントは以下のとおり。
    • コマンドライン図出力を実行するには、DISPLAY(Xサーバ)が必要。
      • APIの場合はXサーバなしでも動くけど、図出力はdisplayが初期化できないと先に進まない。
      • 図出力用のディスプレイという位置づけで、vncserverを使うことにした。
    • astahライセンスをセットアップする必要がある

    1. ディスプレイを用意

    • 図出力を実行するユーザ向けにvncserverのディスプレイを作る。
    • CentOSの場合、yumリポジトリにvnc-serverがあるのでこれをインストール。
    • 実行ユーザで一回vncserverを起動しておく。
      • 各種ファイルのひな型が作成されるのと、vncserverのパスワード設定を一度に出来るから。
        % vncserver

        You will require a password to access your desktops.

        Password:
        Verify:

        New 'somehost:1 (someuser)' desktop is host:1

        Creating default startup script /home/someuser/.vnc/xstartup
        Starting applications specified in /home/someuser/.vnc/xstartup
        Log file is /home/someuser/.vnc/somehost:1.log
    • 上で起動したvncserverはkillしちゃう。
      で、ひな型をちょこっと編集。CentOSの場合、xstartupは以下の内容になっていた。
      twmが動いていると、Xクライアントがウィンドウを作成するときに出現位置をユーザ操作で指定する流れになるので、図出力の自動化においては邪魔になってしまう。ので、twmの行を削除した。xtermも特に必要ないので削除。
      #!/bin/sh

      # Uncomment the following two lines for normal desktop:
      # unset SESSION_MANAGER
      # exec /etc/X11/xinit/xinitrc

      [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
      [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
      xsetroot -solid grey
      vncconfig -iconic &
      #xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
      #twm &
    • システム起動時の自動起動を考慮して/etc/sysconfig/vncserverに設定
      図出力を実行するユーザに合わせて編集。とりあえずディスプレイ番号は2のままにした。ジオメトリはもっと小さくてもいいはず。
      VNCSERVERS="2:someuser"
      VNCSERVERARGS[2]="-geometry 800x600 -nohttpd -localhost"
    • rootでrcスクリプトから起動
      # /etc/init.d/vncserver start
    2. astah*を用意

    • astah*のダウンロードサイトからzipを入手。「JREなし、インストーラなしのアーカイブ」と書かれているもの。
    • 適当な場所にunzipする。
    • 同梱されているastah-command.shは後半がちょいおかしい(pro 6.1.1)ので、ちびっと修正して、とりあえず同じディレクトリに「run.sh」という名前で保存した。実行権限を忘れない。
      #!/bin/sh

      ASTAH_HOME=`cd \`dirname $0\` && pwd`

      INITIAL_HEAP_SIZE=64m
      MAXIMUM_HEAP_SIZE=1024m
      STACK_SIZE=3m

      JAVA_OPTS="-Xms$INITIAL_HEAP_SIZE -Xmx$MAXIMUM_HEAP_SIZE -Xss$STACK_SIZE"

      java $JAVA_OPTS -cp "$ASTAH_HOME/astah-pro.jar" com.change_vision.jude.cmdline.JudeCommandRunner $*

    • ライセンスを配置。
      自分ところはJUDEのユーザライセンスがサポート時効前なのでJUDEのライセンスで。
      $HOME/.astah/professional/JUDE_License_User_Professional.xml
    3. 実行

    • path上にjavaコマンドがあることを確認。なければ適宜pathを通す。
    • 環境変数DISPLAYにvncserverを指定。
      自分はtcshスキーなので以下の通りだが、他のシェルの場合は適宜
      % setenv DISPLAY 127.0.0.1:2
    • 実行
      % /path/to/astah/run.sh -image all -f /path/to/some.asta -o /path/to/dir 

    おわり

    • で、出力されたのが冒頭のpng画像。
    • Windowsで出力したときとフォントが異なるので、見た目の違いはあるけど、元の図がキープされていることに意義はありそう。
    • 元の図が大きくなりがちなので、wikiに張り付けるのに向かないケースも多そう。
    • 図出力にはかなり時間がかかる&出力したい図を指定できない(種類は指定出来る)ので、運用上はcronで出力しておいてどーこーみたいな仕組みも必要っぽい。
    • wikiマクロ的には、.astaファイルと図のpath(名前空間+名前)を指定する感じか。


    環境:
      Windows 7 Ultimate x64
        JRE6 x86
          astah* professional 6.1.1
      CentOS 5.4 x64
        vnc-server-4.1.2-14.el5_3.1
        JRE6 x64
          astah* professional 6.1.1



  • JUDEで FP

    失敗のないファンクションポイント法
    受託開発の見積りをすることがある。

    このフェーズにおいてもJUDEを利用しています。
    以前はモデリングはともかく数字の部分が「KKD(経験・勘・度胸)」だったのだけど、ここ二年ぐらいはファンクションポイントによる見積りにチャレンジしているのです。
    ※機能規模と関連の薄い部分(導入とか利用者トレーニングとかバッファ)は相変わらずKKDだけど。

    • ヒアリングしたメモをマインドマップにざらーっと書き出しつつ、思いついたことをちょいちょい書き足す
    • マインドマップを見返しながらアクターとユースケースを並べる
    • ざーっとエンティティを見出す
    • CRUDを埋める
    • FP計数
    という感じで。

    かなり詳細にシステム像をイメージしないと数字が出せないのが難点といえば難点だけど、どんなものを作るかわからないのに見積り数字が出るってのも変といえば変。
    それに計数を重ね記録することで、(組織/チームとしての)生産性が見えることがわかったのは収穫だったと思う。

    で、

    せっかくJUDEでモデリングしているのだから、これを活かしてFP計数が出来ればなお効率もいいだろう、という話し。
    すでにやっておられる方がいるので今更感はあったのだけど、これも理解を深めるため&自分都合の使い易さのためということで。

    judeユーティリティ

    ■実行環境
     OS: CentOS 5.2 i386
       libxml2: 2.6.26-2.1.2.6
       ruby: 1.8.5-5.el5_2.3
         rubygems: 1.2.0
         libxml-ruby: 0.8.3 (gem)
       JRE: Sun Java 1.6.0_07
         jruby: 1.1.4
         JUDE-Pro: 5.4

    ※注意:プログラムの実行結果について作者はなんら責任を持ちませんので悪しからず。

    このFP計数ユーティリティにおける前提条件は以下のとおり。
    • データファンクション(以下DF):
      • JUDEモデルでいうと以下のいずれかで、属性が1つ以上あるものをDFとみなす。
         <<entity>>なclass
         ERエンティティ
    • DFのファイルタイプ(ILF/EIF):
      • CRUD図で当該エンティティに対する操作の有無で判断、または手動付与
         Rのみのエンティティ→EIF扱い
         CUDのいずれかが設定されているエンティティ→ILF扱い
    • DFのDET:
      • 非PKな属性の数をDETとみなす
      • JUDE APIを jrubyから使う その1 」で書いたようにIdentifierを使ったモデリングをするようにしているので、主キーにはユーザ識別可能なデータは出てこない、とみなしています
    • DFのRET:
      • 考えられるグループを@retアノテーションで列挙する。列挙された@retアノテーションの数をRETとする。
      • ここでのアノテーションとはjavaのアレではなく、JUDEにタグ付き値がなかったころに独自データを付与するため作ったオレオレ表記。
        モデルの定義中の「@アノテーション名(空白)値」という記述部分を抜き出してデータとします。
      • とあるエンティティが「xxx種別」の値で意味合いを制御するようなモデリングの場合に、
         @ret xxx種別が講師の場合
         @ret xxx種別が講師以外の場合
        のようにエンティティの定義に記述することでRET=2と計数します
    • トランザクショナルファンクション(以下TF)は、JUDEモデルでいうとユースケース1つに対応するものとします。
    • TFのファイルタイプ(EI/EO/EQ):
      • TFのCRUD操作から判断させるか手動で付与します
        • RのみのTF→EO
          CUDあり→EI
        • ユースケースに対して@tfアノテーションで明示指定
           @tf eo
           @tf ei
           @tf eq
      • 結果的にCRUDからはEQが出てこないのだけども、全く加工のない操作って少ないのではないかと考えたから
    • TFのFTR:
      • 当該ユースケースのCRUDで操作対象となっているエンティティの個数をFTRとします
    • TFのDET:
      • ここはまだ方式を確立しかねている
      • 現状は、当該TF(ユースケース)の直下に「FP-」で始まる名前のシーケンス図を書き、アクターが発するメッセージから計数することにしています
        例:「FP-社員情報を登録する」みたいな感じで。
      • DET=メッセージ(=トリガ)+操作の引数の個数+返り値の個数
        • 「操作」に対して返り値は1つしか指定できないので、返り値にclassを指定した場合はその属性の数を返り値の個数とします
        • あるいは、返り値ではなく「操作」の「out」パラメータとして記述します

    FP計数周辺に絞った手順

    1. モデリング
    • ユースケースをモデリング
      • TFのDET計数用シーケンス図作成
    • ERモデリング(クラス図でもよい)
    • CRUD表作成してユースケースとエンティティの操作を結びつける
    2. 計数元ネタファイル作成
    • judeファイルからAPIを使ってFP計数に必要な情報を抽出→中間XMLファイル
      ※linuxの操作例
      % env CLASSPATH=./jude-pro.jar jruby ./jude_export.rb -o 出力中間.xml 入力.jude
      

    • 中間XMLファイルからFP計数→TSVファイルに出力
      ※linuxの操作例
      % ./calc_fp.rb -e cp932 -o 出力.txt 入力中間.xml
      

    • TSVファイルを雛形xlsに貼り付けて集計
      • TSVファイルをテキストエディタで開いてコピー&ペースト
      • アーカイブにFP-hinagata.xlsというxlsブックが入っています。TSV全体をコピペで[ファンクション]シートに貼り付けます
      • もし既存の表をはみ出たら適宜書式をコピーしておきます
    3. FP計数
    • 一般システム特性記入
      • [一般システム特性]シートに数字を入れます
      • この辺が参考になります
    • 雛形xlsのピボットテーブル更新
      • [業務単位FP集計]シート
      • [FP概算法]シート
      • [FP試算法]シート
      • FP概算法、FP試算法についてはこの辺を参考にしました。
      • 個人的な感覚では試算法だと数字が離れるなーという印象。rapidに見積もる必要がある、あるいは画面項目を想定するほど情報が揃っていないときは概算法のほうがいいなという感触。


    ファンクションポイント法自体については「失敗のないファンクションポイント法 」という本を参考にしています。
    この本は項目説明が網羅されているだけでなく例示が勉強になります。300ページちょいの本ですが、約200ページを「計測実習」に割いており非常に具体的で参考になります。




  • JUDE APIを jrubyから使う その2

    JUDE 5.3には編集APIのサンプルとしてDBリバースのプログラムが付属しています。
    サンプルといっても十分便利。DB接続可能なときはこれを利用している。


    何かしらのシステムやアプリを引き継ぐと、DDLすら提示されず、「テーブル定義書」「テーブル設計書」といった名称のxlsブックだけ出てくる場合がある。困ったことによくある。
    目視でぽちぽちjudeにエントリしてもいいのだけど、編集APIのプラクティスを兼ねてインポートツールを書いた。

    要するにCSVで記述したERエンティティをjudeモデルとして一括登録、というもの。
    ※注意:judeファイルになんらか問題が発生しても責任を負いかねます。自己責任で。そしてバックアップ or リビジョン管理重要。

    judeユーティリティ


    1. xlsからCSVを作成する
      • 記述例はアーカイブ同梱のsamp1.xlsを参照
      • 「テーブル定義書」のレイアウトは様々。それに合わせて以下のようなCSVファイルを出力するようマクロを調整のこと
        • 1CSVファイル=1エンティティ
        • 1行=1属性
      • CSVファイル内の最初の列が「#」で始まる行はメタ情報行
        • #@entity行
          • 1列目:エンティティの論理名
          • 2列目:エンティティの物理名
        • 次に#で始まる行は各列の値の意味を指定するヘッダ。認識するヘッダは以下の通り
          logicalname属性の論理名
          physicalname属性の物理名
          domain属性のドメイン(の論理名)
          更新対象judeファイル内に同名の論理名を持つドメインがない場合は作成される
          type属性のデータ型
          更新対象judeファイル内に同名のデータ型がない場合は作成される
          length属性の長さ
          nnNOT NULLかどうか
          非空文字ならNOT NULL指定
          default属性のデフォルト値
          pkPRIMARY KEY制約をつけるかどうか
          非空文字ならPRIMARY KEY指定
      • excelがインストールされたwindows上で同梱のmake_csv.jsマクロ実行し、全シートをCSV出力します
        • 出力ファイル名は"シート名.csv"になります。
          シートごとに別ファイルに出力されます

          > cscript.exe make_csv.js samp1.xls
      • 編集APIの仕様で以下の点に注意
        • 論理名のないエンティティは登録できない
        • 論理名のない属性は登録できない
        • 同じ論理名を持つエンティティが既に存在すると登録できない
        • データ型に英小文字を指定しても英大文字になる
          • GUIでは英小文字名称のデータ型を登録できるけど、編集APIでcreateすると大文字になる。
    2. 出来たCSVをjudeファイルにインポートする
      • 実行例

        $ env CLASSPATH=./jude-pro.jar jruby ./import_ermodel.rb --fs=, -o new.jude samp2.csv
        ※インポートのデフォルトのフィールド区切りは「HT」です。--fsでカンマを指定しています。
        ※jude-pro.jarがカレントにある前提
      • 存在しないjudeファイルを指定してもよいし、既存のjudeファイルを指定してもよいです。
        存在しないjudeファイルを指定するとjudeファイルが作成されます。
        新規judeファイルに出力しインポート後の内容を確認して問題なさそうならマージするという手順がいいと思う。
      • 本スクリプトは日本語環境で作成されたjudeファイルを前提としています。
        編集APIサンプルのように createERModel(project, "ER Model");でIERModelを作成すると、日本語環境GUIでマージできなかった。日本語環境GUIで作ったjudeファイルの場合、IERModelの名称が"ERモデル"(これはエクスポートするとわかる)となっていることに関係するのではないかと想像している。

    ■実行環境
     OS: CentOS 5.2 i386
       JRE: Sun Java 1.6.0_07
         jruby: 1.1.4
         JUDE-Pro: 5.3.0

    モデル編集APIは、「図要素」を編集できるようになるとうれしい。図中のモデルの位置だとか大きさ。GUIの自動レイアウトがもうひとつだなぁと感じている。何かしらのレイアウトエンジンを使って独自の整列ができるようになったらかなり素敵だと思うんだけどな。


  • JUDE Community版より Professional版がよいと思うこと

    JUDEには無償のCommunity版と有償のProfessional版がある。
    両者の違いは製品公式ページの機能比較表のとおり。
    結構Community版使ってますみたいなエントリを見かけるんだけども、自分がPro版購入を決めたポイントを並べてみる。
    ※僕はチェンジビジョンの関係者ではありません。

    1. EMF出力できる
      • 特にコピー&ペーストでWord等office文書に貼り付けられるところがいい。
      • ビットマップでなくベクターグラフィックだから、拡大縮小しても印刷しても綺麗。貼り付け先文書内で好きな大きさにできる。
    2. ステレオタイプのアイコンを指定できる
      • 機能比較表ではさらっと書いてあるけど、これはかなりうれしい。
      • boundary(メロンが横になった記号)やactor(棒人間)に帳票や人を示すビットマップを指定すると「普通の人」も見る気になってくれる
        icon.png
      • オブジェクトごとにUML表記/アイコン表記を切り替えられるので、読み手に合わせた作図をしつつ、情報量はキープみたいな使い方。
    3. モデルから関連する図へジャンプできる
      • これ
      • このモデルが使われているあの図はどこだっけ・・、とモデル基点で図を逆引きできるのは地味に便利。
    4. CRUDマトリクスを書ける
      • ファンクションポイント法による見積りのソースに使えてうれしい
      • Com版とPro版の違い、とは関係ないが、CRUDの軸に指定したユースケース図にユースケースを足したとき、ER図にモデルを足したときに、CRUD表の当該モデルに対する行/列が自動で追加されるのは本当にうれしい機能だ。
    5. 別名をつけられる
      • クラスの名前や属性の名前など、日本語表記と英語表記を付けることが出来る。
      • モデリングは日本語で行い、SQL出力など英語表記にしたい部分だけ英語、という使い分けができて助かる
    6. APIの違い
      • ER図(系のモデル)、CRUDの情報を取れるのはかなりのアドバンテージ
    7. プロジェクトをマージできる
      • judeを2つ起動して、片方のjudeからもう片方にコピー&ペースト、ということが「出来ない」ので、その代わりとして使えるから。

    ちょっとした違いかもしれないけど、普段の業務でしみじみ便利だなーと思う瞬間。
    こういう違いを知らずにCommunity版を使ってる人がいたらちょっともったいないな、と思ったので書いてみた。