ヘッダーをスキップ
Oracle Application Server Wireless開発者ガイド
10gリリース2(10.1.2)
B15742-02
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

16 ユーザー・カスタマイズの有効化

項ごとに様々なトピックを記載しています。各項の内容は、次のとおりです。

16.1 ユーザー作業環境の概要

OracleAS Wirelessには、ユーザー作業環境を管理するための、セキュアで信頼性の高いスケーラブルな機能が用意されています。ユーザー作業環境により、相互作用をパーソナライズし、アプリケーションの効率を高める柔軟なアプリケーションの開発が可能になります。また、この機能によって、コンテキストを認識した複数モーダルのマルチチャネル・アプリケーションを迅速に開発してデプロイできます。その結果、ユーザー操作が拡大し、一連の匿名トランザクションが継続的な1対1の顧客関係になります。

この章では、ユーザー作業環境を管理するためのOracleAS Wirelessの機能について説明し、高度なカスタマイズ機能を開発するためにユーザー作業環境を適用する手順をサンプルを使用して説明します。通常、カスタマイズは、ユーザーによるシステムの調整方法、つまりシステムをユーザーの特定のニーズや作業環境に適応させる方法を指します。ユーザー中心のカスタマイズ機能によって、ユーザーはシステムをニーズと作業環境にあわせて調整する方法を制御できます。このシステムでは、一般向けカスタマイズ・アプローチも導入できます。このアプローチでは、ユーザー・プロファイリング(ユーザーを類似のユーザー・グループに関連付けるなど)を適用し、ユーザーのニーズと作業環境を予測し、それに応じてシステムを調整します。

アプリケーションでカスタマイズを実行するには、ユーザーのニーズをそのロールと作業環境に基づいて理解する必要があります。たとえば、顧客、仕入先および従業員に、様々な方法であらかじめ情報を送信すると便利です。ユーザーの作業環境とニーズを十分に把握することによって、アプリケーションではユーザー操作を拡大できます。

自動ユーザー・プロファイリングを使用すると、一般向けカスタマイズ・アプローチを導入できます。ユーザーの使用履歴は、OracleAS Wirelessリポジトリ内のptg_service_logの表とptg_session_ logの表で確認できます。この章の一部の例では、OracleAS Wireless Runtimeを拡張して一般向けカスタマイズを導入する方法について説明します。OracleAS Wirelessには、エンド・ユーザーがPCブラウザから自分の作業環境を管理できるサンプル・カスタマイズ・ポータルが組み込まれています。

OracleAS Wirelessのサンプル・カスタマイズ・ポータルは、Oracle Cabo UI XML(uix)およびUI Beansを使用して開発されています。カスタマイズ・ポータルによって、エンド・ユーザーは、通常使用するユーザー・デバイス、フォルダ、アプリケーション(サービスとも呼ばれます)、ブックマーク、通知イベント(アラートとも呼ばれます)、通知アドレス、ロケーション・マーク、プリセットなどのユーザー作業環境をカスタマイズできます。さらに、ユーザーは、コラボレーション・サービスで使用する、連絡ルールとロケーションのプライバシ・ルールを指定できます。UIXコンポーネントとクラス・ライブラリは、特定の機能別にカテゴリ化されています。このUIXコンポーネントを再利用して、サンプル・カスタマイズ・ポータルの特性を変更できます。また、複数のUIXコンポーネントを使用したり組み合せることによって、独自のカスタマイズ・ポータルを開発したり、既存のポータルにカスタマイズ・ウィザードを統合できます。


注意:

カスタマイズ・ポータルのカスタマイズにUIXは不要です。任意のWeb UIフレームワークを使用できます。

カスタマイズ・ポータルの開発時には、Runtime APIData Model APIおよびサンプルのUIXコンポーネントをガイドラインとして参照してください。この章で説明する概念と例は、エンド・ユーザーの操作性を高めるカスタマイズ機能の設計に役立ちます。


カスタマイズ・ポータルの例では、ユーザーは、フォルダの編成、サービスのサブスクライブまたは取消し、1つ以上のカスタマイズ・プロファイルでのブックマークとクイックリンクの作成または削除などを実行できます。ユーザーが実行できる操作は、次のとおりです。

OracleAS Wirelessに用意されているサンプルのデバイス・カスタマイズ・ポータルを使用すると、ユーザーは、Web電話やPDAなどのワイヤレス・デバイスからパーソナル・ポータルを直接カスタマイズできます。デバイス・カスタマイズ・ポータルには、ワイヤレス・デバイスの設定ボタンからアクセスできます。このポータルは、デバイスの限定された表示機能や入力機能を調整し、ユーザーによるユーザー作業環境設定の変更、フォルダとサービス・リンクの編成、ロケーション・マーク、ブックマーク、クイックリンクおよびカスタマイズ・プロファイルの作成、変更または削除が可能な特殊なモードを提供します。

マルチ・ユーザー・カスタマイズ・プロファイルによって、ワイヤレス・デバイスからのナビゲーションが効率的になりパーソナライズされます。ユーザーは、1つ以上のカスタマイズ・プロファイルを保持し、PCまたはデバイス・カスタマイズ・ポータルから管理できます。また、デバイス内で異なるカスタマイズ・プロファイルに切り替えることができます。

OracleAS Wirelessには、ユーザーが入力した値を今後の起動に備えてプリセット値として保存するかどうかを選択するオプションが用意されています。また、OracleAS Wirelessには、プリセットを表す記号名を入力するオプションもあります。これらの記号名を使用すると、プリセット値のグループが複数ある場合に簡単に選択できます。また、ユーザーは任意のデバイスやPCからプリセットを管理できます。

Presetsには、フィールドを一致させるのに必要な数の属性をWebフォームで追加できます。アプリケーション開発者は、プリセット・カテゴリを作成してPresetsの属性を定義できます。各プリセット・カテゴリは、プリセット・カテゴリ名と必要な数のプリセット属性で構成されます。たとえば、Auto-Fill Address Forms Fieldsという名前のプリセット・カテゴリを作成し、1〜3番目の属性としてStreet、City、およびZIPを定義できます。また、ユーザーは、たとえばこのカテゴリにmy work、Mom's homeという複数のPresetsを作成できます。これらのPresetsは、運転方向サービスに対するフォームの自動入力に使用できます。

