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.olap.type.LevelType; 017import mondrian.olap.type.Type; 018 019/** 020 * Definition of the <code>Ancestor</code> MDX function. 021 * 022 * @author jhyde 023 * @since Mar 23, 2006 024 */ 025class AncestorFunDef extends FunDefBase { 026 static final ReflectiveMultiResolver Resolver = 027 new ReflectiveMultiResolver( 028 "Ancestor", 029 "Ancestor(<Member>, {<Level>|<Numeric Expression>})", 030 "Returns the ancestor of a member at a specified level.", 031 new String[] {"fmml", "fmmn"}, 032 AncestorFunDef.class); 033 034 public AncestorFunDef(FunDef dummyFunDef) { 035 super(dummyFunDef); 036 } 037 038 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 039 final MemberCalc memberCalc = 040 compiler.compileMember(call.getArg(0)); 041 final Type type1 = call.getArg(1).getType(); 042 if (type1 instanceof LevelType) { 043 final LevelCalc levelCalc = 044 compiler.compileLevel(call.getArg(1)); 045 return new AbstractMemberCalc( 046 call, new Calc[] {memberCalc, levelCalc}) 047 { 048 public Member evaluateMember(Evaluator evaluator) { 049 Level level = levelCalc.evaluateLevel(evaluator); 050 Member member = memberCalc.evaluateMember(evaluator); 051 int distance = 052 member.getLevel().getDepth() - level.getDepth(); 053 return ancestor(evaluator, member, distance, level); 054 } 055 }; 056 } else { 057 final IntegerCalc distanceCalc = 058 compiler.compileInteger(call.getArg(1)); 059 return new AbstractMemberCalc( 060 call, new Calc[] {memberCalc, distanceCalc}) 061 { 062 public Member evaluateMember(Evaluator evaluator) { 063 int distance = distanceCalc.evaluateInteger(evaluator); 064 Member member = memberCalc.evaluateMember(evaluator); 065 return ancestor(evaluator, member, distance, null); 066 } 067 }; 068 } 069 } 070} 071 072// End AncestorFunDef.java