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-2011 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.calc;
011
012import mondrian.olap.Evaluator;
013import mondrian.olap.Hierarchy;
014import mondrian.olap.type.Type;
015
016/**
017 * <code>Calc</code> is the base class for all calculable expressions.
018 *
019 * <h3>Logical and physical expression languages</h3>
020 *
021 * Mondrian has two expression languages:<ul>
022 * <li>The logical language of parsed MDX fragments ({@link mondrian.olap.Exp}).
023 * <li>The phyiscal language of compiled expressions ({@link Calc}).
024 * </ul></p>
025 *
026 * The two languages allow us to separate logical (how an
027 * MDX expression was specified) from physical (how it is to be evaluated).
028 * The physical language is more strongly typed, and certain constructs which
029 * are implicit in the logical language (such as the addition of calls
030 * to the <code>&lt;Member&gt;.CurrentMember</code> function) are made
031 * explicit in the physical language.<p/>
032 *
033 * <h3>Compilation</h3>
034 *
035 * Expressions are generally created from using an expression compiler
036 * ({@link ExpCompiler}). There are often more than one evaluation strategy
037 * for a given expression, and compilation process gives us an opportunity to
038 * choose the optimal one.<p/>
039 *
040 * <h3>Implementing expressions</h3>
041 *
042 * The <code>Calc</code> interface has sub-interfaces for various types:
043 * {@link IntegerCalc},
044 * {@link BooleanCalc},
045 * {@link DoubleCalc},
046 * {@link StringCalc} are scalar expressions;
047 * {@link MemberCalc},
048 * {@link LevelCalc},
049 * {@link HierarchyCalc},
050 * {@link DimensionCalc} yield elements of the OLAP model.<p/>
051 *
052 * Each of these sub-interfaces has an abstract implementation:
053 * {@link mondrian.calc.impl.AbstractIntegerCalc},
054 * {@link mondrian.calc.impl.AbstractBooleanCalc},
055 * {@link mondrian.calc.impl.AbstractDoubleCalc},
056 * {@link mondrian.calc.impl.AbstractStringCalc},
057 * {@link mondrian.calc.impl.AbstractMemberCalc},
058 * {@link mondrian.calc.impl.AbstractLevelCalc},
059 * {@link mondrian.calc.impl.AbstractHierarchyCalc},
060 * {@link mondrian.calc.impl.AbstractDimensionCalc}.<p/>
061 *
062 * {@link mondrian.calc.impl.GenericCalc} is an adapter which implements all of these interfaces
063 * and will try to convert any given result to the correct type. Use it
064 * sparingly: if you know the expected result type, it is better to write a
065 * class which implements a specific <code><em>Type</em>Calc</code> interface.
066 *
067 * @author jhyde
068 * @since Sep 26, 2005
069 */
070public interface Calc {
071    /**
072     * Evaluates this expression.
073     *
074     * @param evaluator Provides dimensional context in which to evaluate
075     *                  this expression
076     * @return Result of expression evaluation
077     */
078    Object evaluate(Evaluator evaluator);
079
080    /**
081     * Returns whether this expression depends upon a given hierarchy.
082     *
083     * <p>If it does not depend on the hierarchy, then re-evaluating the
084     * expression with a different member of this context must produce the
085     * same answer.<p/>
086     *
087     * Some examples:<ul>
088     *
089     * <li>The expression
090     * <blockquote><code>[Measures].[Unit Sales]</code></blockquote>
091     * depends on all dimensions except <code>[Measures]</code>.
092     *
093     * <li>The boolean expression
094     * <blockquote><code>([Measures].[Unit Sales],
095     * [Time].[1997]) &gt; 1000</code></blockquote>
096     * depends on all hierarchies except [Measures] and [Time].
097     *
098     * <li>The list expression
099     * <blockquote><code>Filter([Store].[USA].Children,
100     * [Measures].[Unit Sales] &lt; 50)</code></pre></blockquote>
101     * depends upon all hierarchies <em>except</em> [Store] and [Measures].
102     * How so? Normally the scalar expression would depend upon all hierarchies
103     * except [Measures], but the <code>Filter</code> function sets the [Store]
104     * context before evaluating the scalar expression, so it is not inherited
105     * from the surrounding context.
106     *
107     * </ul><p/>
108     *
109     * @param hierarchy Hierarchy
110     * @return Whether this expression's result depends upon the current member
111     *   of the hierarchy
112     */
113    boolean dependsOn(Hierarchy hierarchy);
114
115    /**
116     * Returns the type of this expression.
117     */
118    Type getType();
119
120    /**
121     * Prints this expression, by accepting a visiting {@link CalcWriter}.
122     *
123     * @param calcWriter Writer
124     */
125    void accept(CalcWriter calcWriter);
126
127    /**
128     * Returns style in which the result of evaluating this expression is
129     * returned.
130     *
131     * <p>One application of this method is for the compiler to figure out
132     * whether the compiled expression is returning a mutable list. If a mutable
133     * list is required, the compiler can create a mutable copy.
134     *
135     * @see ExpCompiler#compileList(mondrian.olap.Exp, boolean)
136     */
137    ResultStyle getResultStyle();
138
139    boolean isWrapperFor(java.lang.Class<?> iface);
140
141    <T> T unwrap(java.lang.Class<T> iface);
142}
143
144// End Calc.java