2009年7月29日水曜日

SimpleModeler 0.1.9

SimpleModeler 0.1.9を先日公開しました。


Google App Engine Javaコード生成の精度を上げています。

2009年6月27日土曜日

関連の格納方法

オブジェクト間の関連の格納方法について考えている。




  • 同じエンティティにまとめる範囲、エンティティ・グループにまとめる範囲
  • 連鎖削除ありなし
  • 同時ローディング、オンデマンド・ローディング
  • 検索対象、対象外
  • DataStoreデータ型で格納する。それ以外のデータ型はString、Textなどにエンコーディング。Javaプログラム上の表現とJDO格納表現がずれるで注意。
  • オブジェクト間に関連については関連、集約、合成、部品で処理方法を調整
  • 属性(attribute)
    • document(またはvalue)をエンティティの属性とする
    • エンティティのカラムに(必要に応じてテキスト、XMLエンコーディングして)格納

  • 関連(association)
    • エンティティ間で連鎖削除はしない
    • エンティティは独立して管理
    • エンティティをロードする時に、関連先エンティティはロードしない。使用時にオンデマンドでロードする。

  • 集約(aggregation)
    • 全体エンティティが削除されても部品エンティティは削除されない
    • 全体エンティティと部品エンティティは独立して管理
    • 全体エンティティをロードする時に、部品エンティティはロードしない。使用時にオンデマンドでロードする。

  • 合成(composition)
    • 全体エンティティが削除されると部品エンティティも削除される
    • 全体エンティティをロードする時に、部品エンティティをロードする。
    • 全体エンティティと部品エンティティでエンティティ・グループを構成する。

  • 部品(part)
    • 部品エンティティはエンティティIDを持たない
    • エンティティのステレオタイプとしてpartを用意(DSLでは定義済み)
    • partは、全体エンティティの部品として使用するオブジェクト
    • 検索対象から外すことによって、全体エンティティのカラムにXMLエンコーディングして格納


2009年6月25日木曜日

SimpleModeler 0.1.8

SimpleModelerは、地道にバージョンアップしていて0.1.7と0.1.8をリリース。

http://code.google.com/p/simplemodeler/
http://code.google.com/p/simplemodeler/downloads/list

現在はGoogle App Engine/Java向けにデータ型まわりを実装中。

以下つぶやき。

Entityの部品をEntityの一部として扱いたい。

Entityの部品をJavaオブジェクトをシリアライズして格納すると持続性に問題がある。

Domain Model - Java - JDO(GAEJ)のギャップを地道に埋めていく。

JDOの基本データ型。これ以外のデータ型も使えないことはないが、できれば使わない方がよい。
  • java.lang.String
  • com.google.appengine.api.datastore.ShortBlob
  • boolean
  • java.lang.Boolean
  • short
  • java.lang.Short
  • int
  • java.lang.Integer
  • long
  • java.lang.Long
  • float
  • java.lang.Float
  • double
  • java.lang.Double
  • java.util.Date
  • com.google.appengine.api.users.User
  • com.google.appengine.api.datastore.Text
  • com.google.appengine.api.datastore.Blob
  • com.google.appengine.api.datastore.Key

2009年5月31日日曜日

SimpleModeler 0.1.6

GWの連休ボケでSimpleModeler開発の日記が何となく滞っている。
ただ、SimpleModelerの開発は進んでいて、5月22日にSimpleModeler 0.1.6をリリースした。

[SimpleModeler 0.1.6]

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

http://code.google.com/p/simplemodeler/downloads/list

SimpleModeler 0.1.6は、AtomPubの自動生成機能を追加した。
-gaej.atomオプションで、AtomPubの参照系のプロトコルハンドラを自動生成する。更新系は折を見てサポートする予定。

serviceに対するGETはこんな感じ。

# curl http://localhost:8080/yorozu/atom/
<service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom">
<workspace>
<atom:title>Entity Repository</atom:title>
<collection href="customer/">
<atom:title>Customer</atom:title>
<accept>application/atom+xml;type=entry</accept>
<categories fixed="yes"></categories>
</collection><collection href="goods/">
<atom:title>Goods</atom:title>
<accept>application/atom+xml;type=entry</accept>
<categories fixed="yes"></categories>
</collection><collection href="buy/">
<atom:title>Buy</atom:title>
<accept>application/atom+xml;type=entry</accept>
<categories fixed="yes"></categories>
</collection>
</workspace>
</service>


