1 28 29 package com.caucho.config.types; 30 31 import com.caucho.config.ConfigException; 32 import com.caucho.server.util.CauchoSystem; 33 import com.caucho.util.CharBuffer; 34 import com.caucho.util.L10N; 35 36 import javax.annotation.PostConstruct; 37 import java.lang.reflect.Method ; 38 import java.util.ArrayList ; 39 40 43 public class Signature { 44 private static L10N L = new L10N(Signature.class); 45 46 private String _signature; 47 private String _className; 48 private String _name; 49 private String []_parameterTypes; 50 private String _returnType; 51 52 private int _index; 53 54 public Signature() 55 { 56 } 57 58 public Signature(String sig) 59 { 60 addText(sig); 61 init(); 62 } 63 64 67 public String getSignature() 68 { 69 return _signature; 70 } 71 72 75 public String getName() 76 { 77 return _name; 78 } 79 80 83 public String getClassName() 84 { 85 return _className; 86 } 87 88 91 public Method getMethod() 92 { 93 if (_className == null) 94 return null; 95 96 try { 97 Class cl = CauchoSystem.loadClass(_className); 98 if (cl == null) 99 return null; 100 101 Method []methods = cl.getMethods(); 102 for (int i = 0; i < methods.length; i++) { 103 if (matches(methods[i])) { 104 return methods[i]; 105 } 106 } 107 } catch (Exception e) { 108 } 109 110 return null; 111 } 112 113 116 public String getReturnType() 117 { 118 return _returnType; 119 } 120 121 125 public String []getParameterTypes() 126 { 127 return _parameterTypes; 128 } 129 130 133 public void addText(String value) 134 { 135 _signature = value; 136 } 137 138 141 @PostConstruct 142 public void init() 143 throws ConfigException 144 { 145 if (_signature == null) 146 throw new ConfigException(L.l("A Signature requires the method signature.")); 147 148 parseSignature(); 149 } 150 151 154 public boolean matches(Method method) 155 { 156 if (! method.getName().equals(getName())) 157 return false; 158 159 Class []parameterTypes = method.getParameterTypes(); 160 String []sigTypes = getParameterTypes(); 161 162 if (parameterTypes.length != sigTypes.length) 163 return false; 164 165 for (int i = 0; i < parameterTypes.length; i++) { 166 String param = getName(parameterTypes[i]); 167 168 if (! param.equals(sigTypes[i]) && 169 ! param.endsWith("." + sigTypes[i])) 170 return false; 171 } 172 173 return true; 174 } 175 176 private String getName(Class cl) 177 { 178 if (cl.isArray()) 179 return getName(cl.getComponentType()) + "[]"; 180 else 181 return cl.getName(); 182 } 183 184 187 private void parseSignature() 188 throws ConfigException 189 { 190 _index = 0; 191 192 _returnType = parseType(skipWhitespace(read())); 193 194 CharBuffer cb = CharBuffer.allocate(); 195 int ch = skipWhitespace(read()); 196 197 if (ch == '(' || ch < 0) { 198 _name = _returnType; 199 _returnType = null; 200 } 201 else { 202 for (; Character.isJavaIdentifierPart((char) ch) || ch == '.'; ch = read()) 203 cb.append((char) ch); 204 205 if (cb.length() == 0) 206 throw new ConfigException(L.l("unexpected empty function name in `{0}'", 207 _signature)); 208 209 _name = cb.toString(); 210 211 int p = _name.lastIndexOf('.'); 212 if (p > 0) { 213 _className = _name.substring(0, p); 214 _name = _name.substring(p + 1); 215 } 216 217 ch = skipWhitespace(ch); 218 } 219 220 if (ch != '(') 221 throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'", 222 _signature)); 223 224 ArrayList <String > argList = new ArrayList <String >(); 225 226 ch = read(); 227 while (Character.isJavaIdentifierPart((char) (ch = skipWhitespace(ch))) || 228 ch == '.') { 229 String type = parseType(ch); 230 231 argList.add(type); 232 233 ch = skipWhitespace(read()); 234 235 for (; 236 Character.isJavaIdentifierPart((char) ch) || ch == '.'; 237 ch = read()) { 238 } 239 240 if (ch == ',') 241 ch = read(); 242 } 243 244 _parameterTypes = (String []) argList.toArray(new String [argList.size()]); 245 246 if (ch != ')') 247 throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'", 248 _signature)); 249 250 ch = skipWhitespace(read()); 251 252 if (ch != -1) 253 throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'", 254 _signature)); 255 } 256 257 260 private String parseType(int ch) 261 throws ConfigException 262 { 263 CharBuffer cb = CharBuffer.allocate(); 264 265 for (; Character.isJavaIdentifierPart((char) ch) || ch == '.'; ch = read()) 266 cb.append((char) ch); 267 268 if (cb.length() == 0) 269 throw new ConfigException(L.l("unexpected empty type in `{0}'", 270 _signature)); 271 272 while (true) { 273 for (; Character.isWhitespace((char) ch); ch = read()) { 274 } 275 276 if (ch == '[') { 277 ch = read(); 278 279 if (ch != ']') 280 throw new ConfigException(L.l("function syntax is `ret-type name(arg1, ..., argn)' in `{0}'", 281 _signature)); 282 283 cb.append("[]"); 284 285 ch = read(); 286 } 287 else 288 break; 289 } 290 291 292 293 String className = cb.toString(); 294 295 unread(ch); 296 297 return className; 298 } 299 300 303 private int skipWhitespace(int ch) 304 { 305 for (; Character.isWhitespace((char) ch); ch = read()) { 306 } 307 308 return ch; 309 } 310 311 314 private int read() 315 { 316 if (_index < _signature.length()) 317 return _signature.charAt(_index++); 318 else 319 return -1; 320 } 321 322 325 private void unread(int ch) 326 { 327 if (ch >= 0) 328 _index--; 329 } 330 331 public String toString() 332 { 333 return "Signature[" + _signature + "]"; 334 } 335 } 336 337 | Popular Tags |