1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.site.run;
20
21 import javax.servlet.Filter;
22 import javax.servlet.FilterChain;
23 import javax.servlet.FilterConfig;
24 import javax.servlet.ServletContext;
25 import javax.servlet.ServletException;
26 import javax.servlet.ServletRequest;
27 import javax.servlet.ServletResponse;
28 import javax.servlet.http.HttpServletRequest;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.nio.file.Files;
33 import java.nio.file.Path;
34 import java.util.List;
35 import java.util.Locale;
36 import java.util.Map;
37
38 import org.apache.maven.doxia.siterenderer.DocumentRenderer;
39 import org.apache.maven.doxia.siterenderer.DoxiaDocumentRenderer;
40 import org.apache.maven.doxia.siterenderer.Renderer;
41 import org.apache.maven.doxia.siterenderer.RendererException;
42 import org.apache.maven.doxia.siterenderer.SiteRenderingContext;
43 import org.apache.maven.plugins.site.render.ReportDocumentRenderer;
44 import org.eclipse.jetty.http.MimeTypes;
45
46 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
47
48
49
50
51
52
53 public class DoxiaFilter implements Filter {
54 public static final String OUTPUT_DIRECTORY_KEY = "outputDirectory";
55
56 public static final String SITE_RENDERER_KEY = "siteRenderer";
57
58 public static final String I18N_DOXIA_CONTEXTS_KEY = "i18nDoxiaContexts";
59
60 public static final String LOCALES_LIST_KEY = "localesList";
61
62 private ServletContext servletContext;
63
64 private File outputDirectory;
65
66 private Renderer siteRenderer;
67
68 private Map<String, DoxiaBean> i18nDoxiaContexts;
69
70 private List<Locale> localesList;
71
72
73
74
75 public void init(FilterConfig filterConfig) throws ServletException {
76 servletContext = filterConfig.getServletContext();
77
78 outputDirectory = (File) servletContext.getAttribute(OUTPUT_DIRECTORY_KEY);
79
80 siteRenderer = (Renderer) servletContext.getAttribute(SITE_RENDERER_KEY);
81
82 i18nDoxiaContexts = (Map<String, DoxiaBean>) servletContext.getAttribute(I18N_DOXIA_CONTEXTS_KEY);
83
84 localesList = (List<Locale>) servletContext.getAttribute(LOCALES_LIST_KEY);
85 }
86
87
88
89
90 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
91 throws IOException, ServletException {
92 HttpServletRequest req = (HttpServletRequest) servletRequest;
93
94
95
96
97 String path = req.getServletPath();
98
99 if (path.endsWith("/")) {
100 path += "index.html";
101 }
102
103
104 path = path.substring(1);
105
106
107 SiteRenderingContext context;
108 Map<String, DocumentRenderer> documents;
109 SiteRenderingContext generatedSiteContext;
110
111 String localeWanted = null;
112 for (Locale locale : localesList) {
113 if (path.startsWith(locale + "/")) {
114 localeWanted = locale.toString();
115 path = path.substring(localeWanted.length() + 1);
116 }
117 }
118
119 if (localeWanted == null) {
120 DoxiaBean defaultDoxiaBean = i18nDoxiaContexts.get("default");
121 if (defaultDoxiaBean == null) {
122 throw new ServletException("No doxia bean found for the default locale");
123 }
124 context = defaultDoxiaBean.getContext();
125 documents = defaultDoxiaBean.getDocuments();
126 generatedSiteContext = defaultDoxiaBean.getGeneratedSiteContext();
127 } else {
128 DoxiaBean i18nDoxiaBean = i18nDoxiaContexts.get(localeWanted);
129 if (i18nDoxiaBean == null) {
130 throw new ServletException("No doxia bean found for locale '" + localeWanted + "'");
131 }
132 context = i18nDoxiaBean.getContext();
133 documents = i18nDoxiaBean.getDocuments();
134 generatedSiteContext = i18nDoxiaBean.getGeneratedSiteContext();
135 }
136
137
138
139
140 if (documents.containsKey(path)) {
141 try {
142 DocumentRenderer renderer = documents.get(path);
143 logDocumentRenderer(path, renderer);
144 String outputName = renderer.getOutputName();
145 String contentType = MimeTypes.getDefaultMimeByExtension(outputName);
146 if (contentType != null) {
147 servletResponse.setContentType(contentType);
148 }
149 renderer.renderDocument(servletResponse.getWriter(), siteRenderer, context);
150
151 if (renderer instanceof ReportDocumentRenderer) {
152 ReportDocumentRenderer reportDocumentRenderer = (ReportDocumentRenderer) renderer;
153 if (reportDocumentRenderer.isExternalReport()) {
154 Path externalReportFile = outputDirectory.toPath().resolve(outputName);
155 servletResponse.reset();
156 if (contentType != null) {
157 servletResponse.setContentType(contentType);
158 }
159 Files.copy(externalReportFile, servletResponse.getOutputStream());
160 }
161 }
162
163 return;
164 } catch (RendererException e) {
165 throw new ServletException(e);
166 }
167 } else if (generatedSiteContext != null) {
168 try {
169 Map<String, DocumentRenderer> locateDocuments =
170 siteRenderer.locateDocumentFiles(generatedSiteContext, false);
171
172 if (locateDocuments.containsKey(path)) {
173 DocumentRenderer renderer = locateDocuments.get(path);
174 logDocumentRenderer(path, renderer);
175 String outputName = renderer.getOutputName();
176 String contentType = MimeTypes.getDefaultMimeByExtension(outputName);
177 if (contentType != null) {
178 servletResponse.setContentType(contentType);
179 }
180 renderer.renderDocument(servletResponse.getWriter(), siteRenderer, generatedSiteContext);
181
182 return;
183 }
184 } catch (RendererException e) {
185 throw new ServletException(e);
186 }
187 }
188
189 filterChain.doFilter(servletRequest, servletResponse);
190 }
191
192 private void logDocumentRenderer(String path, DocumentRenderer renderer) {
193 String source;
194 if (renderer instanceof DoxiaDocumentRenderer) {
195 DoxiaDocumentRenderer doxiaDocumentRenderer = (DoxiaDocumentRenderer) renderer;
196 source = doxiaDocumentRenderer.getRenderingContext().getInputName();
197 } else if (renderer instanceof ReportDocumentRenderer) {
198 ReportDocumentRenderer reportDocumentRenderer = (ReportDocumentRenderer) renderer;
199 source = reportDocumentRenderer.getReportMojoInfo();
200 } else {
201 source = renderer.getClass().getName();
202 }
203 servletContext.log(path + " -> " + buffer().strong(source));
204 }
205
206
207
208
209 public void destroy() {}
210 }