MOSA Multi-OS Software Artists

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

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

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

2005-04-26

目次

  • 「WebObjects Dev Report」    第4回   田畑 英和
  • 小池邦人の「Carbon API 徒然草」
  • SqueakではじめるSmalltalk入門  第38回  鷲見 正人
  • ニュース・解説               木下 誠

「WebObjects Dev Report」  第4回  田畑 英和

10.3.9問題

 Tigerがもうまもまくリリースされますが、そんなところに10.3.9へのアップデートがリリースされました。これがPanther(10.3)の最終形かと思われますが、さっそく10.3.9をインストールしたところとんでもないことになってしまいました。今回は、まずは10.3.9に関する問題とその解決方法からレポートします。

 10.3.9をインストールするとまず影響を受けるのがJavaプログラムです。つまりWebObjectsアプリケーションも影響を受けることになります。これは独自に開発したプログラムだけではなく、JavaMonitorなど標準で提供されているJavaアプリケーションにも影響を与えます。
 具体的な症状としては、Javaプログラムが起動しなくなります。ターミナル上でJavaプログラムを起動しようとすると最後に「Segmentation fault」と表示され、プログラムの起動に失敗します。
 この問題に関してはすでにAppleから解決方法が公開されており、まず問題の確認方法として以下のコマンドの利用が紹介されています。またJavaプログラム以外にもSafariでも問題が発生することが報告されています。

・10.3.9 Updateにともなう問題点の確認方法
% java -version

 これはもともとJavaのバージョンを調べるためのコマンド(オプション)ですが10.3.9の問題にひっかかっている場合、コマンドの実行時にさきほど紹介した「Segmentation fault」が表示されます。これが表示された場合問題があるということです。
 では肝心の解決方法はといいますと、「Java 1.4.2 Update 2」と「Security Update 2005-002」をインストール(場合に寄っては後者だけ)する方法が紹介されています。問題が発生したマシンにこのアップデートを適用したところ無事Javaプログラムが起動するようになりました。
 今後この問題点を修正したアップデートがリリースされるかどうかは分かりませんが、これから10.3.9へのアップデートをおこなう方はくれぐれもご注意ください。*1

・10.3.9 Updateにともなう問題の解決方法
http://docs.info.apple.com/article.html?artnum=301380

*1
原稿執筆後、Java Update for Mac OS X 10.3.9がリリースされました。今回の問題を解消するアップデートでソフトウェアアップデート経由で配布されています。
http://www.apple.com/support/downloads/javaupdateformacosx1039.html

Eclipse

 さて、ここからようやく本題ですが、先週は開発環境の準備について解説しました。今回はその続きとしてEclipseでWebObjectsの開発環境を整える方法を紹介しておきます。

 まずEclipseですが、これは様々なツールを組み合わせた開発環境であり、”universal tool platform”といった呼ばれ方もされています。特にJavaの開発ではすっかり市民権を得ており、解説書も多数出版されています。
 Eclipseは、いわゆるオープンソースとして公開されていて、Mac OS X版も利用することができます。マシンリソースがそれなりに要求され、以前は動作が遅くてなかなか満足に利用できなかったりもしましたが、最近の環境ですとようやく普通に使えるようになってきました。

 このEclipseはプラグインを追加することにより、機能を拡張できることが特徴ですが、WebObjectsのためのプラグインが開発されており、こちらを利用することでEclipse上でWebObjectsの開発をおこなうことができます。

インストール

 ではまずインストールです。EclipseのサイトからMac OS X用のEclipseをダウンロードしてください。ちなみにこの原稿を執筆している時点での最新版は3.0.2となっています。

・Eclipseダウンロード
http://www.eclipse.org/downloads/index.php

 ”eclipse-SDK-3.0.2-macosx-carbon.tar.gz”というファイルがダウンロードできますが、インストール方法はいたって簡単です。ファイルを解凍するだけですぐにEclipseが利用できるようになります。解凍すると”eclipse”フォルダが作成されますが、この中に”Eclipse”(ターミナル上ではEclipse.app)というファイルがありますので、これをダブルクリックするとEclipseを起動できます。あとは必要に応じて”eclipse”フォルダを移動してください。

WOLips

 Eclipseの準備が整った次はWebObjects用のプラグインのインストールですが、WebObjects向けのプラグインはORマッパー「Cayenne」の開発でも有名なObjectStyleのWebサイトで公開されています。プラグインは「WOLips」と呼ばれており、最新版はVer 1.1.0.102 RC 2がリリースされています。