collectionに対するGETはこんな感じ。

# curl http://localhost:8080/yorozu/atom/customer/
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Entity Repository</title>
<updated>2009-05-30T22:02:48.010Z</updated>
<id>uuid</id>
<link href="http://localhost:8080/yorozu/atom/customer/" type="application/atom+xml" rel="self"></link>
<link href="http://localhost:8080/" type="text/html" rel="alternate"></link>
<generator uri="http://code.google.com/p/simplemodeler" version="0.1">SimpleModeler</generator>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>ABC(c001)</title>
<id>c001</id>
<updated>2009-05-30T22:02:48.030Z</updated>
<published>2009-05-30T22:02:48.010Z</published>
<link href="c001/" rel="edit"></link>
<content type="application/xml">
<customer xmlns="http://yorozu.com/"><customerId>c001</customerId><customerName>ABC</customerName><phone>045</phone></customer>
</content>
</entry>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>XYZ(c002)</title>
<id>c002</id>
<updated>2009-05-30T22:02:48.030Z</updated>
<published>2009-05-30T22:02:48.010Z</published>
<link href="c002/" rel="edit"></link>
<content type="application/xml">
<customer xmlns="http://yorozu.com/"><customerId>c002</customerId><customerName>XYZ</customerName><phone>06</phone></customer>
</content>
</entry>
<entry xmlns="http://www.w3.org/2005/Atom">
<title>MNO(c003)</title>
<id>c003</id>
<updated>2009-05-30T22:02:48.030Z</updated>
<published>2009-05-30T22:02:48.010Z</published>
<link href="c003/" rel="edit"></link>
<content type="application/xml">
<customer xmlns="http://yorozu.com/"><customerId>c003</customerId><customerName>MNO</customerName><phone>06</phone></customer>
</content>
</entry>

</feed>


memberに対するGETはこんな感じ。

# curl http://localhost:8080/yorozu/atom/customer/c001
<entry xmlns="http://www.w3.org/2005/Atom">
<title>ABC(c001)</title>
<id>c001</id>
<updated>2009-05-30T22:02:34.350Z</updated>
<published>2009-05-30T22:02:34.340Z</published>
<link href="." rel="edit"></link>
<content type="application/xml">
<customer xmlns="http://yorozu.com/"><customerId>c001</customerId><customerName>ABC</customerName><phone>045</phone></customer>
</content>
</entry>

2009年4月18日土曜日

Google Web Toolkit動いた

昨晩、SimpleModelerのGoogle App Engine Java(GAEJ)のGoogle Web Toolkit(GWT)が動き出した。
通常のServlet/JSPのWeb MVC版はすでに動いているので、GAEJ生成器はWeb MVC版とGWT版の2種類の実装を生成することになる。
Web MVCとGWTの双方からGAEJのDataStoreを操作することができる。

GWTは今のところあまり人気がないという話もあるけれど、実際に使ってみるとなかなかよいではないですか。
とっかかりの設定ファイルがやや面倒なのだけれど、こういったところが自動生成でカバーできれば、アプリケーション本体の開発はWeb MVCよりもかなり簡単であるにもかかわらず、Ajaxを使った普通のGUIアプリケーションがWeb上に構築できるというかなり凄い結果を得られる。
普通のJavaオブジェクトを使ったAjaxの非同期通信用の専用RPCであるGWT-RPCも使い方は簡単で、サーバー側の処理を普通にJavaで書けるのもうれしい。
クライアント側とサーバー側の処理をすべてJavaで書いて、Eclipseでデバッグまでできる。
Widgetの部分はプログラマが書いて、Widgetを埋め込むHTMLはデザイナが作るといった分業もJSPとは比較にならないほどスムーズにできそう。
なぜ、流行っていないのか不思議である。

Webアプリケーション技術は新参者なので、事情はよく分からないのだけれど、Webを見てまわると昔は設定が難しいようだったからそういうのも影響があるのかも。でも、GAEJにバンドルされているGWTは特に設定いらずなので、少なくてもこの問題は解消される。

GWTはかなり気に入ってしまったので、SimpleModelerのGAE向け機能はGWTを中心に機能セットを整えていくことにした。

GWT単体でも便利だけれど、自動生成と組み合わせると、これは何ともいえないぐらい強力、というのがSimpleModelerが吐き出したGAEJ+GWTを触ってみた感想。
4月21日(火)のJJUG CCCで、デモしたいと思います。

http://www.java-users.jp/contents/events/ccc2009spring/

