From 24050d713fc5f49ffe1cee966316f43003b86d6e Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Thu, 1 Oct 2009 00:57:29 +0000 Subject: [PATCH] Add writeback API (Scenario, AllocationPolicy). Fix some references broken by the CellSetFormatter move. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@282 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- src/org/olap4j/AllocationPolicy.java | 100 ++++++++++++++++++ src/org/olap4j/Cell.java | 22 ++++ src/org/olap4j/OlapConnection.java | 38 +++++++ src/org/olap4j/Scenario.java | 47 ++++++++ .../olap4j/driver/xmla/XmlaOlap4jCell.java | 8 ++ .../driver/xmla/XmlaOlap4jConnection.java | 12 +++ src/org/olap4j/sample/SimpleQuerySample.java | 2 +- testsrc/org/olap4j/CellSetFormatterTest.java | 6 +- 8 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 src/org/olap4j/AllocationPolicy.java create mode 100644 src/org/olap4j/Scenario.java diff --git a/src/org/olap4j/AllocationPolicy.java b/src/org/olap4j/AllocationPolicy.java new file mode 100644 index 0000000..c9e65c7 --- /dev/null +++ b/src/org/olap4j/AllocationPolicy.java @@ -0,0 +1,100 @@ +/* +// $Id: Cell.java 229 2009-05-08 19:11:29Z jhyde $ +// 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) 2009-2009 Julian Hyde +// All Rights Reserved. +// You must accept the terms of that agreement to use this software. +*/ +package org.olap4j; + +/** + * Enumeration of the policies that can be used to modify the values of + * child cells when their parent cell is modified in a writeback operation. + * + * @see Cell#setValue + * + * @author jhyde + * @version $Id: Cell.java 229 2009-05-08 19:11:29Z jhyde $ + * @since Aug 22, 2006 + */ +public enum AllocationPolicy { + /** + * Every atomic cell that contributes to the updated cell will be + * assigned an equal value that is: + * + *
+ * <atomic cell value> = + * <value> / Count(atomic cells contained in <tuple>) + *
+ */ + EQUAL_ALLOCATION, + + /** + * Every atomic cell that contributes to the updated cell will be + * changed according to: + * + *
+ * <atomic cell value> = <atomic cell value> + + * (<value> - <existing value>) / + * Count(atomic cells contained in <tuple>) + *
+ */ + EQUAL_INCREMENT, + + /** + * Every atomic cell that contributes to the updated cell will be + * assigned an equal value that is: + * + *
+ * <atomic cell value> = + * <value> * <weight value expression> + *
+ * + *

Takes an optional argument, {@code weight_value_expression}. + * If {@code weight_value_expression} is not provided, the following + * expression is assigned to it by default: + * + *

+ * <weight value expression> = + * <atomic cell value> / <existing value> + *
+ * + *

The value of {@code weight value expression} should be expressed + * as a value between 0 and 1. This value specifies the ratio of the + * allocated value you want to assign to the atomic cells that are + * affected by the allocation. It is the client application programmer's + * responsibilffity to create expressions whose rollup aggregate values + * will equal the allocated value of the expression. + */ + WEIGHTED_ALLOCATION, + + /** + * Every atomic cell that contributes to the updated cell will be + * changed according to: + * + *

+ * <atomic cell value> = <atomic cell value> + + * (<value> - <existing value>) * + * <weight value expression> + *
+ * + *

Takes an optional argument, {@code weight_value_expression}. + * If {@code weight_value_expression} is not provided, the following + * expression is assigned to it by default: + * + *

+ * <weight value expression> = + * <atomic cell value> / <existing value> + *
+ * + *

The value of {@code weight value expression} should be expressed + * as a value between 0 and 1. This value specifies the ratio of the + * allocated value you want to assign to the atomic cells that are + * affected by the allocation. It is the client application programmer's + * responsibility to create expressions whose rollup aggregate values + * will equal the allocated value of the expression. + */ + WEIGHTED_INCREMENT, +} diff --git a/src/org/olap4j/Cell.java b/src/org/olap4j/Cell.java index f485a5e..b7e2bbd 100755 --- a/src/org/olap4j/Cell.java +++ b/src/org/olap4j/Cell.java @@ -168,6 +168,28 @@ public interface Cell { * @throws OlapException if a database error occurs */ ResultSet drillThrough() throws OlapException; + + /** + * Sets the value of a cell. + * + *

When this method may be called depends on the provider. But typically, + * the connection must at least have an active scenario; see + * {@link OlapConnection#setScenario(Scenario)}. + * + *

The number and type of additional arguments specified in the + * {@code allocationArgs} parameter depends on the allocation policy chosen. + * Some policies, such as {@link AllocationPolicy#EQUAL_ALLOCATION}, do not + * require any additional arguments, in which case {@code allocationArgs} + * may be {@code null}. + * + * @param value Cell value + * @param allocationPolicy Allocation policy + * @param allocationArgs Allocation policy arguments + */ + void setValue( + Object value, + AllocationPolicy allocationPolicy, + Object... allocationArgs); } // End Cell.java diff --git a/src/org/olap4j/OlapConnection.java b/src/org/olap4j/OlapConnection.java index ca3f396..0a8e244 100644 --- a/src/org/olap4j/OlapConnection.java +++ b/src/org/olap4j/OlapConnection.java @@ -113,6 +113,44 @@ public interface OlapConnection extends Connection, OlapWrapper { * @return name of the role in which this connection executes queries */ String getRoleName(); + + /** + * Creates a Scenario. + * + *