・WOLips
http://www.objectstyle.org/woproject/index.html

 WOLipsをEclipseに組み込む方法ですが、ダウンロードしたWOLipsをあらかじめ解凍し、Eclipseを起動します。Eclipseを起動しますとワークスペースの選択が求められますが、このワークスペースとは作成したプロジェクトの保存先になります。自分のホーム内にワークスペースを作成することもできます。
 ワークスペースを選択してEclipseが起動したら、次に「Help」メニューから「Software Updates」->「Find and Install…」を実行し以下の手順でインストールをおこなってください。

1.「Install/Update」画面で「Search for new features to ins…」を選択
2.「Next」ボタンをクリック
3.「Install」画面で「New Local Site…」ボタンをクリック
4. あらかじめ解凍しておいたWOLipsのフォルダを選択
5. リストに選択したWOLipsが追加されたらチェックボックスをチェックし、「Next」ボタンをクリック
6. 4つの項目が表示され、すべてをチェックし「Next」ボタンをクリック
7. ライセンスが表示されるので、じっくり確認
8.「I accept the terms in the license agreeme…」を選択し、「Next」ボタンをクリック
9. 「Finish」ボタンをクリック
10. 計4回の確認画面が表示され、それぞれ「Install」ボタンをクリック
11. 最後にEclipseを再起動

 以上の手順でEclipseにWOLispが組み込まれます。これでいよいよEclipse上でWebObjectsの開発環境が整ったことになりますが、次回はEclipse + WOLipsでの開発方法について解説し、そろそろビジネスマッチングシステムの話を進めていきたいと思います。

小池邦人の「Carbon API 徒然草」(2005/04/22)

ドラッグ&ドロップの活用(その2)

今回は、Finderでドラッグされたアイコンがターゲット領域(ブラウザコントロール)へドロップされた瞬間の処理について解説します。具体的には、InstallReceiveHandler()で登録されているmyReciveDrag()ルーチンから順次処理を追跡していきます。

以下が、InstallReceiveHandler()で先んじてインストールしておいたmyReciveDrag()ルーチンです。

pascal short myReciveDrag( WindowPtr window,long *refcon,DragReference dref )
{
    short            ret=1;
    CGrafPtr         cptr;
    Point            pt;
    unsigned short   ct;

    GetPort( &cptr );              // カレントポートを保存する
    SetPortWindowPort( window );   // カレントポートをカタログウィンドウにする
    HideDragHilite( dref );        // ターゲット領域の強調色を元に戻す
    GetDragMouse( dref,&pt,NULL ); // ドロップされた座標を得る
    GlobalToLocal( &pt );          // ドロップ座標をローカル座標へ変換
    CountDragItems( dref,&ct );    // ドラッグされたアイテムの個数を得る
    switch( GetWRefCon( window ) ) // ウィンドウの種類をチェックする
    {
        case 'CATA':     // ドロップされたのがカタログウィンドウ内の場合

            ret=reciveCatalogWindow( window,dref,ct,pt ); // 実際のReceive処理へ
            break;
    }
    SetPort( cptr );              // カレントポートを復帰する
    return( ret );
}


myReciveDrag()には3つの引き数が渡されます。最初にSetPortWindowPort()でターゲットとなるウィンドウをカレントポートに設定し、HideDragHilite()でターゲット枠の強調表示を消します。アイコンのドロップ位置のグローバル座標はGetDragMouse()で得ることができるので、GlobalToLocal()でカタログウィンドウのローカル座標へと変換しておきます。また、CountDragItems()によりドロップされたオブジェクト数を得ることができます。こうした情報をまとめて次のreciveCatalogWindow()ルーチンに渡すことで、実際のRecive処理を実行します。

本サンプルアプリケーションでは、アイコンに添付されてくる’hfs ‘というタイプのデータのみを受け取ります。このデータの実態は、HFSFlavorという構造体であり、その内容はGetFlavorData()で得ることが可能です。この構造体には、ドロップされたファイルやフォルダのFSSpec構造体やファイルタイプが含まれています。reciveCatalogWindow()では、ファイルタイプにより次の3つの処理を実行します(ソースコードに番号を添付)。

(1)アイコンがフォルダやボリュームの場合
(2)アイコンがドキュメントファイルの場合
(3)アイコンが表示可能な画像ファイルの場合