2009年4月15日水曜日

Google App Engine Java動いた

昨晩、SimpleModelerのGoogle App Engine Java(GAEJ)が動き出した。
GAEJのSDKでDataStoreの中身を見る方法が分からず、JDOを使うのも始めてなので、疎通が難航することを覚悟していたのだけれど、案外すんなりと動いた。
来週のJJUG CCCでは無事デモができそうである。

2009年4月13日月曜日

Google App Engine Java開発中

先週の水曜(4/8)にGoogle App Engine Javaが公開されたことを受けて、Google App Engine Python向けの機能拡張を保留して、Google App Engine Java向けの開発を開始した。
SimpleModelerではWeb MVCのMをEntity/Service/Documentの構成とするので、全体としてはESDVCとなる。この内、E(Entity)、D(Document)、V(View)は成果物のJavaやJSPがコンパイルできる所まできた。今はC(Controller)とS(Service)の実装中で、これができたら全体をつなげて疎通確認に入る予定。
来週火曜日4月21日のJJUG CCCでは、google App Engine Javaのデモも行いたい。

2009年4月7日火曜日

scala-toolsが落ちてる

今朝、急にmavenのscala-pluginが動かなくなる。

The server hosting scala-tools.org is experiencing a denial of service attack. We expect to have it back up and running really soon now(tm).

だそうです。
でも、-oオプションつけても動かないのは勘弁して欲しいなぁ。
mavenでscala-pluginのバージョン・チェックを回避すればよいかもしれないのだけど、回避方法が分からない。
しばし、待つとしよう。

2009年4月6日月曜日

Dojo Toolkit

Google App EngineのWebアプリケーションでDojo Toolkitを使うようにしてみた。
Dojo Toolkitはかなり大きいので配備の問題が悩ましいなぁと思っていたら、AJAX Libraries APIが使えることが判明。前にAJAX Libraries APIをみた時は今ひとつぴんと来なかったなのだけれど、こうやって実際にWebアプリケーションを作ってみるととても重要なAPIであることが分かった。

Dojo Toolkitはなかなかよい感じ。使い方も簡単で効果も抜群。こういったAjaxライブラリを使うのが、Webアプリケーションを作る際のいまどきの標準ということなのかな。

2009年4月3日金曜日

aggregation



クラウドでは、関連の深いデータをできるだけ近くに配備したいので、個々のデータのメタ情報にそいういった情報を格納する。たとえばGoogle App Engineの場合はデータの親データをKeyに入れているけれど、そういう目的ではないかと思う。
こういった情報の元ネタはモデリングの段階で収集するのが効率的であるけれど、その一つのアプローチがAggregateである。
ただ、「Aggregate Root」というステレオタイプを使うのはややクールでないかなぁ、と思いつつ常々扱いを気にしていたのだけれど、モデル内のaggregationを手繰ってAggregateを自動抽出すればよいことに思いついた。
現在の所SimpleModelerはassociationとcompositionをサポートしているもののaggregationはサポートしていない。というのは、aggregationはモデルの意味・意図が不明瞭であり、使い方が難しい、という評価があるモデルであり、モデル駆動を目指すSimpleModelerでは明確な使い方が見つかるまで、サポートを保留していたのである。
このaggregationを使うと、(ツールがモデルを解析する手間を惜しまなければ)Aggregateを明確に記述できる。Aggregateはクラウド時代にはとても重要なモデルの構成要素でありプラクティスとなるので、このAggregateを成立させるためのモデル要素としてaggregationをサポートする価値は非常に高い。
そのような判断でaggregationをサポートすることにした。
帰宅後、aggregationの実装。同時にcompositionを指定する文法も改良。
無事動作。

折を見て、Aggregateも実装したい。

2009年3月31日火曜日

NetBeans

NetBeansのScalaプラグインの出来がよいとの噂があったので、ダウンロードしてみた。
日本語の識別子には対応していないみたい。がっくし。
SimpleModelerのScala DSLは、IDEのサポートが受けられるとかなり使いやすくなるはずなので、期待してみたのだけれど、日本語の識別子が使えないと現時点では使えないなぁ。

2009年3月27日金曜日

XMLリテラル

Google App Engine用ドメイン・オブジェクトCRUD MVCでは、ScalaのXMLリテラルがとても役になった。

生成するHTMLをXMLリテラルでそのまま記述できる。その上で、「{」「}」で囲んだ所にScala関数を評価した結果が挿入される。そのままテンプレートエンジンである。


  val html =
