[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