MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第246号

2007-04-03  

目次

  • 「「Wonderful Server Life」    第44回   田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • SqueakではじめるSmalltalk入門  第81回   鷲見 正人
  • 書籍紹介 アーロン・ヒレガス著 Mac OS X Cocoaプログラミング

「Wonderful Server Life」  第44回  田畑 英和

  〜アカウント編〜

 WWDC2007のセッション概要もぼちぼち公開され始めましたね。Leopardの発売日はまだあきらかにされていませんが、今年のWWDCの目玉はいったいどうなるのでしょうか。

◇アカウント管理
 さて、今回はアカウント管理の解説をしたいと思います。アカウントについてはすでにネットワークユーザの解説を以前行いましたが、OpenDirectoryでは管理可能なアカウントとして次の3種類があります。

・管理可能なアカウント
  - ユーザ
  - グループ
  - コンピュータ

 ユーザについてはすでに解説済みですので、残りのグループとコンピュータについて解説していきたいと思います。Mac OS Xを1人のユーザだけが使用している場合には、グループやコンピュータといったアカウントを直接意識することはないかもしれません。ですが、サーバを使ってクライアント管理を行う場合には、グループやコンピュータのアカウントを利用することで効率よく管理ができるようになります。
 グループでは、複数のユーザ(あるいはグループ)をメンバーとして1つにまとめて管理することができます。たとえばファイルサービスの場合では、グループ単位でアクセス権の管理を行うことができます。
 さらに、コンピュータもアカウントとして管理することができ、ユーザ、グループ、コンピュータごとにサーバ上で環境設定の一元管理を行うことができます。

◇グループ
 ではグループから解説していきましょう。グループの管理はユーザの管理と同様に「ワークグループマネージャ」を使用します。「ワークグループマネージャ」を起動し、まずツールバーから「アカウント」をクリックします。すると画面左側にアカウントのリストが表示されます。
 アカウントのリストはユーザ、グループ、コンピュータの3つに分かれており、リスト上部のボタンでそれぞれの表示を切換えることができます。左から2番目のボタンがグループのボタンです。

 初期状態ではグループのリストにはまだなにも表示されません。ユーザを新規に作成したときと同じ要領で、ツールバーから「新規グループ」ボタンをクリックすると新規グループを追加することができます。グループのパラメータとしては次のようなものがあります。

・名前
  最大長255byte
  フォーマット:UTF-8
・ユーザ名
  最大長255byte、ショートネームとも呼ばれる
  フォーマット:A〜Z、a〜z、0〜9、_で構成されるASCII文字
・グループID
  グループごとに一意に割り当てられるID
  フォーマット:32ビットの数値

・グループレコード内の標準属性
「オープンディレクトリの管理」P.222
http://images.apple.com/jp/server/pdfs/Open_Directory_v10.4_j.pdf

 以上の3つがグループの基本的なパラメータになります。「グループID」はグループを新規に作成したときに自動的に割り当てられますので、あとは「名前」と「ユーザ名」を指定すればよいことになります。
 グループの設定をしているにもかかわらず、画面上の表示は「ユーザ名」となっていますが、英語環境で「ワークグループマネージャ」を起動しますと「Short name」と表示されています。ユーザの管理画面でも同様の名前が使われていますので、おそらくリソースの翻訳ミスでしょう。ここは「グループ名」のことです。パラメータの設定が終われば最後に画面右下の「保存」ボタンをクリックします。

・グループの管理画面
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Group/WGM_Group_01.png

◇グループメンバーの管理
 グループには複数のユーザをメンバーとして登録することができます。MacOS X Server v10.4ではグループに登録できるユーザ数に制限はありません。また、ユーザがメンバーになれるグループの数にも制限はありません。
 さらにMac OS X Server v10.4からは、ほかのグループをメンバーとして登録できるようにもなりました。つまりグループの階層構造を実現することができるのです。グループの階層構造により、実際の組織体系に合わせたグループ管理が可能になります。

 メンバーの追加方法ですが、メンバーリストの右側にある「+」ボタンをクリックすると画面の端にユーザおよびグループのリストが表示されます。このリストから任意のユーザあるいはグループを選択して、グループのメンバーリストにドラッグ&ドロップします。

