001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/fun/extra/CalculatedChildFunDef.java#6 $ 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-2007 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.extra; 011 012 import mondrian.olap.*; 013 import mondrian.olap.fun.FunDefBase; 014 import mondrian.calc.*; 015 import mondrian.calc.impl.AbstractMemberCalc; 016 import mondrian.mdx.ResolvedFunCall; 017 018 import java.util.List; 019 020 /** 021 * Definition of the <code>CalculatedChild</code> MDX function. 022 * 023 * <p>Syntax: 024 * <blockquote><code><Member>CalculatedChild(<String>)</code></blockquote> 025 * 026 * @author bchow 027 * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/extra/CalculatedChildFunDef.java#6 $ 028 * @since 2006/4/12 029 */ 030 public class CalculatedChildFunDef extends FunDefBase { 031 public static final CalculatedChildFunDef instance = new CalculatedChildFunDef(); 032 033 CalculatedChildFunDef() { 034 super("CalculatedChild", 035 "Returns an existing calculated child member with name <String> from the specified <Member>.", 036 "mmmS"); 037 } 038 039 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 040 final MemberCalc memberCalc = compiler.compileMember(call.getArg(0)); 041 final StringCalc stringCalc = compiler.compileString(call.getArg(1)); 042 043 return new AbstractMemberCalc(call, new Calc[] {memberCalc, stringCalc}) { 044 public Member evaluateMember(Evaluator evaluator) { 045 Member member = memberCalc.evaluateMember(evaluator); 046 String name = stringCalc.evaluateString(evaluator); 047 return getCalculatedChild(member, name, evaluator); 048 } 049 }; 050 } 051 052 private Member getCalculatedChild( 053 Member parent, String childName, Evaluator evaluator) { 054 055 final SchemaReader schemaReader = 056 evaluator.getQuery().getSchemaReader(true); 057 Level childLevel = parent.getLevel().getChildLevel(); 058 if (childLevel == null) { 059 return parent.getHierarchy().getNullMember(); 060 } 061 List<Member> calcMemberList = 062 schemaReader.getCalculatedMembers(childLevel); 063 064 for (Member child : calcMemberList) { 065 // the parent check is required in case there are parallel children 066 // with the same names 067 if (child.getParentMember().equals(parent) && 068 child.getName().equals(childName)) { 069 return child; 070 } 071 } 072 073 return parent.getHierarchy().getNullMember(); 074 } 075 } 076 077 078 // End CalculatedChildFunDef.java