001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/AncestorFunDef.java#1 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2006-2006 Julian Hyde 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.olap.fun; 011 012 import mondrian.olap.FunDef; 013 import mondrian.olap.Member; 014 import mondrian.olap.Evaluator; 015 import mondrian.olap.Level; 016 import mondrian.olap.type.Type; 017 import mondrian.olap.type.LevelType; 018 import mondrian.calc.*; 019 import mondrian.calc.impl.AbstractMemberCalc; 020 import mondrian.mdx.ResolvedFunCall; 021 022 /** 023 * Definition of the <code>Ancestor</code> MDX function. 024 * 025 * @author jhyde 026 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/AncestorFunDef.java#1 $ 027 * @since Mar 23, 2006 028 */ 029 class AncestorFunDef extends FunDefBase { 030 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 031 "Ancestor", 032 "Ancestor(<Member>, {<Level>|<Numeric Expression>})", 033 "Returns the ancestor of a member at a specified level.", 034 new String[] {"fmml", "fmmn"}, 035 AncestorFunDef.class); 036 037 public AncestorFunDef(FunDef dummyFunDef) { 038 super(dummyFunDef); 039 } 040 041 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 042 final MemberCalc memberCalc = 043 compiler.compileMember(call.getArg(0)); 044 final Type type1 = call.getArg(1).getType(); 045 if (type1 instanceof LevelType) { 046 final LevelCalc levelCalc = 047 compiler.compileLevel(call.getArg(1)); 048 return new AbstractMemberCalc(call, new Calc[] {memberCalc, levelCalc}) { 049 public Member evaluateMember(Evaluator evaluator) { 050 Level level = levelCalc.evaluateLevel(evaluator); 051 Member member = memberCalc.evaluateMember(evaluator); 052 int distance = 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(call, new Calc[] {memberCalc, distanceCalc}) { 060 public Member evaluateMember(Evaluator evaluator) { 061 int distance = distanceCalc.evaluateInteger(evaluator); 062 Member member = memberCalc.evaluateMember(evaluator); 063 return ancestor(evaluator, member, distance, null); 064 } 065 }; 066 } 067 } 068 } 069 070 // End AncestorFunDef.java