From e62ce882045052e41e3f907d5f7627b2dac536d6 Mon Sep 17 00:00:00 2001 From: Rick Herrick <jrherrick@wustl.edu> Date: Fri, 22 Jul 2016 17:37:20 -0500 Subject: [PATCH] XNAT-2429 Workaround for bean loading issue: extension bean aggregates all extension instances, letting Spring manage the "beans of type" problem. --- .../xnat/configuration/ApplicationConfig.java | 12 ++++++ .../org/nrg/xnat/configuration/WebConfig.java | 8 ++-- .../org/nrg/xnat/restlet/XNATApplication.java | 21 +++++----- .../xnat/restlet/XnatRestletExtensions.java | 21 ++++++---- .../restlet/XnatRestletExtensionsBean.java | 39 +++++++++++++++++++ 5 files changed, 80 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/nrg/xnat/restlet/XnatRestletExtensionsBean.java diff --git a/src/main/java/org/nrg/xnat/configuration/ApplicationConfig.java b/src/main/java/org/nrg/xnat/configuration/ApplicationConfig.java index f618b49c..8d3a1e5d 100644 --- a/src/main/java/org/nrg/xnat/configuration/ApplicationConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/ApplicationConfig.java @@ -14,7 +14,9 @@ import org.nrg.xdat.services.ThemeService; import org.nrg.xdat.services.impl.ThemeServiceImpl; import org.nrg.xnat.initialization.InitializingTask; import org.nrg.xnat.initialization.InitializingTasksExecutor; +import org.nrg.xnat.restlet.XnatRestlet; import org.nrg.xnat.restlet.XnatRestletExtensions; +import org.nrg.xnat.restlet.XnatRestletExtensionsBean; import org.nrg.xnat.restlet.actions.importer.ImporterHandlerPackages; import org.nrg.xnat.services.PETTracerUtils; import org.nrg.xnat.utils.XnatUserProvider; @@ -97,11 +99,21 @@ public class ApplicationConfig { return new XnatUserProvider(preferences.getReceivedFileUser()); } + @Bean + public XnatRestletExtensionsBean xnatRestletExtensionsBean(final List<XnatRestletExtensions> extensions) { + return new XnatRestletExtensionsBean(extensions); + } + @Bean public XnatRestletExtensions defaultXnatRestletExtensions() { return new XnatRestletExtensions(new HashSet<>(Arrays.asList(new String[] {"org.nrg.xnat.restlet.extensions"}))); } + @Bean + public XnatRestletExtensions extraXnatRestletExtensions() { + return new XnatRestletExtensions(new HashSet<>(Arrays.asList(new String[] {"org.nrg.xnat.restlet.actions"}))); + } + @Bean public ImporterHandlerPackages importerHandlerPackages() { return new ImporterHandlerPackages(new HashSet<>(Arrays.asList(new String[] {"org.nrg.xnat.restlet.actions", "org.nrg.xnat.archive"}))); diff --git a/src/main/java/org/nrg/xnat/configuration/WebConfig.java b/src/main/java/org/nrg/xnat/configuration/WebConfig.java index 4bc2cdc4..2829c778 100644 --- a/src/main/java/org/nrg/xnat/configuration/WebConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/WebConfig.java @@ -9,7 +9,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.context.support.ReloadableResourceBundleMessageSource; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.ViewResolver; @@ -59,8 +59,8 @@ public class WebConfig extends WebMvcConfigurerAdapter { @Bean public MessageSource messageSource() { - return new ResourceBundleMessageSource() {{ - setBasename("org/nrg/xnat/messages/system.properties"); + return new ReloadableResourceBundleMessageSource() {{ + setBasename("classpath:org/nrg/xnat/messages/system"); }}; } @@ -71,6 +71,8 @@ public class WebConfig extends WebMvcConfigurerAdapter { } private ApiInfo apiInfo() { + // TODO: The deprecated class is ApiInfo(). There's no documentation on how to use the replacement Contact class instead, so migrate this when that's explained. + //noinspection deprecation return new ApiInfo("XNAT REST API", "The XNAT REST API (XAPI) functions provide access to XNAT internal functions for remote clients.", "1.7.0", "http://www.xnat.org", "info@xnat.org", "Simplified 2-Clause BSD", "API license URL"); } diff --git a/src/main/java/org/nrg/xnat/restlet/XNATApplication.java b/src/main/java/org/nrg/xnat/restlet/XNATApplication.java index fc54abf4..32913dc4 100755 --- a/src/main/java/org/nrg/xnat/restlet/XNATApplication.java +++ b/src/main/java/org/nrg/xnat/restlet/XNATApplication.java @@ -46,10 +46,10 @@ public class XNATApplication extends Application { public static final String PREARC_PROJECT_URI = "/prearchive/projects/{PROJECT_ID}"; public static final String PREARC_SESSION_URI = PREARC_PROJECT_URI + "/{SESSION_TIMESTAMP}/{SESSION_LABEL}"; + @SuppressWarnings("WeakerAccess") @JsonIgnore public XNATApplication(Context parentContext) { super(parentContext); - } @Override @@ -364,19 +364,18 @@ public class XNATApplication extends Application { * @param router The URL router for the restlet servlet. * @return A list of classes that should be attached unprotected, i.e. publicly accessible. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "Duplicates"}) private List<Class<? extends Resource>> addExtensionRoutes(Router router) { - final Set<String> packages = new HashSet<>(); - final Map<String, XnatRestletExtensions> pkgLists = XDAT.getContextService().getBeansOfType(XnatRestletExtensions.class); - if (pkgLists.size() == 0) { - final XnatRestletExtensions extensions = XDAT.getContextService().getBean("defaultXnatRestletExtensions", XnatRestletExtensions.class); - if (extensions != null) { - pkgLists.put("defaultXnatRestletExtensions", extensions); + final Set<String> packages = new HashSet<>(); + final XnatRestletExtensionsBean extensions = XDAT.getContextService().getBean(XnatRestletExtensionsBean.class); + if (extensions.size() > 0) { + packages.addAll(extensions.getPackages()); + } else { + final XnatRestletExtensions extension = XDAT.getContextService().getBean("defaultXnatRestletExtensions", XnatRestletExtensions.class); + if (extension != null) { + packages.addAll(extension.getPackages()); } } - for (XnatRestletExtensions pkgList : pkgLists.values()) { - packages.addAll(pkgList); - } if (packages.size() == 0) { packages.add("org.nrg.xnat.restlet.extensions"); } diff --git a/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensions.java b/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensions.java index c583e55f..cf51a588 100644 --- a/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensions.java +++ b/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensions.java @@ -12,16 +12,23 @@ package org.nrg.xnat.restlet; +import java.util.Collections; import java.util.HashSet; import java.util.Set; -public class XnatRestletExtensions extends HashSet<String> { - public XnatRestletExtensions(Set<String> packages) { - super(); - this.setPackages(packages); +public class XnatRestletExtensions { + public XnatRestletExtensions(final Set<String> packages) { + super(); + _packages.addAll(packages); } - public void setPackages(Set<String> packages) { - clear(); - addAll(packages); + + public int size() { + return _packages.size(); + } + + public Set<String> getPackages() { + return Collections.unmodifiableSet(_packages); } + + private final Set<String> _packages = new HashSet<>(); } diff --git a/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensionsBean.java b/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensionsBean.java new file mode 100644 index 00000000..64963b6d --- /dev/null +++ b/src/main/java/org/nrg/xnat/restlet/XnatRestletExtensionsBean.java @@ -0,0 +1,39 @@ +/* + * org.nrg.xnat.restlet.XnatRestletExtensionList + * + * Copyright (c) 2016, Washington University School of Medicine + * All Rights Reserved + * + * XNAT is an open-source project of the Neuroinformatics Research Group. + * Released under the Simplified BSD. + * + * Last modified 1/19/16 3:49 PM + */ + +package org.nrg.xnat.restlet; + +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Component +public class XnatRestletExtensionsBean { + public XnatRestletExtensionsBean(final List<XnatRestletExtensions> extensions) { + for (final XnatRestletExtensions extension : extensions) { + _packages.addAll(extension.getPackages()); + } + } + + public int size() { + return _packages.size(); + } + + public Set<String> getPackages() { + return Collections.unmodifiableSet(_packages); + } + + private final Set<String> _packages = new HashSet<>(); +} -- GitLab