機械翻訳について

10 動的問合せの作成

動的問合せを作成するには、Oracle OLAP Java API Templateクラスおよび他の関連クラスを使用します。 次のトピックでは、これらのクラスについて説明し、クラスの実装例を示します。

Templateオブジェクトの概要

Templateクラスは、Oracle OLAP Java APIの強力な機能の基礎となります。 Templateオブジェクトを使用して、変更可能なSourceオブジェクトを作成します。 これらのSourceオブジェクトを使用すると、エンド・ユーザーの選択に応じて変更可能な動的問合せを作成できます。 Templateオブジェクトを使用すると、ユーザー・インタフェース要素をOLAP Java APIの操作およびオブジェクトに簡単に変換できます。

動的Sourceを変更したり、変更を保存したり破棄したりするために使用するTransactionオブジェクトの詳細については、「TransactionProviderの使用」を参照してください。

動的Sourceの作成

Templateの主な機能は、動的Sourceを生成する機能です。 この機能は、Templateによって使用される他のオブジェクトのうち、DynamicDefinitionクラスおよびMetadataStateクラスのインスタンスに基づいています。

Sourceを作成すると、SourceDefinitionが自動的に関連付けられます。 SourceDefinitionにはSourceに関する情報があります。 Sourceは、作成後はSourceDefinitionに永続的に関連付けられます。 SourceDefinitiongetSourceメソッドを使用すると、関連付けられているSourceが戻されます。

DynamicDefinitionは、SourceDefinitionのサブクラスです。 Templateは、Templateによって生成されたSourceSourceDefinitionのプロキシとして機能するDynamicDefinitionを作成します。 これは、同じ永続的に関連付けられたSourceを常に取得する代わりに、DynamicDefinitiongetSourceメソッドは、Templateによって現在生成されているSourceを取得することを意味します。 取得されたSourceが異なる場合でも、DynamicDefinitionのインスタンスは変更されません。

Templateが生成するSourceは、TemplateSourceを作成するために使用する他のSourceオブジェクトを含む値が変更できるため変更できます。 Templateはこれらの値をMetadataStateに格納します。 Templateは、MetadataStateの現在の状態を取得し、値を取得または設定し、状態を設定するメソッドを提供します。 これらのメソッドを使用して、MetadataStateが格納するデータ値を変更します。

DynamicDefinitionを使用して、Templateによって作成されたSourceを取得します。 たとえば、エンドユーザーの選択に応じて、TemplateSourceを作成するために使用する値の状態が変更された場合、新しいSourceが結果を定義しても、アプリケーションは同じDynamicDefinitionを使用してSourceを再度取得します。以前のSourceとは異なる設定になっています。

Templateによって生成されるSourceは、一連の選択、ソート、計算、および結合など、他のSourceオブジェクトを作成する一連のSource操作の結果である可能性があります。 これらの操作のコードを、Template用のSourceGeneratorgenerateSourceメソッドに格納します。 このメソッドは、Templateによって作成されたSourceを戻します。 この操作では、MetadataStateに格納されたデータが使用されます。

様々なTemplateオブジェクトによって作成された動的Sourceオブジェクトが相互に作用する複雑な問合せを作成する場合があります。 この問合せを作成すると、複雑な問合せ全体を定義するSourceが作成されます。 最後のSourceを作成するために使用したTemplateオブジェクトのいずれかの状態を変更すると、最後のSourceは前のSourceの結果セットとは異なる結果セットを表します。 これによって、問合せを定義するために行ったすべての操作を繰り返さずに、最終の問合せを変更できます。

ユーザー・インタフェース要素のOLAP Java APIオブジェクトへの変換

Templateオブジェクトを設計して、アプリケーションのユーザー・インタフェースの要素を表します。 このTemplateオブジェクトによって、エンド・ユーザーの選択が、Sourceを作成するOLAP Java APIの問合せ作成の操作に変換されます。 次に、Cursorを作成して、Oracle OLAPからSourceで定義された結果セットをフェッチします。 Cursorから値を取得し、それらの値をエンド・ユーザーに表示します。 エンド・ユーザーによって選択が変更された場合は、Templateの状態を変更します。 その後、Templateによって作成されたSourceを取得して、新しいCursorを作成し、取得した新しい値を表示します。