#define BROW_ID    100        // ブラウザコントロールのID番号
#define MY_DOC    'MosD' // サンプルアプリ・ドキュメントのファイルタイプ

short reciveCatalogWindow( WindowPtr window,DragReference dref,
                                                  unsigned short ct,Point pt )
{
    Boolean          folder,alias;
    FSSpec           fsc,fsc1;
    short            i,ret=1;
    ControlRef       browser;
    FInfo            info;
    FlavorFlags      flag;
    ItemReference    item;
    OSType           type;
    HFSFlavor        hfs;
    Rect             brt;
    long             len;

    getMyControlRef( window,BROW_ID,&browser ); // ブラウザのControlRefを得る
    GetControlBounds( browser,&brt );           // ブラウザの矩形枠を得る
    for( i=1;i<=ct;i++ ) // ドロップアイテムの個数分ループさせる
    {
        GetDragItemReferenceNumber( dref,i,&item ); // 指定番号のアイテムを得る
        if( ! GetFlavorFlags( dref,item,'hfs ',&flag ) ) // 'hfs 'タイプか?
        {
            GetFlavorDataSize( dref,item,'hfs ',&len ); // データ容量を得る
            GetFlavorData( dref,item,'hfs ',(Ptr)&hfs,&len,0L ); // データを得る
            if( PtInRect( pt,&brt ) )  // ブラウザ内へのドロップか?
            {
                fsc=hfs.fileSpec;  // アイコン(ファイル)のFSSpecを得る
                type=hfs.fileType; //  アイコンのファイルタイプを得る

                ResolveAliasFile( &fsc,1,&folder,&alias ); // エイリアスか?
                if( alias ) // アイコンはエリアスである
                {
                    if( folder ) // フォルダやボリュームのエイリアスか?(1)
                    {
                        getFolderFSSpec( &fsc,&fsc1 ); // フォルダのFSSpecを得る
                        ret=addImageFolder( window,&fsc1 ); // フォルダ内を登録
                    break;
                    }
                    else
                    {
                        FSpGetFInfo( &fsc,&info ); // ファイル情報を得る
                        type=info.fdType;          // ファイルタイプを再設定する
                    }
                }
                if( ( type=='fold' || type=='fldr' || type=='disk' ||
                                   type=='srvr' ) && hfs.fileCreator=='MACS' )
                                   //  アイコンはフォルダやボリュームか?(1)
                {
                    getFolderFSSpec( &fsc,&fsc1 );     // フォルダのFSSecを得る
                    ret=addImageFolder( window,&fsc1 ); // フォルダ内を登録する
                    break;
                }
                if( type==MY_DOC ) // ドキュメントかどうか?(2)
                {
                    if( ! loadObjectFile( window,&fsc ) ) // ドキュメントロード
                    {
                        mainteAddImageFile( window ); // ウィンドウをメンテする
                        ret=0;
                    }
                }
                else
                {
                    navCheckImportExtention( fsc.name,&type ); // 拡張子チェック
                    if( ! navImportCheckTypeList( type ) ) // 登録可能か?(3)
                    {
                        if( ! addImageFile( window,1,&type,&fsc ) ) //登録する
                            ret=0;
                    }
                }
            }
        }
    }
    return( ret );
}


ファイルタイプの違いで処理を分岐する前に、得られたFSSpecをResolveAliasFile()に渡してドロップされたアイコンがエイリアスかどうかを調べます。もしエイリアスであれば(aliasがTRUE)、渡したFSSpecがオリジナルの物と差し替えられて戻ります。アイコンのオリジナルがフォルダであれば(folderがTRUE)、getFolderFSSpec()でフォルダ自身のFSSpecを求め、それをaddImageFolder()ルーチンに渡して内部にある画像ファイルをすべてブラウザに登録します。また、オリジナルがファイルであれば、FSpGetFInfo()でそのファイル情報を得て、正しいファイルタイプを設定し直しています。

ファイルタイプが'fold'や'fldr'であればフォルダアイコンが、'disk'や'srvr'であればボリュームアイコンがドロップされたことを示します。この場合の処理は、エイリアスがフォルダだった場合とまったく同じです。ファイルタイプが'MosD'であれば、これはサンプルアプリケーションのドキュメントですので、loadObjectFile()ルーチンでファイル読み込み処理を実行します。それ以外のファイルタイプであれば、画像ファイルである可能性が残されています。まず、navCheckImportExtention()ルーチンで拡張子を調べてから、navImportCheckTypeList()で登録可能(QuickTimeで表示できる)画像ファイルかどうかを見極め、addImageFile()ルーチンに渡してブラウザへと登録します。

