📄 xmla_util.java
字号:
/*
* ====================================================================
* 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) 2003-2004 TONBELLER AG.
* All Rights Reserved.
* You must accept the terms of that agreement to use this software.
* ====================================================================
*
*
*/
package com.tonbeller.jpivot.xmla;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import com.tonbeller.jpivot.olap.mdxparse.Exp;
import com.tonbeller.jpivot.olap.mdxparse.FunCall;
import com.tonbeller.jpivot.olap.mdxparse.Literal;
import com.tonbeller.jpivot.olap.model.Axis;
import com.tonbeller.jpivot.olap.model.Hierarchy;
import com.tonbeller.jpivot.olap.model.Member;
import com.tonbeller.jpivot.olap.model.OlapException;
import com.tonbeller.jpivot.util.TreeNode;
import com.tonbeller.jpivot.util.TreeNodeCallback;
/**
* static XMLA Utils
*/
public class XMLA_Util {
static Logger logger = Logger.getLogger(XMLA_Util.class);
/**
* generate Exp[] from Member[]
* @param members
* @return Exp[]
* @deprecated
*/
public static Exp[] member2Exp(Member[] members) {
Exp[] memExp = new Exp[members.length];
for (int i = 0; i < memExp.length; i++) {
memExp[i] = Literal.createSymbol(((XMLA_Member) members[i]).getUniqueName());
}
return memExp;
}
/**
* generate Exp from Member
* @param member
* @return Exp
* @deprecated
*/
public static Exp member2Exp(Member member) {
return Literal.createSymbol(member.getLabel());
}
/**
* determine hierarchy index on axis
* @param axis
* @param member
* @return int
*/
public static int hierIndex(XMLA_Axis axis, XMLA_Member member) {
XMLA_Level lev = (XMLA_Level) member.getLevel();
XMLA_Hierarchy hier = (XMLA_Hierarchy) lev.getHierarchy();
return hierIndex(axis, hier);
}
/**
* determine hierarchy index on axis
* @param axis
* @param hier
* @return int
*/
public static int hierIndex(XMLA_Axis axis, XMLA_Hierarchy hier) {
Hierarchy[] hiersOfAxis = axis.getHierarchies();
for (int j = 0; j < hiersOfAxis.length; j++) {
if (((XMLA_Hierarchy) hiersOfAxis[j]).isEqual(hier)) { return j; }
}
return -1; // should never get here
}
/**
* find the result axis for a member
*/
public static int axisOrdinalForMember(Axis[] axes, XMLA_Member member) {
XMLA_Level lev = (XMLA_Level) member.getLevel();
XMLA_Hierarchy hier = (XMLA_Hierarchy) lev.getHierarchy();
return axisOrdinalForHier(axes, hier);
}
/**
* find the result axis for a hierarchy
*/
public static int axisOrdinalForHier(Axis[] axes, XMLA_Hierarchy hier) {
AxesLoop: for (int i = 0; i < axes.length; i++) {
Hierarchy[] hiersOfAxis = axes[i].getHierarchies();
for (int j = 0; j < hiersOfAxis.length; j++) {
if (((XMLA_Hierarchy) hiersOfAxis[j]).isEqual(hier)) { return i; }
}
}
return -1; // should never get here
}
/**
* determine descendants of member at specific level
* @param scr SchemaReader
* @param member
* @param level
* @return descendants
*/
public static XMLA_Member[] getMemberDescendants(XMLA_Member member, XMLA_Level level)
throws OlapException {
int depth = level.getDepth();
XMLA_Level lev = (XMLA_Level) member.getLevel();
if (depth <= lev.getDepth())
return new XMLA_Member[0];
//XMLA_Member[] currentMembers = new XMLA_Member[] { member };
List currentMembers = new ArrayList();
currentMembers.add(member);
while (depth > lev.getDepth()) {
lev = lev.getChildLevel();
List aMembers = new ArrayList();
for (Iterator iter = currentMembers.iterator(); iter.hasNext();) {
XMLA_Member m = (XMLA_Member) iter.next();
XMLA_Member[] mems = m.getChildren();
for (int i = 0; i < mems.length; i++) {
aMembers.add(mems[i]);
}
}
currentMembers = aMembers;
}
return (XMLA_Member[]) currentMembers.toArray(new XMLA_Member[0]);
}
/**
* @param ancestor
* @param descendant
*/
public static boolean isDescendant(XMLA_Member ancestor, XMLA_Member descendant) {
// a calculated member, even if defined under "ancestor" is *not* descendant,
// WITM MEMBER a.b as '..'
// a.children does *not* include b
if (descendant.isCalculated())
return false;
if (ancestor.equals(descendant))
return false;
int ancestorLevelNumber = ((XMLA_Level) ancestor.getLevel()).getDepth();
XMLA_Member mm = descendant;
while (mm != null && ancestorLevelNumber < ((XMLA_Level) mm.getLevel()).getDepth()) {
try {
mm = (XMLA_Member) mm.getParent();
} catch (OlapException e) {
logger.error("?", e); // should not occur
break;
}
}
if (mm.equals(ancestor))
return true;
else
return false;
}
/**
* @return an Expression Object for the top level members of an hierarchy
*/
public static Exp topLevelMembers(Hierarchy hier, boolean expandAllMember) {
XMLA_Level topLevel = (XMLA_Level) ((XMLA_Hierarchy) hier).getLevels()[0];
XMLA_Member mAll = (XMLA_Member) ((XMLA_Hierarchy) hier).getAllMember();
// if there is an All Member, we will have to expand it
// according to expandAllMember flag
if (mAll != null ) {
XMLA_Member [] memar = new XMLA_Member[] {mAll};
Exp mAllSet = new FunCall("{}", memar, FunCall.TypeBraces);
if (!expandAllMember) {
return mAll;
}
// must expand
// create Union({AllMember}, AllMember.children)
Exp mAllChildren = new FunCall("children", memar, FunCall.TypeProperty);
Exp union = new FunCall("union", new Exp[] {mAllSet, mAllChildren}, FunCall.TypeFunction);
return union;
}
XMLA_Member[] topMembers;
try {
// HHTASK ok, for a parent-child hierarchy ?
topMembers = topLevel.getMembers();
} catch (OlapException e) {
// should not occur
logger.error("?", e);
return null;
}
if (topMembers.length == 1)
return topMembers[0]; // single member
return new FunCall("{}", topMembers, FunCall.TypeBraces);
}
/**
*
* @param root
* @param iDim
* @return
*/
static List collectMembers(TreeNode root, final int iDim) {
if (root == null)
return null;
final List memberList = new ArrayList();
root.walkChildren(new TreeNodeCallback() {
/**
* callback
* find node matching member Path exactly
*/
public int handleTreeNode(TreeNode node) {
int iDimNode = node.getLevel() - 1;
if (iDimNode < iDim)
return TreeNodeCallback.CONTINUE; // we are below iDim, don't care
// iDimNode == iDim
// node Exp must contain children of member[iDim]
Exp exp = (Exp) node.getReference();
if (exp instanceof XMLA_Member) {
XMLA_Member m = (XMLA_Member) exp;
if (!memberList.contains(m))
memberList.add(m);
} else {
// must be FunCall
FunCall f = (FunCall) exp;
try {
resolveFunCallMembers(f, memberList);
} catch (OlapException e) {
logger.error("?", e);
}
}
return TreeNodeCallback.CONTINUE_SIBLING; // continue next sibling
}
});
return memberList;
}
/**
*
* @param f
* @param memberList
*/
static void resolveFunCallMembers(FunCall f, List memberList) throws OlapException {
if (f.isCallTo("Children")) {
XMLA_Member m = (XMLA_Member) f.getArgs()[0];
XMLA_Member[] members = m.getChildren();
for (int i = 0; i < members.length; i++) {
if (!memberList.contains(members[i]))
memberList.add(members[i]);
}
} else if (f.isCallTo("Descendants")) {
XMLA_Member m = (XMLA_Member) f.getArgs()[0];
XMLA_Level level = (XMLA_Level) f.getArgs()[1];
XMLA_Member[] members = XMLA_Util.getMemberDescendants(m, level);
for (int i = 0; i < members.length; i++) {
if (!memberList.contains(members[i]))
memberList.add(members[i]);
}
} else if (f.isCallTo("Members")) {
XMLA_Level level = (XMLA_Level) f.getArgs()[0];
XMLA_Member[] members = level.getMembers();
for (int i = 0; i < members.length; i++) {
if (!memberList.contains(members[i]))
memberList.add(members[i]);
}
} else if (f.isCallTo("Union")) {
resolveFunCallMembers((FunCall) f.getArgs()[0], memberList);
resolveFunCallMembers((FunCall) f.getArgs()[1], memberList);
} else if (f.isCallTo("{}")) {
for (int i = 0; i < f.getArgs().length; i++) {
if (!memberList.contains(f.getArgs()[i]))
memberList.add(f.getArgs()[i]);
}
} else if (
// we cannot handle this properly, just return members of base set
f.isCallTo("TopCount") || f.isCallTo("BottomCount") || f.isCallTo("TopPercent")
|| f.isCallTo("BottomPercent")) {
resolveFunCallMembers((FunCall) f.getArgs()[0], memberList);
} else {
logger.error("invalid FunCall encountered " + f.getFunction());
}
}
/**
* Map function names to XMLA Function type
* @param fuName
* @return Syntax type
*/
public static int funCallSyntax(String fuName) {
if (fuName.equals("()"))
return FunCall.TypeParentheses;
else if (fuName.equals("{}"))
return FunCall.TypeBraces;
else if (fuName.equalsIgnoreCase("members"))
return FunCall.TypeProperty;
else if (fuName.equalsIgnoreCase("children"))
return FunCall.TypeProperty;
else
return FunCall.TypeFunction;
// HHTASK complete
}
} // End XMLA_Util
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -