ヘッダーをスキップ
Oracle OLAP Java API開発者ガイド
11g リリース1(11.1)
E05733-01
  目次へ
目次
索引へ
索引

前へ
前へ
 
次へ
次へ
 

5 Sourceオブジェクトの理解

この章では、問合せの指定に使用するSourceオブジェクトについて説明します。Sourceオブジェクトを使用して、データ・ストアから取得するデータ、およびデータに対して実行する分析またはその他の処理を指定します。Sourceオブジェクトの使用例は、第6章「Sourceメソッドを使用した問合せの作成」を参照してください。Templateオブジェクトを使用した変更可能な問合せを作成する方法の詳細は、第10章「動的問合せの作成」を参照してください。

この章では、次の項目について説明します。

Sourceオブジェクトの概要

oracle.olapi.metadata.mdmパッケージのクラスを使用して、OLAPメタデータのメジャーおよびディメンションを表すMdmSourceオブジェクトを取得した後、そのオブジェクトからSourceオブジェクトを取得できます。また、DataProviderのメソッドを使用して他のSourceオブジェクトを作成することもできます。このSourceオブジェクトを使用して、データベースから取得するデータを指定する問合せを作成できます。データを取得するには、SourceCursorを作成します。

Sourceのメソッドを使用すると、ディメンションやメジャーの値の選択や、Sourceの要素に対する数学計算、比較、および問合せの要素の順序付け、追加または削除などの操作を指定できます。Sourceクラスは、小数の基本メソッドと、1つ以上の基本メソッドを使用する多数のショートカット・メソッドを持ちます。最も複雑な基本メソッドは、join(Source joined, Source comparison, int comparisonRule, boolean visible)メソッドおよびrecursiveJoin(Source joined, Source comparison, Source parent, int comparisonRule, boolean parentsFirst, boolean parentsRestrictedToBase, int maxIterations, boolean visible)メソッドです。joinおよびrecursiveJoinメソッドのその他多くのシグネチャは、基本メソッドの特定の操作のショートカットです。

この章では、特に記述している場合を除き、joinメソッドに関する情報がrecursiveJoinメソッドにも同様に適用されます。joinメソッドを使用すると、Sourceの要素を選択でき、さらに重要なこととして、1つのSourceの要素を別のSourceの要素に関連付けることができます。たとえば、メジャー・データの取得に必要なディメンション・メンバーを指定するには、joinメソッドを使用して、そのディメンションをメジャーに関連付けます。

Sourceは、タイプおよびデータ型などの特定の特性を持ち、1つ以上の入力や出力を持つ場合もあります。この章ではこれらの概念について説明します。また、様々な種類のSourceオブジェクトとそれらを取得する方法、joinメソッドと他のSourceメソッド、および、これらのメソッドを使用した問合せの指定方法についても説明します。

Sourceオブジェクトの種類

データの指定および分析の実行に使用するSourceオブジェクトの種類と、これらを取得する方法を次に示します。

Sourceクラスには次のサブクラスがあります。

これらのサブクラスは異なるデータ型を持ち、それらのデータ型を必要とするSourceメソッドを実装します。各サブクラスは、BooleanSourceimpliesメソッドやStringSourceindexOfメソッドなど、それぞれ固有のメソッドを実装します。

Sourceオブジェクトの特性

Sourceはデータ型とタイプ、Source識別子(ID)およびSourceDefinitionを持ちます。ここではこれらの概念について説明します。Sourceオブジェクトには、1つ以上の入力や出力を持つものもあります。これらの複雑な概念については、「Sourceの入力と出力」の項を参照してください。一部のSourceオブジェクトは、関連Modelオブジェクトを持ちます(「ModelオブジェクトとSourceオブジェクト」の項を参照)。

Sourceのデータ型

第2章「OLAP Java APIメタデータの理解」で説明したように、OLAP Java APIには、MdmSourceの要素のデータ型を表すクラスFundamentalMetadataObjectがあります。Sourceのデータ型は、基本Sourceによって表されます。たとえば、BooleanSourceは、Javaのboolean値を持つ要素を持ちます。BooleanSourceのデータ型は、OLAP Java API Boolean値を表す基本Sourceです。

Sourceのデータ型を表す基本Sourceを取得するには、SourcegetDataTypeメソッドをコールします。基本Sourceは、FundamentalMetadataObjectgetSourceメソッドをコールしても取得できます。

例5-1では、OLAP Java API Stringデータ型の基本SourceMdmPrimaryDimensionのデータ型のSource、およびMdmPrimaryDimensionSourceのデータ型のSourceを取得し、それらを比較して同じオブジェクトであることを確認します。例の中のdpDataProviderで、mdmProdDimは製品ディメンションのMdmPrimaryDimensionです。

例5-1 Sourceのデータ型の取得

FundamentalMetadataProvider fmp = dp.getFundamentalMetadataProvider();
FundamentalMetadataObject fmoStringDataType = fmp.getStringDataType();
Source stringDataTypeSource = fmoStringDataType.getSource();
FundamentalMetadataObject fmoMdmProdDimDataType =
                                               mdmProdDim.getDataType();
Source mdmProdDimDataTypeSource = fmoMdmProdDimDataType.getSource();
Source prodDim = mdmProdDim.getSource();
Source prodDimDataTypeSource = prodDim.getDataType();
if(stringDataTypeSource == prodDimDataTypeSource &&
   mdmProdDimDataTypeSource == prodDimDataTypeSource)
  println("The Source objects for the data types are the same.");
else
  println("The Source objects for the data types are not the same.");

この例によって、次のように表示されます。

The Source objects for the data types are the same.

Sourceのタイプ

Sourceは、データ型の他にタイプを持ちます。タイプとは、Sourceの要素の導出元のSourceです。Sourceのタイプによって、joinメソッドがSourceを別のSourceの入力と一致させることができるかどうかが決まります。タイプを持たない唯一のSourceは、OLAP Java API Valueデータ型の基本Sourceです。これはすべての値セットを表し、その他すべてのSourceオブジェクトは最終的にこれに由来します。

基本SourceのタイプはそのSourceのデータ型です。リストまたは範囲Sourceのタイプは、そのリストまたは範囲Sourceの要素の値のデータ型です。

プライマリSourceのタイプは、次のいずれかです。

  • プライマリSourceの要素の値のデータ型を表す基本Source。たとえば、一般的なMdmMeasuregetSourceメソッドによって戻されたSourceは、すべてのOLAP Java API数値データ型を表す基本Sourceです。

  • プライマリSourceMdmSourceがコンポーネントであるMdmSourceSource。たとえば、MdmLevelHierarchygetSourceメソッドによって戻されたSourceのタイプは、階層がコンポーネントであるMdmPrimaryDimensionSourceです。

