/// <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, IInternalContextAdapter context) { IDuck duck = o as IDuck; object[] parameters = new object[paramCount]; if (duck != null) { EvalParameters(parameters, context); return(duck.Invoke(methodName, parameters)); } /* * new strategy (strategy!) 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 = new object[paramCount]; try { /* * check the cache */ IntrospectionCacheData introspectionCacheData = 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. */ EvalParameters(parameters, context); if (introspectionCacheData != null && introspectionCacheData.ContextData == c) { preparedAlready = true; /* * and get the method from the cache */ if (introspectionCacheData.Thingy is MethodInfo) { method = (MethodInfo)introspectionCacheData.Thingy; methodArguments = BuildMethodArgs(method, parameters, paramArrayIndex); } if (introspectionCacheData.Thingy is PropertyInfo) { property = (PropertyInfo)introspectionCacheData.Thingy; } } else { /* * otherwise, do the introspection, and then * cache it */ Object obj = PerformIntrospection(context, c, parameters); if (obj is MethodInfo) { method = (MethodInfo)obj; } if (obj is PropertyInfo) { property = (PropertyInfo)obj; } if (obj != null) { introspectionCacheData = new IntrospectionCacheData(); introspectionCacheData.ContextData = c; introspectionCacheData.Thingy = obj; context.ICachePut(this, introspectionCacheData); } } /* * 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 ex) { runtimeServices.Error(string.Format("ASTMethod.execute() : exception from introspection : {0}", ex)); throw new RuntimeException( String.Format( "Error during object introspection. Check inner exception for details. Node literal {0} Line {1} Column {2}", base.Literal, Line, Column), ex); } 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; if (method == null) { obj = property.GetValue(o, null); } else { if (!preparedAlready) { methodArguments = BuildMethodArgs(method, parameters); } obj = method.Invoke(o, methodArguments); if (obj == null && method.ReturnType == typeof(void)) { obj = String.Empty; } } return(obj); } catch (TargetInvocationException targetInvocationException) { /* * 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 eventCartridge = context.EventCartridge; /* * if we have an event cartridge, see if it wants to veto * also, let non-Exception Throwables go... */ if (eventCartridge == null) { /* * no event cartridge to override. Just throw */ throw new MethodInvocationException( string.Format("Invocation of method '{0}' in {1} threw exception {2} : {3}", methodName, o.GetType(), targetInvocationException.GetBaseException().GetType(), targetInvocationException.GetBaseException().Message), targetInvocationException, methodName); } else { try { return(eventCartridge.HandleMethodException(o.GetType(), methodName, targetInvocationException)); } catch (Exception e) { throw new MethodInvocationException( string.Format("Invocation of method '{0}' in {1} threw exception {2} : {3}", methodName, o.GetType(), e.GetType(), e.Message), e, methodName); } } } catch (Exception e) { runtimeServices.Error( string.Format("ASTMethod.execute() : exception invoking method '{0}' in {1} : {2}", methodName, o.GetType(), e)); throw; } }
public override object Execute(object o, IInternalContextAdapter context) { MethodInfo methodInfo = null; PropertyInfo propertyInfo = null; bool flag = false; object[] array = this.parameters; object result; try { IntrospectionCacheData introspectionCacheData = context.ICacheGet(this); Type type = o.GetType(); if (introspectionCacheData != null && introspectionCacheData.ContextData == type) { for (int i = 0; i < this.paramCount; i++) { this.parameters[i] = base.GetChild(i + 1).Value(context); } flag = true; if (introspectionCacheData.Thingy is MethodInfo) { methodInfo = (MethodInfo)introspectionCacheData.Thingy; array = this.BuildMethodArgs(methodInfo, this.paramArrayIndex); } if (introspectionCacheData.Thingy is PropertyInfo) { propertyInfo = (PropertyInfo)introspectionCacheData.Thingy; } } else { object obj = this.doIntrospection(context, type); if (obj is MethodInfo) { methodInfo = (MethodInfo)obj; } if (obj is PropertyInfo) { propertyInfo = (PropertyInfo)obj; } if (obj != null) { context.ICachePut(this, new IntrospectionCacheData { ContextData = type, Thingy = obj }); } } if (methodInfo == null && propertyInfo == null) { result = null; return(result); } } catch (System.Exception ex) { this.rsvc.Error("ASTMethod.execute() : exception from introspection : " + ex); throw new RuntimeException(string.Format("Error during object instrospection. Check inner exception for details. Node literal {0} Line {1} Column {2}", base.Literal, base.Line, base.Column), ex); } try { object obj; if (methodInfo != null) { if (!flag) { array = this.BuildMethodArgs(methodInfo); } obj = methodInfo.Invoke(o, array); if (obj == null && methodInfo.ReturnType == typeof(void)) { obj = string.Empty; } } else { obj = propertyInfo.GetValue(o, null); } result = obj; } catch (TargetInvocationException ex2) { EventCartridge eventCartridge = context.EventCartridge; if (eventCartridge != null) { try { result = eventCartridge.HandleMethodException(o.GetType(), this.methodName, ex2.GetBaseException()); return(result); } catch (System.Exception ex3) { throw new MethodInvocationException(string.Concat(new object[] { "Invocation of method '", this.methodName, "' in ", o.GetType(), " threw exception ", ex3.GetType(), " : ", ex3.Message }), ex3, this.methodName); } } throw new MethodInvocationException(string.Concat(new object[] { "Invocation of method '", this.methodName, "' in ", o.GetType(), " threw exception ", ex2.GetBaseException().GetType(), " : ", ex2.GetBaseException().Message }), ex2.GetBaseException(), this.methodName); } catch (System.Exception ex3) { this.rsvc.Error(string.Concat(new object[] { "ASTMethod.execute() : exception invoking method '", this.methodName, "' in ", o.GetType(), " : ", ex3 })); throw ex3; } return(result); }
/// <summary> /// invokes the method on the object passed in /// </summary> public override Object Execute(Object o, IInternalContextAdapter context) { bool isString = o.GetType() == typeof(string); bool isDecimal = o.GetType() == typeof(decimal); bool isPrimitive = o.GetType().IsPrimitive; if (identifier == "to_quote" && (isString || isPrimitive || isDecimal)) { return(string.Format("\"{0}\"", EscapeDoubleQuote(o.ToString()))); } else if (identifier == "to_squote" && (isString || isPrimitive || isDecimal)) { return(string.Format("'{0}'", EscapeSingleQuote(o.ToString()))); } IDuck duck = o as IDuck; if (duck != null) { return(duck.GetInvoke(identifier)); } IVelPropertyGet velPropertyGet = null; try { Type c = o.GetType(); // first, see if we have this information cached. IntrospectionCacheData introspectionCacheData = 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 all-right. The last 'variable' is the method name, and // that is fixed in the template :) if (introspectionCacheData != null && introspectionCacheData.ContextData == c) { velPropertyGet = (IVelPropertyGet)introspectionCacheData.Thingy; } else { // otherwise, do the introspection, and cache it velPropertyGet = runtimeServices.Uberspect.GetPropertyGet(o, identifier, uberInfo); if (velPropertyGet != null && velPropertyGet.Cacheable) { introspectionCacheData = new IntrospectionCacheData(c, velPropertyGet); context.ICachePut(this, introspectionCacheData); } } } catch (Exception e) { runtimeServices.Error(string.Format("ASTIdentifier.execute() : identifier = {0} : {1}", identifier, e)); } // we have no executor... punt... if (velPropertyGet == null) { return(null); } // now try and execute. If we get a TargetInvocationException, // throw that as the app wants to get these. If not, log and punt. try { return(velPropertyGet.Invoke(o)); } catch (TargetInvocationException targetInvocationException) { 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) { // no event cartridge to override. Just throw String message = String.Format( "Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw an exception", velPropertyGet.MethodName, o != null ? o.GetType().FullName : string.Empty, uberInfo.TemplateName, uberInfo.Line, uberInfo.Column); throw new MethodInvocationException(message, targetInvocationException.InnerException, velPropertyGet.MethodName); } else { try { return(ec.HandleMethodException(o.GetType(), velPropertyGet.MethodName, targetInvocationException.InnerException)); } catch (Exception) { String message = String.Format( "Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw an exception", velPropertyGet.MethodName, o != null ? o.GetType().FullName : string.Empty, uberInfo.TemplateName, uberInfo.Line, uberInfo.Column); throw new MethodInvocationException(message, targetInvocationException.InnerException, velPropertyGet.MethodName); } } } catch (ArgumentException) { return(null); } catch (Exception e) { runtimeServices.Error( string.Format("ASTIdentifier() : exception invoking method for identifier '{0}' in {1} : {2}", identifier, o.GetType(), e)); } return(null); }
public override object Execute(object o, IInternalContextAdapter context) { IVelPropertyGet velPropertyGet = null; try { Type type = o.GetType(); IntrospectionCacheData introspectionCacheData = context.ICacheGet(this); if (introspectionCacheData != null && introspectionCacheData.ContextData == type) { velPropertyGet = (IVelPropertyGet)introspectionCacheData.Thingy; } else { velPropertyGet = this.rsvc.Uberspect.GetPropertyGet(o, this.identifier, this.uberInfo); if (velPropertyGet != null && velPropertyGet.Cacheable) { introspectionCacheData = new IntrospectionCacheData(type, velPropertyGet); context.ICachePut(this, introspectionCacheData); } } } catch (System.Exception ex) { this.rsvc.Error(string.Concat(new object[] { "ASTIdentifier.execute() : identifier = ", this.identifier, " : ", ex })); } object result; if (velPropertyGet == null) { result = null; } else { try { result = velPropertyGet.Invoke(o); return(result); } catch (TargetInvocationException ex2) { EventCartridge eventCartridge = context.EventCartridge; string message; if (eventCartridge != null) { try { result = eventCartridge.HandleMethodException(o.GetType(), velPropertyGet.MethodName, ex2.InnerException); return(result); } catch (System.Exception) { message = string.Format("Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw an exception", new object[] { velPropertyGet.MethodName, (o != null) ? o.GetType().FullName : "", this.uberInfo.TemplateName, this.uberInfo.Line, this.uberInfo.Column }); throw new MethodInvocationException(message, ex2.InnerException, velPropertyGet.MethodName); } } message = string.Format("Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw an exception", new object[] { velPropertyGet.MethodName, (o != null) ? o.GetType().FullName : "", this.uberInfo.TemplateName, this.uberInfo.Line, this.uberInfo.Column }); throw new MethodInvocationException(message, ex2.InnerException, velPropertyGet.MethodName); } catch (ArgumentException) { result = null; return(result); } catch (System.Exception ex) { this.rsvc.Error(string.Concat(new object[] { "ASTIdentifier() : exception invoking method for identifier '", this.identifier, "' in ", o.GetType(), " : ", ex })); } result = null; } return(result); }