001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/CubeAccess.java#14 $ 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) 1999-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 // lkrivopaltsev, 01 November, 1999 012 */ 013 014 package mondrian.olap; 015 import mondrian.resource.MondrianResource; 016 017 import java.util.List; 018 import java.util.ArrayList; 019 020 /** 021 * This class implements object of type GrantCube to apply permissions 022 * on user's MDX query 023 */ 024 public class CubeAccess { 025 026 private boolean hasRestrictions; 027 /** array of hierarchies with no access */ 028 private Hierarchy[] noAccessHierarchies; 029 /** array of members which have limited access */ 030 private Member[] limitedMembers; 031 private final List<Hierarchy> hierarchyList = new ArrayList<Hierarchy>(); 032 private final List<Member> memberList = new ArrayList<Member>(); 033 private final Cube mdxCube; 034 035 /** 036 * Creates a CubeAccess object. 037 * 038 * <p>User's code should be responsible for 039 * filling cubeAccess with restricted hierarchies and restricted 040 * members by calling addSlicer(). Do NOT forget to call 041 * {@link #normalizeCubeAccess()} after you done filling cubeAccess. 042 */ 043 public CubeAccess(Cube mdxCube) { 044 this.mdxCube = mdxCube; 045 noAccessHierarchies = null; 046 limitedMembers = null; 047 hasRestrictions = false; 048 } 049 050 public boolean hasRestrictions() { 051 return hasRestrictions; 052 } 053 054 public Hierarchy[] getNoAccessHierarchies() { 055 return noAccessHierarchies; 056 } 057 058 public Member[] getLimitedMembers() { 059 return limitedMembers; 060 } 061 062 public List<Hierarchy> getNoAccessHierarchyList() { 063 return hierarchyList; 064 } 065 066 public List<Member> getLimitedMemberList() { 067 return memberList; 068 } 069 070 public boolean isHierarchyAllowed(Hierarchy mdxHierarchy) { 071 String hierName = mdxHierarchy.getUniqueName(); 072 if (noAccessHierarchies == null || hierName == null) { 073 return true; 074 } 075 for (Hierarchy noAccessHierarchy : noAccessHierarchies) { 076 if (hierName.equalsIgnoreCase(noAccessHierarchy.getUniqueName())) { 077 return false; 078 } 079 } 080 return true; 081 } 082 083 public Member getLimitedMemberForHierarchy(Hierarchy mdxHierarchy) { 084 String hierName = mdxHierarchy.getUniqueName(); 085 if (limitedMembers == null || hierName == null) { 086 return null; 087 } 088 for (Member limitedMember : limitedMembers) { 089 Hierarchy limitedHierarchy = limitedMember.getHierarchy(); 090 if (hierName.equalsIgnoreCase(limitedHierarchy.getUniqueName())) { 091 return limitedMember; 092 } 093 } 094 return null; 095 } 096 097 /** 098 * Adds restricted hierarchy or limited member based on bMember 099 */ 100 public void addGrantCubeSlicer( 101 String sHierarchy, 102 String sMember, 103 boolean bMember) { 104 if (bMember) { 105 boolean fail = false; 106 List<Id.Segment> sMembers = Util.parseIdentifier(sMember); 107 SchemaReader schemaReader = mdxCube.getSchemaReader(null); 108 Member member = schemaReader.getMemberByUniqueName(sMembers, fail); 109 if (member == null) { 110 throw MondrianResource.instance().MdxCubeSlicerMemberError.ex( 111 sMember, sHierarchy, mdxCube.getUniqueName()); 112 } 113 // there should be only slicer per hierarchy; ignore the rest 114 if (getLimitedMemberForHierarchy(member.getHierarchy()) == null) { 115 memberList.add(member); 116 } 117 } else { 118 boolean fail = false; 119 Hierarchy hierarchy = mdxCube.lookupHierarchy(new Id.Segment( 120 sHierarchy, Id.Quoting.UNQUOTED), fail); 121 if (hierarchy == null) { 122 throw MondrianResource.instance().MdxCubeSlicerHierarchyError 123 .ex(sHierarchy, mdxCube.getUniqueName()); 124 } 125 hierarchyList.add(hierarchy); 126 } 127 } 128 129 /** 130 * Initializes internal arrays of restricted hierarchies and limited 131 * members. It has to be called after all 'addSlicer()' calls. 132 */ 133 public void normalizeCubeAccess() { 134 if (memberList.size() > 0) { 135 limitedMembers = memberList.toArray(new Member[memberList.size()]); 136 hasRestrictions = true; 137 } 138 if (hierarchyList.size() > 0) { 139 noAccessHierarchies = 140 hierarchyList.toArray( 141 new Hierarchy[hierarchyList.size()]); 142 hasRestrictions = true; 143 } 144 } 145 146 public boolean equals(Object object) { 147 if (!(object instanceof CubeAccess)) { 148 return false; 149 } 150 CubeAccess cubeAccess = (CubeAccess) object; 151 List<Hierarchy> hierarchyList = cubeAccess.getNoAccessHierarchyList(); 152 List<Member> limitedMemberList = cubeAccess.getLimitedMemberList(); 153 154 if ((this.hierarchyList.size() != hierarchyList.size()) || 155 (this.memberList.size() != limitedMemberList.size())) { 156 return false; 157 } 158 for (Hierarchy o : hierarchyList) { 159 if (!this.hierarchyList.contains(o)) { 160 return false; 161 } 162 } 163 for (Member member : limitedMemberList) { 164 if (!this.memberList.contains(member)) { 165 return false; 166 } 167 } 168 return true; 169 } 170 171 public int hashCode() { 172 int h = mdxCube.hashCode(); 173 h = Util.hash(h, hierarchyList); 174 h = Util.hash(h, memberList); 175 h = Util.hashArray(h, noAccessHierarchies); 176 h = Util.hashArray(h, limitedMembers); 177 return h; 178 } 179 } 180 181 // End CubeAccess.java