Olap Java Api Developers Guide
Olap Java Api Developers Guide
Olap Java Api Developers Guide
21c
F31849-01
November 2020
Oracle OLAP Java API Developer's Guide, 21c
F31849-01
Contributors: David Greenfield, Jim Hartsing, Scott Feinstein, Anne Murphy, Richard Samuels, Steve
Mesropian, Chuck Venezia, Afsaneh Koochek
This software and related documentation are provided under a license agreement containing restrictions on
use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your
license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license,
transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse
engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is
prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-free. If
you find any errors, please report them to us in writing.
If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on
behalf of the U.S. Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated software,
any programs embedded, installed or activated on delivered hardware, and modifications of such programs)
and Oracle computer documentation or other Oracle data delivered to or accessed by U.S. Government
end users are "commercial computer software" or "commercial computer software documentation" pursuant
to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such,
the use, reproduction, duplication, release, display, disclosure, modification, preparation of derivative works,
and/or adaptation of i) Oracle programs (including any operating system, integrated software, any programs
embedded, installed or activated on delivered hardware, and modifications of such programs), ii) Oracle
computer documentation and/or iii) other Oracle data, is subject to the rights and limitations specified in the
license contained in the applicable contract. The terms governing the U.S. Government’s use of Oracle cloud
services are defined by the applicable contract for such services. No other rights are granted to the U.S.
Government.
This software or hardware is developed for general use in a variety of information management applications.
It is not developed or intended for use in any inherently dangerous applications, including applications that
may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you
shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its
safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this
software or hardware in dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of
their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are
used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Epyc,
and the AMD logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered
trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content, products,
and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly
disclaim all warranties of any kind with respect to third-party content, products, and services unless otherwise
set forth in an applicable agreement between you and Oracle. Oracle Corporation and its affiliates will not
be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content,
products, or services, except as set forth in an applicable agreement between you and Oracle.
Contents
Preface
Audience ix
Documentation Accessibility ix
Related Documents x
Conventions x
iii
2.2.1.3 Supporting Legacy Metadata Objects 2-4
2.2.2 Using Descriptions 2-6
2.2.3 Using Classifications 2-9
2.3 Providing Metadata Objects 2-9
2.3.1 Describing Metadata Providers 2-9
2.3.1.1 Getting Metadata Objects by ID 2-10
2.3.1.2 Exporting and Importing Metadata as XML Templates 2-10
2.3.2 Representing Schemas 2-13
2.3.2.1 Representing the Root Schema 2-13
2.3.2.2 Representing Database Schemas 2-14
2.3.2.3 Representing Organizational Schemas 2-15
2.4 Providing Access to Data Sources 2-15
2.4.1 Representing Cubes and Measures 2-16
2.4.1.1 Representing Cubes 2-16
2.4.1.2 Representing Measures 2-18
2.4.2 Representing Dimensions, Levels, and Hierarchies 2-19
2.4.2.1 Representing Dimensions 2-20
2.4.2.2 Representing Dimension Levels 2-21
2.4.2.3 Representing Hierarchies 2-21
2.4.2.4 Representing Hierarchy Levels 2-23
2.4.3 Representing Dimension Attributes 2-23
2.4.3.1 Describing the MdmAttribute Class 2-24
2.4.3.2 Describing the MdmBaseAttribute Class 2-25
2.4.3.3 Describing the MdmDerivedAttribute Class 2-29
2.4.4 Using OLAP Views 2-29
2.4.4.1 Getting Cube View and View Column Names 2-29
2.4.4.2 Getting Dimension and Hierarchy View and View Column Names 2-30
2.4.4.3 Using OLAP View Columns 2-31
2.4.4.4 Using Source Objects 2-34
3 Discovering Metadata
3.1 Connecting to Oracle OLAP 3-1
3.1.1 Prerequisites for Connecting 3-1
3.1.2 Establishing a Connection 3-1
3.1.2.1 Creating a JDBC Connection 3-2
3.1.2.2 Creating a DataProvider and a UserSession 3-2
3.1.3 Closing the Connection and the DataProvider 3-3
3.2 Overview of the Procedure for Discovering Metadata 3-3
3.2.1 Purpose of Discovering the Metadata 3-3
3.2.2 Steps in Discovering the Metadata 3-4
iv
3.3 Creating an MdmMetadataProvider 3-4
3.4 Getting the MdmSchema Objects 3-5
3.5 Getting the Contents of an MdmSchema 3-6
3.6 Getting the Objects Contained by an MdmPrimaryDimension 3-7
3.6.1 Getting the Hierarchies and Levels of an MdmPrimaryDimension 3-7
3.6.2 Getting the Attributes for an MdmPrimaryDimension 3-8
3.7 Getting the Source for a Metadata Object 3-9
v
5.4.2 Outputs of a Source 5-8
5.4.2.1 Producing a Source with an Output 5-8
5.4.2.2 Using COMPARISON_RULE_SELECT 5-9
5.4.2.3 Using COMPARISON_RULE_REMOVE 5-9
5.4.2.4 Producing a Source with Two Outputs 5-10
5.4.2.5 Hiding an Output 5-11
5.4.3 Inputs of a Source 5-12
5.4.3.1 Primary Source Objects with Inputs 5-12
5.4.3.2 Deriving a Source with an Input 5-12
5.4.3.3 Type of Inputs 5-13
5.4.4 Matching a Source with an Input 5-13
5.4.4.1 Matching the Input of the Source for an MdmAttribute 5-14
5.4.4.2 Matching the Inputs of a Measure 5-14
5.4.4.3 Using the value Method to Derive a Source with an Input 5-16
5.4.4.4 Using the value Method to Select Values of a Source 5-16
5.4.4.5 Using the extract Method to Combine Elements of Source Objects 5-18
5.5 Describing Parameterized Source Objects 5-19
vi
7 Using a TransactionProvider
7.1 About Creating a Metadata Object or a Query in a Transaction 7-1
7.1.1 Types of Transaction Objects 7-2
7.1.2 Committing a Transaction 7-2
7.1.3 About Transaction and Template Objects 7-3
7.1.4 Beginning a Child Transaction 7-3
7.1.5 About Rolling Back a Transaction 7-4
7.1.6 Getting and Setting the Current Transaction 7-6
7.2 Using TransactionProvider Objects 7-6
vii
10 Creating Dynamic Queries
10.1 About Template Objects 10-1
10.1.1 About Creating a Dynamic Source 10-1
10.1.2 About Translating User Interface Elements into OLAP Java API
Objects 10-2
10.2 Overview of Template and Related Classes 10-2
10.2.1 What Is the Relationship Between the Classes That Produce a
Dynamic Source? 10-2
10.2.2 Template Class 10-3
10.2.3 MetadataState Interface 10-3
10.2.4 SourceGenerator Interface 10-3
10.2.5 DynamicDefinition Class 10-4
10.3 Designing and Implementing a Template 10-4
10.3.1 Implementing the Classes for a Template 10-5
10.3.2 Implementing an Application That Uses Templates 10-9
B SingleSelectionTemplate Class
B.1 Code for the SingleSelectionTemplate Class B-1
Index
viii
Preface
Oracle OLAP Java API Developer's Guide introduces Java programmers to the Oracle
OLAP Java API, which is the Java application programming interface for Oracle
OLAP. Through Oracle OLAP, the OLAP Java API provides access to data stored
in an Oracle database, particularly data in an analytic workspace. The OLAP Java
API capabilities for creating and maintaining analytic workspaces, and for querying,
manipulating, and presenting data are particularly suited to applications that perform
online analytical processing (OLAP) operations.
The preface contains these topics:
• Audience
• Documentation Accessibility
• Related Documents
• Conventions
Audience
Oracle OLAP Java API Developer's Guide is intended for Java programmers who are
responsible for creating applications that do one or more of the following:
• Implement an Oracle OLAP metadata model.
• Define, build, and maintain analytic workspaces.
• Perform analysis using Oracle OLAP.
To use this manual, you should be familiar with Java, relational database management
systems, data warehousing, OLAP concepts, and Oracle OLAP.
Documentation Accessibility
For information about Oracle's commitment to accessibility, visit the Oracle
Accessibility Program website at http://www.oracle.com/pls/topic/lookup?
ctx=acc&id=docacc.
ix
Preface
Related Documents
For more information, see these Oracle resources:
• Oracle OLAP Java API Reference
• Oracle OLAP User's Guide
• Oracle OLAP DML Reference
Conventions
The following text conventions are used in this document:
Convention Meaning
boldface Boldface type indicates graphical user interface elements associated
with an action, or terms defined in text or the glossary.
italic Italic type indicates book titles, emphasis, or placeholder variables for
which you supply particular values.
monospace Monospace type indicates commands within a paragraph, URLs, code
in examples, text that appears on the screen, or text that you enter.
x
Changes in This Release for Oracle OLAP
Java API Developer's Guide
No changes have been made to the Oracle OLAP Java API since Oracle Database
12c, Release 1 (12.1). For changes in that release, see the following topic.
Desupported Features
Some features previously described in this document are desupported in Oracle
Database 12c Release 1 (12.1). See Oracle Database Upgrade Guide for information
on desupported features.
xi
1
Introduction to the OLAP Java API
This chapter introduces the Oracle OLAP Java application programming interface
(API). The chapter includes the following topics:
• OLAP Java API Overview
• Accessing Data Through the OLAP Java API
• Sample Schema for OLAP Java API Examples
• Tasks That an OLAP Java API Application Performs
1-1
Chapter 1
OLAP Java API Overview
• Modify queries, rather than totally redefine them, as application users refine their
analyses.
• Retrieve query results that are structured for display in a multidimensional format.
For more information on some of these operations, see "Tasks That an OLAP Java
API Application Performs".
Package Description
data.cursor Contains classes that represent cursor managers and cursors
that retrieve the data specified by a Source object. For
information on Cursor objects, see Understanding Cursor
Classes and Concepts and Retrieving Query Results.
data.source Contains classes that represent data sources and cursor
specifications. You use Source objects to create queries of
the data store. With the Template class you can incrementally
build a Source object that represents a query that you can
dynamically modify. For information on Source objects, see
Understanding Source Objects and Making Queries Using
Source Methods. For information on Template objects, see
Creating Dynamic Queries.
metadata Contains classes that represent metadata objects, classes that
metadata.deployment map the metadata objects to relational data sources, and classes
that deploy the metadata objects in an analytic workspace or
metadata.mapping in relational database structures. For a description of these
metadata.mdm packages, see Understanding OLAP Java API Metadata. For
information on using the classes in these packages, see
Discovering Metadata and Creating Metadata and Analytic
Workspaces.
resource Contains classes that support the internationalization of
messages for Exception classes.
session Contains a class that represents a session in a connection to an
Oracle database.
1-2
Chapter 1
OLAP Java API Overview
Table 1-1 (Cont.) Packages of the OLAP Java API under oracle.olapi
Package Description
syntax Contains classes that represent the items and commands that
specify how Oracle OLAP builds analytic workspace objects
and classes that implement a syntax for creating SQL-like
expressions. You use Expression objects in mapping metadata
objects to relational data sources such as columns in a table or
a view. You also use Expression objects to specify calculations
and analytical operations for some metadata objects.
transaction Contains classes that represent transactions with Oracle OLAP
in an Oracle Database instance. You use Transaction objects
to commit changes to the database. For information on
Transaction objects, see Using a TransactionProvider.
The OLAP Java API also has packages organized under the oracle.express
package. These packages date from the earliest versions of the API. The classes
that remain in these packages are mostly Exception classes for exceptions that occur
during interactions between Oracle OLAP and a client application.
For information on obtaining the OLAP Java API software and on the requirements for
using it to develop applications, see Setting Up the Development Environment.
Cubes
Cubes are containers for measures that have the same set of dimensions. A cube
usually corresponds to a single relational fact table or view. The measures of a
cube contain facts and the dimensions give shape to the fact data. Typically, the
dimensions form the edges of the cube and the measure data is the body of the cube.
For example, you could organize data on product units sold into a cube whose edges
contain values for members from time, product, customer, and channel dimensions
and whose body contains values from a measure of the quantity of units sold and a
measure of sales amounts.
The OLAP concept of a cube edge is not represented by a metadata object in the
OLAP Java API, but edges are often incorporated into the design of applications that
use the OLAP Java API. Each edge contains values of members from one or more
dimensions. Although there is no limit to the number of edges on a cube, data is often
organized for display purposes along three edges, which are referred to as the row
edge, column edge, and page edge.
Measures
Measures contain fact data in a cube. The measure values are organized and
identified by dimensions. Measures are usually multidimensional. Each measure
value is identified by a unique set of dimension members. This set of dimension
members is called a tuple.
1-3
Chapter 1
OLAP Java API Overview
Dimensions
Dimensions contain lists of unique values that identify and categorize data in a
measure. Commonly-used dimensions are customers, products, and times. Typically,
a dimension has one or more hierarchies that organize the dimension members into
parent-child relationships.
By specifying dimension members, measures, and calculations to perform on the
data, end users formulate business questions and get answers to their queries. For
example, using a time dimension that categorizes data by month, a product dimension
that categorizes data by unit item, and a measure that contains data for the quantities
of product units sold by month, you can formulate a query that asks if sales of a
product unit were higher in January or in June.
Hierarchies
Hierarchies are components of a dimension that organize dimension members into
parent-child relationships. Typically, in the user interface of a client application, an end
user can expand or collapse a hierarchy by drilling down or up among the parents and
children. The measure values for the parent dimension members are aggregations of
the values of the children.
A dimension can have more than one hierarchy. For example, a time dimension
could have a calendar year hierarchy and a fiscal year hierarchy. A hierarchy can be
level-based or value-based.
In a level-based hierarchy, a parent must be in a higher level than the children of
that parent. In a cube, the measure values for the parents are typically aggregated
from the values of the children. For example, a time dimension might have levels for
year, quarter, and month. The month level contains the base data, which is the most
detailed data. The measure value for a quarter is an aggregation of the values of
the months that are the children of the quarter and the measure value for a year is
the aggregation of the quarters that are children of the year. Typically each level is
mapped to a different column in the relational dimension table.
In a value-based hierarchy, the parent and the child dimension members typically
come from the same column in the relational table. Another column identifies the
parent of a member. For example, a value hierarchy could contain all employees of
a company and identify the manager for each employee that has one. All employees,
including managers, would come from the same column. Another column would
contain the managers of the employees.
Levels
Levels are components of a level-based hierarchy. A level can be associated with
more than one hierarchy. A dimension member can belong to only one level.
A level typically corresponds to a column in a dimension table or view. The base level
is the primary key.
Attributes
Attributes contain information related to the members of a dimension. An end user
can use an attribute to select data. For example, an end user might select a set
of products by using an attribute that has a descriptive name of each product. An
attribute is contained by a dimension.
Queries
A query is a specification for a particular set of data. The term query in the OLAP
Java API refers to a Source object that specifies a set of data and can include
aggregations, calculations, or other operations to perform using the data. The data
and the operations on it define the result set of the query. In this documentation, the
general term query refers to a Source object.
1-4
Chapter 1
Accessing Data Through the OLAP Java API
The API has a Query class in the oracle.olapi.syntax package. A Query represents
a multirow, multicolumn result set that is similar to a relational table, a SQL SELECT
statement, or an OLAP function. You use a Query object in mapping a dimension or
measure to a relational table or view.
1-5
Chapter 1
Sample Schema for OLAP Java API Examples
object. To specify the data that you want, you must create a query. In specifying the
data, you usually must specify one or more dimension member values. To retrieve the
specified data, you create a Cursor. This topic briefly describes those actions.
Another way that you can query the data contained in OLAP metadata objects
is through SQL queries of the views that Oracle OLAP creates for the metadata
objects. For information about querying these views, see "Using OLAP Views" in
Understanding OLAP Java API Metadata.
CALENDAR_YEAR::YEAR::CY2001
The third part of a unique value is the local value. The local value in the preceding
example identifies the calendar year 2001.
1-6
Chapter 1
Sample Schema for OLAP Java API Examples
(OTN) website. One example, CreateAndBuildAW.java, has methods that create and
build an analytic workspace. Another example, SpecifyAWValues, calls the methods
of CreateAndBuildAW.java and specifies values, such as names for the metadata
objects and names of columns of relational tables for mapping the metadata objects
to data sources. The analytic workspace produced by these examples is named
GLOBAL_AWJ. Other examples query that analytic workspace. The metadata objects
in the analytic workspace are mapped to columns in relational tables that are in the
Global schema.
From the OTN website, you can download a file that contains SQL scripts that create
the Global schema and a file that contains the example programs. The OTN website is
at http://www.oracle.com/technetwork/database/options/olap/index.html.
To get either file, select Sample Code and Schemas in the Download section of the
web page. To get the sample schema, select Global Schema 11g. To get the example
programs, select Example Programs for Documentation and then select Download
the Example Programs for 11g Release 2 (11.2) to download the compressed file
that contains the examples.
The example programs are in a package structure that you can easily add
to your development environment. The classes include a base class that the
example program classes extend, and utility classes that they use. The base
class is BaseExample11g.java. The utility classes include Context11g.java and
CursorPrintWriter.java. The Context11g.java class has methods that create
a connection to an Oracle Database instance, that store metadata objects,
that return the stored metadata objects, and that create Cursor objects. The
CursorPrintWriter.java class is a PrintWriter that has methods that display the
contents of Cursor objects.
The OLAP metadata objects are created and built by the CreateAndBuildAW.java and
the SpecifyAWValues programs. Those metadata objects include the following:
• GLOBAL_AWJ, which is the analytic workspace that contains the other objects.
• PRODUCT_AWJ, which is a dimension for products. It has one hierarchy
named PRODUCT_PRIMARY. The lowest level of the hierarchy has product item
identifiers and the higher levels have product family, class, and total products
identifiers.
• CUSTOMER_AWJ, which is a dimension for customers. It has two hierarchies
named SHIPMENTS and MARKETS. The lowest level of each hierarchy
has customer identifiers and higher levels have warehouse, region, and
total customers, and account, market segment, and total market identifiers,
respectively.
• TIME_AWJ, which is a dimension for time values. It has a hierarchy named
CALENDAR_YEAR. The lowest level has month identifiers, and the other levels
have quarter and year identifiers.
• CHANNEL_AWJ, which is a dimension for sales channels. It has one hierarchy
named CHANNEL_PRIMARY. The lowest level has sales channel identifiers and
the higher level has the total channel identifier.
• UNITS_CUBE_AWJ, which is a cube that contains the measures COST, SALES,
and UNITS. COST has values for the costs of product units. SALES has the
dollar amounts for the sales of product units. UNITS has values for the quantities
of product units sold. The cube is dimensioned by all four dimensions. The
aggregation method for the cube is SUM, in which each the value for each parent is
the sum of the values of the children of the parent.
1-7
Chapter 1
Tasks That an OLAP Java API Application Performs
Task 1: Connect to the Data Store and Create a DataProvider and UserSession
You connect to the data store by identifying some information about the target Oracle
Database instance and specifying this information in a JDBC connection method.
Having established a connection, you create a DataProvider and use it and the
connection to create a UserSession. For more information about connecting and
creating a DataProvider and UserSession, see "Connecting to Oracle OLAP" in
Discovering Metadata.
1-8
Chapter 1
Tasks That an OLAP Java API Application Performs
For a description of the metadata objects, see Understanding OLAP Java API
Metadata. For information about how you can discover the available metadata, see
Discovering Metadata.
1-9
Chapter 1
Tasks That an OLAP Java API Application Performs
1-10
2
Understanding OLAP Java API Metadata
This chapter describes the classes in the Oracle OLAP Java API that represent OLAP
dimensional and relational metadata objects. It also describes the classes that provide
access to the metadata objects and to data sources, or that contain information about
the metadata objects. This chapter includes the following topics:
• Overview of OLAP Java API Metadata Classes
• Identifying, Describing, and Classifying Metadata Objects
• Providing Metadata Objects
• Providing Access to Data Sources
For more information on getting existing metadata objects, see Discovering Metadata.
For more information on creating metadata objects, see Creating Metadata and
Analytic Workspaces.
2-1
Chapter 2
Overview of OLAP Java API Metadata Classes
oracle.olapi.metadata
2-2
Chapter 2
Identifying, Describing, and Classifying Metadata Objects
Other classes in the package correspond to relational objects. Table 2-2 shows those
correspondences.
2-3
Chapter 2
Identifying, Describing, and Classifying Metadata Objects
For some objects, you can use the setName method to change the name of an existing
object. For example, you can change the name of an MdmStandardDimension by calling
the setName method of the dimension object. The new name does not take effect until
you commit the root Transaction of the session. After you call setName, but before you
commit the root Transaction, the getNewName method returns the new name while the
getName method returns the existing name. For more information on getting objects by
name, see "About Creating a Metadata Object or a Query in a Transaction"
You can get some objects by name from an MdmDatabaseSchema. For more information
on getting objects by name, see "Representing Schemas".
For use in displaying names or descriptions in a user interface, or for any purpose you
want, you can associate any number of names and descriptions with an MdmObject
by using the MdmDescription class. For information on using that class, see "Using
Descriptions".
2-4
Chapter 2
Identifying, Describing, and Classifying Metadata Objects
The 11g XML definition of a 10g object has a Namespace attribute. For information
on exporting and importing XML definitions of metadata objects, see "Exporting and
Importing Metadata as XML Templates".
The namespace of a legacy metadata object identifies the metadata format and the
type of object. It begins with either AWXML_ or CWM_ and then has the type of object,
such as CUBE or DIMENSION. For example, a dimension created by using the Oracle
OLAP Analytic Workspace Java API in Oracle Database 10g, Release 2 (10.2), would
have the namespace AWXML_DIMENSION in 11g.
2-5
Chapter 2
Identifying, Describing, and Classifying Metadata Objects
In the ALL metadata reader mode, you get an existing 10g metadata object but you
cannot create a new one. If the legacy metadata object does not exist, the method
returns an 11g object that has the specified name.
Note:
A descriptive name that you associate with an MdmObject through
an MdmDescription is not the object name that is returned by the
MdmObject.getName method. The object name is used by Oracle OLAP
to identify the object internally. A descriptive name is used only by an
application.
The OLAP Java API defines some types of descriptions. The MdmDescriptionType
class has static methods that provide the following description types:
• Name
• Short name
• Long name
• Plural name
• Short plural name
• Long plural name
• Description
• Short description
• Long description
You get one of these defined description types by calling a method of
MdmDescriptionType. For example, the following code gets the description type object
for a long name and a long description.
MdmDescriptionType mdmLongNameDescrType =
MdmDescriptionType.getLongNameDescriptionType();
MdmDescriptionType mdmLongDescrDescrType =
MdmDescriptionType.getLongDescriptionDescriptionType();
2-6
Chapter 2
Identifying, Describing, and Classifying Metadata Objects
Some of the defined description types have an associated default description type.
You change a default description type or assign a default description type for a new
or existing MdmDescriptionType by using the MdmDescriptionType(java.lang.String
type, MdmDescriptionType defaultType) constructor method. You can get the
default type of an MdmDescriptionType object with the getDescriptiveTypeDefault
method.
Example 2-1 Associating a Description with an MdmObject
To associate an MdmDescription object with an MdmObject, use the
findOrCreateDescription or a setDescription method of the MdmObject. The
findOrCreateDescription method returns an MdmDescription object. To specify a
value for the description, use the setValue method of MdmDescription.
mdmProdDim.setDescription(
MdmDescriptionType.getLongNameDescriptionType(), "Product Dimension");
2-7
Chapter 2
Identifying, Describing, and Classifying Metadata Objects
MdmObject
0..*
MdmDescription MdmDescriptionType
Versions of the OLAP Java API before 11g did not have the MdmDescription and
MdmDescriptionType classes. In those versions, the MdmObject class had only the
following methods for getting and setting descriptions.
Figure 2-3 Methods for Getting and Setting Descriptions Before 11g
MdmObject
getDescription() : String
getShortDescription() : String
setShortDescription(String description) : void
setDescription(String description) : void
For backward compatibility, the OLAP Java API still supports these methods, but
implements them internally using MdmDescription and MdmDescriptionType objects.
2-8
Chapter 2
Providing Metadata Objects
The top-level objects are the containers of objects such as MdmMeasure, MdmHierarchy,
and MdmAttribute objects. You create the contained objects by using methods of the
top-level objects.
For more information on MdmSchema objects, see "Representing Schemas". For
information on top-level metadata objects, see "Providing Access to Data Sources".
You can also get an existing metadata object by calling the getMetadataObject or
getMetadataObjects method of the MdmMetadataProvider and providing the ID of the
metadata object.
The following topics describe getting metadata objects:
• Getting Metadata Objects by ID
• Exporting and Importing Metadata as XML Templates
2-9
Chapter 2
Providing Metadata Objects
You can store the ID of a metadata object from one session and then get the object by
that ID in another session. Of course, getting an object by a stored ID assumes that
the object still exists and that the ID of the object has not changed. For some metadata
objects, you can change the name or the owner. If the name or owner of the object
changes, then the ID of the object changes.
The following topics describe exporting and importing metadata objects through XML
templates.
• Exporting XML Templates
• Importing XML Templates
• Describing Bind Variables in XML Templates
You can use an XML template produced by these methods to import metadata objects
through the importXML methods of MdmMetadataProvider. You can also use the XML
template to import metadata objects in Analytic Workspace Manager.
2-10
Chapter 2
Providing Metadata Objects
An exportIncrementalXML method exports only the XML attributes that have changed
for a metadata object since a specified Transaction. If you specify a List of objects,
then the exported templates contain the XML attributes that have changed for the
objects that are in the list. The exported incremental XML includes the type and name
of the objects in the ownership and containment hierarchy of the changed object.
The exportFullXML and exportIncrementalXML methods take various combinations of
the following parameters.
• A List of the objects to export or a Transaction.
• A Writer to which Oracle OLAP exports the XML. If you do not specify a Writer,
then the method returns a java.lang.String that contains the XML.
• A java.util.Map that has metadata object references as keys and that has, as
the objects for the keys, String values that contain new names for the referenced
objects. With this Map, you can rename an object that you export. You can specify
null for the parameter if you do not want to rename any objects.
If you specify a Map for this renameMap parameter, then the Oracle OLAP XML
generator renames a referenced object during the export. You can copy the
definition of an existing object this way, by renaming an object during the export of
an XML template and then importing the template.
• A boolean that specifies whether or not to include the name of the owning object in
the exported XML.
• An optional Map that has metadata object references as keys and that has, as the
objects for the keys, String values that function like SQL bind variables. For more
information on the bind variables in this parameter, see "Describing Bind Variables
in XML Templates".
• An optional implementation of the oracle.olapi.metadata.XMLWriterCallback
interface. With an XMLWriterCallback, you can specify whether or not to exclude
an attribute or an owner name from the exported XML.
All metadata objects that share an ancestor are grouped together in the exported XML.
For any object that is not a top-level object and whose top-level container is not in the
List of the objects to export, the exported template contains an incremental definition
to the object and a full definition below that. This supports the export of objects such
as a calculated measure in a cube without having to export the entire cube template.
If an MdmDatabaseSchema is in the List of objects to export, then the
exported template includes all objects within the database schema. If an
oracle.olapi.metadata.deployment.AW object is in the List, then the exported
template includes all of the objects that are contained by the AW. If the MdmRootSchema
is in the list, it is ignored.
2-11
Chapter 2
Providing Metadata Objects
An importXML method imports XML definitions of objects and either creates new
objects or modifies existing objects. The importXML method take various combinations
of the following parameters.
• A java.io.Reader for input of the XML or a String that contains the XML to
import.
• An MdmDatabaseSchema to contain the new or modified metadata objects.
• A boolean, modifyIfExists, that indicates whether or not you want differences in
the imported XML definition to modify an existing object of the same name.
• An optional Map, bindValues, that contains bind variables as keys and, as the
objects for the keys, String values to replace the bind variables. For more
information on the bind values in this parameter, see "Describing Bind Variables in
XML Templates".
• An optional implementation of the oracle.olapi.metadata.XMLParserCallback
interface.
If the value of the modifyIfExists parameter is true and if the imported XML contains
a full definition for an object that already exists and the object definition is different
from the XML, then the method merges the new or changed elements of the object
definition with the existing definition of the object. If the value of modifyIfExists is
false and if the XML contains a full definition for an object that already exists, then the
importXML method throws an exception.
With the bindValues parameter, you can specify a Map that has key/object pairs that
Oracle OLAP uses to replace bind variables when importing an XML template. A key
in the Map is a bind variable to replace and the object paired to the key is the value with
which to replace the bind variable. When you import a template, if you specify a Map
that contains bind variables as keys, then Oracle OLAP replaces a bind variable in the
imported XML with the value specified for the bind variable in the bindValues Map.
2-12
Chapter 2
Providing Metadata Objects
A value specified in the bindVariables map appears in the exported XML in the
format "&BV;", where BV is the bind variable.
If you provide a Map for the bindValues parameter, then the inXML string that you
provide to the method must include the !DOCTYPE Metadata declaration and the bind
variables in the XML to import must be in the "&BV;" format.
The MdmRootSchema class also contains all of the MdmCube, MdmMeasure, and
MdmPrimaryDimension objects that are provided by the MdmMetadataProvider, and
has methods for getting those objects. However, the List of objects returned by
2-13
Chapter 2
Providing Metadata Objects
those methods contains only the cubes, measures, or dimensions that the user has
permission to see.
Figure 2-4 shows the associations between an MdmMetadataProvider and the
subclasses of MdmSchema.
1 1
MdmMetadataProvider MdmRootSchema
getRootSchema
1
getDatabaseSchema
0...* 1...* getDatabaseSchemas
addOrganizationalSchema
1
0...*
MdmOrganizationalSchema MdmDatabaseSchema
findOrCreateOrganizationalSchema
The MdmRootSchema has one MdmDatabaseSchema object for each database user. An
MdmDatabaseSchema has the same name as the database user. For example, the name
of the MdmDatabaseSchema for the user GLOBAL is GLOBAL.
You can get one or all of the MdmDatabaseSchema objects with methods of
the MdmRootSchema. However, access to the objects that are owned by an
MdmDatabaseSchema is determined by the security privileges granted to the user of
the session.
An MdmDatabaseSchema is the owner of top-level OLAP metadata objects and the
objects created by them. You use an MdmDatabaseSchema to get existing metadata
objects or to create new ones. The top-level objects are the following:
• AW
• MdmCube
• MdmNamedBuildProcess
• MdmOrganizationalSchema
• MdmPrimaryDimension
• MdmTable
Except for an MdmTable, you can create new top-level objects, or get
existing ones, with the findOrCreate methods such as findOrCreateAW and
findOrCreateStandardDimension. Creating objects is described in Discovering
Metadata.
When you commit the Transaction in which you have created top-level OLAP
metadata objects, those objects then exist in the Oracle data dictionary. They are
2-14
Chapter 2
Providing Access to Data Sources
available for use by ordinary SQL queries as well as for use by applications that use
the Oracle OLAP Java API.
Because the metadata objects exist in the Oracle data dictionary, an Oracle Database
DBA can restrict access to certain types of the metadata objects. In a client
application, you can set such restrictions by using the JDBC API to send standard
SQL GRANT and REVOKE commands through the JDBC connection for the user session.
You can get an MdmTable, or other top-level object, with the getTopLevelObject
method. You can get all of the instances of a particular type of top-level object
with methods such as getAWs, getDimensions, or getOrganizationalSchemas, or
you can use the getSchemaObjects to get all of the objects owned by the
MdmDatabaseSchema. You can add or remove top-level objects with methods like addAW
and removeSchemaObject.
0...*
MdmCube MdmPrimaryDimension
1 1 1 1
2-15
Chapter 2
Providing Access to Data Sources
The classes that represent these dimensional or relational data objects are subclasses
of the MdmSource class. Subclasses of MdmSource have a getSource method, which
returns a Source object. You use Source objects to define a query of the data. You
then use Cursor objects to retrieve the data. For more information about working with
Source and Cursor objects, see Understanding Source Objects and Understanding
Cursor Classes and Concepts.
You can also use SQL to query the views that Oracle OLAP automatically generates
for the cubes, dimensions, and hierarchies. For information on querying these views,
see "Getting Dimension and Hierarchy View and View Column Names".
The following topics describe the classes that provide access to data sources.
• Representing Cubes and Measures
• Representing Dimensions, Levels, and Hierarchies
• Representing Dimension Attributes
• Using OLAP Views
An MdmCube usually corresponds to a single fact table or view. To associate the table or
view with the cube, you use Query and CubeMap objects. You get the Query for the table
or view and then associate the Query with the CubeMap by using the setQuery method
of the CubeMap.
The CubeMap contains MeasureMap and CubeDimensionalityMap objects that map the
measures and dimensions of the cube to data sources. With the MeasureMap, you
specify an MdmBaseMeasure and an Expression that identifies the column in the fact
table or view that contains the base data for the measure.
To map the dimensions of the cube you get the MdmDimensionality objects of the
cube. You create a CubeDimensionalityMap for each MdmDimensionality. You then
specify an Expression for the CubeDimensionalityMap that identifies the foreign
key column for the dimension in the fact table or view. If you want to specify
a dimension column other than the column for the leaf-level dimension members,
then you must specify a join Condition with the setJoinCondition method of the
CubeDimensionalityMap.
2-16
Chapter 2
Providing Access to Data Sources
A cube is consistent when the values of the measures match the specification,
for example, when the values of the parents are equal to the SUM of the values
of their children. A cube becomes consistent when the BuildProcess executes the
ConsistentSolveCommand.
For examples of creating MdmCube and MdmMeasure objects and mapping them, and of
the other operations described in this topic, see Example 4-7 and Example 4-8.
Figure 2-6 shows the associations between an MdmCube and the some of the classes
mentioned in this topic. The figure shows an MdmCube as deployed in an analytic
workspace.
ConsistentSolveCommand
1...*
setConsistentSolveSpecification
findOrCreateAWCubeOrganization
ConsistentSolveSpecification AWCubeOrganization
1 1
findOrCreateCubeMap
addDimension
MdmDimensionality MdmCube CubeMap
0...* 1 0...*
1
MdmDimension 1 1
findOrCreateBaseMeasure findOrCreateDerivedMeasure
0...* 0...*
MdmBaseMeasure MdmDerivedMeasure
2-17
Chapter 2
Providing Access to Data Sources
For example, suppose you have an MdmMeasure that has data that records the number
of product units sold to a customer during a time period and through a sales channel.
The data of the measure is organized by dimensions for products, times, customers,
and channels (with a channel representing the sales avenue, such as catalog or
internet.). You can think of the data as occupying a four-dimensional array with
the product, time, customer, and channel dimensions providing the organizational
structure. The values of these four dimensions are indexes for identifying each
particular cell in the array. Each cell contains a single data value for the number of
units sold. You must specify a value for each dimension in order to identify a value in
the array.
The values of an MdmMeasure are usually numeric, but a measure can have values
of other data types. The concrete subclasses of MdmMeasure are MdmBaseMeasure and
MdmDerivedMeasure.
2-18
Chapter 2
Providing Access to Data Sources
• Aggregated values that Oracle OLAP has provided. These measure values are
identified by at least one member from an aggregate level of a hierarchy.
• Values specified by an Expression for a MdmDerivedMeasure or a custom
dimension member.
As an example, imagine an MdmBaseMeasure that is dimensioned by an
MdmTimeDimension and an MdmStandardDimension of products. The metadata objects
for the measure and the dimensions are mdmUnitCost, mdmTimeDim, and mdmProdDim.
Each of the mdmTimeDim and the mdmProdDim objects has all of the leaf members and
aggregate members of the dimension it represents. A leaf member is one that has no
children. An aggregate member has one or more children.
A unique combination of two members, one from mdmTimeDim and one from
mdmProdDim, identifies each mdmUnitCost value, and every possible combination of
dimension members is used to specify the entire set of mdmUnitCost values.
2-19
Chapter 2
Providing Access to Data Sources
• Buildable, which is a marker interface for objects that you can specify in
constructing a BuildItem.
• MdmMemberListMapOwner, which defines methods for finding or creating, or getting,
a MemberListMap object.
• MdmViewColumnOwner, which is marker interface for objects that can have an
associated MdmViewColumn.
• MetadataObject, which defines a method for getting a unique identifier.
• MdmQuery, which defines methods for getting the Query object associated with the
implementing class and for getting information about the Query.
An MdmPrimaryDimension can have component MdmDimensionLevel objects that
organize the dimension members into levels. It also can have MdmHierarchy objects,
which organize the levels into the hierarchies. An MdmPrimaryDimension has all of the
members of the component MdmHierarchy objects, while each of the MdmHierarchy
objects has only the members in that hierarchy.
You can get all of the MdmPrimaryDimension objects that are contained by an
MdmDatabaseSchema or an MdmOrganizationalSchema by calling the getDimensions
method of the object. An MdmDatabaseSchema has methods for finding an
MdmTimeDimension or an MdmStandardDimension by name or creating the object if it
does not already exist.
MdmStandardDimension and MdmTimeDimension objects contain MdmAttribute objects.
Some of the attributes are derived by Oracle OLAP, such as the parent attribute,
2-20
Chapter 2
Providing Access to Data Sources
and others you map to data in relational tables or to data that you specify by an
Expression. For information on attributes, see "Representing Dimension Attributes".
The following topics describe the objects that represent level-based and value-based
hierarchies.
• Representing a Level-based Hierarchy
• Representing a Value-based Hierarchy
2-21
Chapter 2
Providing Access to Data Sources
Oracle OLAP also expects that if a member is in a level below the top level, then
that member has a parent, and that the parent is in the level just above the level of
the member. If a member is not at the top level and that member either does not
have a parent or the parent is not in the next higher level, then the hierarchy is a
skip-level hierarchy. You can specify allowing a skip-level hierarchy by calling the
setIsSkipLevel(true) method of the MdmLevelHierarchy.
Regular
Level Hierarchy Ragged Hierarchy Skip-level Hierarchies
Top level
Leaf level
2-22
Chapter 2
Providing Access to Data Sources
The order of the levels in the hierarchy is specified by the order in which
you create the MdmHierarchyLevel objects for the MdmLevelHierarchy. The first
MdmHierarchyLevel that you create is the highest level and the last one that you
create is the lowest level. For an example of creating a hierarchy, see "Creating and
Mapping an MdmLevelHierarchy".
2-23
Chapter 2
Providing Access to Data Sources
Table 2-3 shows the first few members of the PRODUCT_AWJ dimension and their
related short description and package attribute values. Only some of the members of
the ITEM level of the dimension have a package attribute. For other items, and for
higher levels, the package attribute value is null, which appears as NA in the table.
To get values from an MdmAttribute, you must join the Source for the MdmAttribute
and a Source that specifies one or more members of the MdmDimension. For
an explanation of joining Source objects, see Understanding Source Objects. For
examples of joining the Source objects for an MdmAttribute and an MdmDimension, see
Example 4-5 and examples from Understanding Source Objects and Making Queries
Using Source Methods, such as Example 5-7 and Example 6-10.
The following topics describe the classes that represent dimension attributes.
• Describing the MdmAttribute Class
• Describing the MdmBaseAttribute Class
• Describing the MdmDerivedAttribute Class
2-24
Chapter 2
Providing Access to Data Sources
Examples of MdmBaseAttribute objects are the name attribute created and mapped in
Example 4-5 and the long description attribute created in Example 4-6. The mapping
for that long description attribute is in Example 4-3.
For regular OLAP queries, using Source objects, you only need to map an
MdmBaseAttribute to MdmDimensionLevel objects by using MemberListMap objects.
2-25
Chapter 2
Providing Access to Data Sources
For SQL queries against OLAP views, you should map the attributes to
MdmHierarchyLevel objects by using HierarchyLevelMap objects.
2-26
Chapter 2
Providing Access to Data Sources
The language in use for the database determines which language appears in the
OLAP view for the dimension. Only one language is in use at a time in a session,
but if the language in use changes, then the language in the attribute column in the
OLAP view also changes. For more information on specifying languages for database
sessions, see Setting Up a Globalization Support Environment in Oracle Database
Globalization Support Guide.
For materialized views, you should create a separate attribute for each language, so
that there is a long description attribute for English, one for French, and so on. That
behavior is more typical in SQL, which does not expect multivalued columns.
The OLAP view for a hierarchy of the dimension would then have a column for each
of the long description attributes. Those columns would contain the long description
attribute values for the members of the mapped hierarchy level and for the hierarchy
members of all levels that are descendants of the mapped level.
For example, the CreateAndBuildAW example class has a line of code that specifies
populating the lineage for the MdmBaseAttribute objects that it adds to each individual
MdmHierarchyLevel. The following line appears in the createLineageAttributes
method of the class.
mdmAttr.setPopulateLineage(true);
Example 2-2 shows the results of the following SQL query when that line of code
is commented out. Example 2-3 shows the results of the SQL query when the line
is included in the class. Both examples show the values that are in the selected
columns of the OLAP view for the PRODUCT_PRIMARY hierarchy. The view name
is PRODUCT_AWJ_PRODUCT_PRIMA_VIEW. The examples show only a few of the
lines returned by the SQL query.
SELECT TOTAL_PRODUCT_SHORT_DESC || '*' || CLASS_SHORT_DESC || '*' ||
FAMILY_SHORT_DESC || '*' || ITEM_SHORT_DESC
FROM PRODUCT_AWJ_PRODUCT_PRIMA_VIEW
2-27
Chapter 2
Providing Access to Data Sources
2-28
Chapter 2
Providing Access to Data Sources
EnableMVs.java example program creates unique key attributes and adds them to
the MdmDimensionLevel objects of the dimensions.
When Oracle OLAP creates a materialized view for a cube, it creates columns for
the attributes of the dimensions of the cube. For the name of a column, it uses the
name of the attribute column from the OLAP view of the dimension. To ensure that
the column name is unique, Oracle OLAP adds a default prefix to the name. You can
specify the prefix by using the setETAttrPrefix method of the MdmDimensionality
object for a dimension of the cube.
2-29
Chapter 2
Providing Access to Data Sources
You can change the name of the OLAP view by using the MdmCube.setViewName
method. To make the name change permanent, you must commit the Transaction.
The OLAP view for an MdmCube has a column for each measure of the cube, including
each derived measure. In Oracle OLAP User's Guide, a derived measure is known
as a calculated measure. A cube view also has a column for each dimension of the
cube. For example, for the MdmCube named UNITS_CUBE_AWJ, the view is named
UNITS_CUBE_AWJ_VIEW. The following code gets the names of the view columns.
MdmCube mdmUnitsCube = mdmDBSchema.findOrCreateCube("UNITS_CUBE_AWJ");
List<MdmQueryColumn> mdmQCols = mdmUnitsCube.getQueryColumns();
for (MdmQueryColumn mdmQCol : mdmQCols )
{
MdmViewColumn mdmViewCol = (MdmViewColumn) mdmQCol;
println(mdmViewCol.getViewColumnName());
}
The UNITS, SALES, and COST columns are for the measures of the cube, and the other
four columns are for the dimensions of the cube.
2.4.4.2 Getting Dimension and Hierarchy View and View Column Names
To get the name of the OLAP view for a dimension or a hierarchy, call the
getETViewName() method of the MdmPrimaryDimension or MdmHierarchy. You can
get the name of a column in the view by calling the appropriate method of the
metadata object. For example, the following code gets the name of the key column for
the CHANNEL_AWJ dimension and the parent column for the CHANNEL_PRIMARY
hierarchy.
println(mdmChanDim.getETKeyColumn().getViewColumnName());
MdmViewColumn mdmParentCol =(MdmViewColumn) mdmChanHier.getETParentColumn();
println(mdmParentCol.getViewColumnName());
You can change the name of the OLAP view by using the setETViewName method of
the MdmPrimaryDimension or MdmHierarchy.
The OLAP view for an MdmPrimaryDimension has a column for the dimension
keys, a column for each dimension level, and a column for each attribute
associated with the dimension. For example, for the MdmStandardDimension named
CHANNEL_AWJ, the view is named CHANNEL_AWJ_VIEW. The SQL command
DESCRIBE CHANNEL_AWJ_VIEW displays the names of the following columns.
DIM_KEY
LEVEL_NAME
2-30
Chapter 2
Providing Access to Data Sources
MEMBER_TYPE
DIM_ORDER
LONG_DESCRIPTION
SHORT_DESCRIPTION
TOTAL_CHANNEL_LONG_DESC
TOTAL_CHANNEL_SHORT_DESC
CHANNEL_LONG_DESC
CHANNEL_SHORT_DESC
The OLAP view for an MdmHierarchy has a column for the dimension keys and a
column for the parent of a hierarchy member. If it is an MdmLevelHierarchy, then it
also has a column for each hierarchy level and a column for the depth of a level.
If the hierarchy has one or more added attributes, then the view has a column for
each attribute. For example, for the MdmLevelHierarchy named CHANNEL_PRIMARY,
the view is named CHANNEL_AWJ_CHANNEL_PRIMA_VIEW. The SQL command
DESCRIBE CHANNEL_AWJ_CHANNEL_PRIMA_VIEW displays the names of the following
columns.
DIM_KEY
LEVEL_NAME
MEMBER_TYPE
DIM_ORDER
HIER_ORDER
LONG_DESCRIPTION
SHORT_DESCRIPTION
TOTAL_CHANNEL_LONG_DESC
TOTAL_CHANNEL_SHORT_DESC
CHANNEL_LONG_DESC
CHANNEL_SHORT_DESC
PARENT
DEPTH
TOTAL_CHANNEL
CHANNEL
2-31
Chapter 2
Providing Access to Data Sources
// Display the name of the OLAP view name for the hierarchy and
// display the names of the hierarchy levels.
displayViewAndLevelNames(mdmCalHier);
MdmPrimaryDimension mdmProdDim =
(MdmPrimaryDimension)mdmDBSchema.getTopLevelObject("PRODUCT_AWJ");
MdmLevelHierarchy mdmProdHier =
mdmProdDim.findOrCreateLevelHierarchy("PRODUCT_PRIMARY");
displayViewAndLevelNames(mdmProdHier);
MdmPrimaryDimension mdmCustDim =
(MdmPrimaryDimension)mdmDBSchema.getTopLevelObject("CUSTOMER_AWJ");
MdmLevelHierarchy mdmShipHier =
mdmCustDim.findOrCreateLevelHierarchy("SHIPMENTS");
displayViewAndLevelNames(mdmShipHier);
MdmPrimaryDimension mdmChanDim =
(MdmPrimaryDimension)mdmDBSchema.getTopLevelObject("CHANNEL_AWJ");
MdmLevelHierarchy mdmChanHier =
mdmChanDim.findOrCreateLevelHierarchy("CHANNEL_PRIMARY");
displayViewAndLevelNames(mdmChanHier);
// Create a SQL SELECT statement using the names of the views and the
// levels.
// UNITS_CUBE_AWJ_VIEW has a column named SALES for the sales measure.
// TIME_AWJ_CALENDAR_YEAR_VIEW has a column named LONG_DESCRIPTION
// for the long description attribute.
// The hierarchy views have columns that have the same names as the levels.
String sql = "SELECT t.long_description time,\n" +
" ROUND(f.sales) sales\n" +
" FROM TIME_AWJ_CALENDAR_YEAR_VIEW t,\n" +
" PRODUCT_AWJ_PRODUCT_PRIMA_VIEW p,\n" +
" CUSTOMER_AWJ_SHIPMENTS_VIEW cu,\n" +
" CHANNEL_AWJ_CHANNEL_PRIMA_VIEW ch,\n" +
" UNITS_CUBE_AWJ_VIEW f\n" +
" WHERE t.level_name = 'YEAR'\n" +
" AND p.level_name = 'TOTAL_PRODUCT'\n" +
" AND cu.level_name = 'TOTAL_CUSTOMER'\n" +
" AND ch.level_name = 'TOTAL_CHANNEL'\n" +
" AND t.dim_key = f.time_awj\n" +
" AND p.dim_key = f.product_awj\n" +
" AND cu.dim_key = f.customer_awj\n" +
" AND ch.dim_key = f.channel_awj\n" +
" ORDER BY t.end_date";
2-32
Chapter 2
Providing Access to Data Sources
// ...
} // End of method.
2-33
Chapter 2
Providing Access to Data Sources
TOTAL_PRODUCT
CLASS
FAMILY
ITEM
TIME SALES
---------- ----------------------
1998 100870877
1999 134109248
2000 124173522
2001 116931722
2002 92515295
2003 130276514
2004 144290686
2005 136986572
2006 140138317
2007 <null>
2-34
Chapter 2
Providing Access to Data Sources
// Select single values for the hierarchies except for the time hierarchy.
Source prodSel = prodHier.selectValue("PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL");
Source custSel = shipHier.selectValue("SHIPMENTS::TOTAL_CUSTOMER::TOTAL");
Source chanSel = chanHier.selectValue("CHANNEL_PRIMARY::TOTAL_CHANNEL::TOTAL");
getContext().commit();
getContext().displayResult(result);
The values of the Cursor for the result Source are the following. The code for
formatting the values is not shown. For the complete code for Example 2-4 and
Example 2-5, see the BasicCubeViewQuery.java example program.
Year Sales
---- ------------
1998 100870876.58
1999 134109248.15
2000 124173521.55
2001 116931722.03
2002 92515295.02
2003 130276513.86
2004 144290685.55
2005 136986571.96
2-35
Chapter 2
Providing Access to Data Sources
2006 140138317.39
2007 NA
2-36
3
Discovering Metadata
This chapter describes how to connect to an Oracle Database instance and how to
discover existing Oracle OLAP metadata objects. It includes the following topics:
• Connecting to Oracle OLAP
• Overview of the Procedure for Discovering Metadata
• Creating an MdmMetadataProvider
• Getting the MdmSchema Objects
• Getting the Contents of an MdmSchema
• Getting the Objects Contained by an MdmPrimaryDimension
• Getting the Source for a Metadata Object
3-1
Chapter 3
Connecting to Oracle OLAP
In the example, the connection uses the Oracle JDBC thin driver. There are many
ways to specify your connection characteristics using the getConnection method.
There are also other ways to connect to an Oracle Database instance. For more
information about Oracle JDBC connections, see Oracle Database JDBC Developer’s
Guide.
After you have the OracleConnection object, you can create OLAP Java API
DataProvider and UserSession objects.
3-2
Chapter 3
Overview of the Procedure for Discovering Metadata
}
catch(SQLException e)
{
System.out.println("Could not create a UserSession. " + e);
}
Using the DataProvider, you can get the MdmMetadataProvider, which is described
in "Creating an MdmMetadataProvider". You use the DataProvider to get the
TransactionProvider and to create Source and CursorManager objects as described
in Understanding Source Objects and Making Queries Using Source Methods.
When you have completed your work with the database, use the
OracleConnection.close method.
3-3
Chapter 3
Creating an MdmMetadataProvider
Therefore, after connecting, your first step is to find out what metadata is available.
You can then present choices to the end user about what data to select or calculate
and how to display it.
After an application discovers the metadata, it typically goes on to create queries
for selecting, calculating, and otherwise manipulating the data. To work with data in
these ways, you must get the Source objects from the metadata objects. These Source
objects specify the data for querying. For more information on Source objects, see
Understanding Source Objects.
3-4
Chapter 3
Getting the MdmSchema Objects
if (orgSchemaList.size() > 0)
{
println("The MdmOrganizationalSchema subschemas of "
+ mdmSchema.getName() + " are:");
Iterator orgSchemaListItr = orgSchemaList.iterator();
while (orgSchemaListItr.hasNext())
{
MdmOrganizationalSchema mdmOrgSchema = (MdmOrganizationalSchema)
orgSchemaListItr.next();
println(mdmOrgSchema.getName());
getOrgSchemas(mdmOrgSchema);
}
}
else
{
println(mdmSchema.getName() + " does not have any" +
3-5
Chapter 3
Getting the Contents of an MdmSchema
If you want to display all of the dimensions and methods that are owned by a
particular user, then you could get the lists of dimensions and measures from the
MdmDatabaseSchema for that user.
3-6
Chapter 3
Getting the Objects Contained by an MdmPrimaryDimension
UNIT_PRICE
SALES
UNITS
COST
3-7
Chapter 3
Getting the Objects Contained by an MdmPrimaryDimension
3-8
Chapter 3
Getting the Source for a Metadata Object
3-9
Chapter 3
Getting the Source for a Metadata Object
To get the primary Source for a metadata object, an application calls the getSource
method of that metadata object. For example, if an application needs to display the
quantity of product units sold during the year 1999, then it must use the getSource
method of the MdmMeasure for that data, which is mdmUnits in the following example.
For more information about getting and working with primary Source objects, see
Understanding Source Objects.
3-10
4
Creating Metadata and Analytic
Workspaces
This chapter describes how to create new metadata objects and map them to
relational structures or expressions. It describes how to export and import the
definitions of the metadata objects to XML templates. It also describes how to
associate the objects with an analytic workspace, and how to build the analytic
workspace.
The examples in this chapter are from the CreateMetadataAndAW.java example
program. That program creates some of the same metadata objects as
the CreateAndBuildAW.java and SpecifyAWValues.java example programs. The
CreateMetadataAndAW program also exports the analytic workspace to an XML
template.
This chapter includes the following topics:
• Overview of Creating and Mapping Metadata
• Creating an Analytic Workspace
• Creating the Dimensions, Levels, and Hierarchies
• Creating Attributes
• Creating Cubes and Measures
• Committing Transactions
• Exporting and Importing XML Templates
• Building an Analytic Workspace
4-1
Chapter 4
Creating an Analytic Workspace
Example 4-1 demonstrates getting the MdmDatabaseSchema for the GLOBAL user
and creating an AW. For an example that gets the MdmRootSchema, see Discovering
Metadata.
Example 4-1 Creating an AW
private void createAW(MdmRootSchema mdmRootSchema)
{
MdmDatabaseSchema mdmDBSchema = mdmRootSchema.getDatabaseSchema("GLOBAL");
aw = mdmDBSchema.findOrCreateAW("GLOBAL_AWJ");
}
4-2
Chapter 4
Creating the Dimensions, Levels, and Hierarchies
Example 4-2 creates a standard dimension that has the name CHANNEL_AWJ.
The example creates an AWPrimaryDimensionOrganization object to deploy the
dimension in an analytic workspace. The mdmDBSchema and aw objects are created
by Example 4-1. The last three lines call the methods of Example 4-3, Example 4-4,
and Example 4-9, respectively.
Example 4-2 Creating and Deploying an MdmStandardDimension
MdmStandardDimension mdmChanDim =
mdmDBSchema.findOrCreateStandardDimension("CHANNEL_AWJ");
AWPrimaryDimensionOrganization awChanDimOrg =
mdmChanDim.findOrCreateAWPrimaryDimensionOrganization(aw);
createAndMapDimensionLevels(mdmChanDim);
createAndMapHierarchies();
commit(mdmChanDim);
keyColumns.add("GLOBAL.CHANNEL_DIM.TOTAL_ID");
keyColumns.add("GLOBAL.CHANNEL_DIM.CHANNEL_ID");
lDescColNames.add("GLOBAL.CHANNEL_DIM.TOTAL_DSC");
lDescColNames.add("GLOBAL.CHANNEL_DIM.CHANNEL_DSC");
4-3
Chapter 4
Creating the Dimensions, Levels, and Hierarchies
4-4
Chapter 4
Creating the Dimensions, Levels, and Hierarchies
mdmChanDim.findOrCreateDimensionLevel(dimLevelName);
MdmHierarchyLevel mdmHierLevel =
mdmLevelHier.findOrCreateHierarchyLevel(mdmDimLevel);
HierarchyLevelMap hierLevelMap =
mdmHierLevel.findOrCreateHierarchyLevelMap();
ColumnExpression keyColExp =
(ColumnExpression)SyntaxObject.fromSyntax(keyColumns.get(i),
metadataProvider);
hierLevelMap.setKeyExpression(keyColExp);
hierLevelMap.setQuery(keyColExp.getQuery());
i++;
}
}
// Get the EMP table and the Query for the table.
MdmTable empTable = (MdmTable)mdmDBSchema.getTopLevelObject("EMP");
Query empQuery = empTable.getQuery();
4-5
Chapter 4
Creating the Dimensions, Levels, and Hierarchies
solvedValHierMap.setQuery(empQuery);
Expression keyExp =
(Expression)SyntaxObject.fromSyntax("SCOTT.EMP.EMPNO", mp);
solvedValHierMap.setKeyExpression(keyExp);
Expression parentExp =
(Expression)SyntaxObject.fromSyntax("SCOTT.EMP.MGR", mp);
solvedValHierMap.setParentKeyExpression(parentExp);
//Get the Source objects for the dimension, the hierarchy, and the attribute.
Source empDim = mdmEmpDim.getSource();
Source valHier = mdmValHier.getSource();
Source empNameAttr = mdmNameAttr.getSource();
// Get the parent attribute and get the Source for it.
MdmAttribute mdmParentAttr = mdmEmpDim.getParentAttribute();
Source parentAttr = mdmParentAttr.getSource();
4-6
Chapter 4
Creating Attributes
The output of the example is the following. It shows the employee name, the employee
ID and then the employee ID of the manager. The results are sorted by manager. The
employee King does not have a parent and is the highest member of the hierarchy so
the manager value for King is null, which appears as NA in the output.
The managers of the employees are:
1: ((SCOTT,EMPVALHIER::7788),EMPVALHIER::7566)
2: ((FORD,EMPVALHIER::7902),EMPVALHIER::7566)
3: ((ALLEN,EMPVALHIER::7499),EMPVALHIER::7698)
4: ((WARD,EMPVALHIER::7521),EMPVALHIER::7698)
5: ((MARTIN,EMPVALHIER::7654),EMPVALHIER::7698)
6: ((TURNER,EMPVALHIER::7844),EMPVALHIER::7698)
7: ((JAMES,EMPVALHIER::7900),EMPVALHIER::7698)
8: ((MILLER,EMPVALHIER::7934),EMPVALHIER::7782)
9: ((ADAMS,EMPVALHIER::7876),EMPVALHIER::7788)
10: ((JONES,EMPVALHIER::7566),EMPVALHIER::7839)
11: ((BLAKE,EMPVALHIER::7698),EMPVALHIER::7839)
12: ((CLARK,EMPVALHIER::7782),EMPVALHIER::7839)
13: ((SMITH,EMPVALHIER::7369),EMPVALHIER::7902)
14: ((KING,EMPVALHIER::7839),NA)
Example 4-6 creates a long description attribute for the CHANNEL_AWJ dimension
and specifies it as the attribute that contains descriptions of the members of the
dimension. The example specifies that Oracle OLAP automatically determines a SQL
data type for the attribute.
Example 4-6 Creating an MdmBaseAttribute
private MdmBaseAttribute chanLongDescAttr = null;
private void createLongDesciptionAttribute(MdmPrimaryDimension mdmChanDim)
{
// Create the long description attribute and allow the automatic changing of
// the SQL data type.
chanLongDescAttr = mdmChanDim.findOrCreateBaseAttribute("LONG_DESCRIPTION");
chanLongDescAttr.setAllowAutoDataTypeChange(true));
4-7
Chapter 4
Creating Cubes and Measures
mdmChanDim.setValueDescriptionAttribute(chanLongDescAttr);
}
An attribute can have different values for the members of different levels of
the dimension. In that case the attribute has an attribute mapping for each
level. Example 4-3 creates an AttributeMap for the long description attribute for
each dimension level by calling the findOrCreateAttributeMap method of the
MemberListMap for each dimension level. It specifies a different column for each
attribute map.
AWCubeOrganization awCubeOrg =
mdmPriceCube.findOrCreateAWCubeOrganization(aw);
4-8
Chapter 4
Creating Cubes and Measures
awCubeOrg.setMVOption(AWCubeOrganization.NONE_MV_OPTION);
awCubeOrg.setMeasureStorage(AWCubeOrganization.SHARED_MEASURE_STORAGE);
awCubeOrg.setCubeStorageType("NUMBER");
4-9
Chapter 4
Committing Transactions
4-10
Chapter 4
Exporting and Importing XML Templates
}
}
4-11
Chapter 4
Building an Analytic Workspace
4-12
5
Understanding Source Objects
This chapter describes Source objects, which you use to specify a query. With a
Source, you specify the data that you want to retrieve from the data store and the
analytical or other operations that you want to perform on the data. Making Queries
Using Source Methods, provides examples of using Source objects. Creating Dynamic
Queries, describes using Template objects to make modifiable queries.
With the methods of a Source, you can specify selections of dimension members,
attribute values, or measure values. You can also specify operations on the elements
of the Source, such as mathematical calculations, comparisons, and ordering, adding,
or removing elements of a query.
The Source class has a few basic methods and many shortcut methods that use one
or more of the basic methods. The most complex basic methods are the join(Source
joined, Source comparison, int comparisonRule, boolean visible) method and
the recursiveJoin(Source joined, Source compariso4n, Source parent, int
comparisonRule, boolean parentsFirst, boolean parentsRestrictedToBase, int
maxIterations, boolean visible) method. The many other signatures of the join
and recursiveJoin methods are shortcuts for certain operations of the basic methods.
In this chapter, the information about the join method applies equally to the
recursiveJoin method, except where otherwise noted. With the join method you
can relate the elements of one Source to those of another Source by joining a Source
with an input to a Source that matches with that input. For example, to specify the
dimension members that are required to retrieve the data of a measure that has the
dimension as an input, you use a join method to relate the dimension members to the
5-1
Chapter 5
Kinds of Source Objects
measure. The join method and the inputs of a Source are described in "Inputs and
Outputs of a Source".
A Source has certain characteristics, such as a type and a data type, and it can
have one or more inputs or outputs. This chapter describes these concepts. It also
describes the different kinds of Source objects and how you get them, and the join
method and other Source methods and how you use those methods to specify a query.
5-2
Chapter 5
Characteristics of Source Objects
the derived Source, use that same Cursor to retrieve the results of the modified
query.
The Source class has the following subclasses:
• BooleanSource
• DateSource
• NumberSource
• StringSource
These subclasses have different data types and implement Source methods that
require those data types. Each subclass also implements methods unique to it, such
as the implies method of a BooleanSource or the indexOf method of a StringSource.
5-3
Chapter 5
Characteristics of Source Objects
The data type for a primary Source is related to the SQL data type of the associated
metadata object. For example, an MdmBaseAttribute that has a SQL data type
of VARCHAR2(30) would produce a Source whose data type is the fundamental
Source that represents OLAP Java API String values. The following code gets that
fundamental Source.
fmp.getStringDataType().getSource(); // fmp is the FundamentalMetadataProvider.
A typical use of a Source for a data type is as the comparison Source for a join or a
recursive join operation. As such it represents the set of all values of that data type.
For examples of the use of the getDataType method, see Example 6-3, Example 6-5,
and Example 6-11.
The type of a fundamental Source is the data type of the Source. The type of a list or
range Source is the data type of the values of the elements of the list or range Source.
• The fundamental Source that represents the data type of the values of the
elements of the primary Source. For example, the type of the Source returned by
the getSource method of a typical numeric MdmMeasure is the fundamental Source
that represents the set of all OLAP Java API number values.
• The Source for the object that contains the primary Source. For example, the type
of the Source returned by the getSource method of an MdmLevelHierarchy is the
Source for the MdmPrimaryDimension that contains the hierarchy.
The type of a derived Source is one of the following:
• The base Source, which is the Source whose method returned the derived Source.
A Source returned by the alias, distinct, extract, join, recursiveJoin, or
value methods, or one of their shortcuts, has the base Source as the type.
• A fundamental Source. The type of the Source returned by methods such as
position and count is the fundamental Source for the OLAP Java API Integer
data type. The type of the Source returned by methods that make comparisons,
such as eq, le, and so on, is the fundamental Source for the Boolean data type.
The type of the Source returned by methods that perform aggregate functions,
such as the NumberSource methods total and average, is a fundamental Source
that represents the function.
A derived Source that has the base Source as the type is a subtype of the Source
from which it is derived. A derived Source that has a fundamental Source as the type
is a subtype of the fundamental Source. You can use the isSubtypeOf method to
determine if a Source is a subtype of another Source.
For example, in Example 5-1 the myList object is a list Source. The example uses
myList to select values from prodHier, a Source for an MdmLevelHierarchy of the
5-4
Chapter 5
Characteristics of Source Objects
The type of myList is the fundamental String Source. The type of prodHier is the
Source for the PRODUCT_AWJ dimension. The type of prodSel is prodHier because
the elements of prodSel are derived from the elements of prodHier.
The supertype of a Source is the type of the type of a Source, and so on, up
through the types to the Source for the fundamental Value data type. For example,
the fundamental Value Source is the type of the fundamental String Source, which is
the type of prodHier, which is the type of prodSel. The fundamental Value Source and
the fundamental String Source are both supertypes of prodSel. The prodSel Source is
a subtype of prodHier, and of the fundamental String Source, and of the fundamental
Value Source.
5-5
Chapter 5
Inputs and Outputs of a Source
The inputs and outputs of a base Source influence the elements of a Source that
you derive from that base Source. To derive a Source, you use methods of the base
Source. The derived Source can have outputs or inputs or both or neither, depending
on the method and the parameters of the method.
Some Source methods, such as the value and position methods, return a Source
that has an input. The join and recursiveJoin methods can return a Source that
has an output. If the join operation involves a Source with an input and a Source that
matches with that input, then the input acts as a filter in producing the elements of the
derived Source.
The following topics describe the join method, the concepts of outputs and inputs,
and the matching of inputs. They provide examples of producing Source objects that
have outputs, Source objects that have inputs, and join operations that match an input
with a Source.
The Source on which you call the join method is the base of the join operation. The
parameters of the method are the following.
5-6
Chapter 5
Inputs and Outputs of a Source
related to the values of the base Source, that is, if neither the joined Source nor the
base Source matches with an input of the other, then the join produces a Cartesian
product of the elements of the base and the joined Source objects. The examples in
the "Outputs of a Source" topic demonstrate this kind of join operation.
If the values of the joined Source are related to the values of the base Source, that is, if
either the joined Source or the base Source is an input of the other, then the elements
of the derived Source are the result of the matching of the input. The examples in
"Matching a Source with an Input" demonstrate this kind of join operation.
5-7
Chapter 5
Inputs and Outputs of a Source
If the value of the visible parameter of the join method is true, then the joined
Source becomes an output of the derived Source. The elements of the derived Source
then have the values of the output and the base values, as specified by the other
parameters of the join operation.
A derived Source can have from zero to many outputs. A Source that is an output
can itself have outputs. You can get the outputs of a Source by calling the getOutputs
method, which returns a List of Source objects.
The examples in the following topics all have simple join operations that produce
Source objects that have one or more outputs. Because none of the Source objects
in the join operations have inputs, the values of the derived Source objects produced
by the join operations are the Cartesian products of the base and the joined Source
objects.
• Producing a Source with an Output
• Using COMPARISON_RULE_SELECT
• Using COMPARISON_RULE_REMOVE
• Producing a Source with Two Outputs
• Hiding an Output
Very different results occur from a join operation that involves a Source that has an
input and a Source that matches with that input. For examples of Source objects with
inputs and the matching of inputs, see the following topics.
• Inputs of a Source
• Matching a Source with an Input
// Oracle OLAP translates this shortcut signature of the join method into the
// following full signature, where dp is the DataProvider for the session.
// Source letters.join(names,
// dp.getEmptySource(),
// Source.COMPARISON_RULE_REMOVE,
// true);
5-8
Chapter 5
Inputs and Outputs of a Source
The letters.join(names) operation joins the elements of the base Source, letters,
and the joined Source, names. Because the comparison Source has no elements,
the join operation does not remove any of the elements that are in the joined
Source in producing the derived Source. (The comparison Source is the empty
Source that is returned by the dp.getEmptySource() parameter of the full join
signature shown in the example.) The resulting derived Source, lettersWithNames,
is the Cartesian product of the elements of the base letters and the joined names.
Because both letters and names have three elements, the number of elements in
lettersWithNames is nine.
A Cursor for a Source has the same structure as the Source. A Cursor for the
lettersWithNames Source has a ValueCursor for the base values of the derived
Source and a ValueCursor for the output values. The following table presents the
values of the ValueCursor objects. The table includes headings that are not in the
ValueCursor objects.
Output Values Base Values
Stephen A
Stephen B
Stephen C
Leo A
Leo B
Leo C
Molly A
Molly B
Molly C
A Cursor for the lettersAndSelectedNames Source has the values specified by the
Source. The following table presents the Cursor values and has headings added.
Output Values Base Values
Stephen A
Stephen B
Stephen C
Molly A
Molly B
Molly C
5-9
Chapter 5
Inputs and Outputs of a Source
Example 5-4 A Simple Join That Removes Elements of the Joined Source
This example demonstrates using a comparison Source that has values and the
comparison rule COMPARISON_RULE_REMOVE. That comparison rule removes from
participation in the join operation those values that are the same in the joined and
in the comparison Source objects. The output of the derived Source therefore has only
the name from the joined Source that is not in the comparison Source.
The example has the same base, joined, and comparison Source objects as
Example 5-3.
Source lettersAndNamesWithoutRemovedNames =
letters.join(names,
someNames,
Source.COMPARISON_RULE_REMOVE,
true);
Source lettersWithSelectedNames =
letters.join(names,
someNames,
Source.COMPARISON_RULE_SELECT,
true);
Source lettersWithSelectedNamesAndColors =
lettersWithSelectedNames.join(colors);
5-10
Chapter 5
Inputs and Outputs of a Source
Green Stephen B
Green Stephen C
Green Molly A
Green Molly B
Green Molly C
Maroon Stephen A
Maroon Stephen B
Maroon Stephen C
Maroon Molly A
Maroon Molly B
Maroon Molly C
5-11
Chapter 5
Inputs and Outputs of a Source
A Source with an input is an incomplete specification of data. The input represents the
type of Source that can have the elements that a join operation requires to complete
the data specification. Before you can retrieve the data with a Cursor, you must match
the input with a Source that has the elements that complete the specification.
You match an input with a Source by using the join or recursiveJoin method. The
match occurs between the base Source and the joined Source.
The matching of an input acts as a filter so that the Source derived by the join
operation has only the elements of the base Source whose values are related to those
of the elements of the joined Source. The rules related to matching a Source with an
input are described in "Matching a Source with an Input". That topic has examples that
produce derived Source objects that are the result of the matching of an input.
A Source can have from zero to many inputs. You can get all of the inputs of a Source
by calling the getInputs method.
Some primary Source objects have inputs. You can derive a Source that has an input
by using some methods of the Source class.
The inputs of an MdmAttribute or an MdmMeasure are the Source objects for the
MdmPrimaryDimension objects that dimension the attribute or measure. To get the
value of an attribute or a measure, you must join the attribute or measure with a
Source that contains the related dimension members. The join operation matches
the input of the attribute or measure with the Source that contains the dimension
members. Example 5-7 matches the input of an attribute with the dimension of that
attribute. Example 5-8 matches the inputs of a measure with the dimensions of that
measure.
5-12
Chapter 5
Inputs and Outputs of a Source
The value method returns a Source that has the elements of the base Source and
has the base Source as an input. You typically use the Source returned by the
value method as the base or joined Source of a join method, or sometimes as the
comparison Source. Several examples in this chapter and in Making Queries Using
Source Methods use the value method.
The position method returns a Source that has the position of each element of the
base Source and that has the base Source as an input. For an example of using the
position method, see Example 6-4.
You use the extract method when elements of the Source objects that you want to
join have Source objects as values. For examples of using the extract method, see
Example 5-12, Example 6-8, Example 6-13, and Example 6-14.
The input of a Source returned by the extract method is an extraction input. You can
get the extraction inputs by calling the getExtractionInputs method.
When a Source with an input is joined to a Source that matches with the input, the
derived Source returned by the join method has the elements of the base that are
related to the elements specified by the parameters of the method. The derived Source
does not have the input.
Matching a Source with an input does not affect the outputs of the base Source or the
joined Source. If a base Source has an output that matches with the input of the joined
Source, then the resulting Source does not have the input but it does have the output.
If the base Source or the joined Source in a join operation has an input that is not
matched in the operation, then the unmatched input is an input of the resulting Source.
The comparison Source of a join method does not participate in the input matching.
If the comparison Source has an input, then that input is not matched and the Source
returned by the join method has that same input.
The examples in the following topics demonstrate matching a Source with an input.
5-13
Chapter 5
Inputs and Outputs of a Source
In the example, locValAttr is the base Source of the join operation and chanDim
is the joined Source. Because chanDim is an instance of the Source for the
MdmPrimaryDimension for the CHANNEL_AWJ dimension, chanDim matches with the
input of locValAttr. The result of the join is dimMembersWithLocalValue, which has
chanDim as an output and does not have any inputs.
The locValAttr Source has four elements because each of the four members of the
CHANNEL_AWJ dimension has a different local value. The Source derived by the join
operation, dimMembersWithLocalValue, has four elements. The value of each element
is the dimension member and the related attribute value. The dimension member is a
value from the output and the attribute value is from the base.
Example 5-7 demonstrates matching the input of a base Source with the joined
Source. In the example, mdmDBSchema is the MdmDatabaseSchema for the GLOBAL
schema.
A Cursor for the dimMembersWithLocalValue Source has the values shown in the
following table. The output values are the unique dimension member values derived
from the joined Source, chanDim. The base values are derived from the base Source,
locValAttr. The table has headings added.
Output Values Base Values
CHANNEL_PRIMARY::TOTAL_CHANNEL::TOTAL TOTAL
CHANNEL_PRIMARY::CHANNEL::CAT CAT
CHANNEL_PRIMARY::CHANNEL::DIR DIR
CHANNEL_PRIMARY::CHANNEL::INT INT
5-14
Chapter 5
Inputs and Outputs of a Source
the MdmPrimaryDimension objects for those dimensions and gets the Source objects
for those metadata objects.
The Source for the measure, unitPrice, has the Source objects for the two
MdmPrimaryDimension objects as inputs. The example joins the Source for the
measure with the Source objects for the dimensions. The join operations match the
inputs of the measure with the Source objects for the dimensions.
The example first joins the Source for the PRODUCT_AWJ dimension to the Source
for the measure. That unitPrice.join(prodDim) operation derives a Source that
has base values from unitPrice and has prodDim as an output. It also has the
Source for the TIME_AWJ dimension as an input. The next join operation joins
the Source derived by unitPrice.join(prodDim) with timeDim, the Source for the
TIME_AWJ dimension. That join operation matches the input of the Source derived by
unitPrice.join(prodDim) with timeDim.
5-15
Chapter 5
Inputs and Outputs of a Source
A Cursor for the lettersByLettersValue Source has the values shown in the
following table. The table has headings added.
Output Values Base Values
A A
B B
C C
5-16
Chapter 5
Inputs and Outputs of a Source
The two Source objects contain the same values. However, the types of the
objects are different. The type of the productsToSelect Source is the Source
for the FundamentalMetadataObject for the String data type. The type of the
selectedProducts Source is prodDim because selectedProducts is derived from
prodDim. Therefore, selectedProducts is a subtype of prodDim and as such it can
match with a Source that has the Source for the PRODUCT_AWJ dimension as an
input, as shown in the next example.
Example 5-11 Using Derived Source Objects to Select Measure Values
This example selects elements from the Source objects for two dimensions and
then gets the measure values for the selected dimension members. The example
uses the same dimensions and measure as in Example 5-8. In this example,
however, the Source objects that match with the inputs of the Source for the
measure are not the Source objects for the dimensions. Instead they are subtypes
of the Source objects for the dimensions. The subtypes specify selected members
of the dimensions. The Source that is derived by joining the measure with the
dimensions, pricesForSelectedProductsAndTimes, has six elements, which specify
only the measure values for the two products for the three time values, instead of
the 4998 elements of the pricesByProductAndTime Source in Example 5-8. In this
example, mdmDBSchema is the MdmDatabaseSchema for the GLOBAL schema.
// Create lists of product and time dimension members.
Source productsToSelect = dp.createListSource(new String[]
{"PRODUCT_PRIMARY::ITEM::ENVY EXE",
"PRODUCT_PRIMARY::ITEM::ENVY STD"});
Source timesToSelect = dp.createListSource(new String[]
{"CALENDAR_YEAR::MONTH::2000.01",
"CALENDAR_YEAR::MONTH::2001.01",
"CALENDAR_YEAR::MONTH::2002.01"});
// Get the PRICE_CUBE_AWJ cube.
MdmCube mdmPriceCube = mdmDBSchema.findOrCreateCube("PRICE_CUBE_AWJ");
// Get the UNIT_PRICE measure from the cube.
MdmBaseMeasure mdmUnitPrice =
mdmPriceCube.findOrCreateBaseMeasure("UNIT_PRICE");
// Get the PRODUCT_AWJ and TIME_AWJ dimensions.
MdmStandardDimension mdmProdDim =
mdmDBSchema.findOrCreateStandardDimension("PRODUCT_AWJ");
MdmTimeDimension mdmTimeDim =
mdmDBSchema.findOrCreateTimeDimension("TIME_AWJ");
// Get the Source objects for the dimensions and the measure.
Source prodDim = mdmProdDim.getSource();
Source timeDim = mdmTimeDim.getSource();
Source unitPrice = mdmUnitPrice.getSource();
// Using the value method, derive Source objects that specify the selected
// dimension members.
Source selectedProducts = prodDim.join(prodDim.value(),
productsToSelect,
Source.COMPARISON_RULE_SELECT,
false);
Source selectedTimes = timeDim.join(timeDim.value(),
timesToSelect,
Source.COMPARISON_RULE_SELECT,
false);
5-17
Chapter 5
Inputs and Outputs of a Source
// Derive a Source that specifies the unitPrice values for the selected products
// and times.
Source pricesForSelectedProductsAndTimes = unitPrice.join(selectedProducts)
.join(selectedTimes);
This example creates a list Source, sourcesToCombine, that has the two
derived Source objects as element values. The sourcesToCombine.extract()
method produces sourcesToCombineWithAnInput, which is a Source
that has sourcesToCombine as an input. The join operation
sourcesToCombineWithAnInput.joinHidden(sourcesToCombine) matches the input
of sourcesToCombineWithAnInput with the joined sourcesToCombine and produces
combinedSources, which has no inputs or outputs. A shortcut for this combining of
Source elements is the appendValues method.
MdmStandardDimension mdmProdDim =
mdmDBSchema.findOrCreateStandardDimension("PRODUCT_AWJ");
StringSource prodDim = (StringSource) mdmProdDim.getSource();
Source productsToSelect = prodDim.selectValues(new String[]
{"PRODUCT_PRIMARY::ITEM::ENVY ABM",
"PRODUCT_PRIMARY::ITEM::ENVY EXE",
"PRODUCT_PRIMARY::ITEM::ENVY STD"});
Source moreProductsToSelect = prodDim.selectValues(new String[]
{"PRODUCT_PRIMARY::ITEM::SENT FIN",
"PRODUCT_PRIMARY::ITEM::SENT MM",
"PRODUCT_PRIMARY::ITEM::SENT STD"});
Source sourcesToCombine =
dp.createListSource(new Source[] {productsToSelect, moreProductsToSelect});
Source sourcesToCombineWithAnInput = sourcesToCombine.extract();
Source combinedProducts =
sourcesToCombineWithAnInput.joinHidden(sourcesToCombine);
5-18
Chapter 5
Describing Parameterized Source Objects
PRODUCT_PRIMARY::ITEM::ENVY ABM
PRODUCT_PRIMARY::ITEM::ENVY EXE
PRODUCT_PRIMARY::ITEM::ENVY STD
PRODUCT_PRIMARY::ITEM::SENT FIN
PRODUCT_PRIMARY::ITEM::SENT MM
PRODUCT_PRIMARY::ITEM::SENT STD
The example in this topic is a very simple demonstration of using a Parameter object.
A typical use of a Parameter is to specify the page edges of a cube, as shown in
Example 6-9. Another use of a Parameter is to fetch from the server only the set
of elements that you currently need. Example 6-15 demonstrates using Parameter
objects to fetch different sets of elements.
When you create a Parameter object, you supply an initial value for the Parameter.
You then create the parameterized Source using the Parameter. You include the
parameterized Source in specifying a query. You create a Cursor for the query. You
can change the value of the Parameter with the setValue method, which changes the
set of elements that the query specifies. Using the same Cursor, you can then retrieve
the new set of values.
This example demonstrates the use of a Parameter and a parameterized Source to
specify a member in a dimension. The example gets the MdmStandardDimension for
the PRODUCT_AWJ dimension and gets the Source for the MdmStandardDimension
cast as a StringSource.
The example gets the Source for the local value attribute of the dimension. It
joins that Source, locValAttr, with paramProdSel. That join operation produces the
dimMemberWithLocalValue Source.
The example creates a Cursor for dimMemberWithLocalValue and displays the value
of the Cursor. After resetting the Cursor position and changing the value of the
prodParam StringParameter, the example displays the value of the Cursor again.
The dp object is the DataProvider. The getContext method gets a Context11g object
that has a method that commits the current Transaction and a method that displays
the values of a Cursor.
StringParameter prodParam =
new StringParameter(dp, "PRODUCT_PRIMARY::FAMILY::LTPC");
5-19
Chapter 5
Describing Parameterized Source Objects
After changing the value of the StringParameter and resetting the position of the
Cursor, the Cursor for dimMemberWithLocalValue displays the following.
PRODUCT_PRIMARY::FAMILY::DTPC,DTPC
5-20
6
Making Queries Using Source Methods
You create a query by producing a Source that specifies the data that you want to
retrieve and any operations that you want to perform on that data. To produce the
query, you begin with the primary Source objects that represent the metadata of the
measures and the dimensions and their attributes that you want to query. Typically,
you use the methods of the primary Source objects to derive a number of other Source
objects, each of which specifies a part of the query, such as a selection of dimension
members or an operation to perform on the data. You then join the Source objects
that specify the data and the operations that you want. The result is one Source that
represents the query. You can then retrieve the data by creating a Cursor for the
Source.
This chapter briefly describes the various kinds of Source methods, and discusses
some of them in greater detail. It also discusses how to make some typical OLAP
queries using these methods and provides examples of some of them.
This chapter includes the following topics:
• Describing the Basic Source Methods
• Using the Basic Methods
• Using Other Source Methods
Many other methods of the Source class use one or more of the basic methods
to perform operations such as selecting elements of the base Source by value
or by position, or sorting elements. Many of the examples in this chapter and in
Understanding Source Objects, use some of these methods. Other Source methods
get objects that have information about the Source, such as the getID, getInputs, and
getType methods, perform comparisons, such as the ge and gt methods, or convert
the values of the Source from one data type to another, such as the toDoubleSource
method.
Method Description
alias Returns a Source that has the same elements as the base
Source, but has the base Source as the type.
distinct Returns a Source that has the same elements as the base
Source, except that any elements that are duplicated in the base
appear only once in the derived Source.
6-1
Chapter 6
Using the Basic Methods
Method Description
join Returns a Source that has the elements of the base
Source that are specified by the joined, comparison, and
comparisonRule parameters of the method call. If the visible
parameter is true, then the joined Source is an output of the
resulting Source.
position Returns a Source that has the positions of the elements of the
base Source, and that has the base Source as an input.
recursiveJoin Similar to the join method, except that this method, in the
Source that it returns, orders the elements of the Source
hierarchically by parent-child relationships.
value Returns a Source that has the same elements as the base
Source, but that has the base Source as an input.
The following topics describe the basic Source methods and provide some examples
of their use.
• Using the Basic Methods
• Using Other Source Methods
Example 6-1 performs such an operation. It produces a Source that specifies whether
the number of units sold for each value of the CHANNEL_AWJ dimension is greater
than the number of units sold for the other values of the CHANNEL_AWJ dimension.
6-2
Chapter 6
Using the Basic Methods
The example joins units, which is the Source for a measure, to Source objects that
are selections of single values of three of the dimensions of the measure to produce
unitsSel. The unitsSel Source specifies the units elements for the dimension values
that are specified by the timeSel, custSel, and prodSel objects, which are outputs of
unitsSel. The unitsSel Source has the Source for CHANNEL_AWJ dimension as an
input.
The timeSel, custSel, and prodSel Source objects specify single values from
hierarchies of the TIME_AWJ, CUSTOMER_AWJ, and PRODUCT_AWJ dimensions,
respectively. The timeSel value is CALENDAR_YEAR::MONTH::2001.01, which identifies
the month January, 2001, the custSel value is SHIPMENTS::SHIP_TO::BUSN WRLD SJ,
which identifies the Business World San Jose customer, and the prodSel value is
PRODUCT_PRIMARY::ITEM::ENVY ABM, which identifies the Envoy Ambassador portable
PC.
The example next creates two aliases, chanAlias1 and chanAlias2, for chanHier,
which is the Source for the CHANNEL_PRIMARY hierarchy of the CHANNEL_AWJ
dimension. It then produces unitsSel1 by joining unitsSel with the Source returned
by chanAlias1.value(). The unitsSel1 Source has the elements and outputs of
unitsSel and it has chanAlias1 as an input. Similarly, the example produces
unitsSel2, which has chanAlias2 as an input.
The example uses the gt method of unitsSel1, which determines whether the values
of unitsSel1 are greater than the values of unitsSel2. The final join operations
match chanAlias1 with the input of unitsSel1 and match chanAlias2 with the input of
unitsSel2.
The result Source specifies the query, "Are the units sold values of unitsSel1 for
the channel values of chanAlias1 greater than the units sold values of unitsSel2 for
the channel values of chanAlias2?" Because result is produced by the joining of
chanAlias2 to the Source returned by unitsSel1.gt(unitsSel2).join(chanAlias1),
chanAlias2 is the first output of result, and chanAlias1 is the second output of
result.
A Cursor for the result Source has as values the boolean values that answer the
query. The values of the first output of the Cursor are the channel values specified by
chanAlias2 and the values of the second output are the channel values specified by
chanAlias1.
The following is a display of the values of the Cursor formatted as a crosstab with
headings added. The column edge values are the values from chanAlias1, and the
row edge values are the values from chanAlias2. The values of the crosstab cells are
the boolean values that indicate whether the units sold value for the column channel
value is greater than the units sold value for the row channel value. For example, the
6-3
Chapter 6
Using the Basic Methods
crosstab values in the first column indicate that the units sold value for the column
channel value Total Channel is not greater than the units sold value for the row Total
Channel value but it is greater than the units sold value for the Direct Sales, Catalog,
and Internet row values.
----------------- chanAlias1 ----------------
chanAlias2 TotalChannel Catalog Direct Sales Internet
------------ ------------ ------- ------------ --------
TotalChannel false false false false
Catalog true false false false
Direct Sales true true false false
Internet true true true false
Source customersToSelect =
mktHier.selectValues(new String[] {"MARKETS::SHIP_TO::KOSH ENT BOS",
"MARKETS::SHIP_TO::KOSH ENT TOK",
"MARKETS::SHIP_TO::KOSH ENT WAN"});
Source moreCustomersToSelect =
mktHier.selectValues(new String[] {"MARKETS::SHIP_TO::KOSH ENT BOS",
"MARKETS::SHIP_TO::KOSH ENT TOK",
"MARKETS::SHIP_TO::BUSN WRLD NY",
"MARKETS::SHIP_TO::BUSN WRLD SJ"});
Source combinedCustomers =
customersToSelect.appendValues(moreCustomersToSelect);
6-4
Chapter 6
Using the Basic Methods
Most of the examples in this chapter use one or more signatures of the join
method, as do many of the examples in Understanding Source Objects. Example 6-3
uses the full join signature and the simplest join signature. In the example, the
full join signature demonstrates the use of COMPARISON_RULE_DESCENDING as the
comparisonRule parameter.
6-5
Chapter 6
Using the Basic Methods
The next three join operations join the single member selections of the other three
dimensions of the measure. The result Source specifies the product family level
members in descending order of sales amounts for the month of May, 2001 for all
customers and all channels.
Example 6-3 Using COMPARISON_RULE_DESCENDING
Source result = prodSelWithShortDescr.join(salesMeasure,
salesMeasure.getDataType(),
Source.COMPARISON_RULE_DESCENDING,
true)
.join(timeSelWithShortDescr)
.join(custSelWithShortDescr)
.join(chanSelWithShortDescr);
A Cursor for the result Source has the following values, displayed as a table. The
table includes only the short value descriptions of the hierarchy members and the
sales amount values, and has headings and formatting added.
Total Channel
Total Customer
MAY-01
Next, the example creates an array of Source objects and gets a List of the
MdmHierarchyLevel components of the hierarchy. It gets the Source object for each
level and adds it to the array, and then creates a list Source that has the Source
objects for the levels as element values.
The example then produces levelMembers, which is a Source that specifies the
members of the levels of the hierarchy. Because the comparison parameter of the
join operation is the Source produced by levelList.value(), levelMembers has
levelList as an input. Therefore, levelMembers is a Source that returns the members
of each level, by level, when the input is matched in a join operation.
The range Source specifies a range of elements from the second element to the next
to last element of a Source.
6-6
Chapter 6
Using the Basic Methods
The next join operation produces the firstAndLast Source. The base of the
operation is levelMembers. The joined parameter is the Source that results from the
levelMembers.position() method. The comparison parameter is the range Source
and the comparison rule is COMPARISON_RULE_REMOVE. The value of the visible
parameter is true. The firstAndLast Source therefore specifies only the first and
last members of the levels because it removes all of the other members of the levels
from the selection. The firstAndLast Source still has levelList as an input.
The final join operation matches the input of firstAndLast with levelList.
A Cursor for the result Source has the following values, displayed as a table with
column headings and formatting added. The left column names the level, the middle
column is the position of the member in the level, and the right column is the local
value of the member. The TOTAL_TIME level has only one member.
Level Member Position in Level Member Value
---------- ------------------------ ------------
TOTAL_TIME 1 TOTAL
YEAR 1 CY1998
YEAR 10 CY2007
QUARTER 1 CY1998.Q1
QUARTER 40 CY2007.Q4
MONTH 1 1998.01
MONTH 120 2007.12
6-7
Chapter 6
Using the Basic Methods
Like the join method, you use the recursiveJoin method to produce a Source that
has the elements of the base Source that are determined by the joined, comparison,
and comparisonRule parameters of the method. The visible parameter determines
whether the joined Source is an output of the Source produced by the recursive join
operation.
The full recursiveJoin method has other parameters that specify the parent attribute
of the hierarchy, whether the result should have the parents before or after their
children, and how to order the elements of the result if the result includes children but
not the parent. The recursiveJoin method has several signatures that are shortcuts
for the full signature.
Example 6-5 uses a recursiveJoin method that lists the parents first, restricts the
parents to the base, and does not add the joined Source as an output. The example
first sorts the members of the PRODUCT_PRIMARY hierarchy of the PRODUCT_AWJ
dimension by hierarchical levels and then by the value of the package attribute of each
member.
In the first recursiveJoin method, the COMPARISON_RULE_ASCENDING parameter
specifies that the members of the prodHier hierarchy be in ascending alphabetical
order within each level. The prodParentAttr object is the Source for the parent
attribute of the hierarchy.
The prodPkgAttr object in the second recursiveJoin method is the Source for
the package attribute of the dimension. Only the members of the ITEM level have
a related package attribute value. Because the members in the aggregate levels
TOTAL_PRODUCT, CLASS, and FAMILY, do not have a related package, the package
attribute value for members in those levels is null, which appears as NA in the results.
Some of the ITEM level members do not have a related package value, so their values
are NA, also.
The second recursiveJoin method joins the package attribute values to their related
hierarchy members and sorts the members hierarchically by level, and then sorts
them in ascending alphabetical order in the level by the package attribute value.
The COMPARISON_RULE_ASCENDING_NULLS_FIRST parameter specifies that members
that have a null value appear before the other members in the same level. The
example then joins the result of the method, sortedHierAscending, to the package
attribute to produce a Source that has the package attribute values as element values
and sortedHierAscending as an output.
The third recursiveJoin method is the same as the second, except that the
COMPARISON_RULE_DESCENDING_NULLS_FIRST parameter sorts the hierarchy members
in descending alphabetical order in the level by package attribute value.
Example 6-5 Sorting Products Hierarchically by Attribute
Source result1 = prodHier.recursiveJoin(prodDim.value(),
prodHier.getDataType(),
prodParentAttr,
Source.COMPARISON_RULE_ASCENDING);
Source sortedHierAscending =
prodHier.recursiveJoin(prodPkgAttr,
prodPkgAttr.getDataType(),
prodParentAttr,
Source.COMPARISON_RULE_ASCENDING_NULLS_FIRST);
Source result2 = prodPkgAttr.join(sortedHierAscending);
6-8
Chapter 6
Using the Basic Methods
Source sortedHierDescending =
prodHier.recursiveJoin(prodPkgAttr,
prodPkgAttr.getDataType(),
prodParentAttr,
Source.COMPARISON_RULE_DESCENDING_NULLS_FIRST);
Source result3 = prodPkgAttr.join(sortedHierDescending);
A Cursor for the result1 Source has the following values, displayed with a heading
added. The list contains only the first seventeen values of the Cursor.
Product Primary Hierarchy Value
-------------------------------------
PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL
PRODUCT_PRIMARY::CLASS::HRD
PRODUCT_PRIMARY::FAMILY::DISK
PRODUCT_PRIMARY::ITEM::EXT CD ROM
PRODUCT_PRIMARY::ITEM::EXT DVD
PRODUCT_PRIMARY::ITEM::INT 8X DVD
PRODUCT_PRIMARY::ITEM::INT CD ROM
PRODUCT_PRIMARY::ITEM::INT CD USB
PRODUCT_PRIMARY::ITEM::INT RW DVD
PRODUCT_PRIMARY::FAMILY::DTPC
PRODUCT_PRIMARY::ITEM::SENT FIN
PRODUCT_PRIMARY::ITEM::SENT MM
PRODUCT_PRIMARY::ITEM::SENT STD
PRODUCT_PRIMARY::FAMILY::LTPC
PRODUCT_PRIMARY::ITEM::ENVY ABM
PRODUCT_PRIMARY::ITEM::ENVY EXE
PRODUCT_PRIMARY::ITEM::ENVY STD
...
A Cursor for the result2 Source has the following values, displayed as a table with
headings added. The table contains only the first seventeen values of the Cursor.
The left column has the member values of the hierarchy and the right column has the
package attribute value for the member.
The ITEM level members that have a null value appear first, and then the other level
members appear in ascending order of package value. Since the data type of the
package attribute is String, the package values are in ascending alphabetical order.
Product Primary Hierarchy Value Package Attribute Value
------------------------------------- -----------------------
PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL NA
PRODUCT_PRIMARY::CLASS::HRD NA
PRODUCT_PRIMARY::FAMILY::DISK NA
PRODUCT_PRIMARY::ITEM::EXT CD ROM NA
PRODUCT_PRIMARY::ITEM::INT 8X DVD NA
PRODUCT_PRIMARY::ITEM::INT CD USB NA
PRODUCT_PRIMARY::ITEM::EXT DVD Executive
PRODUCT_PRIMARY::ITEM::INT CD ROM Laptop Value Pack
PRODUCT_PRIMARY::ITEM::INT RW DVD Multimedia
PRODUCT_PRIMARY::FAMILY::DTPC NA
PRODUCT_PRIMARY::ITEM::SENT FIN NA
PRODUCT_PRIMARY::ITEM::SENT STD NA
PRODUCT_PRIMARY::ITEM::SENT MM Multimedia
PRODUCT_PRIMARY::FAMILY::LTPC NA
RODUCT_PRIMARY::ITEM::ENVY ABM NA
PRODUCT_PRIMARY::ITEM::ENVY EXE Executive
PRODUCT_PRIMARY::ITEM::ENVY STD Laptop Value Pack
...
6-9
Chapter 6
Using the Basic Methods
A Cursor for the result3 Source has the following values, displayed as a table with
headings added. This time the members are in descending order, alphabetically by
package attribute value.
Product Primary Hierarchy Value Package Attribute Value
------------------------------------- -----------------------
PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL NA
PRODUCT_PRIMARY::CLASS::HRD NA
PRODUCT_PRIMARY::FAMILY::DISK NA
PRODUCT_PRIMARY::ITEM::EXT CD ROM NA
PRODUCT_PRIMARY::ITEM::INT 8X DVD NA
PRODUCT_PRIMARY::ITEM::INT CD USB NA
PRODUCT_PRIMARY::ITEM::INT RW DVD Multimedia
PRODUCT_PRIMARY::ITEM::INT CD ROM Laptop Value Pack
PRODUCT_PRIMARY::ITEM::EXT DVD Executive
PRODUCT_PRIMARY::FAMILY::DTPC NA
PRODUCT_PRIMARY::ITEM::SENT FIN NA
PRODUCT_PRIMARY::ITEM::SENT STD NA
PRODUCT_PRIMARY::ITEM::SENT MM Multimedia
PRODUCT_PRIMARY::FAMILY::LTPC NA
PRODUCT_PRIMARY::ITEM::ENVY ABM NA
PRODUCT_PRIMARY::ITEM::ENVY STD Laptop Value Pack
PRODUCT_PRIMARY::ITEM::ENVY EXE Executive
...
The first join method has custSel as the base and as the joined Source. It has
custSel2 as the comparison Source. The elements of the resulting Source, result1,
are the Cartesian product of the base and joined Source objects that are specified by
the comparison Source. The result1 Source has one set of the elements of custSel
for each element of custSel that is in the comparison Source. The true value of the
visible parameter causes the joined Source to be an output of result1.
The second join method also has custSel as the base and custSel2 as the
comparison Source, but it has the Source returned by the custSel.value() method as
the joined Source. Because custSel is an input of the joined Source, the base Source
matches with that input. That input relationship causes the resulting Source, result2,
to have only those elements of custSel that are also in the comparison Source.
6-10
Chapter 6
Using the Basic Methods
A Cursor for result1 has the values shown in the following table. The table has
formatting and headings that are not in the Cursor. The left column has the values of
the elements of the output of the Cursor. The right column has the base values of the
Cursor.
Output Value result1 Value
--------------------------------- ---------------------------------
SHIPMENTS::SHIP_TO::COMP WHSE SJ SHIPMENTS::SHIP_TO::COMP WHSE ATL
SHIPMENTS::SHIP_TO::COMP WHSE SJ SHIPMENTS::SHIP_TO::COMP WHSE SJ
SHIPMENTS::SHIP_TO::COMP WHSE SJ SHIPMENTS::SHIP_TO::COMP WHSE SIN
SHIPMENTS::SHIP_TO::COMP WHSE SJ SHIPMENTS::SHIP_TO::COMP WHSE LON
SHIPMENTS::SHIP_TO::COMP WHSE SIN SHIPMENTS::SHIP_TO::COMP WHSE ATL
SHIPMENTS::SHIP_TO::COMP WHSE SIN SHIPMENTS::SHIP_TO::COMP WHSE SJ
SHIPMENTS::SHIP_TO::COMP WHSE SIN SHIPMENTS::SHIP_TO::COMP WHSE SIN
SHIPMENTS::SHIP_TO::COMP WHSE SIN SHIPMENTS::SHIP_TO::COMP WHSE LON
A Cursor for result2 has the following values, displayed as a table with headings
added. The left column has the values of the elements of the output of the Cursor. The
right column has the base values of the Cursor.
Output Value result2 Value
--------------------------------- ---------------------------------
SHIPMENTS::SHIP_TO::COMP WHSE SJ SHIPMENTS::SHIP_TO::COMP WHSE SJ
SHIPMENTS::SHIP_TO::COMP WHSE SIN SHIPMENTS::SHIP_TO::COMP WHSE SIN
6-11
Chapter 6
Using the Basic Methods
The example next gets the ancestors attribute of the dimension and the Source for
it. The ancestors attribute relates each dimension member to the ancestors of that
member.
To produce a Source that represents the descendants of each member of the
dimension, the example reverses the ancestor relation by joining the Source
for the hierarchy, mktHier, with the ancestors attribute, ancestorsAttr. The join
operation uses mktHier.value() as the comparison Source, so that the Source
returned by the join operation, marketsDescendants, has mktHier as an input.
The marketsDescendants Source specifies, for each element of ancestorsAttr, the
elements of mktHier that have the ancestorsAttr element as their ancestor. Because
it has mktHier as an input, the marketsDescendants Source functions in the same way
as an attribute that represents the descendants relationship for the hierarchy.
The example demonstrates this when it joins mktHier to marketsDescendants in the
following line.
Source selValDescendants = marketsDescendants.join(mktHier, selVal);
In the join operation, the joined Source, mktHier, matches with the input of
marketsDescendants. The comparison Source is selVal, which specifies a single
member of the hierarchy. The join operation returns selValDescendants, which
specifies the elements of marketsDescendants that are the descendants of the selVal
member. The result also includes the ancestor member itself. The mktHier Source is
not an output of selValDescendants because the signature of the join method used
derives a Source that does not have the joined Source as an output.
The example next uses the full signature of the join method to produce
selValDescendantsOnly, which contains only the descendants and not the ancestor
value. To remove the ancestor value, the example again uses the value method, this
time to return a Source that is the joined parameter of the join operation that returns
selValDescendantsOnly. The comparison Source is selVal, and the comparison rule
is COMPARISON_RULE_REMOVE.
6-12
Chapter 6
Using Other Source Methods
The subclasses of Source each have other specialized methods, also. For example,
the NumberSource class has many methods that perform mathematical functions such
as abs, div, and cos, and methods that perform aggregations, such as average and
total.
The following topics have examples that demonstrate the use of some of the Source
methods. Some of the examples are tasks that an OLAP application typically performs.
• Using the extract Method
• Creating a Cube and Pivoting Edges
• Drilling Up and Down in a Hierarchy
• Sorting Hierarchically by Measure Values
• Using NumberSource Methods To Compute the Share of Units Sold
6-13
Chapter 6
Using Other Source Methods
Example 6-8 uses the extract method to get the values of the NumberSource objects
that are themselves the values of the elements of the list Source measDim. Each of the
NumberSource objects represents a measure.
The example selects elements from StringSource objects for the hierarchies of the
dimensions of the UNITS_CUBE_AWJ cube. The cost, units, and sales objects are
NumberSource objects for the COST, UNITS, and SALES measures of the cube.
Next, the example creates measDim, which is a list Source that has the three
NumberSource objects as element values. It then uses the extract method to get the
values of the NumberSource objects. The resulting unnamed Source has measDim as an
extraction input. The first join operation has measDim.extract() as the base Source.
The input of the base Source matches with measDim, which is the joined parameter.
The example then matches the other inputs of the measures by joining the dimension
selections to produce the result Source.
The following crosstab displays the values of a Cursor for the result Source, with
headings and formatting added.
SHIPMENTS::TOTAL_CUSTOMER::TOTAL
CHANNEL_PRIMARY::CHANNEL::DIR
CALENDAR_YEAR::MONTH::2001.05
6-14
Chapter 6
Using Other Source Methods
The example joins the selections of the hierarchy members to the short value
description attributes for the dimensions so that the results include the attribute values.
The example then joins the Source objects derived from the hierarchies to the Source
for the measure to produce the cube query. It commits the current Transaction, and
then creates a Cursor for the query and displays the values.
After displaying the values of the Cursor, the example changes the value of the
Parameter for the parameterized Source for the customer selection, thereby retrieving
a different result set using the same Cursor in the same Transaction. The example
resets the position of the Cursor, and displays the values of the Cursor again.
The example then pivots the column and row edges so that the column values are
time members and the row values are channel members. It commits the Transaction,
creates another Cursor for the query, and displays the values. It then changes the
value of each Parameter object and displays the values of the Cursor again.
The dp object is the DataProvider. The getContext method gets a Context11g object
that has a method that displays the values of the Cursor in a crosstab format.
6-15
Chapter 6
Using Other Source Methods
Source chanSel =
chanHier.selectValues(new String[] {"CHANNEL_PRIMARY::CHANNEL::DIR",
"CHANNEL_PRIMARY::CHANNEL::CAT ",
"CHANNEL_PRIMARY::CHANNEL::INT"});
6-16
Chapter 6
Using Other Source Methods
The following crosstab has the values of cubeCursor displayed by the first
displayCursorAsCrosstab method.
Portable PCs
Europe
The following crosstab has the values of cubeCursor after the example changed the
value of the custParam Parameter object.
Portable PCs
North America
The next crosstab has the values of cubeCursor after pivoting the column and row
edges.
Portable PCs
North America
The last crosstab has the values of cubeCursor after changing the value of the
prodParam Parameter object.
Desktop PCs
North America
6-17
Chapter 6
Using Other Source Methods
• prodHierParentAttr, which is the Source for the parent attribute of the hierarchy.
• prodHierAncsAttr, which is the Source for the ancestors attribute of the hierarchy.
• prodShortLabel, which is the Source for the short value description attribute of the
PRODUCT_AWJ dimension.
Example 6-10 Drilling in a Hierarchy
int pos = 5;
// Get the element at the specified position of the level Source.
Source levelElement = levelSrc.at(pos);
// Get the short value descriptions for the members of the level.
Source levelSrcWithShortDescr = prodShortLabel.join(levelSrc);
The following list has the values of the Cursor objects created by the displayResults
methods.
Level Source element values:
PRODUCT_PRIMARY::FAMILY::ACC,Accessories
PRODUCT_PRIMARY::FAMILY::DISK,CD/DVD
PRODUCT_PRIMARY::FAMILY::DOC,Documentation
PRODUCT_PRIMARY::FAMILY::DTPC,Portable PCs
PRODUCT_PRIMARY::FAMILY::LTPC,Desktop PCs
6-18
Chapter 6
Using Other Source Methods
PRODUCT_PRIMARY::FAMILY::MEM,Memory
PRODUCT_PRIMARY::FAMILY::MOD,Modems/Fax
PRODUCT_PRIMARY::FAMILY::MON,Monitors
PRODUCT_PRIMARY::FAMILY::OS,Operating Systems
The successive joinHidden methods join the selections of the other dimensions of
units to produce the result Source, which has the measure data as element values
and sortedProductsShortDescr as an output. The example uses the joinHidden
methods so that the other dimension selections are not outputs of the result.
The example uses the following objects.
• prodHier, which is the Source for the PRODUCT_PRIMARY hierarchy.
• units, which is the Source for the UNITS measure of product units sold.
• prodParentAttr, which is the Source for the parent attribute of the
PRODUCT_PRIMARY hierarchy.
• prodShortDescr, which is the Source for the short value description attribute of the
PRODUCT_AWJ dimension.
• custSel, which is a Source that specifies a single member of the
SHIPMENTS hierarchy of the CUSTOMER_AWJ dimension. The member is
SHIPMENTS::TOTAL_CUSTOMER::TOTAL, which is the total for all customers.
• chanSel, which is a Source that specifies a single member of the
CHANNEL_PRIMARY hierarchy of the CHANNEL_AWJ dimension. The member
value is CHANNEL_PRIMARY::CHANNEL::DIR, which is the direct sales channel.
• timeSel, which is a Source that specifies a single member of the
CALENDAR_YEAR hierarchy of the TIME_AWJ dimension. The member is
CALENDAR_YEAR::YEAR::CY2001, which is the year 2001.
6-19
Chapter 6
Using Other Source Methods
A Cursor for the result Source has the following values, displayed in a table with
column headings and formatting added. The left column has the name of the level
in the PRODUCT_PRIMARY hierarchy. The next column to the right has the product
identification value, and the next column has the short value description of the product.
The rightmost column has the number of units of the product sold to all customers in
the year 2001 through the direct sales channel.
The table contains only the first nine and the last eleven values of the Cursor, plus
the Software/Other class value. The product values are listed hierarchically and in
ascending order by units sold. The Hardware class appears before the Software/Other
class because the Software/Other class has a greater number of units sold. In the
Hardware class, the Portable PCs family sold the fewest units, so it appears first.
In the Software/Other class, the Accessories family has the greatest number of units
sold, so it appears last.
Product Level ID Description Units Sold
------------- ------------ ----------------------------- ----------
TOTAL_PRODUCT TOTAL Total Product 43,785
CLASS HRD Hardware 16,543
FAMILY LTPC Portable PCs 1,192
ITEM ENVY ABM Envoy Ambassador 330
ITEM ENVY EXE Envoy Executive 385
ITEM ENVY STD Envoy Standard 477
FAMILY MON Monitors 1,193
ITEM 19 SVGA Monitor- 19" Super VGA 207
ITEM 17 SVGA Monitor- 17"Super VGA 986
...
CLASS SFT Software/Other) 27,242
...
FAMILY ACC Accessories 18,949
ITEM ENVY EXT KBD Envoy External Keyboard 146
ITEM EXT KBD External 101-key keyboard 678
ITEM MM SPKR 5 Multimedia speakers- 5" cones 717
ITEM STD MOUSE Standard Mouse 868
ITEM MM SPKR 3 Multimedia speakers- 3" cones 1,120
ITEM 144MB DISK 1.44MB External 3.5" Diskette 1,145
TEM KBRD REST Keyboard Wrist Rest 2,231
ITEM LT CASE Laptop carrying case 3,704
ITEM DLX MOUSE Deluxe Mouse 3,884
ITEM MOUSE PAD Mouse Pad 4,456
6-20
Chapter 6
Using Other Source Methods
The prodFamilies object is the Source for the FAMILY level of the
PRODUCT_PRIMARY hierarchy. The join method of productShare, with
prodFamilies as the joined Source, produces a Source that specifies the share that
each product family has of the total quantity of products sold.
The custSel, chanSel, and timeSel Source objects are selections of single
members of hierarchies of the CUSTOMER_AWJ, CHANNEL_AWJ, and TIME_AWJ
dimensions. The remaining join methods match those Source objects to the other
inputs of productShare, to produce result. The join(Source joined, String
comparison) signature of the join method produces a Source that does not have
the joined Source as an output.
The result Source specifies the share for each product family of the total quantity of
products sold to all customers through the direct sales channel in the year 2001.
Example 6-12 Getting the Share of Units Sold
Source totalProds =
prodHier.selectValue("PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL");
NumberSource totalUnits = (NumberSource) units.joinHidden(totalProds);
Source productShare = units.div(totalUnits).times(100);
Source result =
productShare.join(prodFamilies)
.join(timeHier, "CALENDAR_YEAR::YEAR::CY2001")
.join(chanHier, "CHANNEL_PRIMARY::CHANNEL::DIR")
.join(custHier, "SHIPMENTS::TOTAL_CUSTOMER::TOTAL");
Source sortedResult = result.sortAscending();
A Cursor for the sortedResult Source has the following values, displayed in a table
with column headings and formatting added. The left column has the product family
value and the right column has the share of the total number of units sold for the
product family to all customers through the direct sales channel in the year 2001.
Product Family Member Share of Total Units Sold
----------------------------- -------------------------
PRODUCT_PRIMARY::FAMILY::LTPC 2.72%
6-21
Chapter 6
Using Other Source Methods
PRODUCT_PRIMARY::FAMILY::MON 2.73%
PRODUCT_PRIMARY::FAMILY::MEM 3.57%
PRODUCT_PRIMARY::FAMILY::DTPC 5.13%
PRODUCT_PRIMARY::FAMILY::DOC 6.4%
PRODUCT_PRIMARY::FAMILY::DISK 11.71%
PRODUCT_PRIMARY::FAMILY::MOD 11.92%
PRODUCT_PRIMARY::FAMILY::OS 12.54%
PRODUCT_PRIMARY::FAMILY::ACC 43.28%
The unitPrice and unitPriceLag4 measures both have the Source objects for
the PRODUCT_AWJ and TIME_AWJ dimensions as inputs. The second join
method matches quarterLevel, which is a Source for the QUARTER level of the
CALENDAR_YEAR hierarchy of the TIME_AWJ dimension, with the TIME_AWJ
dimension input of the measure, and makes it an output of the resulting Source.
The lagResult Source specifies the aggregate unit prices for the Desktop PC product
family for each quarter and the quarter that is four quarters earlier.
Example 6-13 Using the Lag Method
NumberSource unitPriceLag4 = unitPrice.lag(mdmCalHier, 4);
Source measuresDim = dp.createListSource(new Source[] {unitPrice,
unitPriceLag4});
A Cursor for the lagResult Source has the following values, displayed in a table with
column headings and formatting added. The left column has the quarter, the middle
column has the total of the unit prices for the members of the Desktop PC family for
that quarter, and the right column has the total of the unit prices for the quarter that is
four quarters earlier. The first four values in the right column are NA because quarter 5,
Q1-98, is the first quarter in the CALENDAR_YEAR hierarchy. The table includes only
the first eight quarters.
6-22
Chapter 6
Using Other Source Methods
Unit Price
Quarter Unit Price Four Quarters Before
--------------------------------- ---------- --------------------
CALENDAR_YEAR::QUARTER::CY1998.Q1 2687.54 NA
CALENDAR_YEAR::QUARTER::CY1998.Q2 2704.48 NA
CALENDAR_YEAR::QUARTER::CY1998.Q3 2673.27 NA
CALENDAR_YEAR::QUARTER::CY1998.Q4 2587.76 NA
CALENDAR_YEAR::QUARTER::CY1999.Q1 2394.79 2687.54
CALENDAR_YEAR::QUARTER::CY1999.Q2 2337.18 2704.48
CALENDAR_YEAR::QUARTER::CY1999.Q3 2348.39 2673.27
CALENDAR_YEAR::QUARTER::CY1999.Q4 2177.89 2587.76
...
Source measuresDim =
dp.createListSource(new Source[]{unitPrice, unitPriceMovingTotal});
A Cursor for the movingTotalResult Source has the following values, displayed in a
table with column headings and formatting added. The left column has the quarter,
the middle column has the total of the unit prices for the members of the Desktop
PC family for that quarter, and the left column has the total of the unit prices for that
quarter and the next three quarters. The table includes only the first eight quarters.
Unit Price Moving Total
Quarter Unit Price Current Plus Next Three Periods
--------------------------------- ---------- -------------------------------
CALENDAR_YEAR::QUARTER::CY1998.Q1 2687.54 10653.05
CALENDAR_YEAR::QUARTER::CY1998.Q2 2704.48 10360.30
CALENDAR_YEAR::QUARTER::CY1998.Q3 2673.27 9993.00
CALENDAR_YEAR::QUARTER::CY1998.Q4 2587.76 9668.12
CALENDAR_YEAR::QUARTER::CY1999.Q1 2394.79 9258.25
CALENDAR_YEAR::QUARTER::CY1999.Q2 2337.18 8911.87
CALENDAR_YEAR::QUARTER::CY1999.Q3 2348.39 8626.48
CALENDAR_YEAR::QUARTER::CY1999.Q4 2177.89 8291.37
...
6-23
Chapter 6
Using Other Source Methods
The setValue methods of the NumberParameter objects change the values of those
objects, which changes the selection of elements of the product Source that are
specified by the query. The example then displays the values of the Cursor again.
Source paramProdSelInterval =
prodHier.interval(startParamSrc, endParamSrc);
6-24
Chapter 6
Using Other Source Methods
Source paramProdSelIntervalShortDescr =
prodShortDescr.join(paramProdSelInterval);
NumberSource result =
(NumberSource)units.join(chanHier, "CHANNEL_PRIMARY::CHANNEL::INT")
.join(calHier, "CALENDAR_YEAR::YEAR::CY2001")
.join(shipHier, "SHIPMENTS::TOTAL_CUSTOMER::TOTAL")
.join(paramProdSelIntervalShortDescr);
getContext().displayCursor(resultCursor);
The following table displays the values of resultCursor, with column headings and
formatting added. The left column has the product hierarchy members, the middle
column has the short value description, and the right column has the quantity of units
sold.
Product Description Units Sold
------------------------------------- ---------------------- ----------
PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL Total Product 55,872
PRODUCT_PRIMARY::CLASS::HRD Hardware 21,301
PRODUCT_PRIMARY::FAMILY::DISK Memory 6,634
PRODUCT_PRIMARY::ITEM::EXT CD ROM External 48X CD-ROM 136
PRODUCT_PRIMARY::ITEM::EXT DVD External - DVD-RW - 8X 1,526
PRODUCT_PRIMARY::ITEM::INT 8X DVD Internal - DVD-RW - 8X 1,543
6-25
7
Using a TransactionProvider
This chapter describes the Oracle OLAP Java API Transaction and
TransactionProvider interfaces and describes how you use implementations of those
interfaces in an application. You get a TransactionProvider from a DataProvider.
You use the commitCurrentTransaction method of the TransactionProvider to save
a metadata object in persistent storage in the database. You also use that method
after creating a derived Source and before creating a Cursor for the Source. For
examples of committing a Transaction after creating a metadata object, see Creating
Metadata and Analytic Workspaces.
This chapter includes the following topics:
• About Creating a Metadata Object or a Query in a Transaction
• Using TransactionProvider Objects
A single-user application does not need to explicitly create a root Transaction. The
ability to create multiple root Transaction objects is provided for use by multithreaded,
middle-tier applications. If your application uses multiple root Transaction objects, the
changes that the application makes in one root Transaction can be overwritten by
changes the application makes in another root Transaction. The changes that occur
in the last root Transaction that the application commits are the changes that persist.
7-1
Chapter 7
About Creating a Metadata Object or a Query in a Transaction
When you or Oracle OLAP creates the initial root Transaction, it is the current
Transaction. If you create another root Transaction, it becomes the current
Transaction.
Oracle OLAP creates other Transaction objects as you create Source objects or
child Transaction objects under a root Transaction. You must commit the root
Transaction for the Oracle Database to add to persistent storage any metadata
objects that you have created in any Transaction in the session.
When you create a derived Source by calling a method of another Source, the derived
Source is created in the context of the current Transaction. The Source is active in the
Transaction in which you create it or in a child Transaction of that Transaction.
You get or set the current Transaction, or begin a child Transaction, by calling
methods of a TransactionProvider. In a child Transaction you can alter a query,
for example by changing the selection of dimension elements or by performing a
different mathematical or analytical operation on the data, which changes the state
of a Template that you created in the parent Transaction. By displaying the data
specified by the Source produced by the Template in the parent Transaction and also
displaying the data specified by the Source produced by the Template in the child
Transaction, you can provide the end user of your application with the means of
easily altering a query and viewing the results of different operations on the same set
of data, or the same operations on different sets of data.
If you then create another derived Source or change the Template state again, then
that operation occurs in the same write Transaction. You can create any number of
derived Source objects, or make any number of Template state changes, in that same
write Transaction. You can use those Source objects, or the Source produced by the
Template, to define a complex query.
Before you can create a Cursor to fetch the result set specified by a derived Source,
you must move the Source from the child write Transaction into the parent read
Transaction. To do so, you commit the Transaction.
7-2
Chapter 7
About Creating a Metadata Object or a Query in a Transaction
created in the child Transaction moves into the parent read Transaction. The
child Transaction disappears and the parent Transaction becomes the current
Transaction. The Source is active in the current read Transaction and you can
therefore create a Cursor for it.
To get the data specified by the Source produced by the Template, you commit the
write Transaction into the parent read Transaction. You can then create a Cursor to
fetch the data. The changed state of the Template is not visible in the original parent.
The changed state does not become visible in the parent until you commit the child
read Transaction into the parent read Transaction.
7-3
Chapter 7
About Creating a Metadata Object or a Query in a Transaction
After beginning a child read Transaction, you can begin a child read Transaction of
that child, or a grandchild of the initial parent Transaction. For an example of creating
child and grandchild Transaction objects, see Example 7-3.
Before rolling back a Transaction, you must close any CursorManager objects you
created in that Transaction. After rolling back a Transaction, any Source objects that
you created or Template state changes that you made in the Transaction are no
longer valid. Any Cursor objects you created for those Source objects are also invalid.
Once you roll back a Transaction, you cannot commit that Transaction. Likewise,
once you commit a Transaction, you cannot roll it back.
7-4
Chapter 7
About Creating a Metadata Object or a Query in a Transaction
// Undo t3, which discards the state of topNBottom that was set in t4.
tp.rollbackCurrentTransaction(); // t3 disappears
1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL
2. PRODUCT_PRIMARY::CLASS::SFT
3. PRODUCT_PRIMARY::FAMILY::ACC
4. PRODUCT_PRIMARY::CLASS::HRD
5. PRODUCT_PRIMARY::FAMILY::MOD
7-5
Chapter 7
Using TransactionProvider Objects
6. PRODUCT_PRIMARY::FAMILY::OS
7. PRODUCT_PRIMARY::FAMILY::DISK
8. PRODUCT_PRIMARY::ITEM::MOUSE PAD
9. PRODUCT_PRIMARY::ITEM::OS 1 USER
10. PRODUCT_PRIMARY::ITEM::DLX MOUSE
1. PRODUCT_PRIMARY::ITEM::EXT CD ROM
2. PRODUCT_PRIMARY::ITEM::OS DOC ITA
3. PRODUCT_PRIMARY::ITEM::OS DOC SPA
4. PRODUCT_PRIMARY::ITEM::INT CD USB
5. PRODUCT_PRIMARY::ITEM::ENVY EXT KBD
6. PRODUCT_PRIMARY::ITEM::19 SVGA
7. PRODUCT_PRIMARY::ITEM::OS DOC FRE
8. PRODUCT_PRIMARY::ITEM::OS DOC GER
9. PRODUCT_PRIMARY::ITEM::ENVY ABM
10. PRODUCT_PRIMARY::ITEM::INT CD ROM
11. PRODUCT_PRIMARY::ITEM::ENVY EXE
12. PRODUCT_PRIMARY::ITEM::OS DOC KAN
13. PRODUCT_PRIMARY::ITEM::ENVY STD
14. PRODUCT_PRIMARY::ITEM::1GB USB DRV
15. PRODUCT_PRIMARY::ITEM::SENT MM
1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL
2. PRODUCT_PRIMARY::CLASS::SFT
3. PRODUCT_PRIMARY::FAMILY::ACC
4. PRODUCT_PRIMARY::CLASS::HRD
5. PRODUCT_PRIMARY::FAMILY::MOD
6. PRODUCT_PRIMARY::FAMILY::OS
7. PRODUCT_PRIMARY::FAMILY::DISK
8. PRODUCT_PRIMARY::ITEM::MOUSE PAD
9. PRODUCT_PRIMARY::ITEM::OS 1 USER
10. PRODUCT_PRIMARY::ITEM::DLX MOUSE
To make a previously saved Transaction the current Transaction, you call the
setCurrentTransaction method of the TransactionProvider, as in the following
example.
tp.setCurrentTransaction(t1);
7-6
Chapter 7
Using TransactionProvider Objects
If you are using Template objects in your application, then you might also use the other
methods of TransactionProvider to do the following:
7-7
Chapter 7
Using TransactionProvider Objects
// The commit moves the changes made in writeT3 into its parent,
// the read Transaction childT2. The writeT3 Transaction
// disappears. The current Transaction is now childT2
// again but the state of the TopBottomTemplate has changed.
getContext().displayTopBottomResult(result);
}
catch(Exception e)
{
println("Cannot display the results of the query. " + e);
}
// Commit writeT5.
commit();
7-8
Chapter 7
Using TransactionProvider Objects
1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL
2. PRODUCT_PRIMARY::CLASS::SFT
3. PRODUCT_PRIMARY::FAMILY::ACC
4. PRODUCT_PRIMARY::CLASS::HRD
5. PRODUCT_PRIMARY::FAMILY::MOD
6. PRODUCT_PRIMARY::FAMILY::OS
7. PRODUCT_PRIMARY::FAMILY::DISK
8. PRODUCT_PRIMARY::ITEM::MOUSE PAD
9. PRODUCT_PRIMARY::ITEM::OS 1 USER
10. PRODUCT_PRIMARY::ITEM::DLX MOUSE
1. PRODUCT_PRIMARY::ITEM::EXT CD ROM
2. PRODUCT_PRIMARY::ITEM::OS DOC ITA
3. PRODUCT_PRIMARY::ITEM::OS DOC SPA
4. PRODUCT_PRIMARY::ITEM::INT CD USB
5. PRODUCT_PRIMARY::ITEM::ENVY EXT KBD
6. PRODUCT_PRIMARY::ITEM::19 SVGA
7. PRODUCT_PRIMARY::ITEM::OS DOC FRE
8. PRODUCT_PRIMARY::ITEM::OS DOC GER
9. PRODUCT_PRIMARY::ITEM::ENVY ABM
10. PRODUCT_PRIMARY::ITEM::INT CD ROM
11. PRODUCT_PRIMARY::ITEM::ENVY EXE
12. PRODUCT_PRIMARY::ITEM::OS DOC KAN
1. PRODUCT_PRIMARY::TOTAL_PRODUCT::TOTAL
2. PRODUCT_PRIMARY::CLASS::SFT
3. PRODUCT_PRIMARY::FAMILY::ACC
4. PRODUCT_PRIMARY::CLASS::HRD
5. PRODUCT_PRIMARY::FAMILY::MOD
6. PRODUCT_PRIMARY::FAMILY::OS
7. PRODUCT_PRIMARY::FAMILY::DISK
8. PRODUCT_PRIMARY::ITEM::MOUSE PAD
9. PRODUCT_PRIMARY::ITEM::OS 1 USER
10. PRODUCT_PRIMARY::ITEM::DLX MOUSE
11. PRODUCT_PRIMARY::ITEM::LT CASE
12. PRODUCT_PRIMARY::ITEM::56KPS MODEM
7-9
8
Understanding Cursor Classes and
Concepts
This chapter describes the Oracle OLAP Java API Cursor class and the related
classes that you use to retrieve the results of a query. This chapter also describes
the Cursor concepts of position, fetch size, and extent. For examples of creating and
using a Cursor and its related objects, see Retrieving Query Results.
You can get the SQL generated for a Source by the Oracle OLAP SQL generator
without having to create a Cursor. To get the SQL for the Source, you create an
SQLCursorManager by using a createSQLCursorManager method of a DataProvider.
You can then use classes outside of the OLAP Java API, or other methods, to retrieve
data using the generated SQL.
8-1
Chapter 8
Cursor Classes
For a Cursor that you create for a query that includes a parameterized Source,
you can change the value of the Parameter object and then get the new values
of the Cursor without having to commit the Transaction again. For information on
parameterized Source objects, see Understanding Source Objects.
Interface Description
Cursor An abstract superclass that encapsulates the notion of a current
position.
ValueCursor A Cursor that has a value at the current position. A ValueCursor
has no child Cursor objects.
CompoundCursor A Cursor that has child Cursor objects, which are a child
ValueCursor for the values of the Source associated with it and
an output child Cursor for each output of the Source.
8-2
Chapter 8
Cursor Classes
ValueCursor. If the Source has one or more outputs, then the Cursor for that Source is
a CompoundCursor. A CompoundCursor has as children a base ValueCursor, which has
the values of the base of the Source of the CompoundCursor, and one or more output
Cursor objects.
The output of a Source is another Source. An output Source can itself have outputs.
The child Cursor for an output of a Source is a ValueCursor if the output Source does
not have any outputs and a CompoundCursor if it does.
Example 8-1 creates a query that specifies the prices of selected product items for
selected months. In the example, timeHier is a Source for a hierarchy of a dimension
of time values, and prodHier is a Source for a hierarchy of a dimension of product
values.
If you create a Cursor for prodSel or for timeSel, then either Cursor is a ValueCursor
because both prodSel and timeSel have no outputs.
The unitPrice object is a Source for an MdmBaseMeasure that represents values for the
price of product units. The MdmBaseMeasure has as inputs the MdmPrimaryDimension
objects representing products and times, and the unitPrice Source has as inputs the
Source objects for those dimensions.
The example selects elements of the dimension hierarchies and then joins the Source
objects for the selections to that of the measure to produce querySource, which has
prodSel and timeSel as outputs.
The result set defined by querySource is the unit price values for the selected products
for the selected months. The results are organized by the outputs. Since timeSel is
joined to the Source produced by the unitPrice.join(prodSel) operation, timeSel is
the slower varying output, which means that the result set specifies the set of selected
products for each selected time value. For each time value the result set has three
product values so the product values vary faster than the time values. The values of
the base ValueCursor of querySource are the fastest varying of all, because there is
one price value for each product for each day.
Example 9-1 in Retrieving Query Results, creates a Cursor, queryCursor, for
querySource. Since querySource has outputs, queryCursor is a CompoundCursor. The
base ValueCursor of queryCursor has values from unitPrice, which is the base
Source of the operation that created querySource. The values from unitPrice are
those specified by the outputs. The outputs for queryCursor are a ValueCursor that
has values from prodSel and a ValueCursor that has values from timeSel.
8-3
Chapter 8
Cursor Classes
This figure illustrates the structure of queryCursor. The base ValueCursor and the
two output ValueCursor objects are the children of queryCursor, which is the parent
CompoundCursor.
queryCursor
CompoundCursor
Base
Output 1 Output 2 ValueCursor
The following table displays the values from queryCursor in a table. The left column
has time values, the middle column has product values, and the right column has the
unit price of the product for the month.
For examples of getting the values from a ValueCursor, see Retrieving Query Results.
• setDefaultFetchSize
• setExtentCalculationSpecified
• setParentEndCalculationSpecified
• setParentStartCalculationSpecified
8-4
Chapter 8
CursorInfoSpecification Classes
• getExtent
• getFetchSize
• getParentEnd
• getParentStart
• setFetchSize
For examples of specifying Cursor behavior, see Retrieving Query Results. For
information on fetch sizes, see "About Fetch Sizes". For information on the extent
of a Cursor, see "What is the Extent of a Cursor?". For information on the starting and
ending positions in a parent Cursor of the current value of a Cursor, see "About the
Parent Starting and Ending Positions in a Cursor".
8-5
Chapter 8
CursorManager Class
starting and ending positions of a value in the parent, then you can determine how
many faster varying elements the parent Cursor has for that value.
• Determine whether calculating the starting or ending position of the current value
of the corresponding Cursor in the parent is specified.
• Accept a CursorSpecificationVisitor.
For more information, see "About Cursor Positions and Extent" and "About Fetch
Sizes".
In the oracle.olapi.data.source package, the Oracle OLAP Java API defines the
classes described in the following table.
Interface Description
CursorInfoSpecification An interface that specifies methods for
CursorSpecification objects.
CursorSpecification An abstract class that implements some
methods of the CursorInfoSpecification
interface.
CompoundCursorSpecification A CursorSpecification for a Source
that has one or more outputs.
A CompoundCursorSpecification has
component child CursorSpecification
objects.
CompoundInfoCursorSpecification An interface that specifies methods for
CompoundCursorSpecification objects.
ValueCursorSpecification A CursorSpecification for a Source that
has values and no outputs.
ValueCursorInfoSpecification An interface for ValueCursorSpecification
objects.
You can create more than one Cursor from the same CursorManager, which is useful
for displaying data from a result set in different formats such as a table or a graph. All
of the Cursor objects created by a CursorManager have the same specifications, such
as the default fetch sizes. Because the Cursor objects have the same specifications,
they can share the data managed by the CursorManager.
A SQLCursorManager has methods that return the SQL generated by the Oracle OLAP
SQL generator for a Source. You create one or more SQLCursorManager objects
by calling the createSQLCursorManager or createSQLCursorManagers methods of a
8-6
Chapter 8
About Cursor Positions and Extent
Oracle OLAP does not validate the position that you set on the Cursor until you
attempt an operation on the Cursor, such as calling the getCurrentValue method.
If you set the current position to a negative value or to a value that is greater than
the number of positions in the Cursor and then attempt a Cursor operation, then the
Cursor throws a PositionOutOfBoundsException.
8-7
Chapter 8
About Cursor Positions and Extent
2 PRODUCT_PRIMARY::ITEM::ENVY EXE
3 PRODUCT_PRIMARY::ITEM::ENVY STD
For more examples of getting the current value of a ValueCursor, see Retrieving
Query Results.
Each position of queryCursor specifies one set of positions of the outputs and the
base ValueCursor. For example, position 1 of queryCursor defines the following set of
positions for the outputs and the base ValueCursor:
8-8
Chapter 8
About Cursor Positions and Extent
queryCursor
CompoundCursor
Positions
1 Output 1 = 1, Output 2 = 1, VC=1
2 Output 1 = 1, Output 2 = 2, VC=1
3 Output 1 = 1, Output 2 = 3, VC=1
4 Output 1 = 2, Output 2 = 1, VC=1
5 Output 1 = 2, Output 2 = 2, VC=1
6 Output 1 = 2, Output 2 = 3, VC=1
7 Output 1 = 3, Output 2 = 1, VC=1
8 Output 1 = 3, Output 2 = 2, VC=1
9 Output 1 = 3, Output 2 = 3, VC=1
10 Output 1 = 4, Output 2 = 1, VC=1
11 Output 1 = 4, Output 2 = 2, VC=1
12 Output 1 = 4, Output 2 = 3, VC=1
The ValueCursor for queryCursor has only one position because only one value of
unitPrice is specified by any one set of values of the outputs. For a query such as
querySource, the ValueCursor of the Cursor has only one value, and therefore only
one position, at a time for any one position of the root CompoundCursor.
This figure illustrates one possible display of the data from queryCursor. It is a
crosstab view with four columns and five rows. In the left column are the month values.
In the top row are the product values. In each of the intersecting cells of the crosstab is
the price of the product for the month.
Product
Month ENVY ABM ENVY EXE ENVY STD
2001.01 3042.22 3223.28 2426.07
2001.04 3026.12 3107.65 2412.42
2001.07 2892.18 3155.91 2505.57
2001.10 2892.18 3105.53 2337.30
8-9
Chapter 8
About Cursor Positions and Extent
Example 8-2 Setting the CompoundCursor Position and Getting the Current
Values
This example sets the position of queryCursor and then gets the current values and
the positions of the child Cursor objects.
CompoundCursor rootCursor = (CompoundCursor) queryCursor;
ValueCursor baseValueCursor = rootCursor.getValueCursor();
List outputs = rootCursor.getOutputs();
ValueCursor output1 = (ValueCursor) outputs.get(0);
ValueCursor output2 = (ValueCursor) outputs.get(1);
int pos = 5;
rootCursor.setPosition(pos);
println("CompoundCursor position set to " + pos + ".");
println("The current position of the CompoundCursor is = " +
rootCursor.getPosition() + ".");
println("Output 1 position = " + output1.getPosition() +
", value = " + output1.getCurrentValue());
println("Output 2 position = " + output2.getPosition() +
", value = " + output2.getCurrentValue());
println("VC position = " + baseValueCursor.getPosition() +
", value = " + baseValueCursor.getCurrentValue());
The positions of queryCursor are symmetric in that the result set for querySource
always has three product values for each time value. The ValueCursor for prodSel,
therefore, always has three positions for each value of the timeSel ValueCursor. The
timeSel output ValueCursor is slower varying than the prodSel ValueCursor.
The example creates a Cursor for querySource2, loops through the positions of the
CompoundCursor, gets the position and current value of the first output ValueCursor
and the ValueCursor of the CompoundCursor, and displays the positions and values of
the ValueCursor objects. The getLocalValue method is a method in the program that
extracts the local value from a unique value.
8-10
Chapter 8
About Cursor Positions and Extent
Because not every combination of product and time selections has unit sales greater
than 1 for the specified channel and customer selections, the number of elements of
the ValueCursor for the values derived from prodSel is not the same for each value of
the output ValueCursor. For time value 2001.01, all three products have sales greater
than one, but for time value 2001.04, only one of the products does. The other two
time values, 2001.07 and 2001.10, have two products that meet the criteria. Therefore,
the ValueCursor for the CompoundCursor has three positions for time 2001.01, only
one position for time 2001.04, and two positions for times 2001.07 and 2001.10.
8-11
Chapter 8
About Cursor Positions and Extent
The result is the span of the current value of the child Cursor in the parent Cursor,
which tells you how many values of the fastest varying child Cursor exist for the
current value. Calculating the starting and ending positions is costly in time and
computing resources, so you should only specify that you want those calculations
performed when your application needs the information.
An Oracle OLAP Java API Cursor enables your application to have only the data that
it is currently displaying actually present on the client computer. For information on
specifying the amount of data for a Cursor, see "About Fetch Sizes".
From the data on the client computer, however, you cannot determine at what position
of the parent Cursor the current value of a child Cursor begins or ends. To get that
information, you use the getParentStart and getParentEnd methods of a Cursor.
To specify that you want Oracle OLAP to calculate the starting and
ending positions of a value of a child Cursor in the parent Cursor, call
the setParentStartCalculationSpecified and setParentEndCalculationSpecified
methods of the CursorSpecification corresponding to the Cursor. You can
determine whether calculating the starting or ending positions is specified by calling
the isParentStartCalculationSpecified or isParentEndCalculationSpecified
methods of the CursorSpecification. For an example of specifying these
calculations, see Retrieving Query Results.
8-12
Chapter 8
About Fetch Sizes
To specify that you want Oracle OLAP to calculate the extent for a Cursor, call the
setExtentCalculationSpecified method of the CursorSpecification corresponding
to the Cursor. You can determine whether calculating the extent is specified by
calling the isExtentCalculationSpecified method of the CursorSpecification. For
an example of specifying the calculation of the extent of a Cursor, see Retrieving
Query Results.
The amount of data that a Cursor retrieves in a single fetch operation is determined
by the fetch size specified for the Cursor. You specify a fetch size to limit the amount
of data your application needs to cache on the local computer and to maximize the
efficiency of the fetch by customizing it to meet the needs of your method of displaying
the data.
You can also regulate the number of elements that Oracle OLAP returns by using
Parameter and parameterized Source objects in constructing your query. For more
information on Parameter objects, see Understanding Source Objects. For examples
of using parameterized Source objects, see Making Queries Using Source Methods.
When you create a CursorManager for a Source, Oracle OLAP specifies a default fetch
size on the root CursorSpecification. You can change the default fetch size with the
setDefaultFetchSize method of the root CursorSpecification.
You can create two or more Cursor objects from the same CursorManager and use
both Cursor objects simultaneously. Rather than having separate data caches, the
Cursor objects can share the data managed by the CursorManager.
An example is an application that displays the results of a query to the user as both
a table and a graph. The application creates a CursorManager for the Source. The
application creates two separate Cursor objects from the same CursorManager, one
for a table view and one for a graph view. The two views share the same query and
display the same data, just in different formats.
Figure 8-4 A Source and Two Cursors for Different Views of the Values
This figure illustrates the relationship between the Source, the Cursor objects, and the
views.
8-13
Chapter 8
About Fetch Sizes
queryCM : CursorManager
querySource : Source
8-14
9
Retrieving Query Results
This chapter describes how to retrieve the results of a query with an Oracle OLAP
Java API Cursor and how to gain access to those results. This chapter also describes
how to customize the behavior of a Cursor to fit your method of displaying the
results. For information on the class hierarchies of Cursor and its related classes,
and for information on the Cursor concepts of position, fetch size, and extent, see
Understanding Cursor Classes and Concepts.
This chapter includes the following topics:
• Retrieving the Results of a Query
• Navigating a CompoundCursor for Different Displays of Data
• Specifying the Behavior of a Cursor
• Calculating Extent and Starting and Ending Positions of a Value
• Specifying a Fetch Size
Finally, the example closes the CursorManager. When you have finished using the
Cursor, you should close the CursorManager to free resources.
CursorManager cursorMngr = dp.createCursorManager(querySource);
Cursor queryCursor = cursorMngr.createCursor();
9-1
Chapter 9
Retrieving the Results of a Query
// Use the Cursor in some way, such as to display the values of it.
cursorMngr.close();
A ValueCursor is returned for a Source that has a single set of values. A ValueCursor
has a value at its current position, and it has methods for getting the value at the
current position.
A CompoundCursor is created for a Source that has more than one set of values,
which is a Source that has one or more outputs. Each set of values of the Source is
represented by a child ValueCursor of the CompoundCursor. A CompoundCursor has
methods for getting its child Cursor objects.
The structure of the Source determines the structure of the Cursor. A Source can have
nested outputs, which occurs when one or more of the outputs of the Source is itself a
Source with outputs. If a Source has a nested output, then the CompoundCursor for that
Source has a child CompoundCursor for that nested output.
The CompoundCursor coordinates the positions of the child Cursor objects that it
contains. The current position of the CompoundCursor specifies one set of positions
of the child Cursor objects.
For an example of a Source that has only one level of output values, see Example 9-4.
For an example of a Source that has nested output values, see Example 9-5.
9-2
Chapter 9
Retrieving the Results of a Query
// Product values are strings. Get the value at the current position.
String value = prodValues.getCurrentString();
The values of the result set represented by a CompoundCursor are in the child
ValueCursor objects of the CompoundCursor. To get those values, you must get the
child ValueCursor objects from the CompoundCursor.
Example 9-4 joins the dimension selections to the measure, which results
in a Source named unitsForSelections. It creates a CompoundCursor, named
unitsForSelCursor, for unitsForSelections, and gets the base ValueCursor and the
outputs from the CompoundCursor. Each output is a ValueCursor, in this case. The
outputs are returned in a List. The order of the outputs in the List is the inverse of
the order in which the outputs were added to the list of outputs by the successive join
operations. In the example, dp is the DataProvider.
9-3
Chapter 9
Retrieving the Results of a Query
// You can now get the values from the ValueCursor objects.
// When you have finished using the Cursor objects, close the CursorManager.
cursorMngr.close();
Example 9-5 uses the same units measure as Example 9-4, but it joins the dimension
selections to the measure differently. Example 9-5 joins two of the dimension
selections together. It then joins the result to the Source produced by joining the single
dimension selections to the measure. The resulting Source, unitsForSelections,
represents a query has nested outputs, which means it has more than one level of
outputs.
The CompoundCursor that this example creates for unitsForSelections therefore also
has nested outputs. The CompoundCursor has a child base ValueCursor and has as
outputs three child ValueCursor objects and one child CompoundCursor.
Example 9-5 joins the selection of channel dimension values, chanSel, to the selection
of customer dimension values, custSel. The result is custByChanSel, a Source that
has customer values as the base values and channel values as the values of the
output. The example joins to units the selections of product and time values, and then
joins custByChanSel. The resulting query is represented by unitsForSelections.
The example commits the current Transaction and creates a CompoundCursor, named
unitsForSelCursor, for unitsForSelections.
The example gets the base ValueCursor and the outputs from the CompoundCursor. In
the example, dp is the DataProvider.
9-4
Chapter 9
Retrieving the Results of a Query
9-5
Chapter 9
Navigating a CompoundCursor for Different Displays of Data
}
}
To display the results of a query in a table view, in which each row contains a value
from each output ValueCursor and from the base ValueCursor, you determine the
position of the top-level, or root, CompoundCursor and then iterate through its positions.
Example 9-6 displays only a portion of the result set at one time. It creates a Cursor
for a Source that represents a query that is based on a measure that has unit cost
values. The dimensions of the measure are the product and time dimensions. The
creation of the primary Source objects and the derived selections of the dimensions is
not shown.
The example joins the Source objects representing the dimension value selections to
the Source representing the measure. It commits the current Transaction and then
creates a Cursor, casting it to a CompoundCursor. The example sets the position of the
CompoundCursor, iterates through twelve positions of the CompoundCursor, and prints
out the values specified at those positions. The DataProvider is dp.
9-6
Chapter 9
Navigating a CompoundCursor for Different Displays of Data
If the time selection for the query has eight values, such as the first month of each
calendar quarter for the years 2001 and 2002, and the product selection has three
values, then the result set of the unitPriceByMonth query has twenty-four positions.
The example displays the following table, which has the values specified by positions
7 through 18 of the CompoundCursor.
Month Product Unit Price
------- -------- ----------
2001.07 ENVY ABM 2892.18
2001.07 ENVY EXE 3155.91
2001.07 ENVY STD 2505.57
2001.10 ENVY ABM 2856.86
2001.10 ENVY EXE 3105.53
2001.10 ENVY STD 2337.3
2002.01 ENVY ABM 2896.77
2002.01 ENVY EXE 3008.95
2002.01 ENVY STD 2140.71
2002.04 ENVY ABM 2880.39
2002.04 ENVY EXE 2953.96
2002.04 ENVY STD 2130.88
9-7
Chapter 9
Navigating a CompoundCursor for Different Displays of Data
do
{
// Print the row dimension values.
String value = ((ValueCursor) rowCursor).getCurrentString();
print(getContext().getLocalValue(value) + " ");
// Loop over columns.
do
{
// Print data value.
print(unitPriceValues.getCurrentValue() + " ");
} while (columnCursor.next());
println();
cursorMngr.close();
The following is a crosstab view of the values from the result set specified by the
unitPriceByMonth query. The first line labels the rightmost three columns as having
product values. The third line labels the first column as having month values and then
labels each of the rightmost three columns with the product value for that column. The
remaining lines have the month value in the left column and then have the data values
from the units measure for the specified month and product.
PRODUCT
---------------------------------
Month ENVY ABM ENVY EXE ENVY STD
------- -------- -------- --------
2001.01 3042.22 3223.28 2426.07
2001.04 3026.12 3107.65 2412.42
2001.07 2892.18 3155.91 2505.57
2001.10 2856.86 3105.53 2337.30
2002.01 2896.77 3008.95 2140.71
2002.04 2880.39 2953.96 2130.88
2002.07 2865.14 3002.34 2074.56
2002.10 2850.88 2943.96 1921.62
9-8
Chapter 9
Navigating a CompoundCursor for Different Displays of Data
The query that results from joining the dimension selections to the measure Source
represents unit sold values as specified by the values of the outputs.
The example creates a Cursor for the query and then sends the Cursor to the
printAsCrosstab method, which prints the values from the Cursor in a crosstab. That
method calls other methods that print page, column, and row values.
The fastest-varying output of the Cursor is the selection of products, which has three
values (the product items ENVY ABM, ENVY EXE, and ENVY STD). The product
values are the column headings of the crosstab. The next fastest-varying output is
the selection of customers, which has three values (the customers COMP SERV
TOK, COMP WHSE LON, and COMP WHSE SD). Those three values are the row
headings. The page dimensions are selections of three time values (the months
2000.01, 2000.02, and 2000.03), and one channel value (DIR, which is the direct sales
channel).
The DataProvider is dp. The getLocalValue method gets the local value from a
unique dimension value.
// In someMethod.
Source unitsForSelections = units.join(prodSel)
.join(custSel)
.join(timeSel)
.join(chanSel);
// Commit the current Transaction (code not shown).
cursorMngr.close();
// The remainder of the code of someMethod is not shown.
9-9
Chapter 9
Navigating a CompoundCursor for Different Displays of Data
{
pageCursors.add(outputs.get(i));
}
9-10
Chapter 9
Navigating a CompoundCursor for Different Displays of Data
println();
}
The example displays the following values, formatted as a crosstab. The display has
added page, column, and row headings to identify the local values of the dimensions.
Channel DIR
Month 2001.01
Product
------------------------------
Customer ENVY ABM ENVY EXE ENVY STD
------------- -------- -------- --------
COMP WHSE SD 0 0 1
COMP SERV TOK 2 4 2
COMP WHSE LON 1 1 2
Channel DIR
Month 2000.02
Product
9-11
Chapter 9
Specifying the Behavior of a Cursor
------------------------------
Customer ENVY ABM ENVY EXE ENVY STD
------------- -------- -------- --------
COMP WHSE SD 1 1 1
COMP SERV TOK 5 6 6
COMP WHSE LON 1 2 2
Channel DIR
Month 2000.03
Product
------------------------------
Customer ENVY ABM ENVY EXE ENVY STD
------------- -------- -------- --------
COMP WHSE SD 0 2 2
COMP SERV TOK 2 0 2
COMP WHSE LON 0 2 3
• The fetch size of a Cursor, which is the number of elements of the result set that
the Cursor retrieves during one fetch operation.
• Whether or not Oracle OLAP calculates the extent of the Cursor. The extent
is the total number of positions of the Cursor. The extent of a child Cursor
of a CompoundCursor is relative to any of the slower varying outputs of the
CompoundCursor.
• Whether or not Oracle OLAP calculates the positions in the parent Cursor at which
the value of a child Cursor starts or ends.
To specify the behavior of Cursor, you use methods of a CursorSpecification
that you specify for that Cursor. A CursorSpecification implements the
CursorInfoSpecification interface.
Note:
Specifying the calculation of the extent or the starting or ending position in a
parent Cursor of the current value of a child Cursor can be a very expensive
operation. The calculation can require considerable time and computing
resources. You should only specify these calculations when your application
needs them.
9-12
Chapter 9
Calculating Extent and Starting and Ending Positions of a Value
Once you have the CursorSpecification objects, you can use their methods to
specify the behavior of the Cursor objects that correspond to them.
Example 9-10 specifies calculating the extent of a Cursor. The example uses the
CompoundCursorSpecification from Example 9-9.
9-13
Chapter 9
Calculating Extent and Starting and Ending Positions of a Value
Example 9-11 specifies calculating the starting and ending positions of the
current value of a child Cursor in the parent Cursor. The example uses the
CompoundCursorSpecification from Example 9-9.
The example gets the starting and ending positions of the current values of the time
and product selections and then calculates the span of those values in the parent
Cursor. The parent is the root CompoundCursor. The DataProvider is dp.
Example 9-12 Calculating the Span of the Positions in the Parent of a Value
Source unitsForSelections = units.join(prodSel)
.join(custSel)
.join(timeSel)
.join(chanSel);
// Commit the current Transaction (code not shown).
9-14
Chapter 9
Specifying a Fetch Size
// Get the values at the current position and determine the span
// of the values of the time and product outputs.
print(chanSelVals.getCurrentValue() + ", ");
print(timeSelVals.getCurrentValue() + ",\n ");
print(custSelVals.getCurrentValue() + ", ");
print(prodSelVals.getCurrentValue() + ", ");
print(baseValCursor.getCurrentValue());
println();
9-15
Chapter 9
Specifying a Fetch Size
default fetch size is 100. To change the fetch size, you can set the fetch size on the
root Cursor for a Source.
9-16
10
Creating Dynamic Queries
To create dynamic queries, you use the Oracle OLAP Java API Template class
and other related classes. The following topics describe these classes and provide
examples of implementations of them.
• About Template Objects
• Overview of Template and Related Classes
• Designing and Implementing a Template
The Source that a Template produces can change because the values, including other
Source objects, that the Template uses to create the Source can change. A Template
stores those values in a MetadataState. A Template provides methods to get the
current state of the MetadataState, to get or set a value, and to set the state. You use
those methods to change the data values that the MetadataState stores.
10-1
Chapter 10
Overview of Template and Related Classes
Source, for example, in response to end-user selections, then the application uses
the same DynamicDefinition to get the Source again, even though the new Source
defines a result set different than the previous Source.
The Source produced by a Template can be the result of a series of Source operations
that create other Source objects, such as a series of selections, sortings, calculations,
and joins. You put the code for those operations in the generateSource method of a
SourceGenerator for the Template. That method returns the Source produced by the
Template. The operations use the data stored in the MetadataState.
You might build an extremely complex query that involves the interactions of dynamic
Source objects produced by many different Template objects. The end result of the
query building is a Source that defines the entire complex query. If you change the
state of any one of the Template objects that you used to create the final Source,
then the final Source represents a result set that is different from that of the previous
Source. You can thereby modify the final query without having to reproduce all of the
operations involved in defining the query.
10.1.2 About Translating User Interface Elements into OLAP Java API
Objects
You design Template objects to represent elements of the user interface of an
application. Your Template objects turn the selections that the end user makes into
OLAP Java API query-building operations that produce a Source. You then create a
Cursor to fetch from Oracle OLAP the result set defined by the Source. You get the
values from the Cursor and display them to the end user. When an end user makes
changes to the selections, you change the state of the Template. You then get the
Source produced by the Template, create a new Cursor, get the new values, and
display them.
• A Template has methods that create a DynamicDefinition and that get and set
the current state of a MetadataState. An extension to the Template abstract class
adds methods that get and set the values of fields on the MetadataState.
10-2
Chapter 10
Overview of Template and Related Classes
• The MetadataState implementation has fields for storing the data to use in
generating the Source for the Template. When you create a new Template, you
pass the MetadataState to the constructor of the Template. When you call the
getSource method of the DynamicDefinition, the MetadataState is passed to the
generateSource method of the SourceGenerator.
• The DataProvider is used in creating a Template and by the SourceGenerator in
creating new Source objects.
• The SourceGenerator implementation has a generateSource method that uses
the current state of the data in the MetadataState to produce a Source for the
Template. You pass in the SourceGenerator to the createDynamicDefinition
method of the Template to create a DynamicDefinition.
• The DynamicDefinition has a getSource method that gets the Source produced
by the SourceGenerator. The DynamicDefinition serves as a proxy for the
SourceDefinition that is immutably associated with the Source.
10-3
Chapter 10
Designing and Implementing a Template
A Template can create more than one DynamicDefinition, each with a differently
implemented SourceGenerator. The generateSource methods of the different
SourceGenerator objects use the same data, as defined by the current state of
the MetadataState for the Template, to produce Source objects that define different
queries.
For an example of a SourceGenerator implementation, see Example 10-3.
10-4
Chapter 10
Designing and Implementing a Template
To generate a Source that represents the query that the end user creates in
the first dialog box, you design a Template called TopBottomTemplate. You also
design a second Template, called SingleSelectionTemplate, to create a Source that
represents the end user's selections of single values for the dimensions other than
the base dimension. The designs of your Template objects reflect the user interface
elements of the dialog boxes.
In designing the TopBottomTemplate and its MetadataState and SourceGenerator,
you do the following:
• Create a class called TopBottomTemplate that extends Template. To the class, you
add methods that get the current state of the Template, set the values specified by
the user, and then set the current state of the Template.
• Create a class called TopBottomTemplateState that implements MetadataState.
You provide fields on the class to store values for the SourceGenerator to use in
generating the Source produced by the Template. The values are set by methods
of the TopBottomTemplate.
• Create a class called TopBottomTemplateGenerator that implements
SourceGenerator. In the generateSource method of the class, you provide the
operations that create the Source specified by the end user's selections.
Using your application, an end user selects units sold as the measure and products as
the base dimension in the first dialog box. The end user also selects the Asia Pacific
region, the first quarter of 2001, and the direct sales channel as the single values for
each of the remaining dimensions.
The query that the end user has created requests the ten products that have the
highest total amount of units sold through the direct sales channel to customers in the
Asia Pacific region during the calendar year 2001.
For examples of implementations of the TopBottomTemplate,
TopBottomTemplateState, and TopBottomTemplateGenerator classes, and an
example of an application that uses them, see Example 10-1, Example 10-2,
Example 10-3, and Example 10-4. The TopBottomTemplateState and
TopBottomTemplateGenerator classes are implemented as inner classes of the
TopBottomTemplate outer class.
/**
* Creates a TopBottomTemplateState, a TopBottomTemplateGenerator,
* and a DynamicDefinition.
* Gets the current state of the TopBottomTemplateState and the values
10-5
Chapter 10
Designing and Implementing a Template
* 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;
/**
* 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.
*/
10-6
Chapter 10
Designing and Implementing a Template
/**
* 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-7
Chapter 10
Designing and Implementing a Template
/**
* 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;
}
}
}
/**
* Creates a TopBottomTemplateGenerator.
*/
public TopBottomTemplateGenerator(DataProvider dataProvider)
{
10-8
Chapter 10
Designing and Implementing a Template
_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;
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));
}
}
10-9
Chapter 10
Designing and Implementing a Template
/**
* 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();
10-10
Chapter 10
Designing and Implementing a Template
MdmCube unitsCube =
(MdmCube)mdmDBSchema.getTopLevelObject("UNITS_CUBE_AWJ");
MdmBaseMeasure mdmUnits = unitsCube.findOrCreateBaseMeasure("UNITS");
MdmBaseMeasure mdmSales = unitsCube.findOrCreateBaseMeasure("SALES");
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();
10-11
Chapter 10
Designing and Implementing a Template
// 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);
// Create a Cursor for the result and display the values of the Cursor.
getContext().displayTopBottomResult(result);
10-12
Chapter 10
Designing and Implementing a Template
// 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);
topNBottomResult = topNBottom.getSource();
result = prodShortDescrAttr.joinHidden(topNBottomResult);
topNBottomResult = topNBottom.getSource();
result = prodShortDescrAttr.joinHidden(topNBottomResult);
/**
* 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();
10-13
Chapter 10
Designing and Implementing a Template
// SingleSelectionTemplate.
StringBuffer shortDescrsForMemberVals =
singleSelections.getMemberShortDescrs(dp);
/**
* 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);
}
}
The TopBottomTest program produces the following output.
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
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
10-14
Chapter 10
Designing and Implementing a Template
10-15
A
Setting Up the Development Environment
This appendix describes the development environment for creating applications that
use the OLAP Java API.
This appendix includes the following topics:
• Overview
• Required Class Libraries
• Obtaining the Class Libraries
A.1 Overview
The OLAP Java API client software is a set of Java packages containing classes that
implement a Java programming interface to Oracle OLAP. An Oracle Database with
the OLAP option provides the OLAP Java API and other required class libraries as
Java archive (JAR) files. As an application developer, you must copy the required JAR
files to the computer on which you develop your Java application, or otherwise make
them accessible to your development environment.
When a Java application calls methods of OLAP Java API objects, it uses the OLAP
Java API client software to communicate with Oracle OLAP, which resides within
an Oracle Database instance. The communication between the OLAP Java API
client software and Oracle OLAP is provided through the Java Database Connectivity
(JDBC) API, which is a standard Java interface for connecting to relational databases.
Another required JAR file provides support for importing and exporting OLAP Java API
metadata objects XML.
To use the OLAP Java API classes as you develop your application, import them into
your Java code. When you deliver your application to users, include the OLAP Java
API classes with the application. You must also ensure that users can access JDBC.
To develop an OLAP Java API application, you must have the Java Development
Kit (JDK), such as one in Oracle JDeveloper. Users must have a Java Runtime
Environment (JRE) whose version number is compatible with the JDK that you used
for development.
A-1
Appendix A
Obtaining the Class Libraries
• The Java Development Kit (JDK) version 1.6. The Oracle Database installation
does not provide the JDK. If you are using Oracle JDeveloper as your
development environment, then the JDK is already installed on your computer.
However, ensure that you are using the correct version of the JDK in JDeveloper.
For information about obtaining and using some other JDK, see the Oracle
Technology Network Java website at http://www.oracle.com/technetwork/java/
index.html.
Table A-1 Required Class Libraries and Their Locations in the Oracle
Installation
A-2
B
SingleSelectionTemplate Class
This appendix contains the code for the SingleSelectionTemplate class. This class is
used by the examples in Using a TransactionProvider, and Creating Dynamic Queries.
/**
* A Template that joins Source objects for selected members of
* dimension hierarchies to a Source for a measure.
*/
public class SingleSelectionTemplate extends Template
{
// Variable to store the DynamicDefinition.
private DynamicDefinition dynamicDef;
/**
* Creates a SingleSelectionTemplate.
*/
public SingleSelectionTemplate(Source measure, DataProvider dataProvider)
{
super(new SingleSelectionTemplateState(measure), dataProvider);
dynamicDef = createDynamicDefinition(
new SingleSelectionTemplateGenerator(dataProvider));
}
/**
* Gets the Source produced by the SingleSelectionTemplateGenerator
* from the DynamicDefinition.
*/
public final Source getSource()
B-1
Appendix B
Code for the SingleSelectionTemplate Class
{
return dynamicDef.getSource();
}
/**
* Gets the Source for the measure stored by the SingleSelectionTemplateState.
*/
public Source getMeasure()
{
SingleSelectionTemplateState state =
(SingleSelectionTemplateState)getCurrentState();
return state.measure;
}
/**
* Specifies the Source for the measure stored by the
* SingleSelectionTemplateState.
*/
public void setMeasure(Source measure)
{
SingleSelectionTemplateState state =
(SingleSelectionTemplateState)getCurrentState();
state.measure = measure;
setCurrentState(state);
}
/**
* Gets the List of MdmDimensionMemberInfo objects for the selected members
* of the dimensions.
*/
public List getDimMemberInfos()
{
SingleSelectionTemplateState state =
(SingleSelectionTemplateState)getCurrentState();
return Collections.unmodifiableList(state.dimMemberInfos);
}
/**
* Adds an MdmDimensionMemberInfo to the List of
* MdmDimensionMemberInfo objects.
*/
public void addDimMemberInfo(MdmDimensionMemberInfo mdmDimMemberInfo)
{
SingleSelectionTemplateState state =
(SingleSelectionTemplateState)getCurrentState();
state.dimMemberInfos.add(mdmDimMemberInfo);
setCurrentState(state);
}
/**
* Changes the member specified for a dimension.
*/
public void changeSelection(MdmDimensionMemberInfo mdmDimMemberInfo)
{
SingleSelectionTemplateState state =
(SingleSelectionTemplateState)getCurrentState();
int i = 0;
B-2
Appendix B
Code for the SingleSelectionTemplate Class
MdmDimensionMemberInfo mdmDimMemberInfoInList =
(MdmDimensionMemberInfo)dimMemberInfosItr.next();
MdmPrimaryDimension mdmPrimDim1 = mdmDimMemberInfo.getPrimaryDimension();
MdmPrimaryDimension mdmPrimDim2 =
mdmDimMemberInfoInList.getPrimaryDimension();
//String value = (String)valuesItr.next();
if (mdmPrimDim1.getName().equals(mdmPrimDim2.getName()))
{
state.dimMemberInfos.remove(i);
state.dimMemberInfos.add(i, mdmDimMemberInfo);
break;
}
i++;
}
setCurrentState(state);
}
/**
* Gets the short value description of the each of the dimension members
* specified by the list of MdmDimensionMemberInfo objects and returns
* the descriptions in a StringBuffer.
*/
public StringBuffer getMemberShortDescrs(DataProvider dp)
{
boolean firsttime = true;
while(mdmDimMemInfoListItr.hasNext())
{
MdmDimensionMemberInfo mdmDimMemInfo =
(MdmDimensionMemberInfo)mdmDimMemInfoListItr.next();
MdmPrimaryDimension mdmPrimDim = mdmDimMemInfo.getPrimaryDimension();
MdmAttribute mdmShortDescrAttr =
mdmPrimDim.getShortValueDescriptionAttribute();
Source shortDescrAttr = mdmShortDescrAttr.getSource();
MdmHierarchy mdmHier = mdmDimMemInfo.getHierarchy();
StringSource hierSrc = (StringSource) mdmHier.getSource();
Source memberSel = hierSrc.selectValue(mdmDimMemInfo.getUniqueValue());
Source shortDescrForMember = shortDescrAttr.joinHidden(memberSel);
B-3
Appendix B
Code for the SingleSelectionTemplate Class
if(firsttime)
{
shortDescrForMemberVals.append(shortDescrForMemberVal);
firsttime = false;
}
else
{
shortDescrForMemberVals.append(", " + shortDescrForMemberVal);
}
}
return shortDescrForMemberVals;
}
/**
* Inner class that implements the MetadataState object for this Template.
* Stores data that can be changed by its SingleSelectionTemplate.
* The data is used by a SingleSelectionTemplateGenerator in producing
* a Source for the SingleSelectionTemplate.
*/
private static class SingleSelectionTemplateState
implements MetadataState
{
public Source measure;
public ArrayList dimMemberInfos;
/**
* Creates a SingleSelectionTemplateState.
*/
public SingleSelectionTemplateState(Source measure)
{
this(measure, new ArrayList());
}
/**
* Inner class that implements the SourceGenerator object for this Template.
* Produces a Source based on the data values of a SingleSelectionTemplate.
*/
private static final class SingleSelectionTemplateGenerator
implements SourceGenerator
{
DataProvider dp = null;
/**
* Creates a SingleSelectionTemplateGenerator.
*/
B-4
Appendix B
Code for the SingleSelectionTemplate Class
/**
* Generates a Source for the SingleSelectionTemplate.
*/
public Source generateSource(MetadataState state)
{
SingleSelectionTemplateState castState =
(SingleSelectionTemplateState)state;
Source result = castState.measure;
B-5
Index
A attributes (continued)
specifying target dimension for, 2-25
access to metadata objects unique key, 2-28
restricting, 2-14 AW objects
addObjectClassification method, 2-9 creating, 4-2
aggregate levels of a hierarchy, 2-21 naming, 2-4
AggregationCommand objects AWCubeOrganization class, 2-17
example of creating, 4-8 AWCubeOrganization objects
alias method example of creating, 4-8
description, 6-1 AWPrimaryDimensionOrganization objects
example of, 6-3 creating, 4-3
ALL metadata reader mode, 2-5, 2-6
Analytic Workspace Manager, 1-5
analytic workspaces
B
building, 1-5 base Source
building, example of, 4-11 definition, 5-4, 6-1
creating, 4-2 of a join operation, 5-6
sample, 1-6 BaseExample11g.java example program, 1-7
ancestors attribute BaseMetadataObject class, 2-3
example of getting, 6-12 basic Source methods, 6-1
method for getting, 2-21 bind variables
appendValues method, 5-18 in XML templates, 2-12
example of, 6-4 Buildable interface, 2-20
applications building analytic workspaces, 1-5
requirements for developing, A-1 example of, 4-11
typical tasks performed by, 1-8 BuildItem objects
ascending creating, 4-11
comparison rules in a join operation, 5-7 BuildProcess objects
asymmetric result set, Cursor positions in an, creating, 4-11
8-10
at method
example of, 6-17 C
AttributeMap objects Cartesian product
creating, 4-3 result of joining unrelated Source objects, 5-6
attributes class libraries
as dimensional data objects, 1-4 obtaining, A-2
creating, 4-7 classifying metadata objects, 2-9
creating an index for, 2-26 ColumnExpression objects
grouping, 2-26 creating, 4-3
mapping, 4-8 committing transactions, 4-10
mapping, example of, 4-3 comparison parameter
multilingual, 2-26 of the join method, 5-7
prefixes for in materialized views, 2-29 COMPARISON_RULE_ASCENDING
represented by MdmAttribute objects, 2-23 example of, 6-8, 6-19
specifying language for, 2-26
Index-1
Index
Index-2
Index
D div method
example of, 6-21
data drilling in a hierarchy
retrieving, 1-6, 8-1 example of, 6-17
specifying, 1-6, 5-1 dynamic queries, 10-1
data objects dynamic Source objects
first-class, 2-9 definition, 5-2
data store example of getting, 10-9
definition, 1-5 produced by a Template, 10-1
exploring, 3-3 DynamicDefinition class, 10-4
gaining access to data in, 1-5, 2-15, 3-3
scope of, 3-3
data types, 5-3
E
converting, 6-1 edges of a cube
of Source objects, 5-3 creating, 4-2
See also SQL data types definition, 1-3
data warehouse, 1-5 pivoting, example of, 6-15
database schemas elements
represented by MdmDatabaseSchema of a Source, 5-3
objects, 2-14 empty Source objects
DataProvider objects definition, 5-2
creating, 3-2 EnableMVs.java example program, 2-28
needed to create MdmMetadataProvider, 3-4 end date
deployment package attribute, 2-24
description, 1-2 of a time dimension, 2-20
derived Source objects ET views, 2-29
definition, 5-2 embedded total views for OLAP metadata
descending objects, 2-29
comparison rules in a join operation, 5-7 See also OLAP views
descriptions example programs
metadata objects for, 2-6 compressed file containing, 1-7
types provided by API, 2-6 sample schema for, 1-6
dimension levels executeBuild method
mapping, 4-3 example of, 4-11
metadata object for, 2-21 exportFullXML methods
dimensional data model description, 2-11
associations between classes, 2-15 example of, 4-11
description, 1-3 exportIncrementalXML methods
designing an OLAP, 1-5 description, 2-11
implementing, 1-5 exporting XML templates, 2-10, 4-11
objects corresponding to MDM objects, 2-2 Expression objects
star schema as a, 1-5 creating, 4-3
dimensioned Source example of, 4-9
definition, 5-12 extent of a Cursor
dimensions definition, 8-12
as dimensional data objects, 1-4 example of calculating, 9-13
creating, 4-2 use of, 8-12
dimensioning measures, 2-19 extract method, 5-12
MdmDimension classes, 2-19 description, 6-14
MdmDimension objects, 4-2 example of, 5-19, 6-14, 6-22, 6-23
member value formatting, 1-6 extraction input
metadata objects representing, 2-20 definition, 5-13
distinct method
description, 6-1
example of, 6-4
Index-3
Index
Index-4
Index
Index-5
Index
Index-6
Index
metadata O
creating, 4-1
creating a provider, 3-4 ojdbc6.jar file, A-2
discovering, 3-3 OLAP Java API
mapping, 4-1 description, 1-1
metadata model required class libraries, A-1
implementing, 1-5 sample schema for examples, 1-6
MDM, 2-2 software components, A-1
metadata objects uses of, 1-1, 1-8
classifying, 2-9 OLAP metadata, 1-5
creating OLAP, 1-5 OLAP metadata objects, 1-5
getting and setting names for, 2-4 OLAP views,
getting by ID, 2-10 description, 2-29
in example programs, 1-7 getting name of cube view, 2-29
OLAP, 1-5 getting name of dimension or hierarchy view,
renaming, 2-4 2-30
representing data sources, 2-15 populating attribute hierarchy lineage in, 2-27
restricting access to, 2-14 olap_api.jar file, A-2
supporting legacy, 2-4 Oracle OLAP
top-level, 2-14 database administration and management
unique identifiers of, 2-4 tasks related to, 1-1
metadata package Oracle Technology Network (OTN), 1-6
description, 1-2 ORACLE_HOME environment variable, A-2
subpackages, 2-2 OracleConnection objects
metadata reader modes, 2-5 creating, 3-2
MetadataObject interface OracleDataSource objects
implemented by MdmPrimaryDimension, creating, 3-2
2-20 outputs
MetadataState class, 10-3 getting from a CompoundCursor, example,
example of implementation, 10-8 9-3
movingTotal method getting from a
example of, 6-23 CompoundCursorSpecification,
multidimensional metadata objects example, 9-13
corresponding to dimensional data model getting nested, example, 9-4
objects, 2-2 in a CompoundCursor, 8-2, 8-12
corresponding to relational objects, 2-3 positions of, 8-8
multilingual attributes, 2-26 of a Source
multiple user sessions, 1-1 definition, 5-8
hiding, 5-11
obtaining, 5-8
N order of, 6-3
names producing, 5-8
getting and setting for metadata objects, 2-4 owner
namespaces of a BaseMetadataObject, 2-3
description, 2-5
nested outputs P
getting values from a Cursor with, example,
9-4 package attribute
of a Source, definition, 9-2 MdmAttribute for the PRODUCT_AWJ
null Source objects dimension, 2-23
definition, 5-2 packages
nullSource method, 5-2 in the OLAP Java API, 1-2
NumberParameter objects metadata, 2-2
example of, 6-24 Parameter objects
description, 5-19
Index-7
Index
Index-8
Index
Index-9
Index
target dimension U
of an attribute, 2-25
Template class, 10-3 unique dimension member values, 1-6
designing, 10-4 unique identifiers,
example of implementation, 10-5 of a Source, 5-5
Template objects of dimension members, 1-6
classes used to create, 10-2 of metadata objects, 2-4
for creating modifiable Source objects, 10-1 unique key attributes, 2-28
relationship of classes producing a dynamic UserSession objects
Source, 10-2 creating, 3-2
Transaction objects used in, 7-3 sharing connection, 1-1
templates
bind variables in XML, 2-12
exporting XML, 2-10, 4-11
V
importing XML, 2-11, 4-11 Value data type, 5-2
time series value method, 5-12
selecting based on, 6-22 description, 6-2
time span example of, 5-16, 6-6, 6-10, 6-11, 6-17
attribute, 2-24 value separation string, 1-6
of a time dimension, 2-20 value-based hierarchy, 2-23
times method ValueCursor objects
example of, 6-21 getting from a parent CompoundCursor,
top-level metadata objects example, 9-3
creating, 2-14 getting values from, example, 9-2, 9-3
defined, 2-9 position, 8-7
getting, 2-14 values
listed, 2-14 of a Cursor, 8-2, 8-7
TopBottomTemplate class, 7-4, 7-7, 10-5 of the elements of a Source, 5-3
Transaction objects views
child read and write, 7-2 materialized, 2-28
committing, 4-10, 7-2 OLAP, 2-29
creating a Cursor in the current, 8-2 virtual Cursor
current, 7-2 definition, 8-13
example of using child, 7-7 visible parameter
getting the current, 7-6 of a join method, 5-7
preparing, 7-2 void Source objects
read, 7-2 definition, 5-2
rolling back, 7-4
root, 7-1
setting the current, 7-6 W
using in Template classes, 7-3 write Transaction object, 7-2
write, 7-2
transaction package
description, 1-3 X
TransactionProvider
XML templates
provided by DataProvider, 7-6
bind variables in, 2-12
tuple
controlling attribute export, 2-11
definition, 2-18
exporting, 2-10, 4-11
in a Cursor, example, 9-5
importing, 2-11, 4-11
specifying a measure value, 8-8
XMLParserCallback interface, 2-10
type of an Source object
xmlparserv2.jar file, A-2
definition, 5-4
XMLWriterCallback interface, 2-11
obtaining, 5-4
Index-10