2005-09-06
目次
「WebObjects Dev Report」 第20回 田畑 英和
前回に引き続きシステムで扱うデータについて検討していきます。前回は登録者情報について検討してみましたが、今回はその他のデータについてみていきましょう。
現在、以下の3種類のユーザタイプを想定しています。
・MOSA会員
・非会員
・事務局(管理者)
登録したユーザは、それぞれユーザタイプを設定することになりますが、システムを利用するさいにユーザタイプによるアクセス制限をおこないます。例えば「MOSA会員」のみ閲覧可能なページといった制限をおこないます。つまり、アクセスのあったユーザを特定(ログイン認証が必要)して、そのユーザのタイプにより処理を振り分けるということになります。
こういったユーザタイプの実装方法としては何通りか考えられます。まず、ユーザのEntityにユーザタイプ用のAttributeを用意するのがもっとも単純な実現方法でしょう。たとえばMOSA会員は「1」、非会員は「2」、事務局は「0」といったやり方です。たしかに実現方法は単純なのですが、これでは「1」というユーザタイプがなんであるのかといった情報を別途管理する必要があります。
そこで2つ目の方法としては、ユーザタイプ用のEntityを別途用意しておき、ユーザEntityとのRelationを設定します。こうすればユーザタイプはユーザとは切り離して管理でき、ユーザタイプに関する属性を一元管理できるようになります。
また、EOFを用いればオブジェクト指向的アプローチをとることもできます。まず、すべてのタイプのユーザに共通する項目を抽出して、基底ユーザEntityとして定義します。次にその基底ユーザEntityから、各タイプのユーザEntityを派生させ、派生したEntityにはそれぞれのタイプごとに依存する属性情報をAttributeとして追加していきます。このようにモデルを定義すれば、各ユーザタイプをそれぞれ異なったEntityとして表現することができます。
ビジネスマッチングには2種類のやり方があります。1つは登録されているユーザのProfile情報を検索/閲覧し、目的に該当する人材を探すというやり方。もう1つは案件情報を掲載して人材を募集するというやり方です。
後者の人材を募集するやり方では、まず案件の内容をシステムに入力することになりますが、次のようなデータが考えられます。
・概要
・期間
・開発環境
・言語
・地域/条件等
・開発依頼内容
・備考
人材を募集する場合は、案件ベースで一時的に募集する場合と、社員を募集する場合がありますが、上記の項目は一時的に募集する場合を想定しています。
これらのデータですが、基本的には文字列情報として記録することになります。募集情報を検索するとなると、まとまりのあるデータのほうが扱いやすいのですが、募集情報によって様々な要求があるでしょうから、基本的には自由入力とします。言語などは、あらかじめ登録しておいた一覧から選択するような形式でもよいでしょうが、マイナーな言語をどこまで登録するのかといった問題もあります。
マッチング結果として、マッチングの成立件数を記録します。成立の確認をどのようにするかという問題はありますが、マッチング結果はつまり実績になりますので、人材を探すさいに1つの評価基準にもなるでしょう。
もっともネットオークションなどと違って、短期間で成立件数が増えるようなことはないでしょうが、成立件数の他に会員からの紹介推薦文の掲載もおこないます。こちらは会員同士がお互いに推薦をおこなうというものです。実際にビジネスマッチングをおこなった相手からの推薦があれば、よい評価材料にもなるでしょう。
さて、ビジネスマッチングシステムとして扱うデータは以上です。他にも細かなデータや、管理用のデータなどが必要になってきますが、主要なデータとしては以上です。今後はこれらのデータをモデルとして定義してから、アプリケーションの開発を進めていきたいと思います。
小池邦人のCarbon API 徒然草(2005/09/02)
本サンプルアプリケーションでは、データブラウザに登録されたファイル一覧のダブルクリック(もしくは表示ボタンクリック)で、その画像をスクロールバー付きのウィンドウへ表示(オープン)することが可能です。今回からは、自作アプリケーションへの画像表示用ウィンドウの実装について解説していきたいと思います。
Mac OS X 10.2から、Carbon Frameworkには「HIView」という仕組みが導入されました。その仕組みの一部として、「Image View」や「Scroll View」といった新しいユーザインターフェースユニット(旧コントロールの一種)が用意されています。これらと、Carbon Event Handlerををうまく利用することで、画像をスクロールバー付きのウィンドウに表示する機能を簡単に実現することが可能となりました。本サンプルは、このImage ViewとScroll Viewを使うことで、画像ファイルをウィンドウに表示させます。
画像を独立したウィンドウに表示(オープン)させるには、データブラウザの画像ファイル一覧をダブルクリックするか、表示させたい画像ファイルを選択しておいてから、カタログウィンドウの「表示」ボタンをクリックします。後者の場合には、同時に複数の画像ファイルをオープンすることが可能です。前者は、「データブラウザ・コールバックルーチン」を解説した時に紹介した、myNotification()ルーチンが実行していますので、そちらを参照してみてください。後者の場合は、以下のopenSelectedImageFile()ルーチンが実行しています。
#define MAX_FILE 1000 // カタログに登録できる最大ファイル数
void openSelectedImageFile( WindowRef window,short launch )
{
unsigned long i,nb,ct,item[MAX_FILE]; // ファイル最大数は1000
ControlRef browser;
WindowRef wptr;
ObjectPtr optr;
getMyControlRef( window,BROW_ID,&browser ); // ブラウザのControlRefを得る
getSelectedDataBrowser( browser,item,&ct ); // 選択されているアイテムを得る
for( i=0;i
まず最初に、以下のgetSelectedDataBrowser()を使い、データブラウザで選択されている画像ファイルのアイテム番号と、その個数を得ます。
void getSelectedDataBrowser( ControlRef browser,unsigned long item[],
unsigned long *ct )
{
long size;
Handle hd;
*ct=0;
if( hd=NewHandle( 0 ) ) //アイテム番号を保存するためのHandleを確保
{
GetDataBrowserItems( browser,kDataBrowserNoItem,0,
kDataBrowserItemIsSelected,hd );
// 選択されているアイテム番号を得る
if( size=GetHandleSize( hd ) ) // Handleのサイズを得る
{
HLock( hd ); // Handleをロックする
BlockMoveData( *hd,item,size ); // 引数のitem[]へコピーする
*ct=size/sizeof( unsigned long ); // アイテム番号の個数を計算する
}
DisposeHandle( hd ); // 確保したHandleを削除
}
}
アイテム番号から1を引いた値は、カタログウィンドウのプロパティとして保存されているWInfo構造体(以下参照)のw_optr配列の引数と一致します。そこで、getWObject()ルーチンを使い、その番号に対応するObject構造体のポインタを得ておきます。
typedef struct {
WindowRef w_pref; // 親ウィンドウのWindowRef
unsigned long w_count; // ObjectPtrの個数
ObjectPtr w_optr[MAX_FILE]; // ObjectPtrのリスト
} WInfo,*WInfoPtr,**WInfoHandle;
short getWObject( WindowRef window,unsigned long nb,ObjectPtr *optr )
{
WInfo winf;
if( ! getWInfo( window,&winf ) ) // ウィンドウのプロパティとして
{ // 保存されているWInfo構造体を得る
*optr=winf.w_optr[nb]; // 指定番号のObjectPtrを返す
return( noErr );
}
return( 1 );
}
続いて紹介するのは、openSelectedImageFile()で呼ばれているopenViwerWindow()ルーチンです。最初にimageFileToImage()ルーチンで、画像ファイルからCore Graphics Imageを作り、それを、createMyWindow()ルーチンで作成したウィンドウに表示させます。ウィンドウにImage ViewやScroll Viewを配置するのは、setupViwerWindow()ルーチンの役割です。そして最後に、setupViwerWindowEvent()で必要とされるCarbon Event Handlerが登録されています。
short openViwerWindow( WindowRef window,FSSpec *fsc,WindowRef *wptr )
{
short ret=1;
CGImageRef image;
WindowClass wcls;
WindowAttributes watt;
GWorldPtr off;
Rect drt;
if( ! imageFileToImage( fsc,&image,&off,&drt ) )
{ // 画像ファイルからCore Graphics Imageを作る
wcls=kDocumentWindowClass; // ウィンドウクラスはドキュメントにセット
watt=kWindowStandardDocumentAttributes|kWindowLiveResizeAttribute|
kWindowStandardHandlerAttribute|kWindowCompositingAttribute;
// ウィンドウアトリビュートをセット
if( ! createMyWindow( fsc->name,'VIEW',wcls,watt,&drt,fsc,wptr ) )
{ // 画像表示用ウィンドウの作成
if( ! setupViwerWindow( *wptr,image ) ) // ウィンドウの各種初期化
{
setupViwerWindowEvent( *wptr ); // Carbon Event Handlerの登録
setWParent( *wptr ,window ); // 親ウィンドウのセット
ShowWindow( *wptr ); // ウィンドウを表示する
ret=0;
}
else
DisposeWindow( *wptr ); // エラーであれば削除する
}
CGImageRelease( image ); // 得られたCore Graphics Imageをリリース
DisposeGWorld( off ); // オフスクリーン用GWorldを削除
}
return( ret );
}
画像ファイルを選択し、「表示」の代わりに「起動」ボタンが押された場合には、アプリ起動オプションがONで(引数のlaunchが1)openSelectedImageFile()が実行されます。その時、画像を作成したアプリケーションを起動しているのが、launchApplication()ルーチンです。この処理にはシステムのLaunch Servicesが提供するAPIが利用されています。各APIの詳しい内容については、LSInfo.hやLSOpen.hを参照してみてください。
short launchApplication( FSSpec *fsc )
{
short ret=1;
FSRef ref;
if( ! FSpMakeFSRef( fsc,&ref ) ) // FSSpecからFSRefを作成する
ret=LSOpenFSRef( &ref,NULL ); // 作成したアプリをオープンしそれに渡す
return( ret );
}
次回は、openViwerWindow()から呼ばれているimageFileToImage()ルーチンについて解説します。基本的には、画像ファイルからCore Graphics Imageを作る処理なのですが、Mac OS Xのバージョンにより、その方法が大きく異なることを紹介したいと思います。
つづく
SqueakではじめるSmalltalk入門 第46回 鷲見正人
本連載では、名前は知っていてもなかなか触れる機会のないSmalltalkについて、最近話題のSqueakシステムを使って紹介しています。引き続き、ファイルリストの文字化けをフィックスする作業を通じて、Smalltalkならではの便利機能に触れてゆきます。
▼メソッドのバージョンをもとに戻す(バージョン管理システム)
前回、「FileList >> #readContentsBrief:」というメソッドを改変することで、ファイルリストをテキストエディタモードで呼び出したとき、このメソッドが呼び出されていることを確認しました。もはやこの細工は必要ないので、忘れないうちに元に戻しておくことにします。
もちろん追加した行を削除して再コンパイルすれば済むことですが、ここではあえて、Smalltalkシステムのバージョン管理機構を使用して、元のバージョンを復活させてみましょう。
Smalltalkでは、メソッド単位でコンパイルが完結することは、前回すでに体験していただいているとおりです。したがって、バージョン、つまり、改変の履歴も、各メソッドごとに個別に管理されています。注目するメソッドの過去のバージョンを見るには、ブラウザでそのメソッドを閲覧中にウインドウ中段のボタン群の中にある「versions」ボタンをクリックします。
[fig.A]「versions」ボタン
http://squab.no-ip.com:8080/mosaren/uploads/46a.png
バージョンブラウザの上のペインには、そのメソッドの改変履歴がリストで表示されます。リストには、改変者のイニシャル(最初のメソッド改変のときに尋ねられたり、Utilities setAuthorInitialsでセットされたものです)、改変の日時、クラス名、メソッド名の順に表示されています。リストの上に行くほど最近の改変で、一番上のものが現行バージョンです。ためしに現行バージョンをクリックしてみてください。
[fig.B]バージョンブラウザ
http://squab.no-ip.com:8080/mosaren/uploads/46b.png
ウインドウ中段、右端の「diff」(差分表示)オプションがオンになっているので、加えられた行は赤く、また、この差分にはありませんが、削除された行は青い色で、さらに取消線が付いた状態で表示されます。
では、改変を加える前のバージョンに戻してみましょう。上のペインの2行目をクリックして選択します(この時点で、差分の青い取消線表示も確認できるはずです)。選択したバージョンに戻すには、ウインドウ中段のボタン「revert」をクリックします。これだけです。
ウインドウを切り換え、元のブラウザに戻って確認してみると分かりますが、ちゃんとメソッドは手を加える前のバージョンに戻っています。
▼原因メソッドの呼び出し
前回の解析の結果、FileList >> #readContentsBrief:の定義中、
f converter: (self defaultEncoderFor: self fullName).
とあるところで正しくコンバータが設定されていないのが、どうやら文字化けの原因であることが分かりました(簡単のため、そういうことにしてください)。ここでコンバータを生成している、#defaultEncoderFor:というメソッドがなにをしているのかを覗いてみることにしましょう。
Smalltalkのメソッドは、やはりそれ自体がオブジェクトで、自分の定義の中で、どんなメソッドを呼び出しているのか(正確には、呼び出すためのメッセージを送信しているか)を把握しています。たとえば、今、注目している「FileList >> #readContentsBrief:」というメソッドなら、これにmessagesというメッセージを送ることで、自分の定義の中で呼び出しているメソッドの名前の一覧を返してきます。
(FileList >> #readContentsBrief:) messages
=> a Set(#oldFileOrNoneNamed: #defaultEncoderFor: #not #braceWith:with:with:
#translated #contentsOfEntireFile #'<=' #next: #readServerBrief #fullName #close
#converter: #size #format: #isRemoteDirectory #'==')
この性質を利用して、定義の中で送信されているメッセージに関係した情報をたやすく引き出せるように用意されたUIが、ブラウザ中段やや右寄りに並んでいるボタン「senders」と「implementors」です。これらのボタンをクリックすると、現在ブラウズ中のメソッド名に続いて、メソッドにmessgesメッセージを送信したときに得られるメソッド名の一覧がポップアップします。
[fig.C]「implementors」をクリックしたときポップアップするメニュー
http://squab.no-ip.com:8080/mosaren/uploads/46c.png
このポップアップから適当なメソッド名を選ぶと、クリックしたのがたとえば「senders」ならsenders of it、つまり、選択した項目と同名のメソッドを呼び出しているメソッドの一覧がブラウズできます。これは、メソッド名をタイプして入力後、選択してcmd-Nとしたのと同じです。同様に「implementors」ならimplementors of it、つまり、選択した項目と同名のメソッドの定義をブラウズできます(cmd-B、もしくはcmd-Mと同じ)。
今回は、指定したメソッドの定義を見たいので、implementorsボタンをクリックしてdefaultEncoderFor:を選びます。さいわい、この名前を持つメソッドはFileListに定義されたひとつだけです。
[fig.D]FileList >> defaultEncoderFor:の定義
http://squab.no-ip.com:8080/mosaren/uploads/46d.png
最後の行で、a Latin1TextConverterを返していますが、どうやらこれが文字化けの元凶のようです。試しに、文字化けの起こらないa ShiftJISTextConverterを返すように差し替えて動きを見てみましょう。
まず、Latin1TextConverterを選択して、Shiftjまでタイプしたあと、cmd-Qとします(クラス名やメソッド名の補完サービス)。すると、ShiftJISTextConverterと完全なクラス名が挿入されるので、そのままaccept(cmd-S)してコンパイルします。
[fig.E]暫定的なFileList >> defaultEncoderFor:の定義
http://squab.no-ip.com:8080/mosaren/uploads/46e.png
あらためて、どこか適当な場所で、次の式をdo it (cmd-D)してみてください。
(FileStream fileNamed: 'ShiftJisExample.txt') edit
どうでしょう。文字化けは解消されましたね。次回は、この改変の影響を最小限にするため、ファイルの拡張子が.txtか.textの場合だけa ShiftJISTextConverterを返すような仕組みを設けて、このハックを終わりにしようと思います。
バックナンバー:
http://squab.no-ip.com:8080/mosaren/
ニュース・解説
今週の解説担当:木下 誠
----------------------------------------------------------------------
Developer Transition Resource Centerがオープン
----------------------------------------------------------------------
ADCに、Intelチップへのアプリケーションの移行を促進するためのWebページ、「Developer Transition Resource Center」がオープンしました。基本的に、あちこちに分散していたIntel移行に関するドキュメントの、リンク集となっています。
特に目新しい情報はありませんが、今後追加される情報は、要チェックでしょう。WWDCでの関連するセッションのビデオへのリンクがあるのが、うれしいところです。(視聴にはADCへの登録が必要)
また、Universal Binaryへの移行をまとめた記事、「Adopting Universal Binaries」も公開されていました。Universal Binaryの必要性と、そのために必要なリソースを、まとめて紹介する内容になっています。
Developer Transition Resource Center
http://developer.apple.com/transition/index.html
Adopting Universal Binaries
http://developer.apple.com/macosx/adoptinguniversalbinaries.html
----------------------------------------------------------------------
Xcode 2.1の紹介
----------------------------------------------------------------------
Xcode 2.1の機能を紹介する記事、「Working with Xcode: Building Applications for the Future」が公開されていました。Xcodeが持つ機能を、初めて使う人に紹介するような内容になっています。
事実上、Mac OS Xでの開発環境は、Xcodeただ一つになってしまいました。今後は、Intel対応などのような機能の拡張に加え、他の環境からの移行者を受け入れるための、ユーザインタフェースの拡充が求められるでしょう。
Working with Xcode: Building Applications for the Future
http://developer.apple.com/tools/xcode/xcodefuture.html
----------------------------------------------------------------------
Technical Q&A
----------------------------------------------------------------------
新規Technical Q&Aが、4つ公開されていました。
Core Videoに関するもの(QA1440、QA1401)、QuickTimeのテキストトラックに関するもの(QA1400)、IntelマシンでのJavaアプリケーションに関するもの(QA1295)です。
QA1440: Implementing a CVFillExtendedPixelsCallback
http://developer.apple.com/qa/qa2005/qa1440.html
QA1401: Registering custom pixel formats with QuickTime and Core Video
http://developer.apple.com/qa/qa2005/qa1401.html
QA1400: Adding Unicode characters to Text Media in a Text Track
http://developer.apple.com/qa/qa2005/qa1400.html
QA1295: Java on Intel-based Macintosh Computers
http://developer.apple.com/qa/qa2005/qa1295.html
MOSAからのお知らせと編集後記は割愛します