Exemple #1
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 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.GetBaseException(),
						methodName);
				}
				else
				{
					try
					{
						return eventCartridge.HandleMethodException(o.GetType(), methodName, targetInvocationException.GetBaseException());
					}
					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 e;
			}
		}
        /// <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;
        }
Exemple #3
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 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;
            }
        }
Exemple #4
0
        /// <summary>
        /// returns an Iterator to the collection in the #foreach()
        /// </summary>
        /// <param name="context"> current context </param>
        /// <param name="node">  AST node </param>
        /// <returns>Iterator to do the dataset </returns>
        private IEnumerator GetIterator(IInternalContextAdapter context, INode node)
        {
            // get our list object, and punt if it's null.
            Object listObject = node.GetChild(2).Value(context);

            // if we have an event cartridge, get a new value object
            NVelocity.App.Events.EventCartridge eventCartridge = context.EventCartridge;
            if (eventCartridge != null)
            {
                listObject = eventCartridge.ReferenceInsert(new Stack(), node.GetChild(2).Literal, listObject);
            }

            if (listObject == null)
            {
                return(null);
            }

            // See if we already know what type this is.
            // Use the introspection cache
            EnumType type = EnumType.Unknown;

            IntrospectionCacheData introspectionCacheData = context.ICacheGet(this);
            Type c = listObject.GetType();

            // if we have an entry in the cache, and the Class we have
            // cached is the same as the Class of the data object
            // then we are ok

            if (introspectionCacheData != null && introspectionCacheData.ContextData == c)
            {
                // dig the type out of the data object
                type = ((EnumType)introspectionCacheData.Thingy);
            }

            // If we still don't know what this is,
            // figure out what type of object the list
            // element is, and get the iterator for it
            if (type == EnumType.Unknown)
            {
                if (listObject.GetType().IsArray)
                {
                    type = EnumType.Array;
                }
                else if (listObject is IDictionary)
                {
                    type = EnumType.Dictionary;
                }
                else if (listObject is ICollection)
                {
                    type = EnumType.Collection;
                }
                else if (listObject is IEnumerable)
                {
                    type = EnumType.Enumerable;
                }
                else if (listObject is IEnumerator)
                {
                    type = EnumType.Enumeration;
                }

                // if we did figure it out, cache it
                if (type != EnumType.Unknown)
                {
                    introspectionCacheData = new IntrospectionCacheData(c, type);
                    context.ICachePut(this, introspectionCacheData);
                }
            }

            // now based on the type from either cache or examination...
            switch (type)
            {
            case EnumType.Collection:
                return(((ICollection)listObject).GetEnumerator());

            case EnumType.Enumerable:
                return(((IEnumerable)listObject).GetEnumerator());

            case EnumType.Enumeration:
                runtimeServices.Warn(
                    string.Format(
                        "Warning! The reference {0} is an Enumeration in the #foreach() loop at [{1},{2}] in template {3}. Because it's not resetable, if used in more than once, this may lead to unexpected results.",
                        node.GetChild(2).FirstToken.Image, Line, Column, context.CurrentTemplateName));
                return((IEnumerator)listObject);

            case EnumType.Array:
                return(((Array)listObject).GetEnumerator());

            case EnumType.Dictionary:
                return(((IDictionary)listObject).GetEnumerator());

            default:
                /*  we have no clue what this is  */
                runtimeServices.Warn(
                    string.Format(
                        "Could not determine type of enumerator ({0}) in #foreach loop for {1} at [{2},{3}] in template {4}",
                        listObject.GetType().Name, node.GetChild(2).FirstToken.Image, Line, Column, context.CurrentTemplateName));

                return(null);
            }
        }
