rolapdimension.java
来自「数据仓库展示程序」· Java 代码 · 共 258 行
JAVA
258 行
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/RolapDimension.java#16 $
// 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, 10 August, 2001
*/
package mondrian.rolap;
import org.apache.log4j.Logger;
import mondrian.olap.*;
import mondrian.resource.MondrianResource;
/**
* <code>RolapDimension</code> implements {@link Dimension}for a ROLAP
* database.
*
* <h2><a name="topic_ordinals">Topic: Dimension ordinals </a></h2>
*
* {@link RolapEvaluator} needs each dimension to have an ordinal, so that it
* can store the evaluation context as an array of members. When virtual cubes
* and shared dimensions enter the picture, we find that dimensions' ordinals
* must be unique within the whole schema, not just their cube.
*
* <p>
* The ordinal of a dimension <em>within a particular cube</em> is found by
* calling {@link #getOrdinal(Cube)}, which is implemented in terms of the
* {@link RolapCube#localDimensionOrdinals} map. This map converts a
* dimension's global ordinal into a local one within the cube. Local ordinals
* are contiguous and zero-based. Zero is always the <code>[Measures]</code>
* dimension.
*
* <p>
* A dimension may be either shared or private to a particular cube. The
* dimension object doesn't actually know which; {@link Schema} has a list of
* shared hierarchies ({@link Schema#getSharedHierarchies}), and {@link Cube}
* has a list of dimensions ({@link Cube#getDimensions}).
*
* <p>
* If a dimension is shared between several cubes, the {@link Dimension}objects
* which represent them may (or may not be) the same. (That's why there's no
* <code>getCube()</code> method.)
*
* <p>
* Furthermore, since members are created by a {@link MemberReader}which
* belongs to the {@link RolapHierarchy}, you will the members will be the same
* too. For example, if you query <code>[Product].[Beer]</code> from the
* <code>Sales</code> and <code>Warehouse</code> cubes, you will get the
* same {@link RolapMember}object.
* ({@link RolapSchema#mapSharedHierarchyToReader} holds the mapping. I don't
* know whether it's still necessary.)
*
* @author jhyde
* @since 10 August, 2001
* @version $Id: //open/mondrian/src/main/mondrian/rolap/RolapDimension.java#16 $
*/
class RolapDimension extends DimensionBase {
private static final Logger LOGGER = Logger.getLogger(RolapDimension.class);
/** Generator for {@link #globalOrdinal}. * */
private static int nextOrdinal = 1; // 0 is reserved for [Measures]
static int getNextOrdinal() {
return RolapDimension.nextOrdinal++;
}
private final Schema schema;
RolapDimension(Schema schema,
String name,
int globalOrdinal,
DimensionType dimensionType) {
super(name,
Util.makeFqName(name),
null,
globalOrdinal,
// todo: recognition of a time dimension should be improved
// allow multiple time dimensions
dimensionType);
this.schema = schema;
Util.assertTrue((globalOrdinal == 0) == name.equals(MEASURES_NAME));
this.hierarchies = new RolapHierarchy[0];
}
/**
* Creates a dimension from an XML definition.
*
* @pre schema != null
*/
RolapDimension(RolapSchema schema,
RolapCube cube,
MondrianDef.Dimension xmlDimension,
MondrianDef.CubeDimension xmlCubeDimension) {
this(schema,
xmlDimension.name,
chooseOrdinal(cube, xmlCubeDimension),
xmlDimension.getDimensionType());
Util.assertPrecondition(schema != null);
if (cube != null) {
Util.assertTrue(cube.getSchema() == schema);
}
if (!Util.isEmpty(xmlDimension.caption)) {
setCaption(xmlDimension.caption);
}
this.hierarchies = new RolapHierarchy[xmlDimension.hierarchies.length];
for (int i = 0; i < xmlDimension.hierarchies.length; i++) {
RolapHierarchy hierarchy = new RolapHierarchy(
cube, this, xmlDimension.hierarchies[i],
xmlCubeDimension);
hierarchies[i] = hierarchy;
}
// if there was no dimension type assigned, determine now.
if (dimensionType == null) {
for (int i = 0; i < hierarchies.length; i++) {
Level[] levels = hierarchies[i].getLevels();
LevLoop:
for (int j = 0; j < levels.length; j++) {
Level lev = levels[j];
if (lev.isAll()) {
continue LevLoop;
}
if (dimensionType == null) {
// not set yet - set it according to current level
dimensionType = (lev.getLevelType().isTime())
? DimensionType.TimeDimension
: DimensionType.StandardDimension;
} else {
// Dimension type was set according to first level.
// Make sure that other levels fit to definition.
if (dimensionType == DimensionType.TimeDimension &&
!lev.getLevelType().isTime() &&
!lev.isAll()) {
throw MondrianResource.instance().NonTimeLevelInTimeHierarchy.ex(
getUniqueName());
}
if (dimensionType != DimensionType.TimeDimension &&
lev.getLevelType().isTime()) {
throw MondrianResource.instance().TimeLevelInNonTimeHierarchy.ex(
getUniqueName());
}
}
}
}
}
}
protected Logger getLogger() {
return LOGGER;
}
/**
* Assigns an ordinal for a dimension usage; also assigns the join-level of
* the usage.
*/
private static int chooseOrdinal(RolapCube cube,
MondrianDef.CubeDimension xmlCubeDimension) {
if (xmlCubeDimension.name.equals(MEASURES_NAME)) {
return 0;
}
if (xmlCubeDimension instanceof MondrianDef.DimensionUsage) {
RolapSchema schema = (RolapSchema) cube.getSchema();
MondrianDef.DimensionUsage usage =
(MondrianDef.DimensionUsage) xmlCubeDimension;
RolapHierarchy hierarchy = schema.getSharedHierarchy(usage.source);
if (hierarchy != null) {
cube.createUsage(hierarchy, usage);
RolapDimension dimension =
(RolapDimension) hierarchy.getDimension();
return dimension.getGlobalOrdinal();
}
}
return RolapDimension.getNextOrdinal();
}
/**
* Initializes a dimension within the context of a cube.
*/
void init(RolapCube cube, MondrianDef.CubeDimension xmlDimension) {
for (int i = 0; i < hierarchies.length; i++) {
if (hierarchies[i] != null) {
((RolapHierarchy) hierarchies[i]).init(cube, xmlDimension);
}
}
}
RolapHierarchy newHierarchy(String subName, boolean hasAll) {
RolapHierarchy hierarchy = new RolapHierarchy(this, subName, hasAll);
this.hierarchies = (RolapHierarchy[])
RolapUtil.addElement(this.hierarchies, hierarchy);
return hierarchy;
}
/**
* Returns the hierarchy of an expression.
*
* <p>In this case, the expression is a dimension, so the hierarchy is the
* dimension's default hierarchy (its first).
*/
public Hierarchy getHierarchy() {
return hierarchies[0];
}
public int getOrdinal(Cube cube) {
return ((RolapCube) cube).getOrdinal(this.globalOrdinal);
}
public Schema getSchema() {
return schema;
}
/**
* See {@link #nextOrdinal}.
*/
int getGlobalOrdinal() {
return globalOrdinal;
}
/**
* Returns a copy of this dimension with a different name.
*
* @param cube
* @param name Name for the new dimension.
* @param xmlCubeDimension
*/
public RolapDimension copy(RolapCube cube,
String name,
MondrianDef.CubeDimension xmlCubeDimension) {
RolapDimension dimension = new RolapDimension(
schema,
name,
RolapDimension.getNextOrdinal(),
dimensionType);
dimension.hierarchies = (Hierarchy[]) hierarchies.clone();
for (int i = 0; i < hierarchies.length; i++) {
final RolapHierarchy hierarchy = (RolapHierarchy) hierarchies[i];
dimension.hierarchies[i] = new RolapHierarchy(cube, dimension,
hierarchy.xmlHierarchy, xmlCubeDimension);
}
return dimension;
}
}
// End RolapDimension.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?