OracleAS Wirelessのユーザー作業環境には、連絡ルール、ロケーションのプライバシ・ルールと認可ルールが含まれます。連絡ルールはユーザー作業環境設定の1つで、コラボレーション・サービスとメッセージ・サービスで使用されます。連絡ルールは、ユーザーがコールやメッセージを受信する方法を示します。たとえば、ユーザーは会議の連絡ルールを設定する場合、すべての通知を携帯電話で受け取るように設定できます。また、複数の連絡ルールを定義し、それぞれ特定の状況にあわせて適切に設定できます。アクティブにできるのは、一度に1つの連絡ルールのみです。アクティブな連絡ルールによって、ユーザーが使用できるデバイス、およびユーザーへの通知方法を制御します。ロケーションのプライバシ・ルールと認可ルールは、ロケーション・ベースのコラボレーション・サービスで使用されます。ユーザーは、これらのロケーション・ルールを使用して、ユーザーのロケーションをロケーション・ベースのアプリケーションの対象にするかどうか、およびその時期を制御できます。また、ユーザーは、これらのルールを使用して、ユーザーのロケーションを問い合せるサービスまたはユーザーを許可できます。


注意:

連絡ルールの詳細は、『Oracle Application Server Wireless管理者ガイド』を参照してください。

16.2 複数のカスタマイズ・プロファイル

OracleAS Wirelessでは、コンテンツをデバイスとネットワークの機能のみでなく、エンド・ユーザーの作業環境にあわせて調整するユーザー中心のWebサービスを開発できます。通常、デバイス・ポータルにはサービス・メニューが用意されており、複数のフォルダとサブフォルダに編成できます。メニュー方式のデバイス・ポータルは、ワイヤレス・デバイスのナビゲーション効率を最適化するように設計されています。通常、サービス・メニューは静的ですが、ポータルではユーザーのニーズと作業環境に関する情報がより多く記憶されるため、ユーザーに対して新規サービスを提案できます。OracleAS Wirelessサーバーでは、エンド・ユーザーはメニュー上のサービスの配置を制御して、ポータルをパーソナライズできます。ポータルはユーザーに新規サービスを提案できますが、各サービスを自分のパーソナライズ・ポータルに組み込む場合と除外する場合を制御するのはユーザーです。管理者は、特定のサービス(プロモーション、優先パートナ、緊急サービスなど)をパーソナライズ・ポータルで再配置または削除する操作を、エンド・ユーザーに対して明示的に禁止できます。

16.2.1 概要

Profilesを使用すると、ユーザーはポータルのパーソナライズ・バージョンをデバイス用に複数作成できます。サービス・メニューは、プロファイルごとに異なる場合があります。たとえば、ユーザー用フォルダの1つに次のサービスが含まれているとします。

  • 電子メール

  • ニュース

  • 株式

  • マップ

  • 電話帳

  • ショッピング

Homeプロファイルでは、フォルダのサービス・メニューを次のようにカスタマイズできます。

  • 電話帳

  • 電子メール

  • ニュース

  • 株式

同じフォルダを、Travelingプロファイルでは次のようにカスタマイズできます。

  • マップ

  • ショッピング

  • 電話帳

様々なロール、ロケーションまたはコンテキスト、デバイスとネットワークの特性その他の観点について、複数のProfileを作成できます。

これらのロールごとにProfileを作成すると、サービスの効率とアクセス可能性が向上します。複数の都市を頻繁に訪れる移動型ユーザーの場合は、ロケーションごとにプロファイルを作成できます。たとえば、ユーザーが、文化の中心地(イタリアのローマなど)のカスタマイズProfileに、劇場、美術館および交通手段の時刻表のサービスを含めるとします。この同じユーザーは、バイカル湖地域について、異なるサービスを組み合せて別のProfileを使用できます。ロケーション認識ポータルでは、ユーザーが異なるロケーションから接続した場合に、そのユーザーのセッションProfileを自動的に設定できます。Profileはロケーション・マークと関連付けることができます。ロケーション・マークについては、「ロケーション・マーク」の項を参照してください。

OracleAS Wireless Runtime controllerは、ユーザーのProfileを自動的にプロビジョニングするように拡張できます。これによって、たとえば複数タイプのデバイスからポータルの異なるビューを提供できます。ユーザー用のプロファイルを自動的にプロビジョニングする方法は、次の項の例を参照してください。また、エンド・ユーザーは、PCブラウザ経由でカスタマイズ・ポータルを介して、任意のコンテキストのProfileを必要な数だけ作成できます。OracleAS Wirelessツールを使用すると、Profileごとにサービスの配置をカスタマイズできます。

管理者は、共有フォルダのデフォルトのソート規則を指定できます。Profileアーキテクチャでは、エンド・ユーザーはデフォルトのソート規則を変更し、共有フォルダの独自のビューをパーソナライズできます。この場合、次のソート規則から選択できます。

  • 指定した順序番号

  • 五十音順

  • 作成日

  • アクセス頻度

  • 最新アクセス時間

順序番号、五十音順および作成日を選択すると、フォルダの静的ビューが生成されます。アクセス頻度順または最新アクセス時間順にソートすると、フォルダの動的ビューが生成されます。さらに、管理者は、緊急、プロモーションおよび優先パートナのサービスなど、フォルダ内でエンド・ユーザーが再配置できない一部のアプリケーションの静的または動的な配置を制御できます。また、管理者はエンド・ユーザーが再配置または非表示にできるビューのセグメントを指定できます。

フォルダのビューをセグメントに分割し、あるセグメントは管理者の指定に従ってソートされ、別のセグメントはユーザーの指定に従ってソートされるように指定したりできます。

Profileのアーキテクチャによって、管理者がアプリケーションのパーソナライズ可能な属性を明示的に使用禁止にしていない場合、エンド・ユーザーはプロファイル内のサービスの可視性を指定できます。これによって、エンド・ユーザーは、システムによってフォルダに置かれたアプリケーションへのサブスクライブとサブスクライブの取消しができます。また、システムでは、ロケーション対応フォルダ内のサービスにロケーション・ベースのフィルタ処理を適用し、ユーザーのモバイル位置に応じて変化するビューの動的性質を高めることができます。