導出Sourceのタイプは、次のいずれかです。

  • ベースSource。これは、導出Sourceを戻したメソッドを持つSourceです。aliasextractjoinrecursiveJoinまたはvalueメソッドによって戻されたSource、またはそれらのショートカットの1つは、タイプとしてベースSourceを持ちます。例外は、distinctメソッドによって戻された導出Sourceで、このタイプは、ベースSource自身ではなく、そのベースSourceのタイプです。

  • 基本Sourcepositionおよびcountなどのメソッドは、そのタイプとしてOLAP Java API Integerデータ型の基本Sourceを持つSourceを戻します。eqleなどの比較を行うメソッドは、そのタイプとしてBooleanデータ型の基本Sourceを持つSourceを戻します。NumberSourcetotalおよびaverageメソッドなど、集計関数を実行するメソッドは、Sourceのタイプとして、その関数を表す基本Sourceを戻します。

Sourceのタイプを取得するには、そのgetTypeメソッドをコールします。

別のSourceから導出されたSourceは、導出元のSourceのサブタイプです。isSubtypeOfメソッドを使用すると、あるSourceが別のSourceのサブタイプかどうかを判別できます。

たとえば、例5-2myListオブジェクトは、リストSourceです。この例ではmyListを使用して、製品ディメンションのMdmPrimaryDimensionのデフォルトMdmLevelHierarchySourceprodHierから値を選択します。例の中のdpは、DataProviderです。

例5-2 isSubtypeOfメソッドの使用

Source myList = dp.createListSource(new String[] {
                                     "PRODUCT_PRIMARY::FAMILY::LTPC",
                                     "PRODUCT_PRIMARY::FAMILY::DTPC",
                                     "PRODUCT_PRIMARY::FAMILY::ACC",
                                     "PRODUCT_PRIMARY::FAMILY::MON"});
Source prodSel = prodHier.selectValues(myList);
if (prodSel.isSubtypeOf(prodHier))
  println("prodSel is a subtype of prodHier.");
else
  println("prodSel is not a subtype of prodHier.");

prodSelprodHierのサブタイプなので、if文の条件はtrueです。次のように表示されます。

prodSel is a subtype of prodHier.

myListおよびprodHierのタイプは、どちらもStringデータ型の基本Sourceです。prodSelのタイプはprodHierです。これは、prodSelの要素がprodHierの要素から導出されているためです。

あるSourceのタイプのタイプなど(Valueデータ型の基本Sourceのタイプ)をSourceのスーパータイプといいます。たとえば、Valueデータ型の基本Sourceは、prodHierのタイプであるStringデータ型の基本Sourceのタイプで、さらにこのprodHierは、prodSelのタイプです。この場合、Valueデータ型の基本SourceおよびStringデータ型の基本Sourceはともに、prodSelのスーパータイプです。また、prodSel Sourceは、prodHierのサブタイプであると同時に、Stringデータ型の基本SourceおよびValueデータ型の基本Sourceのサブタイプでもあります。

SourceのSource識別子およびSourceDefinition

Sourceはそれぞれ識別子(ID)を持ちます。これは、データベースへの現行の接続期間においてそのSourceを一意に識別できるStringです。Sourceの識別子を取得するには、getIDメソッドをコールします。たとえば、次のコードでは、製品ディメンションのMdmPrimaryDimensionSourceの識別子を取得して、その値を表示します。

println("The Source ID of prodDim is " + prodDim.getID());

このコードによって、次のように表示されます。

The Source ID of prodDim is Hidden..GLOBAL.PRODUCT_AWJ

例5-9の出力に、Source識別子の例がいくつか示されています。

Sourceは、そのSourceに関する情報を記録する1つのSourceDefinitionオブジェクトを持ちます。Sourceオブジェクトの種類が異なれば、SourceDefinitionオブジェクトの種類も異なります。たとえば、MdmPrimaryDimensionの基本Sourceは、SourceDefinitionのサブクラスであるHiddenDefinitionのサブクラスであるMdmSourceDefinitionを持ちます。

joinメソッドをコールすることによって生成されたSourceSourceDefinitionは、JoinDefinitionクラスのインスタンスです。JoinDefinitionから、ベースSource、結合Source、比較Source、比較規則およびvisibleパラメータの値など、そのSourceを生成した結合操作のパラメータに関する情報を取得できます。

Sourceの入力と出力

Sourceの入力および出力は、クラスの複雑かつ高度な側面です。この項では、入力および出力の概念を説明し、それらがどのように関連するのかを例示します。

Sourceの入力

入力を持つSourceは、ディメンション化されたSourceです。Sourceの入力もまたSourceです。入力によって、ディメンション化されたSourceの値が、指定されていない入力の値セットに基づくことが示されます。入力と一致するSourceが、その入力が必要とする値を提供します。入力をディメンション化されたSourceと一致させるには、joinメソッドを使用します。Sourceと入力を一致させる方法については、「Sourceと入力の一致」を参照してください。

特定のSourceオブジェクトは、常に1つ以上の入力を持ちます。それらは、MdmDimensionedObjectサブクラスMdmMeasureおよびMdmAttributeSourceオブジェクトです。こうしたオブジェクトが入力を持つのは、メジャーまたは属性の値が、これらのディメンションの値によって指定されているためです。メジャーまたは属性のSourceの入力は、そのメジャーまたは属性のディメンションのSourceオブジェクトです。メジャーまたは属性のデータを取得するには、必要な値を提供するSourceとそれぞれの入力を一致させておく必要があります。

入力を持つSourceを生成するSourceメソッドがいくつかあります。入力を持つSourceは、extractpositionまたはvalueメソッドを使用して生成できます。これらのメソッドによって、別のSourceの要素のサブセットである要素を持つSourceを生成する手段が提供されます。これらのメソッドのいずれかで生成したSourceは、ベースSourceを入力として持ちます。

たとえば、次のコードでは、prodHierがベースSourceです。valueメソッドによって、入力としてprodHierを持つprodHierValuesが生成されます。

Source prodHierValues = prodHier.value();

入力によって、prodHierから値を選択する手段が提供されます(例5-2を参照)。例5-2selectValuesメソッドは、次のjoinメソッドのショートカットです。

Source prodSel = prodHier.join(prodHier.value(),
                                 myList,
                                 Source.COMPARISON_RULE_SELECT,
                                 false);

joinメソッドのパラメータは、結果のSourceに現れるベースSourceの要素を指定します。例では、joinedパラメータがprodHier.value()メソッドによって生成されるSourceです。結果のSource(名前なし)は、入力としてprodHierを持ちます。この入力は、prodHierでもあるjoinメソッドのベースと一致します。結合操作の結果prodSelは、比較SourcemyList)にあるprodHierの値と一致するprodHierの値を持ちます。

