/** * Invoked on startup. Looks for a single VelocityConfig bean to * find the relevant VelocityEngine for this factory. */ @Override protected void initApplicationContext() throws BeansException { super.initApplicationContext(); if (getVelocityEngine() == null) { // No explicit VelocityEngine: try to autodetect one. setVelocityEngine(autodetectVelocityEngine()); } }
/** * Process the model map by merging it with the Velocity template. * Output is directed to the servlet response. * <p>This method can be overridden if custom behavior is needed. */ @Override protected void renderMergedTemplateModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { exposeHelpers(model, request); Context velocityContext = createVelocityContext(model, request, response); exposeHelpers(velocityContext, request, response); exposeToolAttributes(velocityContext, request); doRender(velocityContext, response); }
/** * Render the Velocity view to the given response, using the given Velocity * context which contains the complete template model to use. * <p>The default implementation renders the template specified by the "url" * bean property, retrieved via {@code getTemplate}. It delegates to the * {@code mergeTemplate} method to merge the template instance with the * given Velocity context. * <p>Can be overridden to customize the behavior, for example to render * multiple templates into a single view. * @param context the Velocity context to use for rendering * @param response servlet response (use this to get the OutputStream or Writer) * @throws Exception if thrown by Velocity * @see #setUrl * @see #getTemplate() * @see #mergeTemplate */ protected void doRender(Context context, HttpServletResponse response) throws Exception { if (logger.isDebugEnabled()) { logger.debug("Rendering Velocity template [" + getUrl() + "] in VelocityView '" + getBeanName() + "'"); } mergeTemplate(getTemplate(), context, response); }
/** * Retrieve the Velocity template to be rendered by this view. * <p>By default, the template specified by the "url" bean property will be * retrieved: either returning a cached template instance or loading a fresh * instance (according to the "cacheTemplate" bean property) * @return the Velocity template to render * @throws Exception if thrown by Velocity * @see #setUrl * @see #setCacheTemplate * @see #getTemplate(String) */ protected Template getTemplate() throws Exception { // We already hold a reference to the template, but we might want to load it // if not caching. Velocity itself caches templates, so our ability to // cache templates in this class is a minor optimization only. if (isCacheTemplate() && this.template != null) { return this.template; } else { return getTemplate(getUrl()); } }
/** * Retrieve the Velocity template specified by the given name, * using the encoding specified by the "encoding" bean property. * <p>Can be called by subclasses to retrieve a specific template, * for example to render multiple templates into a single view. * @param name the file name of the desired template * @return the Velocity template * @throws Exception if thrown by Velocity * @see VelocityEngine#getTemplate */ protected Template getTemplate(String name) throws Exception { return (getEncoding() != null ? getVelocityEngine().getTemplate(name, getEncoding()) : getVelocityEngine().getTemplate(name)); }
/** * Check that the Velocity template used for this view exists and is valid. * <p>Can be overridden to customize the behavior, for example in case of * multiple templates to be rendered into a single view. */ @Override public boolean checkResource(Locale locale) throws Exception { try { // Check that we can get the template, even if we might subsequently get it again. this.template = getTemplate(getUrl()); return true; } catch (ResourceNotFoundException ex) { if (logger.isDebugEnabled()) { logger.debug("No Velocity view found for URL: " + getUrl()); } return false; } catch (Exception ex) { throw new NestedIOException( "Could not load Velocity template for URL [" + getUrl() + "]", ex); } }
/** * Expose helpers unique to each rendering operation. This is necessary so that * different rendering operations can't overwrite each other's formats etc. * <p>Called by {@code renderMergedTemplateModel}. Default implementation * delegates to {@code exposeHelpers(velocityContext, request)}. This method * can be overridden to add special tools to the context, needing the servlet response * to initialize (see Velocity Tools, for example LinkTool and ViewTool/ChainedContext). * @param velocityContext Velocity context that will be passed to the template * @param request current HTTP request * @param response current HTTP response * @throws Exception if there's a fatal error while we're adding model attributes * @see #exposeHelpers(Context, HttpServletRequest) */ protected void exposeHelpers( Context velocityContext, HttpServletRequest request, HttpServletResponse response) throws Exception { exposeHelpers(velocityContext, request); }
/** * Autodetect a VelocityEngine via the ApplicationContext. * Called if no explicit VelocityEngine has been specified. * @return the VelocityEngine to use for VelocityViews * @throws BeansException if no VelocityEngine could be found * @see #getApplicationContext * @see #setVelocityEngine */ protected VelocityEngine autodetectVelocityEngine() throws BeansException { try { VelocityConfig velocityConfig = BeanFactoryUtils.beanOfTypeIncludingAncestors( getApplicationContext(), VelocityConfig.class, true, false); return velocityConfig.getVelocityEngine(); } catch (NoSuchBeanDefinitionException ex) { throw new ApplicationContextException( "Must define a single VelocityConfig bean in this web application context " + "(may be inherited): VelocityConfigurer is the usual implementation. " + "This bean may be given any name.", ex); } }
/** * Merge the template with the context. * Can be overridden to customize the behavior. * @param template the template to merge * @param context the Velocity context to use for rendering * @param response servlet response (use this to get the OutputStream or Writer) * @throws Exception if thrown by Velocity * @see Template#merge */ protected void mergeTemplate( Template template, Context context, HttpServletResponse response) throws Exception { try { template.merge(context, response.getWriter()); } catch (MethodInvocationException ex) { Throwable cause = ex.getWrappedThrowable(); throw new NestedServletException( "Method invocation failed during rendering of Velocity view with name '" + getBeanName() + "': " + ex.getMessage() + "; reference [" + ex.getReferenceName() + "], method '" + ex.getMethodName() + "'", cause==null ? ex : cause); } }
/** * Create a Velocity Context instance for the given model, * to be passed to the template for merging. * <p>The default implementation delegates to {@link #createVelocityContext(Map)}. * Can be overridden for a special context class, for example ChainedContext which * is part of the view package of Velocity Tools. ChainedContext is needed for * initialization of ViewTool instances. * <p>Have a look at {@link VelocityToolboxView}, which pre-implements * ChainedContext support. This is not part of the standard VelocityView class * in order to avoid a required dependency on the view package of Velocity Tools. * @param model the model Map, containing the model attributes to be exposed to the view * @param request current HTTP request * @param response current HTTP response * @return the Velocity Context * @throws Exception if there's a fatal error while creating the context * @see #createVelocityContext(Map) * @see #initTool * @see org.apache.velocity.tools.view.context.ChainedContext * @see VelocityToolboxView */ protected Context createVelocityContext( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { return createVelocityContext(model); }
/** * Retrieve the Velocity template to be rendered by this view. * <p>By default, the template specified by the "url" bean property will be * retrieved: either returning a cached template instance or loading a fresh * instance (according to the "cacheTemplate" bean property) * @return the Velocity template to render * @throws Exception if thrown by Velocity * @see #setUrl * @see #setCacheTemplate * @see #getTemplate(String) */ protected Template getTemplate() throws Exception { // We already hold a reference to the template, but we might want to load it // if not caching. Velocity itself caches templates, so our ability to // cache templates in this class is a minor optimization only. if (isCacheTemplate() && this.template != null) { return this.template; } else { return getTemplate(getUrl()); } }
/** * Retrieve the Velocity template specified by the given name, * using the encoding specified by the "encoding" bean property. * <p>Can be called by subclasses to retrieve a specific template, * for example to render multiple templates into a single view. * @param name the file name of the desired template * @return the Velocity template * @throws Exception if thrown by Velocity * @see VelocityEngine#getTemplate */ protected Template getTemplate(String name) throws Exception { return (getEncoding() != null ? getVelocityEngine().getTemplate(name, getEncoding()) : getVelocityEngine().getTemplate(name)); }
/** * Check that the Velocity template used for this view exists and is valid. * <p>Can be overridden to customize the behavior, for example in case of * multiple templates to be rendered into a single view. */ @Override public boolean checkResource(Locale locale) throws Exception { try { // Check that we can get the template, even if we might subsequently get it again. this.template = getTemplate(getUrl()); return true; } catch (ResourceNotFoundException ex) { if (logger.isDebugEnabled()) { logger.debug("No Velocity view found for URL: " + getUrl()); } return false; } catch (Exception ex) { throw new NestedIOException( "Could not load Velocity template for URL [" + getUrl() + "]", ex); } }
/** * Expose helpers unique to each rendering operation. This is necessary so that * different rendering operations can't overwrite each other's formats etc. * <p>Called by {@code renderMergedTemplateModel}. Default implementation * delegates to {@code exposeHelpers(velocityContext, request)}. This method * can be overridden to add special tools to the context, needing the servlet response * to initialize (see Velocity Tools, for example LinkTool and ViewTool/ChainedContext). * @param velocityContext Velocity context that will be passed to the template * @param request current HTTP request * @param response current HTTP response * @throws Exception if there's a fatal error while we're adding model attributes * @see #exposeHelpers(Context, HttpServletRequest) */ protected void exposeHelpers( Context velocityContext, HttpServletRequest request, HttpServletResponse response) throws Exception { exposeHelpers(velocityContext, request); }
/** * Autodetect a VelocityEngine via the ApplicationContext. * Called if no explicit VelocityEngine has been specified. * @return the VelocityEngine to use for VelocityViews * @throws BeansException if no VelocityEngine could be found * @see #getApplicationContext * @see #setVelocityEngine */ protected VelocityEngine autodetectVelocityEngine() throws BeansException { try { VelocityConfig velocityConfig = BeanFactoryUtils.beanOfTypeIncludingAncestors( getApplicationContext(), VelocityConfig.class, true, false); return velocityConfig.getVelocityEngine(); } catch (NoSuchBeanDefinitionException ex) { throw new ApplicationContextException( "Must define a single VelocityConfig bean in this web application context " + "(may be inherited): VelocityConfigurer is the usual implementation. " + "This bean may be given any name.", ex); } }
/** * Merge the template with the context. * Can be overridden to customize the behavior. * @param template the template to merge * @param context the Velocity context to use for rendering * @param response servlet response (use this to get the OutputStream or Writer) * @throws Exception if thrown by Velocity * @see Template#merge */ protected void mergeTemplate( Template template, Context context, HttpServletResponse response) throws Exception { try { template.merge(context, response.getWriter()); } catch (MethodInvocationException ex) { Throwable cause = ex.getWrappedThrowable(); throw new NestedServletException( "Method invocation failed during rendering of Velocity view with name '" + getBeanName() + "': " + ex.getMessage() + "; reference [" + ex.getReferenceName() + "], method '" + ex.getMethodName() + "'", cause==null ? ex : cause); } }
/** * Create a Velocity Context instance for the given model, * to be passed to the template for merging. * <p>The default implementation delegates to {@link #createVelocityContext(Map)}. * Can be overridden for a special context class, for example ChainedContext which * is part of the view package of Velocity Tools. ChainedContext is needed for * initialization of ViewTool instances. * <p>Have a look at {@link VelocityToolboxView}, which pre-implements * ChainedContext support. This is not part of the standard VelocityView class * in order to avoid a required dependency on the view package of Velocity Tools. * @param model the model Map, containing the model attributes to be exposed to the view * @param request current HTTP request * @param response current HTTP response * @return the Velocity Context * @throws Exception if there's a fatal error while creating the context * @see #createVelocityContext(Map) * @see #initTool * @see org.apache.velocity.tools.view.context.ChainedContext * @see VelocityToolboxView */ protected Context createVelocityContext( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { return createVelocityContext(model); }
/** * Process the model map by merging it with the Velocity template. * Output is directed to the servlet response. * <p>This method can be overridden if custom behavior is needed. */ @Override protected void renderMergedTemplateModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { exposeHelpers(model, request); Context velocityContext = createVelocityContext(model, request, response); exposeHelpers(velocityContext, request, response); exposeToolAttributes(velocityContext, request); doRender(velocityContext, response); }
/** * Render the Velocity view to the given response, using the given Velocity * context which contains the complete template model to use. * <p>The default implementation renders the template specified by the "url" * bean property, retrieved via {@code getTemplate}. It delegates to the * {@code mergeTemplate} method to merge the template instance with the * given Velocity context. * <p>Can be overridden to customize the behavior, for example to render * multiple templates into a single view. * @param context the Velocity context to use for rendering * @param response servlet response (use this to get the OutputStream or Writer) * @throws Exception if thrown by Velocity * @see #setUrl * @see #getTemplate() * @see #mergeTemplate */ protected void doRender(Context context, HttpServletResponse response) throws Exception { if (logger.isDebugEnabled()) { logger.debug("Rendering Velocity template [" + getUrl() + "] in VelocityView '" + getBeanName() + "'"); } mergeTemplate(getTemplate(), context, response); }
/** * Invoked on startup. Looks for a single VelocityConfig bean to * find the relevant VelocityEngine for this factory. */ @Override protected void initApplicationContext() throws BeansException { super.initApplicationContext(); if (getVelocityEngine() == null) { // No explicit VelocityEngine: try to autodetect one. setVelocityEngine(autodetectVelocityEngine()); } }