/// <summary> the logical or : /// the rule : /// left || null -> left /// null || right -> right /// null || null -> false /// left || right -> left || right /// </summary> public override bool evaluate(InternalContextAdapter context) { INode left = jjtGetChild(0); INode right = jjtGetChild(1); /* * if the left is not null and true, then true */ if (left != null && left.evaluate(context)) { return(true); } /* * same for right */ if (right != null && right.evaluate(context)) { return(true); } return(false); }
/* * CODE FOR ALTERNATE IMPL : please ignore. I will remove when confortable with current. */ /// <summary> not used in current impl /// * /// Constructor for alternate impl where VelProxy class would make new /// VMProxyArg objects, and use this contructor to avoid reparsing the /// reference args /// * /// that impl also had the VMProxyArg carry it's context /// </summary> public VMProxyArg(VMProxyArg model, InternalContextAdapter c) { usercontext = c; contextReference = model.ContextReference; callerReference = model.CallerReference; nodeTree = model.NodeTree; staticObject = model.StaticObject; type = model.Type; if (nodeTree != null) { numTreeChildren = nodeTree.jjtGetNumChildren(); } if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTREFERENCE) { if (numTreeChildren == 0) { /* * use the reference node to do this... */ singleLevelRef = ((ASTReference)nodeTree).RootString; } } }
/// <summary> The major meat of VelocimacroProxy, init() checks the # of arguments, patches the /// macro body, renders the macro into an AST, and then inits the AST, so it is ready /// for quick rendering. Note that this is only AST dependant stuff. Not context. /// </summary> public override void init(RuntimeServices rs, InternalContextAdapter context, INode node) { base.init(rs, context, node); /* * how many args did we get? */ int i = node.jjtGetNumChildren(); /* * right number of args? */ if (NumArgs != i) { rsvc.error("VM #" + macroName + ": error : too " + ((NumArgs > i) ? "few" : "many") + " arguments to macro. Wanted " + NumArgs + " got " + i); return; } /* * get the argument list to the instance use of the VM */ callingArgs = getArgArray(node); /* * now proxy each arg in the context */ setupMacro(callingArgs, callingArgTypes); return; }
/// <summary> computes the product of the two args. Returns null if either arg is null /// or if either arg is not an integer /// </summary> public override Object Value(InternalContextAdapter context) { /* * get the two args */ Object left = jjtGetChild(0).Value(context); Object right = jjtGetChild(1).Value(context); /* * if either is null, lets log and bail */ if (left == null || right == null) { rsvc.error((left == null ? "Left" : "Right") + " side (" + jjtGetChild((left == null ? 0 : 1)).literal() + ") of multiplication operation has null value." + " Operation not possible. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return(null); } /* * if not an Integer, not much we can do either */ if (!(left is Int32) || !(right is Int32)) { rsvc.error((!(left is Int32) ? "Left" : "Right") + " side of multiplication operation is not a valid type. " + "Currently only integers (1,2,3...) and Integer type is supported. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return(null); } return(((Int32)left) * ((Int32)right)); }
/// <summary> Calculates the value of the logical expression /// * /// arg1 == arg2 /// * /// All class types are supported. Uses equals() to /// determine equivalence. This should work as we represent /// with the types we already support, and anything else that /// implements equals() to mean more than identical references. /// * /// * /// </summary> /// <param name="context"> internal context used to evaluate the LHS and RHS /// </param> /// <returns>true if equivalent, false if not equivalent, /// false if not compatible arguments, or false /// if either LHS or RHS is null /// /// </returns> public override bool evaluate(InternalContextAdapter context) { Object left = jjtGetChild(0).Value(context); Object right = jjtGetChild(1).Value(context); /* * for equality, they are allowed to be null references */ try { if (ObjectComparer.CompareObjects(left, right) == 0) { return(true); } } catch { // Ignore, we can't compare decently by value, but we honestly don't give a sh*t } // They are not equal by value, try a reference comparison // reference equal => definitely equal objects ;) // For operator overloaded types, this will not really be a reference comp, but that's ok. return(left == right); }
public override bool evaluate(InternalContextAdapter context) { /* * get the two args */ Object left = jjtGetChild(0).Value(context); Object right = jjtGetChild(1).Value(context); /* * if either is null, lets log and bail */ if (left == null || right == null) { rsvc.error((left == null ? "Left" : "Right") + " side (" + jjtGetChild((left == null ? 0 : 1)).literal() + ") of '<=' operation has null value." + " Operation not possible. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return(false); } try { return(ObjectComparer.CompareObjects(left, right) <= 0); } catch (ArgumentException ae) { rsvc.error(ae.Message); return(false); } }
public override Object init(InternalContextAdapter context, Object data) { /* * init our children */ base.init(context, data); /* * the only thing we can do in init() is getRoot() * as that is template based, not context based, * so it's thread- and context-safe */ rootString = Root; numChildren = jjtGetNumChildren(); /* * and if appropriate... */ if (numChildren > 0) { identifier = jjtGetChild(numChildren - 1).FirstToken.image; } return(data); }
/// <summary> Return name of this directive. /// </summary> /// <summary> Return type of this directive. /// </summary> /// <summary> render() doesn't do anything in the final output rendering. /// There is no output from a #macro() directive. /// </summary> public override bool render(InternalContextAdapter context, TextWriter writer, Node node) { /* * do nothing : We never render. The VelocimacroProxy object does that */ return(true); }
/// <summary> logical and : /// null && right = false /// left && null = false /// null && null = false /// </summary> public override bool evaluate(InternalContextAdapter context) { INode left = jjtGetChild(0); INode right = jjtGetChild(1); /* * if either is null, lets log and bail */ if (left == null || right == null) { rsvc.error((left == null ? "Left" : "Right") + " side of '&&' operation is null." + " Operation not possible. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return(false); } /* * short circuit the test. Don't eval the RHS if the LHS is false */ if (left.evaluate(context)) { if (right.evaluate(context)) { return(true); } } return(false); }
/// <summary> iterates through the argument list and renders every /// argument that is appropriate. Any non appropriate /// arguments are logged, but render() continues. /// </summary> public override bool render(InternalContextAdapter context, TextWriter writer, INode node) { /* * get our arguments and check them */ int argCount = node.jjtGetNumChildren(); for (int i = 0; i < argCount; i++) { /* * we only handle StringLiterals and References right now */ INode n = node.jjtGetChild(i); if (n.Type == ParserTreeConstants.JJTSTRINGLITERAL || n.Type == ParserTreeConstants.JJTREFERENCE) { if (!renderOutput(n, context, writer)) { outputErrorToStream(writer, "error with arg " + i + " please see log."); } } else { //UPGRADE_TODO: The equivalent in .NET for method 'java.Object.toString' may return a different value. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1043"' rsvc.error("#include() error : invalid argument type : " + n.ToString()); outputErrorToStream(writer, "error with arg " + i + " please see log."); } } return(true); }
/// <summary> init : we don't have to do much. Init the tree (there /// shouldn't be one) and then see if interpolation is turned on. /// </summary> public override Object init(InternalContextAdapter context, Object data) { /* * simple habit... we prollie don't have an AST beneath us */ base.init(context, data); /* * the stringlit is set at template parse time, so we can * do this here for now. if things change and we can somehow * create stringlits at runtime, this must * move to the runtime execution path * * so, only if interpolation is turned on AND it starts * with a " AND it has a directive or reference, then we * can interpolate. Otherwise, don't bother. */ interpolate = rsvc.getBoolean(RuntimeConstants_Fields.INTERPOLATE_STRINGLITERALS, true) && FirstToken.image.StartsWith("\"") && ((FirstToken.image.IndexOf((Char)'$') != -1) || (FirstToken.image.IndexOf((Char)'#') != -1)); /* * get the contents of the string, minus the '/" at each end */ image = FirstToken.image.Substring(1, (FirstToken.image.Length - 1) - (1)); /* * tack a space on the end (dreaded <MORE> kludge) */ interpolateimage = image + " "; if (interpolate) { /* * now parse and init the nodeTree */ //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(interpolateimage); /* * it's possible to not have an initialization context - or we don't * want to trust the caller - so have a fallback value if so * * Also, do *not* dump the VM namespace for this template */ nodeTree = rsvc.parse(br, (context != null) ? context.CurrentTemplateName : "StringLiteral", false); /* * init with context. It won't modify anything */ nodeTree.init(context, rsvc); } return(data); }
/// <summary> CTOR, wraps an ICA /// </summary> public VMContext(InternalContextAdapter inner, RuntimeServices rsvc) { InitBlock(); localcontextscope = rsvc.getBoolean(RuntimeConstants_Fields.VM_CONTEXT_LOCALSCOPE, false); wrappedContext = inner; innerContext = inner.BaseContext; }
public override bool render(InternalContextAdapter context, System.IO.TextWriter writer) { int i, k = jjtGetNumChildren(); for (i = 0; i < k; i++) jjtGetChild(i).render(context, writer); return true; }
/// <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, System.IO.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 (System.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> simple init - don't do anything that is context specific. /// just get what we need from the AST, which is static. /// </summary> public override Object init(InternalContextAdapter context, Object data) { base.init(context, data); identifier = FirstToken.image; uberInfo = new Info(context.CurrentTemplateName, Line, Column); return(data); }
/// <summary> Returns the 'root string', the reference key /// </summary> /// <summary> gets an Object that 'is' the value of the reference /// * /// </summary> /// <param name="o"> unused Object parameter /// </param> /// <param name="context">context used to generate value /// /// </param> public override Object execute(Object o, InternalContextAdapter context) { if (referenceType == RUNT) { return(null); } /* * get the root object from the context */ Object result = getVariableValue(context, rootString); if (result == null) { return(null); } /* * Iteratively work 'down' (it's flat...) the reference * to get the value, but check to make sure that * every result along the path is valid. For example: * * $hashtable.Customer.Name * * The $hashtable may be valid, but there is no key * 'Customer' in the hashtable so we want to stop * when we find a null value and return the null * so the error gets logged. */ try { for (int i = 0; i < numChildren; i++) { result = jjtGetChild(i).execute(result, context); if (result == null) { return(null); } } return(result); } catch (MethodInvocationException mie) { /* * someone tossed their cookies */ rsvc.error("Method " + mie.MethodName + " threw exception for reference $" + rootString + " in template " + context.CurrentTemplateName + " at " + " [" + this.Line + "," + this.Column + "]"); mie.ReferenceName = rootString; throw mie; } }
/// <summary>for log msg purposes /// </summary> /// <summary>for log msg purposes /// </summary> /// <summary> How this directive is to be initialized. /// </summary> public virtual void init(RuntimeServices rs, InternalContextAdapter context, INode node) { rsvc = rs; // int i, k = node.jjtGetNumChildren(); //for (i = 0; i < k; i++) // node.jjtGetChild(i).init(context, rs); }
/// <summary> puts the value of the RHS into the context under the key of the LHS /// </summary> public override bool render(InternalContextAdapter context, TextWriter writer) { /* * get the RHS node, and it's value */ Object value_ = right.Value(context); /* * it's an error if we don't have a value of some sort */ if (value_ == null) { /* * first, are we supposed to say anything anyway? */ if (blather) { EventCartridge ec = context.EventCartridge; bool doit = true; /* * if we have an EventCartridge... */ if (ec != null) { doit = ec.shouldLogOnNullSet(left.literal(), right.literal()); } if (doit) { rsvc.error("RHS of #set statement is null. Context will not be modified. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); } } return(false); } /* * if the LHS is simple, just punch the value into the context * otherwise, use the setValue() method do to it. * Maybe we should always use setValue() */ if (left.jjtGetNumChildren() == 0) { context.Put(leftReference, value_); } else { left.setValue(context, value_); } return(true); }
public override Object init(InternalContextAdapter context, Object data) { Token t = FirstToken; String text = NodeUtils.tokenLiteral(t); ctext = text.ToCharArray(); return(data); }
/// <summary> /// does the instrospection of the class for the method needed. /// Note, as this calls value() on the args if any, this must /// only be called at execute() / render() time. /// /// NOTE: this will try to flip the case of the first character for /// convience (compatability with Java version). If there are no arguments, /// it will also try to find a property with the same name (also flipping first character). /// </summary> private Object doIntrospection(InternalContextAdapter context, Type data) { /* * Now the parameters have to be processed, there * may be references contained within that need * to be introspected. */ for (int j = 0; j < paramCount; j++) { params_Renamed[j] = jjtGetChild(j + 1).Value(context); } String methodNameUsed = methodName; MethodInfo m = rsvc.Introspector.getMethod(data, methodNameUsed, params_Renamed); PropertyInfo p = null; if (m == null) { methodNameUsed = methodName.Substring(0, 1).ToUpper() + methodName.Substring(1); m = rsvc.Introspector.getMethod(data, methodNameUsed, params_Renamed); if (m == null) { methodNameUsed = methodName.Substring(0, 1).ToLower() + methodName.Substring(1); m = rsvc.Introspector.getMethod(data, methodNameUsed, params_Renamed); // if there are no arguments, look for a property if (m == null && paramCount == 0) { methodNameUsed = methodName; p = rsvc.Introspector.getProperty(data, methodNameUsed); if (p == null) { methodNameUsed = methodName.Substring(0, 1).ToUpper() + methodName.Substring(1); p = rsvc.Introspector.getProperty(data, methodNameUsed); if (p == null) { methodNameUsed = methodName.Substring(0, 1).ToLower() + methodName.Substring(1); p = rsvc.Introspector.getProperty(data, methodNameUsed); } } } } } // if a method was found, return it. Otherwise, return whatever was found with a property, may be null if (m != null) { return(m); } else { return(p); } }
public override void init(RuntimeServices rs, InternalContextAdapter context, Node node) { base.init(rs, context, node); /* * again, don't do squat. We want the AST of the macro * block to hang off of this but we don't want to * init it... it's useless... */ return; }
public override bool evaluate(InternalContextAdapter context) { if (jjtGetChild(0).evaluate(context)) { return(false); } else { return(true); } }
public override bool render(InternalContextAdapter context, TextWriter writer) { int i, k = jjtGetNumChildren(); for (i = 0; i < k; i++) { jjtGetChild(i).render(context, writer); } return(true); }
internal virtual void setup(InternalContextAdapter ica) { /* * if not parsed yet, parse! */ if (nodeTree == null) { parseTree(ica); } }
/// <summary> Initialization method - doesn't do much but do the object /// creation. We only need to do it once. /// </summary> public override Object init(InternalContextAdapter context, Object data) { /* * init the tree correctly */ base.init(context, data); value__Field = Int32.Parse(FirstToken.image); return(data); }
internal virtual 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"' System.IO.TextReader br = new System.IO.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> Invoked by VMContext when Context.put() is called for a proxied reference. /// * /// </summary> /// <param name="context">context to modify via direct placement, or AST.setValue() /// </param> /// <param name="o"> new value of reference /// </param> /// <returns>Object currently null /// /// </returns> public Object setObject(InternalContextAdapter context, Object o) { /* * if we are a reference, we could be updating a property */ if (type == ParserTreeConstants.JJTREFERENCE) { if (numTreeChildren > 0) { /* * we are a property, and being updated such as * #foo( $bar.BangStart) */ try { ((ASTReference)nodeTree).setValue(context, o); } catch (MethodInvocationException mie) { rsvc.error("VMProxyArg.getObject() : method invocation error setting value : " + mie); } } else { /* * we are a 'single level' reference like $foo, so we can set * out context directly */ context.Put(singleLevelRef, o); // alternate impl : usercontext.put( singleLevelRef, o); } } else { /* * if we aren't a reference, then we simply switch type, * get a new value, and it doesn't go into the context * * in current impl, this shouldn't happen. */ type = GENERALSTATIC; staticObject = o; rsvc.error("VMProxyArg.setObject() : Programmer error : I am a constant! No setting! : " + contextReference + " / " + callerReference); } return(null); }
public override Object Value(InternalContextAdapter context) { int size = jjtGetNumChildren(); ArrayList objectArray = new ArrayList(); for (int i = 0; i < size; i++) { objectArray.Add(jjtGetChild(i).Value(context)); } return(objectArray); }
/// <summary> Return name of this directive. /// </summary> /// <summary> Return type of this directive. /// </summary> /// <summary> simple init - init the tree and get the elementKey from /// the AST /// </summary> public override void init(RuntimeServices rs, InternalContextAdapter context, INode node) { base.init(rs, context, node); /* * get the msg, and add the space so we don't have to * do it each time */ outputMsgStart = rsvc.getString(RuntimeConstants_Fields.ERRORMSG_START); outputMsgStart = outputMsgStart + " "; outputMsgEnd = rsvc.getString(RuntimeConstants_Fields.ERRORMSG_END); outputMsgEnd = " " + outputMsgEnd; }
/// <summary> /// simple init - init our subtree and get what we can from /// the AST /// </summary> public override Object init(InternalContextAdapter context, Object data) { base.init(context, data); /* * this is about all we can do */ methodName = FirstToken.image; paramCount = jjtGetNumChildren() - 1; params_Renamed = new Object[paramCount]; return(data); }
/// <summary> /// simple init - init the tree and get the elementKey from /// the AST /// </summary> public override void init(RuntimeServices rs, InternalContextAdapter context, INode node) { base.init(rs, context, node); counterName = rsvc.getString(RuntimeConstants_Fields.COUNTER_NAME); counterInitialValue = rsvc.getInt(RuntimeConstants_Fields.COUNTER_INITIAL_VALUE); /* * this is really the only thing we can do here as everything * else is context sensitive */ elementKey = node.jjtGetChild(0).FirstToken.image.Substring(1); }
public override bool render(InternalContextAdapter context, TextWriter writer, INode node) { /* * what is our arg? */ INode n = node.jjtGetChild(0); if (n.Type == ParserTreeConstants.JJTSTRINGLITERAL) { try { String element = (String) node.jjtGetChild(0).value_Renamed(context); TemplateHandler th = (TemplateHandler) rsvc.getApplicationAttribute("NVelocity.Dvsl.TemplateHandler"); th.RegisterMatch(element, (SimpleNode) node.jjtGetChild(node.jjtGetNumChildren() - 1)); } catch (System.Exception ee) {}} return true; }
/// <summary> does the actual rendering of the included file /// * /// </summary> /// <param name="node">AST argument of type StringLiteral or Reference /// </param> /// <param name="context">valid context so we can render References /// </param> /// <param name="writer">output Writer /// </param> /// <returns>boolean success or failure. failures are logged /// /// </returns> private bool renderOutput(INode node, InternalContextAdapter context, System.IO.TextWriter writer) { System.String arg = ""; if (node == null) { rsvc.error("#include() error : null argument"); return false; } /* * does it have a value? If you have a null reference, then no. */ System.Object value_Renamed = node.value_Renamed(context); if (value_Renamed == null) { rsvc.error("#include() error : null argument"); return false; } /* * get the path */ //UPGRADE_TODO: The equivalent in .NET for method 'java.Object.toString' may return a different value. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1043"' arg = value_Renamed.ToString(); Resource resource = null; Resource current = context.CurrentResource; try { /* * get the resource, and assume that we use the encoding of the current template * the 'current resource' can be null if we are processing a stream.... */ System.String encoding = null; if (current != null) { encoding = current.Encoding; } else { encoding = (System.String) rsvc.getProperty(NVelocity.Runtime.RuntimeConstants_Fields.INPUT_ENCODING); } resource = rsvc.getContent(arg, encoding); } catch (ResourceNotFoundException rnfe) { /* * the arg wasn't found. Note it and throw */ rsvc.error("#include(): cannot find resource '" + arg + "', called from template " + context.CurrentTemplateName + " at (" + Line + ", " + Column + ")"); throw rnfe; } catch (System.Exception e) { rsvc.error("#include(): arg = '" + arg + "', called from template " + context.CurrentTemplateName + " at (" + Line + ", " + Column + ") : " + e); } if (resource == null) return false; writer.Write((System.String) resource.Data); return true; }
/// <summary> Returns the value of the expression. /// Since the value of the expression is simply the boolean /// result of evaluate(), lets return that. /// </summary> public override System.Object value_Renamed(InternalContextAdapter context) { return evaluate(context); }
/// <summary> logical and : /// null && right = false /// left && null = false /// null && null = false /// </summary> public override bool evaluate(InternalContextAdapter context) { INode left = jjtGetChild(0); INode right = jjtGetChild(1); /* * if either is null, lets log and bail */ if (left == null || right == null) { rsvc.error((left == null?"Left":"Right") + " side of '&&' operation is null." + " Operation not possible. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return false; } /* * short circuit the test. Don't eval the RHS if the LHS is false */ if (left.evaluate(context)) { if (right.evaluate(context)) { return true; } } return false; }
/// <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 virtual System.Object getObject(InternalContextAdapter context) { try { /* * we need to output based on our type */ System.Object retObject = null; if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTREFERENCE) { /* * 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 == NVelocity.Runtime.Parser.ParserTreeConstants.JJTOBJECTARRAY) { retObject = nodeTree.value_Renamed(context); } else if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTINTEGERRANGE) { retObject = nodeTree.value_Renamed(context); } else if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTTRUE) { retObject = staticObject; } else if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTFALSE) { retObject = staticObject; } else if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTSTRINGLITERAL) { retObject = nodeTree.value_Renamed(context); } else if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTNUMBERLITERAL) { retObject = staticObject; } else if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTTEXT) { /* * this really shouldn't happen. text is just a thowaway arg for #foreach() */ try { System.IO.StringWriter writer = new System.IO.StringWriter(); nodeTree.render(context, writer); retObject = writer; } catch (System.Exception e) { rsvc.error("VMProxyArg.getObject() : error rendering reference : " + e); } } else if (type == GENERALSTATIC) { retObject = staticObject; } else { rsvc.error("Unsupported VM arg type : VM arg = " + callerReference + " type = " + type + "( VMProxyArg.getObject() )"); } return retObject; } catch (MethodInvocationException mie) { /* * not ideal, but otherwise we propogate 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 */ rsvc.error("VMProxyArg.getObject() : method invocation error getting value : " + mie); return null; } }
/// <summary> computes the sum of the two nodes. Currently only integer operations are /// supported. /// </summary> /// <returns>Integer object with value, or null /// /// </returns> public override System.Object value_Renamed(InternalContextAdapter context) { /* * get the two addends */ System.Object left = jjtGetChild(0).value_Renamed(context); System.Object right = jjtGetChild(1).value_Renamed(context); /* * if either is null, lets log and bail */ if (left == null || right == null) { rsvc.error((left == null?"Left":"Right") + " side (" + jjtGetChild((left == null?0:1)).literal() + ") of addition operation has null value." + " Operation not possible. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return null; } /* * if not an Integer, not much we can do either */ if (!(left is System.Int32) || !(right is System.Int32)) { rsvc.error((!(left is System.Int32)?"Left":"Right") + " side of addition operation is not a valid type. " + "Currently only integers (1,2,3...) and Integer type is supported. " + context.CurrentTemplateName + " [line " + Line + ", column " + Column + "]"); return null; } return ((System.Int32) left) + ((System.Int32) right); }
/// <summary> Invoked by VMContext when Context.put() is called for a proxied reference. /// * /// </summary> /// <param name="context">context to modify via direct placement, or AST.setValue() /// </param> /// <param name="o"> new value of reference /// </param> /// <returns>Object currently null /// /// </returns> public virtual System.Object setObject(InternalContextAdapter context, System.Object o) { /* * if we are a reference, we could be updating a property */ if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTREFERENCE) { if (numTreeChildren > 0) { /* * we are a property, and being updated such as * #foo( $bar.BangStart) */ try { ((ASTReference) nodeTree).setValue(context, o); } catch (MethodInvocationException mie) { rsvc.error("VMProxyArg.getObject() : method invocation error setting value : " + mie); } } else { /* * we are a 'single level' reference like $foo, so we can set * out context directly */ context.Put(singleLevelRef, o); // alternate impl : usercontext.put( singleLevelRef, o); } } else { /* * if we aren't a reference, then we simply switch type, * get a new value, and it doesn't go into the context * * in current impl, this shouldn't happen. */ type = GENERALSTATIC; staticObject = o; rsvc.error("VMProxyArg.setObject() : Programmer error : I am a constant! No setting! : " + contextReference + " / " + callerReference); } return null; }
/// <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, System.IO.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 (System.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> Return name of this directive. /// </summary> /// <summary> Return type of this directive. /// </summary> /// <summary> Store the literal rendition of a node using /// the Node.literal(). /// </summary> public override void init(RuntimeServices rs, InternalContextAdapter context, INode node) { base.init(rs, context, node); literalText = node.jjtGetChild(0).literal(); }
/// <summary> Throw the literal rendition of the block between /// #literal()/#end into the writer. /// </summary> public override bool render(InternalContextAdapter context, System.IO.TextWriter writer, INode node) { writer.Write(literalText); return true; }
/// <summary> iterates through the argument list and renders every /// argument that is appropriate. Any non appropriate /// arguments are logged, but render() continues. /// </summary> public override bool render(InternalContextAdapter context, System.IO.TextWriter writer, INode node) { /* * get our arguments and check them */ int argCount = node.jjtGetNumChildren(); for (int i = 0; i < argCount; i++) { /* * we only handle StringLiterals and References right now */ INode n = node.jjtGetChild(i); if (n.Type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTSTRINGLITERAL || n.Type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTREFERENCE) { if (!renderOutput(n, context, writer)) outputErrorToStream(writer, "error with arg " + i + " please see log."); } else { //UPGRADE_TODO: The equivalent in .NET for method 'java.Object.toString' may return a different value. 'ms-help://MS.VSCC/commoner/redir/redirect.htm?keyword="jlca1043"' rsvc.error("#include() error : invalid argument type : " + n.ToString()); outputErrorToStream(writer, "error with arg " + i + " please see log."); } } return true; }
/* * CODE FOR ALTERNATE IMPL : please ignore. I will remove when confortable with current. */ /// <summary> not used in current impl /// * /// Constructor for alternate impl where VelProxy class would make new /// VMProxyArg objects, and use this contructor to avoid reparsing the /// reference args /// * /// that impl also had the VMProxyArg carry it's context /// </summary> public VMProxyArg(VMProxyArg model, InternalContextAdapter c) { usercontext = c; contextReference = model.ContextReference; callerReference = model.CallerReference; nodeTree = model.NodeTree; staticObject = model.StaticObject; type = model.Type; if (nodeTree != null) numTreeChildren = nodeTree.jjtGetNumChildren(); if (type == NVelocity.Runtime.Parser.ParserTreeConstants.JJTREFERENCE) { if (numTreeChildren == 0) { /* * use the reference node to do this... */ singleLevelRef = ((ASTReference) nodeTree).RootString; } } }
/// <summary> Return name of this directive. /// </summary> /// <summary> Return type of this directive. /// </summary> /// <summary> simple init - init the tree and get the elementKey from /// the AST /// </summary> public override void init(RuntimeServices rs, InternalContextAdapter context, INode node) { base.init(rs, context, node); /* * get the msg, and add the space so we don't have to * do it each time */ outputMsgStart = rsvc.getString(NVelocity.Runtime.RuntimeConstants_Fields.ERRORMSG_START); outputMsgStart = outputMsgStart + " "; outputMsgEnd = rsvc.getString(NVelocity.Runtime.RuntimeConstants_Fields.ERRORMSG_END); outputMsgEnd = " " + outputMsgEnd; }
public override Boolean render(InternalContextAdapter context, TextWriter writer, INode node) { return true; }
internal virtual void setup(InternalContextAdapter ica) { /* * if not parsed yet, parse! */ if (nodeTree == null) parseTree(ica); }
/// <summary> The major meat of VelocimacroProxy, init() checks the # of arguments, patches the /// macro body, renders the macro into an AST, and then inits the AST, so it is ready /// for quick rendering. Note that this is only AST dependant stuff. Not context. /// </summary> public override void init(RuntimeServices rs, InternalContextAdapter context, INode node) { base.init(rs, context, node); /* * how many args did we get? */ int i = node.jjtGetNumChildren(); /* * right number of args? */ if (NumArgs != i) { rsvc.error("VM #" + macroName + ": error : too " + ((NumArgs > i)?"few":"many") + " arguments to macro. Wanted " + NumArgs + " got " + i); return ; } /* * get the argument list to the instance use of the VM */ callingArgs = getArgArray(node); /* * now proxy each arg in the context */ setupMacro(callingArgs, callingArgTypes); return ; }