1 /* 2 // $Id: //open/mondrian/src/main/mondrian/calc/Calc.java#5 $ 3 // This software is subject to the terms of the Common Public License 4 // Agreement, available at the following URL: 5 // http://www.opensource.org/licenses/cpl.html. 6 // Copyright (C) 2006-2006 Julian Hyde 7 // All Rights Reserved. 8 // You must accept the terms of that agreement to use this software. 9 */ 10 package mondrian.calc; 11 12 import mondrian.olap.Evaluator; 13 import mondrian.olap.Dimension; 14 import mondrian.olap.type.Type; 15 16 /** 17 * <code>Calc</code> is the base class for all calculable expressions. 18 * 19 * <h3>Logical and physical expression languages</h3> 20 * 21 * Mondrian has two expression languages:<ul> 22 * <li>The logical language of parsed MDX fragments ({@link mondrian.olap.Exp}). 23 * <li>The phyiscal language of compiled expressions ({@link Calc}). 24 * </ul></p> 25 * 26 * The two languages allow us to separate logical (how an 27 * MDX expression was specified) from physical (how it is to be evaluated). 28 * The physical language is more strongly typed, and certain constructs which 29 * are implicit in the logical language (such as the addition of calls 30 * to the <code><Member>.CurrentMember</code> function) are made 31 * explicit in the physical language.<p/> 32 * 33 * <h3>Compilation</h3> 34 * 35 * Expressions are generally created from using an expression compiler 36 * ({@link ExpCompiler}). There are often more than one evaluation strategy 37 * for a given expression, and compilation process gives us an opportunity to 38 * choose the optimal one.<p/> 39 * 40 * <h3>Implementing expressions</h3> 41 * 42 * The <code>Calc</code> interface has sub-interfaces for various types: 43 * {@link IntegerCalc}, 44 * {@link BooleanCalc}, 45 * {@link DoubleCalc}, 46 * {@link StringCalc} are scalar expressions; 47 * {@link MemberCalc}, 48 * {@link LevelCalc}, 49 * {@link HierarchyCalc}, 50 * {@link DimensionCalc} yield elements of the OLAP model.<p/> 51 * 52 * Each of these sub-interfaces has an abstract implementation: 53 * {@link mondrian.calc.impl.AbstractIntegerCalc}, 54 * {@link mondrian.calc.impl.AbstractBooleanCalc}, 55 * {@link mondrian.calc.impl.AbstractDoubleCalc}, 56 * {@link mondrian.calc.impl.AbstractStringCalc}, 57 * {@link mondrian.calc.impl.AbstractMemberCalc}, 58 * {@link mondrian.calc.impl.AbstractLevelCalc}, 59 * {@link mondrian.calc.impl.AbstractHierarchyCalc}, 60 * {@link mondrian.calc.impl.AbstractDimensionCalc}.<p/> 61 * 62 * {@link mondrian.calc.impl.GenericCalc} is an adapter which implements all of these interfaces 63 * and will try to convert any given result to the correct type. Use it 64 * sparingly: if you know the expected result type, it is better to write a 65 * class which implements a specific <code><em>Type</em>Calc</code> interface. 66 * 67 * @author jhyde 68 * @since Sep 26, 2005 69 * @version $Id: //open/mondrian/src/main/mondrian/calc/Calc.java#5 $ 70 */ 71 public interface Calc { 72 /** 73 * Evaluates this expression. 74 * 75 * @param evaluator Provides dimensional context in which to evaluate 76 * this expression 77 * @return Result of expression evaluation 78 */ 79 Object evaluate(Evaluator evaluator); 80 81 /** 82 * Returns whether this expression depends upon a given dimension. 83 * 84 * <p>If it does not depend on the dimension, then re-evaluating the 85 * expression with a different member of this context must produce the 86 * same answer.<p/> 87 * 88 * Some examples:<ul> 89 * 90 * <li>The expression 91 * <blockquote><code>[Measures].[Unit Sales]</code></blockquote> 92 * depends on all dimensions except <code>[Measures]</code>. 93 * 94 * <li>The boolean expression 95 * <blockquote><code>([Measures].[Unit Sales], 96 * [Time].[1997]) > 1000</code></blockquote> 97 * depends on all dimensions except [Measures] and [Time]. 98 * 99 * <li>The list expression 100 * <blockquote><code>Filter([Store].[USA].Children, 101 * [Measures].[Unit Sales] < 50)</code></pre></blockquote> 102 * depends upon all dimensions <em>except</em> [Store] and [Measures]. 103 * How so? Normally the scalar expression would depend upon all dimensions 104 * except [Measures], but the <code>Filter</code> function sets the [Store] 105 * context before evaluating the scalar expression, so it is not inherited 106 * from the surrounding context. 107 * 108 * </ul><p/> 109 * 110 * @param dimension Dimension 111 * @return Whether this expression's result depends upon the current member 112 * of the dimension 113 */ 114 boolean dependsOn(Dimension dimension); 115 116 /** 117 * Returns the type of this expression. 118 */ 119 Type getType(); 120 121 /** 122 * Prints this expression, by accepting a visiting {@link CalcWriter}. 123 * 124 * @param calcWriter Writer 125 */ 126 void accept(CalcWriter calcWriter); 127 128 /** 129 * Returns style in which the result of evaluating this expression is 130 * returned. 131 * 132 * <p>One application of this method is for the compiler to figure out 133 * whether the compiled expression is returning a mutable list. If a mutable 134 * list is required, the compiler can create a mutable copy. 135 * 136 * @see ExpCompiler#compileList(mondrian.olap.Exp, boolean) 137 */ 138 ExpCompiler.ResultStyle getResultStyle(); 139 } 140 141 // End Calc.java 142