From 1bec98716eede4a1c5588b6fc9d36436b8e99bda Mon Sep 17 00:00:00 2001 From: Rick Herrick <jrherrick@wustl.edu> Date: Mon, 22 Feb 2016 13:29:16 -0600 Subject: [PATCH] Moved initializer and root config classes to initialization package to remove change of double-scanning. Fixed a few other items. --- .../xnat/configuration/DatabaseConfig.java | 6 ++ .../RootConfig.java | 3 +- .../XnatWebAppInitializer.java | 87 ++++++++--------- .../security/XnatSessionEventPublisher.java | 94 ++++++++++--------- .../WEB-INF/conf/root-spring-config.xml | 20 ---- 5 files changed, 96 insertions(+), 114 deletions(-) rename src/main/java/org/nrg/xnat/{configuration => initialization}/RootConfig.java (97%) rename src/main/java/org/nrg/xnat/{configuration => initialization}/XnatWebAppInitializer.java (50%) delete mode 100644 src/main/webapp/WEB-INF/conf/root-spring-config.xml diff --git a/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java b/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java index ab3b7734..6fe2217c 100644 --- a/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java +++ b/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java @@ -4,6 +4,7 @@ import org.apache.commons.dbcp.BasicDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; @@ -23,6 +24,11 @@ public class DatabaseConfig { return dataSource; } + @Bean + public JdbcTemplate jdbcTemplate() { + return new JdbcTemplate(dataSource()); + } + @Value("${datasource.driver}") private String _driver; @Value("${datasource.url}") diff --git a/src/main/java/org/nrg/xnat/configuration/RootConfig.java b/src/main/java/org/nrg/xnat/initialization/RootConfig.java similarity index 97% rename from src/main/java/org/nrg/xnat/configuration/RootConfig.java rename to src/main/java/org/nrg/xnat/initialization/RootConfig.java index 7307d849..3f7f48c6 100644 --- a/src/main/java/org/nrg/xnat/configuration/RootConfig.java +++ b/src/main/java/org/nrg/xnat/initialization/RootConfig.java @@ -1,4 +1,4 @@ -package org.nrg.xnat.configuration; +package org.nrg.xnat.initialization; import org.nrg.framework.datacache.SerializerRegistry; import org.nrg.framework.orm.hibernate.HibernateEntityPackageList; @@ -25,6 +25,7 @@ import java.util.List; "org.nrg.xft.daos", "org.nrg.xft.services", "org.nrg.xapi.configuration", "org.nrg.xnat.helpers.merge", + "org.nrg.xnat.configuration", "org.nrg.xnat.services", "org.nrg.prefs.repositories", "org.nrg.prefs.services.impl.hibernate", diff --git a/src/main/java/org/nrg/xnat/configuration/XnatWebAppInitializer.java b/src/main/java/org/nrg/xnat/initialization/XnatWebAppInitializer.java similarity index 50% rename from src/main/java/org/nrg/xnat/configuration/XnatWebAppInitializer.java rename to src/main/java/org/nrg/xnat/initialization/XnatWebAppInitializer.java index c956e120..a2389a15 100644 --- a/src/main/java/org/nrg/xnat/configuration/XnatWebAppInitializer.java +++ b/src/main/java/org/nrg/xnat/initialization/XnatWebAppInitializer.java @@ -1,11 +1,10 @@ -package org.nrg.xnat.configuration; +package org.nrg.xnat.initialization; import org.apache.axis.transport.http.AdminServlet; import org.apache.axis.transport.http.AxisHTTPSessionListener; import org.apache.axis.transport.http.AxisServlet; import org.apache.commons.lang3.StringUtils; import org.apache.turbine.Turbine; -import org.apache.turbine.util.TurbineConfig; import org.nrg.xdat.servlet.XDATAjaxServlet; import org.nrg.xdat.servlet.XDATServlet; import org.nrg.xnat.restlet.servlet.XNATRestletServlet; @@ -13,16 +12,16 @@ import org.nrg.xnat.restlet.util.UpdateExpirationCookie; import org.nrg.xnat.security.XnatSessionEventPublisher; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; -import javax.servlet.Servlet; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRegistration; +import javax.servlet.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; public class XnatWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override public void onStartup(final ServletContext context) throws ServletException { - context.setInitParameter("contextAttribute", "org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-mvc"); context.setInitParameter("org.restlet.component", "org.nrg.xnat.restlet.XNATComponent"); // If the context path is not empty (meaning this isn't the root application), then we'll get true: Restlet will @@ -39,7 +38,7 @@ public class XnatWebAppInitializer extends AbstractAnnotationConfigDispatcherSer context.addListener(XnatSessionEventPublisher.class); context.addListener(AxisHTTPSessionListener.class); - Turbine.setTurbineServletConfig(new TurbineConfig("turbine", "WEB-INF/conf/TurbineResources.properties")); + Turbine.setTurbineServletConfig(new XnatTurbineConfig(context)); _context = context; @@ -49,45 +48,6 @@ public class XnatWebAppInitializer extends AbstractAnnotationConfigDispatcherSer addServlet(XDATAjaxServlet.class, 3, "/ajax/*", "/servlet/XDATAjaxServlet", "/servlet/AjaxServlet"); addServlet(AxisServlet.class, 4, "/servlet/AxisServlet", "*.jws", "/services/*"); addServlet(AdminServlet.class, 5, "/servlet/AdminServlet"); - - // TODO: Don't know how to do these things through the servlet context. - /* - <welcome-file-list> - <welcome-file>index.jsp</welcome-file> - <welcome-file>app</welcome-file> - </welcome-file-list> - <!-- ======================================================================== --> - <!-- --> - <!-- Mapping HTTP error codes and exceptions to custom error pages to make --> - <!-- the display a bit more pleasant and preserve system confidentiality. --> - <!-- --> - <!-- ======================================================================== --> - <error-page> - <exception-type>java.lang.Throwable</exception-type> - <location>/app/template/Error.vm</location> - </error-page> - <!-- ======================================================================== --> - <!-- --> - <!-- Make sure that templates, resources and logs are not available through --> - <!-- the servlet container. Remove security constraints or add an authen- --> - <!-- tication role if you need access to these paths. --> - <!-- --> - <!-- ======================================================================== --> - // Might need to do these through Spring Security configuration: - // http://stackoverflow.com/questions/19297796/how-to-programmatically-setup-a-security-constraint-in-servlets-3-x - // Or move them into WEB-INF a la Spring views. Note that logs is already removed. - <security-constraint> - <web-resource-collection> - <web-resource-name>templates</web-resource-name> - <url-pattern>/templates/*</url-pattern> - </web-resource-collection> - <web-resource-collection> - <web-resource-name>resources</web-resource-name> - <url-pattern>/resources/*</url-pattern> - </web-resource-collection> - <auth-constraint /> - </security-constraint> - */ } @Override @@ -112,5 +72,38 @@ public class XnatWebAppInitializer extends AbstractAnnotationConfigDispatcherSer registration.addMapping(mappings); } + private static class XnatTurbineConfig implements ServletConfig { + public XnatTurbineConfig(final ServletContext context) { + _context = context; + } + + @Override + public String getServletName() { + return "Turbine"; + } + + @Override + public ServletContext getServletContext() { + return _context; + } + + @Override + public String getInitParameter(final String s) { + if (s.equals("properties")) { + return "WEB-INF/conf/TurbineResources.properties"; + } + return null; + } + + @Override + public Enumeration<String> getInitParameterNames() { + final List<String> parameters = new ArrayList<>(); + parameters.add("properties"); + return Collections.enumeration(parameters); + } + + private ServletContext _context; + } + private ServletContext _context; } diff --git a/src/main/java/org/nrg/xnat/security/XnatSessionEventPublisher.java b/src/main/java/org/nrg/xnat/security/XnatSessionEventPublisher.java index f69f2904..5227aa20 100644 --- a/src/main/java/org/nrg/xnat/security/XnatSessionEventPublisher.java +++ b/src/main/java/org/nrg/xnat/security/XnatSessionEventPublisher.java @@ -10,17 +10,6 @@ */ package org.nrg.xnat.security; -import java.util.UUID; - -import javax.inject.Inject; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; -import javax.sql.DataSource; - import org.nrg.xft.security.UserI; import org.nrg.xnat.restlet.resources.SecureResource; import org.slf4j.Logger; @@ -31,15 +20,20 @@ import org.springframework.security.web.session.HttpSessionCreatedEvent; import org.springframework.security.web.session.HttpSessionDestroyedEvent; import org.springframework.web.context.support.WebApplicationContextUtils; +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; +import java.util.UUID; -public class XnatSessionEventPublisher implements HttpSessionListener, ServletContextListener{ - private String contextAttribute = null; - private static final Logger _log = LoggerFactory.getLogger(XnatSessionEventPublisher.class); - - ApplicationContext getContext(ServletContext servletContext) { - return WebApplicationContextUtils.getWebApplicationContext(servletContext,contextAttribute); // contextAttribute in xnat's case will always be "org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-mvc"); - } - +public class XnatSessionEventPublisher implements HttpSessionListener, ServletContextListener { /** * Handles the HttpSessionEvent by publishing a {@link HttpSessionCreatedEvent} to the application * appContext. @@ -67,25 +61,22 @@ public class XnatSessionEventPublisher implements HttpSessionListener, ServletCo * * @param event The HttpSessionEvent pass in by the container */ - public void sessionDestroyed(HttpSessionEvent event) { - - String sessionId = event.getSession().getId(); - - - java.util.Date today = java.util.Calendar.getInstance(java.util.TimeZone.getDefault()).getTime(); - try { + public void sessionDestroyed(final HttpSessionEvent event) { + final String sessionId = event.getSession().getId(); + final Date today = Calendar.getInstance(TimeZone.getDefault()).getTime(); - UserI user = (UserI) event.getSession().getAttribute(SecureResource.USER_ATTRIBUTE); - if(user != null){ - String userId = user.getID().toString(); - JdbcTemplate template = new JdbcTemplate(_dataSource); - java.sql.Timestamp stamp = new java.sql.Timestamp(today.getTime()); - //sessionId's aren't guaranteed to be unique forever. But, the likelihood of sessionId and userId not forming a unique combo with a null logout_date is slim. - template.execute("UPDATE xdat_user_login SET logout_date='" + stamp +"' WHERE logout_date is null and session_id='" + sessionId + "' and user_xdat_user_id='" + userId + "';"); - } - } catch (Exception e){ - //remember, anonymous gets a session, too. Those won't be in the table. Fail silently. - } + try { + final UserI user = (UserI) event.getSession().getAttribute(SecureResource.USER_ATTRIBUTE); + if (user != null) { + final String userId = user.getID().toString(); + final Timestamp stamp = new Timestamp(today.getTime()); + //sessionId's aren't guaranteed to be unique forever. But, the likelihood of sessionId and userId not forming a unique combo with a null logout_date is slim. + //noinspection SqlDialectInspection,SqlNoDataSourceInspection,SqlResolve + _template.execute("UPDATE xdat_user_login SET logout_date='" + stamp + "' WHERE logout_date is null and session_id='" + sessionId + "' and user_xdat_user_id='" + userId + "';"); + } + } catch (Exception e) { + //remember, anonymous gets a session, too. Those won't be in the table. Fail silently. + } HttpSessionDestroyedEvent e = new HttpSessionDestroyedEvent(event.getSession()); if (_log.isDebugEnabled()) { _log.debug("Publishing event: " + e); @@ -93,17 +84,28 @@ public class XnatSessionEventPublisher implements HttpSessionListener, ServletCo getContext(event.getSession().getServletContext()).publishEvent(e); } - @Override - public void contextDestroyed(ServletContextEvent arg0) { - //nothing to do here. + @Override + public void contextDestroyed(final ServletContextEvent event) { + if (_log.isDebugEnabled()) { + final ServletContext context = event.getServletContext(); + _log.debug("Context destroyed: {}", context.getContextPath()); + } + } + + @Override + public void contextInitialized(final ServletContextEvent event) { + if (_log.isDebugEnabled()) { + final ServletContext context = event.getServletContext(); + _log.debug("Context initialized: {}", context.getContextPath()); + } + } + + private ApplicationContext getContext(ServletContext servletContext) { + return WebApplicationContextUtils.findWebApplicationContext(servletContext); // contextAttribute in xnat's case will always be "org.springframework.web.servlet.FrameworkServlet.CONTEXT.spring-mvc"); } - @Override - public void contextInitialized(ServletContextEvent event) { - ServletContext ctx=event.getServletContext(); - contextAttribute=ctx.getInitParameter("contextAttribute"); - } + private static final Logger _log = LoggerFactory.getLogger(XnatSessionEventPublisher.class); @Inject - private DataSource _dataSource; + private JdbcTemplate _template; } \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/conf/root-spring-config.xml b/src/main/webapp/WEB-INF/conf/root-spring-config.xml deleted file mode 100644 index 4da3256c..00000000 --- a/src/main/webapp/WEB-INF/conf/root-spring-config.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - ~ D:/Development/XNAT/1.6/xnat_builder_1_6dev/plugin-resources/conf/root-spring-config.xml - ~ XNAT http://www.xnat.org - ~ Copyright (c) 2014, Washington University School of Medicine - ~ All Rights Reserved - ~ - ~ Released under the Simplified BSD. - ~ - ~ Last modified 2/7/14 12:19 PM - --> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - - <context:component-scan base-package="org.nrg.xnat.configuration"/> - -</beans> -- GitLab