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