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) 2005-2005 Julian Hyde 008// Copyright (C) 2005-2009 Pentaho 009// All Rights Reserved. 010*/ 011package mondrian.spi; 012 013import mondrian.olap.Evaluator; 014import mondrian.olap.Syntax; 015import mondrian.olap.type.Type; 016 017import java.util.List; 018 019/** 020 * Definition of a user-defined function. 021 * 022 * <p>The class must have a public, zero-arguments constructor, be on 023 * Mondrian's runtime class-path, and be referenced from the schema file: 024 * 025 * <blockquote><code> 026 * <Schema><br/> 027 * ....<br/> 028 * <UserDefinedFunction name="MyFun" 029 * class="com.acme.MyFun"><br/> 030 * </Schema></code></blockquote> 031 * 032 * @author jhyde 033 */ 034public interface UserDefinedFunction { 035 /** 036 * Returns the name with which the user-defined function will be used 037 * from within MDX expressions. 038 */ 039 public String getName(); 040 041 /** 042 * Returns a description of the user-defined function. 043 */ 044 public String getDescription(); 045 046 /** 047 * Returns the syntactic type of the user-defined function. 048 * Usually {@link Syntax#Function}. 049 */ 050 public Syntax getSyntax(); 051 052 /** 053 * Returns an array of the types of the parameters of this function. 054 */ 055 public Type[] getParameterTypes(); 056 057 /** 058 * Returns the return-type of this function. 059 * 060 * @param parameterTypes Parameter types 061 * @return Return type 062 */ 063 public Type getReturnType(Type[] parameterTypes); 064 065 /** 066 * Applies this function to a set of arguments, and returns a result. 067 * 068 * @param evaluator Evaluator containts the runtime context, in particular 069 * the current member of each dimension. 070 * @param arguments Expressions which yield the arguments of this function. 071 * Most user-defined functions will evaluate all arguments before using 072 * them. Functions such as <code>IIf</code> do not evaluate all 073 * arguments; this technique is called <dfn>lazy evaluation</dfn>. 074 * @return The result value. 075 */ 076 public Object execute(Evaluator evaluator, Argument[] arguments); 077 078 /** 079 * Returns a list of reserved words used by this function. 080 * May return an empty array or null if this function does not require 081 * any reserved words. 082 */ 083 public String[] getReservedWords(); 084 085 interface Argument { 086 /** 087 * Returns the type of the argument. 088 * 089 * @return Argument type 090 */ 091 Type getType(); 092 093 /** 094 * Evaluates the argument as a scalar expression. 095 * 096 * <p>The effect is the same as 097 * {@link #evaluate(mondrian.olap.Evaluator)} except if the argument 098 * evaluates to a member or tuple. This method will set the context 099 * to the member or tuple and evaluate the current measure, whereas 100 * {@code evaluate} would return the member or tuple. 101 * 102 * <p>The effect is similar to creating a calculated member in an MDX 103 * query:</p> 104 * 105 * <blockquote>WITH MEMBER [Measures].[Previous Period] AS<br/> 106 * ([Measures].[Unit Sales], [Time].[Time].PrevMember)<br/> 107 * SELECT {[Measures].[Unit Sales],<br/> 108 * [Measures].[Previous Period]} on 0,<br/> 109 * [Time].[Time].Children on 1<br/> 110 * FROM [Sales]</blockquote> 111 * 112 * <p>Note how {@code [Measures].[Previous Period]} is defined as a 113 * tuple, but evaluates to a number.</p> 114 * 115 * @param evaluator Evaluation context 116 * @return Scalar expression at the given member or tuple 117 */ 118 Object evaluateScalar(Evaluator evaluator); 119 120 /** 121 * Evaluates the argument. 122 * 123 * <p>If the argument is a set of members or tuples, this method may 124 * return either a {@link List} or an {@link Iterable}. It is not safe 125 * to blindly cast to {@code List}. For guaranteed type, call 126 * {@link #evaluateList(mondrian.olap.Evaluator)} or 127 * {@link #evaluateIterable(mondrian.olap.Evaluator)}. 128 * 129 * @param evaluator Evaluation context 130 * @return Result of evaluating the argument 131 */ 132 Object evaluate(Evaluator evaluator); 133 134 /** 135 * Evaluates the argument to a list of members or tuples. 136 * 137 * @param eval Evaluation context 138 * @return List of members or tuples. 139 */ 140 List evaluateList(Evaluator eval); 141 142 /** 143 * Evaluates the argument to an iterable over members or tuples. 144 * 145 * @param eval Evaluation context 146 * @return Iterable over members or tuples. 147 */ 148 Iterable evaluateIterable(Evaluator eval); 149 } 150} 151 152// End UserDefinedFunction.java