示例#1
0
        public bool Evaluate(IContext context, TextWriter writer, string logTag, TextReader reader)
        {
            SimpleNode simpleNode = null;

            try
            {
                simpleNode = this.ri.Parse(reader, logTag);
            }
            catch (ParseException ex)
            {
                throw new ParseErrorException(ex.Message, ex);
            }
            bool result;

            if (simpleNode != null)
            {
                InternalContextAdapterImpl internalContextAdapterImpl = new InternalContextAdapterImpl(context);
                internalContextAdapterImpl.PushCurrentTemplateName(logTag);
                try
                {
                    try
                    {
                        simpleNode.Init(internalContextAdapterImpl, this.ri);
                    }
                    catch (System.Exception ex2)
                    {
                        this.ri.Error(string.Concat(new object[]
                        {
                            "Velocity.evaluate() : init exception for tag = ",
                            logTag,
                            " : ",
                            ex2
                        }));
                    }
                    simpleNode.Render(internalContextAdapterImpl, writer);
                }
                finally
                {
                    internalContextAdapterImpl.PopCurrentTemplateName();
                }
                result = true;
            }
            else
            {
                result = false;
            }
            return(result);
        }
        /// <summary>
        /// Renders the macro using the context
        /// </summary>
        public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node)
        {
            try
            {
                // it's possible the tree hasn't been parsed yet, so get
                // the VMManager to parse and init it
                if (nodeTree == null)
                {
                    runtimeServices.Error(string.Format("VM error : {0}. Null AST", macroName));
                }
                else
                {
                    if (!init)
                    {
                        nodeTree.Init(context, runtimeServices);
                        init = true;
                    }

                    // wrap the current context and add the VMProxyArg objects
                    VMContext vmContext = new VMContext(context, runtimeServices);

                    for (int i = 1; i < argArray.Length; i++)
                    {
                        // we can do this as VMProxyArgs don't change state. They change
                        // the context.
                        VMProxyArg arg = (VMProxyArg)proxyArgHash[argArray[i]];
                        vmContext.AddVMProxyArg(arg);
                    }

                    // now render the VM
                    nodeTree.Render(vmContext, writer);
                }
            }
            catch (Exception e)
            {
                // if it's a MIE, it came from the render.... throw it...
                if (e is MethodInvocationException)
                {
                    throw;
                }

                runtimeServices.Error(string.Format("VelocimacroProxy.render() : exception VM = #{0}() : {1}", macroName, e));
            }

            return(true);
        }
示例#3
0
        /// <summary>
        /// Renders the input reader using the context into the output writer.
        /// To be used when a template is dynamically constructed, or want to
        /// use Velocity as a token replacer.
        /// </summary>
        /// <param name="context">context to use in rendering input string</param>
        /// <param name="writer"> Writer in which to render the output</param>
        /// <param name="logTag"> string to be used as the template name for log messages in case of error</param>
        /// <param name="reader">Reader containing the VTL to be rendered</param>
        /// <returns>true if successful, false otherwise.  If false, see Velocity runtime log</returns>
        public static bool Evaluate(IContext context, TextWriter writer, String logTag, TextReader reader)
        {
            SimpleNode nodeTree = null;

            try
            {
                nodeTree = RuntimeSingleton.Parse(reader, logTag);
            }
            catch (ParseException parseException)
            {
                throw new ParseErrorException(parseException.Message, parseException);
            }

            // now we want to init and render
            if (nodeTree != null)
            {
                InternalContextAdapterImpl internalContextAdapterImpl = new InternalContextAdapterImpl(context);

                internalContextAdapterImpl.PushCurrentTemplateName(logTag);

                try
                {
                    try
                    {
                        nodeTree.Init(internalContextAdapterImpl, RuntimeSingleton.RuntimeServices);
                    }
                    catch (Exception exception)
                    {
                        RuntimeSingleton.Error(
                            string.Format("Velocity.evaluate() : init exception for tag = {0} : {1}", logTag, exception));
                    }

                    // now render, and let any exceptions fly
                    nodeTree.Render(internalContextAdapterImpl, writer);
                }
                finally
                {
                    internalContextAdapterImpl.PopCurrentTemplateName();
                }

                return(true);
            }

            return(false);
        }
