The function of this class is to proxy for the calling parameter to the VM. * This class is designed to be used in conjunction with the VMContext class which knows how to get and set values via it, rather than a simple get() or put() from a hashtable-like object. * There is probably a lot of undocumented subtlty here, so step lightly. * We rely on the observation that an instance of this object has a constant state throughout its lifetime as it's bound to the use-instance of a VM. In other words, it's created by the VelocimacroProxy class, to represent one of the arguments to a VM in a specific template. Since the template is fixed (it's a file...), we don't have to worry that the args to the VM will change. Yes, the VM will be called in other templates, or in other places on the same template, bit those are different use-instances. * These arguments can be, in the lingo of the parser, one of :
  • Reference() : anything that starts with '$'
  • StringLiteral() : something like "$foo" or "hello geir"
  • NumberLiteral() : 1, 2 etc
  • IntegerRange() : [ 1..2] or [$foo .. $bar]
  • ObjectArray() : [ "a", "b", "c"]
  • True() : true
  • False() : false
  • Word() : not likely - this is simply allowed by the parser so we can have syntactical sugar like #foreach($a in $b) where 'in' is the Word
Now, Reference(), StringLit, NumberLit, IntRange, ObjArr are all dynamic things, so their value is gotten with the use of a context. The others are constants. The trick we rely on is that the context rather than this class really represents the state of the argument. We are simply proxying for the thing, returning the proper value when asked, and storing the proper value in the appropriate context when asked. * So, the hope here, so an instance of this can be shared across threads, is to keep any dynamic stuff out of it, relying on trick of having the appropriate context handed to us, and when a constant argument, letting VMContext punch that into a local context.
Esempio n. 1
0
        /*
         * 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;
                }
            }
        }
Esempio n. 2
0
 public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node)
 {
     try
     {
         if (this.nodeTree != null)
         {
             if (!this.init)
             {
                 this.nodeTree.Init(context, this.rsvc);
                 this.init = true;
             }
             VMContext vMContext = new VMContext(context, this.rsvc);
             for (int i = 1; i < this.argArray.Length; i++)
             {
                 VMProxyArg vmpa = (VMProxyArg)this.proxyArgHash[this.argArray[i]];
                 vMContext.AddVMProxyArg(vmpa);
             }
             this.nodeTree.Render(vMContext, writer);
         }
         else
         {
             this.rsvc.Error("VM error : " + this.macroName + ". Null AST");
         }
     }
     catch (System.Exception ex)
     {
         if (ex is MethodInvocationException)
         {
             throw;
         }
         this.rsvc.Error("VelocimacroProxy.render() : exception VM = #" + this.macroName + "() : " + StringUtils.StackTrace(ex));
     }
     return(true);
 }
Esempio n. 3
0
 private void setupProxyArgs(string[] callArgs, int[] callArgTypes)
 {
     for (int i = 1; i < this.argArray.Length; i++)
     {
         VMProxyArg value = new VMProxyArg(this.rsvc, this.argArray[i], callArgs[i - 1], callArgTypes[i - 1]);
         this.proxyArgHash[this.argArray[i]] = value;
     }
 }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
 private void setupProxyArgs(String[] callArgs, int[] callArgTypes)
 {
     // for each of the args, make a ProxyArg
     for (int i = 1; i < argArray.Length; i++)
     {
         VMProxyArg arg = new VMProxyArg(runtimeServices, argArray[i], callArgs[i - 1], callArgTypes[i - 1]);
         proxyArgHash[argArray[i]] = arg;
     }
 }
Esempio n. 6
0
        private void  setupProxyArgs(System.String[] callArgs, int[] callArgTypes)
        {
            /*
             * for each of the args, make a ProxyArg
             */

            for (int i = 1; i < argArray.Length; i++)
            {
                VMProxyArg arg = new VMProxyArg(rsvc, argArray[i], callArgs[i - 1], callArgTypes[i - 1]);
                proxyArgHash[argArray[i]] = arg;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Renders the macro using the context
        /// </summary>
        public override bool Render(IInternalContextAdapter context, TextWriter writer, INode node)
        {
            try
            {
                // it's possible the tree hasn't been parsed yet, so get
                // the VMManager to parse and init it
                if (nodeTree == null)
                {
                    runtimeServices.Error(string.Format("VM error : {0}. Null AST", macroName));
                }
                else
                {
                    if (!init)
                    {
                        nodeTree.Init(context, runtimeServices);
                        init = true;
                    }

                    // wrap the current context and add the VMProxyArg objects
                    VMContext vmContext = new VMContext(context, runtimeServices);

                    for (int i = 1; i < argArray.Length; i++)
                    {
                        // we can do this as VMProxyArgs don't change state. They change
                        // the context.
                        VMProxyArg arg = (VMProxyArg)proxyArgHash[argArray[i]];
                        vmContext.AddVMProxyArg(arg);
                    }

                    // now render the VM
                    nodeTree.Render(vmContext, writer);
                }
            }
            catch (Exception e)
            {
                // if it's a MIE, it came from the render.... throw it...
                if (e is MethodInvocationException)
                {
                    throw;
                }

                runtimeServices.Error(string.Format("VelocimacroProxy.render() : exception VM = #{0}() : {1}", macroName, e));
            }

            return(true);
        }
Esempio n. 8
0
 public VMProxyArg(VMProxyArg model, IInternalContextAdapter c)
 {
     this.usercontext      = c;
     this.contextReference = model.ContextReference;
     this.callerReference  = model.CallerReference;
     this.nodeTree         = model.NodeTree;
     this.staticObject     = model.StaticObject;
     this.type             = model.Type;
     if (this.nodeTree != null)
     {
         this.numTreeChildren = this.nodeTree.ChildrenCount;
     }
     if (this.type == 14)
     {
         if (this.numTreeChildren == 0)
         {
             this.singleLevelRef = ((ASTReference)this.nodeTree).RootString;
         }
     }
 }
Esempio n. 9
0
		/*
	* CODE FOR ALTERNATE IMPL : please ignore.  I will remove when comfortable with current.
	*/

		/// <summary>  not used in current impl
		/// *
		/// Constructor for alternate impl where VelProxy class would make new
		/// VMProxyArg objects, and use this constructor to avoid re-parsing the
		/// reference args
		/// *
		/// that impl also had the VMProxyArg carry it's context
		/// </summary>
		public VMProxyArg(VMProxyArg model, IInternalContextAdapter c)
		{
			userContext = c;
			contextReference = model.ContextReference;
			callerReference = model.CallerReference;
			nodeTree = model.NodeTree;
			staticObject = model.StaticObject;
			type = model.Type;

			if (nodeTree != null)
			{
				numTreeChildren = nodeTree.ChildrenCount;
			}

			if (type == ParserTreeConstants.REFERENCE)
			{
				if (numTreeChildren == 0)
				{
					/*
		    *  use the reference node to do this...
		    */
					singleLevelRef = ((ASTReference) nodeTree).RootString;
				}
			}
		}
Esempio n. 10
0
		private void setupProxyArgs(String[] callArgs, int[] callArgTypes)
		{
			// for each of the args, make a ProxyArg
			for(int i = 1; i < argArray.Length; i++)
			{
				VMProxyArg arg = new VMProxyArg(rsvc, argArray[i], callArgs[i - 1], callArgTypes[i - 1]);
				proxyArgHash[argArray[i]] = arg;
			}
		}
Esempio n. 11
0
	/// <summary>  return the inner / user context
	/// </summary>


	/// <summary>  Used to put VMProxyArgs into this context.  It separates
	/// the VMProxyArgs into constant and non-constant types
	/// pulling out the value of the constant types so they can
	/// be modified w/o damaging the VMProxyArg, and leaving the
	/// dynamic ones, as they modify context rather than their own
	/// state
	/// </summary>
	/// <param name="vmpa">VMProxyArg to add
	///
	/// </param>
	public virtual void  AddVMProxyArg(VMProxyArg vmpa) {
	    /*
	    *  ask if it's a constant : if so, get the value and put into the
	    *  local context, otherwise, put the vmpa in our vmproxyhash
	    */

	    System.String key = vmpa.ContextReference;

	    if (vmpa.isConstant()) {
		localcontext[key] = vmpa.getObject(wrappedContext);
	    } else {
		vmproxyhash[key] = vmpa;
	    }
	}
Esempio n. 12
0
	/*
	* 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;
		}
	    }
	}