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