예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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);
            }
        }
예제 #3
0
        /// <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;
            }
        }