-
-
Save mysticfall/4e7eba3f129c49152669 to your computer and use it in GitHub Desktop.
Attempt to fix #116. It's not working as it is, because the quax doesn't provide any information about functions at the time of the invocation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PlaceMembersOnAxesImpl extends AbstractTransform implements | |
PlaceMembersOnAxes { | |
/** | |
* @see com.eyeq.pivot4j.transform.PlaceMembersOnAxes#placeMembers(org.olap4j.metadata.Hierarchy, | |
* java.util.List) | |
*/ | |
@Override | |
public void placeMembers(Hierarchy hierarchy, List<Member> members) { | |
QueryAdapter adapter = getQueryAdapter(); | |
Quax quax = adapter.findQuax(hierarchy.getDimension()); | |
if (quax == null) { | |
throw new IllegalArgumentException( | |
"Cannot find the specified hierarchy on any axis."); | |
} | |
// First, check to see if all the hierarchies have only the default | |
// members and the .Children functions. In that case, we try to preserve | |
// them instead of adding only visible members (#116). | |
List<Hierarchy> hierarchies = quax.getHierarchies(); | |
Map<Hierarchy, SelectionChecker> checkers = new HashMap<Hierarchy, SelectionChecker>( | |
hierarchies.size()); | |
for (Hierarchy hier : hierarchies) { | |
if (!OlapUtils.equals(hier, hierarchy)) { | |
SelectionChecker checker = new SelectionChecker(hier); | |
quax.getPosTreeRoot().walkTree(checker); | |
if (checker.getAllMember() != null) { | |
checkers.put(hierarchy, checker); | |
} | |
} | |
} | |
OlapUtils utils = new OlapUtils(getModel().getCube()); | |
List<Exp> expressions = new ArrayList<Exp>(hierarchies.size()); | |
for (Hierarchy hier : hierarchies) { | |
SelectionChecker checker = checkers.get(hier); | |
boolean targetHierarchy = OlapUtils.equals(hier, hierarchy); | |
if (checker == null) { | |
List<Member> selection; | |
if (targetHierarchy) { | |
selection = members; | |
} else { | |
selection = findVisibleMembers(hier); | |
} | |
List<Exp> sets = new ArrayList<Exp>(selection.size()); | |
if (selection.size() == 1) { | |
expressions.add(new MemberExp(utils | |
.wrapRaggedIfNecessary(selection.get(0)))); | |
} else { | |
for (Member member : selection) { | |
sets.add(new MemberExp(utils | |
.wrapRaggedIfNecessary(member))); | |
} | |
expressions.add(new FunCall("{}", Syntax.Braces, sets)); | |
} | |
} else if (checker.isExpanded()) { | |
Member wrap = utils.wrapRaggedIfNecessary(checker | |
.getAllMember()); | |
FunCall set = new FunCall("{}", Syntax.Braces); | |
FunCall children = new FunCall("Children", Syntax.Property); | |
children.getArgs().add(new MemberExp(wrap)); | |
set.getArgs().add(new MemberExp(wrap)); | |
set.getArgs().add(children); | |
expressions.add(set); | |
} else { | |
expressions.add(new MemberExp(utils | |
.wrapRaggedIfNecessary(checker.getAllMember()))); | |
} | |
} | |
// generate the crossjoins | |
quax.regeneratePosTree(expressions, false); | |
if (logger.isDebugEnabled()) { | |
logger.debug("setQueryAxis axis={}, nDimension={}", | |
quax.getOrdinal(), hierarchies.size()); | |
logger.debug("Expression for the axis : {}", quax); | |
} | |
} | |
class SelectionChecker implements TreeNodeCallback<Exp> { | |
private QuaxUtil util = new QuaxUtil(getModel().getCube()); | |
private Hierarchy hierarchy; | |
private Member allMember; | |
private int allMemberCount = 0; | |
private int expandedCount = 0; | |
private boolean hasSelection = false; | |
/** | |
* @param hierarchy | |
*/ | |
SelectionChecker(Hierarchy hierarchy) { | |
if (hierarchy == null) { | |
throw new NullArgumentException("hierarchy"); | |
} | |
this.hierarchy = hierarchy; | |
} | |
/** | |
* @see com.eyeq.pivot4j.util.TreeNodeCallback#handleTreeNode(com.eyeq.pivot4j.util.TreeNode) | |
*/ | |
@Override | |
public int handleTreeNode(TreeNode<Exp> node) { | |
Exp exp = node.getReference(); | |
if (exp != null) { | |
checkExp(exp); | |
} | |
if (hasSelection) { | |
return BREAK; | |
} | |
return CONTINUE; | |
} | |
void checkExp(Exp exp) { | |
if (util.isMember(exp)) { | |
checkMember(util.memberForExp(exp)); | |
} else if (util.isFunCallTo(exp, "{}") | |
|| util.isFunCallTo(exp, "CrossJoin") | |
|| util.isFunCallTo(exp, "Hierarchize") | |
|| util.isFunCallTo(exp, "Union")) { | |
FunCall func = (FunCall) exp; | |
for (Exp arg : func.getArgs()) { | |
checkExp(arg); | |
} | |
} else if (util.isFunCallTo(exp, "Children")) { | |
Member parent = util.memberForExp(util.funCallArg(exp, 0)); | |
if (OlapUtils.equals(hierarchy, parent.getHierarchy())) { | |
this.expandedCount++; | |
} | |
} | |
} | |
void checkMember(Member member) { | |
if (OlapUtils.equals(hierarchy, member.getHierarchy())) { | |
if (member.isAll()) { | |
this.allMember = member; | |
this.allMemberCount++; | |
} else { | |
this.allMember = null; | |
this.hasSelection = true; | |
} | |
} | |
} | |
/** | |
* @return the allMember | |
*/ | |
public Member getAllMember() { | |
return allMember; | |
} | |
/** | |
* @return the expanded | |
*/ | |
public boolean isExpanded() { | |
return allMemberCount == expandedCount; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment