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    */
020    package org.olap4j.mdx;
021    
022    import org.olap4j.type.Type;
023    
024    import java.io.PrintWriter;
025    import 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     */
034    public 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