54 changed files with 135 additions and 4242 deletions
@ -1,128 +0,0 @@
@@ -1,128 +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.ui.velocity; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.Arrays; |
||||
|
||||
import org.apache.commons.collections.ExtendedProperties; |
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.apache.velocity.exception.ResourceNotFoundException; |
||||
import org.apache.velocity.runtime.resource.Resource; |
||||
import org.apache.velocity.runtime.resource.loader.ResourceLoader; |
||||
|
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Velocity ResourceLoader adapter that loads via a Spring ResourceLoader. |
||||
* Used by VelocityEngineFactory for any resource loader path that cannot |
||||
* be resolved to a {@code java.io.File}. |
||||
* |
||||
* <p>Note that this loader does not allow for modification detection: |
||||
* Use Velocity's default FileResourceLoader for {@code java.io.File} |
||||
* resources. |
||||
* |
||||
* <p>Expects "spring.resource.loader" and "spring.resource.loader.path" |
||||
* application attributes in the Velocity runtime: the former of type |
||||
* {@code org.springframework.core.io.ResourceLoader}, the latter a String. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 14.03.2004 |
||||
* @see VelocityEngineFactory#setResourceLoaderPath |
||||
* @see org.springframework.core.io.ResourceLoader |
||||
* @see org.apache.velocity.runtime.resource.loader.FileResourceLoader |
||||
*/ |
||||
public class SpringResourceLoader extends ResourceLoader { |
||||
|
||||
public static final String NAME = "spring"; |
||||
|
||||
public static final String SPRING_RESOURCE_LOADER_CLASS = "spring.resource.loader.class"; |
||||
|
||||
public static final String SPRING_RESOURCE_LOADER_CACHE = "spring.resource.loader.cache"; |
||||
|
||||
public static final String SPRING_RESOURCE_LOADER = "spring.resource.loader"; |
||||
|
||||
public static final String SPRING_RESOURCE_LOADER_PATH = "spring.resource.loader.path"; |
||||
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private org.springframework.core.io.ResourceLoader resourceLoader; |
||||
|
||||
private String[] resourceLoaderPaths; |
||||
|
||||
|
||||
@Override |
||||
public void init(ExtendedProperties configuration) { |
||||
this.resourceLoader = (org.springframework.core.io.ResourceLoader) |
||||
this.rsvc.getApplicationAttribute(SPRING_RESOURCE_LOADER); |
||||
String resourceLoaderPath = (String) this.rsvc.getApplicationAttribute(SPRING_RESOURCE_LOADER_PATH); |
||||
if (this.resourceLoader == null) { |
||||
throw new IllegalArgumentException( |
||||
"'resourceLoader' application attribute must be present for SpringResourceLoader"); |
||||
} |
||||
if (resourceLoaderPath == null) { |
||||
throw new IllegalArgumentException( |
||||
"'resourceLoaderPath' application attribute must be present for SpringResourceLoader"); |
||||
} |
||||
this.resourceLoaderPaths = StringUtils.commaDelimitedListToStringArray(resourceLoaderPath); |
||||
for (int i = 0; i < this.resourceLoaderPaths.length; i++) { |
||||
String path = this.resourceLoaderPaths[i]; |
||||
if (!path.endsWith("/")) { |
||||
this.resourceLoaderPaths[i] = path + "/"; |
||||
} |
||||
} |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("SpringResourceLoader for Velocity: using resource loader [" + this.resourceLoader + |
||||
"] and resource loader paths " + Arrays.asList(this.resourceLoaderPaths)); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public InputStream getResourceStream(String source) throws ResourceNotFoundException { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Looking for Velocity resource with name [" + source + "]"); |
||||
} |
||||
for (String resourceLoaderPath : this.resourceLoaderPaths) { |
||||
org.springframework.core.io.Resource resource = |
||||
this.resourceLoader.getResource(resourceLoaderPath + source); |
||||
try { |
||||
return resource.getInputStream(); |
||||
} |
||||
catch (IOException ex) { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Could not find Velocity resource: " + resource); |
||||
} |
||||
} |
||||
} |
||||
throw new ResourceNotFoundException( |
||||
"Could not find resource [" + source + "] in Spring resource loader path"); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isSourceModified(Resource resource) { |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public long getLastModified(Resource resource) { |
||||
return 0; |
||||
} |
||||
|
||||
} |
||||
@ -1,357 +0,0 @@
@@ -1,357 +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.ui.velocity; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.Properties; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.apache.velocity.app.VelocityEngine; |
||||
import org.apache.velocity.exception.VelocityException; |
||||
import org.apache.velocity.runtime.RuntimeConstants; |
||||
import org.apache.velocity.runtime.log.CommonsLogLogChute; |
||||
|
||||
import org.springframework.core.io.DefaultResourceLoader; |
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.core.io.ResourceLoader; |
||||
import org.springframework.core.io.support.PropertiesLoaderUtils; |
||||
import org.springframework.util.CollectionUtils; |
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Factory that configures a VelocityEngine. Can be used standalone, |
||||
* but typically you will either use {@link VelocityEngineFactoryBean} |
||||
* for preparing a VelocityEngine as bean reference, or |
||||
* {@link org.springframework.web.servlet.view.velocity.VelocityConfigurer} |
||||
* for web views. |
||||
* |
||||
* <p>The optional "configLocation" property sets the location of the Velocity |
||||
* properties file, within the current application. Velocity properties can be |
||||
* overridden via "velocityProperties", or even completely specified locally, |
||||
* avoiding the need for an external properties file. |
||||
* |
||||
* <p>The "resourceLoaderPath" property can be used to specify the Velocity |
||||
* resource loader path via Spring's Resource abstraction, possibly relative |
||||
* to the Spring application context. |
||||
* |
||||
* <p>If "overrideLogging" is true (the default), the VelocityEngine will be |
||||
* configured to log via Commons Logging, that is, using |
||||
* {@link CommonsLogLogChute} as log system. |
||||
* |
||||
* <p>The simplest way to use this class is to specify a |
||||
* {@link #setResourceLoaderPath(String) "resourceLoaderPath"}; the |
||||
* VelocityEngine typically then does not need any further configuration. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @see #setConfigLocation |
||||
* @see #setVelocityProperties |
||||
* @see #setResourceLoaderPath |
||||
* @see #setOverrideLogging |
||||
* @see #createVelocityEngine |
||||
* @see VelocityEngineFactoryBean |
||||
* @see org.springframework.web.servlet.view.velocity.VelocityConfigurer |
||||
* @see org.apache.velocity.app.VelocityEngine |
||||
* @deprecated as of Spring 4.3, in favor of FreeMarker |
||||
*/ |
||||
@Deprecated |
||||
public class VelocityEngineFactory { |
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private Resource configLocation; |
||||
|
||||
private final Map<String, Object> velocityProperties = new HashMap<String, Object>(); |
||||
|
||||
private String resourceLoaderPath; |
||||
|
||||
private ResourceLoader resourceLoader = new DefaultResourceLoader(); |
||||
|
||||
private boolean preferFileSystemAccess = true; |
||||
|
||||
private boolean overrideLogging = true; |
||||
|
||||
|
||||
/** |
||||
* Set the location of the Velocity config file. |
||||
* Alternatively, you can specify all properties locally. |
||||
* @see #setVelocityProperties |
||||
* @see #setResourceLoaderPath |
||||
*/ |
||||
public void setConfigLocation(Resource configLocation) { |
||||
this.configLocation = configLocation; |
||||
} |
||||
|
||||
/** |
||||
* Set Velocity properties, like "file.resource.loader.path". |
||||
* Can be used to override values in a Velocity config file, |
||||
* or to specify all necessary properties locally. |
||||
* <p>Note that the Velocity resource loader path also be set to any |
||||
* Spring resource location via the "resourceLoaderPath" property. |
||||
* Setting it here is just necessary when using a non-file-based |
||||
* resource loader. |
||||
* @see #setVelocityPropertiesMap |
||||
* @see #setConfigLocation |
||||
* @see #setResourceLoaderPath |
||||
*/ |
||||
public void setVelocityProperties(Properties velocityProperties) { |
||||
CollectionUtils.mergePropertiesIntoMap(velocityProperties, this.velocityProperties); |
||||
} |
||||
|
||||
/** |
||||
* Set Velocity properties as Map, to allow for non-String values |
||||
* like "ds.resource.loader.instance". |
||||
* @see #setVelocityProperties |
||||
*/ |
||||
public void setVelocityPropertiesMap(Map<String, Object> velocityPropertiesMap) { |
||||
if (velocityPropertiesMap != null) { |
||||
this.velocityProperties.putAll(velocityPropertiesMap); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Set the Velocity resource loader path via a Spring resource location. |
||||
* Accepts multiple locations in Velocity's comma-separated path style. |
||||
* <p>When populated via a String, standard URLs like "file:" and "classpath:" |
||||
* pseudo URLs are supported, as understood by ResourceLoader. Allows for |
||||
* relative paths when running in an ApplicationContext. |
||||
* <p>Will define a path for the default Velocity resource loader with the name |
||||
* "file". If the specified resource cannot be resolved to a {@code java.io.File}, |
||||
* a generic SpringResourceLoader will be used under the name "spring", without |
||||
* modification detection. |
||||
* <p>Note that resource caching will be enabled in any case. With the file |
||||
* resource loader, the last-modified timestamp will be checked on access to |
||||
* detect changes. With SpringResourceLoader, the resource will be cached |
||||
* forever (for example for class path resources). |
||||
* <p>To specify a modification check interval for files, use Velocity's |
||||
* standard "file.resource.loader.modificationCheckInterval" property. By default, |
||||
* the file timestamp is checked on every access (which is surprisingly fast). |
||||
* Of course, this just applies when loading resources from the file system. |
||||
* <p>To enforce the use of SpringResourceLoader, i.e. to not resolve a path |
||||
* as file system resource in any case, turn off the "preferFileSystemAccess" |
||||
* flag. See the latter's javadoc for details. |
||||
* @see #setResourceLoader |
||||
* @see #setVelocityProperties |
||||
* @see #setPreferFileSystemAccess |
||||
* @see SpringResourceLoader |
||||
* @see org.apache.velocity.runtime.resource.loader.FileResourceLoader |
||||
*/ |
||||
public void setResourceLoaderPath(String resourceLoaderPath) { |
||||
this.resourceLoaderPath = resourceLoaderPath; |
||||
} |
||||
|
||||
/** |
||||
* Set the Spring ResourceLoader to use for loading Velocity template files. |
||||
* The default is DefaultResourceLoader. Will get overridden by the |
||||
* ApplicationContext if running in a context. |
||||
* @see org.springframework.core.io.DefaultResourceLoader |
||||
* @see org.springframework.context.ApplicationContext |
||||
*/ |
||||
public void setResourceLoader(ResourceLoader resourceLoader) { |
||||
this.resourceLoader = resourceLoader; |
||||
} |
||||
|
||||
/** |
||||
* Return the Spring ResourceLoader to use for loading Velocity template files. |
||||
*/ |
||||
protected ResourceLoader getResourceLoader() { |
||||
return this.resourceLoader; |
||||
} |
||||
|
||||
/** |
||||
* Set whether to prefer file system access for template loading. |
||||
* File system access enables hot detection of template changes. |
||||
* <p>If this is enabled, VelocityEngineFactory will try to resolve the |
||||
* specified "resourceLoaderPath" as file system resource (which will work |
||||
* for expanded class path resources and ServletContext resources too). |
||||
* <p>Default is "true". Turn this off to always load via SpringResourceLoader |
||||
* (i.e. as stream, without hot detection of template changes), which might |
||||
* be necessary if some of your templates reside in an expanded classes |
||||
* directory while others reside in jar files. |
||||
* @see #setResourceLoaderPath |
||||
*/ |
||||
public void setPreferFileSystemAccess(boolean preferFileSystemAccess) { |
||||
this.preferFileSystemAccess = preferFileSystemAccess; |
||||
} |
||||
|
||||
/** |
||||
* Return whether to prefer file system access for template loading. |
||||
*/ |
||||
protected boolean isPreferFileSystemAccess() { |
||||
return this.preferFileSystemAccess; |
||||
} |
||||
|
||||
/** |
||||
* Set whether Velocity should log via Commons Logging, i.e. whether Velocity's |
||||
* log system should be set to {@link CommonsLogLogChute}. Default is "true". |
||||
*/ |
||||
public void setOverrideLogging(boolean overrideLogging) { |
||||
this.overrideLogging = overrideLogging; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Prepare the VelocityEngine instance and return it. |
||||
* @return the VelocityEngine instance |
||||
* @throws IOException if the config file wasn't found |
||||
* @throws VelocityException on Velocity initialization failure |
||||
*/ |
||||
public VelocityEngine createVelocityEngine() throws IOException, VelocityException { |
||||
VelocityEngine velocityEngine = newVelocityEngine(); |
||||
Map<String, Object> props = new HashMap<String, Object>(); |
||||
|
||||
// Load config file if set.
|
||||
if (this.configLocation != null) { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Loading Velocity config from [" + this.configLocation + "]"); |
||||
} |
||||
CollectionUtils.mergePropertiesIntoMap(PropertiesLoaderUtils.loadProperties(this.configLocation), props); |
||||
} |
||||
|
||||
// Merge local properties if set.
|
||||
if (!this.velocityProperties.isEmpty()) { |
||||
props.putAll(this.velocityProperties); |
||||
} |
||||
|
||||
// Set a resource loader path, if required.
|
||||
if (this.resourceLoaderPath != null) { |
||||
initVelocityResourceLoader(velocityEngine, this.resourceLoaderPath); |
||||
} |
||||
|
||||
// Log via Commons Logging?
|
||||
if (this.overrideLogging) { |
||||
velocityEngine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new CommonsLogLogChute()); |
||||
} |
||||
|
||||
// Apply properties to VelocityEngine.
|
||||
for (Map.Entry<String, Object> entry : props.entrySet()) { |
||||
velocityEngine.setProperty(entry.getKey(), entry.getValue()); |
||||
} |
||||
|
||||
postProcessVelocityEngine(velocityEngine); |
||||
|
||||
// Perform actual initialization.
|
||||
velocityEngine.init(); |
||||
|
||||
return velocityEngine; |
||||
} |
||||
|
||||
/** |
||||
* Return a new VelocityEngine. Subclasses can override this for |
||||
* custom initialization, or for using a mock object for testing. |
||||
* <p>Called by {@code createVelocityEngine()}. |
||||
* @return the VelocityEngine instance |
||||
* @throws IOException if a config file wasn't found |
||||
* @throws VelocityException on Velocity initialization failure |
||||
* @see #createVelocityEngine() |
||||
*/ |
||||
protected VelocityEngine newVelocityEngine() throws IOException, VelocityException { |
||||
return new VelocityEngine(); |
||||
} |
||||
|
||||
/** |
||||
* Initialize a Velocity resource loader for the given VelocityEngine: |
||||
* either a standard Velocity FileResourceLoader or a SpringResourceLoader. |
||||
* <p>Called by {@code createVelocityEngine()}. |
||||
* @param velocityEngine the VelocityEngine to configure |
||||
* @param resourceLoaderPath the path to load Velocity resources from |
||||
* @see org.apache.velocity.runtime.resource.loader.FileResourceLoader |
||||
* @see SpringResourceLoader |
||||
* @see #initSpringResourceLoader |
||||
* @see #createVelocityEngine() |
||||
*/ |
||||
protected void initVelocityResourceLoader(VelocityEngine velocityEngine, String resourceLoaderPath) { |
||||
if (isPreferFileSystemAccess()) { |
||||
// Try to load via the file system, fall back to SpringResourceLoader
|
||||
// (for hot detection of template changes, if possible).
|
||||
try { |
||||
StringBuilder resolvedPath = new StringBuilder(); |
||||
String[] paths = StringUtils.commaDelimitedListToStringArray(resourceLoaderPath); |
||||
for (int i = 0; i < paths.length; i++) { |
||||
String path = paths[i]; |
||||
Resource resource = getResourceLoader().getResource(path); |
||||
File file = resource.getFile(); // will fail if not resolvable in the file system
|
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Resource loader path [" + path + "] resolved to file [" + file.getAbsolutePath() + "]"); |
||||
} |
||||
resolvedPath.append(file.getAbsolutePath()); |
||||
if (i < paths.length - 1) { |
||||
resolvedPath.append(','); |
||||
} |
||||
} |
||||
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); |
||||
velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, "true"); |
||||
velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, resolvedPath.toString()); |
||||
} |
||||
catch (IOException ex) { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Cannot resolve resource loader path [" + resourceLoaderPath + |
||||
"] to [java.io.File]: using SpringResourceLoader", ex); |
||||
} |
||||
initSpringResourceLoader(velocityEngine, resourceLoaderPath); |
||||
} |
||||
} |
||||
else { |
||||
// Always load via SpringResourceLoader
|
||||
// (without hot detection of template changes).
|
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("File system access not preferred: using SpringResourceLoader"); |
||||
} |
||||
initSpringResourceLoader(velocityEngine, resourceLoaderPath); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Initialize a SpringResourceLoader for the given VelocityEngine. |
||||
* <p>Called by {@code initVelocityResourceLoader}. |
||||
* @param velocityEngine the VelocityEngine to configure |
||||
* @param resourceLoaderPath the path to load Velocity resources from |
||||
* @see SpringResourceLoader |
||||
* @see #initVelocityResourceLoader |
||||
*/ |
||||
protected void initSpringResourceLoader(VelocityEngine velocityEngine, String resourceLoaderPath) { |
||||
velocityEngine.setProperty( |
||||
RuntimeConstants.RESOURCE_LOADER, SpringResourceLoader.NAME); |
||||
velocityEngine.setProperty( |
||||
SpringResourceLoader.SPRING_RESOURCE_LOADER_CLASS, SpringResourceLoader.class.getName()); |
||||
velocityEngine.setProperty( |
||||
SpringResourceLoader.SPRING_RESOURCE_LOADER_CACHE, "true"); |
||||
velocityEngine.setApplicationAttribute( |
||||
SpringResourceLoader.SPRING_RESOURCE_LOADER, getResourceLoader()); |
||||
velocityEngine.setApplicationAttribute( |
||||
SpringResourceLoader.SPRING_RESOURCE_LOADER_PATH, resourceLoaderPath); |
||||
} |
||||
|
||||
/** |
||||
* To be implemented by subclasses that want to perform custom |
||||
* post-processing of the VelocityEngine after this FactoryBean |
||||
* performed its default configuration (but before VelocityEngine.init). |
||||
* <p>Called by {@code createVelocityEngine()}. |
||||
* @param velocityEngine the current VelocityEngine |
||||
* @throws IOException if a config file wasn't found |
||||
* @throws VelocityException on Velocity initialization failure |
||||
* @see #createVelocityEngine() |
||||
* @see org.apache.velocity.app.VelocityEngine#init |
||||
*/ |
||||
protected void postProcessVelocityEngine(VelocityEngine velocityEngine) |
||||
throws IOException, VelocityException { |
||||
} |
||||
|
||||
} |
||||
@ -1,79 +0,0 @@
@@ -1,79 +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.ui.velocity; |
||||
|
||||
import java.io.IOException; |
||||
|
||||
import org.apache.velocity.app.VelocityEngine; |
||||
import org.apache.velocity.exception.VelocityException; |
||||
|
||||
import org.springframework.beans.factory.FactoryBean; |
||||
import org.springframework.beans.factory.InitializingBean; |
||||
import org.springframework.context.ResourceLoaderAware; |
||||
|
||||
/** |
||||
* Factory bean that configures a VelocityEngine and provides it as bean |
||||
* reference. This bean is intended for any kind of usage of Velocity in |
||||
* application code, e.g. for generating email content. For web views, |
||||
* VelocityConfigurer is used to set up a VelocityEngine for views. |
||||
* |
||||
* <p>The simplest way to use this class is to specify a "resourceLoaderPath"; |
||||
* you do not need any further configuration then. For example, in a web |
||||
* application context: |
||||
* |
||||
* <pre class="code"> <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> |
||||
* <property name="resourceLoaderPath" value="/WEB-INF/velocity/"/> |
||||
* </bean></pre> |
||||
* |
||||
* See the base class VelocityEngineFactory for configuration details. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @see #setConfigLocation |
||||
* @see #setVelocityProperties |
||||
* @see #setResourceLoaderPath |
||||
* @see org.springframework.web.servlet.view.velocity.VelocityConfigurer |
||||
* @deprecated as of Spring 4.3, in favor of FreeMarker |
||||
*/ |
||||
@Deprecated |
||||
public class VelocityEngineFactoryBean extends VelocityEngineFactory |
||||
implements FactoryBean<VelocityEngine>, InitializingBean, ResourceLoaderAware { |
||||
|
||||
private VelocityEngine velocityEngine; |
||||
|
||||
|
||||
@Override |
||||
public void afterPropertiesSet() throws IOException, VelocityException { |
||||
this.velocityEngine = createVelocityEngine(); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public VelocityEngine getObject() { |
||||
return this.velocityEngine; |
||||
} |
||||
|
||||
@Override |
||||
public Class<? extends VelocityEngine> getObjectType() { |
||||
return VelocityEngine.class; |
||||
} |
||||
|
||||
@Override |
||||
public boolean isSingleton() { |
||||
return true; |
||||
} |
||||
|
||||
} |
||||
@ -1,118 +0,0 @@
@@ -1,118 +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.ui.velocity; |
||||
|
||||
import java.io.StringWriter; |
||||
import java.io.Writer; |
||||
import java.util.Map; |
||||
|
||||
import org.apache.velocity.VelocityContext; |
||||
import org.apache.velocity.app.VelocityEngine; |
||||
import org.apache.velocity.exception.VelocityException; |
||||
|
||||
/** |
||||
* Utility class for working with a VelocityEngine. |
||||
* Provides convenience methods to merge a Velocity template with a model. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 22.01.2004 |
||||
* @deprecated as of Spring 4.3, in favor of FreeMarker |
||||
*/ |
||||
@Deprecated |
||||
public abstract class VelocityEngineUtils { |
||||
|
||||
/** |
||||
* Merge the specified Velocity template with the given model and write |
||||
* the result to the given Writer. |
||||
* @param velocityEngine VelocityEngine to work with |
||||
* @param templateLocation the location of template, relative to Velocity's resource loader path |
||||
* @param model the Map that contains model names as keys and model objects as values |
||||
* @param writer the Writer to write the result to |
||||
* @throws VelocityException if the template wasn't found or rendering failed |
||||
* @deprecated Use {@link #mergeTemplate(VelocityEngine, String, String, Map, Writer)} |
||||
* instead, following Velocity 1.6's corresponding deprecation in its own API. |
||||
*/ |
||||
@Deprecated |
||||
public static void mergeTemplate( |
||||
VelocityEngine velocityEngine, String templateLocation, Map<String, Object> model, Writer writer) |
||||
throws VelocityException { |
||||
|
||||
VelocityContext velocityContext = new VelocityContext(model); |
||||
velocityEngine.mergeTemplate(templateLocation, velocityContext, writer); |
||||
} |
||||
|
||||
/** |
||||
* Merge the specified Velocity template with the given model and write the result |
||||
* to the given Writer. |
||||
* @param velocityEngine VelocityEngine to work with |
||||
* @param templateLocation the location of template, relative to Velocity's resource loader path |
||||
* @param encoding the encoding of the template file |
||||
* @param model the Map that contains model names as keys and model objects as values |
||||
* @param writer the Writer to write the result to |
||||
* @throws VelocityException if the template wasn't found or rendering failed |
||||
*/ |
||||
public static void mergeTemplate( |
||||
VelocityEngine velocityEngine, String templateLocation, String encoding, |
||||
Map<String, Object> model, Writer writer) throws VelocityException { |
||||
|
||||
VelocityContext velocityContext = new VelocityContext(model); |
||||
velocityEngine.mergeTemplate(templateLocation, encoding, velocityContext, writer); |
||||
} |
||||
|
||||
/** |
||||
* Merge the specified Velocity template with the given model into a String. |
||||
* <p>When using this method to prepare a text for a mail to be sent with Spring's |
||||
* mail support, consider wrapping VelocityException in MailPreparationException. |
||||
* @param velocityEngine VelocityEngine to work with |
||||
* @param templateLocation the location of template, relative to Velocity's resource loader path |
||||
* @param model the Map that contains model names as keys and model objects as values |
||||
* @return the result as String |
||||
* @throws VelocityException if the template wasn't found or rendering failed |
||||
* @see org.springframework.mail.MailPreparationException |
||||
* @deprecated Use {@link #mergeTemplateIntoString(VelocityEngine, String, String, Map)} |
||||
* instead, following Velocity 1.6's corresponding deprecation in its own API. |
||||
*/ |
||||
@Deprecated |
||||
public static String mergeTemplateIntoString(VelocityEngine velocityEngine, String templateLocation, |
||||
Map<String, Object> model) throws VelocityException { |
||||
|
||||
StringWriter result = new StringWriter(); |
||||
mergeTemplate(velocityEngine, templateLocation, model, result); |
||||
return result.toString(); |
||||
} |
||||
|
||||
/** |
||||
* Merge the specified Velocity template with the given model into a String. |
||||
* <p>When using this method to prepare a text for a mail to be sent with Spring's |
||||
* mail support, consider wrapping VelocityException in MailPreparationException. |
||||
* @param velocityEngine VelocityEngine to work with |
||||
* @param templateLocation the location of template, relative to Velocity's resource loader path |
||||
* @param encoding the encoding of the template file |
||||
* @param model the Map that contains model names as keys and model objects as values |
||||
* @return the result as String |
||||
* @throws VelocityException if the template wasn't found or rendering failed |
||||
* @see org.springframework.mail.MailPreparationException |
||||
*/ |
||||
public static String mergeTemplateIntoString(VelocityEngine velocityEngine, String templateLocation, |
||||
String encoding, Map<String, Object> model) throws VelocityException { |
||||
|
||||
StringWriter result = new StringWriter(); |
||||
mergeTemplate(velocityEngine, templateLocation, encoding, model, result); |
||||
return result.toString(); |
||||
} |
||||
|
||||
} |
||||
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
/** |
||||
* Support classes for setting up |
||||
* <a href="http://velocity.apache.org">Velocity</a> |
||||
* within a Spring application context. |
||||
*/ |
||||
package org.springframework.ui.velocity; |
||||
@ -1,59 +0,0 @@
@@ -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/"); |
||||
} |
||||
} |
||||
} |
||||
@ -1,41 +0,0 @@
@@ -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(); |
||||
|
||||
} |
||||
@ -1,151 +0,0 @@
@@ -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"> |
||||
* <bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> |
||||
* <property name="resourceLoaderPath"><value>/WEB-INF/velocity/</value></property> |
||||
* </bean></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; |
||||
} |
||||
|
||||
} |
||||
@ -1,188 +0,0 @@
@@ -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()); |
||||
} |
||||
|
||||
} |
||||
@ -1,110 +0,0 @@
@@ -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; |
||||
} |
||||
|
||||
} |
||||
@ -1,134 +0,0 @@
@@ -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); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,578 +0,0 @@
@@ -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); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -1,137 +0,0 @@
@@ -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; |
||||
} |
||||
|
||||
} |
||||
@ -1,7 +0,0 @@
@@ -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; |
||||
@ -1,320 +0,0 @@
@@ -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 ' ' 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 ' ' 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 |
||||
@ -1,56 +0,0 @@
@@ -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; |
||||
} |
||||
|
||||
} |
||||
@ -1,171 +0,0 @@
@@ -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())); |
||||
} |
||||
|
||||
} |
||||
@ -1,266 +0,0 @@
@@ -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]); |
||||
} |
||||
} |
||||
} |
||||
@ -1,173 +0,0 @@
@@ -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); |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -1,83 +0,0 @@
@@ -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); |
||||
} |
||||
|
||||
} |
||||
@ -1,145 +0,0 @@
@@ -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!
|
||||
} |
||||
|
||||
} |
||||
@ -1,280 +0,0 @@
@@ -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()); |
||||
} |
||||
|
||||
} |
||||
@ -1,4 +0,0 @@
@@ -1,4 +0,0 @@
|
||||
## |
||||
## test template for Velocity view with missing method |
||||
## |
||||
$command.nonexistent() |
||||
@ -1,4 +0,0 @@
@@ -1,4 +0,0 @@
|
||||
## |
||||
## test template for Velocity view with exception |
||||
## |
||||
$command.unreliableFileOperation() |
||||
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
## |
||||
## test template for Velocity view |
||||
## |
||||
|
||||
NAME |
||||
$command.name |
||||
@ -1,30 +0,0 @@
@@ -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" "") |
||||
@ -1,64 +0,0 @@
@@ -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(" " "") |
||||
@ -1,23 +0,0 @@
@@ -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> |
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
Loading…
Reference in new issue