Runtimeオブジェクトにアクセスするアプリケーションは、ServiceContext.getProfileメソッドから現行のProfileを取得できます。Runtimeオブジェクトの詳細は、9.4.4項「MCS Runtime API」を参照してください。このメソッドは、最初に現行のRequest内でProfileを検索します。現行のRequestでProfileが指定されていない場合、このメソッドはRuntime Session内でセッションのProfileを検索します。セッションのProfileが空の場合は、ユーザーのデフォルトProfileが検索されます。この解消方法によって、RequestでセッションProfileをオーバーライドし、セッションでデフォルトのユーザー・プロファイルをオーバーライドできます。Profileが存在しない場合、ServiceContext.getProfilenullを戻します。アプリケーションは、Profileが未指定の場合にデフォルト動作で反応するように設計する必要があります。

16.2.2 サンプル・アプリケーション

例16-1に、ユーザー・デバイスを自動的にプロビジョニングする方法、および各デバイス・タイプに対してユーザーが使用できるデバイスのProfileを示します。SampleRequestListenerserviceBegin()イベントをリスニングし、[22]行目、[25]行目および[27]行目に新規のユーザー・デバイスとProfileをプロビジョニングします(RequestとSessionによるProfileの指定がない場合は、[17]行目と[19]行目にもプロビジョニングします)。新規Profileについて、[36]行目でユーザーのホーム・フォルダが、中のサービスが最新アクセス時間順にソートされるように設定されます。[39]行目でビューをカスタマイズ可能なサービスごとに、[40]行目でサービスがProfile内で非表示になるように設定されます。エンド・ユーザーは、使用するサービスが表示されるように後でProfileをカスタマイズできます。この操作は、Profileを初めて作成した後に一度のみ行います。リスナーは、[54]行目でRequest内でProfileを設定します。

例16-1 サンプル・アプリケーション

import oracle.panama.model.*;
import oracle.panama.rt.Session;
import oracle.panama.rt.Request;
import oracle.panama.rt.event.RequestAdapter;
import oracle.panama.rt.event.RequestEvent;
import oracle.panama.rt.event.AbortServiceException;
import oracle.panama.PanamaException;

public class SampleRequestListener extends RequestAdapter {

