explicitrecognizer.java
来自「数据仓库展示程序」· Java 代码 · 共 277 行
JAVA
277 行
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/aggmatcher/ExplicitRecognizer.java#5 $
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// Copyright (C) 2001-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 12 August, 2001
*/
package mondrian.rolap.aggmatcher;
import mondrian.olap.Hierarchy;
import mondrian.recorder.MessageRecorder;
import mondrian.rolap.*;
import java.util.Iterator;
/**
* This is the Recognizer for the aggregate table descriptions that appear in
* the catalog schema files; the user explicitly defines the aggregate.
*
* @author <a>Richard M. Emberson</a>
* @version
*/
class ExplicitRecognizer extends Recognizer {
private ExplicitRules.TableDef tableDef;
ExplicitRecognizer(final ExplicitRules.TableDef tableDef,
final RolapStar star,
final JdbcSchema.Table dbFactTable,
final JdbcSchema.Table aggTable,
final MessageRecorder msgRecorder) {
super(star, dbFactTable, aggTable, msgRecorder);
this.tableDef = tableDef;
}
/**
* Get the ExplicitRules.TableDef associated with this instance.
*
* @return
*/
protected ExplicitRules.TableDef getTableDef() {
return tableDef;
}
/**
* Get the Matcher to be used to match columns to be ignored.
*
* @return
*/
protected Recognizer.Matcher getIgnoreMatcher() {
return getTableDef().getIgnoreMatcher();
}
/**
* Get the Matcher to be used to match the column which is the fact count
* column.
*
* @return
*/
protected Recognizer.Matcher getFactCountMatcher() {
return getTableDef().getFactCountMatcher();
}
/**
* Make the measures for this aggregate table.
* <p>
* First, iterate through all of the columns in the table.
* For each column, iterate through all of the tableDef measures, the
* explicit definitions of a measure.
* If the table's column name matches the column name in the measure
* definition, then make a measure.
* Next, look through all of the fact table column usage measures.
* For each such measure usage that has a sibling foreign key usage
* see if the tableDef has a foreign key defined with the same name.
* If so, then, for free, we can make a measure for the aggregate using
* its foreign key.
* <p>
*
* @return number of measures created.
*/
protected int checkMeasures() {
msgRecorder.pushContextName("ExplicitRecognizer.checkMeasures");
try {
int nosOfMeasureColumns = 0;
// Look at each aggregate table column. For each measure defined,
// see if the measure's column name equals the column's name.
// If so, make the aggregate measure usage for that column.
for (Iterator it = aggTable.getColumns(); it.hasNext(); ) {
JdbcSchema.Table.Column aggColumn =
(JdbcSchema.Table.Column) it.next();
// if marked as ignore, then do not consider
if (aggColumn.hasUsage(JdbcSchema.IGNORE_COLUMN_USAGE)) {
continue;
}
String aggColumnName = aggColumn.getName();
for (Iterator mit = getTableDef().getMeasures(); mit.hasNext();) {
ExplicitRules.TableDef.Measure measure =
(ExplicitRules.TableDef.Measure) mit.next();
// Column name match is case insensitive
if (measure.getColumnName().equalsIgnoreCase(aggColumnName)) {
// Ok, got a match, so now make a measue
makeMeasure(measure, aggColumn);
nosOfMeasureColumns++;
}
}
}
// Ok, now look at all of the fact table columns with measure usage
// that have a sibling foreign key usage. These can be automagically
// generated for the aggregate table as long as it still has the foreign
// key.
for (Iterator it =
dbFactTable.getColumnUsages(JdbcSchema.MEASURE_COLUMN_USAGE);
it.hasNext(); ) {
JdbcSchema.Table.Column.Usage factUsage =
(JdbcSchema.Table.Column.Usage) it.next();
JdbcSchema.Table.Column factColumn = factUsage.getColumn();
if (factColumn.hasUsage(JdbcSchema.FOREIGN_KEY_COLUMN_USAGE)) {
// What we've got here is a measure based upon a foreign key
String aggFK =
getTableDef().getAggregateFK(factColumn.getName());
// OK, not a lost dimension
if (aggFK != null) {
JdbcSchema.Table.Column aggColumn =
aggTable.getColumn(aggFK);
// Column name match is case insensitive
if (aggColumn == null) {
aggColumn = aggTable.getColumn(aggFK.toLowerCase());
}
if (aggColumn == null) {
aggColumn = aggTable.getColumn(aggFK.toUpperCase());
}
if (aggColumn != null) {
makeMeasure(factUsage, aggColumn);
nosOfMeasureColumns++;
}
}
}
}
return nosOfMeasureColumns;
} finally {
msgRecorder.popContextName();
}
}
/**
* Make a measure. This makes a measure usage using the Aggregator found in
* the RolapStar.Measure associated with the ExplicitRules.TableDef.Measure.
*
* @param measure
* @param aggColumn
*/
protected void makeMeasure(final ExplicitRules.TableDef.Measure measure,
final JdbcSchema.Table.Column aggColumn) {
RolapStar.Measure rm = measure.getRolapStarMeasure();
JdbcSchema.Table.Column.Usage aggUsage =
aggColumn.newUsage(JdbcSchema.MEASURE_COLUMN_USAGE);
aggUsage.setSymbolicName(measure.getSymbolicName());
convertAggregator(aggUsage, rm.getAggregator());
aggUsage.rMeasure = rm;
}
/**
* This creates a foreign key usage.
* <p>
* First the column name of the fact usage which is a foreign key is used to
* search for a foreign key definition in the ExplicitRules.tableDef.
* If not found, thats ok, it is just a lost dimension.
* If found, look for a column in the aggregate table with that name and
* make a foreign key usage.
* <p>
*
* @param factUsage
* @return
*/
protected int matchForeignKey(final JdbcSchema.Table.Column.Usage factUsage) {
JdbcSchema.Table.Column factColumn = factUsage.getColumn();
String aggFK = getTableDef().getAggregateFK(factColumn.getName());
// OK, a lost dimension
if (aggFK == null) {
return 0;
}
int nosMatched = 0;
for (Iterator aggit = aggTable.getColumns(); aggit.hasNext();) {
JdbcSchema.Table.Column aggColumn =
(JdbcSchema.Table.Column) aggit.next();
// if marked as ignore, then do not consider
if (aggColumn.hasUsage(JdbcSchema.IGNORE_COLUMN_USAGE)) {
continue;
}
if (aggFK.equals(aggColumn.getName())) {
makeForeignKey(factUsage, aggColumn, aggFK);
nosMatched++;
}
}
return nosMatched;
}
/**
* This creates a level usage. A level usage is a column that is used in a
* collapsed dimension aggregate table.
* <p>
* First, iterate through the ExplicitRules.TableDef's level definitions for
* one with a name equal to the RolapLevel unique name, i.e.,
* [Time].[Quarter]. Now, using the level's column name, search through the
* aggregate table's columns for one with that name and make a level usage
* for the column. Return true if the aggregate table's column was found.
* <p>
*
* @param hierarchy
* @param hierarchyUsage
* @param rlevel
* @return
*/
protected boolean matchLevel(final Hierarchy hierarchy,
final HierarchyUsage hierarchyUsage,
final RolapLevel rlevel) {
msgRecorder.pushContextName("ExplicitRecognizer.matchLevel");
try {
// Try to match a Level's name against the RolapLevel unique name.
String levelUniqueName = rlevel.getUniqueName();
for (Iterator mit = getTableDef().getLevels(); mit.hasNext();) {
ExplicitRules.TableDef.Level level =
(ExplicitRules.TableDef.Level) mit.next();
if (level.getName().equals(levelUniqueName)) {
// Ok, got a match, so now make a measue
//makeLevel(level, xxxxolumn);
// Now can we find a column in the aggTable that matches the
// Level's column
String columnName = level.getColumnName();
for (Iterator aggit = aggTable.getColumns();
aggit.hasNext();) {
JdbcSchema.Table.Column aggColumn =
(JdbcSchema.Table.Column) aggit.next();
if (aggColumn.getName().equals(columnName)) {
makeLevel(aggColumn,
hierarchy,
hierarchyUsage,
getColumnName(rlevel.getKeyExp()),
columnName,
rlevel.getName());
return true;
}
}
}
}
return false;
} finally {
msgRecorder.popContextName();
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?