001 /*
002 // $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/CubeAccess.java#1 $
003 // This software is subject to the terms of the Eclipse Public License v1.0
004 // Agreement, available at the following URL:
005 // http://www.eclipse.org/legal/epl-v10.html.
006 // Copyright (C) 1999-2002 Kana Software, Inc.
007 // Copyright (C) 2001-2009 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 {
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 = mdxCube.lookupHierarchy(new Id.Segment(
121 sHierarchy, Id.Quoting.UNQUOTED), fail);
122 if (hierarchy == null) {
123 throw MondrianResource.instance().MdxCubeSlicerHierarchyError
124 .ex(sHierarchy, mdxCube.getUniqueName());
125 }
126 hierarchyList.add(hierarchy);
127 }
128 }
129
130 /**
131 * Initializes internal arrays of restricted hierarchies and limited
132 * members. It has to be called after all 'addSlicer()' calls.
133 */
134 public void normalizeCubeAccess() {
135 if (memberList.size() > 0) {
136 limitedMembers = memberList.toArray(new Member[memberList.size()]);
137 hasRestrictions = true;
138 }
139 if (hierarchyList.size() > 0) {
140 noAccessHierarchies =
141 hierarchyList.toArray(
142 new Hierarchy[hierarchyList.size()]);
143 hasRestrictions = true;
144 }
145 }
146
147 public boolean equals(Object object) {
148 if (!(object instanceof CubeAccess)) {
149 return false;
150 }
151 CubeAccess cubeAccess = (CubeAccess) object;
152 List<Hierarchy> hierarchyList = cubeAccess.getNoAccessHierarchyList();
153 List<Member> limitedMemberList = cubeAccess.getLimitedMemberList();
154
155 if ((this.hierarchyList.size() != hierarchyList.size())
156 || (this.memberList.size() != limitedMemberList.size()))
157 {
158 return false;
159 }
160 for (Hierarchy o : hierarchyList) {
161 if (!this.hierarchyList.contains(o)) {
162 return false;
163 }
164 }
165 for (Member member : limitedMemberList) {
166 if (!this.memberList.contains(member)) {
167 return false;
168 }
169 }
170 return true;
171 }
172
173 public int hashCode() {
174 int h = mdxCube.hashCode();
175 h = Util.hash(h, hierarchyList);
176 h = Util.hash(h, memberList);
177 h = Util.hashArray(h, noAccessHierarchies);
178 h = Util.hashArray(h, limitedMembers);
179 return h;
180 }
181 }
182
183 // End CubeAccess.java