    public void serviceBegin(RequestEvent event) throws AbortServiceException {
        Request request = event.getRequest();
        Session session = request.getSession();
        User user = session.getUser();

        Profile profile = request.getProfile();         //[17]

        if (profile == null)
            profile = session.getProfile();                //[19]
        if (profile == null) {
            Device device = request.getDevice();
            String deviceName = device.getName();
            Profile deviceProfile;
            synchronized(user) {
                ModelFactory factory = MetaLocator.getInstance().getModelFactory();
                UserDevice userDevice = user.lookupUserDevice(deviceName);
                boolean deviceProfileCreated = false;
                if (userDevice == null) {
                    userDevice = user.createUserDevice();    //[22]
                    userDevice.setName(deviceName);
                    userDevice.setDisplayName("My user device name for " + deviceName);
                    try {
                        factory.save();
                        deviceProfileCreated = true;
                    } catch (PanamaException ex) {
                        deviceProfile = null;
                    }
                }
                deviceProfile = userDevice.getUserProfile();
                if (deviceProfile == null) {
                    deviceProfile = user.lookupProfile(deviceName);         //[25]
                    if (deviceProfile == null) {
                        deviceProfile = user.createProfile(deviceName);      //[27]
                    }
                    try {
                        factory.save();
                        deviceProfileCreated = true;
                    } catch (PanamaException ex) {
                        deviceProfile = null;
                    }
                }

                if (deviceProfileCreated) {
                    boolean needCommit = false;
                    Folder home = user.getHomeFolder();
                    deviceProfile.setSortRule(home, SortRule.SORT_BY_ACCESS_TIME_ASCEND);    //[36]
                    Service[] services = home.getAccessibleUserServices(user);
                    for (int i = 0; i < services.length; i++) {
                        if (services[i].isViewCustomizable()) {           //[39]
                            deviceProfile.setHide(services[i], true);      //[40]
                            needCommit = true;
                        }
                    }
                    try {
                        if (needCommit)
                            factory.save();
                    } catch (PanamaException ex) {

                    }
                }
            }
                       }
        if (deviceProfile != null)
            request.setProfile(deviceProfile);                  //[54]

}

16.3 Presets

OracleAS Wirelessでは、広範囲にカスタマイズを適用するための機能が提供されているため、開発者やエンド・ユーザーはパーソナライズされたポータルを作成できます。これにより、ポータルと各エンド・ユーザーとの1対1の関係が強化されます。主要な機能の1つは、ユーザーの個人情報、作業環境の設定、頻繁に使用する入力パラメータをサーバー側に格納するためのPresetsです。アプリケーションはPresetsを使用してパーソナライズされたレスポンスを生成できます。

OracleAS Wirelessリポジトリには、永続属性が事前に定義されているポータル・ユーザーの概念が含まれています。この基本的な属性には、名前、性別、生年月日、国、言語、ロケールなどがあります。PresetsはOracleAS Wirelessリポジトリ内の永続オブジェクトであり、特にリポジトリにユーザー・オブジェクト用の新規永続属性を取り込むなど、リポジトリ・スキーマの拡張に使用できます。

16.3.1 Presetsの概念とアーキテクチャ

PresetsはOracleAS Wirelessリポジトリ内の永続オブジェクトです。このオブジェクトを使用すると、ユーザー・スキーマを拡張し、ユーザーの個人情報をリポジトリに取り込むことができます。アプリケーションの開発者は、プリセット・カテゴリを定義してユーザー・スキーマをアプリケーション固有の方法で拡張できます。たとえば、請求先住所、クレジット・カード引落し口座、銀行口座、手数料引落し口座、株式のポートフォリオ、緊急時の連絡先などを取り込むことができます。このように拡張されたスキーマは、Personal Information Management(PIM)サービスで定義し、排他的にメンテナンスできます。

Presetsを使用すると、リポジトリにユーザー作業環境を取り込むこともできます。リポジトリ内の標準的なユーザー・エージェント・タイプとデバイス・モデルによって、デバイスの機能が記述されます。個々のエンド・ユーザーは、ユーザー・エージェントの機能の一部をカスタマイズできます。ユーザー・エージェント・プロファイルのPresetsを使用すると、エンド・ユーザーは、サウンドの有効化または無効化、背景色の選択、サービス品質の選択、イメージを使用禁止にしてパケット送信を最小限に抑えるなど、ユーザー・エージェントの機能をカスタマイズできます。ユーザー・エージェント・プロファイルによってコンテンツのフォーマットが制御されますが、一般的なユーザー作業環境プロファイルをアプリケーションの選択とアプリケーションのレスポンスに反映させることができます。たとえば、アプリケーションでは、スポーツ、エンタテインメント、テクノロジ、プライバシ要件などに関するユーザー作業環境プロファイルを使用して、コンテンツをフィルタ処理できます。Presetsアーキテクチャでは、新しいComposite Capability/Preference Profile(CC/PP)、ユーザー・エージェント・プロファイル(WAP UAProf)およびPlatform for Privacy Preferences(P3P)規格(www.wapforum.org)に基づいて、適応Webサービスを開発できます。

また、Presetsには、アプリケーションに頻繁に使用される入力パラメータも格納できます。アプリケーションでは、Presetsの属性をアプリケーションで使用されるフォームに近似となるように定義できます。これらのPresetsは、フォームへの自動入力に使用できます。アプリケーションには、ユーザー入力を後で使用できるようにPresetsとして格納できます。Presets名では入力パラメータ値が一意に識別され、この名前をショートカットとして使用するとデータ入力量を大幅に削減できます。

リポジトリには、様々なカテゴリのPresetsがあります。各Presetsリレーションにはプリセット属性値のセットが含まれており、属性値の型とリレーションはプリセット・カテゴリで定義されています。ユーザーは、各プリセット・カテゴリ内で1つ以上のPresetsリレーションを所有できます。各プリセット・カテゴリにはプリセット記述子のコレクションが含まれており、Presetsリレーションの属性のメタ情報を提供します。属性のメタデータは、属性の名前、型、サイズ、フォーマットおよび記述などです。たとえば、住所録プリセット・カテゴリのPresetsリレーションには、ユーザーの連絡先の名前、住所および電話番号の属性を含めることができます。このようなプリセット・カテゴリは、Personal Information Management(PIM)アプリケーションで定義し、排他的にメンテナンスできます。別のプリセット・カテゴリでは、ユーザーがリストやポートフォリオを注視している企業の銘柄コード、名前および分類を含むPresetsリレーションの属性を定義できます。このカテゴリの銘柄コードを、株価サービスの入力パラメータとして使用できます。

プリセット・カテゴリには、リポジトリ内で一意の名前を使用する必要があります。同様に、プリセット記述子には、属しているプリセット・カテゴリ内で一意の名前を使用してください。Presetsリレーション名はオプションですが、指定する場合は、同じプリセット・カテゴリ内で同じユーザーが所有しているPresetsリレーション間で一意の名前にする必要があります。プログラムによって作成されたプリセット・カテゴリは、デフォルトでシステムとしてマークされます。つまり、アプリケーションによって排他的にメンテナンスされます。システム・レベルのプリセット・カテゴリは、カスタマイズ・ポータル内では参照できず、エンド・ユーザーは直接編集できません。アプリケーションでは、プリセット・カテゴリを非システムに設定できます。これによって、そのPresetsをエンド・ユーザーがカスタマイズ・ポータル内で編集できます。

16.3.2 サンプル・アプリケーション

プリセット・カテゴリは、次の例のようにプログラムによって作成できます。また、OracleAS Wirelessツールの「プリセット定義」コントロール・パネルで作成する方法もあります。

16.3.2.1 例1: ユーザー・スキーマへの属性の追加

例16-2に、プリセット・カテゴリBilling Addressを作成してユーザー・スキーマを拡張する方法を示します。このメソッドは、最初に[13]行目で、Billing Addressカテゴリがリポジトリにすでに存在しているかどうかをチェックします。このカテゴリが存在しない場合は、[21]行目でModelFactoryのメソッドcreatePresetCategory(Billing Address)を使用して作成されます。[23][27]行目では、カテゴリの最初の属性Addressee Nameが定義されます。[25]行目では、最初の属性を1行のテキストで構成するように定義されます。これに対して、第2の属性Street Addressは、[31]行目で複数行のテキスト・フィールドとして定義されます。新規のプリセット・カテゴリは、[47]行目でコミットされます。

例16-2 ユーザー・スキーマへの属性の追加

import oracle.panama.model.ModelFactory;
import oracle.panama.model.PresetCategory;
import oracle.panama.model.PresetDescriptor;
import oracle.panama.ArgumentType;
import oracle.panama.PanamaException;

public void createAddressBook() throws PanamaException {

        ModelFactory factory = MetaLocator.getInstance().getModelFactory();
        ModelServices services = MetaLocator.getInstance().getModelServices();


        PresetCategory category;
        try {
            category = services.lookupPresetCategory("Billing Address");    [13]
        } catch (PanamaRuntimeException ex) {
            category = null;
        }

        if (category != null) {
            return;   // category already exists
        }
         category = factory.createPresetCategory("Billing Address");        [21]

        PresetDescriptor descriptor = category.createPresetDescriptor("Addressee Name");   [23]
        descriptor.setDescription("The name of the addressee");
        descriptor.setPresetType(ArgumentType.SINGLE_LINE);   [25]
        descriptor.setStoredType(Java.sql.Types.VARCHAR);
        descriptor.setSize(new Long(40));[27]

        descriptor = category.createPresetDescriptor("Street Address");
        descriptor.setDescription("The street address");
        descriptor.setPresetType(ArgumentType.MULTI_LINE);    [31]
        descriptor.setStoredType(Java.sql.Types.VARCHAR);
        descriptor.setSize(new Long(120));

        descriptor = category.createPresetDescriptor("State");
        descriptor.setDescription("The name of the state");
        descriptor.setPresetType(ArgumentType.SINGLE_LINE);
        descriptor.setStoredType(Java.sql.Types.VARCHAR);
        descriptor.setSize(new Long(2));

        descriptor = category.createPresetDescriptor("Zip code");
        descriptor.setDescription("The postal zip code");
        descriptor.setPresetType(ArgumentType.SINGLE_LINE);
        descriptor.setStoredType(Java.sql.Types.NUMERIC);
        descriptor.setSize(new Long(5));

        factory.save();   [47]
    }

プリセット・カテゴリには、リポジトリ内で一意の名前を使用する必要があります。アプリケーションが同じ名前でプリセット・カテゴリの作成を試行すると、ModelFactoryのcreatePresetCategory()メソッドがoracle.panama.model.NameUniquenessViolationExceptionをスローします。同様に、プリセット記述子には、プリセット・カテゴリ内で一意の名前を使用する必要があります。アプリケーションが同じ名前でプリセット記述子の作成を試行すると、PresetCategoryのcreatePresetDescriptor()メソッドがoracle.panama.model.NameUniquenessViolationExceptionをスローします。プリセット・カテゴリとプリセット記述子の名前には大/小文字区別があり、空白など、有効な任意の文字を使用できます。

16.3.2.2 例2: ユーザーの一意のPresetsリレーションの追加

例16-3に、プリセット・カテゴリBilling Addressを使用してユーザーに永続属性を追加する方法を示します。Billing Addressカテゴリが存在しない場合、このメソッドは新規カテゴリを作成します。この例では、Presets名としてユーザーの一意のオブジェクトIDを使用しています。新規のPresetsリレーションは、[13]行目の参照メソッドで同じ名前を持つ既存のPresetsリレーションが見つからない場合にのみ、[16]行目で作成されます。Presets名としてオブジェクトIDを使用すると、各ユーザー用にBilling AddressのPresetsリレーションのインスタンスが確実に1つのみ作成されます。Presetsリレーションの属性値は、[18][21]行目で変更されます。変更されたPresetsリレーションは、[23]行目でリポジトリにコミットされます。

例16-3 ユーザーへの永続属性の追加

import oracle.panama.model.*;

public void addBillingAddress(User user, String addressee, String streetAddress,
                             String state, int zipCode) throws PanamaException {
        ModelFactory factory = MetaLocator.getInstance().getModelFactory();
        ModelServices services = MetaLocator.getInstance().getModelServices();

        PresetCategory category;
        try {
            category = services.lookupPresetCategory("Billing Address");
        } catch (PanamaRuntimeException ex) {
            createAddressBook();[9]
            category = services.lookupPresetCategory("Billing Address");
        }

        Presets presets = user.getPresets(category, Long.toString(user.getId()));[13]

        if (presets == null) {
            presets = user.createPresets(category, Long.toString(user.getId()));    [16]
        }

        presets.setPresetValue("Addressee Name", addressee);    [18]
        presets.setPresetValue("Street Address", streetAddress);
        presets.setPresetValue("State", state);
        presets.setPresetValue("Zip code", Integer.toString(zipCode));     [21]


        factory.save();   [23]
    }

Presetsリレーションには、ユーザーのドメイン内で一意の名前を使用する必要があります。アプリケーションが同じユーザー用に同じ名前でPresetsの作成を試行すると、ユーザーのcreatePresets()メソッドがoracle.panama.model.NameUniquenessViolationExceptionをスローします。Presetsリレーション名には大/小文字区別があり、空白など、有効な任意の文字を使用できます。

16.3.2.3 例3: ユーザーのProfile用の一意のPresetsリレーションの追加

Profileは、ユーザーごとにパーソナライズされたポータルの複数バージョンをサポートするリポジトリ・オブジェクトです。ユーザーがBusiness用とPersonal用に1つずつProfileを持ち、Profileごとに別個のクレジット・カード引落し口座が必要であるとします。例16-4のコードに、Credit Card Charge Accountカテゴリと、ユーザーの各プロファイルに対して一意のPresetsリレーションを作成する方法を示します。プロファイルごとに1つのみPresetsリレーションが作成されるように、[43]行目でUserおよびProfileのオブジェクトIDから一意のPresets名が作成されます。この例は、Card Type属性にプリセット・タイプArgumentType.ENUMを使用する方法も示しています。ENUMタイプを使用すると、[28]および[30]行目のように、その属性に有効なオプションを指定できます。[60][62]行目は、永続記憶域にJava.sql.Dateタイプを使用する方法を示しています。クレジット・カードの有効期限は、解析してリポジトリにDate型として格納できるように、[61]行目でJava.text.DateFormatユーティリティを使用してフォーマットされます。

例16-4 ユーザーのProfileへの一意のPresetsの追加

import oracle.panama.model.*;
import Java.util.Date;
import Java.text.DateFormat;

public void addCreditAccount(User user, Profile profile, String cardNumber,
                            String cardType, int expireMonth, int expireYear)
                            throws PanamaException {
        ModelFactory factory = MetaLocator.getInstance().getModelFactory();
        ModelServices services = MetaLocator.getInstance().getModelServices();

        PresetCategory category;
        try {
            category = services.lookupPresetCategory("Credit Card Charge Account");
        } catch (PanamaRuntimeException ex1) {
            try {
                category = factory.createPresetCategory("Credit Card Charge Account");
            } catch (PanamaException ex2) {
                throw ex2;
            }


            PresetDescriptor descriptor = category.createPresetDescriptor("Account Number");
            descriptor.setDescription("The credit card account number");
            descriptor.setPresetType(ArgumentType.SINGLE_LINE);
            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(40));

            descriptor = category.createPresetDescriptor("Card Type");
            descriptor.setDescription("The type of credit card");
            descriptor.setPresetType(ArgumentType.ENUM);    [25]
            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(40));
            String cardTypes[] = { "Master", "Visa", "Discover", "American Express", "Diners Club" };      [28]
            try {
                descriptor.setOptions(cardTypes);     [30]
            } catch (TooManyOptionsException ex3) {
                throw new PanamaException(ex3);
            }

