Skip to content

Commit

Permalink
MONDRIAN: Fixes to access-control.
Browse files Browse the repository at this point in the history
[git-p4: depot-paths = "//open/mondrian/": change = 404]
  • Loading branch information
julianhyde committed Mar 29, 2003
1 parent e6336dd commit bf7bcdd
Show file tree
Hide file tree
Showing 17 changed files with 195 additions and 50 deletions.
14 changes: 13 additions & 1 deletion src/main/mondrian/olap/DelegatingSchemaReader.java
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 2003-2003 Julian Hyde
// Copyright (C) 2003-2003 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
Expand Down Expand Up @@ -39,6 +39,10 @@ public Member[] getHierarchyRootMembers(Hierarchy hierarchy) {
return schemaReader.getHierarchyRootMembers(hierarchy);
}

public Member getMemberParent(Member member) {
return schemaReader.getMemberParent(member);
}

public Member[] getMemberChildren(Member member) {
return schemaReader.getMemberChildren(member);
}
Expand All @@ -47,6 +51,10 @@ public Member[] getMemberChildren(Member[] members) {
return schemaReader.getMemberChildren(members);
}

public int getMemberDepth(Member member) {
return schemaReader.getMemberDepth(member);
}

public Member getMemberByUniqueName(String[] uniqueNameParts, boolean failIfNotFound) {
return schemaReader.getMemberByUniqueName(uniqueNameParts, failIfNotFound);
}
Expand Down Expand Up @@ -74,6 +82,10 @@ public Member[] getLevelMembers(Level level) {
public Level[] getHierarchyLevels(Hierarchy hierarchy) {
return schemaReader.getHierarchyLevels(hierarchy);
}

public Member getHierarchyDefaultMember(Hierarchy hierarchy) {
return schemaReader.getHierarchyDefaultMember(hierarchy);
}
}

// End DelegatingSchemaReader.java
38 changes: 30 additions & 8 deletions src/main/mondrian/olap/Hierarchy.java
Expand Up @@ -3,34 +3,56 @@
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 1999-2002 Kana Software, Inc. and others.
// Copyright (C) 1999-2003 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
// jhyde, 2 March, 1999
*/

package mondrian.olap;
import java.util.List;

/**
* Wrapper around an ADO MD hierarchy.
* A <code>Hierarchy</code> is a set of members, organized into levels.
**/
public interface Hierarchy extends OlapElement {
/**
* Returns the dimension this hierarchy belongs to.
*/
Dimension getDimension();
/**
* Returns the levels in this hierarchy.
*
* <p>If a hierarchy is subject to access-control, some of the levels may
* not be visible; use {@link SchemaReader#getHierarchyLevels} instead.
*
* @post return != null
*/
Level[] getLevels();
/**
* Returns the default member of this hierarchy.
*
* <p>If a hierarchy is subject to access-control, the default member may
* not be visible, so use {@link SchemaReader#getHierarchyDefaultMember}.
*
* @post return != null
*/
Member getDefaultMember();
/**
* Returns a special member representing the "null" value. This never
* occurs on an axis, but may occur if functions such as <code>Lead</code>,
* <code>NextMember</code> and <code>ParentMember</code> walk off the end
* of the hierarchy.
*
* @post return != null
*/
Member getNullMember();
boolean hasAll();
/**
* Creates a member of this hierarchy. If this is the measures hierarchy, a
* calculated member is created, and <code>formula</code> must not be null.
**/
Member createMember(
Member parent, Level level, String name, Formula formula);

/** Find a named level in this hierarchy. */
Level lookupLevel(String s);
Member createMember(Member parent, Level level, String name, Formula formula);
}

