openingclosingperiodfundef.java
来自「数据仓库展示程序」· Java 代码 · 共 198 行
JAVA
198 行
/*
// $Id: //open/mondrian/src/main/mondrian/olap/fun/OpeningClosingPeriodFunDef.java#2 $
// 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) 2002-2005 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 26 February, 2002
*/
package mondrian.olap.fun;
import mondrian.olap.*;
import mondrian.olap.type.MemberType;
import mondrian.olap.type.Type;
import mondrian.resource.MondrianResource;
/**
* Definition of the <code>OpeningPeriod</code> and <code>ClosingPeriod</code>
* builtin functions.
*
* @author jhyde
* @since 2005/8/14
* @version $Id: //open/mondrian/src/main/mondrian/olap/fun/OpeningClosingPeriodFunDef.java#2 $
*/
class OpeningClosingPeriodFunDef extends FunDefBase {
private final boolean opening;
public OpeningClosingPeriodFunDef(
FunDef dummyFunDef,
boolean opening) {
super(dummyFunDef);
this.opening = opening;
}
public Type getResultType(Validator validator, Exp[] args) {
if (args.length == 0) {
// With no args, the default implementation cannot
// guess the hierarchy, so we supply the Time
// dimension.
Hierarchy hierarchy = validator.getQuery()
.getCube().getTimeDimension()
.getHierarchy();
return new MemberType(hierarchy, null, null);
}
return super.getResultType(validator, args);
}
public boolean callDependsOn(FunCall call, Dimension dimension) {
switch (call.getArgCount()) {
case 0:
// OpeningPeriod() depends on [Time]
return dimension.getDimensionType() == DimensionType.TimeDimension;
case 1:
// OpeningPeriod(<Level>)
// depends on Level's dimension even the expression does not.
if (super.callDependsOn(call, dimension)) {
return true;
}
return call.getArg(0).getTypeX().usesDimension(dimension);
case 2:
// OpeningPeriod(<Level>, <Member>)
// depends upon whatever its args depend on.
return super.callDependsOn(call, dimension);
default:
throw Util.newInternal("bad arg count " + call.getArgCount());
}
}
public Object evaluate(Evaluator evaluator, Exp[] args) {
Member member;
Level level;
//
// If the member argument is present, use it. Otherwise default
// to the time dimension's current member.
//
if (args.length == 2) {
member = getMemberArg(evaluator, args, 1, false);
} else {
member = evaluator.getContext(evaluator.getCube().getTimeDimension());
}
//
// If the level argument is present, use it. Otherwise use the level
// immediately after that of the member argument.
//
if (args.length >= 1) {
level = getLevelArg(evaluator, args, 0, false);
} else {
int targetDepth = member.getLevel().getDepth() + 1;
Level[] levels = member.getHierarchy().getLevels();
if (levels.length <= targetDepth) {
return member.getHierarchy().getNullMember();
}
level = levels[targetDepth];
}
//
// Make sure the member and the level come from the same hierarchy.
//
if (!member.getHierarchy().equals(level.getHierarchy())) {
throw MondrianResource.instance().FunctionMbrAndLevelHierarchyMismatch.ex(
opening ? "OpeningPeriod" : "ClosingPeriod",
level.getHierarchy().getUniqueName(),
member.getHierarchy().getUniqueName());
}
//
// Shortcut if the level is above the member.
//
if (level.getDepth() < member.getLevel().getDepth()) {
return member.getHierarchy().getNullMember();
}
//
// Shortcut if the level is the same as the member
//
if (level == member.getLevel()) {
return member;
}
return getDescendant(evaluator.getSchemaReader(), member, level,
opening);
}
/**
* Returns the first or last descendant of the member at the target level.
* This method is the implementation of both OpeningPeriod and ClosingPeriod.
* @param schemaReader The schema reader to use to evaluate the function.
* @param member The member from which the descendant is to be found.
* @param targetLevel The level to stop at.
* @param returnFirstDescendant Flag indicating whether to return the first
* or last descendant of the member.
* @return A member.
* @pre member.getLevel().getDepth() < level.getDepth();
*/
static Member getDescendant(
SchemaReader schemaReader,
Member member,
Level targetLevel,
boolean returnFirstDescendant) {
Member[] children;
final int targetLevelDepth = targetLevel.getDepth();
assertPrecondition(member.getLevel().getDepth() < targetLevelDepth,
"member.getLevel().getDepth() < targetLevel.getDepth()");
for (;;) {
children = schemaReader.getMemberChildren(member);
if (children.length == 0) {
return targetLevel.getHierarchy().getNullMember();
}
member = children[returnFirstDescendant ? 0 : (children.length - 1)];
if (member.getLevel().getDepth() == targetLevelDepth) {
if (member.isHidden()) {
return member.getHierarchy().getNullMember();
} else {
return member;
}
}
}
}
public static Resolver createResolver(final boolean opening) {
return opening ?
(Resolver) new MultiResolver(
"OpeningPeriod",
"OpeningPeriod([<Level>[, <Member>]])",
"Returns the first descendant of a member at a level.",
new String[] {"fm", "fml", "fmlm"}) {
protected FunDef createFunDef(
Exp[] args, FunDef dummyFunDef) {
return new OpeningClosingPeriodFunDef(
dummyFunDef, opening);
}
} :
new MultiResolver(
"ClosingPeriod",
"ClosingPeriod([<Level>[, <Member>]])",
"Returns the last descendant of a member at a level.",
new String[] {"fm", "fml", "fmlm", "fmm"}) {
protected FunDef createFunDef(
Exp[] args, FunDef dummyFunDef) {
return new OpeningClosingPeriodFunDef(
dummyFunDef, opening);
}
};
}
}
// End OpeningClosingPeriodFunDef.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?