            descriptor = category.createPresetDescriptor("Expiration Date");
            descriptor.setDescription("The expiration date of the credit card");
            descriptor.setPresetType(ArgumentType.SINGLE_LINE);
            descriptor.setStoredType(Java.sql.Types.DATE);

            factory.save();      [40]
        }

        String presetsName = Long.toString(user.getId()) + "-" + Long.toString(profile.getId()); [43]
        Presets presets = profile.getPresets(category, presetsName);
        if (presets == null) {
            presets = profile.createPresets(category, presetsName);
        }

        presets.setPresetValue("Account Number", cardNumber);
        presets.setPresetValue("Card Type", cardType);
        Date date = new Date(expireYear, expireMonth, 1);   [60]
        String dateStr = DateFormat.getInstance().format(date);    [61]
        presets.setPresetValue("Expiration Date", dateStr);    [62]

        factory.save();     [64]
    }

16.3.2.4 例4: 現行のProfileでのPresetsリレーションの選択

例16-5では、serviceBegin()イベント通知中のCredit Card Charge AccountのPresetsリレーションへのアクセス方法を示します。このコード例はリクエスト・リスナーから抜粋しました。ユーザーに使用可能な有効なクレジット・カード引落し口座がない場合、このルーチンはAbortServiceExceptionをスローします。また、[14]および[16]行目のように、リクエスト・プロファイル、セッション・プロファイルまたはデフォルトのユーザー・プロファイルを順番にチェックします。Presets名は、UserとProfileのオブジェクトIDで構成されます。Credit Card Charge AccountのPresetsリレーションが見つかると、リスナーは[51][52]行目でクレジット・カード情報をサービスにリクエスト・パラメータとして提供します。

