Remove Velocity support

Issue: SPR-13795
This commit is contained in:
Juergen Hoeller
2016-07-04 23:30:58 +02:00
parent 4027bda168
commit ff6ead1fff
54 changed files with 135 additions and 4242 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,7 +41,6 @@ public class MvcNamespaceHandler extends NamespaceHandlerSupport {
registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("velocity-configurer", new VelocityConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
/**
* Parse the <mvc:velocity-configurer> MVC namespace element and register an
* VelocityConfigurer bean
*
* @author Rossen Stoyanchev
* @since 4.1
*/
public class VelocityConfigurerBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {
public static final String BEAN_NAME = "mvcVelocityConfigurer";
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
return BEAN_NAME;
}
@Override
protected String getBeanClassName(Element element) {
return "org.springframework.web.servlet.view.velocity.VelocityConfigurer";
}
@Override
protected boolean isEligibleAttribute(String attributeName) {
return attributeName.equals("resource-loader-path");
}
@Override
protected void postProcess(BeanDefinitionBuilder builder, Element element) {
if (!builder.getBeanDefinition().hasAttribute("resourceLoaderPath")) {
builder.getBeanDefinition().setAttribute("resourceLoaderPath", "/WEB-INF/");
}
}
}

View File

@@ -58,7 +58,6 @@ import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
* @since 4.1
* @see TilesConfigurerBeanDefinitionParser
* @see FreeMarkerConfigurerBeanDefinitionParser
* @see VelocityConfigurerBeanDefinitionParser
* @see GroovyMarkupConfigurerBeanDefinitionParser
* @see ScriptTemplateConfigurerBeanDefinitionParser
*/
@@ -98,11 +97,6 @@ public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser {
resolverBeanDef.getPropertyValues().add("suffix", ".ftl");
addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
}
else if ("velocity".equals(name)) {
resolverBeanDef = new RootBeanDefinition(org.springframework.web.servlet.view.velocity.VelocityViewResolver.class);
resolverBeanDef.getPropertyValues().add("suffix", ".vm");
addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef);
}
else if ("groovy".equals(name)) {
resolverBeanDef = new RootBeanDefinition(GroovyMarkupViewResolver.class);
resolverBeanDef.getPropertyValues().add("suffix", ".tpl");

View File

@@ -190,26 +190,6 @@ public class ViewResolverRegistry {
return registration;
}
/**
* Register Velocity view resolver with an empty default view name
* prefix and a default suffix of ".vm".
* <p><strong>Note</strong> that you must also configure Velocity by adding a
* {@link org.springframework.web.servlet.view.velocity.VelocityConfigurer} bean.
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public UrlBasedViewResolverRegistration velocity() {
if (this.applicationContext != null && !hasBeanOfType(org.springframework.web.servlet.view.velocity.VelocityConfigurer.class)) {
throw new BeanInitializationException("In addition to a Velocity view resolver " +
"there must also be a single VelocityConfig bean in this web application context " +
"(or its parent): VelocityConfigurer is the usual implementation. " +
"This bean may be given any name.");
}
VelocityRegistration registration = new VelocityRegistration();
this.viewResolvers.add(registration.getViewResolver());
return registration;
}
/**
* Register a Groovy markup view resolver with an empty default view name
* prefix and a default suffix of ".tpl".
@@ -309,15 +289,6 @@ public class ViewResolverRegistry {
}
}
private static class VelocityRegistration extends UrlBasedViewResolverRegistration {
@SuppressWarnings("deprecation")
public VelocityRegistration() {
super(new org.springframework.web.servlet.view.velocity.VelocityViewResolver());
getViewResolver().setSuffix(".vm");
}
}
private static class FreeMarkerRegistration extends UrlBasedViewResolverRegistration {
public FreeMarkerRegistration() {

View File

@@ -31,7 +31,7 @@ import org.springframework.web.util.HtmlUtils;
/**
* Simple adapter to expose the bind status of a field or object.
* Set as a variable both by the JSP bind tag and Velocity/FreeMarker macros.
* Set as a variable both by the JSP bind tag and FreeMarker macros.
*
* <p>Obviously, object status representations (i.e. errors at the object level
* rather than the field level) do not have an expression and a value but only

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,17 +53,18 @@ import org.springframework.web.util.UrlPathHelper;
import org.springframework.web.util.WebUtils;
/**
* Context holder for request-specific state, like current web application context, current locale, current theme,
* and potential binding errors. Provides easy access to localized messages and Errors instances.
* Context holder for request-specific state, like current web application context, current locale,
* current theme, and potential binding errors. Provides easy access to localized messages and
* Errors instances.
*
* <p>Suitable for exposition to views, and usage within JSP's "useBean" tag, JSP scriptlets, JSTL EL, Velocity
* templates, etc. Necessary for views that do not have access to the servlet request, like Velocity templates.
* <p>Suitable for exposition to views, and usage within JSP's "useBean" tag, JSP scriptlets, JSTL EL,
* etc. Necessary for views that do not have access to the servlet request, like FreeMarker templates.
*
* <p>Can be instantiated manually, or automatically exposed to views as model attribute via AbstractView's
* "requestContextAttribute" property.
*
* <p>Will also work outside of DispatcherServlet requests, accessing the root WebApplicationContext and using
* an appropriate fallback for the locale (the HttpServletRequest's primary locale).
* <p>Will also work outside of DispatcherServlet requests, accessing the root WebApplicationContext
* and using an appropriate fallback for the locale (the HttpServletRequest's primary locale).
*
* @author Juergen Hoeller
* @author Rossen Stoyanchev

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -123,8 +123,8 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
* Note that this flag only applies if the general {@link #setCache "cache"}
* flag is kept at its default of "true" as well.
* <p>Of specific interest is the ability for some AbstractUrlBasedView
* implementations (FreeMarker, Velocity, Tiles) to check if an underlying
* resource exists via {@link AbstractUrlBasedView#checkResource(Locale)}.
* implementations (FreeMarker, Tiles) to check if an underlying resource
* exists via {@link AbstractUrlBasedView#checkResource(Locale)}.
* With this flag set to "false", an underlying resource that re-appears
* is noticed and used. With the flag set to "true", one check is made only.
*/
@@ -185,7 +185,7 @@ public abstract class AbstractCachingViewResolver extends WebApplicationObjectSu
/**
* Provides functionality to clear the cache for a certain view.
* <p>This can be handy in case developer are able to modify views
* (e.g. Velocity templates) at runtime after which you'd need to
* (e.g. FreeMarker templates) at runtime after which you'd need to
* clear the cache for the specified view.
* @param viewName the view name for which the cached view object
* (if any) needs to be removed

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,10 +26,9 @@ import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.support.RequestContext;
/**
* Adapter base class for template-based view technologies such as
* Velocity and FreeMarker, with the ability to use request and session
* attributes in their model and the option to expose helper objects
* for Spring's Velocity/FreeMarker macro library.
* Adapter base class for template-based view technologies such as FreeMarker,
* with the ability to use request and session attributes in their model and
* the option to expose helper objects for Spring's FreeMarker macro library.
*
* <p>JSP/JSTL and other view technologies automatically have access to the
* HttpServletRequest object and thereby the request/session attributes
@@ -40,7 +39,6 @@ import org.springframework.web.servlet.support.RequestContext;
* @author Darren Davison
* @since 1.0.2
* @see AbstractTemplateViewResolver
* @see org.springframework.web.servlet.view.velocity.VelocityView
* @see org.springframework.web.servlet.view.freemarker.FreeMarkerView
*/
public abstract class AbstractTemplateView extends AbstractUrlBasedView {
@@ -102,9 +100,9 @@ public abstract class AbstractTemplateView extends AbstractUrlBasedView {
/**
* Set whether to expose a RequestContext for use by Spring's macro library,
* under the name "springMacroRequestContext". Default is "true".
* <p>Currently needed for Spring's Velocity and FreeMarker default macros.
* Note that this is <i>not</i> required for templates that use HTML
* forms <i>unless</i> you wish to take advantage of the Spring helper macros.
* <p>Currently needed for Spring's FreeMarker default macros.
* Note that this is <i>not</i> required for templates that use HTML forms
* <i>unless</i> you wish to take advantage of the Spring helper macros.
* @see #SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE
*/
public void setExposeSpringMacroHelpers(boolean exposeSpringMacroHelpers) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,17 +17,14 @@
package org.springframework.web.servlet.view;
/**
* Abstract base class for template view resolvers,
* in particular for Velocity and FreeMarker views.
* Abstract base class for template view resolvers, in particular for FreeMarker views.
*
* <p>Provides a convenient way to specify {@link AbstractTemplateView}'s
* exposure flags for request attributes, session attributes,
* and Spring's macro helpers.
* <p>Provides a convenient way to specify {@link AbstractTemplateView}'s exposure
* flags for request attributes, session attributes, and Spring's macro helpers.
*
* @author Juergen Hoeller
* @since 1.1
* @see AbstractTemplateView
* @see org.springframework.web.servlet.view.velocity.VelocityViewResolver
* @see org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver
*/
public class AbstractTemplateViewResolver extends UrlBasedViewResolver {

View File

@@ -36,9 +36,8 @@ import org.springframework.web.servlet.View;
* (i.e. the symbolic name is the unique part of the resource's filename),
* without the need for a dedicated mapping to be defined for each view.
*
* <p>Supports {@link AbstractUrlBasedView} subclasses like {@link InternalResourceView},
* {@link org.springframework.web.servlet.view.velocity.VelocityView} and
* {@link org.springframework.web.servlet.view.freemarker.FreeMarkerView}.
* <p>Supports {@link AbstractUrlBasedView} subclasses like {@link InternalResourceView}
* and {@link org.springframework.web.servlet.view.freemarker.FreeMarkerView}.
* The view class for all views generated by this resolver can be specified
* via the "viewClass" property.
*
@@ -79,7 +78,6 @@ import org.springframework.web.servlet.View;
* @see #REDIRECT_URL_PREFIX
* @see AbstractUrlBasedView
* @see InternalResourceView
* @see org.springframework.web.servlet.view.velocity.VelocityView
* @see org.springframework.web.servlet.view.freemarker.FreeMarkerView
*/
public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {

View File

@@ -3,7 +3,7 @@
* including abstract base classes for custom implementations.
*
* <p>Application developers don't usually need to implement views,
* as the framework provides standard views for JSPs, Velocity,
* as the framework provides standard views for JSPs, FreeMarker,
* XSLT, etc. However, the ability to implement custom views easily
* by subclassing the AbstractView class in this package can be
* very helpful if an application has unusual view requirements.

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import org.apache.velocity.app.VelocityEngine;
/**
* Interface to be implemented by objects that configure and manage a
* VelocityEngine for automatic lookup in a web environment. Detected
* and used by VelocityView.
*
* @author Rod Johnson
* @see VelocityConfigurer
* @see VelocityView
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public interface VelocityConfig {
/**
* Return the VelocityEngine for the current web application context.
* May be unique to one servlet, or shared in the root context.
* @return the VelocityEngine
*/
VelocityEngine getVelocityEngine();
}

View File

@@ -1,151 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.io.IOException;
import javax.servlet.ServletContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.web.context.ServletContextAware;
/**
* JavaBean to configure Velocity for web usage, via the "configLocation"
* and/or "velocityProperties" and/or "resourceLoaderPath" bean properties.
* The simplest way to use this class is to specify just a "resourceLoaderPath";
* you do not need any further configuration then.
*
* <pre class="code">
* &lt;bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"&gt;
* &lt;property name="resourceLoaderPath">&lt;value&gt;/WEB-INF/velocity/&lt;/value>&lt;/property&gt;
* &lt;/bean&gt;</pre>
*
* This bean must be included in the application context of any application
* using Spring's {@link VelocityView} for web MVC. It exists purely to configure
* Velocity; it is not meant to be referenced by application components (just
* internally by VelocityView). This class implements {@link VelocityConfig}
* in order to be found by VelocityView without depending on the bean name of
* this configurer. Each DispatcherServlet may define its own VelocityConfigurer
* if desired, potentially with different template loader paths.
*
* <p>Note that you can also refer to a pre-configured VelocityEngine
* instance via the "velocityEngine" property, e.g. set up by
* {@link org.springframework.ui.velocity.VelocityEngineFactoryBean},
* This allows to share a VelocityEngine for web and email usage, for example.
*
* <p>This configurer registers the "spring.vm" Velocimacro library for web views
* (contained in this package and thus in {@code spring.jar}), which makes
* all of Spring's default Velocity macros available to the views.
* This allows for using the Spring-provided macros such as follows:
*
* <pre class="code">
* #springBind("person.age")
* age is ${status.value}</pre>
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Darren Davison
* @see #setConfigLocation
* @see #setVelocityProperties
* @see #setResourceLoaderPath
* @see #setVelocityEngine
* @see VelocityView
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public class VelocityConfigurer extends org.springframework.ui.velocity.VelocityEngineFactory
implements VelocityConfig, InitializingBean, ResourceLoaderAware, ServletContextAware {
/** the name of the resource loader for Spring's bind macros */
private static final String SPRING_MACRO_RESOURCE_LOADER_NAME = "springMacro";
/** the key for the class of Spring's bind macro resource loader */
private static final String SPRING_MACRO_RESOURCE_LOADER_CLASS = "springMacro.resource.loader.class";
/** the name of Spring's default bind macro library */
private static final String SPRING_MACRO_LIBRARY = "org/springframework/web/servlet/view/velocity/spring.vm";
private VelocityEngine velocityEngine;
private ServletContext servletContext;
/**
* Set a pre-configured VelocityEngine to use for the Velocity web
* configuration: e.g. a shared one for web and email usage, set up via
* {@link org.springframework.ui.velocity.VelocityEngineFactoryBean}.
* <p>Note that the Spring macros will <i>not</i> be enabled automatically in
* case of an external VelocityEngine passed in here. Make sure to include
* {@code spring.vm} in your template loader path in such a scenario
* (if there is an actual need to use those macros).
* <p>If this is not set, VelocityEngineFactory's properties
* (inherited by this class) have to be specified.
*/
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
/**
* Initialize VelocityEngineFactory's VelocityEngine
* if not overridden by a pre-configured VelocityEngine.
* @see #createVelocityEngine
* @see #setVelocityEngine
*/
@Override
public void afterPropertiesSet() throws IOException, VelocityException {
if (this.velocityEngine == null) {
this.velocityEngine = createVelocityEngine();
}
}
/**
* Provides a ClasspathResourceLoader in addition to any default or user-defined
* loader in order to load the spring Velocity macros from the class path.
* @see org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
*/
@Override
protected void postProcessVelocityEngine(VelocityEngine velocityEngine) {
velocityEngine.setApplicationAttribute(ServletContext.class.getName(), this.servletContext);
velocityEngine.setProperty(
SPRING_MACRO_RESOURCE_LOADER_CLASS, ClasspathResourceLoader.class.getName());
velocityEngine.addProperty(
VelocityEngine.RESOURCE_LOADER, SPRING_MACRO_RESOURCE_LOADER_NAME);
velocityEngine.addProperty(
VelocityEngine.VM_LIBRARY, SPRING_MACRO_LIBRARY);
if (logger.isInfoEnabled()) {
logger.info("ClasspathResourceLoader with name '" + SPRING_MACRO_RESOURCE_LOADER_NAME +
"' added to configured VelocityEngine");
}
}
@Override
public VelocityEngine getVelocityEngine() {
return this.velocityEngine;
}
}

View File

@@ -1,188 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.io.StringWriter;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.springframework.core.NestedIOException;
/**
* VelocityLayoutView emulates the functionality offered by Velocity's
* VelocityLayoutServlet to ease page composition from different templates.
*
* <p>The {@code url} property should be set to the content template
* for the view, and the layout template location should be specified as
* {@code layoutUrl} property. A view can override the configured
* layout template location by setting the appropriate key (the default
* is "layout") in the content template.
*
* <p>When the view is rendered, the VelocityContext is first merged with
* the content template (specified by the {@code url} property) and
* then merged with the layout template to produce the final output.
*
* <p>The layout template can include the screen content through a
* VelocityContext variable (the default is "screen_content").
* At runtime, this variable will contain the rendered content template.
*
* @author Darren Davison
* @author Juergen Hoeller
* @since 1.2
* @see #setLayoutUrl
* @see #setLayoutKey
* @see #setScreenContentKey
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public class VelocityLayoutView extends VelocityToolboxView {
/**
* The default {@link #setLayoutUrl(String) layout url}.
*/
public static final String DEFAULT_LAYOUT_URL = "layout.vm";
/**
* The default {@link #setLayoutKey(String) layout key}.
*/
public static final String DEFAULT_LAYOUT_KEY = "layout";
/**
* The default {@link #setScreenContentKey(String) screen content key}.
*/
public static final String DEFAULT_SCREEN_CONTENT_KEY = "screen_content";
private String layoutUrl = DEFAULT_LAYOUT_URL;
private String layoutKey = DEFAULT_LAYOUT_KEY;
private String screenContentKey = DEFAULT_SCREEN_CONTENT_KEY;
/**
* Set the layout template to use. Default is {@link #DEFAULT_LAYOUT_URL "layout.vm"}.
* @param layoutUrl the template location (relative to the template
* root directory)
*/
public void setLayoutUrl(String layoutUrl) {
this.layoutUrl = layoutUrl;
}
/**
* Set the context key used to specify an alternate layout to be used instead
* of the default layout. Screen content templates can override the layout
* template that they wish to be wrapped with by setting this value in the
* template, for example:<br>
* {@code #set($layout = "MyLayout.vm" )}
* <p>Default key is {@link #DEFAULT_LAYOUT_KEY "layout"}, as illustrated above.
* @param layoutKey the name of the key you wish to use in your
* screen content templates to override the layout template
*/
public void setLayoutKey(String layoutKey) {
this.layoutKey = layoutKey;
}
/**
* Set the name of the context key that will hold the content of
* the screen within the layout template. This key must be present
* in the layout template for the current screen to be rendered.
* <p>Default is {@link #DEFAULT_SCREEN_CONTENT_KEY "screen_content"}:
* accessed in VTL as {@code $screen_content}.
* @param screenContentKey the name of the screen content key to use
*/
public void setScreenContentKey(String screenContentKey) {
this.screenContentKey = screenContentKey;
}
/**
* Overrides {@code VelocityView.checkTemplate()} to additionally check
* that both the layout template and the screen content template can be loaded.
* Note that during rendering of the screen content, the layout template
* can be changed which may invalidate any early checking done here.
*/
@Override
public boolean checkResource(Locale locale) throws Exception {
if (!super.checkResource(locale)) {
return false;
}
try {
// Check that we can get the template, even if we might subsequently get it again.
getTemplate(this.layoutUrl);
return true;
}
catch (ResourceNotFoundException ex) {
throw new NestedIOException("Cannot find Velocity template for URL [" + this.layoutUrl +
"]: Did you specify the correct resource loader path?", ex);
}
catch (Exception ex) {
throw new NestedIOException(
"Could not load Velocity template for URL [" + this.layoutUrl + "]", ex);
}
}
/**
* Overrides the normal rendering process in order to pre-process the Context,
* merging it with the screen template into a single value (identified by the
* value of screenContentKey). The layout template is then merged with the
* modified Context in the super class.
*/
@Override
protected void doRender(Context context, HttpServletResponse response) throws Exception {
renderScreenContent(context);
// Velocity context now includes any mappings that were defined
// (via #set) in screen content template.
// The screen template can overrule the layout by doing
// #set( $layout = "MyLayout.vm" )
String layoutUrlToUse = (String) context.get(this.layoutKey);
if (layoutUrlToUse != null) {
if (logger.isDebugEnabled()) {
logger.debug("Screen content template has requested layout [" + layoutUrlToUse + "]");
}
}
else {
// No explicit layout URL given -> use default layout of this view.
layoutUrlToUse = this.layoutUrl;
}
mergeTemplate(getTemplate(layoutUrlToUse), context, response);
}
/**
* The resulting context contains any mappings from render, plus screen content.
*/
private void renderScreenContent(Context velocityContext) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug("Rendering screen content template [" + getUrl() + "]");
}
StringWriter sw = new StringWriter();
Template screenContentTemplate = getTemplate(getUrl());
screenContentTemplate.merge(velocityContext, sw);
// Put rendered content into Velocity context.
velocityContext.put(this.screenContentKey, sw.toString());
}
}

View File

@@ -1,110 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
/**
* Convenience subclass of VelocityViewResolver, adding support
* for VelocityLayoutView and its properties.
*
* <p>See VelocityViewResolver's javadoc for general usage info.
*
* @author Juergen Hoeller
* @since 1.2.7
* @see VelocityViewResolver
* @see VelocityLayoutView
* @see #setLayoutUrl
* @see #setLayoutKey
* @see #setScreenContentKey
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public class VelocityLayoutViewResolver extends VelocityViewResolver {
private String layoutUrl;
private String layoutKey;
private String screenContentKey;
/**
* Requires VelocityLayoutView.
* @see VelocityLayoutView
*/
@Override
protected Class<?> requiredViewClass() {
return VelocityLayoutView.class;
}
/**
* Set the layout template to use. Default is "layout.vm".
* @param layoutUrl the template location (relative to the template
* root directory)
* @see VelocityLayoutView#setLayoutUrl
*/
public void setLayoutUrl(String layoutUrl) {
this.layoutUrl = layoutUrl;
}
/**
* Set the context key used to specify an alternate layout to be used instead
* of the default layout. Screen content templates can override the layout
* template that they wish to be wrapped with by setting this value in the
* template, for example:<br>
* {@code #set($layout = "MyLayout.vm" )}
* <p>The default key is "layout", as illustrated above.
* @param layoutKey the name of the key you wish to use in your
* screen content templates to override the layout template
* @see VelocityLayoutView#setLayoutKey
*/
public void setLayoutKey(String layoutKey) {
this.layoutKey = layoutKey;
}
/**
* Set the name of the context key that will hold the content of
* the screen within the layout template. This key must be present
* in the layout template for the current screen to be rendered.
* <p>Default is "screen_content": accessed in VTL as
* {@code $screen_content}.
* @param screenContentKey the name of the screen content key to use
* @see VelocityLayoutView#setScreenContentKey
*/
public void setScreenContentKey(String screenContentKey) {
this.screenContentKey = screenContentKey;
}
@Override
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
VelocityLayoutView view = (VelocityLayoutView) super.buildView(viewName);
// Use not-null checks to preserve VelocityLayoutView's defaults.
if (this.layoutUrl != null) {
view.setLayoutUrl(this.layoutUrl);
}
if (this.layoutKey != null) {
view.setLayoutKey(this.layoutKey);
}
if (this.screenContentKey != null) {
view.setScreenContentKey(this.screenContentKey);
}
return view;
}
}

