示例#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);
        }
示例#2
0
            internal void parseTree(IInternalContextAdapter internalContextAdapter)
            {
                try
                {
                    //UPGRADE_ISSUE: The equivalent of constructor 'java.io.BufferedReader.BufferedReader' is incompatible with the expected type in C#. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1109"'
                    TextReader br = new StringReader(macroBody);

                    nodeTree = Enclosing_Instance.runtimeServices.Parse(br, string.Format("VM:{0}", macroName), true);
                    nodeTree.Init(internalContextAdapter, null);
                }
                catch (System.Exception e)
                {
                    Enclosing_Instance.runtimeServices.Error(
                        string.Format("VelocimacroManager.parseTree() : exception {0} : {1}", macroName, e));
                }
            }
        /// <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);
        }
示例#4
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);
        }
示例#5
0
        /// <summary>  does the housekeeping upon creating.  If a dynamic type
        /// it needs to make an AST for further get()/set() operations
        /// Anything else is constant.
        /// </summary>
        private void setup()
        {
            switch (type)
            {
            case ParserTreeConstants.INTEGER_RANGE:
            case ParserTreeConstants.REFERENCE:
            case ParserTreeConstants.OBJECT_ARRAY:
            case ParserTreeConstants.STRING_LITERAL:
            case ParserTreeConstants.TEXT:
            {
                /*
                 *  dynamic types, just render
                 */

                constant = false;

                try
                {
                    /*
                     *  fakie : wrap in  directive to get the parser to treat our args as args
                     *   it doesn't matter that #include() can't take all these types, because we
                     *   just want the parser to consider our arg as a Directive/VM arg rather than
                     *   as if inline in schmoo
                     */

                    String buff = string.Format("#include({0} ) ", callerReference);

                    //ByteArrayInputStream inStream = new ByteArrayInputStream( buff.getBytes() );

                    //UPGRADE_ISSUE: The equivalent of constructor 'java.io.BufferedReader.BufferedReader' is incompatible with the expected type in C#. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1109"'
                    TextReader br = new StringReader(buff);

                    nodeTree = runtimeServices.Parse(br, string.Format("VMProxyArg:{0}", callerReference), true);

                    /*
                     *  now, our tree really is the first DirectiveArg(), and only one
                     */

                    nodeTree = (SimpleNode)nodeTree.GetChild(0).GetChild(0);

                    /*
                     * sanity check
                     */

                    if (nodeTree != null && nodeTree.Type != type)
                    {
                        runtimeServices.Error("VMProxyArg.setup() : programmer error : type doesn't match node type.");
                    }

                    /*
                     *  init.  We can do this as they are only references
                     */

                    nodeTree.Init(null, runtimeServices);
                }
                catch (System.Exception e)
                {
                    runtimeServices.Error(string.Format("VMProxyArg.setup() : exception {0} : {1}", callerReference, e));
                }

                break;
            }

            case ParserTreeConstants.TRUE:
            {
                constant     = true;
                staticObject = true;
                break;
            }

            case ParserTreeConstants.FALSE:
            {
                constant     = true;
                staticObject = false;
                break;
            }

            case ParserTreeConstants.NUMBER_LITERAL:
            {
                constant     = true;
                staticObject = Int32.Parse(callerReference);
                break;
            }

            case ParserTreeConstants.WORD:
            {
                /*
                 *  this is technically an error...
                 */

                runtimeServices.Error(
                    string.Format(
                        "Unsupported arg type : {0}  You most likely intended to call a VM with a string literal, so enclose with ' or \" characters. (VMProxyArg.setup())",
                        callerReference));
                constant     = true;
                staticObject = new String(callerReference.ToCharArray());

                break;
            }

            default:
            {
                runtimeServices.Error(string.Format(" VMProxyArg.setup() : unsupported type : {0}", callerReference));
            }
            break;
            }
        }
示例#6
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> The major meat of VelocimacroProxy, Init() checks the # of arguments.
        ///
        /// </summary>
        /// <param name="rs">
        /// </param>
        /// <param name="context">
        /// </param>
        /// <param name="node">
        /// </param>
        /// <throws>  TemplateInitException </throws>
        public override void Init(IRuntimeServices rs, IInternalContextAdapter context, INode node)
        {
            // there can be multiple threads here so avoid double inits
            lock (this)
            {
                if (!preInit)
                {
                    base.Init(rs, context, node);

                    // this is a very expensive call (ExtendedProperties is very slow)
                    strictArguments = rs.Configuration.GetBoolean(NVelocity.Runtime.RuntimeConstants.VM_ARGUMENTS_STRICT, false);

                    // support for local context scope feature, where all references are local
                    // we do not have to check this at every invocation of ProxyVMContext
                    localContextScope = rsvc.GetBoolean(NVelocity.Runtime.RuntimeConstants.VM_CONTEXT_LOCALSCOPE, false);

                    // Get the macro call depth limit
                    maxCallDepth = rsvc.GetInt(NVelocity.Runtime.RuntimeConstants.VM_MAX_DEPTH);

                    // Initialize the parsed AST
                    // since this is context independent we need to do this only once so
                    // do it here instead of the render method
                    nodeTree.Init(context, rs);

                    preInit = true;
                }
            }

            // check how many arguments we got
            int i = node.GetNumChildren();

            // Throw exception for invalid number of arguments?
            if (NumArgs != i)
            {
                // If we have a not-yet defined macro, we do Get no arguments because
                // the syntax tree looks different than with a already defined macro.
                // But we do know that we must be in a macro definition context somewhere up the
                // syntax tree.
                // Check for that, if it is true, suppress the Error message.
                // Fixes VELOCITY-71.

                for (INode parent = node.Parent; parent != null;)
                {
                    if ((parent is ASTDirective) && string.Equals(((ASTDirective)parent).DirectiveName, "macro"))
                    {
                        return;
                    }
                    parent = parent.Parent;
                }

                string msg = "VM #" + macroName + ": too " + ((NumArgs > i) ? "few" : "many") + " arguments to macro. Wanted " + NumArgs + " got " + i;

                if (strictArguments)
                {
                    /**
                     * indicate col/line assuming it starts at 0 - this will be corrected one call up
                     */
                    throw new TemplateInitException(msg, context.CurrentTemplateName, 0, 0);
                }
                else
                {
                    rsvc.Log.Debug(msg);
                    return;
                }
            }

            /* now validate that none of the arguments are plain words, (VELOCITY-614)
             * they should be string literals, references, inline maps, or inline lists */
            for (int n = 0; n < i; n++)
            {
                INode child = node.GetChild(n);
                if (child.Type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTWORD)
                {
                    /* indicate col/line assuming it starts at 0
                     * this will be corrected one call up  */
                    throw new TemplateInitException("Invalid arg #" + n + " in VM #" + macroName, context.CurrentTemplateName, 0, 0);
                }
            }
        }