This chapter explains the procedure for discovering the metadata in a data store through the OLAP API.
This chapter includes the following topics:
For information on how to get the complete code for the examples in this chapter, see the topic "Sample Schema for OLAP API Examples" in Chapter 1.
The OLAP API provides access to the data of an analytic workspace. This collection of data is the data store for the application. The API also provides the ability to create custom metadata objects and to create queries that use the data to which the custom objects are mapped.
Potentially, the data store includes all of the measure folders that were created by the database administrator for the analytic workspace. However, the scope of the data store that is visible when an application is running depends on the database privileges that apply to the user ID through which the connection was made. A user sees all of the measure folders (as MdmSchema
objects) that the database administrator or the application created, but the user sees the measures and dimensions that are contained in those measure folders only if he or she has access rights to the relational tables to which the measures and dimensions are mapped.
When the database administrator defined the analytic workspace, the administrator created measures, dimensions, and other OLAP metadata objects by mapping them to columns in database tables or views. Oracle OLAP automatically maps the OLAP metadata objects to MDM objects. In the OLAP API, these objects are accessed as multidimensional metadata (MDM) objects, as described in Chapter 2, "Understanding OLAP API Metadata".
The metadata objects in the data store help your application to make sense of the data. They provide a way for you to find out what data is available, how it is structured, and what the characteristics of it are.
Therefore, after connecting, your first step is to find out what metadata is available. Armed with this knowledge, you can present choices to the end user about what data should be selected or calculated and how it should be displayed.
Before investigating the metadata, your application must make a connection to Oracle OLAP, as described in Chapter 3, "Connecting to a Data Store". Then, your application might perform the following steps:
Create an MdmMetadataProvider
.
Get the root MdmSchema
from the MdmMetadataProvider
.
Get the contents of the root MdmSchema
, which include MdmMeasure
, MdmDimension
, MdmMeasureDimension
, and MdmSchema
objects. In addition, get the contents of any subschemas.
Get the components or related objects of each MdmMeasure
and MdmDimension
. For example, get the MdmDimension
objects for each MdmMeasure
, and get the MdmHierarchy
objects for each MdmDimension
.
The next four topics in this chapter describe these steps in detail.
After your 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 MDM objects. These Source
objects are referred to as primary Source
objects. Source
objects specify the data for querying.
This chapter focuses on the initial step of discovering the available metadata, but it also briefly mentions the step of getting a primary Source
from a metadata object. Subsequent chapters of this guide explain how you work with primary Source
objects and create queries based on them.
An MdmMetadataProvider
gives access to the metadata in a data store. It provides OLAP metadata objects, such as measures, dimensions, and measure folders, as corresponding MDM objects, such as MdmMeasure
, MdmDimension
, and MdmSchema
objects.
Before you can create an MdmMetadataProvider
, you must create a DataProvider
as described in Chapter 3, "Connecting to a Data Store". Example 4-1 creates an MdmMetadataProvider
. In the example, dp
is an ExpressDataProvider
.
Getting the root MdmSchema
is the first step in exploring the metadata in your data store.
The metadata objects that are accessible through an MdmMetadataProvider
are organized in a tree-like structure, with the root MdmSchema
at the top. Under the root MdmSchema
are MdmPrimaryDimension
objects and one or more MdmSchema
objects, which are referred to as subschemas. In addition, if an MdmMeasure
object does not belong to any subschema, then it is included under the root.
Subschemas have their own MdmMeasure
and MdmPrimaryDimension
objects. Optionally, they can have their own subschemas as well.
The root MdmSchema
contains all of the MdmPrimaryDimension
objects that are in the subschemas. Therefore, an MdmPrimaryDimension
typically appears twice in the tree. It appears once under the root MdmSchema
and again under the subschema. If an MdmPrimaryDimension
does not belong to a subschema, then it is listed only under the root.
The starting point for discovering the available metadata objects is the root MdmSchema
, which is the top of the tree. The following diagram illustrates an MdmSchema
that has two subschemas and four MdmPrimaryDimension
objects.
In the OLAP Catalog, a database administrator arranges dimensions and measures under one or more top-level measure folders. When Oracle OLAP maps the measure folders to MdmSchema
objects, it always creates the root MdmSchema
over the MdmSchema
objects for the top-level measure folders. Therefore, even if the database administrator creates only one measure folder, the corresponding MdmSchema
is a subschema under the root.
For more information about MDM metadata objects and how they map to OLAP metadata objects, see Chapter 2, "Understanding OLAP API Metadata".
The root MdmSchema
contains MdmPrimaryDimension
objects, MdmSchema
objects, and possibly MdmMeasure
objects. In addition, the root MdmSchema
has an MdmMeasureDimension
that has a List
of all of the MdmMeasure
objects.
The following code gets a List
of the MdmPrimaryDimension
objects that are in rootSchema
, which is the root MdmSchema
. The List
does not include the MdmMeasureDimension
.
The following code gets a List
of MdmSchema
objects that are in rootSchema
.
For each MdmSchema
that is under the root MdmSchema
, you can call the getMeasures
, getDimensions
, and getSubSchemas
methods of the subschema. The procedures are the same as those for getting the contents of the root MdmSchema
.
Example 4-5 gets the MdmMeasureDimension
that is in the root MdmSchema
. Use this method only on the root MdmSchema
, because only the root MdmSchema
has the MdmMeasureDimension
. The example displays the names of the MdmMeasure
objects that are contained by the MdmMeasureDimension
.
Example 4-5 Getting the MdmMeasureDimension
MdmMeasureDimension mdmMeasureDim = (MdmMeasureDimension) rootSchema.getMeasureDimension(); List mdmMeasureDimMeasures = mdmMeasureDim.getMeasures(); Iterator mdmMeasureDimMeasuresItr = mdmMeasureDimMeasures.iterator(); MdmMeasure measure = null; println("The measures in the MdmMeasureDimension are:"); while (mdmMeasureDimMeasuresItr.hasNext()) { measure = (MdmMeasure) mdmMeasureDimMeasuresItr.next(); println("\t" + measure.getName()); }
Having discovered the list of MdmMeasure
and MdmDimension
objects, the next step in metadata discovery involves finding out the characteristics of those objects.
A primary characteristic of an MdmMeasure
is that it has related MdmPrimaryDimension
objects. Example 4-6 gets a List
of MdmPrimaryDimension
objects for mdmUnits
, which is an MdmMeasure
.
Example 4-6 Getting the Dimensions of an MdmMeasure
List dimsOfUnits = mdmUnits.getDimensions();
The getMeasureInfo
method, which is in the Example 4-9, shows one way to iterate through the MdmPrimaryDimension
objects belonging to an MdmMeasure
.
An MdmPrimaryDimension
has one or more component MdmHierarchy
objects, which you can obtain by calling the getHierarchies
method of the dimension. That method returns a List
of MdmHierarchy
objects. If an MdmHierarchy
is an MdmLevelHierarchy
, then it has levels that you can obtain by calling the getLevels
method of the MdmLevelHierarchy
.
Example 4-7 demonstrates how you can get the MdmHierarchy
objects for an MdmPrimaryDimension
. The example displays the names of the MdmHierarchy
objects.
Example 4-7 Getting the MdmHierarchy Components of an MdmPrimaryDimenison
List mdmHiers = mdmPrimaryDim.getHierarchies(); Iterator mdmHiersItr = mdmHiers.iterator(); println("The MdmHierarchy components of " + mdmPrimaryDim.getName() + " are:"); while (mdmHiersItr.hasNext()) { MdmHierarchy mdmHier = (MdmHierarchy) mdmHiersItr.next(); println("\t" + mdmHier.getName()); }
The getDimInfo
method in Example 4-9 shows one way to get the following metadata objects for an MdmDimension
.
The concrete class.
The MdmHierarchy
objects.
The default MdmHierarchy
object.
The MdmAttribute
objects returned by the getAttributes
method.
Methods are also available for obtaining other MdmPrimaryDimension
characteristics. See the Oracle OLAP Java API Reference for descriptions of all of the methods of the MDM classes.
A metadata object represents a set of data, but it does not provide the ability to create queries on that data. The object is informational. It records the existence, structure, and characteristics of the data. It does not give access to the data values.
To access the data values for a metadata object, an application gets the Source
object for that metadata object. A Source
for a metadata object is called a primary Source
.
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.
Example 4-8 Getting a Primary Source for a Metadata Object
Source units = mdmUnits.getSource();
For more information about getting and working with primary Source
objects, see Chapter 5, "Understanding Source Objects".
The sample code that follows is a simple Java program called SampleMetadataDiscoverer10g
. The program discovers the metadata objects that are associated with the GLOBALAW_SCHEMA
subschema under the root MdmSchema
for the GLOBALAW
analytic workspace. After presenting the program code, this topic presents the output of the program. The output lists the names and related objects for the MdmMeasure
and MdmDimension
objects in the MdmSchema
object for the subschema.
The program in Example 4-9 gets the MDM metadata objects that map to the OLAP metadata created by the GLOBALAW
analytic workspace. The program passes to a Context10g
object the command line arguments that specify the server on which the Oracle Database instance is running and a user name and password. The Context10g
object establishes a connection to the database.
The procedure for connecting is described in Chapter 3, "Connecting to a Data Store". For information on getting the complete code for the SampleMetadataDiscoverer10g
program and the classes that it uses, see the "Sample Schema for OLAP API Examples" section of Chapter 1.
Example 4-9 Discovering the OLAP Metadata
package oracle.olapi.examples.chapter4; import oracle.express.olapi.data.full.ExpressDataProvider; import oracle.olapi.examples.*; import oracle.olapi.metadata.mdm.*; import oracle.olapi.data.source.Source; import java.util.List; import java.util.Iterator; /** * Discovers the MDM metadata objects for the GLOBALAW analytic workspace. */ public class SampleMetadataDiscoverer10g extends ContextExample { private ExpressDataProvider dp = null; private MdmSchema root = null; private MdmPrimaryDimension storedMdmDim = null; private MyMdmObjectVisitor mdmObjVisitor = new MyMdmObjectVisitor(); private String sp3 = " "; // Contains spaces for formatting output. private String sp6 = (sp3 + sp3); private String sp9 = (sp6 + sp3); private String errorMessage; // Contains an error message. /** * Connects to an Oracle Database instance and gets MDM metadata objects. */ protected void run() throws Exception { getLogger().setVerbose(true); // Specify true to display more information. //getLogger().setVerbose(false); // Get the DataProvider associated with the connection. dp = getExpressDataProvider(); // Get the default MdmMetadataProvider from the DataProvider. MdmMetadataProvider mp = null; mp = (MdmMetadataProvider) dp.getDefaultMetadataProvider(); // Get metadata information about the root MdmSchema and the subschemas. root = mp.getRootSchema(); showInfo("The root MdmSchema is " + root.getName() + "."); // To get information about all of metadata objects associated with the root // MdmSchema, set getAllMetadata to true. // To get information about the metadata objects for a single subschema, // specify the subschema in the call to getSubschemaByName and set // getAllMetadata to false. // Get the metadata objects for the specified subschema only. MdmSchema subSchema = getSubschemaByName(root, "GLOBALAW_SCHEMA"); boolean getAllMetadata = false; // boolean getAllMetadata = true; if (!getAllMetadata) { getSchemaInfo(subSchema, getLogger().isVerbose()); } else { getSchemaInfo(root, getLogger().isVerbose()); } // The storedMdmDim object is an MdmPrimaryDimension that is assigned in // the getSchemaInfo method. The getSource method of the MdmPrimaryDimension // gets the Source object for the MdmPrimaryDimension. showOutput("\nGetting the primary Source object for dimension " + storedMdmDim.getName() + "."); Source dimSource = storedMdmDim.getSource(); showInfo("The ID of the Source for " + storedMdmDim.getName() + " is " + dimSource.getID() + ".\n"); } /** * Gets the specified subschema of the root MdmSchema. * * @param rootSchema The root MdmSchema. * @param schemaName The name of a subschema. * @return The specified MdmSchema that is a subschema of the root schema. */ public MdmSchema getSubschemaByName(MdmSchema rootSchema, String schemaName) { MdmSchema subschema = null; try { List subSchemas = rootSchema.getSubSchemas(); Iterator subSchemaIter = subSchemas.iterator(); while (subSchemaIter.hasNext()) { subschema = (MdmSchema) subSchemaIter.next(); if (subschema.getName().equals(schemaName)) { return subschema; } } } catch (Exception e) { showError(sp3 + "Encountered exception " + e); } if(subschema != null) { showOutput("Could not find subschema " + schemaName + "."); showOutput("Using subschema " + subschema.getName() + " instead.\n"); return subschema; } else { showOutput("Could not find any subschema."); showOutput("Using the root schema.\n"); return rootSchema; } } /** * Gets information about the specified MdmSchema and any subschemas of that * MdmSchema. */ public void getSchemaInfo(MdmSchema schema, boolean verbose) { if (schema == root) { showOutput("The MdmPrimaryDimension objects of the root schema are:"); } else { showOutput("\nSchema: " + schema.getName()); showOutput("The MdmPrimaryDimension objects of schema " + schema.getName() + " are:"); } // Get the MdmPrimaryDimension objects of the MdmSchema. int i = 1; try { List dims = schema.getDimensions(); Iterator dimIter = dims.iterator(); // Iterate through the list of MdmPrimaryDimension objects and get // information about each one. while (dimIter.hasNext()) { MdmPrimaryDimension oneDim = (MdmPrimaryDimension) dimIter.next(); // Save a dimension for later use. if ( storedMdmDim == null ) storedMdmDim = oneDim; if (verbose) { getDimInfo(i, oneDim); i++; } else { showOutput(sp3 + oneDim.getName()); } } } catch (Exception e) { showError(sp3 + "Encountered exception " + e); } // If the MdmSchema is the root MdmSchema, get the MdmMeasureDimension // and get the measures of the MdmMeasureDimension. MdmMeasureDimension mdmMeasureDim = (MdmMeasureDimension) schema.getMeasureDimension(); if (mdmMeasureDim != null) { showOutput("The MdmMeasure objects of the MdmMeasureDimension are:"); List mdmMeasures = mdmMeasureDim.getMeasures(); Iterator mdmMeasuresIter = mdmMeasures.iterator(); int count = 1; while (mdmMeasuresIter.hasNext()) { MdmMeasure oneMeasure = (MdmMeasure) mdmMeasuresIter.next(); getMeasureInfo(count, oneMeasure, verbose); if (verbose) showOutput(""); count++; } } // Get the MdmMeasure objects of the MdmSchema. try { List mdmMeasures = schema.getMeasures(); if (mdmMeasures.size() > 0) { Iterator mdmMeasuresIter = mdmMeasures.iterator(); showOutput("The MdmMeasure objects of schema " + schema.getName() + " are:"); int count = 1; while (mdmMeasuresIter.hasNext()) { MdmMeasure oneMeasure = (MdmMeasure) mdmMeasuresIter.next(); getMeasureInfo(count, oneMeasure, verbose); count++; } } } catch (Exception e) { showError(sp3 + "Encountered exception " + e); } // Get the subschema information for the MdmSchema. try { List subSchemas = schema.getSubSchemas(); Iterator subSchemaIter = subSchemas.iterator(); while (subSchemaIter.hasNext()) { MdmSchema oneSchema = (MdmSchema) subSchemaIter.next(); getSchemaInfo(oneSchema, verbose); } } catch (Exception e) { showError(sp3 + "Encountered exception " + e); } } /** * Gets information about an MdmMeasure. * * @param count An integer that tracks the number of MdmMeasure objects. * @param dim The MdmMeasure about which to get information. * @param verbose A boolean that specifies whether to display more or less * information. */ public void getMeasureInfo(int count, MdmMeasure measure, boolean verbose) { showOutput(count + ". " + measure.getName()); if (verbose) { // Get the MdmDimension objects associated with the MdmMeasure. try { List mDims = measure.getDimensions(); Iterator mDimIter = mDims.iterator(); showOutput(sp3 + "The dimensions of the measure are:"); while (mDimIter.hasNext()) { MdmDimension dim = (MdmDimension) mDimIter.next(); showOutput(sp6 + dim.getName()); } if (verbose) showOutput(""); } catch (Exception e) { showError(sp3 + "Encountered exception " + e); } } } /** * Gets information about an MdmDimension. * @param count An integer that indicates the position of the * MdmPrimaryDimension in the list of dimensions of the * MdmSchema. * @param dim The MdmPrimaryDimension about which to get information. */ public void getDimInfo(int count, MdmPrimaryDimension dim) { showOutput(count + ". " + dim.getName()); String description = dim.getDescription(); // Determine the type of the MdmPrimaryDimension. String objType = (String) dim.acceptVisitor(mdmObjVisitor, mdmObjVisitor.OBJTYPE); showOutput(sp3 + objType); // Get the MdmAttribute objects associated with the MdmPrimaryDimension. showInfo(sp3 + "The attributes of the dimension are:"); try { List attributes = dim.getAttributes(); Iterator attrIter = attributes.iterator(); while (attrIter.hasNext()) { MdmAttribute attr = (MdmAttribute) attrIter.next(); showOutput(sp6 + attr.getName()); } } catch (Exception e) { showError(sp3 + "Encountered exception " + e); } // Get information about the MdmHierarchy objects of the // MdmPrimaryDimension. getHierInfo(dim); showOutput(""); } /** * Gets the MdmHierarchy components of an MdmPrimaryDimension. * * @param dim The MdmPrimarydimension for which to get the MdmHierarchy * objects. */ public void getHierInfo(MdmPrimaryDimension dim) { List mdmHiers = dim.getHierarchies(); Iterator mdmHiersItr = mdmHiers.iterator(); MdmHierarchy mdmHier = null; MdmLevelHierarchy mdmLevelHier = null; int i = 1; showOutput(sp3 + "The MdmHierarchy components of " + dim.getName() + " are:"); while (mdmHiersItr.hasNext()) { mdmHier = (MdmHierarchy) mdmHiersItr.next(); showOutput(sp3 + i + ". " + mdmHier.getName()); String objType = (String) mdmHier.acceptVisitor(mdmObjVisitor, mdmObjVisitor.OBJTYPE); showOutput(sp6 + objType); if (mdmHier.isDefaultHierarchy()) { showOutput(sp6 + mdmHier.getName() + " is the default" + " MdmHierarchy of " + dim.getName() + "."); } if (mdmHier instanceof MdmLevelHierarchy) { mdmLevelHier = (MdmLevelHierarchy) mdmHier; getLevelInfo(mdmLevelHier); } i++; } } /** * Gets the MdmLevel components of an MdmLevelHierarchy. * * @param mdmHier The MdmLevelHierarchy about which to get information. */ public void getLevelInfo(MdmLevelHierarchy mdmHier) { List mdmLevels = mdmHier.getLevels(); Iterator mdmLevelsItr = mdmLevels.iterator(); showOutput(sp6 + "The levels of the hierarchy are:"); while (mdmLevelsItr.hasNext()) { MdmLevel mdmLevel = (MdmLevel) mdmLevelsItr.next(); showOutput(sp9 + mdmLevel.getName()); } } // The showError and showInfo methods of this class call methods of the same // name of the Logger object associated with this object. // The showOutput method calls the println method of the Logger. /** * Creates a new SampleMetadataDiscoverer10g object and calls the execute * method, which the class inherits from the ContextExample superclass. * * @param args Arguments supplied on the Java command line. */ public static void main(String[] args) { new SampleMetadataDiscoverer().execute(args); } }
The output from the sample program consists of text lines produced by a PrintWriter
. When the program connects to an Oracle Database instance that has the Global Schema for Documentation installed in it, if the value of the boolean variable getAllMetadata
is true
, the output includes the following items:
The name of the root MdmSchema
, which is ROOT
.
The MdmPrimaryDimension
objects in the root MdmSchema
. From the dimensions the program gets the type of the dimension and the MdmAttribute
and MdmHierarchy
objects associated with it.
If an MdmHierarchy
is an MdmLevelHierarchy
, then the program get the MdmLevel
objects of the hierarchy.
The MdmMeasure
objects in the MdmMeasureDimension
. From each measure, the program gets the MdmPrimaryDimension
objects associated with it.
The MdmSchema
objects that are subschemas of the root MdmSchema
.
The dimensions and measures of each subschema, and the attributes of the dimensions.
The identifier of Source
for one of the MdmPrimaryDimension
objects.
If the value of the boolean variable getAllMetadata
is false
, then the program gets information only about the dimensions, attributes, and measures of the GLOBALAW_SCHEMA
subschema.
The following is the output when getAllMetadata
is false
.
The root MdmSchema is ROOT. Schema: GLOBALAW_SCHEMA The MdmPrimaryDimension objects of schema GLOBALAW_SCHEMA are: 1. PRODUCT_AW It is an MdmStandardDimension. The attributes of the dimension are: PACKAGE_AW BUYER_AW MARKETING_MANAGER_AW LONG_DESCRIPTION SHORT_DESCRIPTION The MdmHierarchy components of PRODUCT_AW are: 1. PRODUCT_PRIMARY_AW It is an MdmLevelHierarchy. PRODUCT_PRIMARY_AW is the default MdmHierarchy of PRODUCT_AW. The levels of the hierarchy are: TOTAL_PRODUCT_AW CLASS_AW FAMILY_AW ITEM_AW 2. TIME_AW It is an MdmTimeDimension. The attributes of the dimension are: END_DATE TIME_SPAN LONG_DESCRIPTION SHORT_DESCRIPTION TIME_AW_DSO_1 The MdmHierarchy components of TIME_AW are: 1. CALENDAR_YEAR_AW It is an MdmLevelHierarchy. CALENDAR_YEAR_AW is the default MdmHierarchy of TIME_AW. The levels of the hierarchy are: YEAR_AW QUARTER_AW MONTH_AW 3. CUSTOMER_AW It is an MdmStandardDimension. The attributes of the dimension are: LONG_DESCRIPTION SHORT_DESCRIPTION The MdmHierarchy components of CUSTOMER_AW are: 1. SHIPMENTS_AW It is an MdmLevelHierarchy. SHIPMENTS_AW is the default MdmHierarchy of CUSTOMER_AW. The levels of the hierarchy are: TOTAL_CUSTOMER_AW REGION_AW WAREHOUSE_AW SHIP_TO_AW 2. MARKET_SEGMENT_AW It is an MdmLevelHierarchy. The levels of the hierarchy are: TOTAL_MARKET_AW MARKET_SEGMENT_AW ACCOUNT_AW SHIP_TO_AW 4. CHANNEL_AW It is an MdmStandardDimension. The attributes of the dimension are: LONG_DESCRIPTION SHORT_DESCRIPTION The MdmHierarchy components of CHANNEL_AW are: 1. CHANNEL_PRIMARY_AW It is an MdmLevelHierarchy. CHANNEL_PRIMARY_AW is the default MdmHierarchy of CHANNEL_AW. The levels of the hierarchy are: TOTAL_CHANNEL_AW CHANNEL_AW The MdmMeasure objects of schema GLOBALAW_SCHEMA are: 1. UNIT_COST_AW The dimensions of the measure are: PRODUCT_AW TIME_AW 2. UNIT_PRICE_AW The dimensions of the measure are: PRODUCT_AW TIME_AW 3. SALES_AW The dimensions of the measure are: TIME_AW CUSTOMER_AW PRODUCT_AW CHANNEL_AW 4. UNITS_AW The dimensions of the measure are: TIME_AW CUSTOMER_AW PRODUCT_AW CHANNEL_AW Getting the primary Source object for dimension PRODUCT_AW. The ID of the Source for PRODUCT_AW is Hidden..D_GLOBAL_AW.PRODUCT_AW. Closing DataProvider. Closing JDBC connection.