001    /*
002    // $Id: //open/mondrian/src/main/mondrian/mdx/NamedSetExpr.java#10 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2006-2006 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.mdx;
011    
012    import mondrian.olap.*;
013    import mondrian.olap.type.Type;
014    import mondrian.calc.*;
015    import mondrian.calc.impl.AbstractListCalc;
016    
017    import java.util.List;
018    
019    /**
020     * Usage of a {@link mondrian.olap.NamedSet} in an MDX expression.
021     *
022     * @author jhyde
023     * @version $Id: //open/mondrian/src/main/mondrian/mdx/NamedSetExpr.java#10 $
024     * @since Sep 26, 2005
025     */
026    public class NamedSetExpr extends ExpBase implements Exp {
027        private final NamedSet namedSet;
028    
029        /**
030         * Creates a usage of a named set.
031         *
032         * @param namedSet namedSet
033         * @pre NamedSet != null
034         */
035        public NamedSetExpr(NamedSet namedSet) {
036            Util.assertPrecondition(namedSet != null, "namedSet != null");
037            this.namedSet = namedSet;
038        }
039    
040        /**
041         * Returns the named set.
042         *
043         * @post return != null
044         */
045        public NamedSet getNamedSet() {
046            return namedSet;
047        }
048    
049        public String toString() {
050            return namedSet.getUniqueName();
051        }
052    
053        public NamedSetExpr clone() {
054            return new NamedSetExpr(namedSet);
055        }
056    
057        public int getCategory() {
058            return Category.Set;
059        }
060    
061        public Exp accept(Validator validator) {
062            // A set is sometimes used in more than one cube. So, clone the
063            // expression and re-validate every time it is used.
064            //
065            // But keep the expression wrapped in a NamedSet, so that the
066            // expression is evaluated once per query. (We don't want the
067            // expression to be evaluated context-sensitive.)
068            NamedSet namedSet2 = namedSet.validate(validator);
069            if (namedSet2 == namedSet) {
070                return this;
071            }
072            return new NamedSetExpr(namedSet2);
073        }
074    
075        public Calc accept(ExpCompiler compiler) {
076            return new AbstractListCalc(this, new Calc[] { /* todo: compile namedSet.getExp() */ }, false) {
077                public List evaluateList(Evaluator evaluator) {
078                    return (List) evaluator.evaluateNamedSet(
079                        namedSet.getName(), namedSet.getExp());
080                }
081    
082                public boolean dependsOn(Dimension dimension) {
083                    // Given that a named set is never re-evaluated within the scope
084                    // of a query, effectively it's independent of all dimensions.
085                    return false;
086                }
087            };
088        }
089    
090        public Object accept(MdxVisitor visitor) {
091            Object o = visitor.visit(this);
092            namedSet.getExp().accept(visitor);
093            return o;
094        }
095    
096        public Type getType() {
097            return namedSet.getType();
098        }
099    }
100    
101    // End NamedSetExpr.java