Templateおよび関連クラスの概要

OLAP Java APIでは、いくつかのクラスが連携して動作して、動的Sourceを作成します。 Templateの設計では、次のクラスおよびインタフェースを実装または拡張する必要があります。

  • Template抽象クラス

  • MetadataStateインタフェース

  • SourceGeneratorインタフェース

これらの3つのクラスのインスタンスと、DataProviderおよびDynamicDefinitionクラスのインスタンスが連携して動作して、Templateによって定義されたSourceを作成します。

動的Sourceを作成するクラス間の関連

動的Sourceを作成するクラスは、次のように連携して動作します。

  • Templateには、DynamicDefinitionを作成し、MetadataStateの現在の状態を取得および設定するメソッドが含まれています。 Template抽象クラスの拡張では、MetadataStateのフィールドの値を取得および設定するメソッドを追加します。

  • MetadataStateの実装には、Template用のSourceの作成に使用されるデータを格納するためのフィールドが存在します。 新しいTemplateを作成すると、MetadataStateTemplateのコンストラクタに渡します。 DynamicDefinitiongetSourceメソッドをコールすると、MetadataStateSourceGeneratorgenerateSourceメソッドに渡されます。

  • DataProviderは、Templateの作成に使用され、SourceGeneratorによって新しいSourceオブジェクトの作成に使用されます。

  • SourceGeneratorの実装には、MetadataStateのデータの現在の状態を使用してTemplate用のSourceを作成するgenerateSourceメソッドが含まれています。 SourceGeneratorTemplatecreateDynamicDefinitionメソッドに渡して、DynamicDefinitionを作成します。

  • DynamicDefinitionには、SourceGeneratorによって作成されたSourceを取得するgetSourceメソッドが含まれています。 DynamicDefinitionは、Sourceに永続的に関連付けられたSourceDefinitionのプロキシとして機能します。

Templateクラス

変更可能なSourceを作成するには、Templateを使用します。 Templateには、DynamicDefinitionを作成し、Templateの現在の状態を取得および設定するためのメソッドがあります。 Templateクラスを拡張するには、TemplateMetadataStateのフィールドへのアクセスを提供するメソッドを追加します。 Templateは、TemplateSourceGeneratorによって生成されたSourceを取得するために使用するDynamicDefinitionを作成します。

Templateの実装例については、例10-1を参照してください。

MetadataStateインタフェース

MetadataStateインタフェースの実装は、Templateの値の現在の状態を格納します。 MetadataStateには、現在の状態のコピーを作成するcloneメソッドが含まれる必要があります。

新しいTemplateをインスタンス化するときは、MetadataStateTemplateコンストラクタに渡します。 Templateには、MetadataStateによって格納された値を取得および設定するためのメソッドが含まれています。 TemplateSourceGeneratorgenerateSourceメソッドは、メソッドがTemplateSourceを生成するときにMetadataStateを使用します。

MetadataStateの実装例については、例10-2を参照してください。

SourceGeneratorインタフェース

SourceGeneratorの実装には、Template用のSourceを作成するgenerateSourceメソッドが含まれている必要があります。 SourceGeneratorが作成する必要があるSourceは1種類のみです(BooleanSourceNumberSourceStringSourceなど)。 generateSourceメソッドは、Sourceを作成する際に、Template用のMetadataStateによって表されるデータの現在の状態を使用します。

generateSourceメソッドによって作成されたSourceを取得するには、TemplatecreateDynamicDefinitionメソッドにSourceGeneratorを渡して、DynamicDefinitionを作成します。 その後、DynamicDefinitiongetSourceメソッドをコールして、Sourceを取得します。

Templateは、それぞれ異なるSourceGeneratorを実装した複数のDynamicDefinitionを作成できます。 異なるSourceGeneratorオブジェクトのgenerateSourceメソッドで、Template用のMetadataStateの現在の状態によって定義された同じデータが使用され、異なる問合せを定義するSourceオブジェクトが作成されます。

SourceGeneratorの実装例については、例10-3を参照してください。

DynamicDefinitionクラス

