MOSA Multi-OS Software Artists

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

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

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

2005-05-31

目次

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

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

 いよいよWWDCも目前となってきました。ここ数年は、WebObjects関連のセッションが減少傾向にあり、残念ながら新しい発表も特にありませんでしたがはたして今年はどうなることでしょうか。Mac OS X ServerやXserve/Xserve RAIDの登場によりサーバ環境は充実してきているのですが、WebObjectsも頑張ってもらいたいものです。

モデルファイル

 さて今回はモデルの作成について取り上げてみたいと思います。前回解説しましたようにモデルファイルとはオブジェクトとデータベースとのマッピングを定義するファイルですが、このファイルによりアプリケーション(プログラム)側からみるとデータベースを抽象化することができます。
 通常WebObjectsではデータベースアクセスをおこなうさいに、直接SQLを記述するようなことはいたしません。(*1) プログラム上でオブジェクトの操作をおこなえば、自動的にその操作に対応するSQL文が生成され、データベースアクセスが自動化されます。基本的には以下のような組み合わせで自動化がおこなれます。

・オブジェクトの操作と対応するSQL
オブジェクトの作成 -> insert
オブジェクトの変更 -> update
オブジェクトの削除 -> delete
オブジェクトの検索 -> select

*1 ただし、直接SQLを記述することも可能

 例えば、プログラム上でオブジェクトが新たに生成されれば、そのオブジェクトをデータベースに格納するために自動的にinsert文の生成がおこなわれることになります。
 このデータベースアクセスを実現しているのがEOF(Enterprise Objects Framework)と呼ばれているフレームワークですが、実際にデータベースアクセスを実行するには、プログラム上のオブジェクトとデータベースをマッピングさせる必要があります。具体的には次のようなマッピングを定義します。

・マッピングの関係
テーブル名 <-> クラス名
カラム名/データベース上での型 <-> アトリビュート名/Java上での型(クラス)

 このようなマッピングをモデルファイルに登録しておくことによりEOFは実行時に、各オブジェクトをデータベース上のテーブルへとマッピングし、オブジェクト上のデータをテーブル上の各カラムへとマッピングすることができるわけです。またデータベース上での型とプログラム(Java)上での型はそれぞれ異なりますし、使用するデータベースによっても型の定義は異なっている場合がありますので、モデル上ではデータベースとJavaの型情報もマッピング情報として定義しておきます。
 このモデルファイルにより、データベースに依存する部分が吸収されるため、プログラム側はデータベース固有の情報からは独立し、モデルファイルのマッピング情報を変更することにより、接続先のデータベースを変更するといったことも可能になっています。

接続情報

 マッピンング情報のほかにデータベースに依存する情報として、データベースへの接続情報があります。WebObjects5.2.xではデータベース(RDB)への接続方式としてJDBCをサポートしており、標準では以下のデータベースをサポートしています。

・標準サポートのデータベース
 - Microsoft SQL Server 2000
 - MySQL 3.23.51
 - OpenBase 7.0.8
 - Oracle 8.1.7 and 9.2.0.1
 - Sybase ASE 12.5

 つまりこれらのデータベースはJDBCに対応しているわけですが、実際にJDBCによる接続をおこなうにはそれぞれのデータベース用のJDBCドライバが必要になります。またモデルファイルでは接続先のデータベースを指定するJDBCの接続情報を指定する必要があります。基本的にはURL形式で接続先のデータベースを指定すればよいのですが、データベースにパスワードが設定してある場合はURLといっしょにユーザ名やパスワードも接続情報として指定する必要があります。
 指定するURLの形式は使用するデータベースによってパラメータが異なっていますが、TILで各種データベースへの接続情報の指定方法が解説されています。たとえばローカルマシン上で稼働しているOpenBase上にある「JobMatch」という名前のデータベースに接続するには次のようなURLになります。

・URLサンプル
jdbc:openbase://127.0.0.1/JobMatch
・WebObjects 5.xからの各種データベースへの接続
http://til.info.apple.co.jp/techinfo/100473

