diff --git a/src/org/olap4j/Axis.java b/src/org/olap4j/Axis.java
index 5de2906..d1b2cf8 100644
--- a/src/org/olap4j/Axis.java
+++ b/src/org/olap4j/Axis.java
@@ -29,6 +29,8 @@ public interface Axis {
/**
* @deprecated Will be removed before olap4j 1.0.
*/
+ // REVIEW: Is it wise to remove this axis enum value?
+ // It's existence IS relevant.
Standard UNUSED = null;
/**
diff --git a/src/org/olap4j/impl/Olap4jUtil.java b/src/org/olap4j/impl/Olap4jUtil.java
index d2f21f0..d64b8d4 100644
--- a/src/org/olap4j/impl/Olap4jUtil.java
+++ b/src/org/olap4j/impl/Olap4jUtil.java
@@ -364,6 +364,22 @@ public static String[] uniqueNameToStringArray(String uniqueName) {
return trail.toArray(new String[trail.size()]);
}
+ /**
+ * Converts the contents of an array of strings to
+ * a proper String representation.
+ */
+ public static String stringArrayToString(String[] array) {
+ StringBuilder sb = new StringBuilder("[");
+ for (int i = 0; i < array.length; i++) {
+ sb.append(array[i]);
+ if (i < (array.length - 1)) {
+ sb.append(",");
+ }
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
@SuppressWarnings({"unchecked"})
public static
NOTE: This package is experimental. Classes may be renamed or removed in a future release of olap4j.
+
+
+
diff --git a/src/org/olap4j/query/Query.java b/src/org/olap4j/query/Query.java
index 494afa0..702134a 100644
--- a/src/org/olap4j/query/Query.java
+++ b/src/org/olap4j/query/Query.java
@@ -22,7 +22,7 @@
/**
* Base query model object.
*
- * @author jhyde, jdixon
+ * @author jhyde, jdixon, Luc Boudreau
* @version $Id$
* @since May 29, 2007
*/
@@ -45,6 +45,13 @@ public class Query extends QueryNodeImpl {
private final OlapConnection connection;
private final SelectionFactory selectionFactory = new SelectionFactory();
+ /**
+ * Constructs a Query object.
+ * @param name Any arbitrary name to give to this query.
+ * @param cube A Cube object against which to build a query.
+ * @throws SQLException If an error occurs while accessing the
+ * cube's underlying connection.
+ */
public Query(String name, Cube cube) throws SQLException {
super();
this.name = name;
@@ -160,6 +167,13 @@ public QueryAxis getUnusedAxis() {
return unused;
}
+ /**
+ * Safely disposes of all underlying objects of this
+ * query.
+ * @param closeConnection Whether or not to call the
+ * {@link OlapConnection#close()} method of the underlying
+ * connection.
+ */
public void tearDown(boolean closeConnection) {
for (Entry Equivalent of calling Query.tearDown(true).
+ */
public void tearDown() {
this.tearDown(true);
}
diff --git a/src/org/olap4j/query/QueryAxis.java b/src/org/olap4j/query/QueryAxis.java
index 72fe9af..0d78513 100644
--- a/src/org/olap4j/query/QueryAxis.java
+++ b/src/org/olap4j/query/QueryAxis.java
@@ -27,7 +27,7 @@
* An axis has a location (columns, rows, etc) and has zero or more
* dimensions that are placed on it.
*
- * @author jdixon
+ * @author jdixon, Luc Boudreau
* @version $Id$
* @since May 29, 2007
*/
@@ -245,36 +245,6 @@ void tearDown() {
this.getDimensions().clear();
}
- /**
- * Defines in what order to perform the sort.
- */
- public static enum SortOrder {
- /**
- * Ascending sort order. Members of
- * the same hierarchy are still kept together.
- */
- ASC,
- /**
- * Descending sort order. Members of
- * the same hierarchy are still kept together.
- */
- DESC,
- /**
- * Sorts in ascending order, but does not
- * maintain members of a same hierarchy
- * together. This is known as a "break
- * hierarchy ascending sort".
- */
- BASC,
- /**
- * Sorts in descending order, but does not
- * maintain members of a same hierarchy
- * together. This is known as a "break
- * hierarchy descending sort".
- */
- BDESC
- }
-
/**
* Sorts the axis according to the supplied order. The sort evaluation
* expression will be the default member of the default hierarchy of
@@ -297,7 +267,7 @@ public void sort(SortOrder order) throws OlapException {
* parts from the underlying cube and find the corresponding
* member. This member will then be passed as a sort evaluation
* expression.
- * @param order The {@link QueryAxis.SortOrder} in which to
+ * @param order The {@link SortOrder} in which to
* sort the axis.
* @param nameParts The unique name parts of the sort
* evaluation expression.
@@ -322,7 +292,7 @@ public void sort(SortOrder order, String... nameParts)
* and member.
* This method is most commonly called by passing
* it a {@link Measure}.
- * @param order The {@link QueryAxis.SortOrder} in which to
+ * @param order The {@link SortOrder} in which to
* sort the axis.
* @param member The member that will be used as a sort
* evaluation expression.
@@ -338,7 +308,7 @@ public void sort(SortOrder order, Member member) {
* and evaluation expression.
* The string value passed as the sortIdentifierNodeName
* parameter willb e used literally as a sort evaluator.
- * @param order The {@link QueryAxis.SortOrder} in which to
+ * @param order The {@link SortOrder} in which to
* sort the axis.
* @param sortEvaluationLiteral The literal expression that
* will be used to sort against.
diff --git a/src/org/olap4j/query/QueryDimension.java b/src/org/olap4j/query/QueryDimension.java
index c083fed..cc8f0a7 100644
--- a/src/org/olap4j/query/QueryDimension.java
+++ b/src/org/olap4j/query/QueryDimension.java
@@ -10,6 +10,7 @@
package org.olap4j.query;
import org.olap4j.OlapException;
+import org.olap4j.impl.Olap4jUtil;
import org.olap4j.mdx.IdentifierNode;
import org.olap4j.mdx.IdentifierNode.Segment;
import org.olap4j.metadata.*;
@@ -31,7 +32,7 @@
* Dimension object in any way so a single Dimension object
* can be referenced by many QueryDimension objects.
*
- * @author jdixon, jhyde
+ * @author jdixon, jhyde, Luc Boudreau
* @version $Id$
* @since May 29, 2007
*/
@@ -67,14 +68,14 @@ public String getName() {
}
@Deprecated
- public void select(String... nameParts) {
+ public void select(String... nameParts) throws OlapException {
this.include(nameParts);
}
@Deprecated
public void select(
Selection.Operator operator,
- String... nameParts)
+ String... nameParts) throws OlapException
{
this.include(operator, nameParts);
}
@@ -102,28 +103,64 @@ public void clearSelection() {
this.clearInclusions();
}
- public void include(String... nameParts) {
+ /**
+ * Selects members and includes them in the query.
+ * This method selects and includes a single member with the
+ * {@link Selection.Operator#MEMBER} operator.
+ * @param nameParts Name of the member to select and include.
+ * @throws OlapException If no member corresponding to the supplied
+ * name parts could be resolved in the cube.
+ */
+ public void include(String... nameParts) throws OlapException {
this.include(Selection.Operator.MEMBER, nameParts);
}
+ /**
+ * Selects members and includes them in the query.
+ * This method selects and includes a member along with it's
+ * relatives, depending on the supplied {@link Selection.Operator}
+ * operator.
+ * @param operator Selection operator that defines what relatives of the
+ * supplied member name to include along.
+ * @param nameParts Name of the root member to select and include.
+ * @throws OlapException If no member corresponding to the supplied
+ * name parts could be resolved in the cube.
+ */
public void include(
Selection.Operator operator,
- String... nameParts)
+ String... nameParts) throws OlapException
{
- try {
+ Member member = this.getQuery().getCube().lookupMember(nameParts);
+ if (member == null) {
+ throw new OlapException(
+ "Unable to find a member with name "
+ + Olap4jUtil.stringArrayToString(nameParts));
+ } else {
this.include(
operator,
- this.getQuery().getCube().lookupMember(nameParts));
- } catch (OlapException e) {
- // Nothing to do, but we'll still log the exception.
- e.printStackTrace();
+ member);
}
}
+ /**
+ * Selects members and includes them in the query.
+ * This method selects and includes a single member with the
+ * {@link Selection.Operator#MEMBER} selection operator.
+ * @param member The member to select and include in the query.
+ */
public void include(Member member) {
include(Selection.Operator.MEMBER, member);
}
+ /**
+ * Selects members and includes them in the query.
+ * This method selects and includes a member along with it's
+ * relatives, depending on the supplied {@link Selection.Operator}
+ * operator.
+ * @param operator Selection operator that defines what relatives of the
+ * supplied member name to include along.
+ * @param member Root member to select and include.
+ */
public void include(
Selection.Operator operator,
Member member)
@@ -136,6 +173,10 @@ public void include(
}
}
+ /**
+ * Includes a selection of members in the query.
+ * @param selection The selection of members to include.
+ */
private void include(Selection selection) {
this.getInclusions().add(selection);
Integer index = Integer.valueOf(
@@ -158,28 +199,64 @@ public void clearInclusions() {
this.notifyRemove(removed);
}
- public void exclude(String... nameParts) {
+ /**
+ * Selects members and excludes them from the query.
+ * This method selects and excludes a single member with the
+ * {@link Selection.Operator#MEMBER} operator.
+ * @param nameParts Name of the member to select and exclude.
+ * @throws OlapException If no member corresponding to the supplied
+ * name parts could be resolved in the cube.
+ */
+ public void exclude(String... nameParts) throws OlapException {
this.exclude(Selection.Operator.MEMBER, nameParts);
}
+ /**
+ * Selects members and excludes them from the query.
+ * This method selects and excludes a member along with it's
+ * relatives, depending on the supplied {@link Selection.Operator}
+ * operator.
+ * @param operator Selection operator that defines what relatives of the
+ * supplied member name to exclude along.
+ * @param nameParts Name of the root member to select and exclude.
+ * @throws OlapException If no member corresponding to the supplied
+ * name parts could be resolved in the cube.
+ */
public void exclude(
Selection.Operator operator,
- String... nameParts)
+ String... nameParts) throws OlapException
{
- try {
+ Member rootMember = this.getQuery().getCube().lookupMember(nameParts);
+ if (rootMember == null) {
+ throw new OlapException(
+ "Unable to find a member with name "
+ + Olap4jUtil.stringArrayToString(nameParts));
+ } else {
this.exclude(
operator,
- this.getQuery().getCube().lookupMember(nameParts));
- } catch (OlapException e) {
- // Nothing to do, but we'll still log the exception.
- e.printStackTrace();
+ rootMember);
}
}
+ /**
+ * Selects members and excludes them from the query.
+ * This method selects and excludes a single member with the
+ * {@link Selection.Operator#MEMBER} selection operator.
+ * @param member The member to select and exclude from the query.
+ */
public void exclude(Member member) {
exclude(Selection.Operator.MEMBER, member);
}
+ /**
+ * Selects members and excludes them from the query.
+ * This method selects and excludes a member along with it's
+ * relatives, depending on the supplied {@link Selection.Operator}
+ * operator.
+ * @param operator Selection operator that defines what relatives of the
+ * supplied member name to exclude along.
+ * @param member Root member to select and exclude.
+ */
public void exclude(
Selection.Operator operator,
Member member)
@@ -192,6 +269,10 @@ public void exclude(
}
}
+ /**
+ * Excludes a selection of members from the query.
+ * @param selection The selection of members to exclude.
+ */
private void exclude(Selection selection) {
this.getExclusions().add(selection);
Integer index = Integer.valueOf(
@@ -223,6 +304,14 @@ public static String[] getNameParts(String sel) {
return nameParts;
}
+ /**
+ * Resolves a selection of members into an actual list
+ * of the root member and it's relatives selected by the Selection object.
+ * @param selection The selection of members to resolve.
+ * @return A list of the actual members selected by the selection object.
+ * @throws OlapException If resolving the selections triggers an exception
+ * while looking up members in the underlying cube.
+ */
public List Returns a mutable object so operations on it have
+ * unpredictable consequences.
+ * @return The underlying dimension representation.
+ */
public Dimension getDimension() {
return dimension;
}
+ /**
+ * Forces a change onto which dimension is the current
+ * base of this QueryDimension object.
+ * Forcing a change in the duimension assignment has
+ * unpredictable consequences.
+ * @param dimension The new dimension to assign to this
+ * query dimension.
+ */
public void setDimension(Dimension dimension) {
this.dimension = dimension;
}
@@ -312,7 +416,7 @@ public void setDimension(Dimension dimension) {
* order supplied as a parameter.
* @param order The {@link SortOrder} to use.
*/
- public void setSortOrder(SortOrder order) {
+ public void sort(SortOrder order) {
this.sortOrder = order;
}
@@ -332,6 +436,12 @@ public void clearSort() {
this.sortOrder = null;
}
+ /**
+ * Returns the current mode of hierarchyzation, or null
+ * if no hierarchyzation is currently performed.
+ * @return Either a hierarchyzation mode value or null
+ * if no hierarchyzation is currently performed.
+ */
public HierarchizeMode getHierarchizeMode() {
return hierarchizeMode;
}
@@ -350,6 +460,13 @@ public void setHierarchizeMode(HierarchizeMode hierarchizeMode) {
this.hierarchizeMode = hierarchizeMode;
}
+ /**
+ * Tells the QueryDimension not to hierarchyze it's included selections.
+ */
+ public void clearHierarchizeMode() {
+ this.hierarchizeMode = null;
+ }
+
private class SelectionList extends AbstractList Implemented via the MDX .Children member property.
+ */
+ CHILDREN,
+ /**
+ * The root member will be selected along with all it's
+ * children.
+ */
+ INCLUDE_CHILDREN,
+ /**
+ * Will select the root member along with all it's siblings.
+ * Implemented via the MDX .Siblings member property.
+ */
+ SIBLINGS,
+ /**
+ * Selects the set of the ascendants of a specified member,
+ * including the member itself.
+ * Implemented via the MDX Ascendants() function.
+ */
+ ANCESTORS,
+ /**
+ * Selects the set of the descendants of a specified member,
+ * including the member itself.
+ * Implemented via the MDX Descendants() function.
+ */
+ DESCENDANTS;
}
}
diff --git a/src/org/olap4j/query/SelectionFactory.java b/src/org/olap4j/query/SelectionFactory.java
index dd2d228..a42a0b1 100644
--- a/src/org/olap4j/query/SelectionFactory.java
+++ b/src/org/olap4j/query/SelectionFactory.java
@@ -20,7 +20,7 @@
* @version $Id$
* @since May 30, 2007
*/
-public class SelectionFactory {
+class SelectionFactory {
Selection createMemberSelection(
Member member,
diff --git a/src/org/olap4j/query/SortOrder.java b/src/org/olap4j/query/SortOrder.java
new file mode 100644
index 0000000..e87686e
--- /dev/null
+++ b/src/org/olap4j/query/SortOrder.java
@@ -0,0 +1,43 @@
+/*
+// $Id:$
+// This software is subject to the terms of the Eclipse Public License v1.0
+// Agreement, available at the following URL:
+// http://www.eclipse.org/legal/epl-v10.html.
+// Copyright (C) 2007-2009 Julian Hyde
+// All Rights Reserved.
+// You must accept the terms of that agreement to use this software.
+*/
+package org.olap4j.query;
+/**
+ * Defines in what order to perform sort operations.
+ * @author Luc Boudreau
+ * @version $Id:$
+ * @since 0.9.8
+ */
+public enum SortOrder {
+ /**
+ * Ascending sort order. Members of
+ * the same hierarchy are still kept together.
+ */
+ ASC,
+ /**
+ * Descending sort order. Members of
+ * the same hierarchy are still kept together.
+ */
+ DESC,
+ /**
+ * Sorts in ascending order, but does not
+ * maintain members of a same hierarchy
+ * together. This is known as a "break
+ * hierarchy ascending sort".
+ */
+ BASC,
+ /**
+ * Sorts in descending order, but does not
+ * maintain members of a same hierarchy
+ * together. This is known as a "break
+ * hierarchy descending sort".
+ */
+ BDESC
+}
+// End SortOrder.java
diff --git a/src/org/olap4j/sample/SimpleQuerySample.java b/src/org/olap4j/sample/SimpleQuerySample.java
index c828803..c85dbdd 100644
--- a/src/org/olap4j/sample/SimpleQuerySample.java
+++ b/src/org/olap4j/sample/SimpleQuerySample.java
@@ -15,7 +15,7 @@
import org.olap4j.mdx.*;
import org.olap4j.metadata.Dimension;
import org.olap4j.metadata.Member;
-import org.olap4j.query.RectangularCellSetFormatter;
+import org.olap4j.layout.RectangularCellSetFormatter;
import org.olap4j.type.MemberType;
import java.io.PrintWriter;
diff --git a/testsrc/org/olap4j/CellSetFormatterTest.java b/testsrc/org/olap4j/CellSetFormatterTest.java
index 589f4e9..51d8a8c 100644
--- a/testsrc/org/olap4j/CellSetFormatterTest.java
+++ b/testsrc/org/olap4j/CellSetFormatterTest.java
@@ -12,8 +12,8 @@
import junit.framework.TestCase;
import org.olap4j.test.TestContext;
-import org.olap4j.query.TraditionalCellSetFormatter;
-import org.olap4j.query.RectangularCellSetFormatter;
+import org.olap4j.layout.TraditionalCellSetFormatter;
+import org.olap4j.layout.RectangularCellSetFormatter;
import java.sql.SQLException;
import java.sql.Connection;
diff --git a/testsrc/org/olap4j/OlapTest.java b/testsrc/org/olap4j/OlapTest.java
index 1cbac50..e7c382d 100644
--- a/testsrc/org/olap4j/OlapTest.java
+++ b/testsrc/org/olap4j/OlapTest.java
@@ -12,13 +12,11 @@
import org.olap4j.metadata.*;
import org.olap4j.query.*;
import org.olap4j.query.QueryDimension.HierarchizeMode;
-import org.olap4j.query.QueryDimension.SortOrder;
import org.olap4j.query.Selection.Operator;
import org.olap4j.test.TestContext;
import java.sql.Connection;
import java.sql.DriverManager;
-import java.util.List;
import junit.framework.TestCase;
@@ -66,20 +64,17 @@ public Cube getFoodmartCube(String cubeName) {
Catalog catalog = olapConnection.getCatalogs().get(catalogName);
NamedList