・グループメンバーの登録
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Group/WGM_Group_02.png

 グループの管理画面ではグループのメンバーとしてユーザを登録しますが、ユーザの管理画面でもグループに関する設定ができます。ユーザの管理画面から「グループ」を選択しますと、ここでは左側のリストで選択中のユーザがメンバーとして登録されているグループのリストを表示することができます。さらに、この画面からはユーザを任意のグループに登録することもできます。
 この画面には「プライマリグループID」というパラメータがありますが、これはユーザがデフォルトで所属するグループのことです。ユーザは最低1つのグループに所属する必要がありますが、ユーザを新規に登録すると自動的にグループIDが20(staffグループ)のグループに登録されます。

・ユーザ管理画面の「グループ」
http://homepage.mac.com/htabata/MXS10.3/img/WGM_Group/WGM_User_12.png

 それでは次回はグループフォルダなどについて解説したいと思います。
                               つづく

小池邦人のCarbon API 徒然草(2007/03/30)

〜 Carbonモダンアプリケーションへの道(その13) 〜

今回は、HIThemeOrientation()によるテキスト描画を印刷(プリントアウト)に利用してみたいと思います。印刷といっても、ウィンドウ上のテキスト描画とそれほど違いはないのですが、幾つか注意すべきポイントを解説します。

せっかくですので、まず最初にCarbonアプリケーションでの印刷手順をおさらいしておきましょう。昔から印刷作業には2種類のダイアログ、もしくはシートウィンドウを利用します。それらは、用紙設定ダイアログ(Page Setup)とプリントダイアログ(Print)と呼ばれており、ファイルメニューの「ページ設定…」や「用紙設定…」そして、「プリント…」を選択することで表示されます。用紙設定ダイアログでは、印刷のための用紙サイズや印刷方向を設定できます。その後、プリントダイアログで印刷枚数等を入力し「プリント」ボタンをクリックすれば、印刷が始まる手順となります。

昔から、このように印刷関連のダイアログが2つに分かれている点については、使い勝手の面からも議論の対象となっています。まあ用途によりけりなので、どちらかが最良と言うわけでもないと思いますが、両ダイアログを一つにまとめたオプションが存在しても良いのではないでしょうか(近々そうなるとの噂アリ)。まずは、用紙設定ダイアログ(シート)の表示方法を調べてみます。

先んじて、両ダイアログの設定内容を保持するための2つのリファレンス
(PMPageFormatとPMPrintSettings)を外部変数として定義しておきます。

PMPageFormat       pt_form=NULL;       //  用紙設定ダイアログ設定を参照
PMPrintSettings    pt_set=NULL;        //  プリントダイアログ設定を参照

getDefaultFormatPrint()は、指定された印刷セッションにおける(PMPrintSessionで参照する)用紙設定のディフォルト内容(つまり初期値)を引数で渡したPMPageFormatに代入する簡単なルーチンです。具体的にはメモリ内に構造体を確保し、そのメンバーに初期値を代入します。

short getDefaultFormatPrint( PMPrintSession pss,PMPageFormat *form )
{
   short    err=1;

   if( ! PMCreatePageFormat( form ) )  // PMPageFormatを作成する
   {
       if( *form )
           err=PMSessionDefaultPageFormat( pss,*form );
   }                                       // 用紙設定の初期値を代入する
   return( err );
}


次が、pt_formの設定内容を変更するための用紙設定ダイアログ(今回はシート)を表示するpageSetupPrint()ルーチンです。シートを表示して「OK」か「キャンセル」ボタンをクリックすると、PMSessionUseSheets()の引数として登録しておいたpageDoneProc()(終了ルーチン)が呼ばれます。ちなみに、この処理からPMSessionUseSheets()を外せば、用紙設定シートはダイアログとして表示されます。しかし、Mac OS X 10.4(Tiger)では、モニターの変な場所にダイアログが表示されるバグが存在しますので注意してください。このバグは、Mac OS X 10.5(Leopard)で修正されるそうです。