<html>
<head>
<title>Show {capitalizedTerm}</title>
</head>
<body>
<h1>Show {capitalizedTerm}</h1>

<table class="datasheet">
<tbody>
{
 for (attr <- entity.attributes.toList) yield {
  <tr>
   <td>{attr.name}</td><td>{{{{doc.{attr.name} }}}}</td>
  </tr>
 }
}
</tbody>
</table>

<table class="action">
<tr>
 <td><form action={getActionPath("edit")} method="get"><input type="hidden" name="key" value={getIdCode} /><input type="submit" value="Edit" /></form></td>
 <td><form action={getActionPath("destroy")} method="post"><input type="hidden" name="key" value={getIdCode} /><input type="submit" value="Delete" /></form></td>
</tr>
</table>
  
<table class="menu">
<tr><td><a href={getActionPath("index")}>Index</a></td><td><a href={getActionPath("new")}>New</a></td></tr>
</table>

</body>
</html>


作成したXMLをテキストとして出力するのはこんな感じ。


XML.write(out, html, entityContext.textEncoding, false, null)


ScalaのXMLはこの他にも色々便利な機能がある。
Web系のプログラムだと何かとXMLやHTMLを使うことが多いので、言語ネイティブのXMLサポートは重要ですね。

2009年3月26日木曜日

Google App Engine CRUD MVC動いた

SimpleModelerドメイン・オブジェクトに対するGoogle App EngineのCRUD MVC&Serviceが動いた。ふぅー。
Model, Serviceに加えて、ViewとControllerも自動生成できるようになった。

Web MVCの自動生成器を作ってみて、Webアプリケーション開発が大変なことを実感。
ここが自動作成できたら、かなり便利なはずである。

今はCURDの範囲だけれど、もう少し自動生成の範囲を広げることができると考えている。
この実現のメカニズムとしてdocumentとstateMachineを作りこんできた。また、昨日書いたように画面遷移モデルをサポートすればさらに自動生成の範囲が広がる。
ここからは先が長そうなので、様子を見ながらぼちぼち取り掛かることにしたい。

2009年3月25日水曜日

Google App Engine MVC

次の組合せでGoogle App EngineのMVC&Serviceが動いた。ふぅー。

Model: 自動生成
Service: 自動生成
View: 金型
Controller: 金型

すっかりPythonプログラマである。
次は、金型をSimpleModelerに取り込んで自動生成する処理の開発。
4月21日のJJUG CCCでデモできそう。

Webフレームワーク

Google App EngineのWebフレームワークとGoogle App Engine Oil(GAEO)を調査している。
GAEOでURLとMVCの実装を:controller/:actionのコンベンションに結び付けている部分が面白い。一種のリンカですね。
本家のRuby on Railsは:controller/:action/:id.:formatというコンベンションのようだけれど、こういったURLと実装の動的リンク機能(何か名前がついているんだろうなー、以下ではURLルーティングと呼ぶことにする)がRuby on Railsの柱の一つであり、これをGoogle App Engine(GAE)で実現しようとしているのがGAEOということである。
GAEOのCRUD VC自動生成はまだまだ発展途上だと思われるけれど、このURLルーティング機能は現時点でもかなり使える。

と、ここでSimpleModelerのGAE生成器だけれど、GAEOに全面依存するのもリスクがあるので、gaeサービスではGAEのみを使うようにしようと思う。URLルーティングも簡単なものを自前で実装することにする。
これとは別にgaeoサービスでは、GAEOのURLルーティングを活用したプログラムを自動生成することにしたい。

調べてみるとWebのこのあたりの技術はなかなか面白い。こういった処理を実装する場合、メタ・プログラミングを使ってコンベンションによる動的リンクが非常に有効なのでPythonやRubyのような動的言語が大人気なのもよく分かる。
ただ、こういったWeb MVCの実装は、自動生成の格好の対象であることも感じた。
単純な繰り返しのプログラミングは、コンベンションと動的リンクで解決することも可能であるけれど、プログラムの自動生成で解決することも可能である。
プログラムの自動生成をするのであれば、ターゲットのプログラミング言語は静的型付のものでよい。つまり、自動生成を前提にするとテーゲット言語はJavaのみでも、Ruby on RailsやPython Djangoと同等のWebアプリケーションの開発効率が得られると思われる。
開発言語がJava指定の案件でも、Ruby on RailsやPython Djangoと同等の開発効率が得られれば魅了的である。

