001    /*
002    // $Id: //open/mondrian-release/3.2/src/main/mondrian/mdx/ResolvedFunCall.java#1 $
003    // This software is subject to the terms of the Eclipse Public License v1.0
004    // Agreement, available at the following URL:
005    // http://www.eclipse.org/legal/epl-v10.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-release/3.2/src/main/mondrian/mdx/ResolvedFunCall.java#1 $
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        @SuppressWarnings({"CloneDoesntCallSuperClone"})
069        public ResolvedFunCall clone() {
070            return new ResolvedFunCall(
071                funDef, ExpBase.cloneArray(args), returnType);
072        }
073    
074        /**
075         * Returns the Exp argument at the specified index.
076         *
077         * @param      index   the index of the Exp.
078         * @return     the Exp at the specified index of this array of Exp.
079         *             The first Exp is at index <code>0</code>.
080         * @see #getArgs()
081         */
082        public Exp getArg(int index) {
083            return args[index];
084        }
085    
086        /**
087         * Returns the internal array of Exp arguments.
088         *
089         * <p>Note: this does NOT do a copy.
090         *
091         * @return the array of expressions
092         */
093        public Exp[] getArgs() {
094            return args;
095        }
096    
097        /**
098         * Returns the number of arguments.
099         *
100         * @return number of arguments.
101         * @see #getArgs()
102         */
103        public final int getArgCount() {
104            return args.length;
105        }
106    
107        public String getFunName() {
108            return funDef.getName();
109        }
110    
111        public Syntax getSyntax() {
112            return funDef.getSyntax();
113        }
114    
115        public Object[] getChildren() {
116            return args;
117        }
118    
119        /**
120         * Returns the definition of the function which is being called.
121         *
122         * @return function definition
123         */
124        public FunDef getFunDef() {
125            return funDef;
126        }
127    
128        public final int getCategory() {
129            return funDef.getReturnCategory();
130        }
131    
132        public final Type getType() {
133            return returnType;
134        }
135    
136        public Exp accept(Validator validator) {
137            // even though the function has already been validated, we need
138            // to walk through the arguments to determine which measures are
139            // referenced
140            Exp[] newArgs = new Exp[args.length];
141            FunUtil.resolveFunArgs(
142                validator, funDef, args, newArgs, getFunName(), getSyntax());
143    
144            return this;
145        }
146    
147        public void unparse(PrintWriter pw) {
148            funDef.unparse(args, pw);
149        }
150    
151        public Calc accept(ExpCompiler compiler) {
152            return funDef.compileCall(this, compiler);
153        }
154    
155        public Object accept(MdxVisitor visitor) {
156            final Object o = visitor.visit(this);
157            if (visitor.shouldVisitChildren()) {
158                // visit the call's arguments
159                for (Exp arg : args) {
160                    arg.accept(visitor);
161                }
162            }
163            return o;
164        }
165    }
166    
167    // End ResolvedFunCall.java