1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.maven.plugin;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.net.MalformedURLException;
25 import java.util.ArrayList;
26 import java.util.EventListener;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.TreeSet;
32
33 import org.eclipse.jetty.annotations.AnnotationConfiguration;
34 import org.eclipse.jetty.plus.webapp.EnvConfiguration;
35 import org.eclipse.jetty.plus.webapp.PlusConfiguration;
36 import org.eclipse.jetty.quickstart.PreconfigureDescriptorProcessor;
37 import org.eclipse.jetty.quickstart.QuickStartDescriptorGenerator;
38 import org.eclipse.jetty.servlet.FilterHolder;
39 import org.eclipse.jetty.servlet.FilterMapping;
40 import org.eclipse.jetty.servlet.ServletHolder;
41 import org.eclipse.jetty.servlet.ServletMapping;
42 import org.eclipse.jetty.util.URIUtil;
43 import org.eclipse.jetty.util.log.Log;
44 import org.eclipse.jetty.util.log.Logger;
45 import org.eclipse.jetty.util.resource.Resource;
46 import org.eclipse.jetty.util.resource.ResourceCollection;
47 import org.eclipse.jetty.webapp.Configuration;
48 import org.eclipse.jetty.webapp.FragmentConfiguration;
49 import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
50 import org.eclipse.jetty.webapp.MetaInfConfiguration;
51 import org.eclipse.jetty.webapp.WebAppContext;
52 import org.eclipse.jetty.webapp.WebInfConfiguration;
53 import org.eclipse.jetty.webapp.WebXmlConfiguration;
54
55
56
57
58
59
60
61
62
63
64 public class JettyWebAppContext extends WebAppContext
65 {
66 private static final Logger LOG = Log.getLogger(JettyWebAppContext.class);
67
68
69
70 private static final String DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN = ".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$|.*javax.servlet.jsp.jstl-[^/]*\\.jar|.*taglibs-standard-impl-.*\\.jar";
71 private static final String WEB_INF_CLASSES_PREFIX = "/WEB-INF/classes";
72 private static final String WEB_INF_LIB_PREFIX = "/WEB-INF/lib";
73
74 private final Configuration[] _defaultConfigurations = {
75 new MavenWebInfConfiguration(),
76 new WebXmlConfiguration(),
77 new MetaInfConfiguration(),
78 new FragmentConfiguration(),
79 new EnvConfiguration(),
80 new PlusConfiguration(),
81 new AnnotationConfiguration(),
82 new JettyWebXmlConfiguration()
83 };
84
85 private final Configuration[] _quickStartConfigurations = {
86 new MavenQuickStartConfiguration(),
87 new EnvConfiguration(),
88 new PlusConfiguration(),
89 new JettyWebXmlConfiguration()
90 };
91
92 private File _classes = null;
93 private File _testClasses = null;
94 private final List<File> _webInfClasses = new ArrayList<File>();
95 private final List<File> _webInfJars = new ArrayList<File>();
96 private final Map<String, File> _webInfJarMap = new HashMap<String, File>();
97 private List<File> _classpathFiles;
98 private String _jettyEnvXml;
99 private List<Overlay> _overlays;
100 private Resource _quickStartWebXml;
101
102
103
104
105
106
107
108 private String _containerIncludeJarPattern = null;
109
110
111
112
113
114 private String _webInfIncludeJarPattern = null;
115
116
117
118
119
120
121
122
123 private boolean _baseAppFirst = true;
124
125
126
127 private boolean _isGenerateQuickStart;
128 private PreconfigureDescriptorProcessor _preconfigProcessor;
129
130
131
132
133 public JettyWebAppContext ()
134 throws Exception
135 {
136 super();
137
138 super.setCopyWebInf(false);
139 }
140 public void setContainerIncludeJarPattern(String pattern)
141 {
142 _containerIncludeJarPattern = pattern;
143 }
144
145 public String getContainerIncludeJarPattern()
146 {
147 return _containerIncludeJarPattern;
148 }
149
150
151 public String getWebInfIncludeJarPattern()
152 {
153 return _webInfIncludeJarPattern;
154 }
155 public void setWebInfIncludeJarPattern(String pattern)
156 {
157 _webInfIncludeJarPattern = pattern;
158 }
159
160
161 public List<File> getClassPathFiles()
162 {
163 return this._classpathFiles;
164 }
165
166
167 public void setJettyEnvXml (String jettyEnvXml)
168 {
169 this._jettyEnvXml = jettyEnvXml;
170 }
171
172 public String getJettyEnvXml()
173 {
174 return this._jettyEnvXml;
175 }
176
177
178 public void setClasses(File dir)
179 {
180 _classes = dir;
181 }
182
183 public File getClasses()
184 {
185 return _classes;
186 }
187
188 public void setWebInfLib (List<File> jars)
189 {
190 _webInfJars.addAll(jars);
191 }
192
193
194 public void setTestClasses (File dir)
195 {
196 _testClasses = dir;
197 }
198
199
200 public File getTestClasses ()
201 {
202 return _testClasses;
203 }
204
205
206
207
208
209
210 public void setOverlays (List<Overlay> overlays)
211 {
212 _overlays = overlays;
213 }
214
215 public List<Overlay> getOverlays()
216 {
217 return _overlays;
218 }
219
220
221 public void setBaseAppFirst(boolean value)
222 {
223 _baseAppFirst = value;
224 }
225
226
227 public boolean getBaseAppFirst()
228 {
229 return _baseAppFirst;
230 }
231
232
233 public void setQuickStartWebDescriptor (Resource quickStartWebXml)
234 {
235 _quickStartWebXml = quickStartWebXml;
236 }
237
238
239 public Resource getQuickStartWebDescriptor ()
240 {
241 return _quickStartWebXml;
242 }
243
244
245
246
247
248
249
250 public void setResourceBases(String[] resourceBases)
251 {
252 List<String> resources = new ArrayList<String>();
253 for (String rl:resourceBases)
254 {
255 String[] rs = rl.split(" *, *");
256 for (String r:rs)
257 resources.add(r);
258 }
259
260 setBaseResource(new ResourceCollection(resources.toArray(new String[resources.size()])));
261 }
262
263 public List<File> getWebInfLib()
264 {
265 return _webInfJars;
266 }
267
268 public void setGenerateQuickStart (boolean quickStart)
269 {
270 _isGenerateQuickStart = quickStart;
271 }
272
273 public boolean isGenerateQuickStart()
274 {
275 return _isGenerateQuickStart;
276 }
277
278
279
280
281 @Override
282 protected void startWebapp() throws Exception
283 {
284 if (isGenerateQuickStart())
285 {
286 if (getQuickStartWebDescriptor() == null)
287 throw new IllegalStateException ("No location to generate quickstart descriptor");
288
289 QuickStartDescriptorGenerator generator = new QuickStartDescriptorGenerator(this, _preconfigProcessor.getXML());
290 try (FileOutputStream fos = new FileOutputStream(getQuickStartWebDescriptor().getFile()))
291 {
292 generator.generateQuickStartWebXml(fos);
293 }
294 }
295 else
296 super.startWebapp();
297 }
298
299
300 @Override
301 public void doStart () throws Exception
302 {
303
304 if (!isGenerateQuickStart() && getQuickStartWebDescriptor() != null)
305 setConfigurations(_quickStartConfigurations);
306 else
307 {
308 setConfigurations(_defaultConfigurations);
309 if (isGenerateQuickStart())
310 {
311 _preconfigProcessor = new PreconfigureDescriptorProcessor();
312 getMetaData().addDescriptorProcessor(_preconfigProcessor);
313 }
314 }
315
316
317
318 for (Configuration c:getConfigurations())
319 {
320 if (c instanceof EnvConfiguration && getJettyEnvXml() != null)
321 ((EnvConfiguration)c).setJettyEnvXml(Resource.toURL(new File(getJettyEnvXml())));
322 else if (c instanceof MavenQuickStartConfiguration && getQuickStartWebDescriptor() != null)
323 ((MavenQuickStartConfiguration)c).setQuickStartWebXml(getQuickStartWebDescriptor());
324 }
325
326
327
328
329
330 String tmp = _containerIncludeJarPattern;
331 if (tmp==null || "".equals(tmp))
332 tmp = (String)getAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN);
333
334 tmp = addPattern(tmp, DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN);
335 setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, tmp);
336
337
338
339
340 if (_webInfIncludeJarPattern != null)
341 setAttribute(WebInfConfiguration.WEBINF_JAR_PATTERN, _webInfIncludeJarPattern);
342
343
344 if (_testClasses != null)
345 _webInfClasses.add(_testClasses);
346 if (_classes != null)
347 _webInfClasses.add(_classes);
348
349
350 _classpathFiles = new ArrayList<File>();
351 _classpathFiles.addAll(_webInfClasses);
352 _classpathFiles.addAll(_webInfJars);
353
354
355 _webInfJarMap.clear();
356 for (File file : _webInfJars)
357 {
358
359 String fileName = file.getName();
360 if (fileName.endsWith(".jar"))
361 _webInfJarMap.put(fileName, file);
362 }
363
364
365 super.doStart();
366 }
367
368 public void doStop () throws Exception
369 {
370 if (_classpathFiles != null)
371 _classpathFiles.clear();
372 _classpathFiles = null;
373
374 _classes = null;
375 _testClasses = null;
376
377 if (_webInfJarMap != null)
378 _webInfJarMap.clear();
379
380 _webInfClasses.clear();
381 _webInfJars.clear();
382
383
384
385
386
387 Thread.currentThread().sleep(500L);
388 super.doStop();
389
390
391
392 setEventListeners(new EventListener[0]);
393 getServletHandler().setFilters(new FilterHolder[0]);
394 getServletHandler().setFilterMappings(new FilterMapping[0]);
395 getServletHandler().setServlets(new ServletHolder[0]);
396 getServletHandler().setServletMappings(new ServletMapping[0]);
397 }
398
399 @Override
400 public Resource getResource(String uriInContext) throws MalformedURLException
401 {
402 Resource resource = null;
403
404 resource = super.getResource(uriInContext);
405
406
407 if ((resource == null || !resource.exists()) && uriInContext != null && _classes != null)
408 {
409 String uri = URIUtil.canonicalPath(uriInContext);
410 if (uri == null)
411 return null;
412
413 try
414 {
415
416 if (uri.startsWith(WEB_INF_CLASSES_PREFIX))
417 {
418 if (uri.equalsIgnoreCase(WEB_INF_CLASSES_PREFIX) || uri.equalsIgnoreCase(WEB_INF_CLASSES_PREFIX+"/"))
419 {
420
421
422 if (_classes != null)
423 return Resource.newResource(_classes);
424 else if (_testClasses != null)
425 return Resource.newResource(_testClasses);
426 }
427 else
428 {
429
430 Resource res = null;
431 int i=0;
432 while (res == null && (i < _webInfClasses.size()))
433 {
434 String newPath = uri.replace(WEB_INF_CLASSES_PREFIX, _webInfClasses.get(i).getPath());
435 res = Resource.newResource(newPath);
436 if (!res.exists())
437 {
438 res = null;
439 i++;
440 }
441 }
442 return res;
443 }
444 }
445 else if (uri.startsWith(WEB_INF_LIB_PREFIX))
446 {
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526