コード例 #1
0
 /// <summary> Put method also stores values in parent context
 ///
 /// </summary>
 /// <param name="key">name of item to set
 /// </param>
 /// <param name="value">object to set to key
 /// </param>
 /// <returns> old stored object
 /// </returns>
 public virtual object Put(string key, object value)
 {
     /*
      * just Put in the local context
      */
     return(innerContext.Put(key, value));
 }
コード例 #2
0
 public object setObject(IInternalContextAdapter context, object o)
 {
     if (this.type == 14)
     {
         if (this.numTreeChildren > 0)
         {
             try
             {
                 ((ASTReference)this.nodeTree).SetValue(context, o);
             }
             catch (MethodInvocationException arg)
             {
                 this.rsvc.Error("VMProxyArg.getObject() : method invocation error setting value : " + arg);
             }
         }
         else
         {
             context.Put(this.singleLevelRef, o);
         }
     }
     else
     {
         this.type         = -1;
         this.staticObject = o;
         this.rsvc.Error("VMProxyArg.setObject() : Programmer error : I am a constant!  No setting! : " + this.contextReference + " / " + this.callerReference);
     }
     return(null);
 }
コード例 #3
0
        /// <summary>   puts the value of the RHS into the context under the key of the LHS
        /// </summary>
        public override bool Render(IInternalContextAdapter 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 eventCartridge = context.EventCartridge;

                    bool doIt = true;

                    /*
                     *  if we have an EventCartridge...
                     */
                    if (eventCartridge != null)
                    {
                        doIt = eventCartridge.ShouldLogOnNullSet(left.Literal, right.Literal);
                    }

                    if (doIt)
                    {
                        runtimeServices.Error(
                            string.Format("RHS of #set statement is null. Context will not be modified. {0} [line {1}, column {2}]",
                                          context.CurrentTemplateName, Line, 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.ChildrenCount == 0)
            {
                context.Put(leftReference, value);
            }
            else
            {
                left.SetValue(context, value);
            }

            return(true);
        }
コード例 #4
0
ファイル: Define.cs プロジェクト: 15831944/tool
 /// <summary> directive.render() simply makes an instance of the Block inner class
 /// and places it into the context as indicated.
 /// </summary>
 public override bool Render(IInternalContextAdapter context, System.IO.TextWriter writer, INode node)
 {
     /* Put a Block instance into the context,
      * using the user-defined key, for later inline rendering.
      */
     context.Put(key, new Block(context, this));
     return(true);
 }
コード例 #5
0
        /// <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(IInternalContextAdapter context, Object o)
        {
            /*
             *  if we are a reference, we could be updating a property
             */

            if (type == ParserTreeConstants.REFERENCE)
            {
                if (numTreeChildren > 0)
                {
                    /*
                     *  we are a property, and being updated such as
                     *  #foo( $bar.BangStart)
                     */

                    try
                    {
                        ((ASTReference)nodeTree).SetValue(context, o);
                    }
                    catch (MethodInvocationException methodInvocationException)
                    {
                        runtimeServices.Error(
                            string.Format("VMProxyArg.getObject() : method invocation error setting value : {0}", methodInvocationException));
                    }
                }
                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;

                runtimeServices.Error(
                    string.Format("VMProxyArg.setObject() : Programmer error : I am a constant!  No setting! : {0} / {1}",
                                  contextReference, callerReference));
            }

            return(null);
        }
コード例 #6
0
        public override bool Render(IInternalContextAdapter context, TextWriter writer)
        {
            object obj = this.right.Value(context);
            bool   result;

            if (obj == null)
            {
                if (this.blather)
                {
                    EventCartridge eventCartridge = context.EventCartridge;
                    bool           flag           = true;
                    if (eventCartridge != null)
                    {
                        flag = eventCartridge.ShouldLogOnNullSet(this.left.Literal, this.right.Literal);
                    }
                    if (flag)
                    {
                        this.rsvc.Error(string.Concat(new object[]
                        {
                            "RHS of #set statement is null. Context will not be modified. ",
                            context.CurrentTemplateName,
                            " [line ",
                            base.Line,
                            ", column ",
                            base.Column,
                            "]"
                        }));
                    }
                }
                result = false;
            }
            else
            {
                if (this.left.ChildrenCount == 0)
                {
                    context.Put(this.leftReference, obj);
                }
                else
                {
                    this.left.SetValue(context, obj);
                }
                result = true;
            }
            return(result);
        }
コード例 #7
0
        /// <summary>  Impl of the Context.put() method.
        /// *
        /// </summary>
        /// <param name="key">name of item to set
        /// </param>
        /// <param name="value">object to set to key
        /// </param>
        /// <returns>old stored object
        ///
        /// </returns>
        public Object Put(String key, Object value)
        {
            /*
             *  first see if this is a vmpa
             */

            VMProxyArg vmProxyArg = (VMProxyArg)vmProxyHash[key];

            if (vmProxyArg == null)
            {
                if (localContextScope)
                {
                    /*
                     *  if we have localContextScope mode, then just
                     *  put in the local context
                     */

                    return(localContext[key] = value);
                }
                else
                {
                    /*
                     *  ok, how about the local context?
                     */

                    if (localContext.ContainsKey(key))
                    {
                        return(localContext[key] = value);
                    }
                    else
                    {
                        /*
                         * otherwise, let them push it into the 'global' context
                         */

                        return(innerContext.Put(key, value));
                    }
                }
            }
            else
            {
                return(vmProxyArg.setObject(wrappedContext, value));
            }
        }
コード例 #8
0
ファイル: Foreach.cs プロジェクト: hatjhie/NVelocity
        /// <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);
        }
コード例 #9
0
ファイル: Foreach.cs プロジェクト: modulexcite/Transformalize
        /// <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;
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
 /// <summary> Extension hook to allow subclasses to control whether loop vars
 /// are set locally or not. So, those in favor of VELOCITY-285, can
 /// make that happen easily by overriding this and having it use
 /// context.localPut(k,v). See VELOCITY-630 for more on this.
 /// </summary>
 protected internal virtual void Put(IInternalContextAdapter context, string key, object value)
 {
     context.Put(key, value);
 }
コード例 #12
0
        public object Put(string key, object value)
        {
            bag.ContextEntries[key] = value;

            return(context.Put(key, value));
        }
コード例 #13
0
        /// <summary>  Sets the value of a complex reference (something like $foo.bar)
        /// Currently used by ASTSetReference()
        ///
        /// </summary>
        /// <seealso cref="ASTSetDirective">
        ///
        /// </seealso>
        /// <param name="context">context object containing this reference
        /// </param>
        /// <param name="value">Object to set as value
        /// </param>
        /// <returns> true if successful, false otherwise
        /// </returns>
        /// <throws>  MethodInvocationException </throws>
        public virtual bool SetValue(IInternalContextAdapter context, object value)
        {
            if (GetNumChildren() == 0)
            {
                context.Put(rootString, value);
                return(true);
            }

            /*
             *  The rootOfIntrospection is the object we will
             *  retrieve from the Context. This is the base
             *  object we will apply reflection to.
             */

            object result = GetVariableValue(context, rootString);

            if (result == null)
            {
                string msg = "reference set is not a valid reference at " + Log.FormatFileString(uberInfo);
                log.Error(msg);
                return(false);
            }

            /*
             * How many child nodes do we have?
             */

            for (int i = 0; i < numChildren - 1; i++)
            {
                result = GetChild(i).Execute(result, context);

                if (result == null)
                {
                    if (strictRef)
                    {
                        string name = GetChild(i + 1).FirstToken.Image;
                        throw new MethodInvocationException("Attempted to access '" + name + "' on a null value", null, name, uberInfo.TemplateName, GetChild(i + 1).Line, GetChild(i + 1).Column);
                    }

                    string msg = "reference set is not a valid reference at " + Log.FormatFileString(uberInfo);
                    log.Error(msg);

                    return(false);
                }
            }

            /*
             *  We support two ways of setting the value in a #set($ref.foo = $value ) :
             *  1) ref.setFoo( value )
             *  2) ref,put("foo", value ) to parallel the get() map introspection
             */

            try
            {
                IVelPropertySet vs = rsvc.Uberspect.GetPropertySet(result, identifier, value, uberInfo);

                if (vs == null)
                {
                    if (strictRef)
                    {
                        throw new MethodInvocationException("Object '" + result.GetType().FullName + "' does not contain property '" + identifier + "'", null, identifier, uberInfo.TemplateName, uberInfo.Line, uberInfo.Column);
                    }
                    else
                    {
                        return(false);
                    }
                }

                vs.Invoke(result, value);
            }
            catch (TargetInvocationException ite)
            {
                /*
                 *  this is possible
                 */

                throw new MethodInvocationException("ASTReference : Invocation of method '" + identifier + "' in  " + result.GetType() + " threw exception " + ite.GetBaseException().ToString(), ite.GetBaseException(), identifier, TemplateName, this.Line, this.Column);
            }

            /**
             * pass through application level runtime exceptions
             */
            catch (System.SystemException e)
            {
                throw e;
            }
            catch (System.Exception e)
            {
                /*
                 *  maybe a security exception?
                 */
                string msg = "ASTReference setValue() : exception : " + e + " template at " + Log.FormatFileString(uberInfo);
                log.Error(msg, e);
                throw new VelocityException(msg, e);
            }

            return(true);
        }
コード例 #14
0
        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);
        }
