Skip to content

Commit

Permalink
Fix bug 2032449, 'User Defined Dimension Properties'.
Browse files Browse the repository at this point in the history
Add builtin properties MEMBER_KEY, IS_PLACEHOLDERMEMBER, IS_DATAMEMBER.
Special treatment for DEPTH property and Member.getDepth() method.
Add test for reading members of parent-child hierarchy.
Fix test now that mondrian has more variants of the Descendants function.
Introduce interface XmlaOlap4jMemberBase, to allow commonality between various
implementations of Member in XMLA driver.


git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@124 c6a108a4-781c-0410-a6c6-c2d559e19af0
  • Loading branch information
julianhyde committed Nov 2, 2008
1 parent dd190c9 commit 0a6f2dc
Show file tree
Hide file tree
Showing 8 changed files with 448 additions and 55 deletions.
28 changes: 25 additions & 3 deletions src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ void populate() throws OlapException {
String hierarchyName =
memberNode.getAttribute("Hierarchy");
final String uname = stringElement(memberNode, "UName");
Member member = memberMap.get(uname);
XmlaOlap4jMemberBase member = memberMap.get(uname);
if (member == null) {
final String caption =
stringElement(memberNode, "Caption");
Expand All @@ -242,7 +242,7 @@ void populate() throws OlapException {
lookupHierarchy(metaData.cube, hierarchyName);
final Level level = hierarchy.getLevels().get(lnum);
member = new XmlaOlap4jSurpriseMember(
level, hierarchy, lnum, caption, uname);
this, level, hierarchy, lnum, caption, uname);
}
propertyValues.clear();
for (Element childNode : childElements(memberNode)) {
Expand Down Expand Up @@ -1228,7 +1228,10 @@ public boolean isWrapperFor(Class<?> iface) throws SQLException {
* in the cube (probably because the member is a calculated member
* defined in the query).
*/
private static class XmlaOlap4jSurpriseMember implements Member {
private static class XmlaOlap4jSurpriseMember
implements XmlaOlap4jMemberBase
{
private final XmlaOlap4jCellSet cellSet;
private final Level level;
private final Hierarchy hierarchy;
private final int lnum;
Expand All @@ -1238,26 +1241,45 @@ private static class XmlaOlap4jSurpriseMember implements Member {
/**
* Creates an XmlaOlap4jSurpriseMember.
*
* @param cellSet Cell set
* @param level Level
* @param hierarchy Hierarchy
* @param lnum Level number
* @param caption Caption
* @param uname Member unique name
*/
XmlaOlap4jSurpriseMember(
XmlaOlap4jCellSet cellSet,
Level level,
Hierarchy hierarchy,
int lnum,
String caption,
String uname)
{
this.cellSet = cellSet;
this.level = level;
this.hierarchy = hierarchy;
this.lnum = lnum;
this.caption = caption;
this.uname = uname;
}

public final XmlaOlap4jCube getCube() {
return cellSet.metaData.cube;
}

public final XmlaOlap4jConnection getConnection() {
return getCatalog().olap4jDatabaseMetaData.olap4jConnection;
}

public final XmlaOlap4jCatalog getCatalog() {
return getCube().olap4jSchema.olap4jCatalog;
}

public Map<Property, Object> getPropertyValueMap() {
return Collections.emptyMap();
}

public NamedList<? extends Member> getChildMembers()
{
return Olap4jUtil.emptyNamedList();
Expand Down
114 changes: 96 additions & 18 deletions src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,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.
// Copyright (C) 2007-2007 Julian Hyde
// Copyright (C) 2007-2008 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
Expand All @@ -19,9 +19,7 @@
import org.olap4j.mdx.parser.*;
import org.olap4j.mdx.parser.impl.DefaultMdxParserImpl;
import org.olap4j.metadata.*;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.*;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.SAXException;
Expand All @@ -34,10 +32,6 @@
import java.util.Map.*;
import java.util.regex.*;

import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;

/**
* Implementation of {@link org.olap4j.OlapConnection}
* for XML/A providers.
Expand Down Expand Up @@ -1078,6 +1072,34 @@ public int compare(
}

static class MemberHandler extends HandlerImpl<XmlaOlap4jMember> {

/**
* Collection of nodes to ignore because they represent standard
* built-in properties of Members.
*/
private static final Set<String> EXCLUDED_PROPERTY_NAMES =
new HashSet<String>(
Arrays.asList(
Property.StandardMemberProperty.CATALOG_NAME.name(),
Property.StandardMemberProperty.CUBE_NAME.name(),
Property.StandardMemberProperty.DIMENSION_UNIQUE_NAME.name(),
Property.StandardMemberProperty.HIERARCHY_UNIQUE_NAME.name(),
Property.StandardMemberProperty.LEVEL_UNIQUE_NAME.name(),
Property.StandardMemberProperty.PARENT_LEVEL.name(),
Property.StandardMemberProperty.PARENT_COUNT.name(),
Property.StandardMemberProperty.MEMBER_KEY.name(),
Property.StandardMemberProperty.IS_PLACEHOLDERMEMBER.name(),
Property.StandardMemberProperty.IS_DATAMEMBER.name(),
Property.StandardMemberProperty.LEVEL_NUMBER.name(),
Property.StandardMemberProperty.MEMBER_ORDINAL.name(),
Property.StandardMemberProperty.MEMBER_UNIQUE_NAME.name(),
Property.StandardMemberProperty.MEMBER_NAME.name(),
Property.StandardMemberProperty.PARENT_UNIQUE_NAME.name(),
Property.StandardMemberProperty.MEMBER_TYPE.name(),
Property.StandardMemberProperty.MEMBER_CAPTION.name(),
Property.StandardMemberProperty.CHILDREN_CARDINALITY.name(),
Property.StandardMemberProperty.DEPTH.name()));

public void handle(Element row, Context context, List<XmlaOlap4jMember> list) {
/*
Example:
Expand All @@ -1103,31 +1125,87 @@ public void handle(Element row, Context context, List<XmlaOlap4jMember> list) {
</row>
*/
int levelNumber = integerElement(row, "LEVEL_NUMBER");
int memberOrdinal = integerElement(row, "MEMBER_ORDINAL");
if (false) {
int levelNumber =
integerElement(
row,
Property.StandardMemberProperty.LEVEL_NUMBER.name());
}
int memberOrdinal =
integerElement(
row,
Property.StandardMemberProperty.MEMBER_ORDINAL.name());
String memberUniqueName =
stringElement(row, "MEMBER_UNIQUE_NAME");
stringElement(
row,
Property.StandardMemberProperty.MEMBER_UNIQUE_NAME.name());
String memberName =
stringElement(row, "MEMBER_NAME");
stringElement(
row,
Property.StandardMemberProperty.MEMBER_NAME.name());
String parentUniqueName =
stringElement(row, "PARENT_UNIQUE_NAME");
stringElement(
row,
Property.StandardMemberProperty.PARENT_UNIQUE_NAME.name());
Member.Type memberType =
Member.Type.values()[
integerElement(row, "MEMBER_TYPE")];
integerElement(
row,
Property.StandardMemberProperty.MEMBER_TYPE.name())];
String memberCaption =
stringElement(row, "MEMBER_CAPTION");
stringElement(
row,
Property.StandardMemberProperty.MEMBER_CAPTION.name());
int childrenCardinality =
integerElement(row, "CHILDREN_CARDINALITY");
integerElement(
row,
Property.StandardMemberProperty.CHILDREN_CARDINALITY.name());
// If this member is a measure, we want to return an object that
// implements the Measure interface to all API calls. But we also
// need to retrieve the properties that occur in MDSCHEMA_MEMBERS
// that are not available in MDSCHEMA_MEASURES, so we create a
// member for internal use.
list.add(
XmlaOlap4jMember member =
new XmlaOlap4jMember(
context.getLevel(row), memberUniqueName, memberName,
memberCaption, "", parentUniqueName, memberType,
childrenCardinality, memberOrdinal));
childrenCardinality, memberOrdinal);
addUserDefinedDimensionProperties(row, member);

// Usually members have the same depth as their level. (Ragged and
// parent-child hierarchies are an exception.) Only store depth for
// the unusual ones.
final Integer depth =
integerElement(
row,
Property.StandardMemberProperty.DEPTH.name());
if (depth != null
&& depth.intValue() != member.getLevel().getDepth())
{
member.setProperty(Property.StandardMemberProperty.DEPTH, depth);
}
list.add(member);
}

private void addUserDefinedDimensionProperties(
Element row,
XmlaOlap4jMember member)
{
NodeList nodes = row.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (EXCLUDED_PROPERTY_NAMES.contains(node.getLocalName())) {
continue;
}
for (Property property : member.getLevel().getProperties()) {
if (property instanceof XmlaOlap4jProperty
&& property.getName().equalsIgnoreCase(
node.getLocalName()))
{
member.setProperty(property, node.getTextContent());
}
}
}
}
}

Expand Down
Loading

0 comments on commit 0a6f2dc

Please sign in to comment.