1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.neo4j.server.web;
21
22 import com.sun.jersey.api.core.ResourceConfig;
23 import com.sun.jersey.spi.container.servlet.ServletContainer;
24 import org.mortbay.jetty.Server;
25 import org.mortbay.jetty.SessionManager;
26 import org.mortbay.jetty.handler.MovedContextHandler;
27 import org.mortbay.jetty.servlet.Context;
28 import org.mortbay.jetty.servlet.HashSessionManager;
29 import org.mortbay.jetty.servlet.ServletHolder;
30 import org.mortbay.jetty.servlet.SessionHandler;
31 import org.mortbay.jetty.webapp.WebAppContext;
32 import org.mortbay.resource.Resource;
33 import org.mortbay.thread.QueuedThreadPool;
34 import org.neo4j.server.NeoServer;
35 import org.neo4j.server.logging.Logger;
36 import org.neo4j.server.rest.web.AllowAjaxFilter;
37
38 import java.net.URI;
39 import java.net.URISyntaxException;
40 import java.net.URL;
41 import java.util.HashMap;
42 import java.util.List;
43
44 import javax.servlet.Servlet;
45
46 public class Jetty6WebServer implements WebServer
47 {
48 public static final Logger log = Logger.getLogger( Jetty6WebServer.class );
49
50
51 private Server jetty;
52 private int jettyPort = 80;
53
54 private final HashMap<String, String> staticContent = new HashMap<String, String>();
55 private final HashMap<String, ServletHolder> jaxRSPackages = new HashMap<String, ServletHolder>();
56 private NeoServer server;
57
58
59 @Override
60 public void setNeoServer( NeoServer server )
61 {
62 this.server = server;
63 }
64
65 @Override
66 public void start() {
67 jetty = new Server(jettyPort);
68 jetty.setStopAtShutdown(true);
69 MovedContextHandler redirector = new MovedContextHandler();
70
71 jetty.addHandler( redirector );
72
73 loadStaticContent();
74 loadJAXRSPackages();
75
76 try {
77 jetty.start();
78 } catch (Exception e) {
79 throw new RuntimeException(e);
80 }
81 }
82
83 @Override
84 public void stop()
85 {
86 try
87 {
88 jetty.stop();
89 jetty.join();
90 }
91 catch ( Exception e )
92 {
93 throw new RuntimeException(e);
94 }
95 finally
96 {
97
98 jetty.setStopAtShutdown( false );
99 }
100 }
101
102 @Override
103 public void setPort(int portNo) {
104 jettyPort = portNo;
105 }
106
107 @Override
108 public void setMaxThreads(int maxThreads) {
109 jetty.setThreadPool(new QueuedThreadPool(maxThreads));
110 }
111
112 @Override
113 public void addJAXRSPackages(List<String> packageNames, String mountPoint) {
114
115 mountPoint = ensureRelativeUri(mountPoint);
116
117
118 mountPoint = trimTrailingSlash(mountPoint);
119
120 ServletContainer container = new NeoServletContainer(server, server.getInjectables( packageNames ) );
121 ServletHolder servletHolder = new ServletHolder(container);
122 servletHolder.setInitParameter("com.sun.jersey.config.property.packages", toCommaSeparatedList(packageNames));
123 servletHolder.setInitParameter(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, AllowAjaxFilter.class.getName());
124 log.info("Adding JAXRS package %s at [%s]", packageNames, mountPoint);
125 jaxRSPackages.put(mountPoint, servletHolder);
126 }
127
128 @Override
129 public void addServlet( Servlet unmanagedServlet, String mountPoint )
130 {
131 log.info("adding Servlet [%s] at [%s]", unmanagedServlet.getClass().getName(), mountPoint);
132 Context servletContext = new Context(jetty, mountPoint);
133 SessionManager sm = new HashSessionManager();
134 SessionHandler sh = new SessionHandler(sm);
135 ServletHolder servletHolder = new ServletHolder(unmanagedServlet);
136 servletContext.addServlet(servletHolder, "/*");
137 servletContext.setSessionHandler(sh);
138 }
139
140 private String trimTrailingSlash(String mountPoint) {
141 if(mountPoint.equals("/")) {
142 return mountPoint;
143 }
144
145 if(mountPoint.endsWith("/")) {
146 mountPoint = mountPoint.substring(0, mountPoint.length() -1);
147 }
148 return mountPoint;
149 }
150
151 private String ensureRelativeUri(String mountPoint) {
152 try {
153 URI result = new URI(mountPoint);
154 if(result.isAbsolute()) {
155 return result.getPath();
156 } else {
157 return result.toString();
158 }
159 } catch (URISyntaxException e) {
160 log.debug("Unable to translate [%s] to a relative URI in ensureRelativeUri(String mountPoint)", mountPoint);
161 return mountPoint;
162 }
163 }
164
165 @Override
166 public void addStaticContent(String contentLocation, String serverMountPoint) {
167 staticContent.put(serverMountPoint, contentLocation);
168 }
169
170 private void loadStaticContent() {
171 for (String mountPoint : staticContent.keySet()) {
172 String contentLocation = staticContent.get(mountPoint);
173 log.info("Mounting static content at [%s] from [%s]", mountPoint, contentLocation);
174 try {
175 final WebAppContext staticContext = new WebAppContext();
176 staticContext.setServer(jetty);
177 staticContext.setContextPath(mountPoint);
178 URL resourceLoc = getClass().getClassLoader().getResource(contentLocation);
179 if(resourceLoc != null) {
180 log.info("Found [%s]", resourceLoc);
181 URL url = resourceLoc.toURI().toURL();
182 final Resource resource = Resource.newResource(url);
183 staticContext.setBaseResource(resource);
184 log.info("Mounting static content from [%s] at [%s]", url, mountPoint);
185 jetty.addHandler(staticContext);
186 } else {
187 log.error("No static content available for Neo Server at port [%d], management console may not be available.", jettyPort);
188 }
189 } catch (Exception e) {
190 log.error(e);
191 e.printStackTrace();
192 throw new RuntimeException(e);
193 }
194 }
195 }
196
197 private void loadJAXRSPackages() {
198 for (String mountPoint : jaxRSPackages.keySet()) {
199
200 ServletHolder servletHolder = jaxRSPackages.get(mountPoint);
201 log.info("Mounting servlet at [%s]", mountPoint);
202 Context jerseyContext = new Context(jetty, mountPoint);
203 SessionManager sm = new HashSessionManager();
204 SessionHandler sh = new SessionHandler(sm);
205 jerseyContext.addServlet(servletHolder, "/*");
206 jerseyContext.setSessionHandler(sh);
207 }
208 }
209
210 private String toCommaSeparatedList(List<String> packageNames) {
211 StringBuilder sb = new StringBuilder();
212
213 for (String str : packageNames) {
214 sb.append(str);
215 sb.append(", ");
216 }
217
218 String result = sb.toString();
219 return result.substring(0, result.length() - 2);
220 }
221 }