/// <summary> Calls event handler method with appropriate chaining across event handlers. /// /// </summary> /// <param name="methodExecutor"> /// </param> /// <param name="rsvc">current instance of RuntimeServices /// </param> /// <param name="context">The current context /// </param> /// <returns> return value from method, or null if no return value /// </returns> public static object InvalidReferenceHandlerCall(IEventHandlerMethodExecutor methodExecutor, IRuntimeServices rsvc, IInternalContextAdapter context) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.ApplicationEventCartridge; System.Collections.IEnumerator applicationEventHandlerIterator = (ev1 == null) ? null : ev1.InvalidReferenceEventHandlers; EventCartridge ev2 = context.EventCartridge; InitializeEventCartridge(rsvc, ev2); System.Collections.IEnumerator contextEventHandlerIterator = (ev2 == null) ? null : ev2.InvalidReferenceEventHandlers; try { CallEventHandlers(applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return(methodExecutor.ReturnValue); } catch (System.SystemException e) { throw e; } catch (System.Exception e) { throw new RuntimeException("Exception in event handler.", e); } }
/// <summary> Called when an include-type directive is encountered (#include or /// #parse). All the registered event handlers are called unless null is /// returned. The default implementation always processes the included /// resource. /// /// </summary> /// <param name="includeResourcePath">the path as given in the include directive. /// </param> /// <param name="currentResourcePath">the path of the currently rendering template that includes the /// include directive. /// </param> /// <param name="directiveName">name of the directive used to include the resource. (With the /// standard directives this is either "parse" or "include"). /// </param> /// <param name="rsvc">current instance of RuntimeServices /// </param> /// <param name="context">The internal context adapter. /// /// </param> /// <returns> a new resource path for the directive, or null to block the /// include from occurring. /// </returns> public static string IncludeEvent(IRuntimeServices rsvc, IInternalContextAdapter context, string includeResourcePath, string currentResourcePath, string directiveName) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.ApplicationEventCartridge; System.Collections.IEnumerator applicationEventHandlerIterator = (ev1 == null) ? null : ev1.IncludeEventHandlers; EventCartridge ev2 = context.EventCartridge; InitializeEventCartridge(rsvc, ev2); System.Collections.IEnumerator contextEventHandlerIterator = (ev2 == null) ? null : ev2.IncludeEventHandlers; try { IEventHandlerMethodExecutor methodExecutor = new NVelocity.App.Event.IncludeEventExecutor(context, includeResourcePath, currentResourcePath, directiveName); CallEventHandlers(applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return((string)methodExecutor.ReturnValue); } catch (System.SystemException e) { throw e; } catch (System.Exception e) { throw new RuntimeException("Exception in event handler.", e); } }
/// <summary> Called when a null is evaluated during a #set. All event handlers are /// called in sequence until a false is returned. The default implementation /// always returns true. /// /// </summary> /// <param name="lhs">Left hand side of the expression. /// </param> /// <param name="rhs">Right hand side of the expression. /// </param> /// <param name="rsvc">current instance of RuntimeServices /// </param> /// <param name="context">The internal context adapter. /// </param> /// <returns> true if to be logged, false otherwise /// </returns> public static bool ShouldLogOnNullSet(IRuntimeServices rsvc, IInternalContextAdapter context, string lhs, string rhs) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.ApplicationEventCartridge; System.Collections.IEnumerator applicationEventHandlerIterator = (ev1 == null) ? null : ev1.NullSetEventHandlers; EventCartridge ev2 = context.EventCartridge; InitializeEventCartridge(rsvc, ev2); System.Collections.IEnumerator contextEventHandlerIterator = (ev2 == null) ? null : ev2.NullSetEventHandlers; try { IEventHandlerMethodExecutor methodExecutor = new ShouldLogOnNullSetExecutor(context, lhs, rhs); CallEventHandlers(applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return((System.Boolean)methodExecutor.ReturnValue); } catch (System.SystemException e) { throw e; } catch (System.Exception e) { throw new RuntimeException("Exception in event handler.", e); } }
/// <summary> Called before a reference is inserted. All event handlers are called in /// sequence. The default implementation inserts the reference as is. /// /// This is a major hotspot method called by ASTReference render. /// /// </summary> /// <param name="reference">reference from template about to be inserted /// </param> /// <param name="value">value about to be inserted (after toString() ) /// </param> /// <param name="rsvc">current instance of RuntimeServices /// </param> /// <param name="context">The internal context adapter. /// </param> /// <returns> Object on which toString() should be called for output. /// </returns> public static object ReferenceInsert(IRuntimeServices rsvc, IInternalContextAdapter context, string reference, object value) { // app level cartridges have already been initialized /* * Performance modification: EventCartridge.getReferenceInsertionEventHandlers * now returns a null if there are no handlers. Thus we can avoid creating the * Iterator object. */ EventCartridge ev1 = rsvc.ApplicationEventCartridge; System.Collections.IEnumerator applicationEventHandlerIterator = (ev1 == null) ? null : ev1.ReferenceInsertionEventHandlers; EventCartridge ev2 = context.EventCartridge; InitializeEventCartridge(rsvc, ev2); System.Collections.IEnumerator contextEventHandlerIterator = (ev2 == null) ? null : ev2.ReferenceInsertionEventHandlers; try { /* * Performance modification: methodExecutor is created only if one of the * iterators is not null. */ IEventHandlerMethodExecutor methodExecutor = null; if (applicationEventHandlerIterator != null) { methodExecutor = new ReferenceInsertExecutor(context, reference, value); LterateOverEventHandlers(applicationEventHandlerIterator, methodExecutor); } if (contextEventHandlerIterator != null) { if (methodExecutor == null) { methodExecutor = new ReferenceInsertExecutor(context, reference, value); } LterateOverEventHandlers(contextEventHandlerIterator, methodExecutor); } return(methodExecutor != null ? methodExecutor.ReturnValue : value); } catch (System.SystemException e) { throw e; } catch (System.Exception e) { throw new RuntimeException("Exception in event handler.", e); } }
/// <summary> Initialize the event cartridge if appropriate. /// /// </summary> /// <param name="rsvc">current instance of RuntimeServices /// </param> /// <param name="eventCartridge">the event cartridge to be initialized /// </param> private static void InitializeEventCartridge(IRuntimeServices rsvc, EventCartridge eventCartridge) { if (eventCartridge != null) { try { eventCartridge.Initialize(rsvc); } catch (System.Exception e) { throw new RuntimeException("Couldn't initialize event cartridge : ", e); } } }
/// <summary> Called when a method exception is generated during Velocity merge. Only /// the first valid event handler in the sequence is called. The default /// implementation simply rethrows the exception. /// /// </summary> /// <param name="claz">Class that is causing the exception /// </param> /// <param name="method">method called that causes the exception /// </param> /// <param name="e">Exception thrown by the method /// </param> /// <param name="rsvc">current instance of RuntimeServices /// </param> /// <param name="context">The internal context adapter. /// </param> /// <returns> Object to return as method result /// </returns> /// <throws> Exception </throws> /// <summary> to be wrapped and propogated to app /// </summary> public static object MethodException(IRuntimeServices rsvc, IInternalContextAdapter context, System.Type claz, string method, System.Exception e) { // app level cartridges have already been initialized EventCartridge ev1 = rsvc.ApplicationEventCartridge; System.Collections.IEnumerator applicationEventHandlerIterator = (ev1 == null) ? null : ev1.MethodExceptionEventHandlers; EventCartridge ev2 = context.EventCartridge; InitializeEventCartridge(rsvc, ev2); System.Collections.IEnumerator contextEventHandlerIterator = (ev2 == null) ? null : ev2.MethodExceptionEventHandlers; IEventHandlerMethodExecutor methodExecutor = new NVelocity.App.Event.MethodExceptionExecutor(context, claz, method, e); if (((applicationEventHandlerIterator == null) || !applicationEventHandlerIterator.MoveNext()) && ((contextEventHandlerIterator == null) || !contextEventHandlerIterator.MoveNext())) { throw e; } CallEventHandlers(applicationEventHandlerIterator, contextEventHandlerIterator, methodExecutor); return(methodExecutor.ReturnValue); }