DynamicDefinitionは、SourceDefinitionのサブクラスです。 TemplatecreateDynamicDefinitionメソッドをコールして、それにSourceGeneratorを渡すことによって、DynamicDefinitionを作成します。 DynamicDefinitiongetSourceメソッドをコールして、SourceGeneratorによって作成されたSourceを取得します。

Templateによって作成されたDynamicDefinitionは、SourceGeneratorによって作成されたSourceSourceDefinitionのプロキシです。 SourceDefinitionは、そのSourceと永続的に関連付けられます。 Templateの状態が変更された場合、SourceGeneratorによって作成されるSourceは異なります。 DynamicDefinitionはプロキシであるため、新しいSourceを取得するために同じDynamicDefinitionを使用しますが、Sourceには異なるSourceDefinitionがあります。

DynamicDefinitiongetCurrentメソッドは、generateSourceメソッドによって現在戻されているSourceに永続的に関連付けられているSourceDefinitionを戻します。 DynamicDefinitionの使用例については、例10-4を参照してください。

Templateの設計および実装

Templateの設計には、アプリケーションのユーザー・インタフェースの問合せ作成要素が反映されます。 たとえば、エンド・ユーザーが値リストから多くの値を要求する問合せを作成可能なアプリケーションを開発すると想定します。 値は、メジャーの1つのディメンションの値です。 そのメジャーの他のディメンションは、単一の値に制限されます。

アプリケーションのユーザー・インタフェースでは、エンド・ユーザーがダイアログ・ボックスを使用して次の操作を実行できます。

  • データ値が特定の範囲内にあるかどうかを指定するラジオ・ボタンの選択。

  • ドロップダウン・リストからのメジャーの選択。

  • フィールドからの数値の選択。 この数値によって、表示するデータ値の数を指定します。

  • 表示するデータ値のベースとしての、メジャーのディメンションの選択。 たとえば、ユーザーが製品ディメンションを選択した場合、問合せによって、製品リストからいくつかの製品が指定されます。 リストは、メジャー、および他のディメンションの選択値によって決定されます。

  • ボタンをクリックすると、エンド・ユーザーが選択したメジャーの他のディメンションの単一の値を選択するためのダイアログ・ボックスが表示されます。 ディメンションの値を選択すると、エンド・ユーザーは2番目のダイアログ・ボックスのOKボタンをクリックし、最初のダイアログ・ボックスに戻ります。

  • OKボタンをクリックし、問合せを作成します。 問合せ結果が表示されます。

最初のダイアログ・ボックスでエンド・ユーザーが作成する問合せを表すSourceを作成するには、TopBottomTemplateという名前のTemplateを設計します。 また、SingleSelectionTemplateという名前のTemplateも設計し、エンド・ユーザーによるベース・ディメンション以外のディメンションに対する単一の値の選択を表すSourceを作成します。 Templateオブジェクトの設計には、ダイアログ・ボックスのユーザー・インタフェース要素が反映されます。

TopBottomTemplateおよびそのMetadataStateSourceGeneratorを設計するには、次の操作を実行します。

  • Templateを拡張するTopBottomTemplateクラスの作成。 このクラスには、Templateの現在の状態を取得し、ユーザーが指定した値を設定し、Templateの現在の状態を設定するメソッドを追加します。

  • MetadataStateを実装するTopBottomTemplateStateクラスの作成。 このクラスに、Templateによって作成されたSourceの作成に使用するSourceGeneratorの値を格納するためのフィールドを提供します。 値は、TopBottomTemplateのメソッドによって設定されます。

  • SourceGeneratorを実装するTopBottomTemplateGeneratorクラスの作成。 このクラスのgenerateSourceメソッドでは、エンド・ユーザーの選択によって指定されるSourceを作成する操作を提供します。

エンド・ユーザーは、このアプリケーションを使用して、最初のダイアログ・ボックスで販売台数をメジャーとして選択し、製品をベース・ディメンションとして選択します。 また、エンド・ユーザーは、残りの各ディメンションの単一の値としてAsia Pacific地域、2001年の第1四半期および直販チャネルも選択します。

エンド・ユーザーが作成した問合せは、2001年にAsia Pacific地域の顧客に対して直販チャネルで販売された製品のうち、販売台数の総数が高い上位10の製品を要求します。