例16-5 Presetsリレーションへのアクセス

import oracle.panama.rt.event.RequestEvent;
import oracle.panama.rt.event.AbortServiceException;
import oracle.panama.rt.Session;
import oracle.panama.rt.Request;

public void serviceBegin(RequestEvent event) throws AbortServiceException {
        Request request = event.getRequest();
        PresetCategory category;
        String presetsName;
        ModelServices services = MetaLocator.getInstance().getModelServices();
        String serviceName = request.getServicePath();
        User user;

        Profile profile = request.getProfile();      [14]
        if (profile == null) {
            profile = request.getSession().getProfile();    [16]
        }
        if (profile != null) {
            user = profile.getUser();
            presetsName = Long.toString(user.getId()) + "-" + Long.toString(profile.getId());
        } else {
            user = request.getSession().getUser();
            presetsName = Long.toString(user.getId());
        }

        try {
            category = services.lookupPresetCategory("Credit Card Charge Account");
        } catch (PanamaRuntimeException ex1) {
            throw new AbortServiceException("This service " + serviceName + " requires a valid charge account");
        }

        Presets presets = null;
        if (profile == null) {
            presets = user.getPresets(category, presetsName);
        } else {
            presets = profile.getPresets(category, presetsName);
            if (presets == null) {
                presets = user.getPresets(category, presetsName);
            }
        }

        if (presets == null) {

            throw new AbortServiceException("This service " + serviceName + " requires a valid charge account");
        }

        String creditCardNumber;
        String cardType;
        String expiration;
        try {
            creditCardNumber = presets.getPresetValue("Account Number");
            cardType = presets.getPresetValue("Card Type");
            expiration = presets.getPresetValue("Expiration Date");
        } catch (PanamaException ex) {
            throw new AbortServiceException("This service " + serviceName + " requires a valid charge account");
        }

        if (! creditAvailable(creditCardNumber, cardType, expiration)) {
            throw new AbortServiceException("This service " + serviceName + " requires a valid charge account");
        }

        request.setParameter("Account Number", creditCardNumber);     [51]
        request.setParameter("Card Type", cardType);      [52]
        request.setParameter("Expiration Date", expiration);    [53]
    }

前述の例は、アプリケーションでPresetsリレーションに予約済のネーミング規則を使用する必要があるが、Presets名自体はオプションであるという使用例に基づいています。次の例に、複数セットのエントリを使用できるプリセット・カテゴリAppointmentsを示します。Presetsリレーションの識別は、その属性の1つで提供されます。この例では、Presetsは名前なしで作成されます。

16.3.2.5 例5: 名前指定なしのPresetsの作成

例16-6に、ユーザーに予定イベントを作成させるプリセット・カテゴリAppointmentsを示します。属性Short Titleを使用してイベントを識別するため、[65]行目のようにイベントPresetsは名前なしで作成されます。ユーザー用のすべてのイベントPresetsは、[97]行目のようにリポジトリから取り出すことができます。Appointmentsカテゴリは、[25]行目で非システムに設定されているため、このカテゴリはエンド・ユーザーが編集できるようにカスタマイズ・ポータルに組み込むことができます。この例は、DateFormatユーティリティを使用して、イベントの時刻を[69]行目で保存し、[105]行目で取り出す方法を示しています。期限切れになったイベントは、[112]行目でリポジトリから削除されます。また、この例は、正規表現を使用してPhone Number属性のフォーマットに制約を適用する方法も示しています。この正規表現には、パブリック・ドメインorg.apache.regexp.REのツールセットとの互換性があります。[59]行目の正規表現は、次のようにUSロケールの電話番号に関するものです。

"\s*[(]?[1-9]\d{2}[)]?\s*-?\s*\d{3}\s*-?\s*\d{4}"

この正規表現にはエスケープ文字がありません。[77]行目のsetPresetValue()メソッドは、値が正規表現と一致しないと、Presets内でPanamaExceptionをスローします。org.apache.regexp.REツールセットと互換性のある正規表現の構文の詳細は、次の項を参照してください。

例16-6 Presetsの作成

import oracle.panama.model.*;
import oracle.panama.PanamaException;
import oracle.panama.PanamaRuntimeException;
import oracle.panama.ArgumentType;

import Java.util.Vector;
import Java.util.Enumeration;
import Java.util.Date;
import Java.text.DateFormat;
import Java.text.ParseException;

public class SamplePresets {

