bpm_migrationの起動方法
下記のコードにより、クリックされたリンクに対応するファイルを読み込み、bpm_migrationを起動します。
class BpmScaffoldController < ApplicationController
# (1)
require "rexml/document"
include REXML
def file_list
end
#-------------------------------------------------------------------
# xcdl ファイルを解析して、マイグレーションファイルとモデルクラス
# を生成します。
#-------------------------------------------------------------------
def generate
print "path = #{params[:path]}"
params[:generation_output] = params[:path] + "\n"
# (2)
doc = Document.new File.new(params[:path])
klass_name = "initialization"
# (3) クラス名を取得します
doc.elements.each("component"){ |component|
klass_name = component.attributes["name"]
}
# (4) String型を取得します
column_hash = Hash.new
doc.elements.each("component/attributes/String"){ |string_element|
column_hash[string_element.attributes["position"]] = string_element.attributes["name"] + ":String"
if string_element.attributes["length"]
column_hash[string_element.attributes["position"]] += ":" + string_element.attributes["length"]
end
}
# (5) Time型を取得します。
doc.elements.each("component/attributes/Time"){ |time_element|
column_hash[time_element.attributes["position"]] = time_element.attributes["name"] + ":Time"
}
# (6) ジェネレータへのaction引数を作成します。
arg_action = ""
for i in 1..column_hash.length
#params[:generation_output] += column_hash[i.to_s].to_s + "\n"
arg_action += column_hash[i.to_s].to_s + " "
end
# (7)
generation_output = `ruby script/generate bpm_migration --skip #{klass_name.downcase} #{arg_action}`
print generation_output
params[:generation_output] = "ruby script/generate bpm_migration --skip #{klass_name.downcase} #{arg_action}\n"
params[:generation_output] += generation_output
render :action=>'result'
end
- Rubyでは、REXMLの機能を利用してXMLファイルの内容を解析することができます。
params[:path]に格納されているファイルの絶対パスを使用して、Document.newにより、XMLファイルを読み込みます。- エレメントにおけるStringエレメントを読み込みます。エレメントでは、アルファベット順に変数が並んでおり、AquaLogic BPM Studioで定義した変数の順番はpositionで表わされています。マイグレーションファイルにおけるテーブルの列名の順番を、変数を定義した設計者の順番にするために、positionをキーとしてcolumn_hashに登録しています。
- String型は「名前:String:長さ」の引数としてbpm_migrationに与えます。
- エレメントにおけるTimeエレメントを読み込みます。Time型は「名前:Time」の引数としてbpm_migrationに与えます。
- bpm_migrationジェネレータに与えるためのaction引数を作成します。
- bpm_migrationを起動します。bpm_migrationの起動コードは、例えば下記のように表わされます。
./script/generate bpm_migration mst_shain shain_cd:String:10 shain_name:String:20 kaishi_date:Time
bpm_migrationのソースコード
bpm_migrationジェネレータ
bpm_migrationジェネレータは、下記のコードで表されます。
class BpmMigrationGenerator < Rails::Generator::NamedBase
def manifest
record do |m|
# (1)
m.migration_template 'migration.rb', 'db/migrate',
:assigns=>{:migrate_columns=>actions}
# (2)
m.template 'model.rb',
File.join('app/models', class_path, "#{file_name}.rb")
end
end
end
- migration.rbテンプレートを使用して、マイグレーションファイルを生成します。migrate_columns引数にアクション引数を与えます。
- model.rbテンプレートを使用して、データアクセスクラスすなわちモデルクラスを生成します。
migrationテンプレート
migrationテンプレートは、下記のコードで表されます。
class < ActiveRecord::Migration
def self.up
create_table : do |t|
# (1)
# (2)
t.column :, :string, :limit=>
# (3)
t.column :, :string
# (4)
t.column :, :datetime
end
end
def self.down
drop_table :
end
end
- migrate_columnsからアクション引数を読み込み、それぞれを「
:」で分割し、変数の名前やStringなどの型を解析します。 - 型がStringでかつ長さがcolumn[2]に格納されているならば、
limitに長さを指定した形でt.columnステートメントを生成します。 - 型がStringで長さが指定されていない場合、
limitを指定しない形で、t.columnステートメントを生成します。 - 型がTimeの場合、datetime型のt.columnステートメントを生成します。
マイグレーションの実行
生成されたマイグレーションファイルを使用して、下記のコマンドによりマイグレーションを実行します。
rake db:migrate
ConditionScaffoldによるアプリケーションの自動生成
図3に示されるようにConditionScaffoldを実行し、図4に示されるようにメンテナンスアプリケーションを自動生成します。ConditionScaffoldの詳細に関しては、記事「Ruby on RailsのScaffoldをカスタマイズして使いやすくする」を参考にして下さい。
まとめ
本稿では、AquaLogic BPM StudioのBPM Object変数定義、BPM Scaffold、ConditionScaffoldの順序で連携を行うことにより、BPMで定義した変数に関するマスタメンテナンスアプリケーションを自動生成しました。BPMの記述をRoRなどのアプリケーションへ変換することができれば、設計者とプログラマの連携も取りやすくなるため、生産性も向上すると思います。本稿では、その第一歩として、マスタメンテナンスアプリケーションを自動生成しました。