結合SourceprodHierで、prodHier.value()によって生成されたSourceでない場合、Sourceの値と比較Sourceの値間の比較ではなく、Sourceオブジェクト自身と比較Sourceの値間での比較になります。結合Sourceオブジェクトは、比較Sourceのいずれの値とも一致しないので、joinメソッドの結果はprodHierのすべての要素を持ちます。比較規則で指定された比較Sourceの値と一致する結合Sourceの値によって指定されたprodHierの値のみを持つことはありません。

positionまたはvalueメソッドによって生成されたSourceの入力、およびMdmDimensionedObject固有の入力を通常の入力といいます。通常の入力は、joinメソッドに、Sourceとその入力を一致させる際に、比較Sourceの値と、入力Source自身とではなく、その入力を持つSourceの値との比較を強制します。

extractメソッドで生成されたSourceの入力を抽出入力といいます。抽出入力は、次の点で通常の入力と異なります。抽出入力を持つSourceの値がSourceである場合、joinメソッドは、その入力を持つSourceの値であるSourceの値を抽出します。次に、joinメソッドは、比較Sourceの値と、Source自身とではなく、抽出した値との比較を行います。

Sourceは多くの入力を持つ場合もあれば、入力を持たない場合もあります。Sourceのすべての入力を取得するには、getInputsメソッドをコールします。通常の入力についてはgetRegularInputsメソッドを、抽出入力についてはgetExtractionInputsメソッドをコールします。各メソッドは、Sourceオブジェクトのセットを戻します。

Sourceの出力

joinメソッドは、メソッドのパラメータによって指定されるベースSourceの要素を持つSourceを戻します。visibleパラメータの値がtrueの場合、結合Sourceは、戻されたSourceの出力となります。joinメソッドによって戻されたSourceの出力は、戻されたSourceの要素を指定する結合Sourceの要素を持ちます。出力は、出力を持つSourceの要素を指定する結合Sourceの要素を識別する手段です。

Sourceは多くの出力を持つ場合もあれば、出力を持たない場合もあります。Sourceの出力を取得するには、SourceオブジェクトのListを戻すgetOutputsメソッドをコールします。

複数の出力を持つSourceは、出力の要素の各セットについて、1つ以上の要素を持ちます。たとえば、すべての入力が一致しており、入力と一致するSourceオブジェクトが出力となったメジャーを表すSourceは、出力の要素の各セットについて単一のタイプの要素を持ちます。これは、そのメジャーの各データ値が、ディメンションの一意の値セットによって識別されるためです。ただし、メジャーのデータに対して実行されたある操作によって選択されるディメンション値を表すSourceは、出力の要素の各セットについて、複数の要素を持つ場合があります。この例として、一定額より大きな単位原価を持つ製品の値を表すSourceがあります。このようなSourceは、指定した額より大きな単位原価を持つ、各期間の製品を複数持つ場合があります。

例5-3では、顧客値のディメンションの階層のSourceである、shipHierの要素の選択が生成されます。顧客は、配送元と宛先の階層によってグループ化されます。

例5-3 joinメソッドを使用した出力を持たないSourceの生成

Source custValuesToSelect = dp.createListSource(new String[]
                                    {"SHIPMENTS::REGION::AMER",
                                     "SHIPMENTS::REGION::EMEA"});
Source shipHierValues = shipHier.value();
Source custSel = shipHier.join(shipHierValues,
                               custValuesToSelect,
                               Source.COMPARISON_RULE_SELECT,
                               false);

shipHierValues Sourceは、shipHierの入力を持ちます。この例のjoinメソッドでは、ベースSourceshipHier)は結合SourceshipHierValues)の入力と一致します。これは、ベースと入力が同じオブジェクトであるためです。joinメソッドは、比較SourcecustValuesToSelect)によって指定される結合shipHierの値と一致する値を持つベースshipHierの要素を選択します。このメソッドによって、shipHierの選択された要素のみを持つSourcecustSel)が生成されます。visibleパラメータがfalseなので、結合SourcecustSelの出力とはなりません。したがって、custSel Sourceは2つの要素しか持ちません。それぞれの値はSHIPMENTS::REGION::AMERSHIPMENTS::REGION::EMEAです。

出力を持つSourceは、joinメソッドのvisibleパラメータとしてtrueを指定することによって生成します。例5-4では、例5-2および例5-3のディメンションの選択のSourceオブジェクトを結合し、1つの出力を持つSourcecustSelByProdSel)を生成します。このcustSelByProdSel Sourceは、prodSelの要素によって指定されるcustSelの要素を持ちます。

比較Sourceは、要素を持たない空のSourceです。これは、DataProviderdp)のgetEmptySourceメソッドの結果です。比較規則値COMPARISON_RULE_REMOVEは、比較SourceにないprodSelの要素のみを選択します。比較Sourceは要素を持たないため、結合Sourceのすべての要素が選択されます。結合Sourceの各要素が、ベースSourceのすべての要素を指定します。したがって、結果のSourcecustSelByProdSel)は、custSelのすべての要素を持ちます。

例5-4では、visibleパラメータがtrueなので、prodSelcustSelByProdSelの出力となります。したがって、出力の各要素について、custSelByProdSelは、出力の各要素によって指定されるcustSelの要素を持ちます。custSelおよびprodSelはどちらもディメンション値の単純なリストなので、結果は、両方のSourceオブジェクトの要素のクロス積となります。

例5-4 joinメソッドを使用した出力を持つSourceの生成

Source custSelByProdSel = custSel.join(prodSel,
                                       dp.getEmptySource(),
                                       Source.COMPARISON_RULE_REMOVE,
                                       true);

custSelByProdSelによって指定されるデータを実際に取得するには、そのCursorを作成する必要があります。このようなCursorの値は、左の列に出力prodSelの値があり、右の列にcustSelByProdSel Sourceの要素の値(そのタイプであるcustSelから導出)があることを示すヘッダー付きの次の表に表示されます。

      Output Values                   Type Values
-----------------------------   ------------------------
PRODUCT_PRIMARY::FAMILY::DTPC   SHIPMENTS::REGION::AMER
PRODUCT_PRIMARY::FAMILY::DTPC   SHIPMENTS::REGION::EMEA
PRODUCT_PRIMARY::FAMILY::LTPC   SHIPMENTS::REGION::AMER
PRODUCT_PRIMARY::FAMILY::LTPC   SHIPMENTS::REGION::EMEA
PRODUCT_PRIMARY::FAMILY::MON    SHIPMENTS::REGION::AMER
PRODUCT_PRIMARY::FAMILY::MON    SHIPMENTS::REGION::EMEA
PRODUCT_PRIMARY::FAMILY::ACC    SHIPMENTS::REGION::AMER
PRODUCT_PRIMARY::FAMILY::ACC    SHIPMENTS::REGION::EMEA