TopBottomTemplateTopBottomTemplateState、およびTopBottomTemplateGeneratorクラスの実装の例と、それらを使用するアプリケーションの例については、「例10-1」「例10-2」「例10-3」 ,および「例10-4」を参照してください。 TopBottomTemplateStateおよびTopBottomTemplateGeneratorクラスは、外部クラスTopBottomTemplateの内部クラスとして実装されます。

Templateのクラスの実装

このトピックの例では、TemplateMetadataState、およびSourceGeneratorクラスを実装しています。

例10-1 Templateの実装

この例は、TopBottomTemplateクラスの実装です。

import oracle.olapi.data.source.DataProvider;
import oracle.olapi.data.source.DynamicDefinition;
import oracle.olapi.data.source.Source;
import oracle.olapi.data.source.SourceGenerator;
import oracle.olapi.data.source.Template;
import oracle.olapi.transaction.metadataStateManager.MetadataState;

/**
 * Creates a TopBottomTemplateState, a TopBottomTemplateGenerator,
 * and a DynamicDefinition.
 * Gets the current state of the TopBottomTemplateState and the values 
 * that it stores. 
 * Sets the data values stored by the TopBottomTemplateState and sets the
 * changed state as the current state.
 */
public class TopBottomTemplate extends Template 
{
// Constants for specifying the selection of elements from the 
// beginning or the end of the result set.
  public static final int TOP_BOTTOM_TYPE_TOP = 0;
  public static final int TOP_BOTTOM_TYPE_BOTTOM = 1;

  // Variable to store the DynamicDefinition.
  private DynamicDefinition dynamicDef;

  /**
   * Creates a TopBottomTemplate with a default type and number values
   * and the specified base dimension.
   */
  public TopBottomTemplate(Source base, DataProvider dataProvider)
  {
    super(new TopBottomTemplateState(base, TOP_BOTTOM_TYPE_TOP, 0),
                                     dataProvider);
    // Create the DynamicDefinition for this Template. Create the 
    // TopBottomTemplateGenerator that the DynamicDefinition uses.
    dynamicDef = 
    createDynamicDefinition(new TopBottomTemplateGenerator(dataProvider));
  }

  /**
   * Gets the Source produced by the TopBottomTemplateGenerator
   * from the DynamicDefinition.
   */
  public final Source getSource() 
  {
    return dynamicDef.getSource();
  }

  /**
   * Gets the Source that is the base of the elements in the result set.
   * Returns null if the state has no base.
   */
  public Source getBase()
  {
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    return state.base;
  }

  /**
   * Sets a Source as the base.
   */
  public void setBase(Source base) 
  {
     TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    state.base = base;
    setCurrentState(state);
  }

  /**
   * Gets the Source that specifies the measure and the single
   * selections from the dimensions other than the base.
   */
  public Source getCriterion()
  {
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    return state.criterion;
  }

  /**
   * Specifies a Source that defines the measure and the single values 
   * selected from the dimensions other than the base.
   * The SingleSelectionTemplate produces such a Source.
   */
  public void setCriterion(Source criterion)
  {
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    state.criterion = criterion;
    setCurrentState(state);
  }

  /**
   * Gets the type, which is either TOP_BOTTOM_TYPE_TOP or 
   * TOP_BOTTOM_TYPE_BOTTOM.
   */
  public int getTopBottomType()
  {
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    return state.topBottomType;
  }

  /**
   * Sets the type.
   */
  public void setTopBottomType(int topBottomType)
  {
    if ((topBottomType < TOP_BOTTOM_TYPE_TOP) ||
        (topBottomType > TOP_BOTTOM_TYPE_BOTTOM	))
      throw new IllegalArgumentException("InvalidTopBottomType");
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    state.topBottomType = topBottomType;
    setCurrentState(state);
  }

  /**
   * Gets the number of values selected.
   */
  public float getN()
  {
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    return state.N;
  }

  /**
   * Sets the number of values to select.
   */
  public void setN(float N)
  {
    TopBottomTemplateState state = (TopBottomTemplateState) getCurrentState();
    state.N = N;
    setCurrentState(state);
  }
}

例10-2 MetadataStateの実装

