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><Member>.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]) > 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] < 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