custSelByProdSel Sourceは2つのタイプの要素を持ち、custSelByProdSelの出力は4つの要素を持ちます。このcustSelByProdSelの要素の数は8つです。これは、このSourceでは、各出力要素が2つのタイプの要素の同じセットを指定するためです。

truevisibleパラメータを指定する各結合操作によって、結果のSourceの出力のリストに1つの出力が追加されます。たとえば、あるSourceが2つの出力を持ち、1つの出力を生成するjoinメソッドの1つをコールすると、結合操作の結果のSourceは3つの出力を持ちます。Sourceの出力を取得するには、SourceオブジェクトのListを戻すgetOutputsメソッドをコールします。

例5-5では、あるメジャーをメジャーのディメンションからの選択に結合することによって、必要な要素を提供するメジャーSourceオブジェクトの入力と一致させる例を示します。最後の2つのjoinメソッドがディメンションの選択とメジャーの入力を一致させるので、結果のSourceは入力を持ちません。これらのjoinにおけるvisibleパラメータはtrueなので、最後のjoinメソッドは2つの出力を持つSourceを生成します。

例5-5では、単位原価のメジャーのSourceを取得します。このSourceunitCost)は2つの入力を持ちます。それぞれ、単位原価のディメンションである、時間ディメンションおよび製品ディメンションのプライマリSourceオブジェクトです。例では、ディメンションのSourceオブジェクトのサブタイプである、ディメンションの階層のSourceオブジェクトが取得されます。次に、階層の選択が生成され、これらの選択とメジャーが結合されます。結果のunitCostSelは、選択された時間における選択された製品の単位原価を指定します。

例5-5 joinメソッドを使用したSourceオブジェクトと入力の一致

Source unitCost = mdmUnitCost.getSource();
Source calendar = mdmCalendar.getSource();
Source prodHier = mdmProdHier.getSource();
Source timeSel = calendar.join(calendar.value(),
                               dp.createListSource(new String[]
                                             {"CALENDAR_YEAR::MONTH::2000.05",
                                              "CALENDAR_YEAR::MONTH::2001.05"}),
                               Source.COMPARISON_RULE_SELECT,
                               false);
Source prodSel = prodHier.join(prodHier.value(),
                               dp.createListSource(new String[]
                                        {"PRODUCT_PRIMARY::ITEM::ENVY STD",
                                         "PRODUCT_PRIMARY::ITEM::ENVY EXE",
                                         "PRODUCT_PRIMARY::ITEM::ENVY ABM"}),
                               Source.COMPARISON_RULE_SELECT,
                               false);
Source unitCostSel = unitCost.join(timeSel,
                                   dp.getEmptySource(),
                                   Source.COMPARISON_RULE_REMOVE,
                                   true)
                             .join(prodSel,
                                   dp.getEmptySource(),
                                   Source.COMPARISON_RULE_REMOVE,
                                   true);

timeSelunitCostの結合によって生成されるSource(名前なし)は、1つの出力を持ちます。これがtimeSelです。このSource(名前なし)にprodSelを結合すると、2つの出力(timeSelおよびprodSel)を持つunitCostSelが生成されます。このunitCostSel Sourceは、これらの出力によって指定されるタイプunitCostからの要素を持ちます。

unitCostSelCursorの値は、Cursorの構造を示すヘッダー付きの表として表示されます。Cursorの構造は、関連するSourceの構造と同じです。単位原価値は、ドル値として書式化されています。

          Output 1                        Output 2               Type
           Values                          Values               Values
-------------------------------  ----------------------------  --------
PRODUCT_PRIMARY::ITEM::ENVY ABM  CALENDAR_YEAR::MONTH::2000.05  2847.47
PRODUCT_PRIMARY::ITEM::ENVY ABM  CALENDAR_YEAR::MONTH::2001.05  2819.85
PRODUCT_PRIMARY::ITEM::ENVY STD  CALENDAR_YEAR::MONTH::2000.05  2897.40
PRODUCT_PRIMARY::ITEM::ENVY STD  CALENDAR_YEAR::MONTH::2001.05  2376.73
PRODUCT_PRIMARY::ITEM::ENVY EXE  CALENDAR_YEAR::MONTH::2000.05  3238.36
PRODUCT_PRIMARY::ITEM::ENVY EXE  CALENDAR_YEAR::MONTH::2001.05  3015.90

Output 1はprodSelの値、Output 2はtimeSelの値、Type Valuesは出力値によって指定されるunitCostの値を示します。

これらの結合操作は、ほとんどのOLAP Java APIアプリケーションで実行されるので、APIでは、これらやその他多くの結合操作のショートカットが提供されています。例5-6では、例5-5の結合操作のショートカットを使用し、同じ結果が生成されます。

例5-6 ショートカットの使用

Source unitCost = mdmUnitCost.getSource();
StringSource calendar = (StringSource) mdmCalendar.getSource();
StringSource prodHier =(StringSource) mdmProdHier.getSource();
Source timeSel = calendar.selectValues(new String[]
                                       {"CALENDAR_YEAR::MONTH::2000.05",
                                        "CALENDAR_YEAR::MONTH::2001.05"}),
Source prodSel = prodHier.selectValues(new String[]
                                        {"PRODUCT_PRIMARY::ITEM::ENVY STD",
                                         "PRODUCT_PRIMARY::ITEM::ENVY EXE",
                                         "PRODUCT_PRIMARY::ITEM::ENVY ABM"}),
Source unitCostSel = unitCost.join(timeSel).join(prodSel);

Sourceと入力の一致

結合操作では、Sourceと入力の一致は、ベースSourceと結合Sourceとの間でのみ発生します。次の条件のいずれかがtrueの場合、Sourceは入力と一致します。

  1. Sourceが入力と同じオブジェクトか、入力のサブタイプである。

  2. Sourceが入力と同じオブジェクトである出力を持つか、入力のサブタイプである出力を持つ。

  3. 出力が入力と同じオブジェクトである出力を持つか、入力のサブタイプである。

結合操作では、前述の順序で条件が検索されます。Sourceの出力のリストが再帰的に検索され、入力との一致が検索されます。この検索は、最初の一致するSourceが見つかると終了します。1つの入力は1つのSourceとのみ一致し、2つの入力が同じSourceと一致することはありません。

Sourceが入力と一致すると、joinメソッドの結果には、メソッドのパラメータによって指定された要素と一致するベースの要素が含まれます。あるSourceが別のSourceや、他のSourceの出力と一致するかどうかを判別するには、他のSourcefindMatchForメソッドにそのSourceを渡します。

Sourceが入力と一致する際、結果のSourceはその入力を持ちません。Sourceと入力の一致によって、結合SourceまたはベースSourceの出力が影響を受けることはありません。ベースSourceが結合Sourceの入力と一致する出力を持つ場合、結果のSourceはその入力を持ちませんが、その出力は持ちます。