Exemple #5
0
        /// <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);
        }
        /// <summary>
        /// returns an Iterator to the collection in the #foreach()
        /// </summary>
        /// <param name="context"> current context </param>
        /// <param name="node">  AST node </param>
        /// <returns>Iterator to do the dataset </returns>
        private IEnumerator GetIterator(IInternalContextAdapter context, INode node)
        {
            // get our list object, and punt if it's null.
            Object listObject = node.GetChild(2).Value(context);

            // if we have an event cartridge, get a new value object
            NVelocity.App.Events.EventCartridge eventCartridge = context.EventCartridge;
            if (eventCartridge != null)
            {
                listObject = eventCartridge.ReferenceInsert(new Stack(), node.GetChild(2).Literal, listObject);
            }

            if (listObject == null)
            {
                return null;
            }

            // See if we already know what type this is. 
            // Use the introspection cache
            EnumType type = EnumType.Unknown;

            IntrospectionCacheData introspectionCacheData = context.ICacheGet(this);
            Type c = listObject.GetType();

            // if we have an entry in the cache, and the Class we have
            // cached is the same as the Class of the data object
            // then we are ok

            if (introspectionCacheData != null && introspectionCacheData.ContextData == c)
            {
                // dig the type out of the data object
                type = ((EnumType)introspectionCacheData.Thingy);
            }

            // If we still don't know what this is, 
            // figure out what type of object the list
            // element is, and get the iterator for it
            if (type == EnumType.Unknown)
            {
                if (listObject.GetType().IsArray)
                {
                    type = EnumType.Array;
                }
                else if (listObject is IDictionary)
                {
                    type = EnumType.Dictionary;
                }
                else if (listObject is ICollection)
                {
                    type = EnumType.Collection;
                }
                else if (listObject is IEnumerable)
                {
                    type = EnumType.Enumerable;
                }
                else if (listObject is IEnumerator)
                {
                    type = EnumType.Enumeration;
                }

                // if we did figure it out, cache it
                if (type != EnumType.Unknown)
                {
                    introspectionCacheData = new IntrospectionCacheData(c, type);
                    context.ICachePut(this, introspectionCacheData);
                }
            }

            // now based on the type from either cache or examination...
            switch (type)
            {
                case EnumType.Collection:
                    return ((ICollection)listObject).GetEnumerator();

                case EnumType.Enumerable:
                    return ((IEnumerable)listObject).GetEnumerator();

                case EnumType.Enumeration:
                    runtimeServices.Warn(
                        string.Format(
                            "Warning! The reference {0} is an Enumeration in the #foreach() loop at [{1},{2}] in template {3}. Because it's not resetable, if used in more than once, this may lead to unexpected results.",
                            node.GetChild(2).FirstToken.Image, Line, Column, context.CurrentTemplateName));
                    return (IEnumerator)listObject;

                case EnumType.Array:
                    return ((Array)listObject).GetEnumerator();

                case EnumType.Dictionary:
                    return ((IDictionary)listObject).GetEnumerator();

                default:
                    /*  we have no clue what this is  */
                    runtimeServices.Warn(
                        string.Format(
                            "Could not determine type of enumerator ({0}) in #foreach loop for {1} at [{2},{3}] in template {4}",
                            listObject.GetType().Name, node.GetChild(2).FirstToken.Image, Line, Column, context.CurrentTemplateName));

                    return null;
            }
        }
 public void ICachePut(Object key, IntrospectionCacheData o)
 {
     innerContext.ICachePut(key, o);
 }