short pageSetupPrint( WindowRef window )
{
   Boolean           chk=0;
   PMPrintSession    pss;

   if( ! PMCreateSession( &pss ) )                    // 印刷セッションを開始
   {
       PMSessionUseSheets( pss,window,pageDoneProc ); // 終了ルーチンを登録
       if( pt_form )                                  // 用紙設定情報登録済み
       {
           if( PMSessionValidatePageFormat( pss,pt_form,kPMDontWantBoolean ) )
               getDefaultFormatPrint( pss,&pt_form ); // 情報内容が妥当か検査
       }
       else
           getDefaultFormatPrint( pss,&pt_form );     // 未登録の場合は初期化
        PMSessionPageSetupDialog( pss,pt_form,&chk ); // 用紙設定シートを表示
   }
   return( chk );
}


以下が、用紙設定シートを閉じる時に呼び出されるpageDoneProc()ルーチンです。渡されてくるchkの内容により、「OK」ボタンが押されたのか「キャンセル」ボタンが押されたのかを判断可能です。もし、PMSessionUseSheets()を実行せず、シートでなくダイアログの方を表示している時には、PMSessionPageSetupDialog()が返すchkの値により、押されたボタンの種類を判断することができます。

void pageDoneProc( PMPrintSession pss,WindowRef window, Boolean chk )
{
   if( chk==1 )     // OKボタンが押された
   {
        // ここには用紙設定情報(pt_formの内容)を保存する処理などを記述する
   }
   PMRelease( pss ); // 印刷セッションを終了
}


次は、プリントシートを表示するstartPrint()ルーチンです。startPrint()を実行する時点で、まだ一度も用紙設定シートがオープンされていない可能性がありますので、先んじてpt_formに対して前記ルーチンと同様な処理を行っています。

short startPrint(WindowRef window)
{
   Boolean           chk=0;
   PMPrintSession    pss;

   if( ! PMCreateSession( &pss ) )                     // 印刷セッションを開始
   {
       PMSessionUseSheets( pss,window,printDoneProc ); // 終了ルーチンを登録
       if( pt_form )                                   // 用紙設定情報登録済み
       {
           if( PMSessionValidatePageFormat( pss,pt_form,kPMDontWantBoolean ) )
               getDefaultFormatPrint( pss,&pt_form );  // 情報内容が妥当か検査
       }
       else
           getDefaultFormatPrint( pss,&pt_form );      // 未登録の場合は初期化

       if( ! PMCreatePrintSettings( &pt_set ) )        // pt_setを作成する
       {
           if( pt_set )
           {
               PMSessionDefaultPrintSettings( pss,pt_set );  // 初期値代入
               PMSessionPrintDialog( pss,pt_set,pt_form,&chk );
           }                                        // プリントシートを表示
       }
   }
   return( chk );
}


続いて、プリントシートを閉じる時に呼び出されるprintDoneProc()ルーチンです。OKボタンが押された時のみstartPrint()ルーチンを実行し、実施の印刷作業を開始します。

void printDoneProc( PMPrintSession pss,WindowRef window, Boolean chk )
{
   if( chk==1 )      // OKボタンが押された
       startPrint( window,pss,pt_set,pt_form );  //  実際の印刷処理
   PMRelease( pss ); // 印刷セッションを終了
}


最後は、実際の印刷作業を受け持つstartPrint()ルーチンです。印刷処理自体については詳しく解説しませんが、この処理中で重要な箇所は、PMSessionGetGraphicsContext()でkPMGraphicsContextQuickdrawを指定し、まずはQuickDraw APIによる描画を印刷に反映させるためのCGrafPtrを得ている所です。しかしこのままでは、HIThemeDrawTextBox()など描画環境をCGContextRefで参照するAPIは利用できません。そこで、QDBeginCGContext()を使いCGrafPtrからCCGContextRefを得て、それを引数で渡すことで初めてCoreGraphics APIでの描画を印刷に反映させることが可能となります。

