rolaphierarchy.java
来自「数据仓库展示程序」· Java 代码 · 共 597 行 · 第 1/2 页
JAVA
597 行
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/RolapHierarchy.java#37 $
// 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.
// (C) Copyright 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 mondrian.olap.*;
import mondrian.olap.fun.BuiltinFunTable;
import mondrian.olap.type.Type;
import mondrian.olap.type.MemberType;
import mondrian.rolap.sql.SqlQuery;
import mondrian.resource.MondrianResource;
import org.apache.log4j.Logger;
import java.util.List;
/**
* <code>RolapHierarchy</code> implements {@link Hierarchy} for a ROLAP database.
*
* @author jhyde
* @since 10 August, 2001
* @version $Id: //open/mondrian/src/main/mondrian/rolap/RolapHierarchy.java#37 $
*/
class RolapHierarchy extends HierarchyBase {
private static final Logger LOGGER = Logger.getLogger(RolapHierarchy.class);
/**
* The raw member reader. For a member reader which incorporates access
* control and deals with hidden members (if the hierarchy is ragged), use
* {@link #getMemberReader(Role)}.
*/
MemberReader memberReader;
MondrianDef.Hierarchy xmlHierarchy;
private String memberReaderClass;
private MondrianDef.Relation relation;
private Member defaultMember;
private String defaultMemberName;
private RolapNullMember nullMember;
/**
* If this hierarchy is a public -- that is, it belongs to a dimension
* which is a usage of a shared dimension -- then
* <code>sharedHierarchy</code> holds the unique name of the shared
* hierarchy; otherwise it is null.
*
* <p> Suppose this hierarchy is "Weekly" in the dimension "Order Date" of
* cube "Sales", and that "Order Date" is a usage of the "Time"
* dimension. Then <code>sharedHierarchy</code> will be "[Time].[Weekly]".
**/
private String sharedHierarchy;
private Exp aggregateChildrenExpression;
// for newClosedPeerHierarchy() to copy; but never used??
private String primaryKey;
/**
* Type for members of this hierarchy. Set once to avoid excessive newing.
*/
final Type memberType = new MemberType(this, null, null);
RolapHierarchy(RolapDimension dimension, String subName, boolean hasAll) {
super(dimension, subName, hasAll);
this.levels = new RolapLevel[0];
setCaption(dimension.getCaption());
if (hasAll) {
this.allLevelName = "(All)";
Util.discard(newLevel(this.allLevelName,
RolapLevel.ALL | RolapLevel.UNIQUE));
this.allMemberName = "All " + name + "s";
}
}
/**
* Creates a <code>RolapHierarchy</code>.
*
* @param cube Cube this hierarchy belongs to, or null if this is a shared
* hierarchy
*/
RolapHierarchy(RolapCube cube, RolapDimension dimension,
MondrianDef.Hierarchy xmlHierarchy,
MondrianDef.CubeDimension xmlCubeDimension) {
this(dimension, xmlHierarchy.name, xmlHierarchy.hasAll.booleanValue());
if (xmlHierarchy.relation == null &&
xmlHierarchy.memberReaderClass == null &&
cube != null) {
xmlHierarchy.relation = cube.fact;
}
this.xmlHierarchy = xmlHierarchy;
this.relation = xmlHierarchy.relation;
this.memberReaderClass = xmlHierarchy.memberReaderClass;
if (hasAll) {
if (xmlHierarchy.allMemberName != null) {
this.allMemberName = xmlHierarchy.allMemberName;
}
if (xmlHierarchy.allLevelName != null) {
this.allLevelName = xmlHierarchy.allLevelName;
}
this.levels = new RolapLevel[xmlHierarchy.levels.length + 1];
this.levels[0] = new RolapLevel(
this, 0, this.allLevelName, null, null, null, null, null, null,
null, RolapProperty.emptyArray,
RolapLevel.ALL | RolapLevel.UNIQUE,
RolapLevel.HideMemberCondition.Never,
LevelType.Regular);
for (int i = 0; i < xmlHierarchy.levels.length; i++) {
final MondrianDef.Level xmlLevel = xmlHierarchy.levels[i];
if (xmlLevel.getKeyExp() == null &&
xmlHierarchy.memberReaderClass == null) {
throw MondrianResource.instance().LevelMustHaveNameExpression.ex(xmlLevel.name);
}
levels[i + 1] = new RolapLevel(this, i + 1, xmlLevel);
}
} else {
this.levels = new RolapLevel[xmlHierarchy.levels.length];
for (int i = 0; i < xmlHierarchy.levels.length; i++) {
levels[i] = new RolapLevel(this, i, xmlHierarchy.levels[i]);
}
}
if (xmlCubeDimension instanceof MondrianDef.DimensionUsage) {
String sharedDimensionName =
((MondrianDef.DimensionUsage) xmlCubeDimension).source;
this.sharedHierarchy = sharedDimensionName;
if (subName != null) {
this.sharedHierarchy += "." + subName; // e.g. "Time.Weekly"
}
} else {
this.sharedHierarchy = null;
}
if (xmlHierarchy.relation != null &&
xmlHierarchy.memberReaderClass != null) {
throw MondrianResource.instance().HierarchyMustNotHaveMoreThanOneSource.ex(getUniqueName());
}
this.primaryKey = xmlHierarchy.primaryKey;
if (!Util.isEmpty(xmlHierarchy.caption)) {
setCaption(xmlHierarchy.caption);
}
defaultMemberName = xmlHierarchy.defaultMember;
}
protected Logger getLogger() {
return LOGGER;
}
public boolean equals(Object o) {
if (!(o instanceof RolapHierarchy)) {
return false;
}
if (this == o) {
return true;
}
RolapHierarchy that = (RolapHierarchy)o;
return ((sharedHierarchy == null) || (that.sharedHierarchy == null))
? false
: (sharedHierarchy.equals(that.sharedHierarchy) &&
getUniqueName().equals(that.getUniqueName()));
}
public int hashCode() {
return super.hashCode() ^ (sharedHierarchy == null
? 0
: sharedHierarchy.hashCode());
}
/**
* Initializes a hierarchy within the context of a cube.
*/
void init(RolapCube cube, MondrianDef.CubeDimension xmlDimension) {
for (int i = 0; i < levels.length; i++) {
((RolapLevel) levels[i]).init(cube, xmlDimension);
}
if (this.memberReader == null) {
this.memberReader = getRolapSchema().createMemberReader(
sharedHierarchy, this, memberReaderClass);
}
if (defaultMemberName != null) {
String[] uniqueNameParts = Util.explode(defaultMemberName);
// We strip off the parent dimension name if the defaultMemberName
// is the full unique name, [Time].[2004] rather than simply
// [2004].
Dimension dim = getDimension();
if (dim.getName().equals(uniqueNameParts[0])) {
String[] tmp = new String[uniqueNameParts.length-1];
System.arraycopy(uniqueNameParts, 1, tmp, 0,
uniqueNameParts.length-1);
uniqueNameParts = tmp;
}
// Now lookup the name from the hierarchy's members.
defaultMember = memberReader.lookupMember(uniqueNameParts, false);
if (defaultMember == null) {
throw Util.newInternal(
"Can not find Default Member with name \""
+ defaultMemberName + "\"");
}
}
}
RolapLevel newLevel(String name, int flags) {
RolapLevel level = new RolapLevel(
this, this.levels.length, name, null, null, null, null,
null, null, null, RolapProperty.emptyArray, flags,
RolapLevel.HideMemberCondition.Never, LevelType.Regular);
this.levels = (RolapLevel[]) RolapUtil.addElement(this.levels, level);
return level;
}
/**
* If this hierarchy has precisely one table, returns that table;
* if this hierarchy has no table, return the cube's fact-table;
* otherwise, returns null.
*/
MondrianDef.Relation getUniqueTable() {
if (relation instanceof MondrianDef.Table ||
relation instanceof MondrianDef.View) {
return relation;
} else if (relation instanceof MondrianDef.Join) {
return null;
} else {
throw Util.newInternal(
"hierarchy's relation is a " + relation.getClass());
}
}
boolean tableExists(String tableName) {
return (relation != null) && tableExists(tableName, relation);
}
private static boolean tableExists(String tableName,
MondrianDef.Relation relation) {
if (relation instanceof MondrianDef.Table) {
MondrianDef.Table table = (MondrianDef.Table) relation;
// Check by table name and alias
return table.name.equals(tableName) ||
((table.alias != null) && table.alias.equals(tableName));
}
if (relation instanceof MondrianDef.Join) {
MondrianDef.Join join = (MondrianDef.Join) relation;
return tableExists(tableName, join.left) ||
tableExists(tableName, join.right);
}
return false;
}
RolapSchema getRolapSchema() {
return (RolapSchema) dimension.getSchema();
}
MondrianDef.Relation getRelation() {
return relation;
}
public Member getDefaultMember() {
// use lazy initialization to get around bootstrap issues
if (defaultMember == null) {
List rootMembers = memberReader.getRootMembers();
if (rootMembers.size() == 0) {
throw MondrianResource.instance().InvalidHierarchyCondition.ex(this.getUniqueName());
/*
throw Util.newError(
"cannot get default member: hierarchy " + getUniqueName() +
" has no root members");
*/
}
defaultMember = (RolapMember) rootMembers.get(0);
}
return defaultMember;
}
public Member getNullMember() {
// use lazy initialization to get around bootstrap issues
if (nullMember == null) {
nullMember = new RolapNullMember(this);
}
return nullMember;
}
public Member createMember(Member parent,
Level level,
String name,
Formula formula) {
return (formula != null)
? new RolapCalculatedMember(
(RolapMember) parent, (RolapLevel) level, name, formula)
: new RolapMember(
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?