// End Hierarchy.java
Expand Down
13 changes: 1 addition & 12 deletions src/main/mondrian/olap/HierarchyBase.java
Expand Up @@ -69,24 +69,13 @@ public boolean equals(OlapElement mdxElement) {
/** find a child object */
public OlapElement lookupChild(SchemaReader schemaReader, String s)
{
Level mdxLevel = lookupLevel(s);
Level mdxLevel = Util.lookupHierarchyLevel(this, s);
if (mdxLevel != null) {
return mdxLevel;
}
return Util.lookupHierarchyRootMember(schemaReader, this, s);
}

// implement Hierarchy
public Level lookupLevel(String s)
{
for (int i = 0; i < levels.length; i++) {
if (levels[i].getName().equalsIgnoreCase(s)) {
return levels[i];
}
}
return null;
}

public Object[] getChildren() {
return getLevels();
}
Expand Down
15 changes: 12 additions & 3 deletions src/main/mondrian/olap/Level.java
@@ -1,14 +1,12 @@
/*
// $Id$
//
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 1999-2002 Kana Software, Inc. and others.
// Copyright (C) 1999-2002 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
//
// jhyde, 1 March, 1999
*/

Expand All @@ -20,6 +18,17 @@
**/
public interface Level extends OlapElement {

/**
* Returns the depth of this level.
*
* <p>Note #1: In an access-controlled context, the first visible level of
* a hierarchy (as returned by {@link SchemaReader#getHierarchyLevels}) may
* not have a depth of 0.</p>
*
* <p>Note #2: In a parent-child hierarchy, the depth of a member (as
* returned by {@link SchemaReader#getMemberDepth}) may not be the same as
* the depth of its level.
*/
int getDepth();
Hierarchy getHierarchy();

Expand Down
11 changes: 8 additions & 3 deletions src/main/mondrian/olap/Member.java
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 1999-2002 Kana Software, Inc. and others.
// Copyright (C) 1999-2003 Kana Software, Inc. and others.
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
Expand Down Expand Up @@ -34,6 +34,13 @@
**/
public interface Member extends OlapElement {

/**
* Returns this member's parent, or null (not the 'null member', as
* returned by {@link Hierarchy#getNullMember}) if it has no parent.
*
* <p>In an access-control context, a member may have no <em>visible</em>
* parents, so use {@link SchemaReader#getMemberParent}.
*/
Member getParentMember();

Level getLevel();
Expand Down Expand Up @@ -76,8 +83,6 @@ public interface Member extends OlapElement {
**/
void setName(String name);

int getDepth();

/** Returns whether this is the 'all' member. */
boolean isAll();

Expand Down
3 changes: 0 additions & 3 deletions src/main/mondrian/olap/MemberBase.java
Expand Up @@ -60,9 +60,6 @@ public final Hierarchy getHierarchy() {
public final Level getLevel() {
return level;
}
public final int getDepth() {
return level.depth;
}
public final int getMemberType() {
return memberType;
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/mondrian/olap/Mondrian.xml
Expand Up @@ -29,6 +29,9 @@ Revision is $Id$
<Doc>
A schema is a collection of cubes and shared dimensions.
</Doc>
<Attribute name="defaultRole" required="false">
<Doc>The name of the default schema for connections to this schema</Doc>
</Attribute>
<Array name="dimensions" type="Dimension"/>
<Array name="cubes" type="Cube"/>
<Array name="virtualCubes" type="VirtualCube"/>
Expand Down
8 changes: 4 additions & 4 deletions src/main/mondrian/olap/Query.java
Expand Up @@ -644,7 +644,7 @@ public void crop(
"CurrentMember",
new Exp[] {hierarchy},
FunDef.TypeProperty),
hierarchy.lookupLevel("(All)"),
Util.lookupHierarchyLevel(hierarchy, "(All)"),
Literal.createSymbol("SELF_BEFORE_AFTER")
})
});
Expand Down Expand Up @@ -1612,11 +1612,11 @@ public void setAxisShowSubtotals(int axis, boolean showSubtotals)
//we need to put only members with biggest depth
int nMaxDepth = 0;
for (int i = 0; i < mdxMembers.length; i++){
if (nMaxDepth < mdxMembers[i].getDepth())
nMaxDepth = mdxMembers[i].getDepth();
if (nMaxDepth < mdxMembers[i].getLevel().getDepth())
nMaxDepth = mdxMembers[i].getLevel().getDepth();
}
for (int i = 0; i < mdxMembers.length; i++){
if (nMaxDepth == mdxMembers[i].getDepth()) {
if (nMaxDepth == mdxMembers[i].getLevel().getDepth()) {
set.add(mdxMembers[i]);
}
}
Expand Down
32 changes: 30 additions & 2 deletions src/main/mondrian/olap/SchemaReader.java
Expand Up @@ -3,7 +3,7 @@
// This software is subject to the terms of the Common Public License
// Agreement, available at the following URL:
// http://www.opensource.org/licenses/cpl.html.
// (C) Copyright 2003-2003 Julian Hyde
// Copyright (C) 2003-2003 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
Expand Down Expand Up @@ -31,9 +31,14 @@ public interface SchemaReader {
*/
Role getRole();
/**
* Returns an array of the root members of <code>hierarchy</code>.
* Returns an array of the root members of <code>hierarchy</code>. If the
* hierarchy is access-controlled, returns the most senior visible members.
**/
Member[] getHierarchyRootMembers(Hierarchy hierarchy);
/**
* Returns the parent of a member, null if the parent is inaccessible.
*/
Member getMemberParent(Member member);
/**
* Returns direct children of <code>member</code>.
* @pre member != null
Expand All @@ -46,6 +51,21 @@ public interface SchemaReader {
* @post return != null
**/
Member[] getMemberChildren(Member[] members);
/**
* Returns the depth of a member. This may not be the same as
* <code>member.{@link Member#getLevel getLevel}().{@link Level#getDepth getDepth}()</code>
* for 2 reasons:<ol>
* <li><b>Access control</b>. The most senior <em>visible</em> member has
* level 0. If the client is not allowed to see the "All" and "Nation"
* levels of the "Store" hierarchy, then members of the "State" level will
* have depth 0.</li>
* <li><b>Parent-child hierarchies</b>. Suppose Fred reports to Wilma, and
* Wilma reports to no one. "All Employees" has depth 0, Wilma has depth 1,
* and Fred has depth 2. Fred and Wilma are both in the "Employees" level,
* which has depth 1.</li>
* </ol>
*/
int getMemberDepth(Member member);
/**
* Finds a member based upon its unique name.
*
Expand Down Expand Up @@ -97,8 +117,16 @@ public interface SchemaReader {
Member[] getLevelMembers(Level level);
/**
* Returns the accessible levels of a hierarchy.
*
* @pre hierarchy != null
* @post return.length >= 1
*/
Level[] getHierarchyLevels(Hierarchy hierarchy);
/**
* Returns the default member of a hierarchy. If the default member is in
* an inaccessible level, returns the nearest ascendant/descendant member.
*/
Member getHierarchyDefaultMember(Hierarchy hierarchy);
}

// End SchemaReader.java
15 changes: 15 additions & 0 deletions src/main/mondrian/olap/Util.java
Expand Up @@ -327,6 +327,21 @@ public static Member lookupHierarchyRootMember(
return null;
}

/**
* Finds a named level in this hierarchy. Returns null if there is no
* such level.
*/
public static Level lookupHierarchyLevel(Hierarchy hierarchy, String s) {
final Level[] levels = hierarchy.getLevels();
for (int i = 0; i < levels.length; i++) {
if (levels[i].getName().equalsIgnoreCase(s)) {
return levels[i];
}
}
return null;
}


/**
* Finds a child of a member with a given name.
*/
Expand Down
10 changes: 5 additions & 5 deletions src/main/mondrian/olap/fun/BuiltinFunTable.java
Expand Up @@ -918,12 +918,12 @@ public void testCurrentMemberInCalcMember(FoodMartTestCase test) {
define(new FunDefBase("DefaultMember", "<Dimension>.DefaultMember", "Returns the default member of a dimension.", "pmd") {
public Object evaluate(Evaluator evaluator, Exp[] args) {
Dimension dimension = getDimensionArg(evaluator, args, 0, true);
return dimension.getHierarchy().getDefaultMember();
return evaluator.getSchemaReader().getHierarchyDefaultMember(
dimension.getHierarchy());
}

public void testDimensionDefaultMember(FoodMartTestCase test) {
Member member = test.executeAxis(
"[Measures].DefaultMember");
Member member = test.executeAxis("[Measures].DefaultMember");
test.assertEquals("Unit Sales", member.getName());
}
});
Expand Down Expand Up @@ -1976,7 +1976,7 @@ public Object evaluate(Evaluator evaluator, Exp[] args) {

for (int i = 0, m = set0.size(); i < m; i++) {
Member member = (Member) set0.elementAt(i);
depthArray[i] = member.getDepth();
depthArray[i] = member.getLevel().getDepth();
// Object o0 = set0.elementAt(i);
// depthVector.addElement(new Object[] {o0});
}
Expand All @@ -1985,7 +1985,7 @@ public Object evaluate(Evaluator evaluator, Exp[] args) {
for (int i = 0, m = set0.size(); i < m; i++) {
Member member = (Member) set0.elementAt(i);
drilledSet.addElement(member);
if (member.getDepth() == maxDepth) {
if (member.getLevel().getDepth() == maxDepth) {
Member[] childMembers = evaluator.getSchemaReader().getMemberChildren(member);
for (int j = 0; j < childMembers.length; j++) {
drilledSet.addElement(childMembers[j]);
Expand Down
6 changes: 2 additions & 4 deletions src/main/mondrian/rolap/RolapConnection.java
Expand Up @@ -135,9 +135,8 @@ public RolapConnection(Util.PropertyList connectInfo) {
if (role == null) {
role = schema.defaultRole;
}
setRole(role);
this.schema = schema;
this.role = role;
this.schemaReader = schema.getSchemaReader();
}

public static synchronized void loadDrivers(String jdbcDrivers) {
Expand Down Expand Up @@ -220,12 +219,11 @@ public void setRole(Role role) {
Util.assertPrecondition(role != null, "role != null");
Util.assertPrecondition(!role.isMutable(), "!role.isMutable()");
this.role = role;
this.schemaReader = new RolapSchemaReader(getRole()) {
this.schemaReader = new RolapSchemaReader(role) {
public Cube getCube() {
throw new UnsupportedOperationException();
}
};

}

public Role getRole() {
Expand Down

0 comments on commit bf7bcdd

Please sign in to comment.