001    /*
002    // $Id: //open/mondrian/src/main/mondrian/mdx/UnresolvedFunCall.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-2007 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.fun.*;
014    import mondrian.olap.type.Type;
015    import mondrian.calc.Calc;
016    import mondrian.calc.ExpCompiler;
017    
018    import java.io.PrintWriter;
019    
020    /**
021     * An expression consisting of a named function or operator
022     * applied to a set of arguments. The syntax determines whether this is
023     * called infix, with function call syntax, and so forth.
024     *
025     * @author jhyde
026     * @version $Id: //open/mondrian/src/main/mondrian/mdx/UnresolvedFunCall.java#10 $
027     * @since Sep 28, 2005
028     */
029    public class UnresolvedFunCall extends ExpBase implements FunCall {
030        private final String name;
031        private final Syntax syntax;
032        private final Exp[] args;
033    
034        /**
035         * Creates a function call with {@link Syntax#Function} syntax.
036         */
037        public UnresolvedFunCall(String name, Exp[] args) {
038            this(name, Syntax.Function, args);
039        }
040    
041        /**
042         * Creates a function call.
043         */
044        public UnresolvedFunCall(String name, Syntax syntax, Exp[] args) {
045            assert name != null;
046            assert syntax != null;
047            assert args != null;
048            this.name = name;
049            this.syntax = syntax;
050            this.args = args;
051            switch (syntax) {
052            case Braces:
053                Util.assertTrue(name.equals("{}"));
054                break;
055            case Parentheses:
056                Util.assertTrue(name.equals("()"));
057                break;
058            case Internal:
059                Util.assertTrue(name.startsWith("$"));
060                break;
061            case Empty:
062                Util.assertTrue(name.equals(""));
063                break;
064            default:
065                Util.assertTrue(!name.startsWith("$") &&
066                    !name.equals("{}") &&
067                    !name.equals("()"));
068                break;
069            }
070        }
071    
072        public UnresolvedFunCall clone() {
073            return new UnresolvedFunCall(name, syntax, ExpBase.cloneArray(args));
074        }
075    
076        public int getCategory() {
077            throw new UnsupportedOperationException();
078        }
079    
080        public Type getType() {
081            throw new UnsupportedOperationException();
082        }
083    
084        public void unparse(PrintWriter pw) {
085            syntax.unparse(name, args, pw);
086        }
087    
088        public Object accept(MdxVisitor visitor) {
089            final Object o = visitor.visit(this);
090            // visit the call's arguments
091            for (Exp arg : args) {
092                arg.accept(visitor);
093            }
094            return o;
095        }
096    
097        public Exp accept(Validator validator) {
098            Exp[] newArgs = new Exp[args.length];
099            FunDef funDef =
100                FunUtil.resolveFunArgs(validator, args, newArgs, name, syntax);
101            return funDef.createCall(validator, newArgs);
102        }
103    
104        public Calc accept(ExpCompiler compiler) {
105            throw new UnsupportedOperationException();
106        }
107    
108        /**
109         * Returns the function name.
110         *
111         * @return function name
112         */
113        public String getFunName() {
114            return name;
115        }
116    
117        /**
118         * Returns the syntax of this function call.
119         *
120         * @return the syntax of the call
121         */
122        public Syntax getSyntax() {
123            return syntax;
124        }
125    
126        /**
127         * Returns the Exp argument at the specified index.
128         *
129         * @param      index   the index of the Exp.
130         * @return     the Exp at the specified index of this array of Exp.
131         *             The first Exp is at index <code>0</code>.
132         * @see #getArgs()
133         */
134        public Exp getArg(int index) {
135            return args[index];
136        }
137    
138        /**
139         * Returns the internal array of Exp arguments.
140         *
141         * <p>Note: this does NOT do a copy.
142         *
143         * @return the array of expressions
144         */
145        public Exp[] getArgs() {
146            return args;
147        }
148    
149        /**
150         * Returns the number of arguments.
151         *
152         * @return number of arguments.
153         * @see #getArgs()
154         */
155        public final int getArgCount() {
156            return args.length;
157        }
158    
159        public Object[] getChildren() {
160            return args;
161        }
162    }
163    
164    // End UnresolvedFunCall.java