001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2006-2011 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.olap.fun; 011 012import mondrian.calc.*; 013import mondrian.calc.impl.AbstractMemberCalc; 014import mondrian.mdx.ResolvedFunCall; 015import mondrian.olap.*; 016import mondrian.rolap.RolapHierarchy; 017 018import java.util.Map; 019 020/** 021 * Definition of the <code><Hierarchy>.CurrentMember</code> MDX 022 * builtin function. 023 * 024 * @author jhyde 025 * @since Mar 23, 2006 026 */ 027public class HierarchyCurrentMemberFunDef extends FunDefBase { 028 static final HierarchyCurrentMemberFunDef instance = 029 new HierarchyCurrentMemberFunDef(); 030 031 private HierarchyCurrentMemberFunDef() { 032 super( 033 "CurrentMember", 034 "Returns the current member along a hierarchy during an iteration.", 035 "pmh"); 036 } 037 038 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 039 final HierarchyCalc hierarchyCalc = 040 compiler.compileHierarchy(call.getArg(0)); 041 final Hierarchy hierarchy = hierarchyCalc.getType().getHierarchy(); 042 if (hierarchy != null) { 043 return new FixedCalcImpl(call, hierarchy); 044 } else { 045 return new CalcImpl(call, hierarchyCalc); 046 } 047 } 048 049 /** 050 * Compiled implementation of the Hierarchy.CurrentMember function that 051 * evaluates the hierarchy expression first. 052 */ 053 public static class CalcImpl extends AbstractMemberCalc { 054 private final HierarchyCalc hierarchyCalc; 055 056 public CalcImpl(Exp exp, HierarchyCalc hierarchyCalc) { 057 super(exp, new Calc[] {hierarchyCalc}); 058 this.hierarchyCalc = hierarchyCalc; 059 } 060 061 protected String getName() { 062 return "CurrentMember"; 063 } 064 065 public Member evaluateMember(Evaluator evaluator) { 066 Hierarchy hierarchy = hierarchyCalc.evaluateHierarchy(evaluator); 067 return evaluator.getContext(hierarchy); 068 } 069 070 public boolean dependsOn(Hierarchy hierarchy) { 071 return hierarchyCalc.getType().usesHierarchy(hierarchy, false); 072 } 073 } 074 075 /** 076 * Compiled implementation of the Hierarchy.CurrentMember function that 077 * uses a fixed hierarchy. 078 */ 079 public static class FixedCalcImpl extends AbstractMemberCalc { 080 // getContext works faster if we give RolapHierarchy rather than 081 // Hierarchy 082 private final RolapHierarchy hierarchy; 083 084 public FixedCalcImpl(Exp exp, Hierarchy hierarchy) { 085 super(exp, new Calc[] {}); 086 assert hierarchy != null; 087 this.hierarchy = (RolapHierarchy) hierarchy; 088 } 089 090 protected String getName() { 091 return "CurrentMemberFixed"; 092 } 093 094 public Member evaluateMember(Evaluator evaluator) { 095 return evaluator.getContext(hierarchy); 096 } 097 098 public boolean dependsOn(Hierarchy hierarchy) { 099 return this.hierarchy == hierarchy; 100 } 101 102 public void collectArguments(Map<String, Object> arguments) { 103 arguments.put("hierarchy", hierarchy); 104 super.collectArguments(arguments); 105 } 106 } 107} 108 109// End HierarchyCurrentMemberFunDef.java