この例は、TopBottomTemplateState内部クラスの実装です。

/**
 * Stores data that can be changed by a TopBottomTemplate.
 * The data is used by a TopBottomTemplateGenerator in producing
 * a Source for the TopBottomTemplate.
 */
private static final class TopBottomTemplateState
     implements Cloneable, MetadataState
{
  public int topBottomType;
  public float N;
  public Source criterion;
  public Source base;

  /**
   * Creates a TopBottomTemplateState.
   */
  public TopBottomTemplateState(Source base, int topBottomType, float N)
  {
    this.base = base;
    this.topBottomType = topBottomType;
    this.N = N;
  }

  /**
   * Creates a copy of this TopBottomTemplateState.
   */
  public final Object clone()
  {
    try 
    {
      return super.clone();
    }
    catch(CloneNotSupportedException e) 
    {
      return null;
    }
  }
}

例10-3 SourceGeneratorの実装

この例は、TopBottomTemplateGenerator内部クラスの実装です。

/**
 * Produces a Source for a TopBottomTemplate based on the data
 * values of a TopBottomTemplateState.
 */
private final class TopBottomTemplateGenerator
      implements SourceGenerator
{
  // Store the DataProvider.
  private DataProvider _dataProvider;

  /**
   * Creates a TopBottomTemplateGenerator.
   */
  public TopBottomTemplateGenerator(DataProvider dataProvider)
  {
    _dataProvider = dataProvider;
  }

  /**
   * Generates a Source for a TopBottomTemplate using the current 
   * state of the data values stored by the TopBottomTemplateState.
   */
  public Source generateSource(MetadataState state)
  {
    TopBottomTemplateState castState = (TopBottomTemplateState) state;
    if (castState.criterion == null)
      throw new NullPointerException("CriterionParameterMissing");
    Source sortedBase = null;

    // Depending on the topBottomType value, select from the base Source
    // the elements specified by the criterion Source and sort the
    // elements in ascending or descending order.
    // For descending order, specify that null values are last.
    // For ascending order, specify that null values are first.
       
    if (castState.topBottomType == TOP_BOTTOM_TYPE_TOP)
      sortedBase = castState.base.sortDescending(castState.criterion, false);
    else
      sortedBase = castState.base.sortAscending(castState.criterion, true);
    return sortedBase.interval(1, Math.round(castState.N));
  }
}

Templateを使用するアプリケーションの実装

エンドユーザーが選択した内容をTemplateMetadataStateに保存したら、DynamicDefinitiongetSourceメソッドを使用して、Templateによって作成された動的Sourceを取得します。 このトピックでは、「例10-1」で説明されているTopBottomTemplateを使用するアプリケーションの例を示します。 便宜上、このコードでは多くの例外処理を省略しています。

BaseExample11gクラスはContext11gクラスのインスタンスを作成および格納します。このクラスには次の操作を行うメソッドがあります。

  • コマンドライン引数で、ユーザーとしてOracle Databaseインスタンスに接続します。

  • Cursorオブジェクトを作成し、その値を表示します。

例10-4では、次の処理を実行します。

  • MdmMetadataProviderおよびMdmRootSchemaの取得。

  • DataProviderの取得。

  • ユーザーのMdmDatabaseSchemaの取得。

  • COSTS、UNITS、およびSALESの値を持つMdmCubeを取得します。 この例では、キューブから、UNITSおよびSALESメジャーと、キューブに関連付けられたディメンションが取得されます。

  • メジャーのいくつかのディメンションから単一の値を選択するためのSingleSelectionTemplateの作成。 この例で使用するSingleSelectionTemplateクラスのコードについては、「SingleSelectionTemplateクラス」を参照してください。

  • TopBottomTemplateの作成およびエンド・ユーザーが行った選択の格納。

  • TopBottomTemplateによって作成されたSourceの取得。

  • Context11gオブジェクトを使用して、そのSourceCursorを作成し、Cursor値を表示します。

「例7-3」の完全なコードには、「例10-4」にある同じコードの一部が含まれています。 この例では、このコードは表示されません。このコードは、「例10-4」の先頭から次の例のコメントまで続きます:

// End of code not shown in 
//Example 7-3.

例10-4 Templateによって作成されたSourceの取得

