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) 2002-2005 Julian Hyde and others 008// Copyright (C) 2005-2011 Pentaho and others 009// All Rights Reserved. 010*/ 011package mondrian.olap.fun; 012 013import mondrian.olap.*; 014 015import java.util.List; 016 017/** 018 * A <code>MultiResolver</code> considers several overloadings of the same 019 * function. If one of these overloadings matches the actual arguments, it 020 * calls the factory method {@link #createFunDef}. 021 * 022 * @author jhyde 023 * @since Feb 12, 2003 024 */ 025public abstract class MultiResolver extends FunUtil implements Resolver { 026 private final String name; 027 private final String signature; 028 private final String description; 029 private final String[] signatures; 030 private final Syntax syntax; 031 032 /** 033 * Creates a <code>MultiResolver</code>. 034 * 035 * @param name Name of function or operator 036 * @param signature Signature of function or operator 037 * @param description Description of function or operator 038 * @param signatures Array of possible signatures, each of which is an 039 * encoding of the syntactic type, return type, and parameter 040 * types of this operator. The "Members" operator has a syntactic 041 * type "pxd" which means "an operator with 042 * {@link Syntax#Property property} syntax (p) which returns a set 043 * (x) and takes a dimension (d) as its argument". 044 * See {@link FunUtil#decodeSyntacticType(String)}, 045 * {@link FunUtil#decodeReturnCategory(String)}, 046 * {@link FunUtil#decodeParameterCategories(String)}. 047 */ 048 protected MultiResolver( 049 String name, 050 String signature, 051 String description, 052 String[] signatures) 053 { 054 this.name = name; 055 this.signature = signature; 056 this.description = description; 057 this.signatures = signatures; 058 Util.assertTrue(signatures.length > 0); 059 this.syntax = decodeSyntacticType(signatures[0]); 060 for (int i = 1; i < signatures.length; i++) { 061 Util.assertTrue(decodeSyntacticType(signatures[i]) == syntax); 062 } 063 } 064 065 public String getName() { 066 return name; 067 } 068 069 public String getDescription() { 070 return description; 071 } 072 073 public String getSignature() { 074 return signature; 075 } 076 077 public Syntax getSyntax() { 078 return syntax; 079 } 080 081 public String[] getReservedWords() { 082 return emptyStringArray; 083 } 084 085 public String[] getSignatures() { 086 return signatures; 087 } 088 089 public FunDef getFunDef() { 090 return null; 091 } 092 093 public FunDef resolve( 094 Exp[] args, 095 Validator validator, 096 List<Conversion> conversions) 097 { 098outer: 099 for (String signature : signatures) { 100 int[] parameterTypes = decodeParameterCategories(signature); 101 if (parameterTypes.length != args.length) { 102 continue; 103 } 104 conversions.clear(); 105 for (int i = 0; i < args.length; i++) { 106 if (!validator.canConvert( 107 i, args[i], parameterTypes[i], conversions)) 108 { 109 continue outer; 110 } 111 } 112 int returnType = decodeReturnCategory(signature); 113 FunDef dummy = createDummyFunDef(this, returnType, args); 114 return createFunDef(args, dummy); 115 } 116 return null; 117 } 118 119 public boolean requiresExpression(int k) { 120 for (String signature : signatures) { 121 int[] parameterTypes = decodeParameterCategories(signature); 122 if ((k < parameterTypes.length) 123 && parameterTypes[k] == Category.Set) 124 { 125 return false; 126 } 127 } 128 return true; 129 } 130 131 protected abstract FunDef createFunDef(Exp[] args, FunDef dummyFunDef); 132} 133 134// End MultiResolver.java