View File

@@ -1,134 +0,0 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.ToolboxManager;
import org.apache.velocity.tools.view.context.ChainedContext;
import org.apache.velocity.tools.view.servlet.ServletToolboxManager;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
/**
* {@link VelocityView} subclass which adds support for Velocity Tools toolboxes
* and Velocity Tools ViewTool callbacks / Velocity Tools 1.3 init methods.
*
* <p>Specify a "toolboxConfigLocation", for example "/WEB-INF/toolbox.xml",
* to automatically load a Velocity Tools toolbox definition file and expose
* all defined tools in the specified scopes. If no config location is
* specified, no toolbox will be loaded and exposed.
*
* <p>This view will always create a special Velocity context, namely an
* instance of the ChainedContext class which is part of the view package
* of Velocity tools. This allows to use tools from the view package of
* Velocity Tools, like LinkTool, which need to be initialized with a special
* context that implements the ViewContext interface (i.e. a ChainedContext).
*
* <p>This view also checks tools that are specified as "toolAttributes":
* If they implement the ViewTool interface, they will get initialized with
* the Velocity context. This allows tools from the view package of Velocity
* Tools, such as LinkTool, to be defined as
* {@link #setToolAttributes "toolAttributes"} on a VelocityToolboxView,
* instead of in a separate toolbox XML file.
*
* <p>This is a separate class mainly to avoid a required dependency on
* the view package of Velocity Tools in {@link VelocityView} itself.
* As of Spring 3.0, this class requires Velocity Tools 1.3 or higher.
*
* @author Juergen Hoeller
* @since 1.1.3
* @see #setToolboxConfigLocation
* @see #initTool
* @see org.apache.velocity.tools.view.context.ViewContext
* @see org.apache.velocity.tools.view.context.ChainedContext
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public class VelocityToolboxView extends VelocityView {
private String toolboxConfigLocation;
/**
* Set a Velocity Toolbox config location, for example "/WEB-INF/toolbox.xml",
* to automatically load a Velocity Tools toolbox definition file and expose
* all defined tools in the specified scopes. If no config location is
* specified, no toolbox will be loaded and exposed.
* <p>The specified location string needs to refer to a ServletContext
* resource, as expected by ServletToolboxManager which is part of
* the view package of Velocity Tools.
* @see org.apache.velocity.tools.view.servlet.ServletToolboxManager#getInstance
*/
public void setToolboxConfigLocation(String toolboxConfigLocation) {
this.toolboxConfigLocation = toolboxConfigLocation;
}
/**
* Return the Velocity Toolbox config location, if any.
*/
protected String getToolboxConfigLocation() {
return this.toolboxConfigLocation;
}
/**
* Overridden to create a ChainedContext, which is part of the view package
* of Velocity Tools, as special context. ChainedContext is needed for
* initialization of ViewTool instances.
* @see #initTool
*/
@Override
protected Context createVelocityContext(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Create a ChainedContext instance.
ChainedContext velocityContext = new ChainedContext(
new VelocityContext(model), getVelocityEngine(), request, response, getServletContext());
// Load a Velocity Tools toolbox, if necessary.
if (getToolboxConfigLocation() != null) {
ToolboxManager toolboxManager = ServletToolboxManager.getInstance(
getServletContext(), getToolboxConfigLocation());
Map<?, ?> toolboxContext = toolboxManager.getToolbox(velocityContext);
velocityContext.setToolbox(toolboxContext);
}
return velocityContext;
}
/**
* Overridden to check for the ViewContext interface which is part of the
* view package of Velocity Tools. This requires a special Velocity context,
* like ChainedContext as set up by {@link #createVelocityContext} in this class.
*/
@Override
protected void initTool(Object tool, Context velocityContext) throws Exception {
// Velocity Tools 1.3: a class-level "init(Object)" method.
Method initMethod = ClassUtils.getMethodIfAvailable(tool.getClass(), "init", Object.class);
if (initMethod != null) {
ReflectionUtils.invokeMethod(initMethod, tool, velocityContext);
}
}
}