まとめ

 今回はモデルファイルの概要について解説しました。モデルファイルは特定のプロジェクトだけで使用するのではなく、フレームワーク化することにより、複数のプロジェクトから共有することも出来ます。
 実際にモデルファイルを作成するにはEOModelerというツールを用いることになりますが、次回はEOModelerについてレポートしたいと思います。

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

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

今回から数回に分け、ドラッグ&ドロップにおけるSend処理を紹介します。ウィンドウ上のオブジェクト(画像、テキスト、ファイル情報など)をドラッグし、Finderなどの別アプリケーションにドロップする仕組みを解説します。

Receive処理とは異なり、Send処理ではデータを受け渡し用ルーチンを「コールバックルーチン」として実装しておく必要はありません。ドラッグしたいデータの表示範囲でマウスクリックが発生した時点で、逐次必要な処理を実行していく形となります。ただし、少々特別なケースに対応するため、データ受け渡し用コールバックルーチンを用いる場合もありますが、それについては別の機会に詳しく解説したいと思います。また残念ながら、本サンプルアプリケーションにはSend処理は実装されていませんので、これから紹介するルーチンは「仮想的な処理」に対するサンプルソースコードとなります。ご了承ください。

先ほど、ドロップするターゲットとして「Finderなどの別アプリケーション」と記述しましたが、当然ターゲットは自分自身でもかまいません。例えば、あるオブジェクトを同じウィンドウや別ウィンドウ内の特定の場所へ移動したりする場合などです。Finderであれば、アイコンをドラッグ&ドロップで別のフォルダへ移動、複製する処理に相当します。結局、Send処理のターゲットとしては以下の3種類を念頭に置けばよいでしょう。当然、Finderも別アプリケーションのひとつなのですが(笑)、システムと密接に関係しているということで、今回はあえて区別をしてみました。

(1)自分自身(Send処理をしているアプリケーション)
(2)別アプリケーション(Adobe Photoshopなど…)
(3)Finder(システム関連…)

基本的には、ウィンドウ上にドラッグ対象オブジェクトが表示されているとすると、その上でマウスクリックが起こる時点でSend処理へと入ります。最初に、そのSend処理への入り口を紹介しておきます。ここでは、あるコントロールにドラッグ画像(PICTやICON)が表示されており、それをユーザがマウスクリックしたと仮定します。この場合には、コントロール自体にイベントハンドラ(Carbon Event Handler)を実装しておき、そこでマウスクリックの発生を感知するのが便利です。以下が、対象コントロールにイベントハンドラを実装するsetupMyControlEvent()ルーチンです。受け取り対象となるイベントの種類は「kEventControlHit」のみとなります。

void setupMyControlEvent( ControlRef chd )
{
    EventTypeSpec    list[]={
                                 { kEventClassControl,kEventControlHit }
                            };

    InstallControlEventHandler( chd,myControlEventHandler,
                              GetEventTypeCount(list),list,(void *)chd,NULL );
}


次に紹介するのが、コントロール上のマウスクリックに対処するためのイベントハンドラmyControlEventHandler()ルーチンです。イベントクラスが「kEventClassControl」で、イベント種類が「kEventControlHit」の場合にのみ、ConvertEventRefToEventRecord()でEventRefの内容をEventRecord(旧イベントループで用いた構造体)へと変換し、それを対象ウィンドウのWindowRefと対象コントロールのControlRefと共にstartMyDrag()に渡しています。

pascal OSStatus myControlEventHandler( EventHandlerCallRef myHandler,
                                               EventRef event,void* userData )
{
    short            ret=eventNotHandledErr;
    unsigned long    ekind;
    EventRecord      evrec;
    WindowRef        wptr;
    ControlRef       chd;
    long             cls;

    cls=GetEventClass( event );   // イベントのクラス名を得る
    ekind=GetEventKind( event );  // イベントの種類を得る
    chd=(ControlRef)userData;     // 対象コントロールのControlRefを得る
    wptr=GetControlOwner( chd );  // 対象ウィンドウのWindowRefを得る

    if( cls==kEventClassControl  && ekind==kEventControlHit )
    {
        if( ! ConvertEventRefToEventRecord( event,&evrec ) )
                           // Carbon EventからEventRecord構造体を作成する
            ret=startMyDrag( wptr,chd,&evrec ); // ドラッグ&ドロップ実行
    }
    return( ret );
}