示例#4
0
        /// <summary>  returns the value of the reference.  Generally, this is only
        /// called for dynamic proxies, as the static ones should have
        /// been stored in the VMContext's localContext store
        /// *
        /// </summary>
        /// <param name="context">Context to use for getting current value
        /// </param>
        /// <returns>Object value
        /// *
        ///
        /// </returns>
        public Object getObject(IInternalContextAdapter context)
        {
            try
            {
                /*
                 *  we need to output based on our type
                 */

                Object retObject = null;

                if (type == ParserTreeConstants.REFERENCE)
                {
                    /*
                     *  two cases :  scalar reference ($foo) or multi-level ($foo.bar....)
                     */

                    if (numTreeChildren == 0)
                    {
                        /*
                         *  if I am a single-level reference, can I not get get it out of my context?
                         */

                        retObject = context.Get(singleLevelRef);
                    }
                    else
                    {
                        /*
                         *  I need to let the AST produce it for me.
                         */

                        retObject = nodeTree.Execute(null, context);
                    }
                }
                else if (type == ParserTreeConstants.OBJECT_ARRAY)
                {
                    retObject = nodeTree.Value(context);
                }
                else if (type == ParserTreeConstants.INTEGER_RANGE)
                {
                    retObject = nodeTree.Value(context);
                }
                else if (type == ParserTreeConstants.TRUE)
                {
                    retObject = staticObject;
                }
                else if (type == ParserTreeConstants.FALSE)
                {
                    retObject = staticObject;
                }
                else if (type == ParserTreeConstants.STRING_LITERAL)
                {
                    retObject = nodeTree.Value(context);
                }
                else if (type == ParserTreeConstants.NUMBER_LITERAL)
                {
                    retObject = staticObject;
                }
                else if (type == ParserTreeConstants.TEXT)
                {
                    /*
                     *  this really shouldn't happen.  text is just a throwaway arg for #foreach()
                     */

                    try
                    {
                        StringWriter writer = new StringWriter();
                        nodeTree.Render(context, writer);

                        retObject = writer;
                    }
                    catch (System.Exception e)
                    {
                        runtimeServices.Error(string.Format("VMProxyArg.getObject() : error rendering reference : {0}", e));
                    }
                }
                else if (type == GENERALSTATIC)
                {
                    retObject = staticObject;
                }
                else
                {
                    runtimeServices.Error(
                        string.Format("Unsupported VM arg type : VM arg = {0} type = {1}( VMProxyArg.getObject() )", callerReference, type));
                }

                return(retObject);
            }
            catch (MethodInvocationException mie)
            {
                /*
                 *  not ideal, but otherwise we propagate out to the
                 *  VMContext, and the Context interface's put/get
                 *  don't throw. So this is a the best compromise
                 *  I can think of
                 */

                runtimeServices.Error(string.Format("VMProxyArg.getObject() : method invocation error getting value : {0}", mie));

                return(null);
            }
        }
