Oracle® OLAP Java API Reference
10g Release 1 (10.1)    B10994-01


Source Concepts and Examples

This document has the following topics.

Complete code for the examples that appear in this document are in the file SourceConceptsExamples.java.

Type of a Source

A Source has a type, which is the Source from which the values 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 type of the Source returned by the getSource method of a typical MdmMeasure is the fundamental Number Source, which represents the set of all OLAP API number values. The type of the Source returned by the getSource method on a MdmLevelHierarchy is the Source for the MdmPrimaryDimension of which it is a component. The only Source that does not have a type is the fundamental Value Source, which represents the set of all values, from which all other Source objects ultimately descend.

The type of a derived Source is one of the following.

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. You can find the type of a Source by calling its getType method.

A Source based on another Source is a subtype of the Source on which it is based. You can use the isSubtypeOf method to determine if a Source is a subtype of another Source. Example 1 creates myList, a list Source, and then uses it to select values from prodHier, a Source that specifies the default hierarchy of a dimension of product values. In the example, dp is the DataProvider. Because prodSel is a subtype of prodHier, the condition in the if statement is true.

Example 1 - Using the isSubtypeOf() Method

Source myList = dp.createListSource(new String[] {
                                   "PRODUCT_ROLLUP::FAMILY::4", // Portable PCs
                                   "PRODUCT_ROLLUP::FAMILY::5", // Desktop PCs
                                   "PRODUCT_ROLLUP::FAMILY::7", // Accessories
                                   "PRODUCT_ROLLUP::FAMILY::8""}); // Monitors

Source prodSel = prodHier.selectValues(myList);
if (prodSel.isSubtypeOf(prodHier))
  System.out.println("prodSel is a subtype of prodHier.");
else
  System.out.println("prodSel is not a subtype of prodHier.");

The type of both myList and prodHier is the fundamental String Source. 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.

Data Type of a Source

A Source also has a data type, which is the fundamental Source that represents the data type of the values of the Source. The data type of a Source is sometimes the same as its type. For example, the data type of myList and prodHier is the fundamental String Source, which is also their type. The data type of prodSel is the fundamental String Source, but its type is prodHier. You can find the data type of a Source by calling its getDataType method.

Inputs of a Source

A typical analytic query specifies data from a measure. Each data value in the measure is uniquely identified by a set of the values of the dimensions of the measure. To identify the dimensions that specify its values, a Source for an MdmMeasure has inputs, which are the Source objects for the dimensions of the measure.

Before you can create a Cursor to retrieve data from a measure, you must specify the elements of the input dimension that identify the data that you want. You specify elements for the input by matching to the input a Source that has the elements required by the input. You match a Source to an input by using the join method to join the Source with the input to a Source that has the elements the input requires. The Source that results from that join operation specifies elements for the input, and therefore the input is not an input of that resulting Source. (For information on matching a Source to an input, see Matching a Source To an Input.)

An MdmAttribute also has a dimension as an input. The MdmAttribute and MdmMeasure classes are subclasses of MdmDimensionedObject. Along with indicating the dependency of a Source for an MdmMeasure or an MdmAttibute upon the elements of its dimensions and providing a way to specify the desired elements of the measure by matching the inputs to the required Source objects for the dimensions, inputs provide the most important means of producing a Source whose elements are a subset of the elements of another Source. The position, extract, and value methods of this class each produces a Source that has the elements of the base Source and that also has that base Source as an input.

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 elements of the comparison parameter Source to the values of the elements 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 an element of the Source that has the extraction input is a Source, the join method extracts the values of the elements of the Source that is a value of the Source that has the input. The join method then compares the values of the elements of the comparison Source to the extracted values rather than to the Source itself. For an example, see the extract() method.

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.

You can use the join method to match a base Source, or a subtype of the base, to the input of a Source derived by the extract, position, or value methods of the base. In the parameters of that join method, you can specify the elements of the base Source that you want to have in the resulting Source. For example, the selectValues method in Example 1 is a shortcut for the following join method.

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

In that join operation, the joined parameter is the Source produced by the prodHier.value() method. The resulting unnamed Source has prodHier as an input. The input is matched by the base of the join, which is also prodHier. The result of the join, prodSel, has the elements of prodHier that match the elements of prodHier that are in the comparison parameter Source, myList. If the joined Source was prodHier and not prodHier.value(), then the result of the join would have all of the elements of prodHier instead of having only the elements of prodHier that match the elements specified by the parameters of the join.

Outputs of a Source

The join method returns a Source that has the elements of its base Source that are specified by the parameters of the join. 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 2 produces a selection of the elements of a Source for a hierarchy of a dimension of customer values. The customers are grouped by a geographical hierarchy.

Example 2 - Using the join Method To Produce a Source Without an Output

Source custValuesToSelect = dp.createListSource(new String[]
                               "SHIPMENTS_ROLLUP::REGION::9", // North America
                               "SHIPMENTS_ROLLUP::REGION::10"}); // Europe
Source custHierValues = custHier.value();
Source custSel = custHier.join(custHierValues, custValuesToSelect,
                               Source.COMPARISON_RULE_SELECT, false);

The custHierValues Source has an input of custHier. In the join method in the example, the base Source, custHier, matches the input of the joined Source, custHierValues because the base and the input are the same object. The join method selects the elements of the base custHier whose values match the values of the joined parameter custHierValues that are specified by the comparison parameter Source, custValuesToSelect. The method produces a Source, custSel, that has only the selected elements of custHier. Because the visible parameter of the join 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 3 joins the Source objects for the dimension selections from Example 1 and Example 2 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 parameter Source is an empty Source, which has no elements and which is the result of the getEmptySource method of the DataProvider, dp. The comparisonRule parameter, COMPARISON_RULE_REMOVE, removes the elements of prodSel that are in the comparison Source from the elements of prodSel. Because the comparison Source has no elements, no elements are removed from the elements that the joined Source specifies. 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, 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 3 - Using the join Method To Produce a Source With an Output

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

Source custSelByProdSelDescr = custSelDescr.join(prodSelDescr,
                                            dp.getEmptySource(),
                                            Source.COMPARISON_RULE_REMOVE,
                                            true);

The values of the custSel and prodSel objects are numbers that identify the product family and the customer shipment region. To distinguish the output and type values more easily, this example also joins custSelDescr and prodSelDescr, which are objects that have the short descriptions for the product and customer selections. To actually retrieve the data specified by custSelByProdSel and custSelByProdSelDescr, you must create a Cursor for each of them. Such Cursor objects contain the values shown in the following tables, which have headings added that indicate that the values from the output are in the left column and the values of the Source, which are derived from its type, are in the right column.

Table 1 Output and Type Values of custSelByProdSel

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

Table 2 Output and Type Values of custSelByProdSelDescr

Output Values   Type Values
--------------  -------------
Portable PCs    North America
Portable PCs    Europe
Desktop PCs     North America
Desktop PCs     Europe
Accessories     North America
Accessories     Europe
Monitors        North America
Monitors        Europe

The custSelByProdSel and custSelByProdSelDescr Source objects each have two type elements, and each output has four elements. The number of elements of both custSelByProdSel and custSelByProdSelDescr is eight because for both Source objects, 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. If a Source has two outputs and you call a join method on it that produces an output, then the Source that results from the join has three outputs. You can get the outputs of a Source by calling its getOutputs method, which returns a List of Source objects.

Example 4 demonstrates joining a measure to selections from the dimensions of the measure, thus matching to the inputs of the measure some 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 produces a Source that has two outputs.

Example 4 gets the Source for the measure of unit costs. That Source, unitCost, has two inputs, which are the primary Source objects for times and products, which are the dimensions of unit cost. The example gets the Source objects for hierarchies of the dimensions, which are subtypes of the Source objects for the dimensions. It produces selections of the hierarchies and then joins those selections to the measure. The result, unitCostSel, specifies the unit costs of the selected products for the selected times.

Example 4 - Using the join Method To Match Source Objects To Inputs

Source unitCost = mdmUnitCost.getSource();
Source timeHier = mdmTimeHier.getSource();
Source prodHier = mdmProdHier.getSource();
Source timeSel = timeHier.join(timeHier.value(),
                               dp.createListSource(new String[]
                                    {"CALENDAR::MONTH::35",
                                     "CALENDAR::MONTH::45"}),
                               Source.COMPARISON_RULE_SELECT,
                               false);
Source prodSel = prodHier.join(prodHier.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.

Output 1 Values            Output 2 Values       Type Values
------------------------   -------------------   -----------
PRODUCT_ROLLUP::ITEM::13   CALENDAR::MONTH::35   3130.05
PRODUCT_ROLLUP::ITEM::13   CALENDAR::MONTH::45   2926.79
PRODUCT_ROLLUP::ITEM::14   CALENDAR::MONTH::35   3493.58
PRODUCT_ROLLUP::ITEM::14   CALENDAR::MONTH::45   3279.4
PRODUCT_ROLLUP::ITEM::15   CALENDAR::MONTH::35   3217.79
PRODUCT_ROLLUP::ITEM::15   CALENDAR::MONTH::45   2818.16

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 5 uses shortcuts for the join operations in Example 4 to produce the same result.

Example 5 - Using Shortcuts

Source unitCost = mdmUnitCost.getSource();
StringSource timeHier = (StringSource) mdmTimeHier.getSource();
StringSource prodHier =(StringSource) mdmProdHier.getSource();
Source timeSel = timeHier.selectValues(new String[] {
                                              "CALENDAR::MONTH::35",
                                              "CALENDAR::MONTH::45"});
Source prodSel = prodHier.selectValues(new String[] {
                                              "PRODUCT_ROLLUP::ITEM::13",
                                              "PRODUCT_ROLLUP::ITEM::14",
                                              "PRODUCT_ROLLUP::ITEM::15"});
Source unitCostSel = unitCost.join(timeSel).join(prodSel);

Matching a Source To an Input

The following describes how a Source matches an input.

A Source-to-input match in a join operation occurs only between the base Source and the joined Source. A Source matches an input if one of the following conditions is true.

The join operation looks for the conditions in the order listed above. 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 has the elements of the base that match the elements specified by the parameters of the join 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 on 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.

Unmatched Inputs

If the base Source or the joined Source in a join method call has an input that is not matched in the join, then the unmatched input is an input of the resulting Source.

The comparison parameter Source of a join does not participate in the input matching. If the comparison Source has an input, then that input is not matched and the Source that results from the join has that same input.

Example 6 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 to the input of the joined Source.

Example 6 - 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, 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.

A Cursor for myListSel has the following values.

PRODUCT_ROLLUP::FAMILY::5
PRODUCT_ROLLUP::FAMILY::8

If the visible parameter in Example 6 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 7 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 dimensions for times, products, customers, and sales channels.

The DataProvider is dp, and prodHier, custHier, timeHier, and chanHier are the Source objects for the default hierarchies of the products, customers, times, and channels dimensions, respectively. Those Source objects are subtypes of the Source objects for the dimensions that are the inputs of units.

The join operation in the first line of Example 7 results in prodSel, which specifies selected product values. In this first line, the joined Source is the result of the value method of prodHier. The joined Source has the same elements as prodHier, and it has prodHier 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, prodHier, matches the input of the joined parameter Source. Because prodHier is the input of the joined Source, the Source that results from the join has only the elements of the base, prodHier, 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 7 result in selections for the other three dimensions. The fifth join operation joins timeSel and custSel. In this join, the comparison Source is the result of the getEmptySource method, so it has no elements. The comparisonRule parameter specifies that the elements of the joined Source that are present in the comparison Source do not appear in the result of the join. Because the comparison Source has no elements, no elements are removed from the joined Source. The true value for the visible parameter causes the joined Source to be an output of the result of the join. The resulting Source, custSelByTime, has the selected elements of the customers dimension and has timeSel as an output.

The next join operation joins custSelByTime and prodSel and results in prodByCustByTime, which has the selected elements from the products dimension and has custSelByTime as an output. Example 7 then joins the dimension selections to the units Source.

The dimension selections are subtypes of the dimensions 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 prodHier. 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 custHier. The input for the times dimension is matched by timeSel, which is the output of custSelByTime. The timeSel Source is a subtype of the timesHier.

Example 7 - Matching an Input of the Base Source to an Output of the Joined Source

Source prodSel = prodHier.join(prodHier.value(),
                               dp.createListSource(new String[]
                                                 {"PRODUCT_ROLLUP::FAMILY::4",
                                                  "PRODUCT_ROLLUP::FAMILY::5"}),
                               Source.COMPARISON_RULE_SELECT, false);
Source custSel = custHier.join(custHier.value(),
                               dp.createListSource(new String[]
                                               {"SHIPMENTS_ROLLUP::REGION::9",
                                                "SHIPMENTS_ROLLUP::REGION::10"}),
                               Source.COMPARISON_RULE_SELECT, false);
Source timeSel = timeHier.join(timeHier.value(),
                               dp.createConstantSource(
                                                "CALENDAR::YEAR::4"),
                               Source.COMPARISON_RULE_SELECT, false);
Source chanSel = chanHier.join(chanHier.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(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 value portion of the unique value of the dimension elements. (For descriptions of unique and local values, see the Overview of this Oracle OLAP Java API Reference.)

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

<nobr>Copyright © 2002, 2003, Oracle.<wbr> All Rights Reserved.</nobr>