[java-identity-provider] branch master updated: IDP-1640 - Override Spring WebFlow's ApplicationContext creation logic
Scott Cantor
cantor.2 at osu.edu
Thu Jul 16 18:57:54 UTC 2020
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=b84c1493388cdba5820bea2bdaa80a82a781123c
The following commit(s) were added to refs/heads/master by this push:
new b84c14933 IDP-1640 - Override Spring WebFlow's ApplicationContext creation logic
b84c14933 is described below
commit b84c1493388cdba5820bea2bdaa80a82a781123c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Jul 16 14:58:22 2020 -0400
IDP-1640 - Override Spring WebFlow's ApplicationContext creation logic
https://issues.shibboleth.net/jira/browse/IDP-1640
Inject our ApplicationContext and BeanDefinitionReader classes
---
.../spring/factory/FlowModelFlowBuilder.java | 29 +++++--
.../spring/factory/FlowRelativeResourceLoader.java | 98 +++++++++++++++-------
2 files changed, 91 insertions(+), 36 deletions(-)
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowModelFlowBuilder.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowModelFlowBuilder.java
index 28420d5bc..290b0a06d 100644
--- a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowModelFlowBuilder.java
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowModelFlowBuilder.java
@@ -24,7 +24,6 @@ import java.util.List;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.service.RuntimeBindingConversionExecutor;
@@ -114,13 +113,22 @@ import org.springframework.webflow.scope.FlowScope;
import org.springframework.webflow.scope.ViewScope;
import org.springframework.webflow.security.SecurityRule;
+import net.shibboleth.ext.spring.context.FilesystemGenericApplicationContext;
+import net.shibboleth.ext.spring.context.FilesystemGenericWebApplicationContext;
+import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
+
/**
*
- * This code is copied verbatim from org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder
+ * This code is extended from org.springframework.webflow.engine.builder.model.FlowModelFlowBuilder
+ * in order to customize the Spring {@link ApplicationContext} used for flow configuration.
+ *
+ * The only method changed is {@link #createFlowApplicationContext(Resource[])}, but it's private
+ * and there are too many threads pulled by anything but a wholesale duplication of this class.
*
* Builds a runtime {@link Flow} definition object from a {@link FlowModel}.
*
* @author Keith Donald
+ * @author Scott Cantor
*/
public class FlowModelFlowBuilder extends AbstractFlowBuilder {
@@ -338,11 +346,13 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
ApplicationContext parent = getContext().getApplicationContext();
GenericApplicationContext flowContext;
if (parent instanceof WebApplicationContext) {
- GenericWebApplicationContext webContext = new GenericWebApplicationContext();
+ // Shibboleth change - Use our override of GenericWebApplicationContext.
+ GenericWebApplicationContext webContext = new FilesystemGenericWebApplicationContext();
webContext.setServletContext(((WebApplicationContext) parent).getServletContext());
flowContext = webContext;
} else {
- flowContext = new GenericApplicationContext();
+ // Shibboleth change - Use our override of GenericApplicationContext.
+ flowContext = new FilesystemGenericApplicationContext();
}
flowContext.setDisplayName("Flow ApplicationContext [" + getContext().getFlowId() + "]");
flowContext.setParent(parent);
@@ -351,7 +361,7 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
flowContext.getBeanFactory().registerScope("view", new ViewScope());
flowContext.getBeanFactory().registerScope("flow", new FlowScope());
flowContext.getBeanFactory().registerScope("conversation", new ConversationScope());
-
+
// Ensure the current ClassLoader is used, or otherwise setting the ResourceLoader would suppress it
ClassLoader classLoaderToUse = flowContext.getClassLoader();
flowContext.setClassLoader(classLoaderToUse);
@@ -359,8 +369,15 @@ public class FlowModelFlowBuilder extends AbstractFlowBuilder {
Resource flowResource = flowModelHolder.getFlowModelResource();
flowContext.setResourceLoader(new FlowRelativeResourceLoader(flowResource));
+ // Shibboleth change - override the property placeholder syntax.
+ flowContext.getEnvironment().setPlaceholderPrefix("%{");
+ flowContext.getEnvironment().setPlaceholderSuffix("}");
+
AnnotationConfigUtils.registerAnnotationConfigProcessors(flowContext);
- new XmlBeanDefinitionReader(flowContext).loadBeanDefinitions(resources);
+
+ // Shibboleth change - Use our document reader instead, which fixes import resolution.
+ new SchemaTypeAwareXMLBeanDefinitionReader(flowContext).loadBeanDefinitions(resources);
+
registerFlowBeans(flowContext.getBeanFactory());
registerMessageSource(flowContext, flowResource);
diff --git a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowRelativeResourceLoader.java b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowRelativeResourceLoader.java
index e4c1c90d0..704c3744a 100644
--- a/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowRelativeResourceLoader.java
+++ b/idp-profile-spring/src/main/java/net/shibboleth/idp/profile/spring/factory/FlowRelativeResourceLoader.java
@@ -20,45 +20,83 @@ package net.shibboleth.idp.profile.spring.factory;
import java.io.IOException;
import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
+import net.shibboleth.ext.spring.resource.ConditionalResourceResolver;
+
/**
- * This code is copied verbatim from org.springframework.webflow.engine.builder.model.FlowRelativeResourceLoader
- *
- * A resource loader that loads other resources relative to a Flow definition resource. Allows for easy loading of
- * flow-relative resources using the standard {@link ResourceLoader} interface.
+ * This code is extended from org.springframework.webflow.engine.builder.model.FlowRelativeResourceLoader
+ * with modifications to support proper lookup of resources via both filesystem and classpath along with
+ * custom protocol-specific loaders.
*
- * @author Keith Donald
+ * This fills a gap for cases where the Spring {@link ResourceLoader} itself is fully replaced, versus
+ * relying solely on customized behavior in the Spring contexts themselves.
*/
-class FlowRelativeResourceLoader implements ResourceLoader {
+class FlowRelativeResourceLoader extends DefaultResourceLoader {
+
+ /** Flow resource for relative lookup. */
+ private Resource flowResource;
- private Resource flowResource;
+ /**
+ * Constructor.
+ *
+ * @param resource flow resource for relative lookup
+ */
+ public FlowRelativeResourceLoader(final Resource resource) {
+ flowResource = resource;
+ getProtocolResolvers().add(new ConditionalResourceResolver());
+ }
- public FlowRelativeResourceLoader(Resource resource) {
- this.flowResource = resource;
- }
+ public ClassLoader getClassLoader() {
+ return flowResource.getClass().getClassLoader();
+ }
- public ClassLoader getClassLoader() {
- return flowResource.getClass().getClassLoader();
- }
+ /** {@inheritDoc} */
+ @Override
+ public Resource getResource(final String location) {
+
+ final Resource r = super.getResource(location);
+ if (r.exists()) {
+ return r;
+ }
+
+ if (location.startsWith(CLASSPATH_URL_PREFIX)) {
+ return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()),
+ getClassLoader());
+ }
+ return createFlowRelativeResource(location);
+ }
- public Resource getResource(String location) {
- if (location.startsWith(CLASSPATH_URL_PREFIX)) {
- return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
- } else {
- return createFlowRelativeResource(location);
- }
- }
+ private Resource createFlowRelativeResource(final String location) {
+ try {
+ return flowResource.createRelative(location);
+ } catch (final IOException e) {
+ final IllegalArgumentException iae = new IllegalArgumentException(
+ "Unable to access a flow relative resource at location '" + location + "'");
+ iae.initCause(e);
+ throw iae;
+ }
+ }
- private Resource createFlowRelativeResource(String location) {
- try {
- return flowResource.createRelative(location);
- } catch (IOException e) {
- IllegalArgumentException iae = new IllegalArgumentException(
- "Unable to access a flow relative resource at location '" + location + "'");
- iae.initCause(e);
- throw iae;
- }
- }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * Overrides the standard behavior of path-only resources and treats them as file paths if the path exists. Note
+ * that this differs from the ordinary Spring contexts that default to file paths because paths are treated as
+ * absolute if they are in fact absolute.
+ * </p>
+ */
+ @Override
+ protected Resource getResourceByPath(final String path) {
+ final Resource r = new FileSystemResource(path);
+ if (r.exists()) {
+ return r;
+ }
+ return super.getResourceByPath(path);
+ }
+
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list