<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/lazybones/">
    <title>lazybones @Wiki</title>
    <link>http://w.atwiki.jp/lazybones/</link>
    <atom:link href="https://w.atwiki.jp/lazybones/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>lazybones @Wiki</description>

    <dc:language>ja</dc:language>
    <dc:date>2005-06-15T13:25:53+09:00</dc:date>
    <utime>1118809553</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/27.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/26.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/25.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/24.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/23.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/22.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/21.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/20.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/19.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/lazybones/pages/18.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/27.html">
    <title>XOOPXモジュール作成覚書</title>
    <link>https://w.atwiki.jp/lazybones/pages/27.html</link>
    <description>
      * XOOPSモジュール作成覚書

参考文献：
 XOOPSコミュニティサイト構築ガイド
 高井守＋インフォリグ　著　小野和巳　監修
 技術評論社
 6 XOOPSの周辺技術
 6.1 smarty
 6.3 外部モジュール
 7 外部モジュールの作成

参考サイト：    </description>
    <dc:date>2005-06-15T13:25:53+09:00</dc:date>
    <utime>1118809553</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/26.html">
    <title>cosUMLTool4</title>
    <link>https://w.atwiki.jp/lazybones/pages/26.html</link>
    <description>
      * 閃いた事　エンドユーザ向けドキュメントの自動生成
私はクラス図を二つ作らなければいけない立場なのです。それは、開発者向けとエンドユーザ向けです。
同じ物でもと思いますが、プロパティ等日本語ではないことで、エンドユーザ向けのドキュメントとなりません。

そこで、cacheが生成するxmlファイルのDescription（///で始まるコメント）をプロパティ名にすることによって、日本語のドキュメントが生成することにしました。

 /// プロパティを持ったクラス。だが、まだメッソドは持っていない。
 Class Simple.withProperty Extends %RegisteredObject [ ProcedureBlock ]
 {
 
 /// 名前
 Property name As %String;
 
 }
上のソースから下のjavaソースを生成するということです。
 class withProperty{
 	public String 名前;
 }
残念ながらクラス名の自動化は諦めました。JUDEに取り込んだときに機能する関連が途切れてしまうためです。しかたがないので、JUDEで取り込んでから、本来の使い方ではありませんが、ステレオタイプに入力することにしました。これで、手でクラス図を作成するという作業は大分軽減されると思います。

