1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.eclipse.jetty.ant;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.net.URL;
25 import java.net.URLClassLoader;
26 import java.util.ArrayList;
27 import java.util.Iterator;
28 import java.util.List;
29
30 import javax.servlet.Servlet;
31
32 import org.apache.tools.ant.AntClassLoader;
33 import org.apache.tools.ant.BuildException;
34 import org.apache.tools.ant.Project;
35 import org.apache.tools.ant.types.FileSet;
36 import org.eclipse.jetty.annotations.AnnotationConfiguration;
37 import org.eclipse.jetty.ant.types.Attribute;
38 import org.eclipse.jetty.ant.types.Attributes;
39 import org.eclipse.jetty.ant.types.FileMatchingConfiguration;
40 import org.eclipse.jetty.ant.utils.TaskLog;
41 import org.eclipse.jetty.plus.webapp.EnvConfiguration;
42 import org.eclipse.jetty.plus.webapp.PlusConfiguration;
43 import org.eclipse.jetty.server.handler.ContextHandler;
44 import org.eclipse.jetty.servlet.Holder;
45 import org.eclipse.jetty.servlet.ServletHandler;
46 import org.eclipse.jetty.servlet.ServletHolder;
47 import org.eclipse.jetty.util.resource.Resource;
48 import org.eclipse.jetty.webapp.Configuration;
49 import org.eclipse.jetty.webapp.FragmentConfiguration;
50 import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
51 import org.eclipse.jetty.webapp.MetaInfConfiguration;
52 import org.eclipse.jetty.webapp.WebAppClassLoader;
53 import org.eclipse.jetty.webapp.WebAppContext;
54 import org.eclipse.jetty.webapp.WebInfConfiguration;
55 import org.eclipse.jetty.webapp.WebXmlConfiguration;
56 import org.eclipse.jetty.xml.XmlConfiguration;
57
58
59
60
61
62
63
64
65
66 public class AntWebAppContext extends WebAppContext
67 {
68 public final AntWebInfConfiguration antWebInfConfiguration = new AntWebInfConfiguration();
69 public final WebXmlConfiguration webXmlConfiguration = new WebXmlConfiguration();
70 public final MetaInfConfiguration metaInfConfiguration = new MetaInfConfiguration();
71 public final FragmentConfiguration fragmentConfiguration = new FragmentConfiguration();
72 public final EnvConfiguration envConfiguration = new EnvConfiguration();
73 public final PlusConfiguration plusConfiguration = new PlusConfiguration();
74 public final AnnotationConfiguration annotationConfiguration = new AnnotationConfiguration();
75 public final JettyWebXmlConfiguration jettyWebXmlConfiguration = new JettyWebXmlConfiguration();
76
77
78 public final Configuration[] DEFAULT_CONFIGURATIONS =
79 {
80 antWebInfConfiguration,
81 webXmlConfiguration,
82 metaInfConfiguration,
83 fragmentConfiguration,
84 envConfiguration,
85 plusConfiguration,
86 annotationConfiguration,
87 jettyWebXmlConfiguration
88 };
89
90
91 public final static String DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN =
92 ".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$|.*/.*jstl[^/]*\\.jar$|.*/.*jsf-impl-[^/]*\\.jar$|.*/.*javax.faces-[^/]*\\.jar$|.*/.*myfaces-impl-[^/]*\\.jar$";
93
94
95
96 private File jettyEnvXml;
97
98
99 private List libraries = new ArrayList();
100
101
102 private List classes = new ArrayList();
103
104
105 private File contextXml;
106
107
108 private FileSet scanTargets;
109
110
111 private Attributes attributes;
112
113 private Project project;
114
115 private List<File> scanFiles;
116
117
118
119
120 private FileMatchingConfiguration extraScanTargetsConfiguration;
121
122
123 private FileMatchingConfiguration librariesConfiguration;
124
125
126 public static void dump(ClassLoader loader)
127 {
128 while (loader != null)
129 {
130 System.err.println(loader);
131 if (loader instanceof URLClassLoader)
132 {
133 URL[] urls = ((URLClassLoader)loader).getURLs();
134 if (urls != null)
135 {
136 for (URL u:urls)
137 System.err.println("\t"+u+"\n");
138 }
139 }
140 loader = loader.getParent();
141 }
142 }
143
144
145
146
147
148
149
150
151 public static class AntServletHolder extends ServletHolder
152 {
153
154 public AntServletHolder()
155 {
156 super();
157 }
158
159
160 public AntServletHolder(Class<? extends Servlet> servlet)
161 {
162 super(servlet);
163 }
164
165
166 public AntServletHolder(Servlet servlet)
167 {
168 super(servlet);
169 }
170
171
172 public AntServletHolder(String name, Class<? extends Servlet> servlet)
173 {
174 super(name, servlet);
175 }
176
177
178 public AntServletHolder(String name, Servlet servlet)
179 {
180 super(name, servlet);
181 }
182
183
184 @Override
185 protected void initJspServlet() throws Exception
186 {
187
188
189 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
190
191
192 ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
193
194
195 String sysClassPath = getSystemClassPath(ch.getClassLoader().getParent());
196 setInitParameter("com.sun.appserv.jsp.classpath", sysClassPath);
197
198
199 if ("?".equals(getInitParameter("classpath")))
200 {
201 String classpath = ch.getClassPath();
202 if (classpath != null)
203 setInitParameter("classpath", classpath);
204 }
205 }
206
207
208 protected String getSystemClassPath (ClassLoader loader) throws Exception
209 {
210 StringBuilder classpath=new StringBuilder();
211 while (loader != null)
212 {
213 if (loader instanceof URLClassLoader)
214 {
215 URL[] urls = ((URLClassLoader)loader).getURLs();
216 if (urls != null)
217 {
218 for (int i=0;i<urls.length;i++)
219 {
220 Resource resource = Resource.newResource(urls[i]);
221 File file=resource.getFile();
222 if (file!=null && file.exists())
223 {
224 if (classpath.length()>0)
225 classpath.append(File.pathSeparatorChar);
226 classpath.append(file.getAbsolutePath());
227 }
228 }
229 }
230 }
231 else if (loader instanceof AntClassLoader)
232 {
233 classpath.append(((AntClassLoader)loader).getClasspath());
234 }
235
236 loader = loader.getParent();
237 }
238
239 return classpath.toString();
240 }
241
242 }
243
244
245
246
247
248
249
250
251 public static class AntServletHandler extends ServletHandler
252 {
253
254 @Override
255 public ServletHolder newServletHolder(Holder.Source source)
256 {
257 return new AntServletHolder();
258 }
259
260 }
261
262
263
264
265
266
267
268
269 public AntWebAppContext(Project project) throws Exception
270 {
271 super();
272 this.project = project;
273 setConfigurations(DEFAULT_CONFIGURATIONS);
274 setAttribute(WebInfConfiguration.CONTAINER_JAR_PATTERN, DEFAULT_CONTAINER_INCLUDE_JAR_PATTERN);
275 setParentLoaderPriority(true);
276 }
277
278
279
280
281
282 public void addAttributes(Attributes atts)
283 {
284 if (this.attributes != null)
285 {
286 throw new BuildException("Only one <attributes> tag is allowed!");
287 }
288
289 this.attributes = atts;
290 }
291
292
293 public void addLib(FileSet lib)
294 {
295 libraries.add(lib);
296 }
297
298
299 public void addClasses(FileSet classes)
300 {
301 this.classes.add(classes);
302 }
303
304
305
306 @Override
307 protected ServletHandler newServletHandler()
308 {
309 return new AntServletHandler();
310 }
311
312
313 public void setJettyEnvXml(File jettyEnvXml)
314 {
315 this.jettyEnvXml = jettyEnvXml;
316 TaskLog.log("jetty-env.xml file: = " + (jettyEnvXml == null ? null : jettyEnvXml.getAbsolutePath()));
317 }
318
319 public File getJettyEnvXml ()
320 {
321 return this.jettyEnvXml;
322 }
323
324
325
326
327 public List getLibraries()
328 {
329 return librariesConfiguration.getBaseDirectories();
330 }
331
332
333 public void addScanTargets(FileSet scanTargets)
334 {
335 if (this.scanTargets != null)
336 {
337 throw new BuildException("Only one <scanTargets> tag is allowed!");
338 }
339
340 this.scanTargets = scanTargets;
341 }
342
343 public List getScanTargetFiles ()
344 {
345 if (this.scanTargets == null)
346 return null;
347
348
349 FileMatchingConfiguration configuration = new FileMatchingConfiguration();
350 configuration.addDirectoryScanner(scanTargets.getDirectoryScanner(project));
351 return configuration.getBaseDirectories();
352 }
353
354 public List<File> getScanFiles()
355 {
356 if (scanFiles == null)
357 scanFiles = initScanFiles();
358 return scanFiles;
359 }
360
361
362 public boolean isScanned (File file)
363 {
364 List<File> files = getScanFiles();
365 if (files == null || files.isEmpty())
366 return false;
367 return files.contains(file);
368 }
369
370
371 public List<File> initScanFiles ()
372 {
373 List<File> scanList = new ArrayList<File>();
374
375 if (getDescriptor() != null)
376 {
377 try
378 {
379 Resource r = Resource.newResource(getDescriptor());
380 scanList.add(r.getFile());
381 }
382 catch (IOException e)
383 {
384 throw new BuildException(e);
385 }
386 }
387
388 if (getJettyEnvXml() != null)
389 {
390 try
391 {
392 Resource r = Resource.newResource(getJettyEnvXml());
393 scanList.add(r.getFile());
394 }
395 catch (IOException e)
396 {
397 throw new BuildException("Problem configuring scanner for jetty-env.xml", e);
398 }
399 }
400
401 if (getDefaultsDescriptor() != null)
402 {
403 try
404 {
405 if (!AntWebAppContext.WEB_DEFAULTS_XML.equals(getDefaultsDescriptor()))
406 {
407 Resource r = Resource.newResource(getDefaultsDescriptor());
408 scanList.add(r.getFile());
409 }
410 }
411 catch (IOException e)
412 {
413 throw new BuildException("Problem configuring scanner for webdefaults.xml", e);
414 }
415 }
416
417 if (getOverrideDescriptor() != null)
418 {
419 try
420 {
421 Resource r = Resource.newResource(getOverrideDescriptor());
422 scanList.add(r.getFile());
423 }
424 catch (IOException e)
425 {
426 throw new BuildException("Problem configuring scanner for webdefaults.xml", e);
427 }
428 }
429
430
431 List<File> cpFiles = getClassPathFiles();
432 if (cpFiles != null)
433 scanList.addAll(cpFiles);
434
435
436 @SuppressWarnings("unchecked")
437 List<File> scanFiles = (List<File>)getScanTargetFiles();
438 if (scanFiles != null)
439 scanList.addAll(scanFiles);
440
441 return scanList;
442 }
443
444
445
446 @Override
447 public void setWar(String path)
448 {
449 super.setWar(path);
450
451 try
452 {
453 Resource war = Resource.newResource(path);
454 if (war.exists() && war.isDirectory() && getDescriptor() == null)
455 {
456 Resource webXml = war.addPath("WEB-INF/web.xml");
457 setDescriptor(webXml.toString());
458 }
459 }
460 catch (IOException e)
461 {
462 throw new BuildException(e);
463 }
464 }
465
466
467
468
469
470 public void doStart()
471 {
472 try
473 {
474 TaskLog.logWithTimestamp("Starting web application "+this.getDescriptor());
475 if (jettyEnvXml != null && jettyEnvXml.exists())
476 envConfiguration.setJettyEnvXml(Resource.toURL(jettyEnvXml));
477 setClassLoader(new WebAppClassLoader(this.getClass().getClassLoader(), this));
478 if (attributes != null && attributes.getAttributes() != null)
479 {
480 for (Attribute a:attributes.getAttributes())
481 setAttribute(a.getName(), a.getValue());
482 }
483
484
485 if (contextXml != null)
486 {
487 XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(contextXml));
488 TaskLog.log("Applying context xml file "+contextXml);
489 xmlConfiguration.configure(this);
490 }
491
492 super.doStart();
493 }
494 catch (Exception e)
495 {
496 TaskLog.log(e.toString());
497 }
498 }
499
500
501
502
503 public void doStop()
504 {
505 try
506 {
507 scanFiles = null;
508 TaskLog.logWithTimestamp("Stopping web application "+this);
509 Thread.currentThread().sleep(500L);
510 super.doStop();
511 }
512 catch (InterruptedException e)
513 {
514 TaskLog.log(e.toString());
515 }
516 catch (Exception e)
517 {
518 TaskLog.log(e.toString());
519 }
520 }
521
522
523
524
525
526
527 public List<File> getClassPathFiles()
528 {
529 List<File> classPathFiles = new ArrayList<File>();
530 Iterator classesIterator = classes.iterator();
531 while (classesIterator.hasNext())
532 {
533 FileSet clazz = (FileSet) classesIterator.next();
534 classPathFiles.add(clazz.getDirectoryScanner(project).getBasedir());
535 }
536
537 Iterator iterator = libraries.iterator();
538 while (iterator.hasNext())
539 {
540 FileSet library = (FileSet) iterator.next();
541 String[] includedFiles = library.getDirectoryScanner(project).getIncludedFiles();
542 File baseDir = library.getDirectoryScanner(project).getBasedir();
543
544 for (int i = 0; i < includedFiles.length; i++)
545 {
546 classPathFiles.add(new File(baseDir, includedFiles[i]));
547 }
548 }
549
550
551 return classPathFiles;
552 }
553
554
555
556
557
558
559
560 public FileMatchingConfiguration getLibrariesConfiguration()
561 {
562 FileMatchingConfiguration config = new FileMatchingConfiguration();
563
564 Iterator classesIterator = classes.iterator();
565 while (classesIterator.hasNext())
566 {
567 FileSet clazz = (FileSet) classesIterator.next();
568 config.addDirectoryScanner(clazz.getDirectoryScanner(project));
569 }
570
571 Iterator librariesIterator = libraries.iterator();
572 while (librariesIterator.hasNext())
573 {
574 FileSet library = (FileSet) librariesIterator.next();
575 config.addDirectoryScanner(library.getDirectoryScanner(project));
576 }
577
578 return config;
579 }
580
581
582 public File getContextXml()
583 {
584 return contextXml;
585 }
586
587
588 public void setContextXml(File contextXml)
589 {
590 this.contextXml = contextXml;
591 }
592
593 }