View File

@@ -1,578 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContextException;
import org.springframework.core.NestedIOException;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.AbstractTemplateView;
import org.springframework.web.util.NestedServletException;
/**
* View using the Velocity template engine.
*
* <p>Exposes the following JavaBean properties:
* <ul>
* <li><b>url</b>: the location of the Velocity template to be wrapped,
* relative to the Velocity resource loader path (see VelocityConfigurer).
* <li><b>encoding</b> (optional, default is determined by Velocity configuration):
* the encoding of the Velocity template file
* <li><b>velocityFormatterAttribute</b> (optional, default=null): the name of
* the VelocityFormatter helper object to expose in the Velocity context of this
* view, or {@code null} if not needed. VelocityFormatter is part of standard Velocity.
* <li><b>dateToolAttribute</b> (optional, default=null): the name of the
* DateTool helper object to expose in the Velocity context of this view,
* or {@code null} if not needed. DateTool is part of Velocity Tools.
* <li><b>numberToolAttribute</b> (optional, default=null): the name of the
* NumberTool helper object to expose in the Velocity context of this view,
* or {@code null} if not needed. NumberTool is part of Velocity Tools.
* <li><b>cacheTemplate</b> (optional, default=false): whether or not the Velocity
* template should be cached. It should normally be true in production, but setting
* this to false enables us to modify Velocity templates without restarting the
* application (similar to JSPs). Note that this is a minor optimization only,
* as Velocity itself caches templates in a modification-aware fashion.
* </ul>
*
* <p>Depends on a VelocityConfig object such as VelocityConfigurer being
* accessible in the current web application context, with any bean name.
* Alternatively, you can set the VelocityEngine object as bean property.
*
* <p>Note: Spring 3.0's VelocityView requires Velocity 1.4 or higher, and optionally
* Velocity Tools 1.1 or higher (depending on the use of DateTool and/or NumberTool).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Dave Syer
* @see VelocityConfig
* @see VelocityConfigurer
* @see #setUrl
* @see #setExposeSpringMacroHelpers
* @see #setEncoding
* @see #setVelocityEngine
* @see VelocityConfig
* @see VelocityConfigurer
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public class VelocityView extends AbstractTemplateView {
private Map<String, Class<?>> toolAttributes;
private String dateToolAttribute;
private String numberToolAttribute;
private String encoding;
private boolean cacheTemplate = false;
private VelocityEngine velocityEngine;
private Template template;
/**
* Set tool attributes to expose to the view, as attribute name / class name pairs.
* An instance of the given class will be added to the Velocity context for each
* rendering operation, under the given attribute name.
* <p>For example, an instance of MathTool, which is part of the generic package
* of Velocity Tools, can be bound under the attribute name "math", specifying the
* fully qualified class name "org.apache.velocity.tools.generic.MathTool" as value.
* <p>Note that VelocityView can only create simple generic tools or values, that is,
* classes with a public default constructor and no further initialization needs.
* This class does not do any further checks, to not introduce a required dependency
* on a specific tools package.
* <p>For tools that are part of the view package of Velocity Tools, a special
* Velocity context and a special init callback are needed. Use VelocityToolboxView
* in such a case, or override {@code createVelocityContext} and
* {@code initTool} accordingly.
* <p>For a simple VelocityFormatter instance or special locale-aware instances
* of DateTool/NumberTool, which are part of the generic package of Velocity Tools,
* specify the "velocityFormatterAttribute", "dateToolAttribute" or
* "numberToolAttribute" properties, respectively.
* @param toolAttributes attribute names as keys, and tool class names as values
* @see org.apache.velocity.tools.generic.MathTool
* @see VelocityToolboxView
* @see #createVelocityContext
* @see #initTool
* @see #setDateToolAttribute
* @see #setNumberToolAttribute
*/
public void setToolAttributes(Map<String, Class<?>> toolAttributes) {
this.toolAttributes = toolAttributes;
}
/**
* Set the name of the DateTool helper object to expose in the Velocity context
* of this view, or {@code null} if not needed. The exposed DateTool will be aware of
* the current locale, as determined by Spring's LocaleResolver.
* <p>DateTool is part of the generic package of Velocity Tools 1.0.
* Spring uses a special locale-aware subclass of DateTool.
* @see org.apache.velocity.tools.generic.DateTool
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
* @see org.springframework.web.servlet.LocaleResolver
*/
public void setDateToolAttribute(String dateToolAttribute) {
this.dateToolAttribute = dateToolAttribute;
}
/**
* Set the name of the NumberTool helper object to expose in the Velocity context
* of this view, or {@code null} if not needed. The exposed NumberTool will be aware of
* the current locale, as determined by Spring's LocaleResolver.
* <p>NumberTool is part of the generic package of Velocity Tools 1.1.
* Spring uses a special locale-aware subclass of NumberTool.
* @see org.apache.velocity.tools.generic.NumberTool
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
* @see org.springframework.web.servlet.LocaleResolver
*/
public void setNumberToolAttribute(String numberToolAttribute) {
this.numberToolAttribute = numberToolAttribute;
}
/**
* Set the encoding of the Velocity template file. Default is determined
* by the VelocityEngine: "ISO-8859-1" if not specified otherwise.
* <p>Specify the encoding in the VelocityEngine rather than per template
* if all your templates share a common encoding.
*/
public void setEncoding(String encoding) {
this.encoding = encoding;
}
/**
* Return the encoding for the Velocity template.
*/
protected String getEncoding() {
return this.encoding;
}
/**
* Set whether the Velocity template should be cached. Default is "false".
* It should normally be true in production, but setting this to false enables us to
* modify Velocity templates without restarting the application (similar to JSPs).
* <p>Note that this is a minor optimization only, as Velocity itself caches
* templates in a modification-aware fashion.
*/
public void setCacheTemplate(boolean cacheTemplate) {
this.cacheTemplate = cacheTemplate;
}
/**
* Return whether the Velocity template should be cached.
*/
protected boolean isCacheTemplate() {
return this.cacheTemplate;
}
/**
* Set the VelocityEngine to be used by this view.
* <p>If this is not set, the default lookup will occur: A single VelocityConfig
* is expected in the current web application context, with any bean name.
* @see VelocityConfig
*/
public void setVelocityEngine(VelocityEngine velocityEngine) {
this.velocityEngine = velocityEngine;
}
/**
* Return the VelocityEngine used by this view.
*/
protected VelocityEngine getVelocityEngine() {
return this.velocityEngine;
}
/**
* 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());
}
}
/**
* 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);
}
}
/**
* 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);
}
}
/**
* 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);
}
/**
* 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}. The default implementation
* is empty. This method can be overridden to add custom helpers to the model.
* @param model the model that will be passed to the template for merging
* @param request current HTTP request
* @throws Exception if there's a fatal error while we're adding model attributes
* @see #renderMergedTemplateModel
*/
protected void exposeHelpers(Map<String, Object> model, HttpServletRequest request) throws Exception {
}
/**
* 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);
}
/**
* Create a Velocity Context instance for the given model,
* to be passed to the template for merging.
* <p>Default implementation creates an instance of Velocity's
* VelocityContext implementation class.
* @param model the model Map, containing the model attributes
* to be exposed to the view
* @return the Velocity Context
* @throws Exception if there's a fatal error while creating the context
* @see org.apache.velocity.VelocityContext
*/
protected Context createVelocityContext(Map<String, Object> model) throws Exception {
return new VelocityContext(model);
}
/**
* 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(org.apache.velocity.context.Context, HttpServletRequest)
*/
protected void exposeHelpers(
Context velocityContext, HttpServletRequest request, HttpServletResponse response) throws Exception {
exposeHelpers(velocityContext, request);
}
/**
* Expose helpers unique to each rendering operation. This is necessary so that
* different rendering operations can't overwrite each other's formats etc.
* <p>Default implementation is empty. This method can be overridden to add
* custom helpers to the Velocity context.
* @param velocityContext Velocity context that will be passed to the template
* @param request current HTTP request
* @throws Exception if there's a fatal error while we're adding model attributes
* @see #exposeHelpers(Map, HttpServletRequest)
*/
protected void exposeHelpers(Context velocityContext, HttpServletRequest request) throws Exception {
}
/**
* Expose the tool attributes, according to corresponding bean property settings.
* <p>Do not override this method unless for further tools driven by bean properties.
* Override one of the {@code exposeHelpers} methods to add custom helpers.
* @param velocityContext Velocity context that will be passed to the template
* @param request current HTTP request
* @throws Exception if there's a fatal error while we're adding model attributes
* @see #setDateToolAttribute
* @see #setNumberToolAttribute
* @see #exposeHelpers(Map, HttpServletRequest)
* @see #exposeHelpers(org.apache.velocity.context.Context, HttpServletRequest, HttpServletResponse)
*/
protected void exposeToolAttributes(Context velocityContext, HttpServletRequest request) throws Exception {
// Expose generic attributes.
if (this.toolAttributes != null) {
for (Map.Entry<String, Class<?>> entry : this.toolAttributes.entrySet()) {
String attributeName = entry.getKey();
Class<?> toolClass = entry.getValue();
try {
Object tool = toolClass.newInstance();
initTool(tool, velocityContext);
velocityContext.put(attributeName, tool);
}
catch (Exception ex) {
throw new NestedServletException("Could not instantiate Velocity tool '" + attributeName + "'", ex);
}
}
}
// Expose locale-aware DateTool/NumberTool attributes.
if (this.dateToolAttribute != null || this.numberToolAttribute != null) {
if (this.dateToolAttribute != null) {
velocityContext.put(this.dateToolAttribute, new LocaleAwareDateTool(request));
}
if (this.numberToolAttribute != null) {
velocityContext.put(this.numberToolAttribute, new LocaleAwareNumberTool(request));
}
}
}
/**
* Initialize the given tool instance. The default implementation is empty.
* <p>Can be overridden to check for special callback interfaces, for example
* the ViewContext interface which is part of the view package of Velocity Tools.
* In the particular case of ViewContext, you'll usually also need a special
* Velocity context, like ChainedContext which is part of Velocity Tools too.
* <p>Have a look at {@link VelocityToolboxView}, which pre-implements such a
* ViewTool check. This is not part of the standard VelocityView class in order
* to avoid a required dependency on the view package of Velocity Tools.
* @param tool the tool instance to initialize
* @param velocityContext the Velocity context
* @throws Exception if initializion of the tool failed
* @see #createVelocityContext
* @see org.apache.velocity.tools.view.context.ViewContext
* @see org.apache.velocity.tools.view.context.ChainedContext
* @see VelocityToolboxView
*/
protected void initTool(Object tool, Context velocityContext) throws Exception {
}
/**
* 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 org.apache.velocity.app.VelocityEngine#getTemplate
*/
protected Template getTemplate(String name) throws Exception {
return (getEncoding() != null ?
getVelocityEngine().getTemplate(name, getEncoding()) :
getVelocityEngine().getTemplate(name));
}
/**
* 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 org.apache.velocity.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);
}
}
/**
* Subclass of DateTool from Velocity Tools, using a Spring-resolved
* Locale and TimeZone instead of the default Locale.
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
* @see org.springframework.web.servlet.support.RequestContextUtils#getTimeZone
*/
private static class LocaleAwareDateTool extends DateTool {
private final HttpServletRequest request;
public LocaleAwareDateTool(HttpServletRequest request) {
this.request = request;
}
@Override
public Locale getLocale() {
return RequestContextUtils.getLocale(this.request);
}
@Override
public TimeZone getTimeZone() {
TimeZone timeZone = RequestContextUtils.getTimeZone(this.request);
return (timeZone != null ? timeZone : super.getTimeZone());
}
}
/**
* Subclass of NumberTool from Velocity Tools, using a Spring-resolved
* Locale instead of the default Locale.
* @see org.springframework.web.servlet.support.RequestContextUtils#getLocale
*/
private static class LocaleAwareNumberTool extends NumberTool {
private final HttpServletRequest request;
public LocaleAwareNumberTool(HttpServletRequest request) {
this.request = request;
}
@Override
public Locale getLocale() {
return RequestContextUtils.getLocale(this.request);
}
}
}

View File

@@ -1,137 +0,0 @@
/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
/**
* Convenience subclass of {@link org.springframework.web.servlet.view.UrlBasedViewResolver}
* that supports {@link VelocityView} (i.e. Velocity templates) and custom subclasses of it.
*
* <p>The view class for all views generated by this resolver can be specified
* via the "viewClass" property. See UrlBasedViewResolver's javadoc for details.
*
* <p><b>Note:</b> When chaining ViewResolvers, a VelocityViewResolver will
* check for the existence of the specified template resources and only return
* a non-null View object if the template was actually found.
*
* @author Juergen Hoeller
* @since 13.12.2003
* @see #setViewClass
* @see #setPrefix
* @see #setSuffix
* @see #setRequestContextAttribute
* @see #setExposeSpringMacroHelpers
* @see #setDateToolAttribute
* @see #setNumberToolAttribute
* @see VelocityView
* @deprecated as of Spring 4.3, in favor of FreeMarker
*/
@Deprecated
public class VelocityViewResolver extends AbstractTemplateViewResolver {
private String dateToolAttribute;
private String numberToolAttribute;
private String toolboxConfigLocation;
public VelocityViewResolver() {
setViewClass(requiredViewClass());
}
/**
* Requires {@link VelocityView}.
*/
@Override
protected Class<?> requiredViewClass() {
return VelocityView.class;
}
/**
* Set the name of the DateTool helper object to expose in the Velocity context
* of this view, or {@code null} if not needed. DateTool is part of Velocity Tools 1.0.
* @see org.apache.velocity.tools.generic.DateTool
* @see VelocityView#setDateToolAttribute
*/
public void setDateToolAttribute(String dateToolAttribute) {
this.dateToolAttribute = dateToolAttribute;
}
/**
* Set the name of the NumberTool helper object to expose in the Velocity context
* of this view, or {@code null} if not needed. NumberTool is part of Velocity Tools 1.1.
* @see org.apache.velocity.tools.generic.NumberTool
* @see VelocityView#setNumberToolAttribute
*/
public void setNumberToolAttribute(String numberToolAttribute) {
this.numberToolAttribute = numberToolAttribute;
}
/**
* Set a Velocity Toolbox config location, for example "/WEB-INF/toolbox.xml",
* to automatically load a Velocity Tools toolbox definition file and expose
* all defined tools in the specified scopes. If no config location is
* specified, no toolbox will be loaded and exposed.
* <p>The specified location string needs to refer to a ServletContext
* resource, as expected by ServletToolboxManager which is part of
* the view package of Velocity Tools.
* <p><b>Note:</b> Specifying a toolbox config location will lead to
* VelocityToolboxView instances being created.
* @see org.apache.velocity.tools.view.servlet.ServletToolboxManager#getInstance
* @see VelocityToolboxView#setToolboxConfigLocation
*/
public void setToolboxConfigLocation(String toolboxConfigLocation) {
this.toolboxConfigLocation = toolboxConfigLocation;
}
@Override
protected void initApplicationContext() {
super.initApplicationContext();
if (this.toolboxConfigLocation != null) {
if (VelocityView.class == getViewClass()) {
logger.info("Using VelocityToolboxView instead of default VelocityView " +
"due to specified toolboxConfigLocation");
setViewClass(VelocityToolboxView.class);
}
else if (!VelocityToolboxView.class.isAssignableFrom(getViewClass())) {
throw new IllegalArgumentException(
"Given view class [" + getViewClass().getName() +
"] is not of type [" + VelocityToolboxView.class.getName() +
"], which it needs to be in case of a specified toolboxConfigLocation");
}
}
}
@Override
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
VelocityView view = (VelocityView) super.buildView(viewName);
view.setDateToolAttribute(this.dateToolAttribute);
view.setNumberToolAttribute(this.numberToolAttribute);
if (this.toolboxConfigLocation != null) {
((VelocityToolboxView) view).setToolboxConfigLocation(this.toolboxConfigLocation);
}
return view;
}
}

View File

@@ -1,7 +0,0 @@
/**
* Support classes for the integration of
* <a href="http://velocity.apache.org">Velocity</a>
* as Spring web view technology.
* Contains a View implementation for Velocity templates.
*/
package org.springframework.web.servlet.view.velocity;

View File

