/// <summary> This method helps to implement the "render literal if null" functionality. /// /// VelocimacroProxy saves references to macro arguments (AST nodes) so that if we have a macro /// #foobar($a $b) then there is key "$a.literal" which points to the literal presentation of the /// argument provided to variable $a. If the value of $a is null, we render the string that was /// provided as the argument. /// /// </summary> /// <param name="context"> /// </param> /// <returns> /// </returns> private string GetNullString(IInternalContextAdapter context) { object callingArgument = context.Get(".literal." + nullString); if (callingArgument != null) { return(((INode)callingArgument).Literal); } else { return(nullString); } }
/// <summary> Impl of the Context.gut() method. /// * /// </summary> /// <param name="key">name of item to get /// </param> /// <returns> stored object or null /// /// </returns> public Object Get(String key) { /* * first, see if it's a VMPA */ Object o; VMProxyArg vmProxyArg = (VMProxyArg)vmProxyHash[key]; if (vmProxyArg == null) { if (localContextScope) { /* * if we have localContextScope mode, then just * put in the local context */ o = localContext[key]; } else { /* * try the local context */ o = localContext[key]; if (o == null) { /* * last chance */ o = innerContext.Get(key); } } } else { o = vmProxyArg.getObject(wrappedContext); } return(o); }
/// <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(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; } }
/// <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); } }
/// <summary> /// renders the #foreach() block /// </summary> public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node) { // do our introspection to see what our collection is IEnumerator enumerator = GetIterator(context, node); INode bodyNode = node.GetChild(3); INode[][] sections = PrepareSections(bodyNode); bool isFancyLoop = (sections != null); if (enumerator == null && !isFancyLoop) { return(true); } int counter = counterInitialValue; // save the element key if there is one, // and the loop counter Object o = context.Get(elementKey); Object ctr = context.Get(counterName); if (enumerator != null && enumerator.MoveNext()) { do { object current = enumerator.Current; context.Put(counterName, counter); //context.Put(hasNextName, enumerator.MoveNext() ? Boolean.TrueString : Boolean.FalseString); context.Put(elementKey, current); try { if (isFancyLoop) { if (counter == counterInitialValue) { ProcessSection(ForeachSectionEnum.BeforeAll, sections, context, writer); } else { ProcessSection(ForeachSectionEnum.Between, sections, context, writer); } ProcessSection(ForeachSectionEnum.Before, sections, context, writer); // since 1st item is zero we invert odd/even if ((counter - counterInitialValue) % 2 == 0) { ProcessSection(ForeachSectionEnum.Odd, sections, context, writer); } else { ProcessSection(ForeachSectionEnum.Even, sections, context, writer); } ProcessSection(ForeachSectionEnum.Each, sections, context, writer); ProcessSection(ForeachSectionEnum.After, sections, context, writer); } else { bodyNode.Render(context, writer); } } catch (BreakException ex) { Console.WriteLine(ex.Message); bodyNode.Render(context, writer); break; } counter++; } while (enumerator.MoveNext()); } if (isFancyLoop) { if (counter > counterInitialValue) { ProcessSection(ForeachSectionEnum.AfterAll, sections, context, writer); } else { ProcessSection(ForeachSectionEnum.NoData, sections, context, writer); } } // restores the loop counter (if we were nested) // if we have one, else just removes if (ctr == null) { context.Remove(counterName); } else { context.Put(counterName, ctr); } // restores element key if exists // otherwise just removes if (o == null) { context.Remove(elementKey); } else { context.Put(elementKey, o); } return(true); }
/// <summary> /// renders the #foreach() block /// </summary> public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node) { // do our introspection to see what our collection is IEnumerator enumerator = GetIterator(context, node); INode bodyNode = node.GetChild(3); INode[][] sections = PrepareSections(bodyNode); bool isFancyLoop = (sections != null); if (enumerator == null && !isFancyLoop) { return true; } int counter = counterInitialValue; // save the element key if there is one, // and the loop counter Object o = context.Get(elementKey); Object ctr = context.Get(counterName); if (enumerator != null && enumerator.MoveNext()) { do { object current = enumerator.Current; context.Put(counterName, counter); //context.Put(hasNextName, enumerator.MoveNext() ? Boolean.TrueString : Boolean.FalseString); context.Put(elementKey, current); try { if (isFancyLoop) { if (counter == counterInitialValue) { ProcessSection(ForeachSectionEnum.BeforeAll, sections, context, writer); } else { ProcessSection(ForeachSectionEnum.Between, sections, context, writer); } ProcessSection(ForeachSectionEnum.Before, sections, context, writer); // since 1st item is zero we invert odd/even if ((counter - counterInitialValue) % 2 == 0) { ProcessSection(ForeachSectionEnum.Odd, sections, context, writer); } else { ProcessSection(ForeachSectionEnum.Even, sections, context, writer); } ProcessSection(ForeachSectionEnum.Each, sections, context, writer); ProcessSection(ForeachSectionEnum.After, sections, context, writer); } else { bodyNode.Render(context, writer); } } catch (BreakException) { break; } counter++; } while (enumerator.MoveNext()); } if (isFancyLoop) { if (counter > counterInitialValue) { ProcessSection(ForeachSectionEnum.AfterAll, sections, context, writer); } else { ProcessSection(ForeachSectionEnum.NoData, sections, context, writer); } } // restores the loop counter (if we were nested) // if we have one, else just removes if (ctr == null) { context.Remove(counterName); } else { context.Put(counterName, ctr); } // restores element key if exists // otherwise just removes if (o == null) { context.Remove(elementKey); } else { context.Put(elementKey, o); } return true; }
/// <summary> renders the #foreach() block</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> MethodInvocationException </throws> /// <throws> ResourceNotFoundException </throws> /// <throws> ParseErrorException </throws> public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node) { /* * do our introspection to see what our collection is */ object listObject = node.GetChild(2).Value(context); if (listObject == null) { return(false); } IEnumerator i = null; try { i = rsvc.Uberspect.GetIterator(listObject, uberInfo); } /** * pass through application level runtime exceptions */ catch (SystemException e) { throw e; } catch (Exception ee) { string msg = "Error getting iterator for #foreach at " + uberInfo; rsvc.Log.Error(msg, ee); throw new VelocityException(msg, ee); } if (i == null) { if (skipInvalidIterator) { return(false); } else { INode pnode = node.GetChild(2); System.String msg = "#foreach parameter " + pnode.Literal + " at " + Log.FormatFileString(pnode) + " is of type " + listObject.GetType().FullName + " and is either of wrong type or cannot be iterated."; rsvc.Log.Error(msg); throw new VelocityException(msg); } } int counter = counterInitialValue; bool maxNbrLoopsExceeded = false; /* * save the element key if there is one, and the loop counter */ object o = context.Get(elementKey); object savedCounter = context.Get(counterName); /* * Instantiate the null holder context if a null value * is returned by the foreach iterator. Only one instance is * created - it's reused for every null value. */ NullHolderContext nullHolderContext = null; while (!maxNbrLoopsExceeded && i.MoveNext()) { // TODO: JDK 1.5+ -> Integer.valueOf() Put(context, counterName, (object)counter); object value = i.Current; Put(context, elementKey, value); try { /* * If the value is null, use the special null holder context */ if (value == null) { if (nullHolderContext == null) { // lazy instantiation nullHolderContext = new NullHolderContext(elementKey, context); } node.GetChild(3).Render(nullHolderContext, writer); } else { node.GetChild(3).Render(context, writer); } } catch (Break.BreakException ex) { // encountered #break directive inside #foreach loop break; } counter++; // Determine whether we're allowed to continue looping. // ASSUMPTION: counterInitialValue is not negative! maxNbrLoopsExceeded = (counter - counterInitialValue) >= maxNbrLoops; } /* * restores the loop counter (if we were nested) * if we have one, else just removes */ if (savedCounter != null) { context.Put(counterName, savedCounter); } else { context.Remove(counterName); } /* * restores element key if exists * otherwise just removes */ if (o != null) { context.Put(elementKey, o); } else { context.Remove(elementKey); } return(true); }
public object getObject(IInternalContextAdapter context) { object result; try { object obj = null; if (this.type == 14) { if (this.numTreeChildren == 0) { obj = context.Get(this.singleLevelRef); } else { obj = this.nodeTree.Execute(null, context); } } else if (this.type == 11) { obj = this.nodeTree.Value(context); } else if (this.type == 12) { obj = this.nodeTree.Value(context); } else if (this.type == 15) { obj = this.staticObject; } else if (this.type == 16) { obj = this.staticObject; } else if (this.type == 6) { obj = this.nodeTree.Value(context); } else if (this.type == 5) { obj = this.staticObject; } else if (this.type == 17) { try { StringWriter stringWriter = new StringWriter(); this.nodeTree.Render(context, stringWriter); obj = stringWriter; } catch (System.Exception arg) { this.rsvc.Error("VMProxyArg.getObject() : error rendering reference : " + arg); } } else if (this.type == -1) { obj = this.staticObject; } else { this.rsvc.Error(string.Concat(new object[] { "Unsupported VM arg type : VM arg = ", this.callerReference, " type = ", this.type, "( VMProxyArg.getObject() )" })); } result = obj; } catch (MethodInvocationException arg2) { this.rsvc.Error("VMProxyArg.getObject() : method invocation error getting value : " + arg2); result = null; } return(result); }
public object Get(string key) { return(context.Get(key)); }
public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node) { IEnumerator iterator = this.GetIterator(context, node); INode child = node.GetChild(3); INode[][] array = this.PrepareSections(child); bool flag = array != null; bool result; if (iterator == null && !flag) { result = true; } else { int num = this.counterInitialValue; object obj = context.Get(this.elementKey); object obj2 = context.Get(this.counterName); if (iterator != null && iterator.MoveNext()) { do { object current = iterator.Current; context.Put(this.counterName, num); context.Put(this.elementKey, current); if (!flag) { child.Render(context, writer); } else { if (num == this.counterInitialValue) { this.ProcessSection(ForeachSectionEnum.BeforeAll, array, context, writer); } else { this.ProcessSection(ForeachSectionEnum.Between, array, context, writer); } this.ProcessSection(ForeachSectionEnum.Before, array, context, writer); if ((num - this.counterInitialValue) % 2 == 0) { this.ProcessSection(ForeachSectionEnum.Odd, array, context, writer); } else { this.ProcessSection(ForeachSectionEnum.Even, array, context, writer); } this.ProcessSection(ForeachSectionEnum.Each, array, context, writer); this.ProcessSection(ForeachSectionEnum.After, array, context, writer); } num++; }while (iterator.MoveNext()); } if (flag) { if (num > this.counterInitialValue) { this.ProcessSection(ForeachSectionEnum.AfterAll, array, context, writer); } else { this.ProcessSection(ForeachSectionEnum.NoData, array, context, writer); } } if (obj2 != null) { context.Put(this.counterName, obj2); } else { context.Remove(this.counterName); } if (obj != null) { context.Put(this.elementKey, obj); } else { context.Remove(this.elementKey); } result = true; } return(result); }
/// <summary> Retrieves from parent context. /// /// </summary> /// <param name="key">name of item to Get /// </param> /// <returns> stored object or null /// </returns> public virtual object Get(string key) { return(innerContext.Get(key)); }