    public void addAppointment(User user, String title, String memo, Date time,
                               boolean alarm, String phone) throws PanamaException {
        ModelFactory factory = MetaLocator.getInstance().getModelFactory();
        ModelServices services = MetaLocator.getInstance().getModelServices();

        PresetCategory category;
        try {
            category = services.lookupPresetCategory("Appointments");
        } catch (PanamaRuntimeException ex1) {
            try {
                category = factory.createPresetCategory("Appointments");
                category.setSystem(false);         [25]
            } catch (PanamaException ex2) {
                throw ex2;
            }

            PresetDescriptor descriptor = category.createPresetDescriptor("Short Title");
            descriptor.setDescription("Brief description of the event");
            descriptor.setPresetType(ArgumentType.SINGLE_LINE);

            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(40));

            descriptor = category.createPresetDescriptor("Memo");
            descriptor.setDescription("Memo for the event");
            descriptor.setPresetType(ArgumentType.MULTI_LINE);
            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(400));

            descriptor = category.createPresetDescriptor("Time");
            descriptor.setDescription("Time of event");
            descriptor.setPresetType(ArgumentType.SINGLE_LINE);
            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(40));

            descriptor = category.createPresetDescriptor("Alarm");
            descriptor.setDescription("Enable or disable alarm before event");
            descriptor.setPresetType(ArgumentType.SINGLE_LINE);
            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(1));

            descriptor = category.createPresetDescriptor("Phone Number");
            descriptor.setDescription("Optional phone number to ring for alarm");
            descriptor.setPresetType(ArgumentType.SINGLE_LINE);
            descriptor.setStoredType(Java.sql.Types.VARCHAR);
            descriptor.setSize(new Long(40));
            descriptor.setFormat("\\s*[(]?[1-9]\\d{2}[)]?\\s*-?\\s*\\d{3}\\s*-?\\s*\\d{4}");      [59]
            descriptor.setEmptyOK(true);

            factory.save();
        }

        Presets presets = user.createPresets(category);    [65]

        presets.setPresetValue("Short Title", title);
        presets.setPresetValue("Memo", memo);
        String timeStr = DateFormat.getDateTimeInstance().format(time);   [69]
        presets.setPresetValue("Time", timeStr);
        if (alarm) {
            presets.setPresetValue("Alarm", "Y");
        } else {
            presets.setPresetValue("Alarm", "Y");

        }
       try {
            presets.setPresetValue("Phone Number", phone);         [77]
        } catch (PanamaException ex) {
            // ignore
        }

        factory.save();
    }

    public Presets[] getAppointments(User user) throws PanamaException {
        ModelFactory factory = MetaLocator.getInstance().getModelFactory();
        ModelServices services = MetaLocator.getInstance().getModelServices();

        PresetCategory category;
        try {
            category = services.lookupPresetCategory("Appointments");
        } catch (PanamaRuntimeException ex1) {
            throw new PanamaException(ex1);
        }

        Date now = new Date(System.currentTimeMillis());
        Vector allPresets = user.getAllPresets(category);       [97]
        Enumeration enum = allPresets.elements();
        Vector pending = new Vector();
        while (enum.hasMoreElements()) {
            Presets event = (Presets) enum.nextElement();
            String timeStr = event.getPresetValue("Time");
            Date time;
            try {
                time = DateFormat.getDateTimeInstance().parse(timeStr);   [105]
            } catch (ParseException ex) {
                time = null;
            }
            if (time != null && time.after(now)) {
                pending.add(event);
            } else {
                user.deletePresets(category, new Long(event.getId()));    [112]
            }
        }
        factory.save();

        Presets presetsArray[] = new Presets[pending.size()];
        pending.copyInto(presetsArray);
        return presetsArray;

    }

}

16.3.3 Presets属性フォーマットの正規表現の構文

次の表に、フォーマットの定義に使用できる正規表現の構文を示します。

表16-1 Presets属性フォーマットの定義で使用する文字

文字 説明

char

同一の1文字と一致

\

エスケープ文字として使用(例: ¥*、¥¥、¥w)

\\

単一の¥文字と一致

¥0nnn

指定の8進番号を持つ1文字と一致

¥xhh

指定の8ビット16進値を持つ1文字と一致

¥¥uhhhh

指定の16ビット16進値を持つ1文字と一致

¥t

タブ文字と一致

¥n

改行文字と一致

¥r

復帰文字と一致

¥f

改ページ文字と一致


表16-2 文字クラス

文字 説明

[abc]

単純な文字クラス

[a-zA-Z]

範囲指定による文字クラス(範囲は"-"と"]"で指定) 例: [x-z]

[^abc]

否定による文字クラス、指定の文字を除外する


表16-3 標準POSIX文字クラス

文字 説明

[:alnum:]

英数字

[:alpha:]

アルファベット

[:digit:]

数字

[:upper:]

大文字のアルファベット

[:lower:]

小文字のアルファベット

[:space:]

空白(スペース、タブ、改ページなど)


表16-4 変数クラス

クラス 説明

.

改行を除く任意の文字と一致

¥w

英数字1文字と一致

¥W

英数字以外の1文字と一致

¥s

空白文字と一致

¥S

空白以外の1文字と一致

¥d

数字1文字と一致

¥D

数字以外の1文字と一致


表16-5 境界との一致

構文 説明

^

行頭と一致

$


行末と一致

¥b

ワード境界と一致

¥B

ワード境界以外と一致


表16-6 最長一致閉包(できるだけ多数の要素との一致)

要素 説明

A*

Aと0回以上一致(最長一致)

A

Aと1回以上一致(最長一致)

A?

Aと1回または0回一致(最長一致)

A{n}

Aと正確にn回一致(最長一致)

A{n,}

Aとn回以上一致(最長一致)

A{n,m}

Aとn回以上m回以内で一致(最長一致)


表16-7 最短一致閉包(できるだけ少数の要素との一致)

要素 説明

A*?

Aと0回以上一致(最短一致)

A?

Aと1回以上一致(最短一致)

A??

Aと0回または1回一致(最短一致)


表16-8 論理演算子

演算子 説明

AB

Bが続くAと一致(連結)

A|B

AまたはBと一致(共用体)

(A)

"("


16.4 ロケーション・マーク

