1 21 package com.db4o.nativequery.optimization; 22 23 import java.lang.reflect.*; 24 25 import com.db4o.nativequery.expr.cmp.*; 26 import com.db4o.nativequery.expr.cmp.field.*; 27 28 final class ComparisonQueryGeneratingVisitor implements ComparisonOperandVisitor { 29 private Object _predicate; 30 31 private Object _value=null; 32 33 public Object value() { 34 return _value; 35 } 36 37 public void visit(ConstValue operand) { 38 _value = operand.value(); 39 } 40 41 public void visit(FieldValue operand) { 42 operand.parent().accept(this); 43 Class clazz=((operand.parent() instanceof StaticFieldRoot) ? (Class )_value : _value.getClass()); 44 try { 45 Field field=ReflectUtil.fieldFor(clazz,operand.fieldName()); 46 _value=field.get(_value); } catch (Exception exc) { 48 exc.printStackTrace(); 49 } 50 } 51 52 Object add(Object a,Object b) { 53 if(a instanceof Double ||b instanceof Double ) { 54 return new Double (((Double )a).doubleValue()+ ((Double )b).doubleValue()); 55 } 56 if(a instanceof Float ||b instanceof Float ) { 57 return new Float (((Float )a).floatValue()+ ((Float )b).floatValue()); 58 } 59 if(a instanceof Long ||b instanceof Long ) { 60 return new Long (((Long )a).longValue()+ ((Long )b).longValue()); 61 } 62 return new Integer (((Integer )a).intValue()+ ((Integer )b).intValue()); 63 } 64 65 Object subtract(Object a,Object b) { 66 if(a instanceof Double ||b instanceof Double ) { 67 return new Double (((Double )a).doubleValue()- ((Double )b).doubleValue()); 68 } 69 if(a instanceof Float ||b instanceof Float ) { 70 return new Float (((Float )a).floatValue() - ((Float )b).floatValue()); 71 } 72 if(a instanceof Long ||b instanceof Long ) { 73 return new Long (((Long )a).longValue() - ((Long )b).longValue()); 74 } 75 return new Integer (((Integer )a).intValue() - ((Integer )b).intValue()); 76 } 77 78 Object multiply(Object a,Object b) { 79 if(a instanceof Double ||b instanceof Double ) { 80 return new Double (((Double )a).doubleValue() * ((Double )b).doubleValue()); 81 } 82 if(a instanceof Float ||b instanceof Float ) { 83 return new Float (((Float )a).floatValue() * ((Float )b).floatValue()); 84 } 85 if(a instanceof Long ||b instanceof Long ) { 86 return new Long (((Long )a).longValue() * ((Long )b).longValue()); 87 } 88 return new Integer (((Integer )a).intValue() * ((Integer )b).intValue()); 89 } 90 91 Object divide(Object a,Object b) { 92 if(a instanceof Double ||b instanceof Double ) { 93 return new Double (((Double )a).doubleValue()/ ((Double )b).doubleValue()); 94 } 95 if(a instanceof Float ||b instanceof Float ) { 96 return new Float (((Float )a).floatValue() / ((Float )b).floatValue()); 97 } 98 if(a instanceof Long ||b instanceof Long ) { 99 return new Long (((Long )a).longValue() / ((Long )b).longValue()); 100 } 101 return new Integer (((Integer )a).intValue() / ((Integer )b).intValue()); 102 } 103 104 public void visit(ArithmeticExpression operand) { 105 operand.left().accept(this); 106 Object left=_value; 107 operand.right().accept(this); 108 Object right=_value; 109 switch(operand.op().id()) { 110 case ArithmeticOperator.ADD_ID: 111 _value=add(left,right); 112 break; 113 case ArithmeticOperator.SUBTRACT_ID: 114 _value=subtract(left,right); 115 break; 116 case ArithmeticOperator.MULTIPLY_ID: 117 _value=multiply(left,right); 118 break; 119 case ArithmeticOperator.DIVIDE_ID: 120 _value=divide(left,right); 121 break; 122 } 123 } 124 125 public void visit(CandidateFieldRoot root) { 126 } 127 128 public void visit(PredicateFieldRoot root) { 129 _value=_predicate; 130 } 131 132 public void visit(StaticFieldRoot root) { 133 try { 134 _value=Class.forName(root.className()); 135 } catch (ClassNotFoundException e) { 136 e.printStackTrace(); 137 } 138 } 139 140 public void visit(ArrayAccessValue operand) { 141 operand.parent().accept(this); 142 Object parent=_value; 143 operand.index().accept(this); 144 Integer index=(Integer )_value; 145 _value=Array.get(parent, index.intValue()); 146 } 147 148 public void visit(MethodCallValue operand) { 149 operand.parent().accept(this); 150 Object receiver=_value; 151 Object [] params=new Object [operand.args().length]; 152 for (int paramIdx = 0; paramIdx < operand.args().length; paramIdx++) { 153 operand.args()[paramIdx].accept(this); 154 params[paramIdx]=_value; 155 } 156 Class clazz=receiver.getClass(); 157 if(operand.parent().root() instanceof StaticFieldRoot&&clazz.equals(Class .class)) { 158 clazz=(Class )receiver; 159 } 160 Method method=ReflectUtil.methodFor(clazz,operand.methodName(),operand.paramTypes()); 161 try { 162 _value=method.invoke(receiver, params); 163 } catch (Exception exc) { 164 exc.printStackTrace(); 165 _value=null; 166 } 167 } 168 169 public ComparisonQueryGeneratingVisitor(Object predicate) { 170 super(); 171 this._predicate = predicate; 172 } 173 174 } | Popular Tags |