結合操作の結合SourceまたはベースSourceが、その操作で一致しない入力を持つ場合、その一致しない入力が結果のSourceの入力となります。

joinメソッドの比較Sourceは、入力一致には関係しません。比較Sourceが入力を持つ場合、その入力は一致せず、joinメソッドによって戻されたSourceは同じ入力を持ちます。

例5-7では、結合操作の結合Sourceの入力とベースSourceとの一致を例示します。この例では、入力を持つSourceの生成にpositionメソッドを、結合操作のベースと結合Sourceの入力との一致にjoinメソッドを使用します。

例5-7 ベースSourceと結合Sourceの入力の一致

Source myList = dp.createListSource(new String[]
                                    {"PRODUCT_PRIMARY::FAMILY::LTPC",
                                     "PRODUCT_PRIMARY::FAMILY::DTPC",
                                     "PRODUCT_PRIMARY::FAMILY::ACC",
                                     "PRODUCT_PRIMARY::FAMILY::MON"});
Source pos = dp.createListSource(new int[] {2, 4});
Source myListPos = myList.position();
Source myListSel = myList.join(myListPos,
                               pos,
                               Source.COMPARISON_RULE_SELECT,
                               false);

例5-7では、positionメソッドによって、myListの要素を持ち、入力としてmyListを持つmyListPosが戻されます。joinメソッドは、ベースmyListと結合SourcemyListPos)の入力を一致させます。

比較Sourcepos)は、myListPosの要素の位置を、myListの要素の位置と一致するように指定します。結果のSourcemyListSel)の要素は、位置がjoinメソッドのパラメータによって指定されたものと一致するmyListの要素です。

myListSelCursorは次の値を持ちます。

PRODUCT_PRIMARY::FAMILY::DTPC
PRODUCT_PRIMARY::FAMILY::MON

例5-7visibleパラメータがfalseではなくtrueである場合、結果にはmyListの要素およびmyListPosの出力が含まれます。この場合、myListSelCursorの値は、出力およびタイプ値を示すヘッダー付きの表として表示されます。

Output            Type
Values           Values
------  -------------------------
  2     PRODUCT_PRIMARY::FAMILY::DTPC
  4     PRODUCT_PRIMARY::FAMILY::MON

例5-8では、結合Sourceの出力とベースSourceの2つの入力との一致を例示します。この例では、unitsMdmMeasureSourceです。これは、時間、製品、顧客、およびチャネル・ディメンションのプライマリSourceオブジェクトを入力として持ちます。

DataProviderdpで、prodHiershipHiercalendarおよびchanHierはそれぞれ、製品ディメンション、顧客ディメンション、時間ディメンションおよびチャネル・ディメンションのデフォルト階層のSourceオブジェクトです。これらのSourceオブジェクトは、unitsの入力であるディメンションのSourceオブジェクトのサブタイプです。

例5-8の最初の行のprodHierjoinメソッドは、選択した製品の値を指定するprodSelを生成します。このメソッドにおいて、結合Sourceは、prodHiervalueメソッドの結果です。結合SourceprodHierと同じ要素を持ち、入力としてprodHierを持ちます。比較Sourceは、DataProvidercreateListSourceメソッドの結果であるリストSourceです。

joinメソッドのベースSourceprodHier)は、結合Sourceの入力と一致します。prodHierは、結合Sourceの入力であるため、joinメソッドによって戻されるSourceが持つのは、比較Sourceに現れる結合Sourceの要素と一致するベースprodHierの要素のみです。visibleパラメータの値はfalseなので、結果のSourceは出力として結合Sourceを持ちません。例5-8における次の3つの同様な結合操作では、その他の3つのディメンションの選択が生成されます。

timeSeljoinメソッドの結合SourcecustSelです。この比較SourcegetEmptySourceメソッドの結果なので、要素は持ちません。比較規則では、比較Sourceに存在する結合Sourceの要素が、結果のSourceに出現しないことを指定します。比較Sourceは要素を持たないため、結合Sourceのすべての要素が選択されます。visibleパラメータの値がtrueであるため、結合Sourceは、joinメソッドによって戻されるSourceの出力となります。戻されたSourcecustSelByTime)は、顧客ディメンションの選択された要素を持ち、出力としてtimeSelを持ちます。

prodSeljoinメソッドの結合SourcecustSelByTimeです。これによって、製品ディメンションの選択された要素を持ち、出力としてcustSelByTimeを持つprodByCustByTimeが生成されます。例5-8では次に、ディメンションの選択をunits Sourceに結合します。

ディメンションの選択は、unitsの入力であるSourceオブジェクトのサブタイプなので、unitsの入力と一致します。製品ディメンションの入力はprodByCustByTimeと一致します。これは、prodByCustByTimeprodHierのサブタイプであるprodSelのサブタイプであるためです。顧客ディメンションの入力は、prodByCustByTimeの出力であるcustSelByTimeと一致します。

custSelByTime Sourceは、shipHierのサブタイプであるcustSelのサブタイプです。時間ディメンションの入力は、custSelByTimeの出力であるtimeSelと一致します。timeSel Sourcecalendarのサブタイプです。

例5-8 ベースSourceの入力と結合Sourceの出力の一致

Source prodSel = prodHier.join(prodHier.value(),
                               dp.createListSource(new String[]
                                     {"PRODUCT_PRIMARY::FAMILY::DTPC",
                                      "PRODUCT_PRIMARY::FAMILY::LTPC"}),
                               Source.COMPARISON_RULE_SELECT,
                               false);
Source custSel = shipHier.join(shipHier.value(),
                               dp.createListSource(new String[]
                                    {"SHIPMENTS::REGION::EMEA",
                                     "SHIPMENTS::REGION::AMER"}),
                               Source.COMPARISON_RULE_SELECT,
                               false);
Source timeSel =  calendar.join(calendar.value(),
                                dp.createConstantSource(
                                               "CALENDAR_YEAR::YEAR::CY2001"),
                                Source.COMPARISON_RULE_SELECT,
                                false);
Source chanSel = chanHier.join(chanHier.value(),
                                dp.createConstantSource(
                                      "CHANNEL_PRIMARY::CHANNEL::INT"),
                                Source.COMPARISON_RULE_SELECT,
                                false);

Source custSelByTime = custSel.join(timeSel,
                                    dp.getEmptySource(),
                                    Source.COMPARISON_RULE_REMOVE,
                                    true);
Source prodByCustByTime = prodSel.join(custSelByTime,
                                       dp.getEmptySource(),
                                       Source.COMPARISON_RULE_REMOVE,
                                       true);