シェルスクリプト conv2java4u.sh
 #!/bin/sh
 if [ $# -ne 1 ]
 then
 	echo &quot;ファイル名がありません。&quot;
 	echo &quot;使用法：conv2java4u.sh ファイル名(.xmlは省略してください。)&quot;
 	exit
 fi
 nkf -s $1&quot;.xml&quot; | sed -f preconv | awk -f cache2java4u &gt; $1&quot;4u.java&quot; 

sedファイル preconvは変更ありません。

awkファイル cache2java4u
 /^&lt;Class name/ { 
 print &quot;class &quot;$3&quot;{&quot;
 inClass = 1 
 }
 /^&lt;\/Class/ { 
 print &quot;}&quot;
 inClass = 0 
 }
 /^&lt;Proper    </description>
    <dc:date>2005-05-27T18:31:19+09:00</dc:date>
    <utime>1117186279</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/25.html">
    <title>cosUMLTool3</title>
    <link>https://w.atwiki.jp/lazybones/pages/25.html</link>
    <description>
      * 参考のスクリプト

シェルスクリプト conv2java.sh
 #!/bin/sh
 if [ $# -ne 1 ]
 then
 	echo &quot;ファイル名がありません。&quot;
 	echo &quot;使用法：conv2java.sh ファイル名(.xmlは省略してください。)&quot;
 	exit
 fi
 nkf -s $1&quot;.xml&quot; | sed -f preconv | awk -f cache2java &gt; $1&quot;.java&quot;

sedファイル preconv
 /^&lt;Class name=\&quot;/ s/\&quot;.*\./\&quot;/
 s/=\&quot;/ /
 s/\&quot;/ /
 s/&gt;/ /
 s/&lt;\/Type/ /
 s/&lt;\/Description/ \/Description/
 s/%String/String/
 s/%Date/Date/

awkファイル cache2java
 /^&lt;Class name/ { 
 print &quot;class &quot;$3&quot;{&quot;
 inClass = 1 
 }
 /^&lt;\/Class/ { 
 print &quot;}&quot;
 inClass = 0 
 }
 /^&lt;Property name/ {
 propName = $3
 inProperty = 1
 }
 /^&lt;\/Property/ {
 printf (&quot;\tpublic %s %s;\n&quot;,propType , propName)
 inProperty = 0
 }
 inProperty == 1 &amp;&amp; /^&lt;Type/ { propType = $2 }
スクリプトの実行結果 Simple.java
 class withProperty{
 	public String name;
 }

このスクリプトでは、プロパティだけを考慮していますが、メソッドなどの処理も同様の方法で処理できそうです。

このスクリプトを書きながら、[[閃いた事&gt;cosUMLTool4]]があります。    </description>
    <dc:date>2005-05-27T17:31:59+09:00</dc:date>
    <utime>1117182719</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/24.html">
    <title>cosUMLTool2</title>
    <link>https://w.atwiki.jp/lazybones/pages/24.html</link>
    <description>
      * Cacheが生成したXMLファイル

 /// プロパティを持ったクラス。だが、まだメッソドは持っていない。
 Class Simple.withProperty Extends %RegisteredObject [ ProcedureBlock ]
 {
 
 /// 名前を設定できるプロパティ。
 Property name As %String;
 
 }
 
上のソースファイルをエクスポートした結果です。
 
 &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
 &lt;Export generator=&quot;Cache&quot; version=&quot;9&quot; zv=&quot;Cache for Windows NT (Intel/P4) 5.0.8 (Build 5105U_SU)&quot; ts=&quot;2005-05-27 15:35:41&quot;&gt;
 &lt;Class name=&quot;Simple.withProperty&quot;&gt;
 &lt;Description&gt;
 プロパティを持ったクラス。だが、まだメッソドは持っていない。&lt;/Description&gt;
 &lt;ProcedureBlock&gt;1&lt;/ProcedureBlock&gt;
 &lt;Super&gt;%RegisteredObject&lt;/Super&gt;
 &lt;TimeChanged&gt;60047,56009.8839&lt;/TimeChanged&gt;
 &lt;ClassDefinitionError&gt;0&lt;/ClassDefinitionError&gt;
 
 &lt;Property name=&quot;name&quot;&gt;
 &lt;Description&gt;
 名前を設定できるプロパティ。&lt;/Description&gt;
 &lt;Type&gt;%String&lt;/Type&gt;
 &lt;/Property&gt;
 &lt;/Class&gt;
 &lt;Checksum value=&quot;3224096104&quot;/&gt;
 &lt;/Export&gt;
Javaのクラスに変換するには、
 &lt;Class name=&quot;Simple.withProperty&quot;&gt;
 &lt;Property name=&quot;name&quot;&gt;
 &lt;Type&gt;%String&lt;/Type&gt;
 &lt;/Property&gt;
 &lt;/Class&gt;
を元に以下の様なJavaソースを生成することにします。
 class withPro    </description>
    <dc:date>2005-05-27T15:50:08+09:00</dc:date>
    <utime>1117176608</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/23.html">
    <title>cosUMLTool</title>
    <link>https://w.atwiki.jp/lazybones/pages/23.html</link>
    <description>
      * UML Toolを使いたい
私は出来る限りドキュメントを自分で作成したくない！と常々思っています。それは、楽したいということが第一の理由ですが、手で書くことになると、プログラムが出来上がるまで、ドキュメントを書かなくなるからということも大きな理由の一つです。変更することが判っているのにその時点でのドキュメントを作成しようとは思わないのは私だけではないでしょう。

出来ることであれば、Cacheでクラスを作成したのだから、それが、ドキュメントになってくれるならば願ったり叶ったりです。Cacheスタジオが生成してくれるクラスドキュメントもその一つですが、UMLのクラス図があればと思います。では、どの様にすればそれを自動的に生成できるでしょうか？

Cacheでは、Rose Linkという機能で、Roseとリンクできるようですが、バージョンが限定されているという問題と、Roseの価格が高いという問題があります。そこで、フリーで使用できるUML Tool 「JUDE Community」を検討してみることにします。でも、このツールには（そして多くのツールでの）、Java用であるという問題があります。しかし、この問題を解決すれば、多くのJava用のツールが使用できるということにもなります。

Java用のツールに対応させるには？私は、CacheのxmlエクスポートファイルをJavaソースファイルに変換できないか検討することにしました。とはいえ、Cacheの全てのシンタックスを網羅することは不可能でしょう。しかし、自分の作成している範囲ぐらいは可能かもしれません。

では、簡単なクラスを作成しながら、可能性を探っていきます。

ということで、私はCygwinでawkを使う方向で検討を始めました。
余談ですが、私のCygwin環境は、デフォルトにvim,nkf,gcc,makeが追加されています。

それでは、cacheが生成した[[xmlファイルを見ていきましょう&gt;cosUMLTool2]]。    </description>
    <dc:date>2005-05-27T15:38:28+09:00</dc:date>
    <utime>1117175908</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/22.html">
    <title>cosUnitTest7</title>
    <link>https://w.atwiki.jp/lazybones/pages/22.html</link>
    <description>
      *UnitTest FirstUnitTestの問題点
このテストは、直ぐに見つかる大きな問題点があります。
それは、nameプロパティに、半角スペースが無かった場合のチェックが行われていないことです。
Humanクラスは正解かどうかは別としてそれらしきコードがあります。
きちんとテストが記述れていれば、このコードはきちんとコーディングされていたものと考えられます。

まだ、問題点はあります。スペースが複数あった場合。先頭がスペースだった場合。それらの記述が欠けている事が予想できます。

こんな簡単な例ですが、テストすべき項目は意外と多い事に気がつきます。    </description>
    <dc:date>2005-05-12T16:50:05+09:00</dc:date>
    <utime>1115884205</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/21.html">
    <title>cosUnitTest6</title>
    <link>https://w.atwiki.jp/lazybones/pages/21.html</link>
    <description>
      *UnitTest メソッドのテストの追加
Humanクラスに名前を取得するgetFirstNameメソッドと苗字を取得するgetFamilyNameメソッドを追加します。前提としては、名前と苗字は、半角のスペースで区切られているとします。
 Class Sample.Human Extends %RegisteredObject [ ProcedureBlock ]
 {
 
 Property height As %Integer;
 
 Property name As %String;
 
 Method getFamilyName() As %String
 {
 	if (..name = &quot;&quot;)
 	{
 		quit &quot;&quot;		
 	}
 	else
 	{
 		set pos = $FIND(..name,&quot; &quot;)
 		if (pos = 0)
 		{
 			quit ..name	
 		}
 		else
 		{
 			quit $EXTRACT(..name,pos,$LENGTH(..name))
 		}
 	}
 }
 
 Method getFirstName() As %String
 {
 	if (..name = &quot;&quot;)
 	{
 		quit &quot;&quot;
 	}
 	else
 	{		
 		set pos = $FIND(..name,&quot; &quot;)
 		if (pos = 0)
 		{
 			quit ..name	
 		}
 		else
 		{
 			quit $EXTRACT(..name,1,pos-2)
 		}
 	}
 }
 
 }
そのテスト仕様も変更して以下のようにしました。
 Include %outUnitTest
 
 /// Unit Test for Human Class
 Class Sample.FirstUnitTest Extends %UnitTest.TestCase [ ProcedureBlock ]
 {
 
 Method TestGetFamilyName()
 {
 	set p = ##class(Sample.Human).%New()    </description>
    <dc:date>2005-04-28T17:48:30+09:00</dc:date>
    <utime>1114678110</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/20.html">
    <title>cosUnitTest5</title>
    <link>https://w.atwiki.jp/lazybones/pages/20.html</link>
    <description>
      *UnitTest WEB上でのテスト結果の表示
 http://127.0.0.1:1972/csp/samples/%UnitTest.Report.cls?NS=USER&amp;INDEX=30
で、今の結果が表示されます。
また、
 http://127.0.0.1:1972/csp/samples/%UnitTest.Report.cls?NS=USER
でUSERネームスペースで行われたテストの一覧が表示されます。

この機能は非常に有効であると思われます。PMは、このページを確認することによってテストの状況を確認することが可能です。

では、Cache Object ScriptでのUnitTestの概要が理解できたところで、もう一度、テスト内容を完全なものにしてみましょう。

以下の様にテストを変更します。

 Include %outUnitTest
 
 /// Unit Test for Human Class
 Class Sample.FirstUnitTest Extends %UnitTest.TestCase [ ProcedureBlock ]
 {
 
 Method TestConstructor()
 {
 	set p = ##class(Sample.Human).%New()
 	set p.name = &quot;Taro Yamada&quot;
 	set p.height = 180
 	DO $$$AssertEquals(p.name,&quot;Taro Yamada&quot;,&quot;My name is &quot;_p.name)
 	DO $$$AssertEquals(p.height,180,&quot;My height is &quot;_p.height)
 }
 
 }

これで、Humanクラスのインスタンスを作成して、nameプロパティ、heightプロパティをセットしその値が正しくセットされているか確認しています。
テストの結果は、
 USER&gt;do ##class(%UnitTest.Manager).RunTest (&quot;Human:Sample.FirstUnitTest&quot;,&quot;/load=0/recursive=0/nodebug&quot;)
 
 =======================    </description>
    <dc:date>2005-04-28T16:48:53+09:00</dc:date>
    <utime>1114674533</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/19.html">
    <title>cosUnitTest4</title>
    <link>https://w.atwiki.jp/lazybones/pages/19.html</link>
    <description>
      *UnitTest エラーの無いクラス
それでは、エラーの無いクラスに変更してみましょう。
簡単ですね。nameプロパティを追加すればエラーは無くなりますが、ここでは、Humanクラスの仕様書通りに、
 name as %String
 height as %Integer
を追加します。Humanクラスをコンパイルして、テストを実行します。
 do ##class(%UnitTest.Manager).RunTest (&quot;Human:Sample.FirstUnitTest&quot;,&quot;/load=0/recursive=0/nodebug&quot;)
 
 ===============================================================================
 Directory: c:\cache\unittests\human\
 ===============================================================================
 Human begins ...
 Skipping loading testsuite Human
   Sample.FirstUnitTest begins ...
     TestConstructor() begins ...
       AssertEquals:Constructor Name (passed)
       LogMessage:Duration of execution: .001808 sec.
     TestConstructor passed
   Sample.FirstUnitTest passed
 Human passed
 
 Use the following URL to view the result:
 http://127.0.0.1:1972/csp/samples/%UnitTest.Report.cls?NS=USER&amp;INDEX=30
 USER&gt;
今度は、テストがパスしました。
ここで、WEB上で今までの[[テストの結果を確認する方法を説明します。&gt;cosUnitTest5]]    </description>
    <dc:date>2005-04-28T15:20:26+09:00</dc:date>
    <utime>1114669226</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/lazybones/pages/18.html">
    <title>cosUnitTest3</title>
    <link>https://w.atwiki.jp/lazybones/pages/18.html</link>
    <description>
      *UnitTestの実行
ターミナルを起動して、
 DO ##class(%UnitTest.Manager).RunTest(&quot;Human:Sample.FirstUnitTest&quot;,&quot;/load=0/recursive=0/nodebug&quot;)
と入力します。
 USER&gt;do ##class(%UnitTest.Manager).RunTest (&quot;Human:Sample.FirstUnitTest&quot;,&quot;/load=0/recursive=0/nodebug&quot;)
 
 ===============================================================================
 Directory: c:\cache\unittests\human\
 ===============================================================================
 Human begins ...
 Skipping loading testsuite Human
   Sample.FirstUnitTest begins ...
     TestConstructor() begins ...
 LogStateStatus:0:TestConstructor():エラー #5002: Cache エラー:&lt;CLASS DOES NOT  EXIST&gt;zTestConstructor^Sample.FirstUnitTest.2
     TestConstructor failed
   Sample.FirstUnitTest failed
 Human failed
 
 Use the following URL to view the result:
 http://127.0.0.1:1972/csp/samples/%UnitTest.Report.cls?NS=USER&amp;INDEX=27
 USER&gt;
期待通り、クラスが無いという&lt;CLASS DOES NOT  EXIST&gt;で失敗しています。

では、次に、メンバーの無いHumanクラスを作成し同じテストを繰り返します。
 USER&gt;do ##    </description>
    <dc:date>2005-04-28T15:05:51+09:00</dc:date>
    <utime>1114668351</utime>
  </item>
  </rdf:RDF>
