KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > olap > fun > LastPeriodsFunDef


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/olap/fun/LastPeriodsFunDef.java#2 $
3 // This software is subject to the terms of the Common Public License
4 // Agreement, available at the following URL:
5 // http://www.opensource.org/licenses/cpl.html.
6 // Copyright (C) 2006-2006 Julian Hyde
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

10 package mondrian.olap.fun;
11
12 import mondrian.olap.*;
13 import mondrian.olap.type.Type;
14 import mondrian.olap.type.SetType;
15 import mondrian.olap.type.MemberType;
16 import mondrian.olap.type.TypeUtil;
17 import mondrian.calc.Calc;
18 import mondrian.calc.ExpCompiler;
19 import mondrian.calc.MemberCalc;
20 import mondrian.calc.IntegerCalc;
21 import mondrian.calc.impl.DimensionCurrentMemberCalc;
22 import mondrian.calc.impl.AbstractListCalc;
23 import mondrian.mdx.ResolvedFunCall;
24
25 import java.util.List JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.ArrayList JavaDoc;
28
29 /**
30  * Definition of the <code>LastPeriods</code> MDX function.
31  *
32  * @author jhyde
33  * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/LastPeriodsFunDef.java#2 $
34  * @since Mar 23, 2006
35  */

36 class LastPeriodsFunDef extends FunDefBase {
37     static final ReflectiveMultiResolver Resolver = new ReflectiveMultiResolver(
38             "LastPeriods",
39             "LastPeriods(<Index> [, <Member>])",
40             "Returns a set of members prior to and including a specified member.",
41             new String JavaDoc[] {"fxn", "fxnm"},
42             LastPeriodsFunDef.class);
43
44     public LastPeriodsFunDef(FunDef dummyFunDef) {
45         super(dummyFunDef);
46     }
47
48     public Type getResultType(Validator validator, Exp[] args) {
49         if (args.length == 1) {
50             // If Member is not specified,
51
// it is Time.CurrentMember.
52
Hierarchy hierarchy = validator.getQuery()
53                     .getCube().getTimeDimension()
54                     .getHierarchy();
55             return new SetType(MemberType.forHierarchy(hierarchy));
56         } else {
57             Type type = args[1].getType();
58             Type memberType =
59             TypeUtil.toMemberOrTupleType(type);
60             return new SetType(memberType);
61         }
62     }
63
64     public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
65         // Member defaults to [Time].currentmember
66
Exp[] args = call.getArgs();
67         final MemberCalc memberCalc;
68         if (args.length == 1) {
69             Dimension timeDimension =
70                     compiler.getEvaluator().getCube()
71                     .getTimeDimension();
72             memberCalc = new DimensionCurrentMemberCalc(
73                     timeDimension);
74         } else {
75             memberCalc = compiler.compileMember(args[1]);
76         }
77
78         // Numeric Expression.
79
final IntegerCalc indexValueCalc =
80                 compiler.compileInteger(args[0]);
81
82         return new AbstractListCalc(call, new Calc[] {memberCalc, indexValueCalc}) {
83             public List JavaDoc evaluateList(Evaluator evaluator) {
84                 Member member = memberCalc.evaluateMember(evaluator);
85                 int indexValue = indexValueCalc.evaluateInteger(evaluator);
86
87                 return lastPeriods(member, evaluator, indexValue);
88             }
89         };
90     }
91
92     /*
93         If Index is positive, returns the set of Index
94         members ending with Member and starting with the
95         member lagging Index - 1 from Member.
96
97         If Index is negative, returns the set of (- Index)
98         members starting with Member and ending with the
99         member leading (- Index - 1) from Member.
100
101         If Index is zero, the empty set is returned.
102     */

103     List JavaDoc<Member> lastPeriods(
104             Member member,
105             Evaluator evaluator,
106             int indexValue) {
107         // empty set
108
if ((indexValue == 0) || member.isNull()) {
109             return Collections.emptyList();
110         }
111         List JavaDoc<Member> list = new ArrayList JavaDoc<Member>();
112
113         // set with just member
114
if ((indexValue == 1) || (indexValue == -1)) {
115             list.add(member);
116             return list;
117         }
118
119         // When null is found, getting the first/last
120
// member at a given level is not particularly
121
// fast.
122
Member startMember;
123         Member endMember;
124         if (indexValue > 0) {
125             startMember = evaluator.getSchemaReader()
126                 .getLeadMember(member, -(indexValue-1));
127             endMember = member;
128             if (startMember.isNull()) {
129                 Member[] members = evaluator.getSchemaReader()
130                     .getLevelMembers(member.getLevel(), false);
131                 startMember = members[0];
132             }
133         } else {
134             startMember = member;
135             endMember = evaluator.getSchemaReader()
136                 .getLeadMember(member, -(indexValue+1));
137             if (endMember.isNull()) {
138                 Member[] members = evaluator.getSchemaReader()
139                     .getLevelMembers(member.getLevel(), false);
140                 endMember = members[members.length - 1];
141             }
142         }
143
144         evaluator.getSchemaReader().
145             getMemberRange(member.getLevel(),
146                startMember,
147                endMember,
148                list);
149         return list;
150     }
151 }
152
153 // End LastPeriodsFunDef.java
154
Popular Tags