Source selectedUnits = units.join(prodByCustByTime,
                                  dp.getEmptySource(),
                                  Source.COMPARISON_RULE_REMOVE,
                                  true)
                            .join(promoSel,
                                  dp.getEmptySource(),
                                  Source.COMPARISON_RULE_REMOVE,
                                  true ),
                            .join(chanSel,
                                  dp.getEmptySource(),
                                  Source.COMPARISON_RULE_REMOVE,
                                  true);

selectedUnitsCursorの値は、列ヘッダーおよび書式が追加されたクロス集計形式で表示されます。この表には、ディメンション要素のローカル値のみが含まれます。最初の2行はクロス集計のページ・エッジ値です。これらは、selectedUnitschanSel出力の値および、selectedUnitsprodByCustByTime出力の出力であるtimeSelの値です。クロス集計の行エッジ値は左の列の顧客値で、列エッジ値は中央および右の列の製品値です。

クロス集計には、ディメンション要素の一意値のローカル値部分のみが含まれます。メジャー値は、選択されたディメンション値によって指定される販売台数の値です。

INT
CY2001
             Products
            -----------
Customers   DTPC   LTPC
---------   ----   ----
AMER        1748   846
EMEA         439   215

次の表では結果は同じですが、ディメンション要素値が、それぞれの値の簡単な説明で置き換えられています。

Internet
2001
                           Products
               -------------------------
Customers      Desktop PCs   Portable PCs
-------------  -----------   ------------
North America      1748           846
Europe              439           215

例5-9では、入力を出力に切り換える例を示すために、units(UNITSメジャーのSource)およびdefaultHiers(メジャーのディメンションのデフォルト階層のSourceオブジェクトのArrayList)を使用します。例では、メジャーのSourceの入力および出力が取得されます。また、メジャーおよびSourceの入力のSourceSource識別子が表示されます。メジャーのSourceの入力は、そのメジャーのディメンションであるMdmPrimaryDimensionオブジェクトのSourceオブジェクトです。

例5-9では次に、メジャーのSourceの入力および出力の数が表示されます。例では、要素として結合操作のベースの要素を持ち、出力としてjoinedパラメータSourceを持つSourceを生成するjoin(Source joined)メソッドを使用して、階層Sourceオブジェクトの1つをメジャーのSourceに結合し、結果のSourceの入力および出力の数を表示します。次に、残りの各階層Sourceを前の結合操作の結果に結合し、結果のSourceの入力および出力の数を表示します。

最後に、最後の結合操作で生成されたSourceの出力が取得され、その出力のSource識別子が表示されます。最後のSourceの出力は、この例でメジャーのSourceに結合したデフォルト階層のSourceオブジェクトです。階層のSourceオブジェクトは、メジャーの入力であるMdmPrimaryDimensionオブジェクトのSourceオブジェクトのサブタイプであるため、これらの入力は一致します。

例5-9 メジャーの入力の一致および出力の生成

Set inputs = units.getInputs();
Iterator inputsItr = inputs.iterator();
List outputs = units.getOutputs();
Source input = null;

int i = 1;
println("The inputs of " + units.getID() + " are:");
while(inputsItr.hasNext())
{
  input = (Source) inputsItr.next();
  println(i + ": " + input.getID());
  i++;
}

println(" ");
int setSize = inputs.size();
for(i = 0; i < (setSize + 1); i++)
{
  println(units.getID() + " has " + inputs.size() +
                   " inputs and " + outputs.size() + " outputs.");
  if (i < setSize)
  {
    input = defaultHiers.get(i);
    println("Joining " + input.getID() + " to " + units.getID());
    units = units.join(input);
    inputs = units.getInputs();
    outputs = units.getOutputs();
  }
}

println("The outputs of " + units.getID() + " are:");
Iterator outputsItr = outputs.iterator();
i = 1;
while(outputsItr.hasNext())
{
  Source output = (Source) outputsItr.next();
  println(i + ": " + output.getID());
  i++;
}

この例の出力は次のようになります。

The inputs of Hidden..GLOBAL.UNITS_CUBE_AWJ.UNITS are:
1: Hidden..GLOBAL.CHANNEL_AWJ
2: Hidden..GLOBAL.CUSTOMER_AWJ
3: Hidden..GLOBAL.PRODUCT_AWJ
4: Hidden..GLOBAL.TIME_AWJ

Hidden..GLOBAL.UNITS_CUBE_AWJ.UNITS has 4 inputs and 0 outputs.
Joining Hidden..GLOBAL.CHANNEL_AWJ.CHANNEL_PRIMARY to Hidden..GLOBAL.UNITS_CUBE_AWJ.UNITS
Join.30 has 3 inputs and 1 outputs.
Joining Hidden..GLOBAL.CUSTOMER_AWJ.SHIPMENTS to Join.30
Join.31 has 2 inputs and 2 outputs.
Joining Hidden..GLOBAL.PRODUCT_AWJ.PRODUCT_PRIMARY to Join.31
Join.32 has 1 inputs and 3 outputs.
Joining Hidden..GLOBAL.TIME_AWJ.CALENDAR_YEAR to Join.32
Join.33 has 0 inputs and 4 outputs.

The outputs of Join.33 are:
1: Hidden..GLOBAL.TIME_AWJ.CALENDAR_YEAR
2: Hidden..GLOBAL.PRODUCT_AWJ.PRODUCT_PRIMARY
3: Hidden..GLOBAL.CUSTOMER_AWJ.SHIPMENTS
4: Hidden..GLOBAL.CHANNEL_AWJ.CHANNEL_PRIMARY

1つの階層の連続するSourceは、前の結合操作の結果にそれぞれ結合されるので、結果のSourceの出力Listの最初の出力になることに注目してください。したがって、Join.33の最初の出力はHidden..GLOBAL.TIME_AWJ.CALENDAR_YEAR、最後の出力はHidden..GLOBAL.CHANNEL_AWJ.CHANNEL_PRIMARYです。

パラメータ化Sourceオブジェクト

パラメータ化Sourceオブジェクトは、ある問合せを指定し、問合せの異なる結果セットを取得する方法を提供します。これは、パラメータ化Sourceによって指定される要素セットを変更することによって行います。パラメータ化Sourceは、ParametercreateSourceメソッドを使用して作成します。このParameterが、パラメータ化Sourceによって指定される値を供給します。

Parameterオブジェクトは、一般的にはキューブのページ・エッジの指定に使用します。例6-9に、ページ・エッジの指定にParameterオブジェクトを使用する例を示しています。その他に、Parameterオブジェクトは現在必要とする要素セットのみをサーバーからフェッチするためにも使用します。例6-15に、異なる要素セットのフェッチにParameterオブジェクトを使用する例を示しています。