実際にドラッグ&ドロップのSend処理を担当しているのがstartMyDrag()ルーチンです。本ソースコードでは、先頭が大文字のルーチンがDrag Manager APIであり、先頭が小文字のルーチンは自作ルーチンですので御注意ください。まず最初に、WaitMouseMoved()を実行します。このAPIはクリックされたマウスカーソルが動き出す(ドラッグされる)かどうかを監視しています。もし、マウスが初期位置から許容範囲外(縦横数ピクセル)へ動くと実際のSend処理へ入ります。このように、マウスドラッグへ入るまでに「数ピクセルの遊び」があるのは、ユーザインターフェース的にとても優れた仕様です(Finderで試してみると分かる)。別環境で「マウス操作がとても難しい!」と感じたならば、この「遊び」の存在をぜひ思い出してください(笑)。

short startMyDrag( WindowRef window,ControlRef chd,EventRecord *event )
{
    short                    chk1,chk2,ret=eventNotHandledErr;
    RgnHandle                rgn1,rgn2;
    GWorldPtr                gptr=NULL;
    DragReference            dref;
    DragSendDataUPP          fptr;
    DragAttributes           att;
    StandardDropLocation     loc;

    if( WaitMouseMoved( event->where ) )  // マウスが範囲外へ動くまで待つ
    {
        if( NewDrag( &dref ) ) // 新規のDragReferenceを得る(セッション開始)
            return( 1 );

        if( createDataMyDrag( window,chd,dref ) ) // ドラッグ用データを設定する
        {
            DisposeMyDrag( dref );
            return( 1 );
        }
        chk1=chk2=1;
        if( rgn1=NewRgn() )
            chk1=createRegionMyDrag( window,chd,rgn1 ); // ドラッグ枠を作成
        if( rgn2=NewRgn() )
            chk2=createImageMyDrag( window,chd,dref,rgn2,&gptr );
                                                        // 半透明画像を作成
        if( chk1==noErr && chk2==noErr )
        {
            fptr=NewDragSendDataUPP( (DragSendDataProcPtr)sendDataMyDrag );
            ret=SetDragSendProc( dref,fptr,0 ) );
                                    // データ受け渡し用のコールバックUPPを実装
            if( ret==noErr )
                TrackDrag( dref,event,rgn1 );   // ドラッグ&ドロップの開始
            DisposeDragSendDataUPP( fptr );     // コールバックUPPを削除
            if( ret==noErr )
            {
                GetDragAttributes( dref,&att ); // ドラッグアトリビュートを得る
                if( (att&kDragInsideSenderApplication)==0 )
                                                // 別アプリへドロップされたか?
                {
                    if( ! GetStandardDropLocation( dref,&loc ) )
                    {
                        if( loc==kDragStandardDropLocationTrash )
                            deleteDataMyDrag( window,chd );
                    }   // オブジェクトがゴミ箱へドロップされた場合の処理
                }
            }
        }
        if( rgn1 )
            DisposeRgn( rgn1 );     // ドロップ枠用のRegionを削除
        if( rgn2 )
            DisposeRgn( rgn2 );     // ドロップ画像用のRegionを削除
        if( gptr )
            DisposeGWorld( gptr );  // ドロップ画像用のGworldを削除
        DisposeDrag( dref );
    }
    return( ret );
}


WaitMouseMoved()によりマウスドラッグが感知されると、だいたい以下の手順でSend処理が進んで行きます。「オプション」の記述がある番号は、ケースによっては実装しなくても全体の処理に影響がない行程です。

(1)NewDrag()で新規DragReferenceを得てセッションを開始する
(2)ドラッグ&ドロップしたいデータをセッションに登録する
(3)ドラッグするオブジェクトのグレイ枠(Region)を作成する
(4)ドラッグ中表示される半透明の画像を作成する(オプション)
(5)データ受け渡し用コールバックルーチンを登録する(オプション)
(6)TrackDrag()でドラッグ&ドロップのSend処理を開始する
(7)セッションの後処理を実行する(オプション)

