Package: DefaultEmbeddedServer
DefaultEmbeddedServer
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
DefaultEmbeddedServer(MimeTypeResolver) |
|
|
|
|
|
||||||||||||||||||||
afterPropertiesSet() |
|
|
|
|
|
||||||||||||||||||||
destroy() |
|
|
|
|
|
||||||||||||||||||||
getPort() |
|
|
|
|
|
||||||||||||||||||||
loadResource(String) |
|
|
|
|
|
||||||||||||||||||||
onOpenSite(OpenSiteEvent) |
|
|
|
|
|
||||||||||||||||||||
putDocument(String, EmbeddedServer.Document) |
|
|
|
|
|
||||||||||||||||||||
serveContentResources(String, HttpServletResponse) |
|
|
|
|
|
||||||||||||||||||||
serveEditorResources(String, HttpServletResponse) |
|
|
|
|
|
||||||||||||||||||||
serveRegisteredResources(String, HttpServletResponse) |
|
|
|
|
|
||||||||||||||||||||
setPort(int) |
|
|
|
|
|
||||||||||||||||||||
start() |
|
|
|
|
|
||||||||||||||||||||
static {...} |
|
|
|
|
|
||||||||||||||||||||
stop() |
|
|
|
|
|
||||||||||||||||||||
updateRegisteredResource(HttpServletRequest, HttpServletResponse) |
|
|
|
|
|
Coverage
1: /*
2: * #%L
3: * *********************************************************************************************************************
4: *
5: * NorthernWind - lightweight CMS
6: * http://northernwind.tidalwave.it - git clone git@bitbucket.org:tidalwave/northernwind-rca-src.git
7: * %%
8: * Copyright (C) 2013 - 2021 Tidalwave s.a.s. (http://tidalwave.it)
9: * %%
10: * *********************************************************************************************************************
11: *
12: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
13: * the License. You may obtain a copy of the License at
14: *
15: * http://www.apache.org/licenses/LICENSE-2.0
16: *
17: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
18: * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
19: * specific language governing permissions and limitations under the License.
20: *
21: * *********************************************************************************************************************
22: *
23: *
24: * *********************************************************************************************************************
25: * #L%
26: */
27: package it.tidalwave.northernwind.rca.embeddedserver.impl;
28:
29: import javax.annotation.CheckForNull;
30: import javax.annotation.Nonnull;
31: import javax.annotation.PostConstruct;
32: import javax.annotation.PreDestroy;
33: import java.util.HashMap;
34: import java.util.Map;
35: import java.io.IOException;
36: import java.io.DataInputStream;
37: import java.io.FileNotFoundException;
38: import javax.servlet.ServletException;
39: import javax.servlet.http.HttpServletRequest;
40: import javax.servlet.http.HttpServletResponse;
41: import it.tidalwave.util.annotation.VisibleForTesting;
42: import lombok.RequiredArgsConstructor;
43: import org.springframework.core.io.ClassPathResource;
44: import org.eclipse.jetty.server.Server;
45: import it.tidalwave.messagebus.annotation.ListensTo;
46: import it.tidalwave.messagebus.annotation.SimpleMessageSubscriber;
47: import it.tidalwave.northernwind.core.impl.filter.LibraryLinkMacroFilter;
48: import it.tidalwave.northernwind.core.impl.filter.MediaLinkMacroFilter;
49: import it.tidalwave.northernwind.core.model.MimeTypeResolver;
50: import it.tidalwave.northernwind.core.model.ResourceFile;
51: import it.tidalwave.northernwind.core.model.ResourceFileSystem;
52: import it.tidalwave.northernwind.rca.embeddedserver.EmbeddedServer;
53: import it.tidalwave.northernwind.rca.ui.event.OpenSiteEvent;
54: import lombok.Getter;
55: import lombok.Setter;
56: import lombok.extern.slf4j.Slf4j;
57: import static java.util.stream.Collectors.joining;
58:
59: /***********************************************************************************************************************
60: *
61: * @author Fabrizio Giudici
62: *
63: **********************************************************************************************************************/
64:•@SimpleMessageSubscriber @RequiredArgsConstructor @Slf4j
65: public class DefaultEmbeddedServer implements EmbeddedServer
66: {
67: @Nonnull
68: private final MimeTypeResolver mimeTypeResolver;
69:
70: @Getter @Setter
71: private int port = 12345;
72:
73: @CheckForNull
74: @VisibleForTesting Server server;
75:
76: private final Map<String, Document> documentMapByUrl = new HashMap<>();
77:
78: @CheckForNull
79: private ResourceFileSystem fileSystem;
80:
81: /*******************************************************************************************************************
82: *
83: *
84: *
85: ******************************************************************************************************************/
86: private final ServletAdapter servlet = new ServletAdapter()
87: {
88: private static final long serialVersionUID = -2887261966375531858L;
89:
90: private final MediaLinkMacroFilter mediaLinkMacroFilter = new MediaLinkMacroFilter();
91: private final LibraryLinkMacroFilter libraryLinkMacroFilter = new LibraryLinkMacroFilter();
92:
93: @Override
94: protected void doGet (@Nonnull final HttpServletRequest request,
95: @Nonnull final HttpServletResponse response)
96: throws ServletException, IOException
97: {
98: String uri = request.getRequestURI();
99: log.debug("doGet({})", uri);
100: // FIXME: use a pipeline for handling those requests - eventually integrate support already in Site
101:
102: uri = mediaLinkMacroFilter.filter(uri, "");
103: uri = libraryLinkMacroFilter.filter(uri, "");
104: uri = uri.replace("//", "/"); // Aloha puts a leading / before the macro
105: log.debug(">>> filtered {}", uri);
106:
107: if (uri.startsWith("/nwa/")) // FIXME - and use ResourcePath
108: {
109: serveEditorResources(uri, response);
110: }
111:
112: else if (uri.startsWith("/library/") || uri.startsWith("/media/")) // FIXME - and use ResourcePath
113: {
114: serveContentResources(uri, response);
115: }
116:
117: else
118: {
119: serveRegisteredResources(uri, response);
120: }
121: }
122:
123: @Override
124: protected void doPut (@Nonnull final HttpServletRequest request,
125: @Nonnull final HttpServletResponse response)
126: throws ServletException, IOException
127: {
128: final String uri = request.getRequestURI();
129: log.debug("doPut({})", uri);
130: updateRegisteredResource(request, response);
131: }
132: };
133:
134: /*******************************************************************************************************************
135: *
136: *
137: *
138: *
139: ******************************************************************************************************************/
140: @VisibleForTesting void onOpenSite (@ListensTo @Nonnull final OpenSiteEvent event)
141: {
142: log.debug("onOpenSite({})", event);
143: fileSystem = event.getFileSystem();
144: }
145:
146: /*******************************************************************************************************************
147: *
148: *
149: *
150: *
151: ******************************************************************************************************************/
152: @PostConstruct
153: public void start()
154: {
155: try
156: {
157: log.info("Starting webserver on port {}...", port);
158: server = new Server(port);
159: server.setHandler(servlet.asHandler());
160: server.start();
161: log.info(">>>> started");
162: }
163: catch (Exception e)
164: {
165: log.error("", e);
166: }
167: }
168:
169: /*******************************************************************************************************************
170: *
171: *
172: *
173: *
174: ******************************************************************************************************************/
175: @PreDestroy
176: public void stop()
177: {
178: try
179: {
180:• if ((server != null) && !server.isStopping() && !server.isStopped())
181: {
182: log.info("Stopping webserver...");
183: server.stop();
184: log.info(">>>> stopped");
185: }
186: }
187: catch (Exception e)
188: {
189: log.error("", e);
190: }
191: }
192:
193: /*******************************************************************************************************************
194: *
195: *
196: *
197: *
198: ******************************************************************************************************************/
199: @Override @Nonnull
200: public String putDocument (@Nonnull final String path, @Nonnull final Document document)
201: {
202: documentMapByUrl.put(path, document);
203: return String.format("http://localhost:%d%s", port, path);
204: }
205:
206: /*******************************************************************************************************************
207: *
208: *
209: *
210: ******************************************************************************************************************/
211: private void serveEditorResources (@Nonnull final String uri,
212: @Nonnull final HttpServletResponse response)
213: throws IOException
214: {
215: try
216: {
217: final byte[] resource = loadResource(uri);
218: response.setCharacterEncoding("");
219: response.setContentType(mimeTypeResolver.getMimeType(uri));
220: response.setStatus(HttpServletResponse.SC_OK);
221: response.getOutputStream().write(resource);
222: }
223: catch (FileNotFoundException e)
224: {
225: log.warn("2 - Not found: {}", uri);
226: response.setStatus(HttpServletResponse.SC_NOT_FOUND);
227: }
228: }
229:
230: /*******************************************************************************************************************
231: *
232: *
233: *
234: ******************************************************************************************************************/
235: private void serveContentResources (@Nonnull final String uri,
236: @Nonnull final HttpServletResponse response)
237: throws IOException
238: {
239: log.debug("serveLibraryResources({})", uri);
240:
241: // don't bother when there's no opened Site
242:• if (fileSystem == null)
243: {
244: response.setStatus(HttpServletResponse.SC_OK);
245: }
246: else
247: {
248: final ResourceFile file = fileSystem.findFileByPath("/content" + uri); // FIXME
249:
250:• if (file == null)
251: {
252: log.warn("5 - Not found: {}", "/content" + uri);
253: response.setStatus(HttpServletResponse.SC_NOT_FOUND);
254: return;
255: }
256:
257: final String mimeType = file.getMimeType();
258: response.setContentType(mimeType);
259: response.setStatus(HttpServletResponse.SC_OK);
260:
261:• if (mimeType.startsWith("image"))
262: {
263: response.getOutputStream().write(file.asBytes());
264: }
265: else
266: {
267: response.setCharacterEncoding("UTF-8");
268: response.getWriter().write(file.asText("UTF-8"));
269: }
270: }
271: }
272:
273: /*******************************************************************************************************************
274: *
275: *
276: *
277: ******************************************************************************************************************/
278: private void serveRegisteredResources (@Nonnull final String uri,
279: @Nonnull final HttpServletResponse response)
280: throws IOException
281: {
282: final Document document = documentMapByUrl.get(uri);
283:
284:• if (document == null)
285: {
286: log.warn("1 - Not found: {}", uri);
287: response.setStatus(HttpServletResponse.SC_NOT_FOUND);
288: }
289: else
290: {
291: response.setCharacterEncoding("UTF-8");
292: response.setContentType(document.getMimeType());
293: response.setStatus(HttpServletResponse.SC_OK);
294: response.getWriter().write(document.getContent());
295: }
296: }
297:
298: /*******************************************************************************************************************
299: *
300: *
301: *
302: ******************************************************************************************************************/
303: private void updateRegisteredResource (@Nonnull final HttpServletRequest request,
304: @Nonnull final HttpServletResponse response)
305: throws IOException
306: {
307: final String uri = request.getRequestURI();
308: final String body = request.getReader().lines().collect(joining("\n"));
309:
310: final Document document = documentMapByUrl.get(uri);
311:
312:• if (document == null)
313: {
314: log.warn("3 - Not found: {}", uri);
315: response.setStatus(HttpServletResponse.SC_NOT_FOUND);
316: }
317: else
318: {
319: document.update(body);
320: response.setStatus(HttpServletResponse.SC_OK);
321: }
322: }
323:
324: /*******************************************************************************************************************
325: *
326: *
327: *
328: ******************************************************************************************************************/
329: @Nonnull
330: @VisibleForTesting byte[] loadResource (@Nonnull final String path)
331: throws IOException
332: {
333: final ClassPathResource resource = new ClassPathResource(path);
334:
335: try (final DataInputStream is = new DataInputStream(resource.getInputStream()))
336: {
337: return is.readAllBytes();
338: }
339: }
340: }