@@ -1,320 +0,0 @@
#**
* spring.vm
*
* This file consists of a collection of Velocity macros aimed at easing
* some of the common requirements of web applications - in particular
* handling of forms.
*
* Spring's Velocity support will automatically make this file and therefore
* all macros within it available to any application using Spring's
* VelocityConfigurer.
*
* To take advantage of these macros, the "exposeSpringMacroHelpers" property
* of the VelocityView class needs to be set to "true". This will expose a
* RequestContext under the name "springMacroRequestContext", as needed by
* the macros in this library.
*
* @author Darren Davison
* @author Juergen Hoeller
* @since 1.1
*#
#**
* springMessage
*
* Macro to translate a message code into a message.
*#
#macro( springMessage $code )$springMacroRequestContext.getMessage($code)#end
#**
* springMessageText
*
* Macro to translate a message code into a message,
* using the given default text if no message found.
*#
#macro( springMessageText $code $text )$springMacroRequestContext.getMessage($code, $text)#end
#**
* springTheme
*
* Macro to translate a theme message code into a string.
*#
#macro( springTheme $code )$springMacroRequestContext.getThemeMessage($code)#end
#**
* springThemeText
*
* Macro to translate a theme message code into a string,
* using the given default text if no message found.
*#
#macro( springThemeText $code $text )$springMacroRequestContext.getThemeMessage($code, $text)#end
#**
* springUrl
*
* Takes a relative URL and makes it absolute from the server root by
* adding the context root for the web application.
*#
#macro( springUrl $relativeUrl )$springMacroRequestContext.getContextUrl(${relativeUrl})#end
#**
* springBind
*
* Exposes a BindStatus object for the given bind path, which can be
* a bean (e.g. "person") to get global errors, or a bean property
* (e.g. "person.name") to get field errors. Can be called multiple times
* within a form to bind to multiple command objects and/or field names.
*
* This macro will participate in the default HTML escape setting for the given
* RequestContext. This can be customized by calling "setDefaultHtmlEscape"
* on the "springMacroRequestContext" context variable, or via the
* "defaultHtmlEscape" context-param in web.xml (same as for the JSP bind tag).
* Also regards a "springHtmlEscape" variable in the template context.
*
* Producing no output, the following context variable will be available
* each time this macro is referenced:
*
* $status : a BindStatus instance holding the command object name,
* expression, value, and error codes and messages for the path supplied
*
* @param $path : the path (string value) of the value required to bind to.
* Spring defaults to a command name of "command" but this can be overridden
* by user config.
*#
#macro( springBind $path )
#if("$!springHtmlEscape"!="")
#set( $status = $springMacroRequestContext.getBindStatus($path, $springHtmlEscape) )
#else
#set( $status = $springMacroRequestContext.getBindStatus($path) )
#end
#end
#**
* springBindEscaped
*
* Similar to springBind, but takes an explicit HTML escape flag rather
* than relying on the default HTML escape setting.
*#
#macro( springBindEscaped $path $htmlEscape )
#set( $status = $springMacroRequestContext.getBindStatus($path, $htmlEscape) )
#end
#**
* springFormInput
*
* Display a form input field of type 'text' and bind it to an attribute
* of a command or bean.
*
* @param path the name of the field to bind to
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*
*#
#macro( springFormInput $path $attributes )
#springBind($path)
<input type="text" id="#springXmlId(${status.expression})" name="${status.expression}" value="$!status.value" ${attributes}#springCloseTag()
#end
#**
* springFormPasswordInput
*
* Display a form input field of type 'password' and bind it to an attribute
* of a command or bean. No value will ever be specified for this field regardless
* of whether one exists or not. For hopefully obvious reasons!
*
* @param path the name of the field to bind to
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*
*#
#macro( springFormPasswordInput $path $attributes )
#springBind($path)
<input type="password" id="#springXmlId(${status.expression})" name="${status.expression}" value="" ${attributes}#springCloseTag()
#end
#**
* springFormHiddenInput
*
* Generate a form input field of type 'hidden' and bind it to an attribute
* of a command or bean.
*
* @param path the name of the field to bind to
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*
*#
#macro( springFormHiddenInput $path $attributes )
#springBind($path)
<input type="hidden" id="#springXmlId(${status.expression})" name="${status.expression}" value="$!status.value" ${attributes}#springCloseTag()
#end
#**
* formTextArea
*
* display a text area and bind it to an attribute
* of a command or bean
*
* @param path the name of the field to bind to
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*
*#
#macro( springFormTextarea $path $attributes )
#springBind($path)
<textarea id="#springXmlId(${status.expression})" name="${status.expression}" ${attributes}>
$!status.value</textarea>
#end
#**
* springFormSingleSelect
*
* Show a selectbox (dropdown) input element allowing a single value to be chosen
* from a list of options.
*
* The null check for $status.value leverages Velocity's 'quiet' notation rather
* than the more common #if($status.value) since this method evaluates to the
* boolean 'false' if the content of $status.value is the String "false" - not
* what we want.
*
* @param path the name of the field to bind to
* @param options a map (value=label) of all the available options
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*#
#macro( springFormSingleSelect $path $options $attributes )
#springBind($path)
<select id="#springXmlId(${status.expression})" name="${status.expression}" ${attributes}>
#foreach($option in $options.keySet())
<option value="${option}"
#if("$!status.value"=="$option") selected="selected" #end>
${options.get($option)}</option>
#end
</select>
#end
#**
* springFormMultiSelect
*
* Show a listbox of options allowing the user to make 0 or more choices from
* the list of options.
*
* @param path the name of the field to bind to
* @param options a map (value=label) of all the available options
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*#
#macro( springFormMultiSelect $path $options $attributes )
#springBind($path)
<select multiple="multiple" id="#springXmlId(${status.expression})" name="${status.expression}" ${attributes}>
#foreach($option in $options.keySet())
<option value="${option}"
#foreach($item in $status.actualValue)
#if($item==$option) selected="selected" #end
#end
>${options.get($option)}</option>
#end
</select>
#end
#**
* springFormRadioButtons
*
* Show radio buttons.
*
* @param path the name of the field to bind to
* @param options a map (value=label) of all the available options
* @param separator the html tag or other character list that should be used to
* separate each option. Typically '&nbsp;' or '<br>'
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*#
#macro( springFormRadioButtons $path $options $separator $attributes )
#springBind($path)
#foreach($option in $options.keySet())
<input type="radio" name="${status.expression}" value="${option}"
#if("$!status.value"=="$option") checked="checked" #end
${attributes}
#springCloseTag()
${options.get($option)} ${separator}
#end
#end
#**
* springFormCheckboxes
*
* Show checkboxes.
*
* @param path the name of the field to bind to
* @param options a map (value=label) of all the available options
* @param separator the html tag or other character list that should be used to
* separate each option. Typically '&nbsp;' or '<br>'.
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*#
#macro( springFormCheckboxes $path $options $separator $attributes )
#springBind($path)
#foreach($option in $options.keySet())
<input type="checkbox" name="${status.expression}" value="${option}"
#foreach($item in $status.actualValue)
#if($item==$option) checked="checked" #end
#end
${attributes} #springCloseTag()
${options.get($option)} ${separator}
#end
<input type="hidden" name="_${status.expression}" value="on"/>
#end
#**
* springFormCheckbox
*
* Show a single checkbox.
*
* @param path the name of the field to bind to
* @param attributes any additional attributes for the element (such as class
* or CSS styles or size)
*#
#macro( springFormCheckbox $path $attributes )
#springBind($path)
<input type="hidden" name="_#springXmlId(${status.expression})" value="on"/>
<input type="checkbox" id="#springXmlId(${status.expression})" name="${status.expression}"#if("$!{status.value}"=="true") checked="checked"#end ${attributes}/>
#end
#**
* springShowErrors
*
* Show validation errors for the currently bound field, with
* optional style attributes.
*
* @param separator the html tag or other character list that should be used to
* separate each option. Typically '<br>'.
* @param classOrStyle either the name of a CSS class element (which is defined in
* the template or an external CSS file) or an inline style. If the value passed in here
* contains a colon (:) then a 'style=' attribute will be used, else a 'class=' attribute
* will be used.
*#
#macro( springShowErrors $separator $classOrStyle )
#foreach($error in $status.errorMessages)
#if($classOrStyle=="")
<b>${error}</b>
#else
#if($classOrStyle.indexOf(":")==-1)
#set($attr="class")
#else
#set($attr="style")
#end
<span ${attr}="${classOrStyle}">${error}</span>
#end
${separator}
#end
#end
#**
* springCloseTag
*
* Simple macro to close an HTML tag that has no body with '>' or '/>',
* depending on the value of a 'springXhtmlCompliant' variable in the
* template context.
*#
#macro( springCloseTag )#if($springXhtmlCompliant)/>#else>#end#end
#macro( springXmlId $id)#if($id)$id.replaceAll("\[","").replaceAll("\]","")#else$id#end#end

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -141,8 +141,6 @@ import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver;
import org.springframework.web.servlet.view.tiles3.SpringBeanPreparerFactory;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
import org.springframework.web.util.UrlPathHelper;
import static org.hamcrest.CoreMatchers.*;
@@ -742,11 +740,11 @@ public class MvcNamespaceTests {
@Test
public void testViewResolution() throws Exception {
loadBeanDefinitions("mvc-config-view-resolution.xml", 7);
loadBeanDefinitions("mvc-config-view-resolution.xml", 6);
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
assertNotNull(compositeResolver);
assertEquals("Actual: " + compositeResolver.getViewResolvers(), 9, compositeResolver.getViewResolvers().size());
assertEquals("Actual: " + compositeResolver.getViewResolvers(), 8, compositeResolver.getViewResolvers().size());
assertEquals(Ordered.LOWEST_PRECEDENCE, compositeResolver.getOrder());
List<ViewResolver> resolvers = compositeResolver.getViewResolvers();
@@ -768,28 +766,21 @@ public class MvcNamespaceTests {
assertEquals(1024, accessor.getPropertyValue("cacheLimit"));
resolver = resolvers.get(4);
assertThat(resolver, instanceOf(VelocityViewResolver.class));
accessor = new DirectFieldAccessor(resolver);
assertEquals("", accessor.getPropertyValue("prefix"));
assertEquals(".vm", accessor.getPropertyValue("suffix"));
assertEquals(0, accessor.getPropertyValue("cacheLimit"));
resolver = resolvers.get(5);
assertThat(resolver, instanceOf(GroovyMarkupViewResolver.class));
accessor = new DirectFieldAccessor(resolver);
assertEquals("", accessor.getPropertyValue("prefix"));
assertEquals(".tpl", accessor.getPropertyValue("suffix"));
assertEquals(1024, accessor.getPropertyValue("cacheLimit"));
resolver = resolvers.get(6);
resolver = resolvers.get(5);
assertThat(resolver, instanceOf(ScriptTemplateViewResolver.class));
accessor = new DirectFieldAccessor(resolver);
assertEquals("", accessor.getPropertyValue("prefix"));
assertEquals("", accessor.getPropertyValue("suffix"));
assertEquals(1024, accessor.getPropertyValue("cacheLimit"));
assertEquals(InternalResourceViewResolver.class, resolvers.get(6).getClass());
assertEquals(InternalResourceViewResolver.class, resolvers.get(7).getClass());
assertEquals(InternalResourceViewResolver.class, resolvers.get(8).getClass());
TilesConfigurer tilesConfigurer = appContext.getBean(TilesConfigurer.class);
assertNotNull(tilesConfigurer);
@@ -808,11 +799,6 @@ public class MvcNamespaceTests {
accessor = new DirectFieldAccessor(freeMarkerConfigurer);
assertArrayEquals(new String[] {"/", "/test"}, (String[]) accessor.getPropertyValue("templateLoaderPaths"));
VelocityConfigurer velocityConfigurer = appContext.getBean(VelocityConfigurer.class);
assertNotNull(velocityConfigurer);
accessor = new DirectFieldAccessor(velocityConfigurer);
assertEquals("/test", accessor.getPropertyValue("resourceLoaderPath"));
GroovyMarkupConfigurer groovyMarkupConfigurer = appContext.getBean(GroovyMarkupConfigurer.class);
assertNotNull(groovyMarkupConfigurer);
assertEquals("/test", groovyMarkupConfigurer.getResourceLoaderPath());
@@ -833,7 +819,7 @@ public class MvcNamespaceTests {
@Test
public void testViewResolutionWithContentNegotiation() throws Exception {
loadBeanDefinitions("mvc-config-view-resolution-content-negotiation.xml", 7);
loadBeanDefinitions("mvc-config-view-resolution-content-negotiation.xml", 6);
ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class);
assertNotNull(compositeResolver);
@@ -843,7 +829,7 @@ public class MvcNamespaceTests {
List<ViewResolver> resolvers = compositeResolver.getViewResolvers();
assertEquals(ContentNegotiatingViewResolver.class, resolvers.get(0).getClass());
ContentNegotiatingViewResolver cnvr = (ContentNegotiatingViewResolver) resolvers.get(0);
assertEquals(7, cnvr.getViewResolvers().size());
assertEquals(6, cnvr.getViewResolvers().size());
assertEquals(1, cnvr.getDefaultViews().size());
assertTrue(cnvr.isUseNotAcceptableStatusCode());

View File

@@ -39,7 +39,6 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import org.springframework.web.servlet.view.groovy.GroovyMarkupConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
import static org.junit.Assert.*;
@@ -61,12 +60,6 @@ public class ViewResolutionIntegrationTests {
assertEquals("<html><body>Hello World!</body></html>", response.getContentAsString());
}
@Test
public void velocity() throws Exception {
MockHttpServletResponse response = runTest(VelocityWebConfig.class);
assertEquals("<html><body>Hello World!</body></html>", response.getContentAsString());
}
@Test
public void tiles() throws Exception {
MockHttpServletResponse response = runTest(TilesWebConfig.class);
@@ -85,12 +78,6 @@ public class ViewResolutionIntegrationTests {
runTest(InvalidFreeMarkerWebConfig.class);
}
@Test
public void velocityInvalidConfig() throws Exception {
this.thrown.expectMessage("In addition to a Velocity view resolver ");
runTest(InvalidVelocityWebConfig.class);
}
@Test
public void tilesInvalidConfig() throws Exception {
this.thrown.expectMessage("In addition to a Tiles view resolver ");
@@ -165,22 +152,6 @@ public class ViewResolutionIntegrationTests {
}
}
@Configuration
static class VelocityWebConfig extends AbstractWebConfig {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.velocity();
}
@Bean
public VelocityConfigurer velocityConfigurer() {
VelocityConfigurer configurer = new VelocityConfigurer();
configurer.setResourceLoaderPath("/WEB-INF/");
return configurer;
}
}
@Configuration
static class TilesWebConfig extends AbstractWebConfig {
@@ -222,15 +193,6 @@ public class ViewResolutionIntegrationTests {
}
}
@Configuration
static class InvalidVelocityWebConfig extends WebMvcConfigurationSupport {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.velocity();
}
}
@Configuration
static class InvalidTilesWebConfig extends WebMvcConfigurationSupport {

View File

@@ -38,8 +38,6 @@ import org.springframework.web.servlet.view.script.ScriptTemplateConfigurer;
import org.springframework.web.servlet.view.script.ScriptTemplateViewResolver;
import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
import org.springframework.web.servlet.view.xml.MarshallingView;
import static org.junit.Assert.*;
@@ -59,7 +57,6 @@ public class ViewResolverRegistryTests {
public void setUp() {
StaticWebApplicationContext context = new StaticWebApplicationContext();
context.registerSingleton("freeMarkerConfigurer", FreeMarkerConfigurer.class);
context.registerSingleton("velocityConfigurer", VelocityConfigurer.class);
context.registerSingleton("tilesConfigurer", TilesConfigurer.class);
context.registerSingleton("groovyMarkupConfigurer", GroovyMarkupConfigurer.class);
context.registerSingleton("scriptTemplateConfigurer", ScriptTemplateConfigurer.class);
@@ -79,7 +76,7 @@ public class ViewResolverRegistryTests {
@Test
public void hasRegistrations() {
assertFalse(this.registry.hasRegistrations());
this.registry.velocity();
this.registry.freeMarker();
assertTrue(this.registry.hasRegistrations());
}
@@ -141,20 +138,6 @@ public class ViewResolverRegistryTests {
checkAndGetResolver(TilesViewResolver.class);
}
@Test
public void velocity() {
this.registry.velocity().prefix("/").suffix(".vm").cache(true);
VelocityViewResolver resolver = checkAndGetResolver(VelocityViewResolver.class);
checkPropertyValues(resolver, "prefix", "/", "suffix", ".vm", "cacheLimit", 1024);
}
@Test
public void velocityDefaultValues() {
this.registry.velocity();
VelocityViewResolver resolver = checkAndGetResolver(VelocityViewResolver.class);
checkPropertyValues(resolver, "prefix", "", "suffix", ".vm");
}
@Test
public void freeMarker() {
this.registry.freeMarker().prefix("/").suffix(".fmt").cache(false);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,6 @@ import java.util.Locale;
import org.junit.Test;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.web.servlet.view.velocity.VelocityView;
import static org.junit.Assert.*;
@@ -50,13 +49,6 @@ public class JasperReportViewResolverTests {
assertEquals("Incorrect URL", prefix + viewName + suffix, view.getUrl());
}
@Test(expected = IllegalArgumentException.class)
public void setIncorrectViewClass() {
// Should not be able to set view class to a class that does not extend
// AbstractJasperReportsView.
new JasperReportsViewResolver().setViewClass(VelocityView.class);
}
@Test
public void withViewNamesAndEndsWithPattern() throws Exception {
doViewNamesTest("DataSource*");

View File

@@ -1,56 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.ResourceNotFoundException;
/**
* @author Juergen Hoeller
* @since 09.10.2004
*/
class TestVelocityEngine extends VelocityEngine {
private final Map<String, Template> templates = new HashMap<>();
public TestVelocityEngine() {
}
public TestVelocityEngine(String expectedName, Template template) {
addTemplate(expectedName, template);
}
public void addTemplate(String expectedName, Template template) {
this.templates.put(expectedName, template);
}
@Override
public Template getTemplate(String name) throws ResourceNotFoundException {
Template template = this.templates.get(name);
if (template == null) {
throw new ResourceNotFoundException("No template registered for name [" + name + "]");
}
return template;
}
}

View File

@@ -1,171 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.VelocityException;
import org.junit.Test;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.DescriptiveResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.UrlResource;
import org.springframework.ui.velocity.VelocityEngineFactoryBean;
import org.springframework.ui.velocity.VelocityEngineUtils;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
/**
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class VelocityConfigurerTests {
@Test
public void velocityEngineFactoryBeanWithConfigLocation() throws VelocityException {
VelocityEngineFactoryBean vefb = new VelocityEngineFactoryBean();
vefb.setConfigLocation(new FileSystemResource("myprops.properties"));
Properties props = new Properties();
props.setProperty("myprop", "/mydir");
vefb.setVelocityProperties(props);
try {
vefb.afterPropertiesSet();
fail("Should have thrown IOException");
}
catch (IOException ex) {
// expected
}
}
@Test
public void velocityEngineFactoryBeanWithVelocityProperties() throws VelocityException, IOException {
VelocityEngineFactoryBean vefb = new VelocityEngineFactoryBean();
Properties props = new Properties();
props.setProperty("myprop", "/mydir");
vefb.setVelocityProperties(props);
Object value = new Object();
Map<String, Object> map = new HashMap<>();
map.put("myentry", value);
vefb.setVelocityPropertiesMap(map);
vefb.afterPropertiesSet();
assertThat(vefb.getObject(), instanceOf(VelocityEngine.class));
VelocityEngine ve = vefb.getObject();
assertEquals("/mydir", ve.getProperty("myprop"));
assertEquals(value, ve.getProperty("myentry"));
}
@Test
public void velocityEngineFactoryBeanWithResourceLoaderPath() throws IOException, VelocityException {
VelocityEngineFactoryBean vefb = new VelocityEngineFactoryBean();
vefb.setResourceLoaderPath("file:/mydir");
vefb.afterPropertiesSet();
assertThat(vefb.getObject(), instanceOf(VelocityEngine.class));
VelocityEngine ve = vefb.getObject();
assertEquals(new File("/mydir").getAbsolutePath(), ve.getProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH));
}
@Test
@SuppressWarnings("deprecation")
public void velocityEngineFactoryBeanWithNonFileResourceLoaderPath() throws Exception {
VelocityEngineFactoryBean vefb = new VelocityEngineFactoryBean();
vefb.setResourceLoaderPath("file:/mydir");
vefb.setResourceLoader(new ResourceLoader() {
@Override
public Resource getResource(String location) {
if (location.equals("file:/mydir") || location.equals("file:/mydir/test")) {
return new ByteArrayResource("test".getBytes(), "test");
}
try {
return new UrlResource(location);
}
catch (MalformedURLException ex) {
throw new IllegalArgumentException(ex.toString());
}
}
@Override
public ClassLoader getClassLoader() {
return getClass().getClassLoader();
}
});
vefb.afterPropertiesSet();
assertThat(vefb.getObject(), instanceOf(VelocityEngine.class));
VelocityEngine ve = vefb.getObject();
assertEquals("test", VelocityEngineUtils.mergeTemplateIntoString(ve, "test", Collections.emptyMap()));
}
@Test
public void velocityConfigurer() throws IOException, VelocityException {
VelocityConfigurer vc = new VelocityConfigurer();
vc.setResourceLoaderPath("file:/mydir");
vc.afterPropertiesSet();
assertThat(vc.createVelocityEngine(), instanceOf(VelocityEngine.class));
VelocityEngine ve = vc.createVelocityEngine();
assertEquals(new File("/mydir").getAbsolutePath(), ve.getProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH));
}
@Test
public void velocityConfigurerWithCsvPath() throws IOException, VelocityException {
VelocityConfigurer vc = new VelocityConfigurer();
vc.setResourceLoaderPath("file:/mydir,file:/yourdir");
vc.afterPropertiesSet();
assertThat(vc.createVelocityEngine(), instanceOf(VelocityEngine.class));
VelocityEngine ve = vc.createVelocityEngine();
Vector<String> paths = new Vector<>();
paths.add(new File("/mydir").getAbsolutePath());
paths.add(new File("/yourdir").getAbsolutePath());
assertEquals(paths, ve.getProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH));
}
@Test
@SuppressWarnings("deprecation")
public void velocityConfigurerWithCsvPathAndNonFileAccess() throws IOException, VelocityException {
VelocityConfigurer vc = new VelocityConfigurer();
vc.setResourceLoaderPath("file:/mydir,file:/yourdir");
vc.setResourceLoader(new ResourceLoader() {
@Override
public Resource getResource(String location) {
if ("file:/yourdir/test".equals(location)) {
return new DescriptiveResource("");
}
return new ByteArrayResource("test".getBytes(), "test");
}
@Override
public ClassLoader getClassLoader() {
return getClass().getClassLoader();
}
});
vc.setPreferFileSystemAccess(false);
vc.afterPropertiesSet();
assertThat(vc.createVelocityEngine(), instanceOf(VelocityEngine.class));
VelocityEngine ve = vc.createVelocityEngine();
assertEquals("test", VelocityEngineUtils.mergeTemplateIntoString(ve, "test", Collections.emptyMap()));
}
}

View File

@@ -1,266 +0,0 @@
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.support.BindStatus;
import org.springframework.web.servlet.support.RequestContext;
import org.springframework.web.servlet.theme.FixedThemeResolver;
import org.springframework.web.servlet.view.DummyMacroRequestContext;
import static org.junit.Assert.*;
/**
* @author Darren Davison
* @author Juergen Hoeller
* @since 18.06.2004
*/
public class VelocityMacroTests {
private static final String TEMPLATE_FILE = "test.vm";
private StaticWebApplicationContext wac;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@Before
public void setUp() throws Exception {
wac = new StaticWebApplicationContext();
wac.setServletContext(new MockServletContext());
final Template expectedTemplate = new Template();
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine(TEMPLATE_FILE, expectedTemplate);
}
};
wac.getDefaultListableBeanFactory().registerSingleton("velocityConfigurer", vc);
wac.refresh();
request = new MockHttpServletRequest();
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver());
request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver());
response = new MockHttpServletResponse();
}
@Test
public void exposeSpringMacroHelpers() throws Exception {
VelocityView vv = new VelocityView() {
@Override
protected void mergeTemplate(Template template, Context context, HttpServletResponse response) {
assertTrue(context.get(VelocityView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE) instanceof RequestContext);
RequestContext rc = (RequestContext) context.get(VelocityView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE);
BindStatus status = rc.getBindStatus("tb.name");
assertEquals("name", status.getExpression());
assertEquals("juergen", status.getValue());
}
};
vv.setUrl(TEMPLATE_FILE);
vv.setApplicationContext(wac);
vv.setExposeSpringMacroHelpers(true);
Map<String, Object> model = new HashMap<String, Object>();
model.put("tb", new TestBean("juergen", 99));
vv.render(model, request, response);
}
@Test
public void springMacroRequestContextAttributeUsed() {
final String helperTool = "wrongType";
VelocityView vv = new VelocityView() {
@Override
protected void mergeTemplate(Template template, Context context, HttpServletResponse response) {
fail();
}
};
vv.setUrl(TEMPLATE_FILE);
vv.setApplicationContext(wac);
vv.setExposeSpringMacroHelpers(true);
Map<String, Object> model = new HashMap<String, Object>();
model.put(VelocityView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE, helperTool);
try {
vv.render(model, request, response);
}
catch (Exception ex) {
assertTrue(ex instanceof ServletException);
assertTrue(ex.getMessage().contains(VelocityView.SPRING_MACRO_REQUEST_CONTEXT_ATTRIBUTE));
}
}
@Test
public void allMacros() throws Exception {
DummyMacroRequestContext rc = new DummyMacroRequestContext(request);
Map<String, String> msgMap = new HashMap<String, String>();
msgMap.put("hello", "Howdy");
msgMap.put("world", "Mundo");
rc.setMessageMap(msgMap);
Map<String, String> themeMsgMap = new HashMap<String, String>();
themeMsgMap.put("hello", "Howdy!");
themeMsgMap.put("world", "Mundo!");
rc.setThemeMessageMap(themeMsgMap);
rc.setContextPath("/springtest");
TestBean tb = new TestBean("Darren", 99);
tb.setJedi(true);
tb.setStringArray(new String[] {"John", "Fred"});
request.setAttribute("command", tb);
Map<String, String> names = new HashMap<String, String>();
names.put("Darren", "Darren Davison");
names.put("John", "John Doe");
names.put("Fred", "Fred Bloggs");
VelocityConfigurer vc = new VelocityConfigurer();
vc.setPreferFileSystemAccess(false);
VelocityEngine ve = vc.createVelocityEngine();
Map<String, Object> model = new HashMap<String, Object>();
model.put("command", tb);
model.put("springMacroRequestContext", rc);
model.put("nameOptionMap", names);
VelocityView view = new VelocityView();
view.setBeanName("myView");
view.setUrl("org/springframework/web/servlet/view/velocity/test.vm");
view.setEncoding("UTF-8");
view.setExposeSpringMacroHelpers(false);
view.setVelocityEngine(ve);
view.render(model, request, response);
// tokenize output and ignore whitespace
String output = response.getContentAsString();
System.out.println(output);
String[] tokens = StringUtils.tokenizeToStringArray(output, "\t\n");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("NAME")) assertEquals("Darren", tokens[i + 1]);
if (tokens[i].equals("AGE")) assertEquals("99", tokens[i + 1]);
if (tokens[i].equals("MESSAGE")) assertEquals("Howdy Mundo", tokens[i + 1]);
if (tokens[i].equals("DEFAULTMESSAGE")) assertEquals("hi planet", tokens[i + 1]);
if (tokens[i].equals("THEME")) assertEquals("Howdy! Mundo!", tokens[i + 1]);
if (tokens[i].equals("DEFAULTTHEME")) assertEquals("hi! planet!", tokens[i + 1]);
if (tokens[i].equals("URL")) assertEquals("/springtest/aftercontext.html", tokens[i + 1]);
if (tokens[i].equals("FORM1")) assertEquals("<input type=\"text\" id=\"name\" name=\"name\" value=\"Darren\" >", tokens[i + 1]);
if (tokens[i].equals("FORM2")) assertEquals("<input type=\"text\" id=\"name\" name=\"name\" value=\"Darren\" class=\"myCssClass\">", tokens[i + 1]);
if (tokens[i].equals("FORM3")) assertEquals("<textarea id=\"name\" name=\"name\" >", tokens[i + 1]);
if (tokens[i].equals("FORM3")) assertEquals("Darren</textarea>", tokens[i + 2]);
if (tokens[i].equals("FORM4")) assertEquals("<textarea id=\"name\" name=\"name\" rows=10 cols=30>", tokens[i + 1]);
if (tokens[i].equals("FORM4")) assertEquals("Darren</textarea>", tokens[i + 2]);
//TODO verify remaining output (fix whitespace)
if (tokens[i].equals("FORM9")) assertEquals("<input type=\"password\" id=\"name\" name=\"name\" value=\"\" >", tokens[i + 1]);
if (tokens[i].equals("FORM10")) assertEquals("<input type=\"hidden\" id=\"name\" name=\"name\" value=\"Darren\" >", tokens[i + 1]);
if (tokens[i].equals("FORM15")) assertEquals("<input type=\"hidden\" name=\"_name\" value=\"on\"/>", tokens[i + 1]);
if (tokens[i].equals("FORM15")) assertEquals("<input type=\"checkbox\" id=\"name\" name=\"name\" />", tokens[i + 2]);
if (tokens[i].equals("FORM16")) assertEquals("<input type=\"hidden\" name=\"_jedi\" value=\"on\"/>", tokens[i + 1]);
if (tokens[i].equals("FORM16")) assertEquals("<input type=\"checkbox\" id=\"jedi\" name=\"jedi\" checked=\"checked\" />", tokens[i + 2]);
}
}
// SPR-5172
@Test
public void idContainsBraces() throws Exception {
DummyMacroRequestContext rc = new DummyMacroRequestContext(request);
Map<String, String> msgMap = new HashMap<String, String>();
msgMap.put("hello", "Howdy");
msgMap.put("world", "Mundo");
rc.setMessageMap(msgMap);
Map<String, String> themeMsgMap = new HashMap<String, String>();
themeMsgMap.put("hello", "Howdy!");
themeMsgMap.put("world", "Mundo!");
rc.setThemeMessageMap(themeMsgMap);
rc.setContextPath("/springtest");
TestBean darren = new TestBean("Darren", 99);
TestBean fred = new TestBean("Fred");
fred.setJedi(true);
darren.setSpouse(fred);
darren.setJedi(true);
darren.setStringArray(new String[] {"John", "Fred"});
request.setAttribute("command", darren);
Map<String, String> names = new HashMap<String, String>();
names.put("Darren", "Darren Davison");
names.put("John", "John Doe");
names.put("Fred", "Fred Bloggs");
VelocityConfigurer vc = new VelocityConfigurer();
vc.setPreferFileSystemAccess(false);
VelocityEngine ve = vc.createVelocityEngine();
Map<String, Object> model = new HashMap<String, Object>();
model.put("command", darren);
model.put("springMacroRequestContext", rc);
model.put("nameOptionMap", names);
VelocityView view = new VelocityView();
view.setBeanName("myView");
view.setUrl("org/springframework/web/servlet/view/velocity/test-spr5172.vm");
view.setEncoding("UTF-8");
view.setExposeSpringMacroHelpers(false);
view.setVelocityEngine(ve);
view.render(model, request, response);
// tokenize output and ignore whitespace
String output = response.getContentAsString();
String[] tokens = StringUtils.tokenizeToStringArray(output, "\t\n");
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].equals("FORM1")) assertEquals("<input type=\"text\" id=\"spouses0.name\" name=\"spouses[0].name\" value=\"Fred\" >", tokens[i + 1]); //
if (tokens[i].equals("FORM2")) assertEquals("<textarea id=\"spouses0.name\" name=\"spouses[0].name\" >", tokens[i + 1]);
if (tokens[i].equals("FORM2")) assertEquals("Fred</textarea>", tokens[i + 2]);
if (tokens[i].equals("FORM3")) assertEquals("<select id=\"spouses0.name\" name=\"spouses[0].name\" >", tokens[i + 1]);
if (tokens[i].equals("FORM4")) assertEquals("<select multiple=\"multiple\" id=\"spouses\" name=\"spouses\" >", tokens[i + 1]);
if (tokens[i].equals("FORM5")) assertEquals("<input type=\"radio\" name=\"spouses[0].name\" value=\"Darren\"", tokens[i + 1]);
if (tokens[i].equals("FORM6")) assertEquals("<input type=\"password\" id=\"spouses0.name\" name=\"spouses[0].name\" value=\"\" >", tokens[i + 1]);
if (tokens[i].equals("FORM7")) assertEquals("<input type=\"hidden\" id=\"spouses0.name\" name=\"spouses[0].name\" value=\"Fred\" >", tokens[i + 1]);
if (tokens[i].equals("FORM8")) assertEquals("<input type=\"hidden\" name=\"_spouses0.name\" value=\"on\"/>", tokens[i + 1]);
if (tokens[i].equals("FORM8")) assertEquals("<input type=\"checkbox\" id=\"spouses0.name\" name=\"spouses[0].name\" />", tokens[i + 2]);
if (tokens[i].equals("FORM9")) assertEquals("<input type=\"hidden\" name=\"_spouses0.jedi\" value=\"on\"/>", tokens[i + 1]);
if (tokens[i].equals("FORM9")) assertEquals("<input type=\"checkbox\" id=\"spouses0.jedi\" name=\"spouses[0].jedi\" checked=\"checked\" />", tokens[i + 2]);
}
}
}

View File

@@ -1,173 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.exception.MethodInvocationException;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.tests.sample.beans.TestBean;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.theme.FixedThemeResolver;
import org.springframework.web.util.NestedServletException;
import static org.junit.Assert.*;
/**
* @author Dave Syer
*/
public class VelocityRenderTests {
private StaticWebApplicationContext wac;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setUp() throws Exception {
wac = new StaticWebApplicationContext();
wac.setServletContext(new MockServletContext());
final Template expectedTemplate = new Template();
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine("test.vm", expectedTemplate);
}
};
wac.getDefaultListableBeanFactory().registerSingleton("velocityConfigurer", vc);
wac.refresh();
request = new MockHttpServletRequest();
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver());
request.setAttribute(DispatcherServlet.THEME_RESOLVER_ATTRIBUTE, new FixedThemeResolver());
response = new MockHttpServletResponse();
}
@Test
public void testSimpleRender() throws Exception {
VelocityConfigurer vc = new VelocityConfigurer();
vc.setPreferFileSystemAccess(false);
VelocityEngine ve = vc.createVelocityEngine();
VelocityView view = new VelocityView();
view.setBeanName("myView");
view.setUrl("org/springframework/web/servlet/view/velocity/simple.vm");
view.setVelocityEngine(ve);
view.setApplicationContext(wac);
Map<String,Object> model = new HashMap<String,Object>();
model.put("command", new TestBean("juergen", 99));
view.render(model, request, response);
assertEquals("\nNAME\njuergen\n", response.getContentAsString().replace("\r\n", "\n"));
}
@Test
@Ignore // This works with Velocity 1.6.2
public void testSimpleRenderWithError() throws Exception {
thrown.expect(NestedServletException.class);
thrown.expect(new TypeSafeMatcher<Exception>() {
@Override
public boolean matchesSafely(Exception item) {
return item.getCause() instanceof MethodInvocationException;
}
@Override
public void describeTo(Description description) {
description.appendText("exception has cause of MethodInvocationException");
}
});
VelocityConfigurer vc = new VelocityConfigurer();
vc.setPreferFileSystemAccess(false);
vc.setVelocityPropertiesMap(Collections.<String,Object>singletonMap("runtime.references.strict", "true"));
VelocityEngine ve = vc.createVelocityEngine();
VelocityView view = new VelocityView();
view.setBeanName("myView");
view.setUrl("org/springframework/web/servlet/view/velocity/error.vm");
view.setVelocityEngine(ve);
view.setApplicationContext(wac);
Map<String,Object> model = new HashMap<String,Object>();
model.put("command", new TestBean("juergen", 99));
view.render(model, request, response);
}
@Test
public void testSimpleRenderWithIOError() throws Exception {
thrown.expect(NestedServletException.class);
thrown.expect(new TypeSafeMatcher<Exception>() {
@Override
public boolean matchesSafely(Exception item) {
return item.getCause() instanceof IOException;
}
@Override
public void describeTo(Description description) {
description.appendText("exception has cause of IOException");
}
});
VelocityConfigurer vc = new VelocityConfigurer();
vc.setPreferFileSystemAccess(false);
vc.setVelocityPropertiesMap(Collections.<String,Object>singletonMap("runtime.references.strict", "true"));
VelocityEngine ve = vc.createVelocityEngine();
VelocityView view = new VelocityView();
view.setBeanName("myView");
view.setUrl("org/springframework/web/servlet/view/velocity/ioerror.vm");
view.setVelocityEngine(ve);
view.setApplicationContext(wac);
Map<String,Object> model = new HashMap<String,Object>();
model.put("command", new TestBean("juergen", 99));
view.render(model, request, response);
}
}

View File

@@ -1,83 +0,0 @@
package org.springframework.web.servlet.view.velocity;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.view.context.ChainedContext;
import org.apache.velocity.tools.view.tools.LinkTool;
import org.junit.Test;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import static org.junit.Assert.*;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Dave Syer
*/
public class VelocityToolboxViewTests {
@Test
public void testVelocityToolboxView() throws Exception {
final String templateName = "test.vm";
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.setServletContext(new MockServletContext());
final Template expectedTemplate = new Template();
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine(templateName, expectedTemplate);
}
};
wac.getDefaultListableBeanFactory().registerSingleton("velocityConfigurer", vc);
final HttpServletRequest expectedRequest = new MockHttpServletRequest();
final HttpServletResponse expectedResponse = new MockHttpServletResponse();
VelocityToolboxView vv = new VelocityToolboxView() {
@Override
protected void mergeTemplate(Template template, Context context, HttpServletResponse response) throws Exception {
assertTrue(template == expectedTemplate);
assertTrue(response == expectedResponse);
assertTrue(context instanceof ChainedContext);
assertEquals("this is foo.", context.get("foo"));
assertTrue(context.get("map") instanceof HashMap<?,?>);
assertTrue(context.get("date") instanceof DateTool);
assertTrue(context.get("math") instanceof MathTool);
assertTrue(context.get("link") instanceof LinkTool);
LinkTool linkTool = (LinkTool) context.get("link");
assertNotNull(linkTool.getContextURL());
assertTrue(context.get("link2") instanceof LinkTool);
LinkTool linkTool2 = (LinkTool) context.get("link2");
assertNotNull(linkTool2.getContextURL());
}
};
vv.setUrl(templateName);
vv.setApplicationContext(wac);
Map<String, Class<?>> toolAttributes = new HashMap<String, Class<?>>();
toolAttributes.put("math", MathTool.class);
toolAttributes.put("link2", LinkTool.class);
vv.setToolAttributes(toolAttributes);
vv.setToolboxConfigLocation("org/springframework/web/servlet/view/velocity/toolbox.xml");
vv.setExposeSpringMacroHelpers(false);
vv.render(new HashMap<String,Object>(), expectedRequest, expectedResponse);
}
}

View File

@@ -1,145 +0,0 @@
package org.springframework.web.servlet.view.velocity;
import java.util.Locale;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.junit.Test;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.web.servlet.view.RedirectView;
import static org.junit.Assert.*;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Dave Syer
*/
public class VelocityViewResolverTests {
@Test
public void testVelocityViewResolver() throws Exception {
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine("prefix_test_suffix", new Template());
}
};
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.getBeanFactory().registerSingleton("configurer", vc);
wac.refresh();
VelocityViewResolver vr = new VelocityViewResolver();
vr.setPrefix("prefix_");
vr.setSuffix("_suffix");
vr.setApplicationContext(wac);
View view = vr.resolveViewName("test", Locale.CANADA);
assertEquals("Correct view class", VelocityView.class, view.getClass());
assertEquals("Correct URL", "prefix_test_suffix", ((VelocityView) view).getUrl());
view = vr.resolveViewName("non-existing", Locale.CANADA);
assertNull(view);
view = vr.resolveViewName("redirect:myUrl", Locale.getDefault());
assertEquals("Correct view class", RedirectView.class, view.getClass());
assertEquals("Correct URL", "myUrl", ((RedirectView) view).getUrl());
view = vr.resolveViewName("forward:myUrl", Locale.getDefault());
assertEquals("Correct view class", InternalResourceView.class, view.getClass());
assertEquals("Correct URL", "myUrl", ((InternalResourceView) view).getUrl());
}
@Test
public void testVelocityViewResolverWithToolbox() throws Exception {
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine("prefix_test_suffix", new Template());
}
};
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.getBeanFactory().registerSingleton("configurer", vc);
wac.refresh();
String toolbox = "org/springframework/web/servlet/view/velocity/toolbox.xml";
VelocityViewResolver vr = new VelocityViewResolver();
vr.setPrefix("prefix_");
vr.setSuffix("_suffix");
vr.setToolboxConfigLocation(toolbox);
vr.setApplicationContext(wac);
View view = vr.resolveViewName("test", Locale.CANADA);
assertEquals("Correct view class", VelocityToolboxView.class, view.getClass());
assertEquals("Correct URL", "prefix_test_suffix", ((VelocityView) view).getUrl());
assertEquals("Correct toolbox", toolbox, ((VelocityToolboxView) view).getToolboxConfigLocation());
}
@Test
public void testVelocityViewResolverWithToolboxSubclass() throws Exception {
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
TestVelocityEngine ve = new TestVelocityEngine();
ve.addTemplate("prefix_test_suffix", new Template());
ve.addTemplate(VelocityLayoutView.DEFAULT_LAYOUT_URL, new Template());
return ve;
}
};
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.getBeanFactory().registerSingleton("configurer", vc);
wac.refresh();
String toolbox = "org/springframework/web/servlet/view/velocity/toolbox.xml";
VelocityViewResolver vr = new VelocityViewResolver();
vr.setViewClass(VelocityLayoutView.class);
vr.setPrefix("prefix_");
vr.setSuffix("_suffix");
vr.setToolboxConfigLocation(toolbox);
vr.setApplicationContext(wac);
View view = vr.resolveViewName("test", Locale.CANADA);
assertEquals("Correct view class", VelocityLayoutView.class, view.getClass());
assertEquals("Correct URL", "prefix_test_suffix", ((VelocityView) view).getUrl());
assertEquals("Correct toolbox", toolbox, ((VelocityToolboxView) view).getToolboxConfigLocation());
}
@Test
public void testVelocityLayoutViewResolver() throws Exception {
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
TestVelocityEngine ve = new TestVelocityEngine();
ve.addTemplate("prefix_test_suffix", new Template());
ve.addTemplate("myLayoutUrl", new Template());
return ve;
}
};
StaticWebApplicationContext wac = new StaticWebApplicationContext();
wac.getBeanFactory().registerSingleton("configurer", vc);
wac.refresh();
VelocityLayoutViewResolver vr = new VelocityLayoutViewResolver();
vr.setPrefix("prefix_");
vr.setSuffix("_suffix");
vr.setLayoutUrl("myLayoutUrl");
vr.setLayoutKey("myLayoutKey");
vr.setScreenContentKey("myScreenContentKey");
vr.setApplicationContext(wac);
View view = vr.resolveViewName("test", Locale.CANADA);
assertEquals("Correct view class", VelocityLayoutView.class, view.getClass());
assertEquals("Correct URL", "prefix_test_suffix", ((VelocityView) view).getUrl());
// TODO: Need to test actual VelocityLayoutView properties and their functionality!
}
}

View File

@@ -1,280 +0,0 @@
/*
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.view.velocity;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.tools.generic.DateTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.junit.Test;
import org.springframework.context.ApplicationContextException;
import org.springframework.mock.web.test.MockHttpServletRequest;
import org.springframework.mock.web.test.MockHttpServletResponse;
import org.springframework.mock.web.test.MockServletContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import org.springframework.web.servlet.support.RequestDataValueProcessor;
import org.springframework.web.servlet.view.AbstractView;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
/**
* @author Rod Johnson
* @author Juergen Hoeller
* @author Dave Syer
*/
public class VelocityViewTests {
@Test
public void testNoVelocityConfig() throws Exception {
VelocityView vv = new VelocityView();
WebApplicationContext wac = mock(WebApplicationContext.class);
given(wac.getBeansOfType(VelocityConfig.class, true, false)).willReturn(new HashMap<String, VelocityConfig>());
vv.setUrl("anythingButNull");
try {
vv.setApplicationContext(wac);
fail();
}
catch (ApplicationContextException ex) {
// Check there's a helpful error message
assertTrue(ex.getMessage().contains("VelocityConfig"));
}
}
@Test
public void testNoTemplateName() throws Exception {
VelocityView vv = new VelocityView();
try {
vv.afterPropertiesSet();
fail("Should have thrown IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
// Check there's a helpful error message
assertTrue(ex.getMessage().indexOf("url") != -1);
}
}
@Test
public void testMergeTemplateSucceeds() throws Exception {
testValidTemplateName(null);
}
@Test
public void testMergeTemplateFailureWithIOException() throws Exception {
testValidTemplateName(new IOException());
}
@Test
public void testMergeTemplateFailureWithParseErrorException() throws Exception {
testValidTemplateName(new ParseErrorException(""));
}
@Test
public void testMergeTemplateFailureWithUnspecifiedException() throws Exception {
testValidTemplateName(new Exception(""));
}
@Test
public void testMergeTemplateFailureWithMethodInvocationException() throws Exception {
testValidTemplateName(new MethodInvocationException("Bad template", null, "none", "foo.vm", 1, 100));
}
/**
* @param mergeTemplateFailureException may be null in which case mergeTemplate override will succeed.
* If it's non null it will be checked
*/
private void testValidTemplateName(final Exception mergeTemplateFailureException) throws Exception {
Map<String, Object> model = new HashMap<String, Object>();
model.put("foo", "bar");
final String templateName = "test.vm";
WebApplicationContext wac = mock(WebApplicationContext.class);
MockServletContext sc = new MockServletContext();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
final Template expectedTemplate = new Template();
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine(templateName, expectedTemplate);
}
};
Map<String, VelocityConfig> configurers = new HashMap<String, VelocityConfig>();
configurers.put("velocityConfigurer", vc);
given(wac.getBeansOfType(VelocityConfig.class, true, false)).willReturn(configurers);
given(wac.getServletContext()).willReturn(sc);
given(wac.getBean("requestDataValueProcessor",
RequestDataValueProcessor.class)).willReturn(null);
HttpServletRequest request = new MockHttpServletRequest();
final HttpServletResponse expectedResponse = new MockHttpServletResponse();
VelocityView vv = new VelocityView() {
@Override
protected void mergeTemplate(Template template, Context context, HttpServletResponse response) throws Exception {
assertTrue(template == expectedTemplate);
assertTrue(context.getKeys().length >= 1);
assertTrue(context.get("foo").equals("bar"));
assertTrue(response == expectedResponse);
if (mergeTemplateFailureException != null) {
throw mergeTemplateFailureException;
}
}
};
vv.setUrl(templateName);
vv.setApplicationContext(wac);
try {
vv.render(model, request, expectedResponse);
if (mergeTemplateFailureException != null) {
fail();
}
}
catch (Exception ex) {
assertNotNull(mergeTemplateFailureException);
assertEquals(ex, mergeTemplateFailureException);
}
}
@Test
public void testKeepExistingContentType() throws Exception {
final String templateName = "test.vm";
WebApplicationContext wac = mock(WebApplicationContext.class);
MockServletContext sc = new MockServletContext();
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
final Template expectedTemplate = new Template();
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine(templateName, expectedTemplate);
}
};
Map<String, VelocityConfig> configurers = new HashMap<String, VelocityConfig>();
configurers.put("velocityConfigurer", vc);
given(wac.getBeansOfType(VelocityConfig.class, true, false)).willReturn(configurers);
given(wac.getServletContext()).willReturn(sc);
given(wac.getBean("requestDataValueProcessor",
RequestDataValueProcessor.class)).willReturn(null);
HttpServletRequest request = new MockHttpServletRequest();
final HttpServletResponse expectedResponse = new MockHttpServletResponse();
expectedResponse.setContentType("myContentType");
VelocityView vv = new VelocityView() {
@Override
protected void mergeTemplate(Template template, Context context, HttpServletResponse response) {
assertTrue(template == expectedTemplate);
assertTrue(response == expectedResponse);
}
@Override
protected void exposeHelpers(Map<String, Object> model, HttpServletRequest request) throws Exception {
model.put("myHelper", "myValue");
}
};
vv.setUrl(templateName);
vv.setApplicationContext(wac);
vv.render(new HashMap<String, Object>(), request, expectedResponse);
assertEquals("myContentType", expectedResponse.getContentType());
}
@Test
public void testExposeHelpers() throws Exception {
final String templateName = "test.vm";
WebApplicationContext wac = mock(WebApplicationContext.class);
given(wac.getServletContext()).willReturn(new MockServletContext());
final Template expectedTemplate = new Template();
VelocityConfig vc = new VelocityConfig() {
@Override
public VelocityEngine getVelocityEngine() {
return new TestVelocityEngine(templateName, expectedTemplate);
}
};
Map<String, VelocityConfig> configurers = new HashMap<String, VelocityConfig>();
configurers.put("velocityConfigurer", vc);
given(wac.getBeansOfType(VelocityConfig.class, true, false)).willReturn(configurers);
// let it ask for locale
HttpServletRequest req = mock(HttpServletRequest.class);
given(req.getAttribute(View.PATH_VARIABLES)).willReturn(null);
given(req.getAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE)).willReturn(new AcceptHeaderLocaleResolver());
given(req.getLocale()).willReturn(Locale.CANADA);
final HttpServletResponse expectedResponse = new MockHttpServletResponse();
VelocityView vv = new VelocityView() {
@Override
protected void mergeTemplate(Template template, Context context, HttpServletResponse response) throws Exception {
assertTrue(template == expectedTemplate);
assertTrue(response == expectedResponse);
assertEquals("myValue", context.get("myHelper"));
assertTrue(context.get("math") instanceof MathTool);
assertTrue(context.get("dateTool") instanceof DateTool);
DateTool dateTool = (DateTool) context.get("dateTool");
assertTrue(dateTool.getLocale().equals(Locale.CANADA));
assertTrue(context.get("numberTool") instanceof NumberTool);
NumberTool numberTool = (NumberTool) context.get("numberTool");
assertTrue(numberTool.getLocale().equals(Locale.CANADA));
}
@Override
protected void exposeHelpers(Map<String, Object> model, HttpServletRequest request) throws Exception {
model.put("myHelper", "myValue");
}
};
vv.setUrl(templateName);
vv.setApplicationContext(wac);
Map<String, Class<?>> toolAttributes = new HashMap<String, Class<?>>();
toolAttributes.put("math", MathTool.class);
vv.setToolAttributes(toolAttributes);
vv.setDateToolAttribute("dateTool");
vv.setNumberToolAttribute("numberTool");
vv.setExposeSpringMacroHelpers(false);
vv.render(new HashMap<String, Object>(), req, expectedResponse);
assertEquals(AbstractView.DEFAULT_CONTENT_TYPE, expectedResponse.getContentType());
}
}

View File

@@ -3,8 +3,8 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<!--
View resolution finds the ContentNegotiationManager created by or
@@ -23,7 +23,6 @@
<mvc:jsp/>
<mvc:tiles/>
<mvc:freemarker/>
<mvc:velocity/>
<mvc:groovy/>
<mvc:script-template/>
</mvc:view-resolvers>
@@ -36,8 +35,6 @@
<mvc:template-loader-path location="/org/springframework/web/servlet/view"/>
</mvc:freemarker-configurer>
<mvc:velocity-configurer resource-loader-path="/org/springframework/web/servlet/view"/>
<mvc:groovy-configurer/>
<mvc:script-template-configurer engine-name="nashorn" render-function="render"/>

View File

@@ -2,15 +2,14 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<mvc:view-resolvers>
<mvc:bean-name/>
<mvc:jsp view-class="org.springframework.web.servlet.view.InternalResourceView"/>
<mvc:tiles/>
<mvc:freemarker prefix="freemarker-" suffix=".freemarker" view-names="my*,*Report"/>
<mvc:velocity cache-views="false"/>
<mvc:groovy/>
<mvc:script-template/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
@@ -31,8 +30,6 @@
<mvc:template-loader-path location="/test"/>
</mvc:freemarker-configurer>
<mvc:velocity-configurer resource-loader-path="/test"/>
<mvc:groovy-configurer resource-loader-path="/test" cache-templates="false" auto-indent="true"/>
<mvc:script-template-configurer engine-name="nashorn" render-function="render" content-type="text/plain"

View File

@@ -1,4 +0,0 @@
##
## test template for Velocity view with missing method
##
$command.nonexistent()

View File

@@ -1,4 +0,0 @@
##
## test template for Velocity view with exception
##
$command.unreliableFileOperation()

View File

@@ -1,6 +0,0 @@
##
## test template for Velocity view
##
NAME
$command.name

View File

@@ -1,30 +0,0 @@
##
## test template for Velocity macro test class
##
FORM1
#springFormInput("command.spouses[0].name" "")
FORM2
#springFormTextarea("command.spouses[0].name" "")
FORM3
#springFormSingleSelect("command.spouses[0].name" $nameOptionMap "")
FORM4
#springFormMultiSelect("command.spouses" $nameOptionMap "")
FORM5
#springFormRadioButtons("command.spouses[0].name" $nameOptionMap " " "")
FORM6
#springFormPasswordInput("command.spouses[0].name" "")
FORM7
#springFormHiddenInput("command.spouses[0].name" "")
FORM8
#springFormCheckbox("command.spouses[0].name" "")
FORM9
#springFormCheckbox("command.spouses[0].jedi" "")

View File

@@ -1,64 +0,0 @@
##
## test template for Velocity macro test class
##
NAME
$command.name
AGE
$command.age
MESSAGE
#springMessage("hello") #springMessage("world")
DEFAULTMESSAGE
#springMessageText("no.such.code" "hi") #springMessageText("no.such.code" "planet")
THEME
#springTheme("hello") #springTheme("world")
DEFAULTTHEME
#springThemeText("no.such.code" "hi!") #springThemeText("no.such.code" "planet!")
URL
#springUrl("/aftercontext.html")
FORM1
#springFormInput("command.name" "")
FORM2
#springFormInput("command.name" 'class="myCssClass"')
FORM3
#springFormTextarea("command.name" "")
FORM4
#springFormTextarea("command.name" "rows=10 cols=30")
FORM5
#springFormSingleSelect("command.name" $nameOptionMap "")
FORM6
#springFormMultiSelect("command.spouses" $nameOptionMap "")
FORM7
#springFormRadioButtons("command.name" $nameOptionMap " " "")
FORM8
#springFormCheckboxes("command.stringArray" $nameOptionMap " " "")
FORM9
#springFormPasswordInput("command.name" "")
FORM10
#springFormHiddenInput("command.name" "")
FORM15
#springFormCheckbox("command.name" "")
FORM16
#springFormCheckbox("command.jedi" "")
ERRORS
#springShowErrors(" " "")

View File

@@ -1,23 +0,0 @@
<?xml version="1.0"?>
<toolbox>
<xhtml>true</xhtml>
<data type="string">
<key>foo</key>
<value>this is foo.</value>
</data>
<tool>
<key>map</key>
<class>java.util.HashMap</class>
</tool>
<tool>
<key>date</key>
<scope>application</scope>
<class>org.apache.velocity.tools.generic.DateTool</class>
</tool>
<tool>
<key>link</key>
<scope>request</scope>
<class>org.apache.velocity.tools.view.tools.LinkTool</class>
</tool>
</toolbox>