OSErr startPrint( WindowRef window,PMPrintSession pss,
                                     PMPrintSettings set,PMPageFormat form )
{
   unsigned long   i,st,ed;
   CFStringRef     cfstr;
   short           err=1;
   CGrafPtr        port;
   CGContextRef    ctx;

   CopyWindowTitleAsCFString( window,&cfstr ); // ウィンドウタイトルを得る
   PMSetJobNameCFString( set,cfstr );          // 印刷ジョブ名を設定
   CFRelease( cfstr );

   PMGetFirstPage( set,&st );                      // 開始ページ
   PMGetLastPage( set,&ed );                       // 終了ページ
   if( ! PMSessionBeginDocument( pss,set,form ) )  // ドキュメント印刷開始
   {
       for( i=st;i<=ed;i++ )
       {
           if( ! PMSessionBeginPage( pss,form,NULL ) )  // 指定ページ印刷
           {
               PMSessionGetGraphicsContext( pss,
                                  kPMGraphicsContextQuickdraw,(void**)&port );
                                                // 印刷環境のCGrafPtrを得る
               if( ! QDBeginCGContext( port,&ctx ) )  // CGContextRefを得る
               {
                    // ここでHIThemeDrawTextBox()などによるテキスト描画を行う
                   err=noErr;
                   QDEndCGContext( port,&ctx );       // CGContextRefを解放
               }
               PMSessionEndPage( pss );   // 指定ページ印刷終了
           }
           if( err )
               break;
       }
       PMSessionEndDocument( pss );       // ドキュメント印刷終了
   }
   return( err );
}


上記処理のような回りくどいことをせずとも、単純にPMSessionGetGraphicsContext()にkPMGraphicsContextCoreGraphicsを代入し、ダイレクトにCGContextRefを得ることができれば、すぐにCoreGraphicsAPIを使えるような気がします...。

ところが、下記のようにCFArrayCreate()とPMSessionSetDocumentFormatGeneration()で行っている手続きを加えないと、この作戦は成功しません。この追加処理の部分、なんだか「おまじない」のような感じなのですが(笑)残念ながら、現状ではこう記述しないとCoreGraphics APIでの描画が印刷に反映されないのです。どう考えても、これは余分な手続きだと思いますので、Mac OS X 10.5では修正してほしいところです。

OSErr startPrint( WindowRef window,PMPrintSession pss,
                                     PMPrintSettings set,PMPageFormat form )
{
   CFStringRef     sref,cfstr;
   unsigned long   i,st,ed;
   short           err=1;
   CGContextRef    ctx;
   CFArrayRef      arr;

   CopyWindowTitleAsCFString( window,&cfstr ); // ウィンドウタイトルを得る
   PMSetJobNameCFString( set,cfstr );          // 印刷ジョブ名を設定
   CFRelease( cfstr );

   PMGetFirstPage( set,&st );
   PMGetLastPage( set,&ed );
   sref=kPMGraphicsContextCoreGraphics;
   if( arr=CFArrayCreate( kCFAllocatorDefault,(const void **)sref,1,
                                                    &kCFTypeArrayCallBacks ) )
   {
       PMSessionSetDocumentFormatGeneration(pss,kPMDocumentFormatPDF,arr,NULL);
       CFRelease( arr );                    // CGContextRefを得るための手続き
       if( ! PMSessionBeginDocument( pss,set,form ) ) // ドキュメント印刷開始
       {
           for( i=st;i<=ed;i++ )
           {
               if( ! PMSessionBeginPage( pss,form,NULL ) ) // 指定ページ印刷
               {
                   PMSessionGetGraphicsContext( pss,
                              kPMGraphicsContextCoreGraphics,(void**)&ctx );
                                              // 印刷環境のCGContextRefを得る

                    // ここでHIThemeDrawTextBox()などによるテキスト描画を行う

                   err=noErr;
                   PMSessionEndPage( pss );   // 指定ページ印刷終了
               }
               if( err )
                   break;
           }
           PMSessionEndDocument( pss );       // ドキュメント印刷終了
       }
   }
   return( err );
}


今回でテキスト関連の話題は終了し、次回からはCarbonのファイルシステムについて解説します。こちらもテキストやグラフィックスに負けず劣らず、時代と共に変貌してきた経緯があります。はたしてファイルシステムは、どの程度モダン化されたのでしょうか?

つづく                                

SqueakではじめるSmalltalk入門   第82回  鷲見 正人

