1 package org.objectweb.modfact.qvt.engine; 2 3 import java.util.*; 4 import javax.jmi.reflect.*; 5 6 import org.objectweb.modfact.qvt.util.RulePrinter; 7 8 class ExpEvaluator { 9 10 RuleBinding binding; 11 12 int indent; 13 14 ExpEvaluator(RuleBinding binding) { 15 this.binding = binding; 16 this.indent = binding.indent+1; 17 } 18 19 Object eval(RefObject exp) throws Exception { 20 try { 21 if(Reflection.isOfType(exp, "ParameterExp") ) { 22 return parameterExp( exp ); 23 24 } else if(Reflection.isOfType(exp, "IfExp") ) { 25 return ifExp( exp ); 26 27 } else if(Reflection.isOfType(exp, "ModelReferenceExp") ) { 28 return modelReferenceExp( exp ); 29 30 } else if(Reflection.isOfType(exp, "LiteralExp") ) { 31 return literalExp( exp ); 32 33 } else if(Reflection.isOfType(exp, "ContextExp") ) { 34 return contextExp( exp ); 35 } 36 throw new ExpEvalException("unknown exp: " +RulePrinter.printer.getTypeName(exp), null); 37 } catch(Exception e) { 38 if(e instanceof ReflectException) { 39 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent+1) +"*** ReflectException :" +e.getMessage()); 40 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent+1) 41 +"at " +RulePrinter.printer.getTypeName(exp) +": " 42 +RulePrinter.printer.printShort(exp) 43 ); 44 Throwable cause = ((ReflectException)e).getCause(); 45 throw new ExpEvalException("", cause); 46 } 47 throw e; 48 } 49 } 50 51 private Object contextExp(RefObject exp) throws Exception { 52 Object context = eval((RefObject)exp.refGetValue("context")); 53 54 if(Reflection.isOfType(exp, "AbstractOperationCallExp") ) { 55 if(context==null) { 56 showNullContextMessage(exp); 57 return null; 58 } 59 return abstractOperationCallExp( exp, context ); 60 61 } else if(Reflection.isOfType(exp, "PropertyCallExp") ) { 62 if(context==null) { 63 showNullContextMessage(exp); 64 return null; 65 } 66 return propertyCallExp( exp, context ); 67 68 } else if(Reflection.isOfType(exp, "PropertyAssignExp") ) { 69 if(context==null) { 70 showNullContextMessage(exp); 71 return null; 72 } 73 propertyAssignExp( exp, context ); 74 return null; 75 76 } else if(Reflection.isOfType(exp, "CollectionExp") ) { 77 if(context==null) { 78 showNullContextMessage(exp); 79 return null; 80 } 81 return collectionExp( exp, context ); 82 83 } else if(Reflection.isOfType(exp, "IsOfTypeExp") ) { 84 return isOfTypeExp( exp, context ); 85 86 } else if(Reflection.isOfType(exp, "CompareExp") ) { 87 return compareExp( exp, context ); 88 } 89 return null; 90 91 } 92 93 private void showNullContextMessage(RefObject exp) { 94 if(RuleBinding.verbose) { 95 System.err.println( 96 RulePrinter.printer.doIndent(indent+1) 97 +exp.refMetaObject().refGetValue("name") 98 +": null context" 99 ); 100 } 101 } 102 103 private Object abstractOperationCallExp ( 104 RefObject exp, Object context) throws Exception { 105 RefObject[] array = (RefObject[]) ((Collection)exp.refGetValue("args")).toArray(new RefObject[0]); 106 List args = new Vector(); 107 for(int i=0; i<array.length; i++) { 108 args.add(eval(array[i])); 109 } 110 if( Reflection.isOfType(exp, "RuleCallExp") ) { 111 return ruleCallExp( exp, context, args ); 112 113 } else { 114 return operationCallExp( exp, context, args ); 115 } 116 } 117 118 private Object ruleCallExp( 119 RefObject exp, Object context, List argsList) throws Exception { 120 if(context==null) { 121 return null; 122 } 123 Object [] argsArray = argsList.toArray(); 124 RefObject[] params = (RefObject[]) ( (Collection)( 125 (RefObject)exp.refGetValue("rule")).refGetValue("params") 126 ).toArray(new RefObject[0]); 127 Hashtable sharedArgs = new Hashtable(); 128 for(int i=0; i<params.length; i++ ) { 129 sharedArgs.put( (String )params[i].refGetValue("name") ,argsArray[i]); 130 } 131 RefObject rule = (RefObject)exp.refGetValue("rule"); 132 133 if(context instanceof Collection) { 134 Object [] contexts = ((Collection)context).toArray(); 136 Collection r = new Vector(); 137 for(int i=0; i<contexts.length; i++) { 138 Hashtable args = new Hashtable(sharedArgs); 139 args.put("context", contexts[i]); 140 Object aCallResult = new RuleBinding( 141 binding.bindingTable 142 , rule, binding.src, binding.target, args, indent+1 143 ).execute(); 144 if(aCallResult instanceof Collection) { 145 r.addAll((Collection) aCallResult); 146 } else if(aCallResult!=null) { 147 r.add( aCallResult ); 148 } 149 } 150 return r; 151 } 152 153 sharedArgs.put("context", context); 155 return new RuleBinding( 156 binding.bindingTable 157 , rule, binding.src, binding.target, sharedArgs, indent+1 158 ).execute(); 159 } 160 161 private Object operationCallExp( 162 RefObject exp, Object context, List args) throws Exception { 163 return Reflection.invokeOperation((String )exp.refGetValue("opName"), context ,args); 164 } 165 166 private Object parameterExp(RefObject exp) throws Exception { 167 return binding.args.get(exp.refGetValue("name")) ; 168 } 169 170 private void propertyAssignExp (RefObject exp, Object context) throws Exception { 171 Object value = eval((RefObject)exp.refGetValue("value")); Reflection.assignProperty((RefObject)context ,(String )exp.refGetValue("propName"), value); 173 } 174 175 private Object collectionExp(RefObject exp, Object context) throws Exception { 176 Object member = eval((RefObject)exp.refGetValue("member")); 177 Collection c = (Collection) context; 178 if(member instanceof Collection) { 179 Collection members = (Collection) member; 180 if (Reflection.isOfType(exp, "AddCollectionExp") ) { 181 c.addAll(members); 182 } else if (Reflection.isOfType(exp, "RemoveCollectionExp") ) { 183 c.removeAll(members); 184 } 185 } else { 186 if (Reflection.isOfType(exp, "AddCollectionExp") ) { 187 c.add(member); 188 } else if (Reflection.isOfType(exp, "RemoveCollectionExp") ) { 189 c.remove(member); 190 } 191 } 192 return c; 193 } 194 195 private Object ifExp(RefObject exp) throws Exception { 196 Object cond = eval((RefObject)exp.refGetValue("cond")); 197 boolean condTestResult; 198 if(cond == null ) { 199 condTestResult = false; 200 } else if ( cond.equals(new Boolean (false)) ) { 201 condTestResult = false; 202 } else if( cond instanceof Collection 203 && ((Collection)cond).isEmpty() ) { 204 condTestResult = false; 205 } else { 206 condTestResult = true; 207 } 208 if(Reflection.isOfType(exp, "IfStatementExp") ) { 209 ifStatementExp( exp ,condTestResult); 210 return null; 211 } else if(Reflection.isOfType(exp, "IfValueExp") ) { 212 return ifValueExp( exp ,condTestResult); 213 } 214 return null; 215 } 216 217 private void ifStatementExp(RefObject exp, boolean condTestResult) throws Exception { 218 RefObject[] selectedStatements; 219 String thenOrElse; 220 if(condTestResult) { 221 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent) 222 +"do 'then' {" 223 ); 224 thenOrElse = "thenStatements"; 225 } else { 226 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent) 227 +"do 'else' {" 228 ); 229 thenOrElse = "elseStatements"; 230 } 231 selectedStatements = (RefObject[]) ((Collection)exp.refGetValue(thenOrElse)).toArray(new RefObject[0]); 232 ExpEvaluator evaluator = new ExpEvaluator(binding); 233 for(int i=0; i< selectedStatements.length; i++) { 234 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent+1) 235 +(i+1) +": " +RulePrinter.printer.printShort(selectedStatements[i]) 236 ); 237 evaluator.eval(selectedStatements[i]); 238 } 239 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent) 240 +"} //end " +RulePrinter.printer.printShort(exp) 241 ); 242 } 243 244 private Object ifValueExp(RefObject exp ,boolean condTestResult) throws Exception { 245 if(condTestResult) { 246 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent) 247 +"do 'then': " +RulePrinter.printer.printShort((RefObject)exp.refGetValue("thenExp")) 248 ); 249 return eval((RefObject)exp.refGetValue("thenExp")); 250 } else { 251 if(RuleBinding.verbose) System.err.println( RulePrinter.printer.doIndent(indent) 252 +"do 'else': " +RulePrinter.printer.printShort((RefObject)exp.refGetValue("elseExp")) 253 ); 254 return eval((RefObject)exp.refGetValue("elseExp")); 255 } 256 } 257 258 private Object modelReferenceExp(RefObject exp) throws Exception { 259 return Reflection.allOfType(binding.src, (String )exp.refGetValue("conceptName")) ; 260 } 261 262 263 private Object propertyCallExp(RefObject exp, Object context) throws Exception { 264 return Reflection.getPropertyValue( 265 (RefObject)context, (String )exp.refGetValue("propName") 266 ); 267 } 268 269 private Object compareExp(RefObject exp, Object context) throws Exception { 270 Object val = eval((RefObject)exp.refGetValue("compareVal")); 271 if(context==null) return new Boolean (val==null); 272 return new Boolean (context.equals(val)); 273 } 274 275 private Object isOfTypeExp(RefObject exp, Object context) throws Exception { 276 if(context==null) 277 return new Boolean (false); 278 return new Boolean ( 279 Reflection.isOfType((RefObject)context, (String )exp.refGetValue("type")) 280 ); 281 } 282 283 private Object literalExp(RefObject exp) throws Exception { 284 285 if(Reflection.isOfType(exp, "DoubleLiteral") ) { 286 return (Double ) exp.refGetValue("val"); 287 288 } else if(Reflection.isOfType(exp, "IntegerLiteral") ) { 289 return (Integer ) exp.refGetValue("val"); 290 291 } else if(Reflection.isOfType(exp, "BooleanLiteral") ) { 292 return (Boolean ) exp.refGetValue("val"); 293 294 } else if(Reflection.isOfType(exp, "StringLiteral") ) { 295 return (String ) exp.refGetValue("val"); 296 297 } else if(Reflection.isOfType(exp, "EnumLiteral") ) { 298 return Reflection.getEnumValue( 299 srcOrTarget((Boolean ) exp.refGetValue("isFromMmSrc")) 300 , (String ) exp.refGetValue("type") 301 , (String ) exp.refGetValue("val") ); 302 303 } 304 return null; 305 } 306 307 private RefPackage srcOrTarget(Boolean isFromMmSrc) { 308 return (isFromMmSrc.equals(Boolean.TRUE))? binding.src: binding.target; 309 } 310 311 } 312 313 314 315 | Popular Tags |