示例#5
0
        /// <summary> Evaluate the argument, convert to a String, and Evaluate again
        /// (with the same context).
        /// </summary>
        /// <param name="context">
        /// </param>
        /// <param name="writer">
        /// </param>
        /// <param name="node">
        /// </param>
        /// <returns> True if the directive rendered successfully.
        /// </returns>
        /// <throws>  IOException </throws>
        /// <throws>  ResourceNotFoundException </throws>
        /// <throws>  ParseErrorException  </throws>
        /// <throws>  MethodInvocationException </throws>
        public override bool Render(IInternalContextAdapter context, System.IO.TextWriter writer, INode node)
        {
            /*
             * Evaluate the string with the current context.  We know there is
             * exactly one argument and it is a string or reference.
             */

            object value = node.GetChild(0).Value(context);
            string sourceText;

            if (value != null)
            {
                sourceText = value.ToString();
            }
            else
            {
                sourceText = "";
            }

            /*
             * The new string needs to be parsed since the text has been dynamically generated.
             */
            string     templateName = context.CurrentTemplateName;
            SimpleNode nodeTree     = null;

            try
            {
                nodeTree = rsvc.Parse(new StringReader(sourceText), templateName, false);
            }
            catch (ParseException pex)
            {
                // use the line/column from the template
                Info info = new Info(templateName, node.Line, node.Column);

                throw new ParseErrorException(pex.Message, info);
            }
            catch (TemplateInitException pex)
            {
                Info info = new Info(templateName, node.Line, node.Column);

                throw new ParseErrorException(pex.Message, info);
            }

            /*
             * now we want to Init and render.  Chain the context
             * to prevent any changes to the current context.
             */

            if (nodeTree != null)
            {
                IInternalContextAdapter ica = new EvaluateContext(context, rsvc);

                ica.PushCurrentTemplateName(templateName);

                try
                {
                    try
                    {
                        nodeTree.Init(ica, rsvc);
                    }
                    catch (TemplateInitException pex)
                    {
                        Info info = new Info(templateName, node.Line, node.Column);

                        throw new ParseErrorException(pex.Message, info);
                    }

                    try
                    {
                        /*
                         *  now render, and let any exceptions fly
                         */
                        nodeTree.Render(ica, writer);
                    }
                    catch (ParseErrorException pex)
                    {
                        // convert any parsing errors to the correct line/col
                        Info info = new Info(templateName, node.Line, node.Column);

                        throw new ParseErrorException(pex.Message, info);
                    }
                }
                finally
                {
                    ica.PopCurrentTemplateName();
                }

                return(true);
            }


            return(false);
        }
        /// <summary> Renders the macro using the context.
        ///
        /// </summary>
        /// <param name="context">Current rendering context
        /// </param>
        /// <param name="writer">Writer for output
        /// </param>
        /// <param name="node">AST that calls the macro
        /// </param>
        /// <returns> True if the directive rendered successfully.
        /// </returns>
        /// <throws>  IOException </throws>
        /// <throws>  MethodInvocationException </throws>
        /// <throws>  MacroOverflowException </throws>
        public override bool Render(IInternalContextAdapter context, System.IO.TextWriter writer, INode node)
        {
            // wrap the current context and Add the macro arguments

            // the creation of this context is a major bottleneck (incl 2x HashMap)
            //UPGRADE_NOTE: Final 已从“vmc ”的声明中移除。 "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
            ProxyVMContext vmc = new ProxyVMContext(context, rsvc, localContextScope);

            int callArguments = node.GetNumChildren();

            if (callArguments > 0)
            {
                // the 0th element is the macro name
                for (int i = 1; i < argArray.Length && i <= callArguments; i++)
                {
                    INode macroCallArgument = node.GetChild(i - 1);

                    /*
                     * literalArgArray[i] is needed for "render literal if null" functionality.
                     * The value is used in ASTReference render-method.
                     *
                     * The idea is to avoid generating the literal until absolutely necessary.
                     *
                     * This makes VMReferenceMungeVisitor obsolete and it would not work anyway
                     * when the macro AST is shared
                     */
                    vmc.AddVMProxyArg(context, argArray[i], literalArgArray[i], macroCallArgument);
                }
            }

            /*
             * check that we aren't already at the max call depth
             */
            if (maxCallDepth > 0 && maxCallDepth == vmc.CurrentMacroCallDepth)
            {
                string   templateName = vmc.CurrentTemplateName;
                object[] stack        = vmc.MacroNameStack;

                System.Text.StringBuilder out_Renamed = new System.Text.StringBuilder(100).Append("Max calling depth of ").Append(maxCallDepth).Append(" was exceeded in Template:").Append(templateName).Append(" and Macro:").Append(macroName).Append(" with Call Stack:");
                for (int i = 0; i < stack.Length; i++)
                {
                    if (i != 0)
                    {
                        out_Renamed.Append("->");
                    }

                    out_Renamed.Append(stack[i]);
                }
                rsvc.Log.Error(out_Renamed);

                try
                {
                    throw new MacroOverflowException(out_Renamed.ToString());
                }
                finally
                {
                    // clean out the macro stack, since we just broke it
                    while (vmc.CurrentMacroCallDepth > 0)
                    {
                        vmc.PopCurrentMacroName();
                    }
                }
            }

            try
            {
                // render the velocity macro
                vmc.PushCurrentMacroName(macroName);
                nodeTree.Render(vmc, writer);
                vmc.PopCurrentMacroName();
                return(true);
            }
            catch (System.SystemException e)
            {
                throw e;
            }
            catch (System.Exception e)
            {
                string msg = "VelocimacroProxy.render() : exception VM = #" + macroName + "()";
                rsvc.Log.Error(msg, e);
                throw new VelocityException(msg, e);
            }
        }