前回は、Squeakと同じXEROXのオリジナルSmalltalk-80の系譜の、しかし子供向けの暫定ダイナブック色の濃いSqueakとは違い、プロプログラマ向けの本格的IDE然としたVisualWorksをご紹介しました。今回は、これら“純正”のSmalltalkに触発されて、いまなお作られ続けているSmalltalkファンお手製の独自のアレンジのSmalltalk処理系について、とくにOS Xで動作させられるものをご紹介します。

▼Little Smalltalk、GNU Smalltalk
Smalltalkのある意味“クセ”のあるGUIは介さずに、通常の言語処理系のようにUNIX系OSの標準入出力を通じて(つまりCUIで)Smalltalkを使いたい…という要望は古くから根強くあるようです。そうしたGUI抜きSmalltalk処理系としての存在で、古くから有名なものに「Little Smalltalk」があります。文字通り、非常にコンパクトなSmalltalk処理系を作るための技術解説書籍とともに、全ソースコードも提供されていました。当時は高価で縁遠い存在だった“ホンモノ”のSmalltalk-80に直に触れて、ハックすることができなかった言語オタク達には、Little Smalltalkはよい遊び道具になっていたようです。

驚いたことにLittle Smalltalkは、Little Smalltalk自身のファンの手により現在も「Little Smalltalkプロジェクト」管轄下でのメンテナンスが行なわれています。

http://www.littlesmalltalk.org/index.php?page=home

余談ですが、Little Smalltalkの生みの親であるティモシー バッドは、これとは別に「Javaアップレット版Little Smalltalk」と呼べそうな「SmallWorld」を作って公開しています。

http://web.engr.oregonstate.edu/~budd/SmallWorld/ReadMe.html

さて。Little Smalltalkは、CUIであることよりは、むしろその小ささやシンプルさが“売り”だったわけですが、同じGUI抜きでも、GUI以外の部分は本家のSmalltalk言語処理系と同じくらい本格的なSmalltalkを目指した処理系もあります。それが「GNU Smalltalk」です。

