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