Skip to content

Commit 0a6f2dc

Browse files
committed
Fix bug 2032449, 'User Defined Dimension Properties'.
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
1 parent dd190c9 commit 0a6f2dc

8 files changed

+448
-55
lines changed

src/org/olap4j/driver/xmla/XmlaOlap4jCellSet.java

+25-3
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ void populate() throws OlapException {
233233
String hierarchyName =
234234
memberNode.getAttribute("Hierarchy");
235235
final String uname = stringElement(memberNode, "UName");
236-
Member member = memberMap.get(uname);
236+
XmlaOlap4jMemberBase member = memberMap.get(uname);
237237
if (member == null) {
238238
final String caption =
239239
stringElement(memberNode, "Caption");
@@ -242,7 +242,7 @@ void populate() throws OlapException {
242242
lookupHierarchy(metaData.cube, hierarchyName);
243243
final Level level = hierarchy.getLevels().get(lnum);
244244
member = new XmlaOlap4jSurpriseMember(
245-
level, hierarchy, lnum, caption, uname);
245+
this, level, hierarchy, lnum, caption, uname);
246246
}
247247
propertyValues.clear();
248248
for (Element childNode : childElements(memberNode)) {
@@ -1228,7 +1228,10 @@ public boolean isWrapperFor(Class<?> iface) throws SQLException {
12281228
* in the cube (probably because the member is a calculated member
12291229
* defined in the query).
12301230
*/
1231-
private static class XmlaOlap4jSurpriseMember implements Member {
1231+
private static class XmlaOlap4jSurpriseMember
1232+
implements XmlaOlap4jMemberBase
1233+
{
1234+
private final XmlaOlap4jCellSet cellSet;
12321235
private final Level level;
12331236
private final Hierarchy hierarchy;
12341237
private final int lnum;
@@ -1238,26 +1241,45 @@ private static class XmlaOlap4jSurpriseMember implements Member {
12381241
/**
12391242
* Creates an XmlaOlap4jSurpriseMember.
12401243
*
1244+
* @param cellSet Cell set
12411245
* @param level Level
12421246
* @param hierarchy Hierarchy
12431247
* @param lnum Level number
12441248
* @param caption Caption
12451249
* @param uname Member unique name
12461250
*/
12471251
XmlaOlap4jSurpriseMember(
1252+
XmlaOlap4jCellSet cellSet,
12481253
Level level,
12491254
Hierarchy hierarchy,
12501255
int lnum,
12511256
String caption,
12521257
String uname)
12531258
{
1259+
this.cellSet = cellSet;
12541260
this.level = level;
12551261
this.hierarchy = hierarchy;
12561262
this.lnum = lnum;
12571263
this.caption = caption;
12581264
this.uname = uname;
12591265
}
12601266

1267+
public final XmlaOlap4jCube getCube() {
1268+
return cellSet.metaData.cube;
1269+
}
1270+
1271+
public final XmlaOlap4jConnection getConnection() {
1272+
return getCatalog().olap4jDatabaseMetaData.olap4jConnection;
1273+
}
1274+
1275+
public final XmlaOlap4jCatalog getCatalog() {
1276+
return getCube().olap4jSchema.olap4jCatalog;
1277+
}
1278+
1279+
public Map<Property, Object> getPropertyValueMap() {
1280+
return Collections.emptyMap();
1281+
}
1282+
12611283
public NamedList<? extends Member> getChildMembers()
12621284
{
12631285
return Olap4jUtil.emptyNamedList();

src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java

+96-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// This software is subject to the terms of the Common Public License
33
// Agreement, available at the following URL:
44
// http://www.opensource.org/licenses/cpl.html.
5-
// Copyright (C) 2007-2007 Julian Hyde
5+
// Copyright (C) 2007-2008 Julian Hyde
66
// All Rights Reserved.
77
// You must accept the terms of that agreement to use this software.
88
*/
@@ -19,9 +19,7 @@
1919
import org.olap4j.mdx.parser.*;
2020
import org.olap4j.mdx.parser.impl.DefaultMdxParserImpl;
2121
import org.olap4j.metadata.*;
22-
import org.w3c.dom.DOMImplementation;
23-
import org.w3c.dom.Document;
24-
import org.w3c.dom.Element;
22+
import org.w3c.dom.*;
2523
import org.w3c.dom.ls.DOMImplementationLS;
2624
import org.w3c.dom.ls.LSSerializer;
2725
import org.xml.sax.SAXException;
@@ -34,10 +32,6 @@
3432
import java.util.Map.*;
3533
import java.util.regex.*;
3634

37-
import javax.xml.transform.*;
38-
import javax.xml.transform.dom.*;
39-
import javax.xml.transform.stream.*;
40-
4135
/**
4236
* Implementation of {@link org.olap4j.OlapConnection}
4337
* for XML/A providers.
@@ -1078,6 +1072,34 @@ public int compare(
10781072
}
10791073

10801074
static class MemberHandler extends HandlerImpl<XmlaOlap4jMember> {
1075+
1076+
/**
1077+
* Collection of nodes to ignore because they represent standard
1078+
* built-in properties of Members.
1079+
*/
1080+
private static final Set<String> EXCLUDED_PROPERTY_NAMES =
1081+
new HashSet<String>(
1082+
Arrays.asList(
1083+
Property.StandardMemberProperty.CATALOG_NAME.name(),
1084+
Property.StandardMemberProperty.CUBE_NAME.name(),
1085+
Property.StandardMemberProperty.DIMENSION_UNIQUE_NAME.name(),
1086+
Property.StandardMemberProperty.HIERARCHY_UNIQUE_NAME.name(),
1087+
Property.StandardMemberProperty.LEVEL_UNIQUE_NAME.name(),
1088+
Property.StandardMemberProperty.PARENT_LEVEL.name(),
1089+
Property.StandardMemberProperty.PARENT_COUNT.name(),
1090+
Property.StandardMemberProperty.MEMBER_KEY.name(),
1091+
Property.StandardMemberProperty.IS_PLACEHOLDERMEMBER.name(),
1092+
Property.StandardMemberProperty.IS_DATAMEMBER.name(),
1093+
Property.StandardMemberProperty.LEVEL_NUMBER.name(),
1094+
Property.StandardMemberProperty.MEMBER_ORDINAL.name(),
1095+
Property.StandardMemberProperty.MEMBER_UNIQUE_NAME.name(),
1096+
Property.StandardMemberProperty.MEMBER_NAME.name(),
1097+
Property.StandardMemberProperty.PARENT_UNIQUE_NAME.name(),
1098+
Property.StandardMemberProperty.MEMBER_TYPE.name(),
1099+
Property.StandardMemberProperty.MEMBER_CAPTION.name(),
1100+
Property.StandardMemberProperty.CHILDREN_CARDINALITY.name(),
1101+
Property.StandardMemberProperty.DEPTH.name()));
1102+
10811103
public void handle(Element row, Context context, List<XmlaOlap4jMember> list) {
10821104
/*
10831105
Example:
@@ -1103,31 +1125,87 @@ public void handle(Element row, Context context, List<XmlaOlap4jMember> list) {
11031125
</row>
11041126
11051127
*/
1106-
int levelNumber = integerElement(row, "LEVEL_NUMBER");
1107-
int memberOrdinal = integerElement(row, "MEMBER_ORDINAL");
1128+
if (false) {
1129+
int levelNumber =
1130+
integerElement(
1131+
row,
1132+
Property.StandardMemberProperty.LEVEL_NUMBER.name());
1133+
}
1134+
int memberOrdinal =
1135+
integerElement(
1136+
row,
1137+
Property.StandardMemberProperty.MEMBER_ORDINAL.name());
11081138
String memberUniqueName =
1109-
stringElement(row, "MEMBER_UNIQUE_NAME");
1139+
stringElement(
1140+
row,
1141+
Property.StandardMemberProperty.MEMBER_UNIQUE_NAME.name());
11101142
String memberName =
1111-
stringElement(row, "MEMBER_NAME");
1143+
stringElement(
1144+
row,
1145+
Property.StandardMemberProperty.MEMBER_NAME.name());
11121146
String parentUniqueName =
1113-
stringElement(row, "PARENT_UNIQUE_NAME");
1147+
stringElement(
1148+
row,
1149+
Property.StandardMemberProperty.PARENT_UNIQUE_NAME.name());
11141150
Member.Type memberType =
11151151
Member.Type.values()[
1116-
integerElement(row, "MEMBER_TYPE")];
1152+
integerElement(
1153+
row,
1154+
Property.StandardMemberProperty.MEMBER_TYPE.name())];
11171155
String memberCaption =
1118-
stringElement(row, "MEMBER_CAPTION");
1156+
stringElement(
1157+
row,
1158+
Property.StandardMemberProperty.MEMBER_CAPTION.name());
11191159
int childrenCardinality =
1120-
integerElement(row, "CHILDREN_CARDINALITY");
1160+
integerElement(
1161+
row,
1162+
Property.StandardMemberProperty.CHILDREN_CARDINALITY.name());
11211163
// If this member is a measure, we want to return an object that
11221164
// implements the Measure interface to all API calls. But we also
11231165
// need to retrieve the properties that occur in MDSCHEMA_MEMBERS
11241166
// that are not available in MDSCHEMA_MEASURES, so we create a
11251167
// member for internal use.
1126-
list.add(
1168+
XmlaOlap4jMember member =
11271169
new XmlaOlap4jMember(
11281170
context.getLevel(row), memberUniqueName, memberName,
11291171
memberCaption, "", parentUniqueName, memberType,
1130-
childrenCardinality, memberOrdinal));
1172+
childrenCardinality, memberOrdinal);
1173+
addUserDefinedDimensionProperties(row, member);
1174+
1175+
// Usually members have the same depth as their level. (Ragged and
1176+
// parent-child hierarchies are an exception.) Only store depth for
1177+
// the unusual ones.
1178+
final Integer depth =
1179+
integerElement(
1180+
row,
1181+
Property.StandardMemberProperty.DEPTH.name());
1182+
if (depth != null
1183+
&& depth.intValue() != member.getLevel().getDepth())
1184+
{
1185+
member.setProperty(Property.StandardMemberProperty.DEPTH, depth);
1186+
}
1187+
list.add(member);
1188+
}
1189+
1190+
private void addUserDefinedDimensionProperties(
1191+
Element row,
1192+
XmlaOlap4jMember member)
1193+
{
1194+
NodeList nodes = row.getChildNodes();
1195+
for (int i = 0; i < nodes.getLength(); i++) {
1196+
Node node = nodes.item(i);
1197+
if (EXCLUDED_PROPERTY_NAMES.contains(node.getLocalName())) {
1198+
continue;
1199+
}
1200+
for (Property property : member.getLevel().getProperties()) {
1201+
if (property instanceof XmlaOlap4jProperty
1202+
&& property.getName().equalsIgnoreCase(
1203+
node.getLocalName()))
1204+
{
1205+
member.setProperty(property, node.getTextContent());
1206+
}
1207+
}
1208+
}
11311209
}
11321210
}
11331211

0 commit comments

Comments
 (0)