001/*
002// $Id: WithMemberNode.java 482 2012-01-05 23:27:27Z jhyde $
003//
004// Licensed to Julian Hyde under one or more contributor license
005// agreements. See the NOTICE file distributed with this work for
006// additional information regarding copyright ownership.
007//
008// Julian Hyde licenses this file to you under the Apache License,
009// Version 2.0 (the "License"); you may not use this file except in
010// compliance with the License. You may obtain a copy of the License at:
011//
012// http://www.apache.org/licenses/LICENSE-2.0
013//
014// Unless required by applicable law or agreed to in writing, software
015// distributed under the License is distributed on an "AS IS" BASIS,
016// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017// See the License for the specific language governing permissions and
018// limitations under the License.
019*/
020package org.olap4j.mdx;
021
022import org.olap4j.type.Type;
023
024import java.io.PrintWriter;
025import java.util.List;
026
027/**
028 * Parse tree node which declares a calculated member. Represented as the
029 * <code>WITH MEMBER</code> clause of an MDX <code>SELECT</code> statement.
030 *
031 * @version $Id: WithMemberNode.java 482 2012-01-05 23:27:27Z jhyde $
032 * @author jhyde
033 */
034public class WithMemberNode implements ParseTreeNode {
035
036    private final ParseRegion region;
037
038    /** name of set or member */
039    private final IdentifierNode name;
040
041    /** defining expression */
042    private ParseTreeNode expression;
043
044    // properties of member, such as SOLVE_ORDER
045    private final List<PropertyValueNode> memberPropertyList;
046
047    /**
048     * Constructs a formula specifying a member.
049     *
050     * @param region Source code region
051     * @param name   Name of member being declared
052     * @param exp    Expression for value of member
053     * @param memberPropertyList Collection of properties of member
054     */
055    public WithMemberNode(
056        ParseRegion region,
057        IdentifierNode name,
058        ParseTreeNode exp,
059        List<PropertyValueNode> memberPropertyList)
060    {
061        this.region = region;
062        this.name = name;
063        this.expression = exp;
064        this.memberPropertyList = memberPropertyList;
065    }
066
067    public ParseRegion getRegion() {
068        return region;
069    }
070
071    public void unparse(ParseTreeWriter writer) {
072        PrintWriter pw = writer.getPrintWriter();
073        pw.print("MEMBER ");
074        name.unparse(writer);
075        writer.indent();
076        pw.println(" AS");
077        // The MDX language, and olap4j's parser, allows formulas in calculated
078        // members and sets to be specified with and without single quotes.
079        expression.unparse(writer);
080        if (memberPropertyList != null) {
081            for (PropertyValueNode memberProperty : memberPropertyList) {
082                pw.print(", ");
083                memberProperty.unparse(writer);
084            }
085        }
086        writer.outdent();
087    }
088
089    /**
090     * Returns the name of the member declared.
091     *
092     * <p>The name is as specified in the parse tree; it may not be identical
093     * to the unique name of the member.
094     *
095     * @return Name of member
096     */
097    public IdentifierNode getIdentifier() {
098        return name;
099    }
100
101    /**
102     * Returns the expression to evaluate to calculate the member.
103     *
104     * @return expression
105     */
106    public ParseTreeNode getExpression() {
107        return expression;
108    }
109
110    /**
111     * Sets the expression to evaluate to calculate the member.
112     *
113     * @param expression Expression
114     */
115    public void setExpression(ParseTreeNode expression) {
116        this.expression = expression;
117    }
118
119
120    public <T> T accept(ParseTreeVisitor<T> visitor) {
121        T t = visitor.visit(this);
122        name.accept(visitor);
123        expression.accept(visitor);
124        return t;
125    }
126
127    public Type getType() {
128        // not an expression
129        throw new UnsupportedOperationException();
130    }
131
132    /**
133     * Returns the list of properties of this member.
134     *
135     * <p>The list may be empty, but is never null.
136     * Each entry is a (name, expression) pair.
137     *
138     * @return list of properties
139     */
140    public List<PropertyValueNode> getMemberPropertyList() {
141        return memberPropertyList;
142    }
143
144    public WithMemberNode deepCopy() {
145        return new WithMemberNode(
146            this.region, // immutable
147            this.name.deepCopy(),
148            this.expression.deepCopy(),
149            MdxUtil.deepCopyList(memberPropertyList));
150    }
151}
152
153// End WithMemberNode.java