次回は、上記の処理を手順を追って説明して行きます。まずは、startMyDrag()内で実行されているcreateDataMyDrag()ルーチンを解説します。ドラッグされるデータ種類を色々と変えることで処理ルーチンがどう変わるかを、例題を上げて紹介したいと思います。

つづく

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

 本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。今回は、つい先頃、メジャーバージョンアップしてリリースされた日本語版Squeak「SqueakNihongo7」のSmalltalk言語における日本語文字列の扱いをみてみます。

 じつのところ、SqueakNihongo7で日本語の文字列を扱うにあたり、すでにお馴染みの文字列オブジェクト(Stringのインスタンス。a String)との違いをユーザーが意識する必要はほとんどありません。これまでと同じようにシングルクオーテーションで括って新しい文字列を作り、これまでと変わらない方法でメッセージを送ることができます。

‘日本語の文字列’ size ” => 7 ”
‘日本語の文字列’ reverse ” => ‘列字文の語本日’ ”

 文字列オブジェクトの要素である文字オブジェクトについても同じです。リテラル表現には、今まで通り、文字の前に「$」を付けます。

‘日本語の文字列’ at: 3 ” => $語 ”
‘日本語の文字列’ at: 3 put: $文 ” => ‘日本文の文字列’ ”

 しかし、日本語の文字列および文字オブジェクトが属するのは、それぞれStringやCharacterとは別の新しく設けられたクラスです。これは、メッセージ「class」を送信すれば簡単に調べられます。

‘single byte’ class = ‘single byte, too’ class ” => true ”
‘single byte’ class = ‘マルチバイト’ class ” => false ”

‘This is a pen.’ class ” => String ”
‘日本語の文字列’ class ” => MultiString”
$a class ” => Character ”
$あ class ” => MultiCharacter ”

 日本語を含めたマルチバイト文字列を扱えるようにするためのクラスを追加するにあたって、文字列クラスが属するコレクションクラス群の構成にも若干手が加えられています。すでに解説を加えたとおり、公式版 3.7 では、

Collection
 SequenceableCollection
  ArrayedCollection
   String
    Symbol

というように、StringやSymbolは抽象クラスのArrayedCollection直下のサブクラスでしたが、SqueakNihongo7の仮想イメージでは、

Collection
 SequenceableCollection
  ArrayedCollection
   AbstractString  ←
    String
     Symbol
    MultiString  ←
     MultiSymbol ←

というように、新しくAbstractStringという文字列を束ねる抽象クラスが設けられ、改めてそのサブクラスとしてStringやSymbol、そして新しいMultiString、MultiSymbolが定義されています。

 a Stringがa Characterのみを要素とすることができる特殊なan ArrayedCollectionであるのに対し、a MultiStringはa Characterの他に、a MultiCharacterを要素に含めることができる文字列として定義されています。なお、a MultiCharacterにはUnicodeに独自の情報を付加した内部表現が用いられています。

$a asciiValue radix: 16 ” => ’16r61′ ”
$あ asciiValue radix: 16 ” => ’16r1403042′ ”

 AbstractStringは、シングルバイト文字列、マルチバイト文字列の双方で共通して使用できるメソッドを収めるために設けられました。つまりこのことは、これまでStringだけに定義されていたメソッドが、AbstractStringとString(あるいはMultiString)に分割して定義されていることを意味します。従来、文字列オブジェクトに特徴的な挙動を調べたいときに、Stringだけのブラウズで済んだものが、SqueakNihongo7ではAbstractStringとString(あるいはMultiString)を同時に調べなければならなくなっている点に注意する必要があるでしょう。

 ところで、通常のブラウザでブラウズできるのは、指定したクラスに定義されたメソッドのみです。StringとそのスーパークラスのAbstractStringの両方に定義されたメソッドを一挙にブラウズするようなことはできません。こうした用途には「プロトコルブラウザ」というものが用意されているのでこれを通常のブラウザの代わりに使用します。プロトコルブラウザは、デスクトップメニューの「開く…」(英語版ではopen…)からではなく、ブラウザのクラスペインの黄ボタンメニューにある「browse protocol」を選択して起動します。

