001    /*
002    // $Id: //open/mondrian/src/main/mondrian/mdx/ResolvedFunCall.java#8 $
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) 1998-2002 Kana Software, Inc.
007    // Copyright (C) 2001-2007 Julian Hyde and others
008    // All Rights Reserved.
009    // You must accept the terms of that agreement to use this software.
010    */
011    
012    package mondrian.mdx;
013    import mondrian.calc.Calc;
014    import mondrian.calc.ExpCompiler;
015    import mondrian.olap.fun.*;
016    import mondrian.olap.type.Type;
017    import mondrian.olap.*;
018    
019    import java.io.PrintWriter;
020    
021    /**
022     * A <code>ResolvedFunCall</code> is a function applied to a list of operands,
023     * which has been validated and resolved to a
024     * {@link FunDef function definition}.
025     *
026     * @author jhyde
027     * @version $Id: //open/mondrian/src/main/mondrian/mdx/ResolvedFunCall.java#8 $
028     * @since Jan 6, 2006
029     */
030    public final class ResolvedFunCall extends ExpBase implements FunCall {
031    
032        /**
033         * The arguments to the function call.  Note that for methods, 0-th arg is
034         * 'this'.
035         */
036        private final Exp[] args;
037    
038        /**
039         * Return type of this function call.
040         */
041        private final Type returnType;
042    
043        /**
044         * Function definition.
045         */
046        private final FunDef funDef;
047    
048        /**
049         * Creates a function call.
050         *
051         * @param funDef Function definition
052         * @param args Arguments
053         * @param returnType Return type
054         */
055        public ResolvedFunCall(FunDef funDef, Exp[] args, Type returnType) {
056            assert funDef != null;
057            assert args != null;
058            assert returnType != null;
059            this.funDef = funDef;
060            this.args = args;
061            this.returnType = returnType;
062        }
063    
064        public String toString() {
065            return Util.unparse(this);
066        }
067    
068        public ResolvedFunCall clone() {
069            return new ResolvedFunCall(funDef, ExpBase.cloneArray(args), returnType);
070        }
071    
072        /**
073         * Returns the Exp argument at the specified index.
074         *
075         * @param      index   the index of the Exp.
076         * @return     the Exp at the specified index of this array of Exp.
077         *             The first Exp is at index <code>0</code>.
078         * @see #getArgs()
079         */
080        public Exp getArg(int index) {
081            return args[index];
082        }
083    
084        /**
085         * Returns the internal array of Exp arguments.
086         *
087         * <p>Note: this does NOT do a copy.
088         *
089         * @return the array of expressions
090         */
091        public Exp[] getArgs() {
092            return args;
093        }
094    
095        /**
096         * Returns the number of arguments.
097         *
098         * @return number of arguments.
099         * @see #getArgs()
100         */
101        public final int getArgCount() {
102            return args.length;
103        }
104    
105        public String getFunName() {
106            return funDef.getName();
107        }
108    
109        public Syntax getSyntax() {
110            return funDef.getSyntax();
111        }
112    
113        public Object[] getChildren() {
114            return args;
115        }
116    
117        /**
118         * Returns the definition of the function which is being called.
119         *
120         * @return function definition
121         */
122        public FunDef getFunDef() {
123            return funDef;
124        }
125    
126        public final int getCategory() {
127            return funDef.getReturnCategory();
128        }
129    
130        public final Type getType() {
131            return returnType;
132        }
133    
134        public Exp accept(Validator validator) {
135            // even though the function has already been validated, we need
136            // to walk through the arguments to determine which measures are
137            // referenced
138            Exp[] newArgs = new Exp[args.length];
139            FunUtil.resolveFunArgs(
140                validator, args, newArgs, getFunName(), getSyntax());
141    
142            return this;
143        }
144    
145        public void unparse(PrintWriter pw) {
146            funDef.unparse(args, pw);
147        }
148    
149        public Calc accept(ExpCompiler compiler) {
150            return funDef.compileCall(this, compiler);
151        }
152    
153        public Object accept(MdxVisitor visitor) {
154            final Object o = visitor.visit(this);
155            // visit the call's arguments
156            for (Exp arg : args) {
157                arg.accept(visitor);
158            }
159            return o;
160        }
161    }
162    
163    // End ResolvedFunCall.java