コード例 #15
0
		/// <summary>   puts the value of the RHS into the context under the key of the LHS
		/// </summary>
		public override bool Render(IInternalContextAdapter 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.ChildrenCount == 0)
			{
				context.Put(leftReference, value_);
			}
			else
			{
				left.SetValue(context, value_);
			}

			return true;
		}
コード例 #16
0
ファイル: VMProxyArg.cs プロジェクト: rambo-returns/MonoRail
		/// <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(IInternalContextAdapter context, Object o)
		{
			/*
	    *  if we are a reference, we could be updating a property
	    */

			if (type == ParserTreeConstants.REFERENCE)
			{
				if (numTreeChildren > 0)
				{
					/*
		    *  we are a property, and being updated such as
		    *  #foo( $bar.BangStart) 
		    */

					try
					{
						((ASTReference) nodeTree).SetValue(context, o);
					}
					catch(MethodInvocationException methodInvocationException)
					{
						runtimeServices.Error(
							string.Format("VMProxyArg.getObject() : method invocation error setting value : {0}", methodInvocationException));
					}
				}
				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;

				runtimeServices.Error(
					string.Format("VMProxyArg.setObject() : Programmer error : I am a constant!  No setting! : {0} / {1}",
					              contextReference, callerReference));
			}

			return null;
		}