Parameterオブジェクトを作成する際は、Parameterの初期値を指定します。次に、そのParameterを使用して、パラメータ化Sourceを作成します。問合せを指定する際に、このパラメータ化Sourceを含めます。問合せにはCursorを作成します。Parameterの値を変更するには、setValueメソッドを使用します。これは問合せが指定する要素セットを変更します。同じCursorを使用して、新しい値セットを表示できます。

例5-10は、メジャー・ディメンションの要素を指定するためのパラメータ化SourceおよびParameterの使用方法の例です。例では、単位原価および単位価格メジャーのSourceオブジェクトを要素値として持つリストSourceを作成します。また、単位原価メジャーのSourceについて一意に識別するStringを初期値として持つStringParameterオブジェクトを作成します。このStringParameterが、パラメータ化Sourceの作成に使用されます。

この例では、メジャーから値を抽出し、パラメータ化Sourceで指定されたメジャーにディメンションの選択を結合することによって指定されたデータ値を選択します。また、結果の問合せに対してCursorを作成し、結果を表示します。Cursorの位置を再設定し、measParam StringParameterの値を変更した後で、再びCursorの値を表示します。

dpオブジェクトは、DataProviderです。getContextメソッドは、ディメンション要素のローカル値のみでCursorの値を表示するメソッドを持つContext11gオブジェクトを取得します。

例5-10 メジャー・ディメンションに関するパラメータ化Sourceの使用

Source measDim = dp.createListSource(new Source[] {unitCost,
                                                   unitPrice});

// Get the unique identifiers of the Source objects for the measures.
String unitCostID = unitCost.getID();
String unitPriceID = unitPrice.getID();

// Create a StringParameter using one of the IDs as the initial value.
StringParameter measParam = new StringParameter(dp, unitCostID);

// Create a parameterized Source.
Source measParamSrc = measParam.createSource();

// Extract the values from the measure dimension elements, and join
// them to the specified measure and the dimension selections.
Source result = measDim.extract().join(measDim, measParamSrc)
                                 .join(prodSelShortDescr)
                                 .join(timeSelShortDescr);
// Get the TransactionProvider and commit the current transaction.
// These operations are not shown.

// Create a Cursor.
CursorManager cursorMngr = getDataProvider().createCursorManager(result);
Cursor resultsCursor = cursorMngr.createCursor();

// Display the results.
getContext().displayCursor(resultsCursor, true);

// Reset the Cursor position to 1.
resultsCursor.setPosition(1);

// Change the value of the parameterized Source.
measParam.setValue(unitPriceID);

// Display the results again.
getContext().displayCursor(resultsCursor, true);

次の表は、列ヘッダーおよび書式を追加して、resultCursorの最初の値セットを表示したものです。表の左の列は、時間ディメンション階層のローカル値を示します。左から2番目の列は、時間値の簡単な説明を示します。3番目の列は、製品ディメンション階層のローカル値を示します。4番目の列は、製品値の簡単な説明を示します。5番目の列は、時間および製品の単位原価メジャー値を示します。

Time     Description  Product     Description    Unit Cost
-------  -----------  --------  ---------------  ---------
2001.04     Apr-01    ENVY EXE  Envoy Executive    2952.85
2001.04     Apr-01    ENVY STD  Envoy Standard     2360.78
2001.05     May-01    ENVY EXE  Envoy Executive    3015.90
2001.05     May-01    ENVY STD  Envoy Standard     2376.73

次の表は、同じ形式で、resultCursorの2つ目の値セットを表示したものです。この表では、5番目の列は単位価格メジャーの値です。

Time     Description  Product     Description    Unit Price
-------  -----------  --------  ---------------  ----------
2001.04     Apr-01    ENVY EXE  Envoy Executive     3107.65
2001.04     Apr-01    ENVY STD  Envoy Standard      2412.42
2001.05     May-01    ENVY EXE  Envoy Executive     3147.85
2001.05     May-01    ENVY STD  Envoy Standard      2395.63

ModelオブジェクトとSourceオブジェクト

この項では、Modelインタフェースとその実装、およびModelオブジェクトとSourceオブジェクトの関係について説明します。また、カスタムModelオブジェクトの作成例、およびSourceオブジェクトとModelオブジェクトに関するその他のタスクの実行例も示します。

SourceのModel

Modelは、Oracle SQLのMODEL句と同様のものです。Modelを使用すると、オブジェクトのディメンション・メンバーの1つ以上のセットのディメンション化されたオブジェクトのSourceに値を割り当てることができます。Modelによって、単純な定数から、ネストされたModelオブジェクトを持つその他の複数のSourceオブジェクトが関与する複雑な計算の結果まで、あらゆる値を割り当てることができます。

Modelがディメンション・メンバーのセットに割り当てる値は、Assignmentオブジェクトによって表されます。Modelは、1つ以上のAssignmentオブジェクトを持つことができます。このセットの各ディメンション・メンバーは、Qualificationオブジェクトによって表されます。Assignmentは、1つ以上のQualificationオブジェクトを持つことができます。

Assignmentが割り当てる値は、Sourceによって指定されます。Assignmentは、Oracle OLAPが値を計算して割り当てる際の順序に影響する優先順位を指定する整数値も持ちます。優先順位を指定せずにModelに複数のAssignmentを作成すると、値の計算および割当てが行われる順序は保証されません。

Modelは、既存のディメンション・メンバーに値を割り当てます。Modelを使用して、1つのディメンション・メンバーに異なる値を割り当てたり、複数のディメンション・メンバーのセットに1つの値を割り当てたり、ディメンション・メンバーのセットの特定のメジャーに異なる値を割り当てたり、属性のディメンション・メンバーに1つの値を割り当てることができます。

カスタム・ディメンション・メンバーを作成する際は割当て値を指定します。Oracle OLAPは、ディメンションの適切なModelに、カスタム・メンバーの値を指定するAssignmentオブジェクトを自動的に追加します。Oracle OLAPは、ディメンションによってディメンション化される任意のメジャーに、その値をメジャー値として割り当てます。

図5-1に、Modelインタフェースのクラス階層およびこのインタフェースを実装するクラスを示します。oracle.olapi.metadata.mdm.MdmModelクラスは、MdmObjectオブジェクトのModelインタフェースを実装します。Modelインタフェースのもう1つの実装は、oracle.olapi.data.sourceパッケージ内のCustomModelクラスです。

図5-1 ModelインタフェースおよびModelを実装するクラス

図5-1の説明は図の下のリンクをクリックしてください。
「図5-1 ModelインタフェースおよびModelを実装するクラス」の説明

