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