そうはいっても、RubyやPythonを主力言語として開発している人がわざわざJavaをやるというのも考えにくいので、結局の所、色々な言語の色々なWebフレームワークが並存することになるだろう。顧客が指定するWebアプリケーションの言語やフレームワークも多極化することになるだろうから、どのような組合せであっても対応できるのが開発者側のスタンスとしては望ましい。
こういったニーズに対してSimpleModelerのようなモデル・コンパイラは有力なソリューションである。

今回、Webフレームワークを調べてみて、SimpleModelerでかなりの部分を自動生成できるように感じた。ただし、ユースケースやドメイン・モデルから自動生成できるという意味ではなくて、システム・モデルとして画面遷移モデルなどの専用PIMモデルを定義すればである。
Webのフロントは開発工数も大きい上にバグの出やすいところでもあるし、要件定義から実装までの各段階で試行錯誤が必須の部分なので、PIMモデルからの自動生成ができれば、その効果は計り知れないだろう。
SimpleModeler的には、Scala DSLで定義した専用画面遷移モデルから、画面遷移図と各種Webフレームワーク向け実装の自動生成の機能ということになる。画面遷移モデルとドメイン・モデル、ユースケース・モデルとの連携は確保すれば、上流モデルからWebフレームワーク向け実装まで一気通貫で開発することができる。
GAEが一段落したら、SimpleModelerをそちらの方向に延ばしてみようかな。

2009年3月24日火曜日

GAEOのMVC遷移

メモ。

GuestbookController
==create
====r.put()
====/guestbook

==destroy
====Guestbook.get()
====r.delete()
====/guestbook

==edit
====Guestbook.get()
====template/guestbook/edit.hml
======/guestbook/update

==index
====Guestbook.all()
====template/guestbook/index.hml
======/guestbook/new
======/guestbook/show?key

==new
====template/guestbook/new.hml
======/guestbook/create

==search
====?

==show
====Guestbook.get()
====template/guestbook/show.hml
======/guestbook/edit?key
======/guestbook/destroy?key

==update
====Guestbook.get()
====r.put()
====/guestbook

コントロール、サービス、ドキュメント

週末にPythonと格闘してGoogle App Engineの金型をつくったので、これをベースにSimpleModelerのGoogle App Engine生成器のリファインを開始。

Ruby on Rails、Grails、Google App Engine、Google App Engine Oilを一通り調べて、これらのWebフレームワークが共通して持っている問題だと思うのは、MVCのコントローラからPSM(Physical Data Model)をダイレクトにマップしたモデルを直接触る構造になっているということである。もちろん、アプリケーションが意識すればそういう構造にしないことも可能だけれど、自動生成されるCRUDのコントローラはPSMモデルを直接操作する構造になっているし、色々なクックガイドのサンプルもそういう形になっている。
この方式が問題なのは、UIのコードがデータベースのデータ構造を直接意識してしまうことと、アプリケーション・ロジックがUIコードに断片としてばら撒かれてしまう点にある。また、UIデザイナとアプリケーション・プログラマの仕事が分離しづらいという問題もある。
この問題はかつてのCS(Client/Server)で既知のものであり、CSシステムの保守や拡張を大変にしている。
作っているプログラマは楽だけれど、その後、高コストになるアーキテクチャなのである。

もちろん、作り捨てで拙速を重要視するタイプのシステムはこの戦略が合っているわけだけれど、"持続性"が大事な企業アプリケーションではそういうわけにはいかない。

この問題を解決するためには、アプリケーション・ロジックをコントローラから分離し、サービスとして独立したジュールとして作成。コントローラからはサービスを呼び出すという構造にするのがよい。
この時、コントローラからサービスを呼び出す際には"構造を持った値"によってパラメータの受け渡しをすることになる。この目的でSimpleModelingが用意しているモデル要素がdocumentである。

以上のような理由によって、SimpleModelerでは、MVCのコントローラとアプリケーション・ロジックを分離して、アプリケーション・ロジックをサービスとして部品化する構造のアプリケーションを自動生成を指向している。このアプリケーション・アーキテクチャでは、ドメイン・モデルの操作もできるだけサービスとしてカプセル化する。

昨日の作業で、この方針に沿ったそれなりのコードが出てくるようになった。
今朝から、Google App Engine SDK上で生成されたコードのデバッグとチューニング。かすかに動き始めたようである。

2009年3月20日金曜日