[fig.A]Stringを選択したブラウザで「browse protocol」を選択
http://squab.no-ip.com:8080/mosaren/uploads/40a.png

[fig.B]起動直後のプロトコルブラウザ
http://squab.no-ip.com:8080/mosaren/uploads/40b.png

 起動直後の初期状態では、Objectクラスからのスーパークラス群に定義された全メソッドを表示してしまっています。これでは情報量が多すぎるので、ウインドウ中央左寄りにある「Only through Object」ボタンをクリックして、ポップアップするメニューから一挙にブラウズしたいスーパークラス(たとえばAbstractString)の範囲を指定します。この操作で、表示するメソッドを限定することが可能です。

[fig.B]スーパークラスの範囲を指定するためのポップアップ
http://squab.no-ip.com:8080/mosaren/uploads/40c.png

 あとは、普通のブラウザと同じように扱えます。少し違うのは、メソッドのリストにメソッド名に加え、それが定義されているクラス名も括弧でくくって表示されていることです。なお、注目するクラス(この場合、String)に定義されたメソッドはリスト中太字で示されます。

[fig.B]プロトコルブラウザでのメソッドのブラウズ
http://squab.no-ip.com:8080/mosaren/uploads/40d.png

 プロトコルブラウザはクラスの定義を行なう作業には向きませんが、注目するクラスのインスタンスが起動することが可能なメソッドを調べたいときなどにはたいへん重宝するツールです。ぜひ覚えて大いに活用してください。

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

ニュース・解説

今週の解説担当:木下 誠

———————————————————————-
Core Imageで使うプロセッサを指定する方法
———————————————————————-

Tigerで導入されたCore Imageでは、描画にGPUを活用することが出来ます。それと同時に、CPUだけで描画する方法も提供されています。この、GPUとCPUの利用はどのようにして決定されるのか、またはプログラムから利用するプロセッサを指定する方法を解説した、「QA1416: QA1416: Specifying if the CPU or the GPU should be used for rendering.」が公開されました。

プロセッサの選択は、基本的にGPUがARBフラグメントを使えるかどうかによります。また、プロセッサの選択には、Core ImageのCIContextクラスを使います。

QA1416: Specifying if the CPU or the GPU should be used for rendering.
http://developer.apple.com/qa/qa2005/qa1416.html

———————————————————————-
Javaのサンプル3つ
———————————————————————-

Javaのサンプルが3つ公開されました。1つは、Javaからコマンドラインのvmmapを呼び出すサンプルです。他の2つは、グラフィックパフォーマンスを上げるためのものです。

HelloVMMap
http://developer.apple.com/samplecode/HelloVMMap/HelloVMMap.html
GraphicsPerfomanceDemo2
http://developer.apple.com/samplecode/GraphicsPerformanceDemo2/GraphicsPerformanceDemo2.html
GraphicsPerfomanceDemo3
http://developer.apple.com/samplecode/GraphicsPerformanceDemo3/GraphicsPerformanceDemo3.html

———————————————————————-
Quartz Composerのチュートリアル
———————————————————————-

MYCOM PC WEBで、Tigerについてくるグラフィックプログラミング環境であるQuartz Composerのチュートリアル記事、「Quartz Composerによるビジュアルフロープログラミング」が掲載されました。

Quartz Composerは、パッチと呼ばれる小さいモジュールをグラフィカルにつなぐことで、グラフィックモジュールを作り上げるためのプログラミング環境です。すべての処理がリアルタイムで行なわれるため、非常に使いやすく、楽しい環境です。

また、ここで作ったファイルは、Quartz Composerフレームワークを利用することで、自分のアプリケーションで再生することも出来ます。いろいろな使い方が考えられるでしょう。ちなみに、この記事は私、木下が書かせていただきました。

Quartz Composerによるビジュアルフロープログラミング
http://pcweb.mycom.co.jp/articles/2005/05/26/qc/

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

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