Exemple #8
0
        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)
		{
			if (identifier == "to_quote" && (o.GetType() == typeof(string) ||
			                                 o.GetType().IsPrimitive || o.GetType() == typeof(decimal)))
			{
				return "\"" + EscapeDoubleQuote(o.ToString()) + "\"";
			}
			else if (identifier == "to_squote" && (o.GetType() == typeof(string) ||
			                                       o.GetType().IsPrimitive || o.GetType() == typeof(decimal)))
			{
				return "'" + EscapeSingleQuote(o.ToString()) + "'";
			}

			IDuck duck = o as IDuck;

			if (duck != null)
			{
				return duck.GetInvoke(identifier);
			}

			IVelPropertyGet 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 = (IVelPropertyGet) 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(c, 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 TargetInvocationException, 
			// 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.HandleMethodException(o.GetType(), vg.MethodName, ite.InnerException);
					}
					catch(Exception)
					{
						String message = String.Format(
							"Invocation of method '{0}' in {1}, template {2} Line {3} Column {4} threw an exception",
							vg.MethodName, o != null ? o.GetType().FullName : "",
							uberInfo.TemplateName, uberInfo.Line, uberInfo.Column);

						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 an exception",
						vg.MethodName, o != null ? o.GetType().FullName : "",
						uberInfo.TemplateName, uberInfo.Line, uberInfo.Column);

					throw new MethodInvocationException(message, ite.InnerException, vg.MethodName);
				}
			}
			catch(ArgumentException)
			{
				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
        /// parameters return if the method returns something, or
        /// an empty string "" if the method returns void
        /// </summary>
        /// <param name="instance">
        /// </param>
        /// <param name="context">
        /// </param>
        /// <returns> Result or null.
        /// </returns>
        /// <throws>  MethodInvocationException </throws>
        public override object Execute(object o, IInternalContextAdapter 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.
             */

            IVelMethod method = null;

            object[] params_Renamed = new object[paramCount];

            try
            {
                /*
                 * sadly, we do need recalc the values of the args, as this can
                 * change from visit to visit
                 */

                System.Type[] paramClasses = paramCount > 0 ? new System.Type[paramCount] : new System.Collections.Generic.List <Type>().ToArray();

                for (int j = 0; j < paramCount; j++)
                {
                    params_Renamed[j] = GetChild(j + 1).Value(context);

                    if (params_Renamed[j] != null)
                    {
                        paramClasses[j] = params_Renamed[j].GetType();
                    }
                }

                /*
                 *   check the cache
                 */

                MethodCacheKey         mck = new MethodCacheKey(methodName, paramClasses);
                IntrospectionCacheData icd = context.ICacheGet(mck);

                /*
                 *  like ASTIdentifier, if we have cache information, and the
                 *  Class of Object instance is the same as that in the cache, we are
                 *  safe.
                 */

                if (icd != null && (o != null && icd.ContextData == o.GetType()))
                {
                    /*
                     * Get the method from the cache
                     */

                    method = (IVelMethod)icd.Thingy;
                }
                else
                {
                    /*
                     *  otherwise, do the introspection, and then
                     *  cache it
                     */

                    method = rsvc.Uberspect.GetMethod(o, methodName, params_Renamed, new Info(TemplateName, Line, Column));

                    if ((method != null) && (o != null))
                    {
                        icd             = new IntrospectionCacheData();
                        icd.ContextData = o.GetType();
                        icd.Thingy      = method;

                        context.ICachePut(mck, 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)
                {
                    if (strictRef)
                    {
                        // Create a parameter list for the exception Error message
                        System.Text.StringBuilder plist = new System.Text.StringBuilder();
                        for (int i = 0; i < params_Renamed.Length; i++)
                        {
                            System.Type param = paramClasses[i];

                            plist.Append(param == null ? "null" : param.FullName);
                            if (i < params_Renamed.Length - 1)
                            {
                                plist.Append(", ");
                            }
                        }

                        throw new MethodInvocationException("Object '" + o.GetType().FullName + "' does not contain method " + methodName + "(" + plist + ")", null, methodName, uberInfo.TemplateName, uberInfo.Line, uberInfo.Column);
                    }
                    else
                    {
                        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;
            }

            /**
             * pass through application level runtime exceptions
             */
            catch (System.SystemException e)
            {
                throw e;
            }
            catch (System.Exception e)
            {
                /*
                 *  can come from the doIntropection() also, from Introspector
                 */
                string msg = "ASTMethod.Execute() : exception from introspection";
                log.Error(msg, e);
                throw new VelocityException(msg, e);
            }

            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 = method.Invoke(o, params_Renamed);

                if (obj == null)
                {
                    if (method.ReturnType == System.Type.GetType("System.Void"))
                    {
                        return("");
                    }
                }

                return(obj);
            }
            catch (System.Reflection.TargetInvocationException ite)
            {
                return(HandleInvocationException(o, context, ite.GetBaseException()));
            }
            /** Can also be thrown by method invocation **/
            catch (System.ArgumentException t)
            {
                return(HandleInvocationException(o, context, t));
            }

            /**
             * pass through application level runtime exceptions
             */
            catch (System.SystemException e)
            {
                throw e;
            }
            catch (System.Exception e)
            {
                string msg = "ASTMethod.Execute() : exception invoking method '" + methodName + "' in " + o.GetType();
                log.Error(msg, e);
                throw new VelocityException(msg, e);
            }
        }
Exemple #11
0
 public void ICachePut(object key, IntrospectionCacheData o)
 {
     context.ICachePut(key, o);
 }
Exemple #12
0
        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);
        }
        /// <seealso cref="NVelocity.Runtime.Paser.Node.SimpleNode.Execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter)">
        /// </seealso>
        public override object Execute(object o, IInternalContextAdapter context)
        {
            IVelPropertyGet vg = null;

            try
            {
                /*
                 *  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 && (o != null) && (icd.ContextData == o.GetType()))
                {
                    vg = (IVelPropertyGet)icd.Thingy;
                }
                else
                {
                    /*
                     *  otherwise, do the introspection, and cache it.  Use the
                     *  uberspector
                     */

                    vg = rsvc.Uberspect.GetPropertyGet(o, identifier, uberInfo);

                    if (vg != null && vg.Cacheable && (o != null))
                    {
                        icd             = new IntrospectionCacheData();
                        icd.ContextData = o.GetType();
                        icd.Thingy      = vg;
                        context.ICachePut(this, icd);
                    }
                }
            }

            /**
             * pass through application level runtime exceptions
             */
            catch (System.SystemException e)
            {
                throw e;
            }
            catch (System.Exception e)
            {
                string msg = "ASTIdentifier.Execute() : identifier = " + identifier;
                log.Error(msg, e);
                throw new VelocityException(msg, e);
            }

            /*
             *  we have no getter... punt...
             */

            if (vg == null)
            {
                if (strictRef)
                {
                    throw new MethodInvocationException("Object '" + o.GetType().FullName + "' does not contain property '" + identifier + "'", null, identifier, uberInfo.TemplateName, uberInfo.Line, uberInfo.Column);
                }
                else
                {
                    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 (System.Reflection.TargetInvocationException ite)
            {
                /*
                 *  if we have an event cartridge, see if it wants to veto
                 *  also, let non-Exception Throwables go...
                 */

                System.Exception t = ite.GetBaseException();
                if (t is System.Exception)
                {
                    try
                    {
                        return(EventHandlerUtil.MethodException(rsvc, context, o.GetType(), vg.MethodName, (System.Exception)t));
                    }

                    /**
                     * If the event handler throws an exception, then wrap it
                     * in a MethodInvocationException.  Don't pass through RuntimeExceptions like other
                     * similar catchall code blocks.
                     */
                    catch (System.Exception)
                    {
                        throw new MethodInvocationException("Invocation of method '" + vg.MethodName + "'" + " in  " + o.GetType() + " threw exception " + ite.GetBaseException().ToString(), ite.GetBaseException(), vg.MethodName, TemplateName, this.Line, this.Column);
                    }
                }
                else
                {
                    /*
                     * no event cartridge to override. Just throw
                     */

                    throw new MethodInvocationException("Invocation of method '" + vg.MethodName + "'" + " in  " + o.GetType() + " threw exception " + ite.GetBaseException().ToString(), ite.GetBaseException(), vg.MethodName, TemplateName, this.Line, this.Column);
                }
            }
            catch (System.ArgumentException)
            {
                return(null);
            }

            /**
             * pass through application level runtime exceptions
             */
            catch (System.SystemException e)
            {
                throw e;
            }
            catch (System.Exception e)
            {
                string msg = "ASTIdentifier() : exception invoking method " + "for identifier '" + identifier + "' in " + o.GetType();
                log.Error(msg, e);
                throw new VelocityException(msg, e);
            }
        }
Exemple #14
0
        private IEnumerator GetIterator(IInternalContextAdapter context, INode node)
        {
            object      obj = node.GetChild(2).Value(context);
            IEnumerator result;

            if (obj == null)
            {
                result = null;
            }
            else
            {
                Foreach.EnumType       enumType = Foreach.EnumType.Unknown;
                IntrospectionCacheData introspectionCacheData = context.ICacheGet(this);
                Type type = obj.GetType();
                if (introspectionCacheData != null && introspectionCacheData.ContextData == type)
                {
                    enumType = (Foreach.EnumType)introspectionCacheData.Thingy;
                }
                if (enumType == Foreach.EnumType.Unknown)
                {
                    if (obj.GetType().IsArray)
                    {
                        enumType = Foreach.EnumType.Array;
                    }
                    else if (obj is IDictionary)
                    {
                        enumType = Foreach.EnumType.Dictionary;
                    }
                    else if (obj is ICollection)
                    {
                        enumType = Foreach.EnumType.Collection;
                    }
                    else if (obj is IEnumerable)
                    {
                        enumType = Foreach.EnumType.Enumerable;
                    }
                    else if (obj is IEnumerator)
                    {
                        enumType = Foreach.EnumType.Enumeration;
                    }
                    if (enumType != Foreach.EnumType.Unknown)
                    {
                        introspectionCacheData = new IntrospectionCacheData(type, enumType);
                        context.ICachePut(this, introspectionCacheData);
                    }
                }
                switch (enumType)
                {
                case Foreach.EnumType.Array:
                    result = ((Array)obj).GetEnumerator();
                    return(result);

                case Foreach.EnumType.Dictionary:
                    result = ((IDictionary)obj).GetEnumerator();
                    return(result);

                case Foreach.EnumType.Collection:
                    result = ((ICollection)obj).GetEnumerator();
                    return(result);

                case Foreach.EnumType.Enumeration:
                    this.rsvc.Warn(string.Concat(new object[]
                    {
                        "Warning! The reference ",
                        node.GetChild(2).FirstToken.Image,
                        " is an Enumeration in the #foreach() loop at [",
                        base.Line,
                        ",",
                        base.Column,
                        "] in template ",
                        context.CurrentTemplateName,
                        ". Because it's not resetable, if used in more than once, this may lead to unexpected results."
                    }));
                    result = (IEnumerator)obj;
                    return(result);

                case Foreach.EnumType.Enumerable:
                    result = ((IEnumerable)obj).GetEnumerator();
                    return(result);
                }
                this.rsvc.Warn(string.Concat(new object[]
                {
                    "Could not determine type of enumerator (",
                    obj.GetType().Name,
                    ") in #foreach loop for ",
                    node.GetChild(2).FirstToken.Image,
                    " at [",
                    base.Line,
                    ",",
                    base.Column,
                    "] in template ",
                    context.CurrentTemplateName
                }));
                result = null;
            }
            return(result);
        }
Exemple #15
0
		/// <summary>
		/// returns an Iterator to the collection in the #foreach()
		/// </summary>
		/// <param name="context"> current context </param>
		/// <param name="node">  AST node </param>
		/// <returns>Iterator to do the dataset </returns>
		private IEnumerator GetIterator(IInternalContextAdapter context, INode node)
		{
			// get our list object, and punt if it's null.
			Object listObject = node.GetChild(2).Value(context);

			if (listObject == null)
				return null;

			// See if we already know what type this is. 
			// Use the introspection cache
			EnumType type = EnumType.Unknown;

			IntrospectionCacheData icd = context.ICacheGet(this);
			Type c = listObject.GetType();

			// if we have an entry in the cache, and the Class we have
			// cached is the same as the Class of the data object
			// then we are ok

			if (icd != null && icd.ContextData == c)
			{
				// dig the type out of the cata object
				type = ((EnumType) icd.Thingy);
			}

			// If we still don't know what this is, 
			// figure out what type of object the list
			// element is, and get the iterator for it
			if (type == EnumType.Unknown)
			{
				if (listObject.GetType().IsArray)
					type = EnumType.Array;
				else if (listObject is IDictionary)
					type = EnumType.Dictionary;
				else if (listObject is ICollection)
					type = EnumType.Collection;
				else if (listObject is IEnumerable)
					type = EnumType.Enumerable;
				else if (listObject is IEnumerator)
					type = EnumType.Enumeration;

				// if we did figure it out, cache it
				if (type != EnumType.Unknown)
				{
					icd = new IntrospectionCacheData(c, type);
					context.ICachePut(this, icd);
				}
			}

			// now based on the type from either cache or examination...
			switch(type)
			{
				case EnumType.Collection:
					return ((ICollection) listObject).GetEnumerator();

				case EnumType.Enumerable:
					return ((IEnumerable) listObject).GetEnumerator();

				case EnumType.Enumeration:
					rsvc.Warn("Warning! The reference " + node.GetChild(2).FirstToken.Image +
					          " is an Enumeration in the #foreach() loop at [" + Line + "," + Column + "]" + " in template " +
					          context.CurrentTemplateName + ". Because it's not resetable," +
					          " if used in more than once, this may lead to" + " unexpected results.");
					return (IEnumerator) listObject;

				case EnumType.Array:
					return ((Array) listObject).GetEnumerator();

				case EnumType.Dictionary:
					return ((IDictionary) listObject).GetEnumerator();

				default:
					/*  we have no clue what this is  */
					rsvc.Warn("Could not determine type of enumerator (" + listObject.GetType().Name + ") in " + "#foreach loop for " +
					          node.GetChild(2).FirstToken.Image + " at [" + Line + "," + Column + "]" + " in template " +
					          context.CurrentTemplateName);

					return null;
			}
		}