1 10 package mondrian.olap.fun; 11 12 import mondrian.mdx.UnresolvedFunCall; 13 import mondrian.olap.*; 14 import mondrian.resource.MondrianResource; 15 16 import java.util.*; 17 18 25 public abstract class FunTableImpl implements FunTable { 26 31 protected final Map<String , List<Resolver>> mapNameToResolvers = 32 new HashMap<String , List<Resolver>>(); 33 private final Set<String > reservedWords = new HashSet<String >(); 34 private final Set<String > propertyWords = new HashSet<String >(); 35 36 protected final List<Resolver> resolverList = new ArrayList<Resolver>(); 37 protected final List<FunInfo> funInfoList = new ArrayList<FunInfo>(); 38 39 protected FunTableImpl() { 40 } 41 42 45 public void init() { 46 defineFunctions(); 47 organizeFunctions(); 48 } 49 50 protected static String makeResolverKey(String name, Syntax syntax) { 51 return name.toUpperCase() + "$" + syntax; 52 } 53 54 protected void define(FunDef funDef) { 55 define(new SimpleResolver(funDef)); 56 } 57 58 protected void define(Resolver resolver) { 59 addFunInfo(resolver); 60 if (resolver.getSyntax() == Syntax.Property) { 61 defineProperty(resolver.getName()); 62 } 63 resolverList.add(resolver); 64 final String [] reservedWords = resolver.getReservedWords(); 65 for (String reservedWord : reservedWords) { 66 defineReserved(reservedWord); 67 } 68 } 69 70 protected void addFunInfo(Resolver resolver) { 71 this.funInfoList.add(FunInfo.make(resolver)); 72 } 73 74 public FunDef getDef( 75 Exp[] args, Validator validator, String funName, Syntax syntax) { 76 String key = makeResolverKey(funName, syntax); 77 78 String signature = syntax.getSignature(funName, 83 Category.Unknown, ExpBase.getTypes(args)); 84 List<Resolver> resolvers = mapNameToResolvers.get(key); 85 if (resolvers == null) { 86 resolvers = Collections.emptyList(); 87 } 88 89 int[] conversionCount = new int[] {0}; 90 int minConversions = Integer.MAX_VALUE; 91 int matchCount = 0; 92 FunDef matchDef = null; 93 for (Resolver resolver : resolvers) { 94 conversionCount[0] = 0; 95 FunDef def = resolver.resolve(args, validator, conversionCount); 96 if (def != null) { 97 int conversions = conversionCount[0]; 98 if (conversions < minConversions) { 99 minConversions = conversions; 100 matchCount = 1; 101 matchDef = def; 102 } else if (conversions == minConversions) { 103 matchCount++; 104 } else { 105 } 108 } 109 } 110 switch (matchCount) { 111 case 0: 112 throw MondrianResource.instance().NoFunctionMatchesSignature.ex( 113 signature); 114 case 1: 115 final String matchKey = makeResolverKey(matchDef.getName(), 116 matchDef.getSyntax()); 117 Util.assertTrue(matchKey.equals(key), matchKey); 118 return matchDef; 119 default: 120 throw MondrianResource.instance().MoreThanOneFunctionMatchesSignature.ex(signature); 121 } 122 } 123 124 public boolean requiresExpression( 125 UnresolvedFunCall call, 126 int k, 127 Validator validator) { 128 String key = makeResolverKey(call.getFunName(), call.getSyntax()); 136 List<Resolver> resolvers = mapNameToResolvers.get(key); 137 if (resolvers == null) { 138 resolvers = Collections.emptyList(); 139 } 140 for (Resolver resolver2 : resolvers) { 141 if (!resolver2.requiresExpression(k)) { 142 return false; 145 } 146 } 147 return true; 148 } 149 150 public List<String > getReservedWords() { 151 return new ArrayList<String >(reservedWords); 152 } 153 154 public boolean isReserved(String s) { 155 return reservedWords.contains(s.toUpperCase()); 156 } 157 158 162 protected void defineReserved(String s) { 163 reservedWords.add(s.toUpperCase()); 164 } 165 166 public List<Resolver> getResolvers() { 167 final List<Resolver> list = new ArrayList<Resolver>(); 168 for (List<Resolver> resolvers : mapNameToResolvers.values()) { 169 list.addAll(resolvers); 170 } 171 return list; 172 } 173 174 public boolean isProperty(String s) { 175 return propertyWords.contains(s.toUpperCase()); 176 } 177 178 182 protected void defineProperty(String s) { 183 propertyWords.add(s.toUpperCase()); 184 } 185 186 public List<FunInfo> getFunInfoList() { 187 return Collections.unmodifiableList(this.funInfoList); 188 } 189 190 193 protected void organizeFunctions() { 194 Collections.sort(funInfoList); 195 for (Resolver resolver : resolverList) { 197 String key = makeResolverKey(resolver.getName(), 198 resolver.getSyntax()); 199 List<Resolver> list = mapNameToResolvers.get(key); 200 if (list == null) { 201 list = new ArrayList<Resolver>(); 202 mapNameToResolvers.put(key, list); 203 } 204 list.add(resolver); 205 } 206 } 207 208 217 protected abstract void defineFunctions(); 218 } 219 220 | Popular Tags |