KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > rolap > agg > MemberTuplePredicate


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/rolap/agg/MemberTuplePredicate.java#1 $
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) 2007-2007 Julian Hyde
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

10 package mondrian.rolap.agg;
11
12 import mondrian.olap.Util;
13 import mondrian.rolap.StarPredicate;
14 import mondrian.rolap.RolapStar;
15 import mondrian.rolap.RolapLevel;
16 import mondrian.rolap.RolapMember;
17
18 import java.util.List JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.Arrays JavaDoc;
22
23 /**
24  * Predicate which constrains a column to a particular member, or a range
25  * above or below a member, or a range between two members.
26  *
27  * @author jhyde
28  * @version $Id: //open/mondrian/src/main/mondrian/rolap/agg/MemberTuplePredicate.java#1 $
29  */

30 public class MemberTuplePredicate implements StarPredicate {
31     private final Bound[] bounds;
32     private final List JavaDoc<RolapStar.Column> columnList;
33
34     /**
35      * Creates a MemberTuplePredicate which evaluates to true for a given
36      * range of members.
37      *
38      * <p>The range can be open above or below, but at least one bound is
39      * required.
40      *
41      * @param levelToColumnMap Map from levels to a columns in the current star
42      * @param lower Member which forms the lower bound, or null if range is
43      * open below
44      * @param lowerStrict Whether lower bound of range is strict
45      * @param upper Member which forms the upper bound, or null if range is
46      * open above
47      * @param upperStrict Whether upper bound of range is strict
48      */

49     public MemberTuplePredicate(
50         Map JavaDoc<RolapLevel, RolapStar.Column> levelToColumnMap,
51         RolapMember lower,
52         boolean lowerStrict,
53         RolapMember upper,
54         boolean upperStrict)
55     {
56         this.columnList =
57             computeColumnList(
58                 lower != null ? lower : upper,
59                 levelToColumnMap);
60
61         if (lower == null) {
62             assert upper != null;
63             bounds = new Bound[] {
64                 new Bound(upper, upperStrict ? RelOp.LT : RelOp.LE)
65             };
66         } else if (upper == null) {
67             bounds = new Bound[] {
68                 new Bound(lower, lowerStrict ? RelOp.GT : RelOp.GE)
69             };
70         } else {
71             bounds = new Bound[] {
72                 new Bound(lower, lowerStrict ? RelOp.GT : RelOp.GE),
73                 new Bound(upper, upperStrict ? RelOp.LT : RelOp.LE)
74             };
75         }
76     }
77
78     /**
79      * Creates a MemberTuplePredicate which evaluates to true for a given
80      * member.
81      *
82      * @param levelToColumnMap Map from levels to a columns in the current star
83      * @param member Member
84      */

85     public MemberTuplePredicate(
86         Map JavaDoc<RolapLevel, RolapStar.Column> levelToColumnMap,
87         RolapMember member)
88     {
89         this.columnList =
90             computeColumnList(
91                 member,
92                 levelToColumnMap);
93
94         this.bounds = new Bound[] {
95             new Bound(member, RelOp.EQ)
96         };
97     }
98
99     public int hashCode() {
100         return this.columnList.hashCode() * 31 +
101             Arrays.hashCode(this.bounds) * 31;
102     }
103
104     public boolean equals(Object JavaDoc obj) {
105         if (obj instanceof MemberTuplePredicate) {
106             MemberTuplePredicate that =
107                 (MemberTuplePredicate) obj;
108             return this.columnList.equals(that.columnList) &&
109                 Arrays.equals(this.bounds, that.bounds);
110         } else {
111             return false;
112         }
113     }
114
115     private List JavaDoc<RolapStar.Column> computeColumnList(
116         RolapMember member,
117         Map JavaDoc<RolapLevel, RolapStar.Column> levelToColumnMap)
118     {
119         List JavaDoc<RolapStar.Column> columnList = new ArrayList JavaDoc<RolapStar.Column>();
120         while (true) {
121             RolapLevel level = member.getLevel();
122             columnList.add(0, levelToColumnMap.get(level));
123             if (level.isUnique()) {
124                 return columnList;
125             }
126             member = member.getParentMember();
127         }
128     }
129
130     /**
131      * Returns a list of constrained columns.
132      *
133      * @return List of constrained columns
134      */

135     public List JavaDoc<RolapStar.Column> getConstrainedColumnList() {
136         return columnList;
137     }
138
139     public boolean equalConstraint(StarPredicate that) {
140         throw new UnsupportedOperationException JavaDoc();
141     }
142
143     public StarPredicate minus(StarPredicate predicate) {
144         throw new UnsupportedOperationException JavaDoc();
145     }
146
147     /**
148      * Evaluates a constraint against a list of values.
149      *
150      * @param valueList List of values, one for each constrained column
151      * @return Whether constraint holds for given set of values
152      */

153     public boolean evaluate(List JavaDoc<Object JavaDoc> valueList) {
154         for (Bound bound : bounds) {
155             for (int k = 0; k < bound.values.length; ++k) {
156                 Object JavaDoc value = valueList.get(k);
157                 if (value == WILDCARD) {
158                     return false;
159                 }
160                 Object JavaDoc boundValue = bound.values[k];
161                 RelOp relOp = bound.relOps[k];
162                 int c = Util.compareKey(value, boundValue);
163                 switch (relOp) {
164                 case GT:
165                     if (c > 0) {
166                         break;
167                     } else {
168                         return false;
169                     }
170                 case GE:
171                     if (c > 0) {
172                         return true;
173                     } else if (c == 0) {
174                         break;
175                     } else {
176                         return false;
177                     }
178                 case LT:
179                     if (c < 0) {
180                         break;
181                     } else {
182                         return false;
183                     }
184                 case LE:
185                     if (c < 0) {
186                         return true;
187                     } if (c == 0) {
188                         break;
189                     } else {
190                         return false;
191                     }
192                 }
193             }
194         }
195         return true;
196     }
197
198     public void describe(StringBuilder JavaDoc buf) {
199         int k = 0;
200         for (Bound bound : bounds) {
201             if (k++ > 0) {
202                 buf.append(" AND ");
203             }
204             buf.append(bound.relOps[bound.relOps.length - 1].getOp());
205             buf.append(' ');
206             buf.append(bound.member);
207         }
208     }
209
210     private enum RelOp {
211         LT("<"),
212         LE("<="),
213         GT(">"),
214         GE(">="),
215         EQ("=");
216
217         private final String JavaDoc op;
218
219         RelOp(String JavaDoc op) {
220             this.op = op;
221         }
222
223         String JavaDoc getOp() {
224             return op;
225         }
226     }
227
228     private static class Bound {
229         private final RolapMember member;
230         private final Object JavaDoc[] values;
231         private final RelOp[] relOps;
232
233         Bound(RolapMember member, RelOp relOp) {
234             this.member = member;
235             List JavaDoc<Object JavaDoc> valueList = new ArrayList JavaDoc<Object JavaDoc>();
236             List JavaDoc<RelOp> relOpList = new ArrayList JavaDoc<RelOp>();
237             while (true) {
238                 valueList.add(0, member.getKey());
239                 relOpList.add(0, relOp);
240                 if (member.getLevel().isUnique()) {
241                     break;
242                 }
243                 member = member.getParentMember();
244                 switch (relOp) {
245                 case GT:
246                     relOp = RelOp.GE;
247                     break;
248                 case LT:
249                     relOp = RelOp.LE;
250                     break;
251                 }
252             }
253             this.values = valueList.toArray(new Object JavaDoc[valueList.size()]);
254             this.relOps = relOpList.toArray(new RelOp[relOpList.size()]);
255         }
256
257
258         public int hashCode() {
259             int h = member.hashCode();
260             h = h * 31 + Arrays.hashCode(values);
261             h = h * 31 + Arrays.hashCode(relOps);
262             return h;
263         }
264
265         public boolean equals(Object JavaDoc obj) {
266             if (obj instanceof Bound) {
267                 Bound that = (Bound) obj;
268                 return this.member.equals(that.member) &&
269                     Arrays.equals(this.values, that.values) &&
270                     Arrays.equals(this.relOps, that.relOps);
271             } else {
272                 return false;
273             }
274         }
275     }
276 }
277
278 // End MemberTuplePredicate.java
279
Popular Tags