It does not become the active scenario for the current connection. + * To do this, call {@link #setScenario(Scenario)}. + * + * @see #setScenario + * + * @return a new Scenario + */ + Scenario createScenario(); + + /** + * Sets the active Scenario of this connection. + * + *

After setting a scenario, the client may call + * {@link Cell#setValue} to change the value of cells returned + * from queries. The value of those cells is changed. This operation is + * referred to as 'writeback', and is used to perform 'what if' analysis, + * such as budgeting. See {@link Scenario} for more details. + * + *

If {@code scenario} is null, the connection will have no active + * scenario, and writeback is not allowed. + * + *

Scenarios are created using {@link #createScenario()}. + * + * @param scenario Scenario + */ + void setScenario(Scenario scenario); + + /** + * Returns this connection's active Scenario, or null if there is no + * active Scenario. + * + * @return Active scenario, or null + */ + Scenario getScenario(); } // End OlapConnection.java diff --git a/src/org/olap4j/Scenario.java b/src/org/olap4j/Scenario.java new file mode 100644 index 0000000..f1d5a87 --- /dev/null +++ b/src/org/olap4j/Scenario.java @@ -0,0 +1,47 @@ +/* +// $Id: //open/mondrian/src/main/mondrian/olap/Scenario.java#4 $ +// 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) 2009-2009 Julian Hyde and others +// All Rights Reserved. +// You must accept the terms of that agreement to use this software. +*/ +package org.olap4j; + +/** + * Context for a set of writeback operations. + * + *

An analyst performing a what-if analysis would first create a scenario, + * or open an existing scenario, then modify a sequence of cell values. + * + *

Some OLAP engines allow scenarios to be saved (to a file, or perhaps to + * the database) and restored in a future session. + * + *

Multiple scenarios may be open at the same time, by different users of + * the OLAP engine. + * + * @see OlapConnection#createScenario() + * @see OlapConnection#setScenario(Scenario) + * @see OlapConnection#getScenario() + * @see Cell#setValue(Object, AllocationPolicy, Object[]) + * @see AllocationPolicy + * + * @author jhyde + * @since 24 April, 2009 + * @version $Id: //open/mondrian/src/main/mondrian/olap/Scenario.java#4 $ + */ +public interface Scenario { + /** + * Returns the unique identifier of this Scenario. + * + *

The format of the string returned is implementation defined. Client + * applications must not make any assumptions about the structure or + * contents of such strings. + * + * @return Unique identifier of this Scenario. + */ + String getId(); +} + +// End Scenario.java diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jCell.java b/src/org/olap4j/driver/xmla/XmlaOlap4jCell.java index 5fa056d..d62423d 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jCell.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jCell.java @@ -102,6 +102,14 @@ public String getFormattedValue() { public ResultSet drillThrough() throws OlapException { throw new UnsupportedOperationException(); } + + public void setValue( + Object value, + AllocationPolicy allocationPolicy, + Object... allocationArgs) + { + throw new UnsupportedOperationException(); + } } // End XmlaOlap4jCell.java diff --git a/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java b/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java index f093fb9..bd231d8 100644 --- a/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java +++ b/src/org/olap4j/driver/xmla/XmlaOlap4jConnection.java @@ -611,6 +611,18 @@ public String getRoleName() { return roleName; } + public Scenario createScenario() { + throw new UnsupportedOperationException(); + } + + public void setScenario(Scenario scenario) { + throw new UnsupportedOperationException(); + } + + public Scenario getScenario() { + throw new UnsupportedOperationException(); + } + void populateList( List list, Context context, diff --git a/src/org/olap4j/sample/SimpleQuerySample.java b/src/org/olap4j/sample/SimpleQuerySample.java index c85dbdd..837da14 100644 --- a/src/org/olap4j/sample/SimpleQuerySample.java +++ b/src/org/olap4j/sample/SimpleQuerySample.java @@ -206,7 +206,7 @@ void statementFromParseTree() throws ClassNotFoundException, SQLException { * Prints a cell set. * *

For more sophisticated printing of cell sets, see - * {@link org.olap4j.query.CellSetFormatter}. + * {@link org.olap4j.layout.CellSetFormatter}. * * @param cellSet Cell set */ diff --git a/testsrc/org/olap4j/CellSetFormatterTest.java b/testsrc/org/olap4j/CellSetFormatterTest.java index 51d8a8c..1488cce 100644 --- a/testsrc/org/olap4j/CellSetFormatterTest.java +++ b/testsrc/org/olap4j/CellSetFormatterTest.java @@ -23,9 +23,9 @@ /** * Unit test for converting MDX CellSets to text. * - * @see org.olap4j.query.CellSetFormatter - * @see org.olap4j.query.RectangularCellSetFormatter - * @see org.olap4j.query.TraditionalCellSetFormatter + * @see org.olap4j.layout.CellSetFormatter + * @see org.olap4j.layout.RectangularCellSetFormatter + * @see org.olap4j.layout.TraditionalCellSetFormatter * * @author jhyde * @version $Id$