📄 xmla_member.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.List;
import org.apache.log4j.Logger;
import com.tonbeller.jpivot.olap.mdxparse.CompoundId;
import com.tonbeller.jpivot.olap.mdxparse.Exp;
import com.tonbeller.jpivot.olap.mdxparse.ExpVisitor;
import com.tonbeller.jpivot.olap.model.Dimension;
import com.tonbeller.jpivot.olap.model.Hierarchy;
import com.tonbeller.jpivot.olap.model.Level;
import com.tonbeller.jpivot.olap.model.Member;
import com.tonbeller.jpivot.olap.model.OlapDiscoverer;
import com.tonbeller.jpivot.olap.model.OlapException;
import com.tonbeller.jpivot.olap.model.Property;
import com.tonbeller.jpivot.olap.model.Visitor;
import com.tonbeller.jpivot.olap.query.MDXMember;
import com.tonbeller.jpivot.util.StringUtil;
/**
* Member Implementation for XMLA
*/
public class XMLA_Member implements Member, MDXMember, Exp {
static Logger logger = Logger.getLogger(XMLA_Member.class);
private XMLA_Model model;
private long ordinal;
private String name;
private int type;
private String caption;
private long childrenCardinality = -1;
private long parentLevel;
private String uniqueName;
private String parentUniqueName = null;
private String key;
private boolean isPlaceHolderMember;
private boolean isDataMember;
private long displayInfo = -1;
private String dimUName = null;
// dimension unique name for calculated members
private XMLA_Level level;
private XMLA_Member parent = null;
private ArrayList aChildren = null;
//private Property[] properties = null;
private List properties = new ArrayList();
private boolean isCalculated; // for a formula member
private boolean complete = false; // completely initialized
private boolean propsOk = false;
private boolean childrenOk = false;
private boolean parentOk = false;
/**
* c'tor
* @param uName
* @param caption
* @param levUname
* @param levelNumber
* @param hierUName
* @param lev
*/
public XMLA_Member(
XMLA_Model model,
String uName,
String caption,
XMLA_Level lev,
boolean isCalculated) {
if (!(model.lookupMemberByUName(uName) == null)) {
// error - should never occur
logger.fatal("cannot create member doubly " + uName);
throw new IllegalArgumentException("cannot create member doubly " + uName);
}
this.model = model;
this.uniqueName = uName;
this.caption = caption;
this.level = lev;
this.isCalculated = isCalculated;
logger.debug("<init>: uName - " + uName + ", level - " + lev + ", isCalculated - " + isCalculated);
model.addMember(this);
if (model.isMicrosoft() || isCalculated) {
parentUniqueName = StringUtil.parentFromUName(uName);
if (parentUniqueName == null) {
parent = null;
parentOk = true;
logger.debug("parentUniqueName from uName: " + uName + " == null");
} else {
parent = (XMLA_Member) model.lookupMemberByUName(parentUniqueName);
logger.debug("lookupMemberByUName(" + parentUniqueName + "): " + parent);
if (parent != null)
parentOk = true;
}
}
// SAP does not return a level name for a calculated measure
// another bug?
// we need (?) a level, so try to get it
// a normal member (not calculated) should always have a level
if (level == null && isCalculated) {
// get the dimension from the unique name
String dimUname = StringUtil.dimFromUName(uniqueName);
XMLA_Dimension dim = model.lookupDimByUName(dimUname);
logger.debug("looked up dimension name: " + uniqueName + " = " + dim);
if (dim != null) {
if (dim.isMeasure()) {
// assign measures level
Hierarchy[] hiers = dim.getHierarchies();
Level[] levs = hiers[0].getLevels();
level = (XMLA_Level) levs[0];
logger.debug("isMeasure: " + level);
} else {
// normal dimension
// if it is NOT SAP (no parent supported) and
// if the unique name contains a parent - get the level from parent
XMLA_Member pm = null;
if (model.isMicrosoft() && parentUniqueName != null) {
pm = (XMLA_Member) model.lookupMemberByUName(parentUniqueName);
if (pm != null)
level = ((XMLA_Level) pm.getLevel()).getChildLevel();
logger.debug("normal dimension: " + level);
}
if (level == null) {
// don't know how to find level
// try default hierarchy - top level
Hierarchy hier = null;
if (pm != null) {
hier = pm.getHierarchy();
logger.debug("hierarchy from member: " + hier);
} else {
String hierUname = dim.getDefaultHier();
hier = model.lookupHierByUName(hierUname);
logger.debug("hierarchy from DefaultHier: " + hier);
}
if (hier != null) {
logger.debug("trying default hierarchy: " + hier);
// take the level with number 0
Level[] levs = hier.getLevels();
for (int i = 0; i < levs.length; i++) {
if (((XMLA_Level) levs[i]).getDepth() == 0) {
level = (XMLA_Level) levs[i];
break;
}
} // for levs
}
}
} // else
} // if dim != null
} // if level == null
// won't survive without a level
// better crash here than later
if (level == null)
throw new IllegalArgumentException("Member " + uName + " Level=null");
if (level.getChildLevel() == null || isCalculated) {
childrenCardinality = 0;
childrenOk = true;
}
}
/**
*
* @param other
* @return boolean
*/
public boolean isEqual(Member otherM) {
XMLA_Member other = (XMLA_Member) otherM;
return this.uniqueName.equals(other.uniqueName);
}
/**
* determine, whether this member is descendant of other member
* @param other
* @return boolean
*/
public boolean isChildOf(Member otherM) throws OlapException {
XMLA_Member other = (XMLA_Member) otherM;
// if not the same hierarchy, say no
XMLA_Hierarchy thisHier = (XMLA_Hierarchy) level.getHierarchy();
XMLA_Hierarchy otherHier = (XMLA_Hierarchy) other.getLevel().getHierarchy();
if (!thisHier.isEqual(otherHier))
return false;
// cannot be a child, if the level is not higher
long otherLevelNumber = ((XMLA_Level) other.getLevel()).getDepth();
if (!(level.getDepth() > otherLevelNumber))
return false;
// go up parent chain
XMLA_Member m = this;
while (m.level.getDepth() > otherLevelNumber) {
m = (XMLA_Member) m.getParent();
}
if (m.isEqual(other))
return true;
return false;
}
/**
* @see com.tonbeller.jpivot.olap.model.Visitable#accept(Visitor)
*/
public void accept(Visitor visitor) {
visitor.visitMember(this);
}
public Object getRootDecoree() {
return this;
}
/**
* Returns the caption as Label.
* @return String
*/
public String getLabel() {
return caption;
}
/**
* Returns the caption.
* @return String
*/
public String getCaption() {
return caption;
}
/**
* Returns the childrenCardinality.
* @return int
*/
public long getChildrenCardinality() {
return childrenCardinality;
}
/**
* Returns the isDataMember.
* @return boolean
*/
public boolean isDataMember() {
return isDataMember;
}
/**
* Returns the isPlaceHolderMember.
* @return boolean
*/
public boolean isPlaceHolderMember() {
return isPlaceHolderMember;
}
/**
* Returns the key.
* @return String
*/
public String getKey() {
return key;
}
/**
* Returns the name.
* @return String
*/
public String getName() {
return name;
}
/**
* Returns the ordinal.
* @return int
*/
public long getOrdinal() {
return ordinal;
}
/**
* Returns the parentLevel.
* @return int
*/
public long getParentLevel() {
return parentLevel;
}
/**
* Returns the type.
* @return int
*/
public int getType() {
return type;
}
/**
* Returns the uniqueName.
* @return String
*/
public String getUniqueName() {
return uniqueName;
}
/**
* set all attributes, which were not set in the c'tor
* @param name
* @param type
* @param ordinal
* @param parentUniqueName
* @param childrenCardinality
* @param parentLevel
* @param isDataMember
* @param isPlaceHolderMember
* @param key
*/
public void complete(
String name,
int type,
long ordinal,
String parentUniqueName,
long childrenCardinality,
long parentLevel,
boolean isDataMember,
boolean isPlaceHolderMember,
String key) {
this.childrenCardinality = childrenCardinality;
this.isDataMember = isDataMember;
this.isPlaceHolderMember = isPlaceHolderMember;
this.key = key;
this.name = name;
this.ordinal = ordinal;
this.parentLevel = parentLevel;
this.type = type;
this.parentUniqueName = parentUniqueName;
complete = true;
}
/**
* Returns the parentUniqueName.
* @return String
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -