internal virtual VelocimacroProxy createVelocimacro(System.String namespace_Renamed) { VelocimacroProxy vp = new VelocimacroProxy(); vp.Name = this.macroname; vp.ArgArray = this.argarray; vp.Macrobody = this.macrobody; vp.NodeTree = this.nodeTree; vp.Namespace = namespace_Renamed; return(vp); }
/// <summary> Velocimacro implementation is not known at the Init time. So look for /// a implementation in the macro libaries and if finds one renders it. The /// parameters rendering is delegated to the VelocimacroProxy object. When /// looking for a macro we first loot at the template with has the /// macro call then we look at the macro lbraries in the order they appear /// in the list. If a macro has many definitions above look up will /// determine the precedence. /// /// </summary> /// <param name="context"> /// </param> /// <param name="writer"> /// </param> /// <param name="node"> /// </param> /// <returns> true if the rendering is successfull /// </returns> /// <throws> IOException </throws> /// <throws> ResourceNotFoundException </throws> /// <throws> ParseErrorException </throws> /// <throws> MethodInvocationException </throws> public override bool Render(IInternalContextAdapter context, System.IO.TextWriter writer, INode node) { VelocimacroProxy vmProxy = null; string renderingTemplate = context.CurrentTemplateName; /** * first look in the source template */ object o = rsvc.GetVelocimacro(macroName, sourceTemplate, renderingTemplate); if (o != null) { // getVelocimacro can only return a VelocimacroProxy so we don't need the // costly instanceof check vmProxy = (VelocimacroProxy)o; } /** * if not found, look in the macro libraries. */ if (vmProxy == null) { System.Collections.IList macroLibraries = context.MacroLibraries; if (macroLibraries != null) { for (int i = macroLibraries.Count - 1; i >= 0; i--) { o = rsvc.GetVelocimacro(macroName, (string)macroLibraries[i], renderingTemplate); // Get the first matching macro if (o != null) { vmProxy = (VelocimacroProxy)o; break; } } } } if (vmProxy != null) { try { // mainly check the number of arguments vmProxy.Init(rsvc, context, node); } catch (TemplateInitException die) { Info info = new Info(sourceTemplate, node.Line, node.Column); throw new ParseErrorException(die.Message + " at " + Log.Log.FormatFileString(info), info); } try { return(vmProxy.Render(context, writer, node)); } catch (System.IO.IOException e) { rsvc.Log.Error("Exception in macro #" + macroName + " at " + Log.Log.FormatFileString(sourceTemplate, Line, Column)); throw e; } catch (System.SystemException e) { /** * We catch, the exception here so that we can record in * the logs the template and line number of the macro call * which generate the exception. This information is * especially important for multiple macro call levels. * this is also true for the following catch blocks. */ rsvc.Log.Error("Exception in macro #" + macroName + " at " + Log.Log.FormatFileString(sourceTemplate, Line, Column)); throw e; } } else if (strictRef) { Info info = new Info(sourceTemplate, node.Line, node.Column); throw new ParseErrorException("Macro '#" + macroName + "' is not defined at " + Log.Log.FormatFileString(info), info); } /** * If we cannot find an implementation write the literal text */ writer.Write(Literal); return(true); }
internal virtual VelocimacroProxy createVelocimacro(System.String namespace_Renamed) { VelocimacroProxy vp = new VelocimacroProxy(); vp.Name = this.macroname; vp.ArgArray = this.argarray; vp.Macrobody = this.macrobody; vp.NodeTree = this.nodeTree; vp.Namespace = namespace_Renamed; return vp; }
/// <summary> actual factory : creates a Directive that will /// behave correctly wrt getting the framework to /// dig out the correct # of args /// </summary> public virtual Directive.Directive getVelocimacro(System.String vmName, System.String sourceTemplate) { VelocimacroProxy vp = null; lock (this) { /* * don't ask - do */ vp = vmManager.get(vmName, sourceTemplate); /* * if this exists, and autoload is on, we need to check * where this VM came from */ if (vp != null && Autoload) { /* * see if this VM came from a library. Need to pass sourceTemplate * in the event namespaces are set, as it could be masked by local */ System.String lib = vmManager.getLibraryName(vmName, sourceTemplate); if (lib != null) { try { /* * get the template from our map */ Twonk tw = (Twonk)libModMap[lib]; if (tw != null) { Template template = tw.template; /* * now, compare the last modified time of the resource * with the last modified time of the template * if the file has changed, then reload. Otherwise, we should * be ok. */ long tt = tw.modificationTime; long ft = template.ResourceLoader.getLastModified(template) ; if (ft > tt) { logVMMessageInfo("Velocimacro : autoload reload for VMs from " + "VM library template : " + lib); /* * when there are VMs in a library that invoke each other, * there are calls into getVelocimacro() from the init() * process of the VM directive. To stop the infinite loop * we save the current time reported by the resource loader * and then be honest when the reload is complete */ tw.modificationTime = ft; template = rsvc.getTemplate(lib) ; /* * and now we be honest */ tw.template = template; tw.modificationTime = template.LastModified; /* * note that we don't need to put this twonk back * into the map, as we can just use the same reference * and this block is synchronized */ } } } catch (System.Exception e) { logVMMessageInfo("Velocimacro : error using VM " + "library template " + lib + " : " + e); } /* * and get again */ vp = vmManager.get(vmName, sourceTemplate); } } } return(vp); }