python

entityとdocumentのマッピング、状態機械モデルからステートマシーン図と状態遷移表の生成ができるようになって、動的モデルを含むドメイン・モデルを扱うプログラムの生成の土台ができた。

エンティティ・オブジェクトの実装はgaeオプションやgaeoオプションですでに実現済みだけれど、状態機械による振舞いの記述やドメイン・オブジェクトを束ねるドメイン・コンポーネントといったものも生成できるようにすることを考えている。

Google App Engine用のプログラム生成器を本格的に取り掛かるわけだけれど、その前にPythonをちゃんとマスターしないといけませんねー。

ということでPythonに取り掛かる。チョー久々にEclipse Ganymedeを動かしてPyDevを入れてみた。
Eclipse使うの久しぶり。
試しにScalaのプラグインも更新してみたけど、あんまり進展はないみたい。

Pythonは、インデントを文法の論理要素に取り込んだ文法が特色だけれど、それを除いてみるとLispの上に外付けにオブジェクト機能をつけた言語という印象。オブジェクト指向言語としては美しくないような気もするけれど、メタなプログラミングをしたいフレームワーク系の人には逆に分かりやすくてよいかもしれない。
フレームワークが充実すれば、結果としてアプリケーション・プログラマにも恩恵があるので、文法が多少不思議系でもトータルとしてはメリットの方が大きい、ということかな。
その文法もとても簡潔で使いやすいので、不思議系の部分はおまじないと考えれば気にならない。

Djangoとの組合せはとてもバランスがよくて、Webアプリケーションのプレゼンテーションはこういった軽量言語が合っているということを実感。これは、ちょっと前に調べたGrailsでも感じたこと。

プレゼンテーション=>軽量言語、アプリケーション・ロジック=>Java、フレームワーク・DSLコンパイラ=>Scalaで3極化というのをこの間のセミナーのスライドで書いたけれど、そういうことなんだろうと思う。

2009年3月19日木曜日

合成状態の状態遷移表



合成状態(composite state)の入った状態遷移表が無事生成できるようになった。
横軸はイベントとガードの組、縦軸は状態の表である。合成状態は合成状態を構成するサブ状態と合成状態の擬似状態2つ(初期状態、終了状態)、そして合成状態全体を示す状態のそれぞれを軸として使用する。
この2つの軸のマトリクスによってエンティティの状態遷移を記述することができる。
また、プログラムの自動生成もこの状態遷移表の振舞いをプログラムコード化したものになる。

ネットワーク系のアプリケーションでは、仕様の概要を見るには状態遷移図がよいけれど、プログラムとして実装するためには、状態遷移表の形でより具体的、網羅的な情報が必要である。この状態遷移表で「N/A」となっている部分が仕様としてありえない組合せだけれど、実システムでは往々にしてこのような状態に陥ることがあり、そうなった時の予防的なロジックを仕込んでおく必要がある。このような抜けを網羅的につぶしていくためには状態遷移表を用いるのが有効である。

そんなこんなで、合成状態をサポートした状態機械のステートマシーン図と状態遷移表ができるようになった。
次はアクションのサポートである。

合成状態



ステートマシーン図の合成状態(composite state)完成。
合成状態そのものに対する遷移を、開始/終了擬似ステートではなくて合成状態のシンボルそのものにするようにした。このあたりはGraphvizと格闘した所。
UMLの合成状態のフルスペックというわけではないけれど、実用的には十分でしょう。後はニーズ駆動で作り足ししていく。

Graphvizのdotコマンド呼び出しでハングアップする件は、標準エラー出力のバッファあふれみたい。dotコマンド起動時にWarning出力を抑止して解決。
外部コマンドを起動して標準入出力で連携する処理を汎用的に書く場合には、標準入出力および標準エラー出力の3つの入出力に対してそれぞれ別スレッドで対応しなければならない。単一スレッドで対応する場合にはselectシステムコールを使ったポーリングのメカニズムとなる。いずれにしても単純ではない。
起動するコマンドの振舞いによっては、標準入力に一括書き込み(コマンド側は読み込み)、標準出力から一括読み込み(コマンド側は書き込み)という逐次処理で連携できることがある、という特殊な連携パターンであるということを念頭においておかなければならない。
今回の場合は、dotコマンドが一括入力、一括出力のバッチ処理であることと、コマンド引数で標準エラー出力を抑止、という工夫を併用することで、特殊な連携パターンが可能になったということである。