/// <summary> Execute method against context. /// </summary> public override System.Object execute(System.Object o, InternalContextAdapter context) { if (property == null && method == null) { return(null); } try { if (property != null) { return(property.GetValue(o, null)); } else { return(method.Invoke(o, new Object[0])); } } catch (System.Reflection.TargetInvocationException ite) { EventCartridge ec = context.EventCartridge; /* * if we have an event cartridge, see if it wants to veto * also, let non-Exception Throwables go... */ if (ec != null && ite.GetBaseException() is System.Exception) { try { return(ec.methodException(o.GetType(), propertyUsed, (System.Exception)ite.GetBaseException())); } catch (System.Exception e) { throw new MethodInvocationException("Invocation of property '" + propertyUsed + "'" + " in " + o.GetType() + " threw exception " + ite.GetBaseException().GetType() + " : " + ite.GetBaseException().Message, ite.GetBaseException(), propertyUsed); } } else { /* * no event cartridge to override. Just throw */ throw new MethodInvocationException("Invocation of property '" + propertyUsed + "'" + " in " + o.GetType() + " threw exception " + ite.GetBaseException().GetType() + " : " + ite.GetBaseException().Message, ite.GetBaseException(), propertyUsed); } } catch (System.ArgumentException iae) { return(null); } }
/// <summary> /// invokes the method. Returns null if a problem, the /// actual return if the method returns something, or /// an empty string "" if the method returns void /// </summary> public override System.Object execute(System.Object o, InternalContextAdapter context) { /* * new strategy (strategery!) for introspection. Since we want * to be thread- as well as context-safe, we *must* do it now, * at execution time. There can be no in-node caching, * but if we are careful, we can do it in the context. */ MethodInfo method = null; PropertyInfo property = null; try { /* * check the cache */ IntrospectionCacheData icd = context.ICacheGet(this); System.Type c = o.GetType(); /* * like ASTIdentifier, if we have cache information, and the * Class of Object o is the same as that in the cache, we are * safe. */ if (icd != null && icd.contextData == c) { /* * sadly, we do need recalc the values of the args, as this can * change from visit to visit */ for (int j = 0; j < paramCount; j++) { params_Renamed[j] = jjtGetChild(j + 1).value_Renamed(context); } /* * and get the method from the cache */ if (icd.thingy is MethodInfo) { method = (MethodInfo)icd.thingy; } if (icd.thingy is PropertyInfo) { property = (PropertyInfo)icd.thingy; } } else { /* * otherwise, do the introspection, and then * cache it */ Object obj = doIntrospection(context, c); if (obj is MethodInfo) { method = (MethodInfo)obj; } if (obj is PropertyInfo) { property = (PropertyInfo)obj; } if (obj != null) { icd = new IntrospectionCacheData(); icd.contextData = c; icd.thingy = obj; context.ICachePut(this, icd); } } /* * if we still haven't gotten the method, either we are calling * a method that doesn't exist (which is fine...) or I screwed * it up. */ if (method == null && property == null) { return(null); } } catch (MethodInvocationException mie) { /* * this can come from the doIntrospection(), as the arg values * are evaluated to find the right method signature. We just * want to propogate it here, not do anything fancy */ throw mie; } catch (System.Exception e) { /* * can come from the doIntropection() also, from Introspector */ rsvc.error("ASTMethod.execute() : exception from introspection : " + e); return(null); } try { /* * get the returned object. It may be null, and that is * valid for something declared with a void return type. * Since the caller is expecting something to be returned, * as long as things are peachy, we can return an empty * String so ASTReference() correctly figures out that * all is well. */ Object obj = null; if (method != null) { obj = method.Invoke(o, (System.Object[])params_Renamed); if (obj == null && method.ReturnType == System.Type.GetType("System.Void")) { obj = String.Empty; } } else { obj = property.GetValue(o, null); } return(obj); } catch (System.Reflection.TargetInvocationException ite) { /* * In the event that the invocation of the method * itself throws an exception, we want to catch that * wrap it, and throw. We don't log here as we want to figure * out which reference threw the exception, so do that * above */ EventCartridge ec = context.EventCartridge; /* * if we have an event cartridge, see if it wants to veto * also, let non-Exception Throwables go... */ if (ec != null && ite.GetBaseException() is System.Exception) { try { return(ec.methodException(o.GetType(), methodName, (System.Exception)ite.GetBaseException())); } catch (System.Exception e) { throw new MethodInvocationException("Invocation of method '" + methodName + "' in " + o.GetType() + " threw exception " + e.GetType() + " : " + e.Message, e, methodName); } } else { /* * no event cartridge to override. Just throw */ throw new MethodInvocationException("Invocation of method '" + methodName + "' in " + o.GetType() + " threw exception " + ite.GetBaseException().GetType() + " : " + ite.GetBaseException().Message, ite.GetBaseException(), methodName); } } catch (System.Exception e) { rsvc.error("ASTMethod.execute() : exception invoking method '" + methodName + "' in " + o.GetType() + " : " + e); return(null); } }
/// <summary> /// invokes the method on the object passed in /// </summary> public override Object execute(Object o, InternalContextAdapter context) { VelPropertyGet vg = null; try { Type c = o.GetType(); /* * first, see if we have this information cached. */ IntrospectionCacheData icd = context.ICacheGet(this); /* * if we have the cache data and the class of the object we are * invoked with is the same as that in the cache, then we must * be allright. The last 'variable' is the method name, and * that is fixed in the template :) */ if (icd != null && icd.contextData == c) { vg = (VelPropertyGet)icd.thingy; } else { /* * otherwise, do the introspection, and cache it */ vg = rsvc.Uberspect.getPropertyGet(o, identifier, uberInfo); if (vg != null && vg.Cacheable) { icd = new IntrospectionCacheData(); icd.contextData = c; icd.thingy = vg; context.ICachePut(this, icd); } } } catch (Exception e) { rsvc.error("ASTIdentifier.execute() : identifier = " + identifier + " : " + e); } /* * we have no executor... punt... */ if (vg == null) { return(null); } /* * now try and execute. If we get a MIE, throw that * as the app wants to get these. If not, log and punt. */ try { return(vg.invoke(o)); } catch (TargetInvocationException ite) { EventCartridge ec = context.EventCartridge; /* * if we have an event cartridge, see if it wants to veto * also, let non-Exception Throwables go... */ if (ec != null) { try { return(ec.methodException(o.GetType(), vg.MethodName, ite.InnerException)); } catch (Exception e) { String message = String.Format( "Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw exception {5} {6}", vg.MethodName, o != null ? o.GetType().FullName : "", uberInfo.TemplateName, uberInfo.Line, uberInfo.Column, ite.InnerException.GetType(), ite.InnerException.Message); throw new MethodInvocationException(message, ite.InnerException, vg.MethodName); } } else { /* * no event cartridge to override. Just throw */ String message = String.Format( "Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw exception {5} {6}", vg.MethodName, o != null ? o.GetType().FullName : "", uberInfo.TemplateName, uberInfo.Line, uberInfo.Column, ite.InnerException.GetType(), ite.InnerException.Message); throw new MethodInvocationException(message, ite.InnerException, vg.MethodName); } } catch (ArgumentException iae) { return(null); } catch (Exception e) { rsvc.error("ASTIdentifier() : exception invoking method " + "for identifier '" + identifier + "' in " + o.GetType() + " : " + e); } return(null); }
/// <summary> /// invokes the method. Returns null if a problem, the /// actual return if the method returns something, or /// an empty string "" if the method returns void /// </summary> public override Object execute(Object o, InternalContextAdapter context) { /* * new strategy (strategery!) for introspection. Since we want * to be thread- as well as context-safe, we *must* do it now, * at execution time. There can be no in-node caching, * but if we are careful, we can do it in the context. */ MethodInfo method = null; PropertyInfo property = null; bool preparedAlready = false; Object[] methodArguments = params_Renamed; try { /* * check the cache */ IntrospectionCacheData icd = context.ICacheGet(this); Type c = o.GetType(); /* * like ASTIdentifier, if we have cache information, and the * Class of Object o is the same as that in the cache, we are * safe. */ if (icd != null && icd.contextData == c) { // We blindly assume that if there's an array, // we're dealing with a "params array[] args" and // if so, we create an array with an appropriate size // int arrayArg = paramArrayIndex == -1 ? int.MaxValue : paramArrayIndex; // for (int j = 0; j < paramCount; j++) // { // if (params_Renamed[j] != null && params_Renamed[j].GetType().IsArray) // { // Array array = Array.CreateInstance( // params_Renamed[j].GetType().GetElementType(), paramCount - j ); // // params_Renamed[j] = array; // // arrayArg = j; break; // } // } /* * sadly, we do need recalc the values of the args, as this can * change from visit to visit */ for (int j = 0; j < paramCount; j++) { params_Renamed[j] = jjtGetChild(j + 1).Value(context); } preparedAlready = true; /* * and get the method from the cache */ if (icd.thingy is MethodInfo) { method = (MethodInfo)icd.thingy; methodArguments = BuildMethodArgs(method, paramArrayIndex); } if (icd.thingy is PropertyInfo) { property = (PropertyInfo)icd.thingy; } } else { /* * otherwise, do the introspection, and then * cache it */ Object obj = doIntrospection(context, c); if (obj is MethodInfo) { method = (MethodInfo)obj; } if (obj is PropertyInfo) { property = (PropertyInfo)obj; } if (obj != null) { icd = new IntrospectionCacheData(); icd.contextData = c; icd.thingy = obj; context.ICachePut(this, icd); } } /* * if we still haven't gotten the method, either we are calling * a method that doesn't exist (which is fine...) or I screwed * it up. */ if (method == null && property == null) { return(null); } } catch (Exception e) { /* * can come from the doIntropection() also, from Introspector */ rsvc.error("ASTMethod.execute() : exception from introspection : " + e); throw; } try { /* * get the returned object. It may be null, and that is * valid for something declared with a void return type. * Since the caller is expecting something to be returned, * as long as things are peachy, we can return an empty * String so ASTReference() correctly figures out that * all is well. */ Object obj = null; if (method != null) { if (!preparedAlready) { methodArguments = BuildMethodArgs(method); } obj = method.Invoke(o, methodArguments); if (obj == null && method.ReturnType == typeof(void)) { obj = String.Empty; } } else { obj = property.GetValue(o, null); } return(obj); } catch (TargetInvocationException ite) { /* * In the event that the invocation of the method * itself throws an exception, we want to catch that * wrap it, and throw. We don't log here as we want to figure * out which reference threw the exception, so do that * above */ EventCartridge ec = context.EventCartridge; /* * if we have an event cartridge, see if it wants to veto * also, let non-Exception Throwables go... */ if (ec != null && ite.GetBaseException() is Exception) { try { return(ec.methodException(o.GetType(), methodName, (Exception)ite.GetBaseException())); } catch (Exception e) { throw new MethodInvocationException("Invocation of method '" + methodName + "' in " + o.GetType() + " threw exception " + e.GetType() + " : " + e.Message, e, methodName); } } else { /* * no event cartridge to override. Just throw */ throw new MethodInvocationException("Invocation of method '" + methodName + "' in " + o.GetType() + " threw exception " + ite.GetBaseException().GetType() + " : " + ite.GetBaseException().Message, ite.GetBaseException(), methodName); } } catch (Exception e) { rsvc.error("ASTMethod.execute() : exception invoking method '" + methodName + "' in " + o.GetType() + " : " + e); throw e; } }