Modelは、値を割り当てる対象のSourceオブジェクトである、1つ以上の入力を持ちます。この入力は、OLAP DMLまたはSQL Modelのディメンション・リストに相当します。たとえば、MdmStandardDimensiongetNumberCalcModelメソッドによって戻されたMdmDimensionCalculationModelは、入力として同じMdmStandardDimensionSourceを持ちます。MdmAttributegetModelメソッドによって戻されたMdmDimensionedObjectModelは、属性をディメンション化するMdmPrimaryDimensionSourceを入力として持ちます。MdmMeasuregetModelメソッドによって戻されたMdmDimensionedObjectModelは、メジャーをディメンション化するMdmPrimaryDimensionオブジェクトのSourceオブジェクトを入力として持ちます。

Modelは1つ以上の親を持つことができます。親は、そのModelAssignmentオブジェクトの継承元である他のModelオブジェクトです。MdmMeasureModelは、自身に関連付けられたディメンションのMdmDimensionCalculationModelオブジェクトを親として持ちます。MdmAttributeModelおよびMdmDimensionCalculationModelオブジェクトは、親Modelオブジェクトを持ちません。

CustomModelは入力および親Modelオブジェクトを持つことができます。CustomModelオブジェクトを作成する場合、入力および親Modelオブジェクトを指定できます。CustomModelは出力も持つことができます。MdmModelオブジェクトは出力を持ちません。

一連のCustomModelオブジェクトを作成し、お互いにAssignmentオブジェクトを継承させることができます。次の制約は、CustomModel同士によるAssignmentの継承に適用されます。

  • 継承は循環できません。たとえば、customModelBcustomModelAから継承する場合、customModelAcustomModelBからは継承できません。

  • CustomModelオブジェクトのタイプおよび出力は同一である必要があります。

  • CustomModelが入力を持つ場合、子CustomModelもその入力を指定する必要があります。子CustomModelは追加の入力を持つことができますが、その親CustomModelオブジェクトの入力を指定する必要があります。

CustomModelを作成し、任意の割当てを追加したら、そのcreateSolvedSourceメソッドをコールして、CustomModelSourceを作成できます。createSolvedSourceメソッドのdefaultValuesパラメータを使用すると、このメソッドによって戻されるSourceのデフォルト値を提供するSourceを指定できます。デフォルト値のSourceを指定しない場合、結果のSourceのデフォルト値はNULLとなります。

CustomModelの作成例

Source.extractメソッドはCustomModelとして実装されます。extractメソッドに対して独自のCustomModelを使用すると、Source IDではなく、Stringにメジャー値を割り当てることができるというメリットがあります。例5-11に、extractメソッドを使用する例と、同じ結果を生成するCustomModelを使用する例を示します。また、別のCustomModelを使用して、String値の異なるセットにメジャー値を割り当てる結果を生成する例も示します。

この例では、unitPriceおよびunitCostが単位価格メジャーおよび単位原価メジャーのNumberSourceオブジェクトで、dpDataProviderです。prodSelオブジェクトは、製品ディメンションの3つのメンバーの選択を表すSourceです。

例5-11 CustomModelとしてのextractメソッドの実装

// Create a Source that represents a calculation involving two measures.
Source calculation = unitPrice.minus(unitCost);

// Create a list Source that has Source objects as element values.
Source sourceListSrc = dp.createListSource(new Source[]
                                           {unitPrice, unitCost, calculation});
// Use the extract method to get the values of the Source components of the
// list and join Source objects that match the inputs.
Source resultUsingExtract =
                   sourceListSrc.extract()
                                .join(sourceListSrc)
                                .join(prodSel)
                                .join(calendar, "CALENDAR_YEAR::MONTH::2000.05");

// Produce the same result using a CustomModel directly.
CustomModel  customModel = dp.createModel(sourceListSrc);
customModel.assign(unitPrice.getID(), unitPrice);
customModel.assign(unitCost.getID(), unitCost);
customModel.assign(calculation.getID(), calculation);
Source measValForSrc = customModel.createSolvedSource();
Source resultUsingCustomModel =
                   measValForSrc.join(sourceListSrc)
                                .join(prodSel)
                                .join(calendar, "CALENDAR_YEAR::MONTH::2000.05");

// Create a list Source that has String objects as element values.
Source stringListSrc = dp.createListSource(new String[]
                                           {"price", "cost", "markup"});
// Create a CustomModel for the list Source.
CustomModel  customModel2 = dp.createModel(stringListSrc);
customModel2.assign("price", unitPrice);
customModel2.assign("cost", unitCost);
customModel2.assign("markup", calculation);
Source measValForSrc2 = customModel2.createSolvedSource();

Source resultUsingCustomModel2 =
                  measValForSrc2.join(stringListSrc)
                                .join(prodSel)
                                .join(calendar, "CALENDAR_YEAR::MONTH::2000.05");

resultUsingCustomModelおよびresultUsingExtractCursorオブジェクトは同じ値を持ちます。これらは、次のように書式が追加されて表示されます。

PRODUCT_PRIMARY::ITEM::ENVY ABM  Hidden..GLOBAL.PRICE_CUBE_AWJ.UNIT_PRICE
 2962.14
PRODUCT_PRIMARY::ITEM::ENVY ABM  Hidden..GLOBAL.PRICE_CUBE_AWJ.UNIT_COST
 2847.47
PRODUCT_PRIMARY::ITEM::ENVY ABM  Join.2
 114.67
PRODUCT_PRIMARY::ITEM::ENVY EXE  Hidden..GLOBAL.PRICE_CUBE_AWJ.UNIT_PRICE
 3442.86
PRODUCT_PRIMARY::ITEM::ENVY EXE  Hidden..GLOBAL.PRICE_CUBE_AWJ.UNIT_COST
 3238.36
PRODUCT_PRIMARY::ITEM::ENVY EXE  Join.2
 204.50
ITEM::ENVY STD  Hidden..GLOBAL.PRICE_CUBE_AWJ.UNIT_PRICE
 3118.61
PRODUCT_PRIMARY::ITEM::ENVY STD  Hidden..GLOBAL.PRICE_CUBE_AWJ.UNIT_COST
 2897.40
PRODUCT_PRIMARY::ITEM::ENVY STD  Join.2
 221.21

resultUsingCustomModel2Cursorの値は、次のように書式が追加されて表示されます。

PRODUCT_PRIMARY::ITEM::ENVY ABM  price  2962.14
PRODUCT_PRIMARY::ITEM::ENVY ABM  cost   2847.47
PRODUCT_PRIMARY::ITEM::ENVY ABM  markup  114.67
PRODUCT_PRIMARY::ITEM::ENVY EXE  price  3442.86
PRODUCT_PRIMARY::ITEM::ENVY EXE  cost   3238.36
PRODUCT_PRIMARY::ITEM::ENVY EXE  markup  204.50
PRODUCT_PRIMARY::ITEM::ENVY STD  price  3118.61
PRODUCT_PRIMARY::ITEM::ENVY STD  cost   2897.40
PRODUCT_PRIMARY::ITEM::ENVY STD  markup  221.21