import oracle.olapi.data.source.DataProvider;
import oracle.olapi.data.source.Source;
import oracle.olapi.examples.*;
import oracle.olapi.metadata.mdm.MdmAttribute;
import oracle.olapi.metadata.mdm.MdmBaseMeasure;
import oracle.olapi.metadata.mdm.MdmCube;
import oracle.olapi.metadata.mdm.MdmDatabaseSchema;
import oracle.olapi.metadata.mdm.MdmDimensionLevel;
import oracle.olapi.metadata.mdm.MdmDimensionMemberInfo;
import oracle.olapi.metadata.mdm.MdmHierarchyLevel;
import oracle.olapi.metadata.mdm.MdmLevelHierarchy;
import oracle.olapi.metadata.mdm.MdmMetadataProvider;
import oracle.olapi.metadata.mdm.MdmPrimaryDimension;
import oracle.olapi.metadata.mdm.MdmRootSchema;

/**
 * Creates a query that specifies a number of elements from the top
 * or bottom of a selection of dimension members, creates a Cursor
 * for the query, and displays the values of the Cursor.
 * The selected dimension members are those that have measure values
 * that are specified by selected members of the other dimensions of
 * the measure.
 */
public class TopBottomTest extends BaseExample11g
{
  /**
   * Gets the MdmMetadataProvider, the DataProvider, the MdmRootSchema, and the
   * MdmDatabaseSchema for the current user.
   * Gets the UNITS_CUBE_AWJ MdmCube.
   * From the cube, gets the MdmBaseMeasure objects for the UNITS and SALES
   * measures and the MdmPrimaryDimension objects that dimension them.
   * Gets a hierarchy of the PRODUCT_AWJ dimension and the leaf level of the
   * dimension.
   * Gets the short description attribute of the dimension.
   * Creates a SingleSelectionTemplate and adds selections to it.
   * Creates a TopBottomTemplate and sets the properties of it.
   * Gets the Source produced by the TopBottomTemplate, creates a Cursor 
   * for it, and displays the values of the Cursor.
   * Changes the state of the SingleSelectionTemplate and the
   * TopBottomTemplate, creates a new Cursor for the Source produced by the
   * TopBottomTemplate, and displays the values of that Cursor.
   */
  public void run() throws Exception
  {
    // Get the MdmMetadataProvider from the superclass.
    MdmMetadataProvider metadataProvider = getMdmMetadataProvider();
    // Get the DataProvider from the Context11g object of the superclass.
    DataProvider dp = getContext().getDataProvider();

    // Get the MdmRootSchema and the MdmDatabaseSchema for the user.
    MdmRootSchema mdmRootSchema =
      (MdmRootSchema)metadataProvider.getRootSchema();
    MdmDatabaseSchema mdmDBSchema = 
      mdmRootSchema.getDatabaseSchema(getContext().getUser());

    MdmCube unitsCube =
      (MdmCube)mdmDBSchema.getTopLevelObject("UNITS_CUBE_AWJ");
    MdmBaseMeasure mdmUnits = unitsCube.findOrCreateBaseMeasure("UNITS");
    MdmBaseMeasure mdmSales = unitsCube.findOrCreateBaseMeasure("SALES");

    // Get the Source objects for the measures.
    Source units = mdmUnits.getSource();
    Source sales = mdmSales.getSource();

    // Get the MdmPrimaryDimension objects for the dimensions of the cube. 
    List<MdmPrimaryDimension> cubeDims = unitsCube.getDimensions();
    MdmPrimaryDimension mdmTimeDim = null;
    MdmPrimaryDimension mdmProdDim = null;
    MdmPrimaryDimension mdmCustDim = null;
    MdmPrimaryDimension mdmChanDim = null;
    
    for(MdmPrimaryDimension mdmPrimDim : cubeDims)
    {
      if (mdmPrimDim.getName().startsWith("TIME"))
        mdmTimeDim = mdmPrimDim;
      else if (mdmPrimDim.getName().startsWith("PROD"))
        mdmProdDim = mdmPrimDim;
      else if (mdmPrimDim.getName().startsWith("CUST"))
        mdmCustDim = mdmPrimDim;
      else if (mdmPrimDim.getName().startsWith("CHAN"))
        mdmChanDim = mdmPrimDim;
    }

    // Get the hierarchy of the PRODUCT_AWJ dimension.
    MdmLevelHierarchy mdmProdHier = 
      mdmProdDim.findOrCreateLevelHierarchy("PRODUCT_PRIMARY");

    // Get the detail dimenson level of the PRODUCT_AWJ dimension.
    MdmDimensionLevel mdmItemDimLevel = 
      mdmProdDim.findOrCreateDimensionLevel("ITEM");
    // Get the hierarchy level of the dimension level.
    MdmHierarchyLevel mdmItemHierLevel = 
                       mdmProdHier.findOrCreateHierarchyLevel(mdmItemDimLevel);       
    // Get the Source for the hierarchy level.
    Source itemLevel = mdmItemHierLevel.getSource();

    // Get the short description attribute for the PRODUCT_AWJ dimension and
    // the Source for the attribute.
    MdmAttribute mdmProdShortDescrAttr = 
      mdmProdDim.getShortValueDescriptionAttribute();
    Source prodShortDescrAttr = mdmProdShortDescrAttr.getSource();

    // Create a SingleSelectionTemplate to produce a Source that
    // represents the measure values specified by single members of each of
    // the dimensions of the measure other than the base dimension.
    SingleSelectionTemplate singleSelections =
      new SingleSelectionTemplate(units, dp);

    // Create MdmDimensionMemberInfo objects for single members of the
    // other dimensions of the measure.
    MdmDimensionMemberInfo timeMemInfo =
      new MdmDimensionMemberInfo(mdmTimeDim, "CALENDAR_YEAR::YEAR::CY2001");
    MdmDimensionMemberInfo custMemInfo =
      new MdmDimensionMemberInfo(mdmCustDim, "SHIPMENTS::REGION::APAC");
    MdmDimensionMemberInfo chanMemInfo =
      new MdmDimensionMemberInfo(mdmChanDim, "CHANNEL_PRIMARY::CHANNEL::DIR");
 
    // Add the dimension member information objects to the
    // SingleSelectionTemplate.
    singleSelections.addDimMemberInfo(custMemInfo);
    singleSelections.addDimMemberInfo(chanMemInfo);
    singleSelections.addDimMemberInfo(timeMemInfo);

    // Create a TopBottomTemplate specifying, as the base, the Source for a
    // a level of a hierarchy.
    TopBottomTemplate topNBottom = new TopBottomTemplate(itemLevel, dp);

    // Specify whether to retrieve the elements from the beginning (top) or the
    // end (bottom) of the selected elements of the base dimension.
    topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_TOP);

