[spring-extensions] branch master updated: IDP-1349 - Migrate existing code base to Spring 5 and SWF 2.5
Scott Cantor
cantor.2 at osu.edu
Tue Oct 23 22:22:07 EDT 2018
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository spring-extensions.
View the commit online:
http://git.shibboleth.net/view/?p=spring-extensions.git;a=commit;h=d38de30acea5e2d458080a1abbe2acca525fc3cb
The following commit(s) were added to refs/heads/master by this push:
new d38de30 IDP-1349 - Migrate existing code base to Spring 5 and SWF 2.5
d38de30 is described below
commit d38de30acea5e2d458080a1abbe2acca525fc3cb
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Oct 23 22:22:05 2018 -0400
IDP-1349 - Migrate existing code base to Spring 5 and SWF 2.5
https://issues.shibboleth.net/jira/browse/IDP-1349
Port VelocityView and supporting classes from Spring 4.
---
.../ext/spring/velocity/VelocityConfig.java | 43 +++
.../ext/spring/velocity/VelocityConfigurer.java | 118 +++++++
.../ext/spring/velocity/VelocityEngineFactory.java | 1 -
.../ext/spring/velocity/VelocityView.java | 359 +++++++++++++++++++++
.../ext/spring/velocity/VelocityViewResolver.java | 41 +++
.../net/shibboleth/ext/spring/velocity/spring.vm | 320 ++++++++++++++++++
6 files changed, 881 insertions(+), 1 deletion(-)
diff --git a/src/main/java/net/shibboleth/ext/spring/velocity/VelocityConfig.java b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityConfig.java
new file mode 100644
index 0000000..e01284f
--- /dev/null
+++ b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityConfig.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.ext.spring.velocity;
+
+import javax.annotation.Nonnull;
+
+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 {@link VelocityView}.
+ *
+ * @author Rod Johnson
+ *
+ * @since 6.0.0
+ */
+public interface VelocityConfig {
+
+ /**
+ * Return the VelocityEngine for the current web application context.
+ *
+ * <p>May be unique to one servlet, or shared in the root context.</p>
+ *
+ * @return the VelocityEngine
+ */
+ @Nonnull VelocityEngine getVelocityEngine();
+}
\ No newline at end of file
diff --git a/src/main/java/net/shibboleth/ext/spring/velocity/VelocityConfigurer.java b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityConfigurer.java
new file mode 100644
index 0000000..0cd9bba
--- /dev/null
+++ b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityConfigurer.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.ext.spring.velocity;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.servlet.ServletContext;
+
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+
+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
+ *
+ * @since 6.0.0
+ */
+public class VelocityConfigurer extends VelocityEngineFactory
+ implements VelocityConfig, ResourceLoaderAware, ServletContextAware {
+
+ /** Name of the resource loader for Spring's bind macros. */
+ private static final String SPRING_MACRO_RESOURCE_LOADER_NAME = "springMacro";
+
+ /** Key for the class of Spring's bind macro resource loader. */
+ private static final String SPRING_MACRO_RESOURCE_LOADER_CLASS = "springMacro.resource.loader.class";
+
+ /** Name of Spring's default bind macro library. */
+ private static final String SPRING_MACRO_LIBRARY = "net/shibboleth/ext/spring/velocity/spring.vm";
+
+ /** Servlet context. */
+ @Nullable private ServletContext servletContext;
+
+ /** Velocity engine. */
+ @Nullable private VelocityEngine velocityEngine;
+
+ /** {@inheritDoc} */
+ @Override
+ public void setServletContext(@Nonnull final ServletContext context) {
+ servletContext = context;
+ }
+
+ /**
+ * 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(@Nonnull final VelocityEngine engine) {
+ velocityEngine = engine;
+
+ velocityEngine.setApplicationAttribute(ServletContext.class.getName(), 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);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public VelocityEngine getVelocityEngine() {
+ return velocityEngine;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/shibboleth/ext/spring/velocity/VelocityEngineFactory.java b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityEngineFactory.java
index 5fa8276..b850d16 100644
--- a/src/main/java/net/shibboleth/ext/spring/velocity/VelocityEngineFactory.java
+++ b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityEngineFactory.java
@@ -246,7 +246,6 @@ public class VelocityEngineFactory {
overrideLogging = flag;
}
-
/**
* Prepare the VelocityEngine instance and return it.
*
diff --git a/src/main/java/net/shibboleth/ext/spring/velocity/VelocityView.java b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityView.java
new file mode 100644
index 0000000..e9110e8
--- /dev/null
+++ b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityView.java
@@ -0,0 +1,359 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.ext.spring.velocity;
+
+import java.util.Locale;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+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.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.view.AbstractTemplateView;
+import org.springframework.web.util.NestedServletException;
+
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+
+/**
+ * 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>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>Note: Spring 3.0's VelocityView requires Velocity 1.4 or higher.</p>
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @author Dave Syer
+ *
+ * @since 6.0.0
+ */
+public class VelocityView extends AbstractTemplateView {
+
+ /** Template encoding. */
+ @Nullable private String encoding;
+
+ /** Caching flag. */
+ private boolean cacheTemplate;
+
+ /** Velocity engine. */
+ @Nullable private VelocityEngine velocityEngine;
+
+ /** The template. */
+ @Nullable private Template template;
+
+ /**
+ * Set the encoding of the Velocity template file.
+ *
+ * <p>Default is determined
+ * by the VelocityEngine: "ISO-8859-1" if not specified otherwise.
+ * Specify the encoding in the VelocityEngine rather than per template
+ * if all your templates share a common encoding.</p>
+ *
+ * @param enc encoding
+ */
+ public void setEncoding(@Nullable final String enc) {
+ encoding = enc;
+ }
+
+ /**
+ * Return the encoding for the Velocity template.
+ *
+ * @return encoding
+ */
+ @Nullable protected String getEncoding() {
+ return encoding;
+ }
+
+ /**
+ * Set whether the Velocity template should be cached (default is "false").
+ *
+ * <p>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>
+ *
+ * <p>Note that this is a minor optimization only, as Velocity itself caches
+ * templates in a modification-aware fashion.</p>
+ *
+ * @param flag flag to set
+ */
+ public void setCacheTemplate(final boolean flag) {
+ cacheTemplate = flag;
+ }
+
+ /**
+ * Return whether the Velocity template should be cached.
+ *
+ * @return whether template should be cached
+ */
+ protected boolean isCacheTemplate() {
+ return cacheTemplate;
+ }
+
+ /**
+ * Set the VelocityEngine to be used by this view.
+ *
+ * <p>If this is not set, the default lookup will occur: A single {@link VelocityConfig}
+ * is expected in the current web application context, with any bean name.</p>
+ *
+ * @param engine velocity engine
+ */
+ public void setVelocityEngine(@Nullable final VelocityEngine engine) {
+ velocityEngine = engine;
+ }
+
+ /**
+ * Return the VelocityEngine used by this view.
+ *
+ * @return engine
+ */
+ @Nullable protected VelocityEngine getVelocityEngine() {
+ return velocityEngine;
+ }
+
+ /**
+ * Invoked on startup. Looks for a single {@link 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.
+ *
+ * <p>Called if no explicit VelocityEngine has been specified.</p>
+ *
+ * @return the VelocityEngine to use
+ *
+ * @throws BeansException if no VelocityEngine could be found
+ */
+ @Nonnull protected VelocityEngine autodetectVelocityEngine() throws BeansException {
+ try {
+ final VelocityConfig velocityConfig = BeanFactoryUtils.beanOfTypeIncludingAncestors(
+ getApplicationContext(), VelocityConfig.class, true, false);
+ return velocityConfig.getVelocityEngine();
+ } catch (final 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(@Nullable final Locale locale) throws Exception {
+ try {
+ // Check that we can get the template, even if we might subsequently get it again.
+ template = getTemplate(getUrl());
+ return true;
+ } catch (final ResourceNotFoundException ex) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("No Velocity view found for URL: " + getUrl());
+ }
+ return false;
+ } catch (final 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.
+ *
+ * <p>Output is directed to the servlet response.
+ * This method can be overridden if custom behavior is needed.</p>
+ */
+ @Override
+ protected void renderMergedTemplateModel(@Nullable final Map<String,Object> model,
+ @Nonnull final HttpServletRequest request, @Nonnull final HttpServletResponse response) throws Exception {
+
+ final Context velocityContext = createVelocityContext(model, request, response);
+
+ doRender(velocityContext, response);
+ }
+
+ /**
+ * 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>
+ *
+ * @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
+ */
+ protected Context createVelocityContext(@Nullable final Map<String,Object> model,
+ @Nonnull final HttpServletRequest request, @Nonnull final 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.</p>
+ *
+ * @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
+ */
+ protected Context createVelocityContext(@Nullable final Map<String, Object> model) throws Exception {
+ return new VelocityContext(model);
+ }
+
+ /**
+ * 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>
+ *
+ * <p>Can be overridden to customize the behavior, for example to render
+ * multiple templates into a single view.</p>
+ *
+ * @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
+ */
+ protected void doRender(@Nonnull final Context context, @Nonnull final 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)</p>
+ *
+ * @return the Velocity template to render
+ *
+ * @throws Exception if thrown by Velocity
+ */
+ 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() && template != null) {
+ return 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.</p>
+ *
+ * @param name the file name of the desired template
+ *
+ * @return the Velocity template
+ *
+ * @throws Exception if thrown by Velocity
+ */
+ protected Template getTemplate(@Nonnull @NotEmpty final String name) throws Exception {
+ return getEncoding() != null ?
+ getVelocityEngine().getTemplate(name, getEncoding()) :
+ getVelocityEngine().getTemplate(name);
+ }
+
+ /**
+ * Merge the template with the context.
+ *
+ * @param t 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
+ */
+ protected void mergeTemplate(@Nonnull final Template t, @Nonnull final Context context,
+ @Nonnull final HttpServletResponse response) throws Exception {
+
+ try {
+ t.merge(context, response.getWriter());
+ } catch (final MethodInvocationException ex) {
+ final 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);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/shibboleth/ext/spring/velocity/VelocityViewResolver.java b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityViewResolver.java
new file mode 100644
index 0000000..bffe05d
--- /dev/null
+++ b/src/main/java/net/shibboleth/ext/spring/velocity/VelocityViewResolver.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements. See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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 net.shibboleth.ext.spring.velocity;
+
+import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
+
+/**
+ * Convenience subclass of {@link org.springframework.web.servlet.view.UrlBasedViewResolver}
+ * that supports {@link VelocityView} (i.e. Velocity templates) and custom subclasses of it.
+ *
+ * <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 6.0.0
+ */
+public class VelocityViewResolver extends AbstractTemplateViewResolver {
+
+ /** Constructor. */
+ public VelocityViewResolver() {
+ setViewClass(VelocityView.class);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/resources/net/shibboleth/ext/spring/velocity/spring.vm b/src/main/resources/net/shibboleth/ext/spring/velocity/spring.vm
new file mode 100644
index 0000000..8ae5fe2
--- /dev/null
+++ b/src/main/resources/net/shibboleth/ext/spring/velocity/spring.vm
@@ -0,0 +1,320 @@
+#**
+ * 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
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list