位置情報依存サービスは、OracleAS Wirelessの主要機能です。ユーザーのロケーションを、E911またはGPSユニット、あるいはロケーション・マークから取得できます。ロケーション・マークは、ユーザー定義ロケーションです。たとえば、エンド・ユーザーがロケーション認識アプリケーションに自宅、職場および本社の住所を入力するとします。次にレストラン検索アプリケーションを使用すると、そのアプリケーションでは現在のロケーションを使用して運転方向を提供できます。セキュリティとプライバシを確保するために、ユーザーは自分のロケーションにアクセスできるアプリケーションを制御できます。

電話など、ある種のモバイル・デバイスは制限を伴うため、長い英数字文字列を入力したり表示するのは困難です。ロケーション・マークにより、簡潔でわかりやすい名前で識別される1つの空間情報が格納されます。たとえば、My Homeがロケーション・マーク名で、内部的な空間情報が123 Main Street, Somewhere City, CA, 12345; Lon = -122.42, Lat = 37.58となる場合があります。

ユーザーは、ロケーション・マークを全面的に制御でき、任意のデバイスまたはPCでロケーションを簡単に選択、作成、削除および変更できます。

また、ロケーション・マークを使用すると、ユーザーはwhat-if?シナリオを試行して、アプリケーションをデフォルト・ロケーションや現在のロケーションとは異なるロケーションにあるかのように動作させることができます。たとえば、エンタテインメント・サービス・アプリケーションのユーザーがボストンにいて、数日後にモンテビデオに旅行するとします。このユーザーがモンテビデオにロケーション・マークを設定すると、モンテビデオ地域に関連する情報とともに表示されます。各ユーザーはパーソナライズされたロケーション・マークを使用できます。これらはWirelessリポジトリに格納されます。

ロケーション・マークはロケーション・マーク・クラスを使用して作成します。また、ユーザーがロケーション・マークを作成するには、OracleAS Wirelessカスタマイズ・ポータルにログインし、「ロケーション・マーク」タブをクリックして「作成」をクリックする方法もあります。ジオコーディング、マッピング、ルーティング、トラフィックおよびリージョン・モデリングの各サービスでロケーション・マークを使用する方法の詳細は、第15章「ロケーション・サービスの使用」を参照してください。ロケーション・マークは、地点(緯度と経度)または都市の範囲内の空間的な地域としてジオコーディングできます。

例16-7では、ユーザーJohnBSmithの職場の住所用のロケーション・マークを作成し、ユーザーのロケーション・プロファイルNEDC AREA LOCATION PROFILEに割り当てる方法を示します。ユーザーは、自分のデバイスからこのロケーション・プロファイルに切り替えて、ロケーション認識サービスからのレスポンスを調整できます。

例16-7 ロケーション・マークの作成

public void createLocations() throws Exception {
        User user = services.lookupUser("JohnBSmith");
        Point point = SpatialManager.createPoint(-71.455, 42.7117);
        Location location = SpatialManager.createLocation(point,"", "","1 oracle drive", "", "nashua", "nh", "03062", "", "", "", "","us");
        LocationMark locMark = factory.createLocationMark("NEDC AREA", user, location, 2.0);
        Profile locationProfile = user.createProfile("NEDC AREA LOCATION PROFILE");
        locationProfile.setLocationMark(locMark);
        factory.save();
    }

16.5 ユーザー・デバイスの管理

複数デバイスを使用するユーザーは、OracleAS Wirelessによって各デバイスのモバイル操作を簡単に管理および最適化できます。デバイスの管理には、PCまたはモバイル・デバイスを使用できます。また、ユーザーは現行のデフォルト・デバイスを簡単に変更できます。

ユーザー・デバイス・オブジェクトを使用すると、同じエンティティ内の複数のデバイス・アドレスをグループ化できます。これは、同じデバイスに複数のユーザー・エージェントが含まれている可能性がある場合、または同じデバイスで、アドレスやIDはそれぞれ異なるが、すべて同じ物理エンティティから生成されている複数のプロトコルやチャネルが使用されている可能性がある場合に役立ちます。さらに、1つのユーザー・エージェントの作業環境設定、ロケーション設定およびデバイス設定が、同じデバイス上の別のユーザー・エージェントに影響を与える場合があります。カスタマイズ・プロファイルは、各ユーザー・デバイス・オブジェクトに対して自動的に作成されます。

ユーザーが新規デバイスのプロファイルを作成すると、デバイスごとに次の属性を入力できます。

16.6 ユーザーとグループの管理

OracleAS Wirelessには、任意のフォルダまたはアプリケーションへのアクセスを制限したりアクセス権を付与するためのグループとユーザーの管理およびアクセス制御リスト(ロールとも呼ばれる)が用意されています。ユーザー・マネージャのロールが付与されているユーザーは、任意のデバイスまたはPCを介してグループとユーザーを作成、削除および変更できます。

GroupオブジェクトとUserオブジェクトは、フォルダとアプリケーションに対するアクセス制御を定義するための便利なメカニズムを表します。ユーザーは、1つ以上のグループのメンバーである場合があります。すべてのフォルダやアプリケーションは個々のユーザーが所有していますが、グループに割り当てることによって、ユーザーのグループ間で共有できます。フォルダまたはアプリケーションをグループに割り当てると、そのグループ内のすべてのユーザーには、そのフォルダまたはアプリケーションへのアクセス権が付与されます。

ユーザーは、所有するフォルダ、および自分のプライベート・フォルダに格納されたアプリケーションを完全に制御できます。また、自分のプライベート・フォルダ内でアプリケーションを作成、削除または変更できます(特にブックマークとクイックリンク)。

16.7 Service Management

OracleAS Wirelessでは、開発者はエンド・ユーザーが実行できるフォルダ管理操作を完全に制御できます。また、グループやユーザーにService Managementでの全面的な柔軟性を与えるか、Service Managementの使用を制限できます。

サービスとフォルダは、次の方法で編成できます。

また、エンド・ユーザーは、ブックマークとクイック・リンクを使用して、モバイル操作をカスタマイズできます。これによって、頻繁にアクセスするサービスをホーム・デッキまたは他の必要なフォルダにリンクできます。