本サンプルアプリケーションは、ウィンドウ全領域をドロップターゲットとはせず、ウィンドウに配置したID=100のブラウザコントロールの矩形枠内のみをターゲットとしています。ちなみに、上記ルーチンでは、PtInRect()を用いて矩形内かどうかを判断をしていますが、もしTrack処理側でも同じ処理を行っていれば、ここで再度行う必要はありません(Recive処理だけインストールした場合には必要です)。今回の例でも分かりますが、外からのデータを受け取る処理(Receive処理)のみを実装するだけなら、Drag Managerは割と簡単に利用できます。

次回は、Receive処理の話の続きです。reciveCatalogWindow()の中から呼ばれている自作ルーチン、addImageFolder()やaddImageFile()などについて詳しく解説したいと思います。

つづく

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

 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。Smalltalkプログラミングには欠かせないコレクション。このコレクションの抽象クラス「Collection」のプロトコルである、accessing、adapting、adding、arithmetic、enumerating、converting、それぞれに属するメソッドを起動するためのメッセージが送信されたとき、コレクションがどんな振る舞いをするのかをこれまで見てきました。今回は残りのmath functions、removing、testingの各プロトコルを取りあげます。

 math functionsプロトコルには、単項メッセージで起動され、そのとき代数的関数のような役割りを果たすメソッドがまとめられています。

#(1 2 3 4) sum " => 10 " "合計を求める"
#(1 2 3 4) min " => 1 " "最小値 "
#(1 2 3 4) max " => 4 " "最大値 "
#(1 2 3 4) negated " => #(-1 -2 -3 -4) " "各要素の符号反転"

 Collectionのmath functionプロトコルを閲覧している状態で、ブラウザ上段右端のペインから各メソッド名(セレクタ)をクリックすると、対応するメソッドの定義が下のコードペインに表示されます。このプロトコルに属するメソッドは、#sumや#max、#minのように結果を求めるために特殊な手続きが必要なタイプのものと、#negatedのように#collect:を使って、各要素に単純にメッセージを送り直した結果を新しいコレクションとして返すタイプのものに大別できます。

Collection >> max
   ^ self inject: self anyOne into: [:max :each | max max: each]

Collection >> negated
   ^ self collect: [:a | a negated]

 ちなみにanyOneは、レシーバの適当な(実際には最初の)要素を返すメソッドを起動するメッセージです。

 arithmeticプロトコルに属するメソッド同様、math functionsに属するメソッドも、起動時のコンテキストにおいてレシーバのすべての要素が数値かそれに準ずるものであることが期待されます。

#(1 #two 3 4) negated " => error "

 removingプロトコルには、レシーバから要素を取り除くためのメソッドが属します。基本的なメソッドは、#remove:、#remove:ifAbsent:、#removeAll:です。addingプロトコルのメソッド同様、removingプロトコルのメソッドも削除した要素を返値とする慣習があるので、ここでは便宜的にレシーバを返すyourselfというメッセージを送っています。

#(1 2 2 3 3 3) asSet remove: 2; yourself   " => a Set(1 3) "
#(1 2 2 3 3 3) asSet remove: 4  " => Error: Object is not in the collection. "
#(1 2 2 3 3 3) asSet remove: 4 ifAbsent: []; yourself  " => a Set(1 2 3) "
#(1 2 2 3 3 3) asSet removeAll: #(1 2); yourself  " => a Set(3) "

 メッセージ「remove: oldElement」は、レシーバからoldElementを削除します。もちろん、要素の増減が可能なコレクションに限ります。

#(1 2 3) remove: 2
   " => Error: This message is not appropriate for this object "

 取り除こうとする要素がレシーバに含まれているかどうかわからないときは、メッセージ「remove: oldElement ifAbsent: [...]」を送ります。第二パラメータのブロックには、削除したい要素がレシーバに見つからないときの処理を記述します。何もしないときは上述のように空のブロック「[]」を渡しておけばよいでしょう。

 メッセージ「removeAll: aCollection」は、aCollectionに含まれる要素をすべてレシーバから削除します。これは、aCollectionに対する要素の列挙と、#remove:を使って表現できそうですね。実際に#removeAll:を見てみると、たしかにその通りの定義になっています。

