rolapevaluator.java
来自「数据仓库展示程序」· Java 代码 · 共 517 行 · 第 1/2 页
JAVA
517 行
/*
// $Id: //open/mondrian/src/main/mondrian/rolap/RolapEvaluator.java#35 $
// 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 mondrian.olap.*;
import mondrian.olap.fun.FunUtil;
import mondrian.util.Format;
import mondrian.resource.MondrianResource;
import org.apache.log4j.Logger;
import java.util.*;
/**
* <code>RolapEvaluator</code> evaluates expressions in a dimensional
* environment.
*
* <p>The context contains a member (which may be the default member)
* for every dimension in the current cube. Certain operations, such as
* evaluating a calculated member or a tuple, change the current context. The
* evaluator's {@link #push} method creates a clone of the current evaluator
* so that you can revert to the original context once the operation has
* completed.
*
* @author jhyde
* @since 10 August, 2001
* @version $Id: //open/mondrian/src/main/mondrian/rolap/RolapEvaluator.java#35 $
*/
class RolapEvaluator implements Evaluator {
private static final Logger LOGGER = Logger.getLogger(RolapEvaluator.class);
/**
* Dummy value to represent null results in the expression cache.
*/
private static final Object nullResult = new Object();
private final Member[] currentMembers;
private final Evaluator parent;
protected CellReader cellReader;
private final int depth;
private Member expandingMember;
private boolean nonEmpty;
protected final RolapEvaluatorRoot root;
/**
* Creates an evaluator.
*/
protected RolapEvaluator(
RolapEvaluatorRoot root,
RolapEvaluator parent,
CellReader cellReader,
Member[] currentMembers) {
this.root = root;
this.parent = parent;
this.depth = parent == null ? 0 : parent.depth + 1;
this.cellReader = cellReader;
if (currentMembers == null) {
this.currentMembers = new Member[root.cube.getDimensions().length];
} else {
this.currentMembers = currentMembers;
}
}
/**
* Creates an evaluator with no parent.
*
* @param root Shared context between this evaluator and its children
*/
RolapEvaluator(RolapEvaluatorRoot root) {
this(root, null, null, null);
// we expect client to set CellReader
SchemaReader scr = this.root.connection.getSchemaReader();
Dimension[] dimensions = this.root.cube.getDimensions();
for (int i = 0; i < dimensions.length; i++) {
final Dimension dimension = dimensions[i];
final int ordinal = dimension.getOrdinal(this.root.cube);
final Hierarchy hier = dimension.getHierarchy();
Member member = scr.getHierarchyDefaultMember(hier);
// If there is no member, we cannot continue.
if (member == null) {
throw MondrianResource.instance().InvalidHierarchyCondition.ex(hier.getUniqueName());
}
HierarchyUsage[] hierarchyUsages = this.root.cube.getUsages(hier);
if (hierarchyUsages.length != 0) {
((RolapMember) member).makeUniqueName(hierarchyUsages[0]);
}
currentMembers[ordinal] = member;
}
}
protected static class RolapEvaluatorRoot {
final RolapResult result;
final Map expResultCache = new HashMap();
final RolapCube cube;
final RolapConnection connection;
final SchemaReader schemaReader;
RolapEvaluatorRoot(RolapResult result) {
this.result = result;
this.cube = (RolapCube) result.getQuery().getCube();
this.connection = (RolapConnection) result.getQuery().getConnection();
this.schemaReader = cube.getSchemaReader(connection.role);
}
}
protected Logger getLogger() {
return LOGGER;
}
Member[] getCurrentMembers() {
return this.currentMembers;
}
void setCellReader(CellReader cellReader) {
this.cellReader = cellReader;
}
public Cube getCube() {
return root.cube;
}
public Query getQuery() {
return root.result.getQuery();
}
public int getDepth() {
return depth;
}
public Evaluator getParent() {
return parent;
}
public SchemaReader getSchemaReader() {
return root.schemaReader;
}
public Evaluator push(Member[] members) {
final RolapEvaluator evaluator = _push();
evaluator.setContext(members);
return evaluator;
}
public Evaluator push(Member member) {
final RolapEvaluator evaluator = _push();
evaluator.setContext(member);
return evaluator;
}
public Evaluator push() {
return _push();
}
/**
* Creates a clone of the current validator.
*/
protected RolapEvaluator _push() {
Member[] cloneCurrentMembers = (Member[]) this.currentMembers.clone();
return new RolapEvaluator(
root,
this,
cellReader,
cloneCurrentMembers);
}
public Evaluator pop() {
return parent;
}
public Object visit(Literal literal) {
return literal.getValue();
}
public Object visit(Parameter parameter) {
return parameter.getExp().evaluate(this);
}
public Object visit(FunCall funCall) {
FunDef funDef = funCall.getFunDef();
return funDef.evaluate(this, funCall.getArgs());
}
public Object visit(Id id) {
throw new Error("unsupported");
}
public Object visit(OlapElement mdxElement) {
return mdxElement;
}
public Member setContext(Member member) {
RolapMember m = (RolapMember) member;
int ordinal = m.getDimension().getOrdinal(root.cube);
Member previous = currentMembers[ordinal];
currentMembers[ordinal] = m;
return previous;
}
public void setContext(Member[] members) {
for (int i = 0; i < members.length; i++) {
Member member = members[i];
// more than one usage
if (member == null) {
if (getLogger().isDebugEnabled()) {
getLogger().debug(
"RolapEvaluator.setContext: member == null "
+ " , count=" + i);
}
continue;
}
setContext(member);
}
}
public Member getContext(Dimension dimension) {
return currentMembers[dimension.getOrdinal(root.cube)];
}
public Object evaluateCurrent() {
Member maxSolveMember = getMaxSolveMember();
if (maxSolveMember != null) {
// There is at least one calculated member. Expand the first one
// with the highest solve order.
RolapMember defaultMember = (RolapMember)
maxSolveMember.getHierarchy().getDefaultMember();
Util.assertTrue(
defaultMember != maxSolveMember,
"default member must not be calculated");
RolapEvaluator evaluator = (RolapEvaluator) push(defaultMember);
evaluator.setExpanding(maxSolveMember);
//((RolapEvaluator) evaluator).cellReader = new CachingCellReader(cellReader);
return maxSolveMember.getExpression().evaluateScalar(evaluator);
}
return cellReader.get(this);
}
/**
* Returns the member in the current context which is (a) calculated, and
* (b) has the highest solve order; returns null if there are no calculated
* members.
*/
private Member getMaxSolveMember() {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?