001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 1999-2005 Julian Hyde 008// Copyright (C) 2005-2012 Pentaho and others 009// All Rights Reserved. 010*/ 011package mondrian.olap; 012 013import mondrian.resource.MondrianResource; 014 015import java.util.ArrayList; 016import java.util.List; 017 018/** 019 * This class implements object of type GrantCube to apply permissions 020 * on user's MDX query 021 * 022 * @author lkrivopaltsev, 01 November, 1999 023 */ 024public 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 { 105 if (bMember) { 106 boolean fail = false; 107 List<Id.Segment> sMembers = Util.parseIdentifier(sMember); 108 SchemaReader schemaReader = mdxCube.getSchemaReader(null); 109 Member member = schemaReader.getMemberByUniqueName(sMembers, fail); 110 if (member == null) { 111 throw MondrianResource.instance().MdxCubeSlicerMemberError.ex( 112 sMember, sHierarchy, mdxCube.getUniqueName()); 113 } 114 // there should be only slicer per hierarchy; ignore the rest 115 if (getLimitedMemberForHierarchy(member.getHierarchy()) == null) { 116 memberList.add(member); 117 } 118 } else { 119 boolean fail = false; 120 Hierarchy hierarchy = 121 mdxCube.lookupHierarchy( 122 new Id.NameSegment(sHierarchy), 123 fail); 124 if (hierarchy == null) { 125 throw MondrianResource.instance().MdxCubeSlicerHierarchyError 126 .ex(sHierarchy, mdxCube.getUniqueName()); 127 } 128 hierarchyList.add(hierarchy); 129 } 130 } 131 132 /** 133 * Initializes internal arrays of restricted hierarchies and limited 134 * members. It has to be called after all 'addSlicer()' calls. 135 */ 136 public void normalizeCubeAccess() { 137 if (memberList.size() > 0) { 138 limitedMembers = memberList.toArray(new Member[memberList.size()]); 139 hasRestrictions = true; 140 } 141 if (hierarchyList.size() > 0) { 142 noAccessHierarchies = 143 hierarchyList.toArray( 144 new Hierarchy[hierarchyList.size()]); 145 hasRestrictions = true; 146 } 147 } 148 149 public boolean equals(Object object) { 150 if (!(object instanceof CubeAccess)) { 151 return false; 152 } 153 CubeAccess cubeAccess = (CubeAccess) object; 154 List<Hierarchy> hierarchyList = cubeAccess.getNoAccessHierarchyList(); 155 List<Member> limitedMemberList = cubeAccess.getLimitedMemberList(); 156 157 if ((this.hierarchyList.size() != hierarchyList.size()) 158 || (this.memberList.size() != limitedMemberList.size())) 159 { 160 return false; 161 } 162 for (Hierarchy o : hierarchyList) { 163 if (!this.hierarchyList.contains(o)) { 164 return false; 165 } 166 } 167 for (Member member : limitedMemberList) { 168 if (!this.memberList.contains(member)) { 169 return false; 170 } 171 } 172 return true; 173 } 174 175 public int hashCode() { 176 int h = mdxCube.hashCode(); 177 h = Util.hash(h, hierarchyList); 178 h = Util.hash(h, memberList); 179 h = Util.hashArray(h, noAccessHierarchies); 180 h = Util.hashArray(h, limitedMembers); 181 return h; 182 } 183} 184 185// End CubeAccess.java