001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2006-2007 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.mdx;
011
012import mondrian.calc.Calc;
013import mondrian.calc.ExpCompiler;
014import mondrian.olap.*;
015import mondrian.olap.fun.FunUtil;
016import mondrian.olap.type.Type;
017
018import 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 * @since Sep 28, 2005
027 */
028public class UnresolvedFunCall extends ExpBase implements FunCall {
029    private final String name;
030    private final Syntax syntax;
031    private final Exp[] args;
032
033    /**
034     * Creates a function call with {@link Syntax#Function} syntax.
035     */
036    public UnresolvedFunCall(String name, Exp[] args) {
037        this(name, Syntax.Function, args);
038    }
039
040    /**
041     * Creates a function call.
042     */
043    public UnresolvedFunCall(String name, Syntax syntax, Exp[] args) {
044        assert name != null;
045        assert syntax != null;
046        assert args != null;
047        this.name = name;
048        this.syntax = syntax;
049        this.args = args;
050        switch (syntax) {
051        case Braces:
052            Util.assertTrue(name.equals("{}"));
053            break;
054        case Parentheses:
055            Util.assertTrue(name.equals("()"));
056            break;
057        case Internal:
058            Util.assertTrue(name.startsWith("$"));
059            break;
060        case Empty:
061            Util.assertTrue(name.equals(""));
062            break;
063        default:
064            Util.assertTrue(
065                !name.startsWith("$")
066                && !name.equals("{}")
067                && !name.equals("()"));
068            break;
069        }
070    }
071
072    @SuppressWarnings({"CloneDoesntCallSuperClone"})
073    public UnresolvedFunCall clone() {
074        return new UnresolvedFunCall(name, syntax, ExpBase.cloneArray(args));
075    }
076
077    public int getCategory() {
078        throw new UnsupportedOperationException();
079    }
080
081    public Type getType() {
082        throw new UnsupportedOperationException();
083    }
084
085    public void unparse(PrintWriter pw) {
086        syntax.unparse(name, args, pw);
087    }
088
089    public Object accept(MdxVisitor visitor) {
090        final Object o = visitor.visit(this);
091        if (visitor.shouldVisitChildren()) {
092            // visit the call's arguments
093            for (Exp arg : args) {
094                arg.accept(visitor);
095            }
096        }
097        return o;
098    }
099
100    public Exp accept(Validator validator) {
101        Exp[] newArgs = new Exp[args.length];
102        FunDef funDef =
103            FunUtil.resolveFunArgs(
104                validator, null, args, newArgs, name, syntax);
105        return funDef.createCall(validator, newArgs);
106    }
107
108    public Calc accept(ExpCompiler compiler) {
109        throw new UnsupportedOperationException();
110    }
111
112    /**
113     * Returns the function name.
114     *
115     * @return function name
116     */
117    public String getFunName() {
118        return name;
119    }
120
121    /**
122     * Returns the syntax of this function call.
123     *
124     * @return the syntax of the call
125     */
126    public Syntax getSyntax() {
127        return syntax;
128    }
129
130    /**
131     * Returns the Exp argument at the specified index.
132     *
133     * @param      index   the index of the Exp.
134     * @return     the Exp at the specified index of this array of Exp.
135     *             The first Exp is at index <code>0</code>.
136     * @see #getArgs()
137     */
138    public Exp getArg(int index) {
139        return args[index];
140    }
141
142    /**
143     * Returns the internal array of Exp arguments.
144     *
145     * <p>Note: this does NOT do a copy.
146     *
147     * @return the array of expressions
148     */
149    public Exp[] getArgs() {
150        return args;
151    }
152
153    /**
154     * Returns the number of arguments.
155     *
156     * @return number of arguments.
157     * @see #getArgs()
158     */
159    public final int getArgCount() {
160        return args.length;
161    }
162
163    public Object[] getChildren() {
164        return args;
165    }
166}
167
168// End UnresolvedFunCall.java