1 package com.atlassian.johnson.spring.lifecycle;
2
3 import com.atlassian.johnson.Johnson;
4 import com.atlassian.johnson.config.JohnsonConfig;
5 import com.atlassian.johnson.spring.web.servlet.JohnsonDispatcherServlet;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.web.context.WebApplicationContext;
9 import org.springframework.web.servlet.DispatcherServlet;
10
11 import javax.servlet.ServletException;
12 import javax.servlet.http.HttpServlet;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import java.io.IOException;
16 import java.net.URLEncoder;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public class LifecycleDispatcherServlet extends HttpServlet {
34
35 private static final String PROP_SYNCHRONOUS = "johnson.spring.lifecycle.synchronousStartup";
36
37 private final Logger log = LoggerFactory.getLogger(getClass());
38
39 private volatile DispatcherServlet delegate;
40 private volatile Thread startup;
41
42 @Override
43 public void destroy() {
44 Thread startup = this.startup;
45 if (startup != null) {
46 if (startup.isAlive()) {
47
48 startup.interrupt();
49 }
50
51 try {
52
53
54
55 startup.join();
56 } catch (InterruptedException e) {
57 log.error("The SpringMVC startup thread could not be joined", e);
58 }
59 }
60
61 DispatcherServlet delegate = this.delegate;
62 if (delegate != null) {
63
64 delegate.destroy();
65 }
66 }
67
68 @Override
69 public void init() throws ServletException {
70 Thread thread = new Thread(new Runnable() {
71
72 @Override
73 public void run() {
74 JohnsonDispatcherServlet servlet = new JohnsonDispatcherServlet() {
75
76 @Override
77 public String getServletContextAttributeName() {
78
79
80
81 return WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
82 }
83 };
84
85 LifecycleUtils.updateState(getServletContext(), LifecycleState.STARTING);
86 try {
87
88
89
90 servlet.init(getServletConfig());
91
92 delegate = servlet;
93 LifecycleUtils.updateState(getServletContext(), LifecycleState.STARTED);
94 } catch (Exception e) {
95 LifecycleUtils.updateState(getServletContext(), LifecycleState.FAILED);
96 log.error("SpringMVC could not be started", e);
97 } finally {
98 startup = null;
99 }
100 }
101 });
102 thread.setDaemon(true);
103 thread.setName("spring-startup");
104
105 (startup = thread).start();
106
107 if (Boolean.getBoolean(PROP_SYNCHRONOUS)) {
108 try {
109 thread.join();
110 } catch (InterruptedException e) {
111 Thread.currentThread().interrupt();
112 log.warn("Interrupted while waiting for synchronous Spring startup to complete");
113 }
114 }
115 }
116
117 @Override
118 protected void service(HttpServletRequest request, HttpServletResponse response)
119 throws ServletException, IOException {
120 DispatcherServlet delegate = this.delegate;
121 if (delegate == null) {
122 JohnsonConfig config = Johnson.getConfig(getServletContext());
123
124 String nextUrl = request.getRequestURI();
125
126 if (request.getQueryString() != null && !request.getQueryString().isEmpty()) {
127 nextUrl += "?" + request.getQueryString();
128 }
129
130 String redirectUrl = request.getContextPath() + config.getErrorPath()
131 + "?next=" + URLEncoder.encode(nextUrl, "UTF-8");
132
133 response.sendRedirect(redirectUrl);
134 } else {
135 delegate.service(request, response);
136 }
137 }
138 }