    // Set the number of elements of the base dimension to retrieve.
    topNBottom.setN(10);
    // Get the Source produced by the SingleSelectionTemplate and specify it as
    // the criterion object.
    topNBottom.setCriterion(singleSelections.getSource());

    // End of code not shown in 
    // Example 7-3.

    // Display a description of the result.
    String resultDescription = " products with the most units sold \nfor";
    displayResultDescr(singleSelections, topNBottom, resultDescription);

    // Get the Source produced by the TopBottomTemplate.
    Source result = topNBottom.getSource();

    // Join the Source produced by the TopBottomTemplate with the short
    // value descriptions. Use the joinHidden method so that the
    // dimension member values do not appear in the result.
    Source result = prodShortDescrAttr.joinHidden(topNBottomResult);

    // Commit the current transaction.
    getContext().commit();  // Method of Context11g.

    // Create a Cursor for the result and display the values of the Cursor.
    getContext().displayTopBottomResult(result);

    // Change a dimension member selection of the SingleSelectionTemplate.
    timeMemInfo.setUniqueValue("CALENDAR_YEAR::YEAR::CY2000");
    singleSelections.changeSelection(timeMemInfo);
 
    // Change the number of elements selected and the type of selection.
    topNBottom.setN(5);
    topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_BOTTOM);
 
    // Join the Source produced by the TopBottomTemplate to the short
    // description attribute.
    result = prodShortDescrAttr.joinHidden(topNBottomResult);

    // Commit the current transaction.
    getContext().commit();
 
    // Display a description of the result.
    resultDescription = " products with the fewest units sold \nfor";
    displayResultDescr(singleSelections, topNBottom, resultDescription);
 
    // Create a new Cursor for the Source produced by the TopBottomTemplate
    // and display the Cursor values.
    getContext().displayTopBottomResult(result);

    // Now change the measure to SALES, and get the top and bottom products by
    // SALES.    
    singleSelections.setMeasure(sales);
    // Change the number of elements selected.
    topNBottom.setN(7);
    // Change the type of selection back to the top.
    topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_TOP);

    resultDescription = " products with the highest sales amounts \nfor";
    displayResultDescr(singleSelections, topNBottom, resultDescription);

    topNBottomResult = topNBottom.getSource();
    result = prodShortDescrAttr.joinHidden(topNBottomResult);
    
    // Commit the current transaction.
    getContext().commit();
    getContext().displayTopBottomResult(result);

    // Change the type of selection back to the bottom.
    topNBottom.setTopBottomType(TopBottomTemplate.TOP_BOTTOM_TYPE_BOTTOM);

    resultDescription = " products with the lowest sales amounts \nfor";
    displayResultDescr(singleSelections, topNBottom, resultDescription);

    topNBottomResult = topNBottom.getSource();
    result = prodShortDescrAttr.joinHidden(topNBottomResult);
    
    // Commit the current transaction.
    getContext().commit();
    getContext().displayTopBottomResult(result);

  } 

  /**
   * Displays a description of the results of the query.
   * 
   * @param singleSelections The SingleSelectionsTemplate used by the query.
   * 
   * @param topNBottom The TopBottomTemplate used by the query.
   * 
   * @param resultDescr A String that contains a description of the query.
   */
  private void displayResultDescr(SingleSelectionTemplate singleSelections,
                                  TopBottomTemplate topNBottom,
                                  String resultDescr)
  {
    DataProvider dp = getContext().getDataProvider();
    
    // Get the short descriptions of the dimension members of the  
    // SingleSelectionTemplate.
    StringBuffer shortDescrsForMemberVals =
      singleSelections.getMemberShortDescrs(dp);
    
    // Display the number of dimension members selected, the result description,
    // and the short descriptions of the single selection dimension members.
    println("\nThe " + Math.round(topNBottom.getN()) + resultDescr
            + shortDescrsForMemberVals +" are:\n"); 
  }

  /**
   * Runs the TopBottomTest application.
   *
   * @param args An array of String objects that provides the arguments
   *             required to connect to an Oracle Database instance, as
   *             specified in the Context11g class.
   */
  public static void main(String[] args) 
  {
    new TopBottomTest().execute(args);
  }

}