MacPorts(http://www.macports.org/)を利用していれば、ターミナルから「sudo port install gst」でインストールし、「gst」で専用のシェルを起動して使うことができるようになります。「gst」のあとにファイル名を付せば、通常のスクリプト言語同様、そのファイルに記述されたSmalltalkコードを実行できます。

GNU Smalltalkは、CUIで使う以上、GUI付きのSmalltalkではお馴染みの「コードを入力して選択 → do it(あるいはprint it)」という実行スタイルはとれません。そのため、一連の式の最後に「!」を付けて、do it(つまり式の評価)のタイミングを処理系に伝える方法をとります。

$ gst
GNU Smalltalk ready

st> 3 + 4!
7
st> | a b |
st> a := 3.
st> b := 4.
st> a + b!
7
st>


ところで、Little SmalltalkもGNU Smalltalkも最近のバージョンでは、立派なGUIを使えるようになっています。なんとも、本末転倒のような気もしなくもないのですが、やはりMac同様、GUIベースOSの始祖的存在であるSmalltalkは、どうあってもGUIとは切っては切れない関係にあるのだろうな…と思えば納得です。たとえば、GNU SmalltalkならX11が使える環境で起動時に、

gst -qK browser/Run.st


とすることで、ごく普通に、選択した式を右クリックメニューからprint itできてしまう、本格的GUI付きSmalltalk環境として機能させられます。

[fig.A]GUI付きで起動したGNU Smalltalk

▼Ambrai Smalltalk
SmalltalkをCUIで使いたい…という願いは、あたかも“独立したOS”がごとく自己完結し自由奔放に振る舞うSmalltalkを、UNIXライクOSの流儀で“たんなる言語処理系”のひとつとしてねじ伏せて飼い慣らしたい…という欲求の表れであるとの解釈もできそうです。これがMacやWinでなら、ネイティブGUIで(あるいは、ダブルクリックで起動可能なアプリのための開発環境として)Smalltalkを使いたい…ということになりましょうか。実際、SmalltalkをCUIで使いたい…というのと同じくらい、ネイティブGUIでSmalltalkを動かしたい、ネイティブGUIをSmalltalkから使いたい…という要求も古くから根強くあ
ります。

そうした要望を自分の手で叶えようとする流れのひとつでしょう。我らがOS X向きにも、Cocoaオブジェクトとの連携を強く意識したSmalltalk処理系が作られています。そのひとつが「Ambrai Smalltalk」です。まだ製品化される前のパブリックベータ公開の段階ですが、安定していて普通に使えます。ワークスペース、トランスクリプト、ブラウザ、インスペクタなど基本的なGUIツールを備え、Smalltalk言語処理系としてもANSIの規格に準拠した本格的なものです。

http://www.ambrai.com/smalltalk/index.html

Ambrai Smalltalkでは、「do it」が「Evaluate It」に、「print it」が「Display It」に変えられていますが、それ以外はSqueakやVisualWorksとさほど違いを意識せずとも使うことができそうです。もしもMacがSmalltalk(=暫定ダイナブック)の遺伝子をもっと色濃く受け継いでいたならば、Undo、Copy、Cut、Paste(ちなみにこれらはSmalltalkがルーツ…)だけでなく、Smalltalkのdo itやprint itに相当する項目も、ちゃっかりEditメニューに加えられていたかもしれませんね。MacっぽさとSmalltalkっぽさをうまくミックスしてあるAmbrai Smalltalkをながめていると、そんな“来なかった未来”が見えてきそうで楽しいです。

Ambrai Smalltalkの面白いところは、CocoaのオブジェクトやAPIに、Smalltalkを使ってアクセスできることです。たとえば、ワースペースなどで

MacWindowFrame new open

と入力して選択してからdo it…もとい、Evaluate Itすることで、新しいウインドウを開くことができます。Ambrai Smalltalkのサイトには、この調子でCocoaのチュートリアルでもお馴染みのCurrency Converterを記述して実際に動作させる方法が紹介されています。コードもSqueakでMorphicアプリケーションを記述する感じとよく似ていますね。

http://www.ambrai.com/smalltalk/tutorials/tutorial1/index.html

さらに、Interface Builderで作成したnibファイルを読み込んで、AmbraiSmalltalkで書いたコントローラオブジェクトと連携させるための手順も書かれています。

http://www.ambrai.com/smalltalk/tutorials/tutorial2/index.html

バックナンバー:
http://squab.no-ip.com:8080/mosaren/

書籍紹介    アーロン・ヒレガス著  Mac OS X Cocoaプログラミング

 解説担当:高橋政明

Mac OS X Cocoaプログラミング
アーロン・ヒレガス (Aaron Hillegass) 著
村上 雅章 訳
ピアソンエデュケーション ISBN4-89471-440-X ¥3,885(税込)

 通称ヒレガス本と呼ばれているCocoa独学のためのテキストです。2002年の本なのでツールなどのバージョンが古いのですがCocoaを理解するにはとても重要な価値ある一冊です。

 著者はNeXT社のOpenStepプログラミングの教育担当として働いていたそうです。プログラマにCocoaを教えてきた著者ならではのバランス感覚で説明されていて、サンプルプログラムもシンプルです。(NeXTがAppleに買収された当時はAppleのエンジニアにもCocoaを教えていたそうです)
 この本は自習形式で書かれています。残念ながら執筆時点が古いため Xcodeではなく Project Builder での例が紹介されていますが、基本的な部分はそのまま通用します。もちろん操作する画面やパネルが違っているところもあるのでその点は注意してください。

 原著は2004年に改訂されていますが対応する日本語版はまだ出ていません。Objective-C はレパード(Mac OS X 10.5)で2.0に変わるので、さらに改訂版が出ることを期待しましょう。残念ながら下記原著のwebで第3版の予定はないと載っていますが...

▼出版社のweb
http://www.pearsoned.co.jp/hed/search/onlinecatalog.html?id=282

▼原著 Cocoa Programming for Mac OS X のweb(原著の正誤表あり)
http://bignerdranch.com/products/cocoa1.shtml

 

◇MOSAからのお知らせと編集後記は割愛します◇

 

MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2007 MOSA. All rights reserved.