001 /* 002 // $Id: //open/mondrian/src/main/mondrian/rolap/CacheMemberReader.java#31 $ 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) 2001-2002 Kana Software, Inc. 007 // Copyright (C) 2001-2008 Julian Hyde and others 008 // All Rights Reserved. 009 // You must accept the terms of that agreement to use this software. 010 // 011 // jhyde, 21 December, 2001 012 */ 013 014 package mondrian.rolap; 015 import java.util.ArrayList; 016 import java.util.HashMap; 017 import java.util.List; 018 import java.util.Map; 019 020 import mondrian.olap.*; 021 import mondrian.rolap.TupleReader.MemberBuilder; 022 import mondrian.rolap.sql.TupleConstraint; 023 import mondrian.rolap.sql.MemberChildrenConstraint; 024 025 /** 026 * <code>CacheMemberReader</code> implements {@link MemberReader} by reading 027 * from a pre-populated array of {@link mondrian.olap.Member}s. 028 * <p>Note: CacheMemberReader can not handle ragged hierarchies. (HR 029 * Tests fail if {@link SmartMemberReader} is replaced with 030 * CacheMemberReader). 031 * 032 * @author jhyde 033 * @since 21 December, 2001 034 * @version $Id: //open/mondrian/src/main/mondrian/rolap/CacheMemberReader.java#31 $ 035 */ 036 class CacheMemberReader implements MemberReader, MemberCache { 037 private final MemberSource source; 038 private final List<RolapMember> members; 039 /** Maps a {@link MemberKey} to a {@link RolapMember}. */ 040 private final Map<Object, RolapMember> mapKeyToMember; 041 042 CacheMemberReader(MemberSource source) { 043 this.source = source; 044 if (false) { 045 // we don't want the reader to write back to our cache 046 Util.discard(source.setCache(this)); 047 } 048 this.mapKeyToMember = new HashMap<Object, RolapMember>(); 049 this.members = source.getMembers(); 050 for (int i = 0; i < members.size(); i++) { 051 members.get(i).setOrdinal(i); 052 } 053 } 054 055 // implement MemberReader 056 public RolapHierarchy getHierarchy() { 057 return source.getHierarchy(); 058 } 059 060 public boolean setCache(MemberCache cache) { 061 // we do not support cache writeback -- we must be masters of our 062 // own cache 063 return false; 064 } 065 066 public RolapMember substitute(RolapMember member) { 067 return member; 068 } 069 070 public RolapMember desubstitute(RolapMember member) { 071 return member; 072 } 073 074 // implement MemberReader 075 public List<RolapMember> getMembers() { 076 return members; 077 } 078 079 // implement MemberCache 080 public Object makeKey(RolapMember parent, Object key) { 081 return new MemberKey(parent, key); 082 } 083 084 // implement MemberCache 085 public RolapMember getMember(Object key) { 086 return mapKeyToMember.get(key); 087 } 088 public RolapMember getMember(Object key, boolean mustCheckCacheStatus) { 089 return mapKeyToMember.get(key); 090 } 091 092 // implement MemberCache 093 public Object putMember(Object key, RolapMember value) { 094 return mapKeyToMember.put(key, value); 095 } 096 097 // don't need to implement this MemberCache method because we're never 098 // used in a context where it is needed 099 public void putChildren( 100 RolapMember member, 101 MemberChildrenConstraint constraint, 102 List<RolapMember> children) 103 { 104 throw new UnsupportedOperationException(); 105 } 106 107 // this cache is immutable 108 public boolean isMutable() 109 { 110 return false; 111 } 112 113 public RolapMember removeMember(Object key) 114 { 115 throw new UnsupportedOperationException(); 116 } 117 118 public RolapMember removeMemberAndDescendants(Object key) 119 { 120 throw new UnsupportedOperationException(); 121 } 122 123 // don't need to implement this MemberCache method because we're never 124 // used in a context where it is needed 125 public List<RolapMember> getChildrenFromCache( 126 RolapMember member, 127 MemberChildrenConstraint constraint) 128 { 129 return null; 130 } 131 132 // don't need to implement this MemberCache method because we're never 133 // used in a context where it is needed 134 public List<RolapMember> getLevelMembersFromCache( 135 RolapLevel level, 136 TupleConstraint constraint) 137 { 138 return null; 139 } 140 141 public RolapMember lookupMember( 142 List<Id.Segment> uniqueNameParts, 143 boolean failIfNotFound) 144 { 145 return RolapUtil.lookupMember(this, uniqueNameParts, failIfNotFound); 146 } 147 148 public List<RolapMember> getRootMembers() { 149 List<RolapMember> list = new ArrayList<RolapMember>(); 150 for (RolapMember member : members) { 151 if (member.getParentUniqueName() == null) { 152 list.add(member); 153 } 154 } 155 return list; 156 } 157 158 public List<RolapMember> getMembersInLevel( 159 RolapLevel level, 160 int startOrdinal, 161 int endOrdinal) 162 { 163 List<RolapMember> list = new ArrayList<RolapMember>(); 164 int levelDepth = level.getDepth(); 165 for (RolapMember member : members) { 166 if ((member.getLevel().getDepth() == levelDepth) && 167 (startOrdinal <= member.getOrdinal()) && 168 (member.getOrdinal() < endOrdinal)) { 169 170 list.add(member); 171 } 172 } 173 return list; 174 } 175 176 public List<RolapMember> getMembersInLevel( 177 RolapLevel level, 178 int startOrdinal, 179 int endOrdinal, 180 TupleConstraint constraint) 181 { 182 return getMembersInLevel(level, startOrdinal, endOrdinal); 183 } 184 185 public int getLevelMemberCount(RolapLevel level) { 186 int count = 0; 187 int levelDepth = level.getDepth(); 188 for (Member member : members) { 189 if (member.getLevel().getDepth() == levelDepth) { 190 ++count; 191 } 192 } 193 return count; 194 } 195 196 public void getMemberChildren( 197 RolapMember parentMember, 198 List<RolapMember> children) 199 { 200 for (Member member : members) { 201 if (member.getParentMember() == parentMember) { 202 ((List)children).add(member); 203 } 204 } 205 } 206 207 public void getMemberChildren( 208 RolapMember member, 209 List<RolapMember> children, 210 MemberChildrenConstraint constraint) 211 { 212 getMemberChildren(member, children); 213 } 214 215 public void getMemberChildren( 216 List<RolapMember> parentMembers, 217 List<RolapMember> children) { 218 for (Member member : members) { 219 if (parentMembers.contains(member.getParentMember())) { 220 ((List)children).add(member); 221 } 222 } 223 } 224 225 public void getMemberChildren( 226 List<RolapMember> parentMembers, 227 List<RolapMember> children, 228 MemberChildrenConstraint constraint) 229 { 230 getMemberChildren(parentMembers, children); 231 } 232 233 public RolapMember getLeadMember(RolapMember member, int n) { 234 if (n >= 0) { 235 for (int ordinal = member.getOrdinal(); ordinal < members.size(); 236 ordinal++) { 237 if ((members.get(ordinal).getLevel() == member.getLevel()) && 238 (n-- == 0)) { 239 240 return members.get(ordinal); 241 } 242 } 243 return (RolapMember) member.getHierarchy().getNullMember(); 244 245 } else { 246 for (int ordinal = member.getOrdinal(); ordinal >= 0; ordinal--) { 247 if ((members.get(ordinal).getLevel() == member.getLevel()) && 248 (n++ == 0)) { 249 return members.get(ordinal); 250 } 251 } 252 return (RolapMember) member.getHierarchy().getNullMember(); 253 } 254 } 255 256 public void getMemberRange( 257 RolapLevel level, 258 RolapMember startMember, 259 RolapMember endMember, 260 List<RolapMember> list) 261 { 262 assert startMember != null; 263 assert endMember != null; 264 assert startMember.getLevel() == endMember.getLevel(); 265 final int endOrdinal = endMember.getOrdinal(); 266 for (int i = startMember.getOrdinal(); i <= endOrdinal; i++) { 267 if (members.get(i).getLevel() == endMember.getLevel()) { 268 list.add(members.get(i)); 269 } 270 } 271 } 272 273 public int getMemberCount() { 274 return members.size(); 275 } 276 277 public int compare(RolapMember m1, RolapMember m2, boolean siblingsAreEqual) { 278 if (m1 == m2) { 279 return 0; 280 } 281 if (siblingsAreEqual && 282 (m1.getParentMember() == m2.getParentMember())) { 283 return 0; 284 } 285 Util.assertTrue(members.get(m1.getOrdinal()) == m1); 286 Util.assertTrue(members.get(m2.getOrdinal()) == m2); 287 288 return (m1.getOrdinal() < m2.getOrdinal()) ? -1 : 1; 289 } 290 291 public MemberBuilder getMemberBuilder() { 292 return null; 293 } 294 295 public RolapMember getDefaultMember() { 296 RolapMember defaultMember = 297 (RolapMember) getHierarchy().getDefaultMember(); 298 if (defaultMember != null) { 299 return defaultMember; 300 } 301 return getRootMembers().get(0); 302 } 303 304 public RolapMember getMemberParent(RolapMember member) { 305 return member.getParentMember(); 306 } 307 } 308 309 // End CacheMemberReader.java