TopBottomTestプログラムの出力は、次のようになります。

The 10 products with the most units sold
for Asia Pacific, Direct Sales, 2001 are:

 1. Mouse Pad
 2. Unix/Windows 1-user pack
 3. Deluxe Mouse
 4. Laptop carrying case
 5. 56Kbps V.90 Type II Modem
 6. 56Kbps V.92 Type II Fax/Modem
 7. Keyboard Wrist Rest
 8. Internal - DVD-RW - 6X
 9. O/S Documentation Set - English
10. External - DVD-RW - 8X
 
The 5 products with the fewest units sold
for Asia Pacific, Direct Sales, 2000 are:
 
 1. Envoy External Keyboard
 2. O/S Documentation Set - Italian
 3. External 48X CD-ROM
 4. O/S Documentation Set - Spanish
 5. Internal 48X CD-ROM USB

The 7 products with the highest sales amounts 
for Asia Pacific, Direct Sales, 2000 are:
 
 1. Sentinel Financial
 2. Sentinel Standard
 3. Envoy Executive
 4. Sentinel Multimedia
 5. Envoy Standard
 6. Envoy Ambassador
 7. 56Kbps V.90 Type II Modem
 
The 7 products with the lowest sales amounts 
for Asia Pacific, Direct Sales, 2000 are:

 1. Envoy External Keyboard
 2. Keyboard Wrist Rest
 3. Mouse Pad
 4. O/S Documentation Set - Italian
 5. O/S Documentation Set - Spanish
 6. Standard Mouse
 7. O/S Documentation Set - French