/// <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="out"> 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 pex) { throw new ParseErrorException(pex.Message); } /* * now we want to init and render */ if (nodeTree != null) { InternalContextAdapterImpl ica = new InternalContextAdapterImpl(context); ica.PushCurrentTemplateName(logTag); try { try { nodeTree.init(ica, RuntimeSingleton.RuntimeServices); } catch (Exception e) { RuntimeSingleton.error("Velocity.evaluate() : init exception for tag = " + logTag + " : " + e); } /* * now render, and let any exceptions fly */ nodeTree.render(ica, writer); } finally { ica.PopCurrentTemplateName(); } return(true); } return(false); }
internal void parseTree(InternalContextAdapter ica) { 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.rsvc.parse(br, "VM:" + macroname, true); nodeTree.init(ica, null); } catch (System.Exception e) { Enclosing_Instance.rsvc.error("VelocimacroManager.parseTree() : exception " + macroname + " : " + StringUtils.stackTrace(e)); } }
/// <summary> Return name of this Velocimacro. /// </summary> /// <summary> Velocimacros are always LINE /// type directives. /// </summary> /// <summary> sets the directive name of this VM /// </summary> /// <summary> sets the array of arguments specified in the macro definition /// </summary> /// <summary> returns the number of ars needed for this VM /// </summary> /// <summary> Sets the orignal macro body. This is simply the cat of the macroArray, but the /// Macro object creates this once during parsing, and everyone shares it. /// Note : it must not be modified. /// </summary> /// <summary> Renders the macro using the context /// </summary> public override bool render(InternalContextAdapter 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) { if (!init_Renamed_Field) { nodeTree.init(context, rsvc); init_Renamed_Field = true; } /* * wrap the current context and add the VMProxyArg objects */ VMContext vmc = new VMContext(context, rsvc); 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]]; vmc.AddVMProxyArg(arg); } /* * now render the VM */ nodeTree.render(vmc, writer); } else { rsvc.error("VM error : " + macroName + ". Null AST"); } } catch (Exception e) { /* * if it's a MIE, it came from the render.... throw it... */ if (e is MethodInvocationException) { throw (MethodInvocationException)e; } rsvc.error("VelocimacroProxy.render() : exception VM = #" + macroName + "() : " + StringUtils.stackTrace(e)); } return(true); }
/// <summary> does the housekeeping upon creationg. 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.JJTINTEGERRANGE: case ParserTreeConstants.JJTREFERENCE: case ParserTreeConstants.JJTOBJECTARRAY: case ParserTreeConstants.JJTSTRINGLITERAL: case ParserTreeConstants.JJTTEXT: { /* * 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 = "#include(" + 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 = rsvc.parse(br, "VMProxyArg:" + callerReference, true); /* * now, our tree really is the first DirectiveArg(), and only one */ nodeTree = (SimpleNode)nodeTree.jjtGetChild(0).jjtGetChild(0); /* * sanity check */ if (nodeTree != null && nodeTree.Type != type) { rsvc.error("VMProxyArg.setup() : programmer error : type doesn't match node type."); } /* * init. We can do this as they are only references */ nodeTree.init(null, rsvc); } catch (Exception e) { rsvc.error("VMProxyArg.setup() : exception " + callerReference + " : " + StringUtils.stackTrace(e)); } break; } case ParserTreeConstants.JJTTRUE: { constant = true; staticObject = true; break; } case ParserTreeConstants.JJTFALSE: { constant = true; staticObject = false; break; } case ParserTreeConstants.JJTNUMBERLITERAL: { constant = true; staticObject = Int32.Parse(callerReference); break; } case ParserTreeConstants.JJTWORD: { /* * this is technically an error... */ rsvc.error("Unsupported arg type : " + callerReference + " You most likely intended to call a VM with a string literal, so enclose with ' or \" characters. (VMProxyArg.setup())"); constant = true; staticObject = new String(callerReference.ToCharArray()); break; } default: { rsvc.error(" VMProxyArg.setup() : unsupported type : " + callerReference); } break; } }