1 33 package net.sf.jga.parser; 34 35 import java.lang.reflect.Field ; 36 import java.lang.reflect.Method ; 37 import java.lang.reflect.Modifier ; 38 import java.math.BigDecimal ; 39 import java.math.BigInteger ; 40 import java.text.MessageFormat ; 41 import java.util.ArrayList ; 42 import java.util.HashMap ; 43 import java.util.List ; 44 import java.util.Map ; 45 import net.sf.jga.fn.UnaryFunctor; 46 import net.sf.jga.fn.arithmetic.ValueOf; 47 48 53 54 class ParserContext { 55 private Map <String ,Class > _arguments = new HashMap <String ,Class >(); 59 60 private Map <String ,Class > _imports = new HashMap <String ,Class >(); 62 63 private List <String > _packages = new ArrayList <String >(); 65 66 private Map <String ,List <Method >> _methods = new HashMap <String ,List <Method >>(); 69 70 private Map <String ,Field > _fields = new HashMap <String ,Field >(); 72 73 private Object _thisObj; 75 76 private boolean _undecoratedDecimal; 79 80 ParserContext() { 81 initializePromotionRules(); 82 } 83 84 87 ParserContext copy() { 88 ParserContext peer = new ParserContext(); 89 peer._arguments.putAll(_arguments); 90 peer._imports.putAll(_imports); 91 peer._methods.putAll(_methods); 92 peer._fields.putAll(_fields); 93 94 peer._packages.addAll(_packages); 95 96 peer._thisObj = _thisObj; 97 peer._undecoratedDecimal = _undecoratedDecimal; 98 99 for (Class fromtype : _promotionRules.keySet()) { 100 HashMap <Class ,UnaryFunctor> ruleset = _promotionRules.get(fromtype); 101 for (Class totype : ruleset.keySet()) { 102 UnaryFunctor fn = ruleset.get(totype); 103 peer.addPromotionRule(fromtype, totype, fn); 104 } 105 } 106 107 return peer; 108 } 109 110 113 public void declareArgument(String argName, Class argType) { 114 _arguments.put(argName, argType); 115 } 116 117 120 public Class getTypeForName(String name) { 121 return _arguments.get(name); 122 } 123 124 125 130 public void importClass(Class clasz) { 131 importClass(ParserUtils.getSimpleName(clasz), clasz); 132 } 133 134 135 140 public void importClass(String alias, Class clasz) { 141 if (alias != null && clasz != null) 142 _imports.put(alias, clasz); 143 } 144 145 146 149 public void deportClass(String alias) { 150 if (alias != null) 151 _imports.remove(alias); 152 } 153 154 157 public Class getImportedClass(String alias) { 158 Class klass = _imports.get(alias); 159 if (klass != null) 160 return klass; 161 162 List <Class > potentials = new ArrayList <Class >(); 163 for (String pkgName : _packages) { 164 try { 165 potentials.add(Class.forName(pkgName+"."+alias)); 166 } 167 catch (Exception x) { 168 } 171 } 172 173 if (potentials.size() == 1) { 174 return potentials.get(0); 175 } 176 177 return null; 178 } 179 180 181 184 public void importPackage(String pkgName) { 185 if ( ! _packages.contains(pkgName)) { 186 _packages.add(pkgName); 187 } 188 } 189 190 191 194 public void deportPackage(String pkgName) { 195 _packages.remove(pkgName); 196 } 197 198 199 202 public void importStatics(Class clasz) { 203 Field [] fields = clasz.getFields(); 205 for (int i = 0; i < fields.length; ++i) { 206 if (Modifier.isStatic(fields[i].getModifiers())) 207 importField(fields[i]); 208 } 209 210 Method [] methods = clasz.getMethods(); 212 for (int i= 0; i < methods.length; ++i) { 213 if (Modifier.isStatic(methods[i].getModifiers())) 214 importMethod(methods[i]); 215 } 216 } 217 218 219 225 public void importField(Class clasz, String name) throws NoSuchFieldException { 226 importField(clasz.getField(name)); 227 } 228 229 234 public void importField(Field field) throws IllegalArgumentException { 235 if (! Modifier.isStatic(field.getModifiers())) { 236 String msg = "Cannot import non-static field {0}"; 237 throw new IllegalArgumentException (MessageFormat.format(msg, new Object []{ field })); 238 } 239 240 _fields.put(field.getName(), field); 241 } 242 243 247 public Field getImportedField(String name) { 248 return _fields.get(name); 249 } 250 251 256 public void importMethod(Class clasz, String name) throws NoSuchMethodException { 257 Method [] methods = clasz.getMethods(); 258 int numImported = 0; 259 for (int i= 0; i < methods.length; ++i) { 260 if (name.equals(methods[i].getName()) && Modifier.isStatic(methods[i].getModifiers())) { 261 importMethod(name, methods[i]); 262 ++numImported; 263 } 264 } 265 266 if (numImported == 0) { 267 String msg = "No non-static method {0} found in class {1}"; 268 Object [] args = new Object [] {name, clasz.getName()}; 269 throw new NoSuchMethodException (MessageFormat.format(msg, args)); 270 } 271 } 272 273 281 public void importMethod(Method meth) { 282 importMethod(meth.getName(), meth); 283 } 284 285 292 public void importMethod(String name, Method meth) { 293 if (! Modifier.isStatic(meth.getModifiers())) { 294 String msg = "Cannot import non-static method {0}"; 295 throw new IllegalArgumentException (MessageFormat.format(msg, new Object []{ meth })); 296 } 297 298 List <Method > methodList = _methods.get(name); 299 if (methodList == null) { 300 methodList = new ArrayList <Method >(); 301 _methods.put(name, methodList); 302 } 303 methodList.add(meth); 304 } 305 306 307 310 public Method [] getImportedMethods(String name) { 311 List <Method > methodList = _methods.get(name); 312 if (methodList == null) 313 return new Method [0]; 314 else 315 return methodList.toArray(new Method [0]); 316 } 317 318 319 322 public void bindThis(Object thisBinding) { 323 _thisObj = thisBinding; 324 } 325 326 327 330 protected Object getBoundObject() { 331 return _thisObj; 332 } 333 334 335 342 public void setUndecoratedDecimal(boolean flag) { _undecoratedDecimal = flag; } 343 344 345 351 public boolean isUndecoratedDecimal() { return _undecoratedDecimal; } 352 353 354 358 public void addPromotionRule(Class fromType, Class toType, UnaryFunctor converter) { 359 HashMap <Class , UnaryFunctor> ruleset = _promotionRules.get(fromType); 360 if (ruleset == null) { 361 ruleset = new HashMap <Class , UnaryFunctor>(); 362 _promotionRules.put(fromType, ruleset); 363 } 364 365 ruleset.put(toType, converter); 366 } 367 368 372 public void removePromotionRule(Class fromType, Class toType) { 373 HashMap <Class , UnaryFunctor> ruleset = _promotionRules.get(fromType); 374 if (ruleset != null) 375 ruleset.remove(toType); 376 } 377 378 383 public UnaryFunctor getPromotionRule(Class fromType, Class toType) { 384 HashMap <Class , UnaryFunctor> ruleset = _promotionRules.get(fromType); 385 if (ruleset == null) 386 return null; 387 388 return ruleset.get(toType); 389 } 390 391 392 private HashMap <Class , HashMap <Class , UnaryFunctor>> _promotionRules = new HashMap (); 393 394 private UnaryFunctor toShort = new ValueOf(Short .class); 395 396 private UnaryFunctor toInteger = new ValueOf(Integer .class); 397 private UnaryFunctor toLong = new ValueOf(Long .class); 398 private UnaryFunctor toFloat = new ValueOf(Float .class); 399 private UnaryFunctor toDouble = new ValueOf(Double .class); 400 private UnaryFunctor toDecimal = new ValueOf(BigDecimal .class); 401 private UnaryFunctor toBigInt = new ValueOf(BigInteger .class); 402 403 private void initializePromotionRules() { 404 addPromotionRule(Byte .class, Short .class, toShort); 405 addPromotionRule(Byte .class, Integer .class, toInteger); 406 addPromotionRule(Byte .class, Long .class, toLong); 407 addPromotionRule(Byte .class, BigInteger .class,toBigInt); 408 addPromotionRule(Byte .class, Double .class, toDouble); 409 addPromotionRule(Byte .class, Float .class, toFloat); 410 addPromotionRule(Byte .class, BigDecimal .class,toDecimal); 411 412 addPromotionRule(Short .class, Integer .class, toInteger); 413 addPromotionRule(Short .class, Long .class, toLong); 414 addPromotionRule(Short .class, BigInteger .class,toBigInt); 415 addPromotionRule(Short .class, Double .class, toDouble); 416 addPromotionRule(Short .class, Float .class, toFloat); 417 addPromotionRule(Short .class, BigDecimal .class,toDecimal); 418 419 addPromotionRule(Integer .class, Long .class, toLong); 420 addPromotionRule(Integer .class, BigInteger .class,toBigInt); 421 addPromotionRule(Integer .class, Float .class, toFloat); 422 addPromotionRule(Integer .class, Double .class, toDouble); 423 addPromotionRule(Integer .class, BigDecimal .class,toDecimal); 424 425 addPromotionRule(Long .class, BigInteger .class,toBigInt); 426 addPromotionRule(Long .class, Float .class, toFloat); 427 addPromotionRule(Long .class, Double .class, toDouble); 428 addPromotionRule(Long .class, BigDecimal .class,toDecimal); 429 430 addPromotionRule(BigInteger .class,Float .class, toFloat); 431 addPromotionRule(BigInteger .class,Double .class, toDouble); 432 addPromotionRule(BigInteger .class,BigDecimal .class,toDecimal); 433 434 addPromotionRule(Float .class, Double .class, toDouble); 435 addPromotionRule(Float .class, BigDecimal .class,toDecimal); 436 437 addPromotionRule(Double .class, BigDecimal .class,toDecimal); 438 } 439 } 440 | Popular Tags |