1 10 package mondrian.olap.fun; 11 12 import mondrian.olap.*; 13 import mondrian.olap.type.Type; 14 import mondrian.olap.type.MemberType; 15 import mondrian.calc.*; 16 import mondrian.calc.impl.DimensionCurrentMemberCalc; 17 import mondrian.calc.impl.ConstantCalc; 18 import mondrian.calc.impl.AbstractMemberCalc; 19 import mondrian.mdx.ResolvedFunCall; 20 import mondrian.resource.MondrianResource; 21 22 29 class ParallelPeriodFunDef extends FunDefBase { 30 static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver( 31 "ParallelPeriod", 32 "ParallelPeriod([<Level>[, <Numeric Expression>[, <Member>]]])", 33 "Returns a member from a prior period in the same relative position as a specified member.", 34 new String [] {"fm", "fml", "fmln", "fmlnm"}, 35 ParallelPeriodFunDef.class); 36 37 public ParallelPeriodFunDef(FunDef dummyFunDef) { 38 super(dummyFunDef); 39 } 40 41 public Type getResultType(Validator validator, Exp[] args) { 42 if (args.length == 0) { 43 Hierarchy hierarchy = validator.getQuery() 47 .getCube().getTimeDimension() 48 .getHierarchy(); 49 return MemberType.forHierarchy(hierarchy); 50 } 51 return super.getResultType(validator, args); 52 } 53 54 public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) { 55 Exp[] args = call.getArgs(); 57 final MemberCalc memberCalc; 58 switch (args.length) { 59 case 3: 60 memberCalc = compiler.compileMember(args[2]); 61 break; 62 case 1: 63 final Dimension dimension = 64 args[0].getType().getHierarchy().getDimension(); 65 memberCalc = new DimensionCurrentMemberCalc(dimension); 66 break; 67 default: 68 final Dimension timeDimension = 69 compiler.getEvaluator().getCube() 70 .getTimeDimension(); 71 memberCalc = new DimensionCurrentMemberCalc( 72 timeDimension); 73 break; 74 } 75 76 final IntegerCalc lagValueCalc = (args.length >= 2) ? 78 compiler.compileInteger(args[1]) : 79 ConstantCalc.constantInteger(1); 80 81 final LevelCalc ancestorLevelCalc = 84 args.length >= 1 ? 85 compiler.compileLevel(args[0]) : 86 null; 87 88 return new AbstractMemberCalc(call, new Calc[] {memberCalc, lagValueCalc, ancestorLevelCalc}) { 89 public Member evaluateMember(Evaluator evaluator) { 90 Member member = memberCalc.evaluateMember( 91 evaluator); 92 int lagValue = lagValueCalc.evaluateInteger( 93 evaluator); 94 Level ancestorLevel; 95 if (ancestorLevelCalc != null) { 96 ancestorLevel = ancestorLevelCalc 97 .evaluateLevel(evaluator); 98 } else { 99 Member parent = member.getParentMember(); 100 if (parent == null) { 101 return member.getHierarchy() 104 .getNullMember(); 105 } 106 ancestorLevel = parent.getLevel(); 107 } 108 return parallelPeriod(member, ancestorLevel, 109 evaluator, lagValue); 110 } 111 }; 112 } 113 114 Member parallelPeriod( 115 Member member, 116 Level ancestorLevel, 117 Evaluator evaluator, 118 int lagValue) { 119 if (member.getHierarchy() != ancestorLevel.getHierarchy()) { 123 MondrianResource.instance().FunctionMbrAndLevelHierarchyMismatch.ex( 124 "ParallelPeriod", ancestorLevel.getHierarchy().getUniqueName(), 125 member.getHierarchy().getUniqueName() 126 ); 127 } 128 129 int distance = member.getLevel().getDepth() - 130 ancestorLevel.getDepth(); 131 Member ancestor = FunUtil.ancestor( 132 evaluator, member, distance, ancestorLevel); 133 Member inLaw = evaluator.getSchemaReader() 134 .getLeadMember(ancestor, -lagValue); 135 return FunUtil.cousin( 136 evaluator.getSchemaReader(), member, inLaw); 137 } 138 } 139 140 | Popular Tags |