Oracle® OLAP Developer's Guide to the OLAP API 10g Release 1 (10.1) Part Number B10335-02 |
|
|
View PDF |
This chapter introduces 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. Chapter 7, " Making Queries Using Source Methods", provides examples of using Source
objects. Using Template
objects to make modifiable queries is discussed in Chapter 11, " Creating Dynamic Queries".
This chapter includes the following topics:
For the complete code for most of the examples in this chapter, see the example programs available from the Overview of the Oracle OLAP Java API Reference.
After you have used the classes in the oracle.olapi.metadata.mdm
package to get MdmSource
objects that represent measures and dimensions in the OLAP Catalog, you can get Source
objects from them. You can also create other Source
objects with methods of a DataProvider
. You can then use the Source
objects to create a query to get dimension or measure values from the database. To retrieve data from the database, you use a Source
to create a Cursor
.
With the methods of a Source
, you can specify selections of dimension or measure values and 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 primary methods and many shortcut methods that use one or more of the primary methods. The most complex primary methods are the join(Source joined, Source comparison, int comparisonRule, boolean visible)
method and the recursiveJoin(Source joined, Source comparison, 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 primary 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 select elements of a Source
and, most importantly, you can relate the elements of one Source
to those of another Source
. For example, to specify the dimension elements that a measure requires, you use a join
method to relate the dimension to the measure.
A Source
has certain characteristics, such as a type and a data type, and it sometimes has 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, the join
method and other Source
methods, and how you use those methods to specify a query.
The kinds of Source
objects that you use to specify data and to perform analysis, and the ways that you get them, are the following:
Primary Source
objects, which are returned by the getSource
method of an MdmSource
object such as an MdmDimension
or an MdmMeasure
. A primary Source
provides access to the data that the MdmSource
represents. Getting primary Source
objects is usually the first step in creating a query. You then typically select elements from the primary Source
objects, thus producing derived Source
objects in the process.
Derived Source
objects, which you get by calling methods on a Source
object. Methods such as join
return a new Source
that is based on the Source
on which you call the method. All queries on the data store, other than a simple list of values specified by the primary Source
for an MdmSubdimension
, such as an MdmLevelHierarchy
or an MdmLevel
, are derived Source
objects.
Fundamental Source
objects, which are returned by the getSource
method of a FundamentalMetadataObject
. These Source
objects represent the OLAP API data types.
List or range Source
objects that you get by calling the createConstantSource
, createListSource
or createRangeSource
methods of a DataProvider
. Typically, you use this kind of Source
as the joined
or comparison
parameter to the join
method.
Dynamic Source
objects, which are returned by the getSource
method of a DynamicDefinition
. A dynamic Source
is usually a derived Source
. It is generated by a Template
, which you use to create a dynamic query that you can revise after interacting with an end user.
Parameterized Source
objects, which are returned by the createParameterizedSource
methods of a DataProvider
. Like a list or range Source
, you use a parameterized Source
as a parameter to the join
method. Unlike a list or range Source
, however, you can change the value that the Parameter
represents after the join operation and thereby change the selection that the derived Source
represents. You can create a Cursor
for that derived Source
and retrieve the results of the query. You can then change the value of the Parameter
, and, without having to create a new Cursor
for 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
.
A Source
has a data type and a type, a Source
identification (ID), and a SourceDefinition
. This topic describes these concepts. Some Source
objects have one or more inputs or outputs. Those complex concepts are discussed in the "Inputs and Outputs of a Source" topic.
As described in Chapter 2, " Understanding OLAP API Metadata", the OLAP API has a class, FundamentalMetadataObject
, that represents the data type of the elements of an MdmSource
. The data type of a Source
is represented by a fundamental Source
. For example, a BooleanSource
has elements that have Java boolean
values. The data type of a BooleanSource
is the fundamental Source
that represents OLAP API Boolean values.
To get the fundamental Source
that represents the data type of a Source
, call the getDataType
method of the Source
. You can also get a fundamental Source
by calling the getSource
method of a FundamentalMetadataObject
.
Example 6-1 demonstrates getting the fundamental Source
for the OLAP API String data type, the Source
for the data type of an MdmPrimaryDimension
, and the Source
for the data type of the Source
for the MdmPrimaryDimension
, and comparing them to verify that they are all the same object. In the example, dp
is the DataProvider
and mdmProdDim
is the MdmPrimaryDimension
for the PRODUCT
dimension.
Example 6-1 Getting the Data Type of a Source
FundamentalMetadataProvider fmp = dp.getFundamentalMetadataProvider(); FundamentalMetadataObject fmoStringDataType = fmp.getStringDataType(); Source stringDataTypeSource = fmoStringDataType.getSource(); FundamentalMetadataObject fmoMdmProdDimDataType = mdmProdDim.getDataType(); Source mdmProdDimDataTypeSource = fmoMdmProdDimDataType.getSource(); Source prodDim = mdmProdDim.getSource(); Source prodDimDataTypeSource = prodDim.getDataType(); if(stringDataTypeSource == prodDimDataTypeSource && mdmProdDimDataTypeSource == prodDimDataTypeSource) System.out.println("The Source objects for the data types are all the same."); else System.out.println("The Source objects for the data types are not " + "all the same.");
The example displays the following:
The Source objects for the data types are all the same.
Along with a data type, a Source
has a type, which is the Source
from which the elements of the Source
are drawn. The type of a Source
determines whether the join
method can match the Source
to an input of another Source
. The only Source
that does not have a type is the fundamental Source
for the OLAP API Value data type, which represents the set of all values, and from which all other Source
objects ultimately descend.
The type of a fundamental Source
is its data type. 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 type of a primary Source
is one of the following:
The fundamental Source
that represents the data type of the values of the elements of the primary Source
. For example, the Source
returned by getSource
method of a typical MdmMeasure
is the fundamental Source
that represents the set of all OLAP API number values.
The Source
for the MdmSource
of which the MdmSource
of the primary Source
is a component. For example, the type of the Source
returned by the getSource
method of an MdmLevelHierarchy
is the Source
for the MdmPrimaryDimension
of which the hierarchy is a component.
The type of a derived Source
is one of the following:
Its base Source
, which is the Source
whose method returned the derived Source
. A Source
returned by the alias
, extract
, join
, recursiveJoin
, or value
methods, or one of their shortcuts, has its base Source
as its type. An exception is the derived Source
returned by the distinct
method, whose type is the type of its base Source
rather than the base Source
itself.
A fundamental Source
. Methods such as position
and count
return a Source
that has the fundamental Source
for the OLAP API Integer data type as its type. Methods that make comparisons, such as eq
, le
, and so on, return a Source
that has the fundamental Source
for the Boolean data type as its type. Methods that perform aggregate functions, such as the NumberSource
methods total
and average
, return as the type of the Source
a fundamental Source
that represents the function.
You can find the type of a Source
by calling its getType
method.
A Source
derived from another Source
is a subtype of the Source
from which it is derived. You can use the isSubtypeOf
method to determine if a Source
is a subtype of another Source
.
For example, in Example 6-2 the myList
object is a list Source
. The example uses myList
to select values from prodRollup
, a Source
for the default MdmLevelHierarchy
of the MdmPrimaryDimension
for the PRODUCT
dimension. In the example, dp
is the DataProvider
. Because prodSel
is a subtype of prodRollup
, the condition in the if
statement is true.
Example 6-2 Using the isSubtypeOf Method
Source myList = dp.createListSource(new String[] { "PRODUCT_ROLLUP::FAMILY::4", "PRODUCT_ROLLUP::FAMILY::5", "PRODUCT_ROLLUP::FAMILY::7", "PRODUCT_ROLLUP::FAMILY::8"}); Source prodSel = prodRollup.selectValues(myList); if (prodSel.isSubtypeOf(prodRollup)) System.out.println("prodSel is a subtype of prodRollup."); else System.out.println("prodSel is not a subtype of prodRollup.");
The type of both myList
and prodRollup
is the fundamental String Source
. The type of prodSel
is prodRollup
because the elements of prodSel
are derived from the elements of prodRollup
.
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 prodRollup
, 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 prodRollup
, and of the fundamental String Source
, and of the fundamental Value Source
.
A Source
has an identification, an ID, which is a String
that uniquely identifies it during the current connection to the database. You can get the identification of a Source
by calling its getID
method. For example, the following code gets the identification of the Source
for the MdmPrimaryDimension
for the PRODUCT
dimension and displays the value.
System.out.println("The Source ID of prodDim is " + prodDim.getID());
The preceding code displays the following:
The Source ID of prodDim is Hidden..D_GLOBAL.PRODUCT
The text displayed by Example 6-9 has several examples of source identifications.
Each Source
has a SourceDefinition
object, which records information about the Source
. The different kinds of Source
objects have different kinds of SourceDefinition
objects. For example, the fundamental Source
for an MdmPrimaryDimension
has an MdmSourceDefinition
, which is a subclass of HiddenDefinition
, which is a subclass of SourceDefinition
.
The SourceDefinition
of a Source
that is produced by a call to the join
method is an instance of the JoinDefinition
class. From a JoinDefinition
you can get information about the parameters of the join operation that produced its Source
, such as the base Source
, the joined Source
, the comparison Source
, the comparison rule, and the value of the visible
parameter.
The inputs and the outputs of a Source
are complex and powerful aspects of the class. This section describes the concepts of inputs and outputs and provides examples of how they are related.
An input of a Source
is also a Source
. An input indicates that the values of the Source
with the input depend upon an unspecified set of values of the input. A Source
that matches to the input provides the values that the input requires. You match an input to a Source
by using the join
method. For information on how to match a Source
to an input, see "Matching a Source To an Input".
Certain Source
objects always have one or more inputs. They are the Source
objects for MdmDimensionedObject
subclasses MdmMeasure
and MdmAttribute
. They have inputs because the values of the measure or attribute are specified by the values of their dimensions. The inputs of the Source
for the measure or attribute are the Source
objects for the dimensions of the measure or the attribute. Before you can retrieve the data for a measure or an attribute, you must match each input to a Source
that provides the required values.
Some Source
methods produce a Source
that has an input. You can produce a Source
that has an input by using the extract
, position
, or value
methods. These methods provide a means of producing a Source
whose elements are a subset of the elements of another Source
. A Source
produced by one of these methods has its base Source
as an input.
For example, in the following code, the base Source
is prodRollup
. Its value
method produces prodRollupValues
, which has prodRollup
as an input.
Source prodRollupValues = prodRollup.value();
The input provides the means to select values from prodRollup
, as demonstrated by Example 6-2. The selectValues
method in Example 6-2 is a shortcut for the following join
method.
Source prodSel = prodRollup.join(prodRollup.value(), myList, Source.COMPARISON_RULE_SELECT, false);
The parameters of the join
method specify the elements of the base Source
that appear in the resulting Source
. In the example, the joined
parameter is the Source
produced by the prodRollup.value()
method. The resulting unnamed Source
has prodRollup
as an input. The input is matched by the base of the join
method, which is also prodRollup
. The result of the join operation, prodSel
, has the values of prodRollup
that match the values of prodRollup
that are in the comparison Source
, myList
.
If the joined Source
were prodRollup
and not the Source
produced by prodRollup.value()
, then the comparison would be between the Source
object itself and the values of the comparison Source
and not between the values of the Source
and the values of the comparison Source
. Because the joined Source
object does not match any of the values of the comparison Source
, the result of the join
method would have all of the elements of prodRollup
instead of having only the values of prodRollup
that are specified by the values of the joined Source
that match the values of the comparison Source
as specified by the comparison rule.
The input of a Source
produced by the position
or value
method, and an input intrinsic to an MdmDimensionedObject
, are regular inputs. A regular input causes the join
method, when it matches a Source
to the input, to compare the values of the comparison Source
to the values of the Source
that has the input rather than to the input Source
itself.
The input of a Source
produced by the extract
method is an extraction input. An extraction input differs from a regular input in that, when a value of the Source
that has the extraction input is a Source
, the join
method extracts the values of the Source
that is a value of the Source
that has the input. The join
method then compares the values of the comparison Source
to the extracted values rather than to the Source
itself.
A Source
can have from zero to many inputs. You can get all of the inputs of a Source
by calling its getInputs
method, the regular inputs by calling its getRegularInputs
method, and its extraction inputs by calling its getExtractionInputs
method. Each of those methods returns a Set
of Source
objects.
The join
method returns a Source
that has the elements of its base Source
that are specified by the parameters of the method. If the value of the visible
parameter is true
, then the joined Source
becomes an output of the returned Source
. An output of a Source
returned by the join
method has the elements of the joined Source
that specify the elements of the returned Source
. An output is a means of identifying the elements of the joined Source
that specify the elements of the Source
that has the output.
A Source
can have from zero to many outputs. You can get the outputs of a Source
by calling its getOutputs
method, which returns a List
of Source
objects.
A Source
with more than one output has one or more elements for each set of the elements of the outputs. For example, a Source
that represents a measure that has had all of its inputs matched, and has had the Source
objects that match the inputs turned into outputs, has a single type element for each set of the elements of its outputs because each data value of the measure is identified by a unique set of the values of its dimensions. A Source
that represents dimension values that are selected by some operation performed on the data of a measure, however, might have more than one element for each set of the elements of its outputs. An example is a Source
that represents product values that have unit costs greater than a certain amount. Such a Source
might have several products for each time period that have a unit cost greater than the specified amount.
Example 6-3 produces a selection of the elements of shipRollup
, which is a Source
for a hierarchy of a dimension of customer values. The customers are grouped by a shipment origination and destination hierarchy.
Example 6-3 Using the join Method To Produce a Source Without an Output
Source custValuesToSelect = dp.createListSource(new String[] {"SHIPMENTS_ROLLUP::REGION::9", "SHIPMENTS_ROLLUP::REGION::10"}); Source shipRollupValues = shipRollup.value(); Source custSel = shipRollup.join(shipRollupValues, custValuesToSelect, Source.COMPARISON_RULE_SELECT, false);
The shipRollupValues
Source
has an input of shipRollup
. In the join
method in the example, the base Source
, shipRollup
, matches the input of the joined Source
, shipRollupValues
because the base and the input are the same object. The join
method selects the elements of the base shipRollup
whose values match the values of the joined shipRollup
that are specified by the comparison Source
, custValuesToSelect
. The method produces a Source
, custSel
, that has only the selected elements of shipRollup
. Because the visible
parameter is false
, the joined Source
is not an output of custSel
. The custSel
Source
therefore has only two elements, the values of which are SHIPMENTS_ROLLUP::REGION::9
and SHIPMENTS_ROLLUP::REGION::10
.
You produce a Source
that has an output by specifying true
as the visible
parameter to the join
method. Example 6-4 joins the Source
objects for the dimension selections from Example 6-2 and Example 6-3 to produce a Source
, custSelByProdSel
, that has one output. The custSelByProdSel
Source
has the elements from custSel
that are specified by the elements of prodSel
.
The comparison Source
is an empty Source
, which has no elements and which is the result of the getEmptySource
method of the DataProvider
, dp
. The comparison rule value, COMPARISON_RULE_REMOVE
, selects only the elements of prodSel
that are not in the comparison Source
. Because the comparison Source
has no elements, all of the elements of the joined Source
are selected. Each of the elements of the joined Source
specify all of the elements of the base Source
. The resulting Source
, custSelByProdSel
, therefore has all of the elements of custSel
.
Because the visible
parameter is true
in Example 6-4, prodSel
is an output of custSelByProdSel
. Therefore, for each element of the output, custSelByProdSel
has the elements of custSel
that are specified by that element of the output. Because the custSel
and prodSel
are both simple lists of dimension values, the result is the cross product of the elements of both Source
objects.
Example 6-4 Using the join Method To Produce a Source With an Output
Source custSelByProdSel = custSel.join(prodSel, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true);
To actually retrieve the data specified by custSelByProdSel
, you must create a Cursor
for it. Such a Cursor
contains the values shown in the following table, which has headings added that indicate that the values from the output, prodSel
, are in the left column and the values from the elements of the custSelByProdSel
Source
, which are derived from its type, custSel
, are in the right column.
Output Values Type Values ------------------------- ---------------------------- PRODUCT_ROLLUP::FAMILY::4 SHIPMENTS_ROLLUP::REGION::10 PRODUCT_ROLLUP::FAMILY::4 SHIPMENTS_ROLLUP::REGION::9 PRODUCT_ROLLUP::FAMILY::5 SHIPMENTS_ROLLUP::REGION::10 PRODUCT_ROLLUP::FAMILY::5 SHIPMENTS_ROLLUP::REGION::9 PRODUCT_ROLLUP::FAMILY::7 SHIPMENTS_ROLLUP::REGION::10 PRODUCT_ROLLUP::FAMILY::7 SHIPMENTS_ROLLUP::REGION::9 PRODUCT_ROLLUP::FAMILY::8 SHIPMENTS_ROLLUP::REGION::10 PRODUCT_ROLLUP::FAMILY::8 SHIPMENTS_ROLLUP::REGION::9
The custSelByProdSel
Source
has two type elements, and its output has four elements. The number of elements of custSelByProdSel
is eight because for this Source
, each output element specifies the same set of two type elements.
Each join operation that specifies a visible
parameter of true
adds an output to the list of outputs of the resulting Source
. For example, if a Source
has two outputs and you call one of its join
methods that produces an output, then the Source
that results from the join operation has three outputs. You can get the outputs of a Source
by calling its getOutputs
method, which returns a List
of Source
objects.
Example 6-5 demonstrates joining a measure to selections from the dimensions of the measure, thus matching to the inputs of the measure Source
objects that provide the required elements. Because the last two join
methods match the dimension selections to the inputs of the measure, the resulting Source
does not have any inputs. Because the visible
parameter in those joins is true
, the last join
method produces a Source
that has two outputs.
Example 6-5 gets the Source
for the measure of unit costs. That Source
, unitCost
, has two inputs, which are the primary Source
objects for the TIME
and PRODUCT
dimensions, which are the dimensions of unit cost. The example gets the Source
objects for level hierarchies of the dimensions, which are subtypes of the Source
objects for the dimensions. It produces selections of the level hierarchies and then joins those selections to the measure. The result, unitCostSel
, specifies the unit costs of the selected products at the selected times.
Example 6-5 Using the join Method To Match Source Objects To Inputs
Source unitCost = mdmUnitCost.getSource(); Source calendar = mdmCalendar.getSource(); Source prodRollup = mdmProdRollup.getSource(); Source timeSel = calendar.join(calendar.value(), dp.createListSource(new String[] {"CALENDAR::MONTH::47", "CALENDAR::MONTH::59"}), Source.COMPARISON_RULE_SELECT, false); Source prodSel = prodRollup.join(prodRollup.value(), dp.createListSource(new String[] {"PRODUCT_ROLLUP::ITEM::13", "PRODUCT_ROLLUP::ITEM::14", "PRODUCT_ROLLUP::ITEM::15"}), Source.COMPARISON_RULE_SELECT, false); Source unitCostSel = unitCost.join(timeSel, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true); .join(prodSel, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true);
The unnamed Source
that results from joining timeSel
to unitCost
has one output, which is timeSel
. Joining prodSel
to that unnamed Source
produces unitCostSel
, which has two outputs, timeSel
and prodSel
. The unitCostSel
Source
has the elements from its type, unitCost
, that are specified by its outputs.
A Cursor
for unitCostSel
contains the following, displayed as a table with headings added that indicate the structure of the Cursor
. A Cursor
has the same structure as its Source
. The unit cost values are formatted as dollar values.
Output 1 Output 2 Type Values Values Values ------------------------ ------------------- -------- PRODUCT_ROLLUP::ITEM::13 CALENDAR::MONTH::47 2897.40 PRODUCT_ROLLUP::ITEM::13 CALENDAR::MONTH::59 2376.73 PRODUCT_ROLLUP::ITEM::14 CALENDAR::MONTH::47 3238.36 PRODUCT_ROLLUP::ITEM::14 CALENDAR::MONTH::59 3015.90 PRODUCT_ROLLUP::ITEM::15 CALENDAR::MONTH::47 2847.47 PRODUCT_ROLLUP::ITEM::15 CALENDAR::MONTH::59 2819.85
Output 1 has the values from prodSel
, output 2 has the values from timeSel
, and the type values are the values from unitCost
that are specified by the output values.
Because these join operations are performed by most OLAP API applications, the API provides shortcuts for these and many other join operations. Example 6-6 uses shortcuts for the join operations in Example 6-5 to produce the same result.
Example 6-6 Using Shortcuts
Source unitCost = mdmUnitCost.getSource(); StringSource calendar = (StringSource) mdmCalendar.getSource(); StringSource prodRollup =(StringSource) mdmProdRollup.getSource(); Source timeSel = calendar.selectValues(new String[] {"CALENDAR::MONTH::47", "CALENDAR::MONTH::59"}), Source prodSel = prodRollup.selectValues(new String[] {"PRODUCT_ROLLUP::ITEM::13", "PRODUCT_ROLLUP::ITEM::14", "PRODUCT_ROLLUP::ITEM::15"}), Source unitCostSel = unitCost.join(timeSel).join(prodSel);
In a join operation, a Source
-to-input match occurs only between the base Source
and the joined Source
. A Source
matches an input if one of the following conditions is true.
The Source
is the same object as the input or it is a subtype of the input.
The Source
has an output that is the same object as the input or the output is a subtype of the input.
The output has an output that is the same object as the input or is a subtype of the input.
The join operation looks for the conditions in the order in the preceding list. It searches the list of outputs of the Source
recursively, looking for a match to the input. The search ends with the first matching Source
. An input can match with only one Source
, and two inputs cannot match with the same Source
.
When a Source
matches an input, the result of the join
method has the elements of the base that match the elements specified by the parameters of the method. You can determine if a Source
matches another Source
, or an output of the other Source
, by passing the Source
to the findMatchFor
method of the other Source
.
When a Source
matches an input, the resulting Source
does not have that input. Matching a Source
to an input does not affect the outputs of the base Source
or the joined Source
. If a base Source
has an output that matches the input of the joined Source
, 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.
Example 6-7 demonstrates a base Source
matching the input of the joined Source
in a join operation. The example uses the position
method to produce a Source
that has an input, and then uses the join
method to match the base of the join operation to the input of the joined Source
.
Example 6-7 Matching the Base Source to an Input of the Joined Source
Source myList = dp.createListSource(new String[] "PRODUCT_ROLLUP::FAMILY::4", "PRODUCT_ROLLUP::FAMILY::5", "PRODUCT_ROLLUP::FAMILY::7", "PRODUCT_ROLLUP::FAMILY::8"}); Source pos = dp.createListSource(new int[] {2, 4}); Source myListPos = myList.position(); Source myListSel = myList.join(myListPos, pos, Source.COMPARISON_RULE_SELECT, false);
In Example 6-7, the position
method returns myListPos
, which has the elements of myList
and which has myList
as an input. The join
method matches the base myList
to the input of the joined Source
, myListPos
.
The comparison Source
, pos
, specifies the positions of the elements of myListPos
to match to the positions of the elements of myList
. The elements of the resulting Source
, myListSel
, are the elements of myList
whose positions match those specified by the parameters of the join
method.
A Cursor
for myListSel
has the following values.
PRODUCT_ROLLUP::FAMILY::5 PRODUCT_ROLLUP::FAMILY::8
If the visible
parameter in Example 6-7 were true
instead of false
, then the result would have elements from myList
and an output of myListPos
. A Cursor
for myListSel
in that case would have the following values, displayed as a table with headings added that indicate the output and type values.
Output Type Values Values ------ ------------------------- 2 PRODUCT_ROLLUP::FAMILY::5 4 PRODUCT_ROLLUP::FAMILY::8
Example 6-8 demonstrates matching outputs of the joined Source
to two inputs of the base Source
. In the example, units
is a Source
for an MdmMeasure
. It has as inputs the primary Source
objects for the TIME
, PRODUCT
, CUSTOMER
, and CHANNEL
dimensions.
The DataProvider
is dp
, and prodRollup
, shipRollup
, calendar
, and chanRollup
are the Source
objects for the default hierarchies of the PRODUCT
, CUSTOMER
, TIME
, and CHANNEL
dimensions, respectively. Those Source
objects are subtypes of the Source
objects for the dimensions that are the inputs of units
.
The join
method of prodRollup
in the first line of Example 6-8 results in prodSel
, which specifies selected product values. In that method, the joined Source
is the result of the value
method of prodRollup
. The joined Source
has the same elements as prodRollup
, and it has prodRollup
as an input. The comparison Source
is the list Source
that is the result of the createListSource
method of the DataProvider
.
The base Source
of the join
method, prodRollup
, matches the input of the joined Source
. Because prodRollup
is the input of the joined Source
, the Source
returned by the join
method has only the elements of the base, prodRollup
, that match the elements of the joined Source
that appear in the comparison Source
. Because the visible
parameter value is false
, the resulting Source
does not have the joined Source
as an output. The next three similar join operations in Example 6-8 result in selections for the other three dimensions.
The join
method of timeSel
has custSel
as the joined Source
. Its comparison Source
is the result of the getEmptySource
method, so it has no elements. The comparison rule specifies that the elements of the joined Source
that are present in the comparison Source
do not appear in the resulting Source
. Because the comparison Source
has no elements, all of the elements of the joined Source
are selected. The true
value for the visible
parameter causes the joined Source
to be an output of the Source
returned by the join
method. The returned Source
, custSelByTime
, has the selected elements of the customers dimension and has timeSel
as an output.
The join
method of prodSel
has custSelByTime
as the joined Source
. It produces prodByCustByTime
, which has the selected elements from the PRODUCT
dimension and has custSelByTime
as an output. Example 6-8 then joins the dimension selections to the units
Source
.
The dimension selections are subtypes of the Source
objects that are the inputs of units
, and therefore the selections match the inputs of units
. The input for the product dimension is matched by prodByCustByTime
because prodByCustByTime
is a subtype of prodSel
, which is a subtype of prodRollup
. The input for the customers dimension is matched by the custSelByTime
, which is the output of prodByCustByTime
.
The custSelByTime
Source
is a subtype of custSel
, which is a subtype of shipRollup
. The input for the times dimension is matched by timeSel
, which is the output of custSelByTime
. The timeSel
Source
is a subtype of calendar
.
Example 6-8 Matching an Input of the Base Source to an Output of the Joined Source
Source prodSel = prodRollup.join(prodRollup.value(), dp.createListSource(new String[] {"PRODUCT_ROLLUP::FAMILY::4", "PRODUCT_ROLLUP::FAMILY::5"}), Source.COMPARISON_RULE_SELECT, false); Source custSel = shipRollup.join(shipRollup.value(), dp.createListSource(new String[] {"SHIPMENTS_ROLLUP::REGION::9", "SHIPMENTS_ROLLUP::REGION::10"}), Source.COMPARISON_RULE_SELECT, false); Source timeSel = calendar.join( calendar.value(), dp.createConstantSource( "CALENDAR::YEAR::4"), Source.COMPARISON_RULE_SELECT, false); Source chanSel = chanRollup.join(chanRollup.value(), dp.createConstantSource( "CHANNEL_ROLLUP::CHANNEL::4"), Source.COMPARISON_RULE_SELECT, false); Source custSelByTime = custSel.join(timeSel, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true); Source prodByCustByTime = prodSel.join(custSelByTime, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true); Source selectedUnits = units.join(prodByCustByTime, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true) .join(promoSel, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true ), .join(chanSel, dp.getEmptySource(), Source.COMPARISON_RULE_REMOVE, true);
A Cursor
for selectedUnits
contains the following values, displayed in a crosstab format with column headings and formatting added. The table has only the local values of the dimension elements. The first two lines are the page edge values of the crosstab, which are the values of the chanSel
output of selectedUnits
, and the value of timeSel
, which is an output of the prodByCustByTime
output of selectedUnits
. The row edge values of the crosstab are the customer values in the left column, and the column edge values are the products values that head the middle and right columns.
The crosstab has only the local value portion of the unique values of the dimension elements. The measure values are the units sold values specified by the selected dimension values.
4 4 Products ---------- Customers 4 5 --------- --- ---- 10 846 1748 9 215 439
The following table has the same results except that the dimension element values are replaced by the short descriptions of those values.
Internet 2001 Products ------------------------- Customers Portable PCs Desktop PCs ------------- ------------ ----------- North America 846 1748 Europe 215 439
To demonstrate turning inputs into outputs, Example 6-9 uses units
, which is the Source
for the UNITS
measure, and defaultHiers
, which is an ArrayList
of the Source
objects for the default hierarchies of the dimensions of the measure. The example gets the inputs and outputs of the Source
for the measure. It displays the Source
identifications of the Source
for the measure and for its inputs. The inputs of the Source
for the measure are the Source
objects for the MdmPrimaryDimension
objects that are the dimensions of the measure.
Example 6-9 next displays the number of inputs and outputs of the Source
for the measure. Using the join(Source joined)
method, which produces a Source
that has the elements of the base of the join operation as its elements and the joined
parameter Source
as an output, it joins one of the hierarchy Source
objects to the Source
for the measure, and displays the number of inputs and outputs of the resulting Source
. It then joins each remaining hierarchy Source
to the result of the previous join operation and displays the number of inputs and outputs of the resulting Source
.
Finally the example gets the outputs of the Source
produced by the last join operation, and displays the Source
identifications of the outputs. The outputs of the last Source
are the Source
objects for the default hierarchies, which the example joined to the Source
for the measure. Because the Source
objects for the hierarchies are subtypes of the Source
objects for the MdmPrimaryDimension
objects that are the inputs of the measure, they match those inputs.
Example 6-9 Matching the Inputs of a Measure and Producing Outputs
Set inputs = units.getInputs(); Iterator inputsItr = inputs.iterator(); List outputs = units.getOutputs(); Source input = null; int i = 1; System.out.println("The inputs of " + units.getID() + " are:"); while(inputsItr.hasNext()) { input = (Source) inputsItr.next(); System.out.println(i + ": " + input.getID()); i++; } System.out.println(" "); int setSize = inputs.size(); for(i = 0; i < (setSize + 1); i++) { System.out.println(units.getID() + " has " + inputs.size() + " inputs and " + outputs.size() + " outputs."); if (i < setSize) { input = defaultHiers.get(i); System.out.println("Joining " + input.getID() + " to " + units.getID()); units = units.join(input); inputs = units.getInputs(); outputs = units.getOutputs(); } } System.out.println(" "); System.out.println("The outputs of " + units.getID() + " are:"); Iterator outputsItr = outputs.iterator(); i = 1; while(outputsItr.hasNext()) { Source output = (Source) outputsItr.next(); System.out.println(i + ": " + output.getID()); i++; }
The text displayed by the example is the following:
The inputs of Hidden..M_GLOBAL.UNITS_CUBE.UNITS are: 1: Hidden..D_GLOBAL.TIME 2: Hidden..D_GLOBAL.PRODUCT 3: Hidden..D_GLOBAL.CUSTOMER 4: Hidden..D_GLOBAL.CHANNEL Hidden..M_GLOBAL.UNITS_CUBE.UNITS has 4 inputs and 0 outputs. Joining Hidden..D_GLOBAL.PRODUCT.PRODUCT_ROLLUP to Hidden..M_GLOBAL.UNITS_CUBE.UNITS Join.0 has 3 inputs and 1 outputs. Joining Hidden..D_GLOBAL.CUSTOMER.SHIPMENTS_ROLLUP to Join.0 Join.1 has 2 inputs and 2 outputs. Joining Hidden..D_GLOBAL.TIME.CALENDAR to Join.1 Join.2 has 1 inputs and 3 outputs. Joining Hidden..D_GLOBAL.CHANNEL.CHANNEL_ROLLUP to Join.2 Join.3 has 0 inputs and 5 outputs. The outputs of Join.3 are: 1: Hidden..D_GLOBAL.CHANNEL.CHANNEL_ROLLUP 2: Hidden..D_GLOBAL.TIME.CALENDAR 3: Hidden..D_GLOBAL.CUSTOMER.SHIPMENTS_ROLLUP 4: Hidden..D_GLOBAL.PRODUCT.PRODUCT_ROLLUP
Note that as each successive Source
for a hierarchy is joined to the result of the previous join operation, it becomes the first output in the List
of outputs of the resulting Source
. Therefore, the first output of Join.3
is Hidden..D_GLOBAL.CHANNEL.CHANNEL_ROLLUP
, and its last output is Hidden..D_GLOBAL.PRODUCT.PRODUCT_ROLLUP
.
Parameterized Source
objects provide a way of specifying a query and retrieving different result sets for the query by changing the set of elements specified by the parameterized Source
. You create a parameterized Source
with a createParameterizedSource
method of the DataProvider
you are using. In creating the parameterized Source
, you supply a Parameter
object. The Parameter
supplies the value that the parameterized Source
specifies.
Parameter
objects are similar to CursorInput
objects in that you use them to specify an initial value for a Source
that is part of a query. A typical use of both Parameter
and CursorInput
objects is to specify the page edges of a cube. Example 7-9 demonstrates using Parameter
objects to specify page edges.
An advantage of Parameter
objects over CursorInput
objects is that with Parameter
objects you can easily fetch from the server only the set of elements that you currently need. Example 7-16 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 its setValue
method, which changes the set of elements that the query specifies. Using the same Cursor
, you can then display the new set of values.
Example 6-10 demonstrates the use of a Parameter
and a parameterized Source
to specify an element in a measure dimension. It creates a list Source
that has as its element values the Source
objects for unit cost and unit price measures. The example creates a StringParameter
object that has as its initial value the unique identifying String
for the Source
for the unit cost measure. That StringParameter
is then used to create a parameterized Source
.
The example extracts the values from the measures, and then selects the data values that are specified by joining the dimension selections to the measure specified by the parameterized Source
. It creates a Cursor
for the resulting query and displays the results. After resetting the Cursor
position and changing the value of the measParam
StringParameter
, the example displays the values of the Cursor
again.
The dp
object is the DataProvider
. The context
object has a method that displays the values of the Cursor
with only the local value of the dimension elements.
Example 6-10 Using a Parameterized Source With a Measure Dimension
Source measDim = dp.createListSource(new Source[] {unitCost, unitPrice}); // Get the unique identifiers of the Source objects for the measures. String unitCostID = unitCost.getID(); String unitPriceID = unitPrice.getID(); // Create a StringParameter using one of the IDs as the initial value. StringParameter measParam = new StringParameter(dp, unitCostID); // Create a parameterized Source. StringSource measParamSrc = dp.createParameterizedSource(measParam); // Extract the values from the measure dimension elements, and join // them to the specified measure and the dimension selections. Source result = measDim.extract().join(measDim, measParamSrc) .join(prodSelShortDescr) .join(timeSelShortDescr); // Get the TransactionProvider and prepare and commit the // current transaction. These operations are not shown. // Create a Cursor. CursorManagerSpecification cMngrSpec = dp.createCursorManagerSpecification(results); SpecifiedCursorManager spCMngr = dp.createCursorManager(cMngrSpec); Cursor resultsCursor = spCMngr.createCursor(); // Display the results. context.displayCursor(resultsCursor, true); //Reset the Cursor position to 1. resultsCursor.setPosition(1); // Change the value of the parameterized Source. measParam.setValue(unitPriceID); // Display the results again. context.displayCursor(resultsCursor, true);
The following table displays the first set of values of resultsCursor
, with column headings and formatting added. The left column of the table has the local value of the TIME
dimension hierarchy. The second column from the left has the short value description of the time value. The third column has the local value of the PRODUCT
dimension hierarchy. The fourth column has the short value description of the product value. The fifth column has the UNIT COST
measure value for the time and product.
Time Description Product Description Unit Cost ---- ----------- ------- --------------- --------- 58 Apr-01 13 Envoy Standard 2360.78 58 Apr-01 14 Envoy Executive 2952.85 59 May-01 13 Envoy Standard 2376.73 59 May-01 14 Envoy Executive 3015.90
The following table displays the second set of values of resultsCursor
in the same format. This time the fifth column has values from the UNIT PRICE
measure.
Time Description Product Description Unit Price ---- ----------- ------- --------------- ---------- 58 Apr-01 13 Envoy Standard 2412.42 58 Apr-01 14 Envoy Executive 3107.65 59 May-01 13 Envoy Standard 2395.63 59 May-01 14 Envoy Executive 3147.85