コード例 #17
0
        /// <summary>   puts the value of the RHS into the context under the key of the LHS</summary>
        /// <param name="context">
        /// </param>
        /// <param name="writer">
        /// </param>
        /// <returns> True if rendering was sucessful.
        /// </returns>
        /// <throws>  IOException </throws>
        /// <throws>  MethodInvocationException </throws>
        public override bool Render(IInternalContextAdapter context, System.IO.TextWriter writer)
        {
            /*
             *  Get the RHS node, and its value
             */

            object value = right.Value(context);

            /*
             * it's an Error if we don't have a value of some sort AND
             * it is not allowed by configuration
             */

            if (!allowNull)
            {
                if (value == null)
                {
                    /*
                     *  first, are we supposed to say anything anyway?
                     */
                    if (logOnNull)
                    {
                        bool doit = EventHandlerUtil.ShouldLogOnNullSet(rsvc, context, left.Literal, right.Literal);

                        if (doit && rsvc.Log.DebugEnabled)
                        {
                            rsvc.Log.Debug("RHS of #set statement is null. Context will not be modified. " + Log.FormatFileString(this));
                        }
                    }

                    string rightReference = null;
                    if (right is ASTExpression)
                    {
                        rightReference = ((ASTExpression)right).LastToken.Image;
                    }
                    EventHandlerUtil.InvalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo);

                    return(false);
                }
            }

            if (value == null && !strictRef)
            {
                string rightReference = null;
                if (right is ASTExpression)
                {
                    rightReference = ((ASTExpression)right).LastToken.Image;
                }
                EventHandlerUtil.InvalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo);

                /*
                 * if RHS is null, remove simple LHS from context
                 * or call setValue() with a null value for complex LHS
                 */
                if (left.GetNumChildren() == 0)
                {
                    context.Remove(leftReference);
                }
                else
                {
                    left.SetValue(context, (object)null);
                }

                return(false);
            }
            else
            {
                /*
                 *  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.GetNumChildren() == 0)
                {
                    context.Put(leftReference, value);
                }
                else
                {
                    left.SetValue(context, value);
                }
            }

            return(true);
        }