1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.hal.docs.impl;
21
22 import java.io.IOException;
23
24 import javax.servlet.Servlet;
25 import javax.servlet.ServletConfig;
26 import javax.servlet.ServletException;
27 import javax.servlet.ServletRequest;
28 import javax.servlet.ServletResponse;
29 import javax.servlet.http.HttpServlet;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.apache.commons.lang3.CharEncoding;
34 import org.apache.commons.lang3.StringUtils;
35 import org.apache.felix.scr.annotations.Activate;
36 import org.apache.felix.scr.annotations.Component;
37 import org.apache.felix.scr.annotations.Deactivate;
38 import org.apache.felix.scr.annotations.Reference;
39 import org.apache.felix.scr.annotations.Service;
40 import org.osgi.framework.Bundle;
41 import org.osgi.service.component.ComponentContext;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import io.wcm.caravan.hal.docs.impl.model.LinkRelation;
46 import io.wcm.caravan.hal.docs.impl.reader.ServiceModelReader;
47
48
49
50
51 @Component(factory = HalDocsServlet.FACTORY)
52 @Service(Servlet.class)
53 public class HalDocsServlet extends HttpServlet {
54
55 private static final long serialVersionUID = 1L;
56
57 static final String FACTORY = "caravan.haldocs.servlet.factory";
58 static final String PROPERTY_BUNDLE = "caravan.haldocs.relatedBundle";
59
60 private io.wcm.caravan.hal.docs.impl.model.Service serviceModel;
61
62 @Reference
63 private TemplateRenderer templateRenderer;
64
65 private static final Logger log = LoggerFactory.getLogger(HalDocsServlet.class);
66
67 @Activate
68 void activate(ComponentContext componentContext) {
69
70 Bundle bundle = (Bundle)componentContext.getProperties().get(PROPERTY_BUNDLE);
71 serviceModel = ServiceModelReader.read(bundle);
72 }
73
74 @Deactivate
75 void deactivate(ComponentContext componentContext) {
76 serviceModel = null;
77 }
78
79 @Override
80 public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
81 HttpServletRequest request = (HttpServletRequest)servletRequest;
82 HttpServletResponse response = (HttpServletResponse)servletResponse;
83
84 if (serviceModel != null) {
85 try {
86 String uri = StringUtils.defaultString(request.getPathInfo());
87 if (StringUtils.equals(uri, "/")) {
88 sendMarkup(templateRenderer.renderServiceHtml(serviceModel), response);
89 return;
90 }
91 else {
92 String rel = StringUtils.substringAfter(uri, "/");
93 LinkRelation linkRelation = serviceModel.getLinkRelations().stream()
94 .filter(item -> StringUtils.equals(item.getRel(), rel))
95 .findFirst().orElse(null);
96 if (linkRelation != null) {
97 sendMarkup(templateRenderer.renderLinkRelationHtml(serviceModel, linkRelation), response);
98 return;
99 }
100 }
101 }
102 catch (Throwable ex) {
103 log.error("Error rendering HAL docs for " + serviceModel.getServiceId() + ": " + request.getPathInfo(), ex);
104 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex.getMessage());
105 }
106 }
107
108 response.sendError(HttpServletResponse.SC_NOT_FOUND);
109 }
110
111 private void sendMarkup(String markup, HttpServletResponse response) throws IOException {
112 byte[] data = markup.getBytes(CharEncoding.UTF_8);
113 response.setContentType(HttpContextWrapper.MIMETYPE_HTML);
114 response.setContentLength(data.length);
115 response.getOutputStream().write(data);
116 }
117
118 @Override
119 public void init() throws ServletException {
120
121 }
122
123 @Override
124 public void init(ServletConfig config) throws ServletException {
125
126 }
127
128 @Override
129 public void destroy() {
130
131 }
132
133 }