From 828ad8f69dc17bce45145422dde81f086182ca77 Mon Sep 17 00:00:00 2001 From: Luc Boudreau Date: Fri, 4 Feb 2011 00:24:40 +0000 Subject: [PATCH] Refactored the selection objects so that everything is statically typed rather than a conditional instanceof check. I used a pseudo visitor pattern approach. I also factored out the selection implementations into an abstract super class. I also simplified the selection objects and removed all unnecessary calls. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@401 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- src/org/olap4j/query/AbstractSelection.java | 73 ++++++++++++ src/org/olap4j/query/LevelSelectionImpl.java | 105 +++--------------- src/org/olap4j/query/MemberSelectionImpl.java | 99 +++-------------- src/org/olap4j/query/Olap4jNodeConverter.java | 15 +-- src/org/olap4j/query/Query.java | 2 +- src/org/olap4j/query/QueryDimension.java | 3 +- src/org/olap4j/query/Selection.java | 41 +++++-- src/org/olap4j/query/SelectionFactory.java | 5 - 8 files changed, 138 insertions(+), 205 deletions(-) create mode 100644 src/org/olap4j/query/AbstractSelection.java diff --git a/src/org/olap4j/query/AbstractSelection.java b/src/org/olap4j/query/AbstractSelection.java new file mode 100644 index 0000000..438d28c --- /dev/null +++ b/src/org/olap4j/query/AbstractSelection.java @@ -0,0 +1,73 @@ +/* +// $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-2011 Julian Hyde +// All Rights Reserved. +// You must accept the terms of that agreement to use this software. +*/ +package org.olap4j.query; + +import java.util.ArrayList; +import java.util.List; + +import org.olap4j.metadata.Dimension; + +/** + * Abstract implementation of a selection. + * @author LBoudreau + * @version $Id:$ + */ +abstract class AbstractSelection extends QueryNodeImpl implements Selection { + + Operator operator; + Dimension dimension; + List selectionContext; + + public AbstractSelection( + Dimension dimension, + Operator operator) + { + this.dimension = dimension; + this.operator = operator; + } + + public Dimension getDimension() { + return dimension; + } + + public Operator getOperator() { + return operator; + } + + public void setOperator(Operator operator) { + assert operator != null; + this.operator = operator; + notifyChange(this,-1); + } + + void tearDown() { + } + + public List getSelectionContext() { + return selectionContext; + } + + public void addContext(Selection selection) { + if (selectionContext == null) { + selectionContext = new ArrayList(); + } + selectionContext.add(selection); + } + + public void removeContext(Selection selection) { + selectionContext.remove(selection); + } + + public String getUniqueName() { + return getRootElement().getUniqueName(); + } +} + +// End AbstractSelection.java diff --git a/src/org/olap4j/query/LevelSelectionImpl.java b/src/org/olap4j/query/LevelSelectionImpl.java index b4f3bf1..85e0a12 100644 --- a/src/org/olap4j/query/LevelSelectionImpl.java +++ b/src/org/olap4j/query/LevelSelectionImpl.java @@ -3,18 +3,16 @@ // 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-2010 Julian Hyde +// Copyright (C) 2007-2011 Julian Hyde // All Rights Reserved. // You must accept the terms of that agreement to use this software. */ package org.olap4j.query; -import java.util.ArrayList; -import java.util.List; - +import org.olap4j.mdx.ParseTreeNode; import org.olap4j.metadata.Dimension; import org.olap4j.metadata.Level; -import org.olap4j.metadata.Member; +import org.olap4j.metadata.MetadataElement; /** * Abstract implementation of {@link Selection}. @@ -23,34 +21,17 @@ * @version $Id: LevelSelectionImpl.java 399 2011-02-03 20:53:50Z pstoellberger $ * @since Feb 3, 2011 */ -class LevelSelectionImpl extends QueryNodeImpl implements Selection { +class LevelSelectionImpl extends AbstractSelection { protected Level level; - protected String dimensionName; - protected String hierarchyName; - protected String levelName; - protected Dimension dimension; - protected Operator operator = Operator.MEMBER; - protected List selectionContext; - /** - * Creates a SelectionImpl. - * - * @pre operator != null - */ public LevelSelectionImpl( Level level, Dimension dimension, - String hierarchyName, - String levelName, Operator operator) { - super(); + super(dimension, operator); this.level = level; - this.dimension = dimension; - this.hierarchyName = hierarchyName; - this.levelName = levelName; - this.operator = operator; } public int hashCode() { @@ -102,81 +83,21 @@ public boolean equals(Object obj) { return true; } - public String getName() { - return levelName; - } - - public void setName(String name) { - levelName = name; - } - - public Dimension getDimension() { - return dimension; - } - - public void setDimension(Dimension dimension) { - this.dimension = dimension; - } - - public Level getLevel() { + public MetadataElement getRootElement() { return level; } - public String getDimensionName() { - return dimensionName; - } - - public void setDimensionName(String dimensionName) { - this.dimensionName = dimensionName; - } - - public String getHierarchyName() { - return hierarchyName; - } - - public void setHierarchyName(String hierarchyName) { - this.hierarchyName = hierarchyName; - } - - public String getLevelName() { - return levelName; - } - - public void setLevelName(String levelName) { - this.levelName = levelName; - } - - public Operator getOperator() { - return operator; + public ParseTreeNode visit() { + return Olap4jNodeConverter.toOlap4j(level, operator); } + @Override public void setOperator(Operator operator) { - assert operator != null; - this.operator = operator; - notifyChange(this,-1); - } - - void tearDown() { - } - - public List getSelectionContext() { - return selectionContext; - } - - public void addContext(Selection selection) { - if (selectionContext == null) { - selectionContext = new ArrayList(); + if (!operator.equals(Operator.MEMBERS)) { + throw new IllegalArgumentException( + "Selections based on a Level have to be of Operator MEMBERS."); } - selectionContext.add(selection); - } - - public void removeContext(Selection selection) { - selectionContext.remove(selection); - } - - public Member getMember() { - // there is no member in this type of Selections - return null; + super.setOperator(operator); } } diff --git a/src/org/olap4j/query/MemberSelectionImpl.java b/src/org/olap4j/query/MemberSelectionImpl.java index e98927f..87a24ae 100644 --- a/src/org/olap4j/query/MemberSelectionImpl.java +++ b/src/org/olap4j/query/MemberSelectionImpl.java @@ -3,17 +3,16 @@ // 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-2010 Julian Hyde +// Copyright (C) 2007-2011 Julian Hyde // All Rights Reserved. // You must accept the terms of that agreement to use this software. */ package org.olap4j.query; -import java.util.ArrayList; -import java.util.List; - +import org.olap4j.mdx.ParseTreeNode; import org.olap4j.metadata.Dimension; import org.olap4j.metadata.Member; +import org.olap4j.metadata.MetadataElement; /** * Abstract implementation of {@link Selection}. @@ -22,16 +21,9 @@ * @version $Id$ * @since May 30, 2007 */ -class MemberSelectionImpl extends QueryNodeImpl implements Selection { +class MemberSelectionImpl extends AbstractSelection { - protected Member member; - protected String dimensionName; - protected String hierarchyName; - protected String levelName; - protected String memberName; - protected Dimension dimension; - protected Operator operator = Operator.MEMBER; - protected List selectionContext; + private Member member; /** * Creates a SelectionImpl. @@ -41,18 +33,10 @@ class MemberSelectionImpl extends QueryNodeImpl implements Selection { public MemberSelectionImpl( Member member, Dimension dimension, - String hierarchyName, - String levelName, - String memberName, Operator operator) { - super(); + super(dimension, operator); this.member = member; - this.dimension = dimension; - this.hierarchyName = hierarchyName; - this.levelName = levelName; - this.memberName = memberName; - this.operator = operator; } public int hashCode() { @@ -104,76 +88,21 @@ public boolean equals(Object obj) { return true; } - public String getName() { - return memberName; - } - - public void setName(String name) { - memberName = name; - } - - public Dimension getDimension() { - return dimension; - } - - public void setDimension(Dimension dimension) { - this.dimension = dimension; - } - - public Member getMember() { + public MetadataElement getRootElement() { return member; } - public String getDimensionName() { - return dimensionName; - } - - public void setDimensionName(String dimensionName) { - this.dimensionName = dimensionName; - } - - public String getHierarchyName() { - return hierarchyName; - } - - public void setHierarchyName(String hierarchyName) { - this.hierarchyName = hierarchyName; - } - - public String getLevelName() { - return levelName; - } - - public void setLevelName(String levelName) { - this.levelName = levelName; - } - - public Operator getOperator() { - return operator; + public ParseTreeNode visit() { + return Olap4jNodeConverter.toOlap4j(member, operator); } + @Override public void setOperator(Operator operator) { - assert operator != null; - this.operator = operator; - notifyChange(this,-1); - } - - void tearDown() { - } - - public List getSelectionContext() { - return selectionContext; - } - - public void addContext(Selection selection) { - if (selectionContext == null) { - selectionContext = new ArrayList(); + if (operator.equals(Operator.MEMBERS)) { + throw new IllegalArgumentException( + "Selections based on a Members cannot be of Operator MEMBERS."); } - selectionContext.add(selection); - } - - public void removeContext(Selection selection) { - selectionContext.remove(selection); + super.setOperator(operator); } } diff --git a/src/org/olap4j/query/Olap4jNodeConverter.java b/src/org/olap4j/query/Olap4jNodeConverter.java index 6b127cd..b2d2a33 100644 --- a/src/org/olap4j/query/Olap4jNodeConverter.java +++ b/src/org/olap4j/query/Olap4jNodeConverter.java @@ -3,7 +3,7 @@ // 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-2010 Julian Hyde +// Copyright (C) 2007-2011 Julian Hyde // All Rights Reserved. // You must accept the terms of that agreement to use this software. */ @@ -407,21 +407,14 @@ private static List toOlap4j(QueryDimension dimension) { private static ParseTreeNode toOlap4j(Selection selection) { try { - if (selection instanceof MemberSelectionImpl) { - return toOlap4j(selection.getMember(), selection.getOperator()); - } - if (selection instanceof LevelSelectionImpl) { - return toOlap4j( - ((LevelSelectionImpl) selection).getLevel(), - selection.getOperator()); - } + return selection.visit(); } catch (Exception e) { e.printStackTrace(); } return null; } - private static ParseTreeNode toOlap4j( + static ParseTreeNode toOlap4j( Member member, Selection.Operator oper) { @@ -478,7 +471,7 @@ private static ParseTreeNode toOlap4j( return node; } - private static ParseTreeNode toOlap4j( + static ParseTreeNode toOlap4j( Level level, Selection.Operator oper) { diff --git a/src/org/olap4j/query/Query.java b/src/org/olap4j/query/Query.java index 60be5fb..1588b9a 100644 --- a/src/org/olap4j/query/Query.java +++ b/src/org/olap4j/query/Query.java @@ -3,7 +3,7 @@ // 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-2010 Julian Hyde +// Copyright (C) 2007-2011 Julian Hyde // All Rights Reserved. // You must accept the terms of that agreement to use this software. */ diff --git a/src/org/olap4j/query/QueryDimension.java b/src/org/olap4j/query/QueryDimension.java index 0349fe2..2951e40 100644 --- a/src/org/olap4j/query/QueryDimension.java +++ b/src/org/olap4j/query/QueryDimension.java @@ -400,7 +400,8 @@ public List resolve(Selection selection) throws OlapException return query.getCube().lookupMembers( set, - IdentifierParser.parseIdentifier(selection.getName())); + IdentifierParser.parseIdentifier( + selection.getUniqueName())); } catch (Exception e) { throw new OlapException( "Error while resolving selection " + selection.toString(), diff --git a/src/org/olap4j/query/Selection.java b/src/org/olap4j/query/Selection.java index 00f127c..1b864d1 100644 --- a/src/org/olap4j/query/Selection.java +++ b/src/org/olap4j/query/Selection.java @@ -3,7 +3,7 @@ // 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-2010 Julian Hyde +// Copyright (C) 2007-2011 Julian Hyde // All Rights Reserved. // You must accept the terms of that agreement to use this software. */ @@ -11,8 +11,9 @@ import java.util.List; +import org.olap4j.mdx.ParseTreeNode; import org.olap4j.metadata.Dimension; -import org.olap4j.metadata.Member; +import org.olap4j.metadata.MetadataElement; /** * A selection of members from an OLAP dimension hierarchy. The selection @@ -35,15 +36,32 @@ */ public interface Selection extends QueryNode { - String getName(); - - void setName(String name); + /** + * Unique name of the selection root. + * @return The unique OLAP name of the selection root. + */ + String getUniqueName(); - Member getMember(); + /** + * Visitor pattern-like function to convert + * the selection into a ParseTreeNode. Typical + * implementation should be:
+ * Olap4jNodeConverter.toOlap4j(member, operator); + * @return A parse tree node of the selection. + */ + ParseTreeNode visit(); + /** + * Parent Dimension of the root selection element. + * @return A dimension object. + */ Dimension getDimension(); - String getHierarchyName(); + /** + * Returns the root selection element of this selection. + * @return + */ + MetadataElement getRootElement(); /** * The selection context includes selections from other dimensions that @@ -58,11 +76,14 @@ public interface Selection extends QueryNode { void removeContext(Selection selection); - String getLevelName(); - Operator getOperator(); - // @pre operator != null + /** + * Set the selection operator to use. + * @throws IllegalArgumentException if the operator cannot + * be used on the root selection member. + * @param operator Operator to apply on the selection. + */ void setOperator(Operator operator); /** diff --git a/src/org/olap4j/query/SelectionFactory.java b/src/org/olap4j/query/SelectionFactory.java index 8376bcc..d20bce5 100644 --- a/src/org/olap4j/query/SelectionFactory.java +++ b/src/org/olap4j/query/SelectionFactory.java @@ -31,9 +31,6 @@ Selection createMemberSelection( new MemberSelectionImpl( member, member.getDimension(), - member.getHierarchy().getUniqueName(), - member.getLevel().getUniqueName(), - member.getUniqueName(), operator); } @@ -44,8 +41,6 @@ Selection createLevelSelection( new LevelSelectionImpl( level, level.getDimension(), - level.getHierarchy().getUniqueName(), - level.getUniqueName(), Selection.Operator.MEMBERS); } }