Collection >> removeAll: aCollection
   aCollection do: [:each | self remove: each].
   ^ aCollection

 コレクションのプロトコル探索の最後はtestingです。ここで注目するメソッドは、#includes:、#isEmpty、#occurrencesOf:です。

#(1 2 2 3 3 3) includes: 2       " => true  "
#(1 2 2 3 3 3) includes: 4       " => false "
'squeak' includes: $a            " => true  "
'squeak' includes: $x            " => false "
#(1 2 2 3 3 3) isEmpty           " => false "
#() isEmpty                      " => true  "
'squeak' isEmpty                 " => false "
'' isEmpty                       " => true  "
#(1 2 2 3 3 3) occurrencesOf: 4  " => 0     "
'SMALLTALK' occurrencesOf: $L    " => 3     "

 「includes: anObject」はレシーバがanObjectを含むかどうかを真偽値で返させます。isEmptyは、単純にレシーバが空(カラ)つまり要素を*持たない*か否かを、やはり真偽値で返させます。

 isEmptyの逆、つまり、要素を*有する*か否かを聞きたいときは、isEmptyの返値にnotを送信して反転させる…という手の他に、notEmptyというメッセージを送る方法もあります。

#(1 2 2 3 3 3) isEmpty not   " => true "
#(1 2 2 3 3 3) notEmpty      " => true "

 メッセージ「occurrencesOf: anObject」は、anObjectのレシーバ内での出現回数を尋ねるときに送ります。

 以上、駆け足でしたが、Smalltalkのコレクションが共通して受け付けるメッセージと、そのときに期待される振る舞いについての簡単な解説を終わります。

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

ニュース・解説

 今週の解説担当:木下 誠

----------------------------------------------------------------------
QuickTimeアプリケーションのモダン化
----------------------------------------------------------------------

QuickTimeアプリケーションをモダン化するためのドキュメント「Modernizing QuickTime Applications Part I」が、公開されていました。これは、古いQuickTimeのAPIを使っているアプリケーションを、QuickTime 6系のAPIに移行させるための、ガイドとなるドキュメントです。

このドキュメントに、特に新しい内容が含まれる訳ではなく、QuickTime 6 APIのサマリーとなっています。各機能の説明では、サンプルのコードを多く含み、かなり大きなドキュメントになっています。さらにタイトルに「Part I」と付いているので、おそらく後日Part IIも公開されるのでしょうから、膨大な量になりそうです。

QuickTime 7の登場を間近に控えていますが、古いアプリケーションのメンテナンスをしたり、QuickTime APIの概要をつかむのに、便利なドキュメントでしょう。

Technical Note TN2140: Modernizing QuickTime Applications Part I
http://developer.apple.com/technotes/tn2005/tn2140.html

----------------------------------------------------------------------
Mac OS X 10.3.9のJavaの問題
----------------------------------------------------------------------

先日、Mac OS X 10.3.9が公開されましたが、アップグレードすると、JavaアプリケーションやSafariでJavaを利用するWebページを開いたときに、問題が発生しました。具体的には、アプリケーションがクラッシュしたり、起動しなくなりました。その問題を解決するJava Update for Mac OS X 10.3.9と、その解説を行なうドキュメントが公開されました。

問題の原因は結局、javaコマンドでバージョンを表示させる、'java -version'でセグメンテーション・フォールトが発生していた、ということのようです。

Java Update for Mac OS X 10.3.9
http://www.apple.com/jp/ftp-info/reference/javaupdateformacosx1039.html
About the Java Update for Mac OS X v10.3.9
http://docs.info.apple.com/article.html?artnum=301382

----------------------------------------------------------------------
WindowsからMacへ、Visual BasicからREALbasicを利用して
----------------------------------------------------------------------

WindowsアプリケーションをMac環境に、数日で移植した例が紹介されていました。CompuTestという会社が、2004年の夏に行なった事例だそうです。

彼らは、WindowsのVisual Basicで書いたソフトを販売していましたが、Mac版の開発の要求を受けて、REALbasicを使って移植することを試しました。その結果、12日で移植を完了することが出来たそうです。

A Pleasant Surprise for CompuTest: Porting From Windows to Mac in Days Instead of Months
http://developer.apple.com/business/macmarket/electronicbluebook.html

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

MOSA Developer News   略称[MOSADeN=モサ伝]
Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2005 MOSA. All rights reserved.