001 /*
002 // $Id: //open/mondrian-release/3.0/src/main/mondrian/olap/CubeAccess.java#2 $
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-2007 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