2011/08/05 - Jakarta Cactus has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.cactus.maven2.mojos;
22
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.text.DecimalFormat;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Random;
31
32 import org.apache.cactus.integration.api.cactify.CactifyUtils;
33 import org.apache.cactus.integration.api.version.Version;
34 import org.apache.maven.archiver.MavenArchiveConfiguration;
35 import org.apache.maven.archiver.MavenArchiver;
36 import org.apache.maven.artifact.DependencyResolutionRequiredException;
37 import org.apache.maven.artifact.factory.ArtifactFactory;
38 import org.apache.maven.artifact.installer.ArtifactInstaller;
39 import org.apache.maven.artifact.repository.ArtifactRepository;
40 import org.apache.maven.plugin.AbstractMojo;
41 import org.apache.maven.plugin.MojoExecutionException;
42 import org.apache.maven.plugin.MojoFailureException;
43 import org.apache.maven.plugin.assembly.archive.ArchiveExpansionException;
44 import org.apache.maven.plugin.assembly.utils.AssemblyFileUtils;
45 import org.apache.maven.project.MavenProject;
46 import org.apache.maven.shared.model.fileset.FileSet;
47 import org.apache.tools.ant.types.XMLCatalog;
48 import org.codehaus.cargo.container.internal.util.ResourceUtils;
49 import org.codehaus.cargo.maven2.log.MavenLogger;
50 import org.codehaus.cargo.module.webapp.DefaultWarArchive;
51 import org.codehaus.cargo.module.webapp.EjbRef;
52 import org.codehaus.cargo.module.webapp.WarArchive;
53 import org.codehaus.cargo.module.webapp.WebXml;
54 import org.codehaus.cargo.module.webapp.WebXmlIo;
55 import org.codehaus.cargo.module.webapp.WebXmlUtils;
56 import org.codehaus.cargo.module.webapp.WebXmlVersion;
57 import org.codehaus.cargo.module.webapp.merge.WebXmlMerger;
58 import org.codehaus.cargo.util.log.Logger;
59 import org.codehaus.plexus.archiver.ArchiverException;
60 import org.codehaus.plexus.archiver.jar.ManifestException;
61 import org.codehaus.plexus.archiver.manager.ArchiverManager;
62 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
63 import org.codehaus.plexus.archiver.war.WarArchiver;
64 import org.codehaus.plexus.util.FileUtils;
65 import org.jdom.JDOMException;
66
67
68
69
70
71
72
73
74
75 public class CactifyWarMojo extends AbstractMojo
76 {
77
78
79
80 private String FILE_NAME = "cactus.war";
81
82
83
84
85
86 private String context;
87
88
89
90
91 private static Random rand = new Random(System.currentTimeMillis()
92 + Runtime.getRuntime().freeMemory());
93
94
95
96
97
98
99 private ArtifactFactory artifactFactory;
100
101
102
103
104 private XMLCatalog xmlCatalog = null;
105
106
107
108
109
110 private File srcFile;
111
112
113
114
115
116 private FileSet testClasses;
117
118
119
120
121
122
123
124 private WarArchiver warArchiver;
125
126
127
128
129
130
131
132
133 private MavenProject project;
134
135
136
137
138
139
140 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
141
142
143
144
145
146
147 private File mergeWebXml;
148
149
150
151
152
153 private final List redirectors = new ArrayList();
154
155
156
157
158
159 private final List ejbRefs = new ArrayList();
160
161
162
163
164 private ResourceUtils utils = new ResourceUtils();
165
166
167
168
169
170 private ArchiverManager archiverManager;
171
172
173
174
175
176 private final List libDependencies = new ArrayList();
177
178
179
180
181 private ArtifactFactory factory;
182
183
184
185
186
187
188 protected ArtifactInstaller installer;
189
190
191
192
193
194
195 private File destFile;
196
197
198
199
200
201
202
203 protected ArtifactRepository localRepository;
204
205
206
207
208
209
210
211 protected String groupId;
212
213
214
215
216
217
218
219 protected String artifactId;
220
221
222
223
224
225
226
227 protected String projectVersion;
228
229
230
231
232
233
234 protected String version = null;
235
236
237
238
239
240
241
242 protected String packaging;
243
244
245
246
247
248
249
250
251 protected String classifier;
252
253
254
255
256
257
258 public void execute() throws MojoExecutionException, MojoFailureException
259 {
260 if (this.srcFile != null)
261 {
262 getLog().info("Analyzing war: " + this.srcFile.getAbsolutePath());
263 }
264
265 WebXml webXml = null;
266 MavenArchiver archiver = new MavenArchiver();
267 archiver.setArchiver(warArchiver);
268 archiver.setOutputFile(destFile);
269
270 File tmpWebXml = null;
271 File tempLocation = null;
272
273 try
274 {
275 if (srcFile != null)
276 {
277 webXml = getOriginalWebXml();
278 if (webXml == null)
279 {
280 if (this.version == null)
281 {
282 throw new MojoExecutionException("Your source file "
283 + "does not contain a web.xml. Please provide a "
284 + "war with a web.xml or specify the [version] "
285 + "attribute.");
286 }
287 WebXmlVersion webXmlVersion = null;
288 if (this.version.equals("2.2"))
289 {
290 webXmlVersion = WebXmlVersion.V2_2;
291 }
292 else if (this.version.equals("2.3"))
293 {
294 webXmlVersion = WebXmlVersion.V2_3;
295 }
296 else
297 {
298 webXmlVersion = WebXmlVersion.V2_4;
299 }
300 webXml = WebXmlIo.newWebXml(webXmlVersion);
301 }
302 }
303 else
304 {
305
306 if (this.version == null)
307 {
308 throw new MojoExecutionException("You need to specify "
309 + "either the [srcFile] or the [version] attribute");
310 }
311 else
312 {
313 WebXmlVersion webXmlVersion = null;
314 if (this.version.equals("2.2"))
315 {
316 webXmlVersion = WebXmlVersion.V2_2;
317 }
318 else if (this.version.equals("2.3"))
319 {
320 webXmlVersion = WebXmlVersion.V2_3;
321 }
322 else
323 {
324 webXmlVersion = WebXmlVersion.V2_4;
325 }
326 webXml = WebXmlIo.newWebXml(webXmlVersion);
327 }
328 }
329 tmpWebXml = cactifyWebXml(webXml);
330
331
332 addJarWithClass("org.aspectj.lang.JoinPoint",
333 "AspectJ Runtime");
334 addJarWithClass("org.apache.cactus."
335 + "ServletTestCase", "Cactus Framework");
336 addJarWithClass("org.apache.commons.logging.Log",
337 "Commons-Logging");
338 addJarWithClass("org.apache.commons."
339 + "httpclient.HttpClient", "Commons-HttpClient");
340 addJarWithClass("junit.framework."
341 + "TestCase", "JUnit");
342
343 tempLocation = createTempFile("cactus", "explode.tmp.dir",
344 getProject().getBasedir(), true);
345 tempLocation.mkdirs();
346 tempLocation.deleteOnExit();
347
348 if (testClasses != null)
349 {
350
351 warArchiver.addClasses(new File(testClasses.getDirectory()),
352 testClasses.getIncludesArray(),
353 testClasses.getExcludesArray());
354 }
355
356
357 for (Iterator iter = libDependencies.iterator(); iter.hasNext();)
358 {
359 org.apache.cactus.maven2.mojos.Dependency dependency =
360 (org.apache.cactus.maven2.mojos.Dependency) iter.next();
361 warArchiver.addLib(new File(dependency.getDependencyPath(
362 project, getLog())));
363 }
364
365 try
366 {
367 if(this.srcFile != null)
368 {
369 AssemblyFileUtils.unpack(this.srcFile, tempLocation,
370 archiverManager);
371 }
372 }
373 catch (ArchiveExpansionException e)
374 {
375 throw new MojoExecutionException("Error extracting the"
376 + " archive.", e);
377 }
378 catch (NoSuchArchiverException e)
379 {
380 throw new MojoExecutionException("Problem reading the "
381 + "source archive.", e);
382 }
383 warArchiver.addDirectory(tempLocation);
384 warArchiver.setWebxml(tmpWebXml);
385 archiver.createArchive(getProject(), getArchive());
386 }
387 catch (ArchiverException e)
388 {
389 throw new MojoExecutionException("Problem reading the "
390 + "source archive.", e);
391 }
392 catch (JDOMException e)
393 {
394 throw new MojoExecutionException("Unable to cactify "
395 + "your web.xml.", e);
396 }
397 catch (ManifestException e)
398 {
399 throw new MojoExecutionException("Problem reading the "
400 + "source archive.", e);
401 }
402 catch (IOException e)
403 {
404 throw new MojoExecutionException("Input/output error reading the"
405 + "source archive.", e);
406 }
407 catch (DependencyResolutionRequiredException e)
408 {
409 throw new MojoExecutionException("Error resolving your "
410 + "dependencies", e);
411 }
412 finally
413 {
414 try
415 {
416 if (tempLocation != null)
417 {
418 FileUtils.deleteDirectory(tempLocation);
419 }
420 }
421 catch (IOException e)
422 {
423 throw new MojoExecutionException("Error deleting temporary "
424 + "folder", e);
425 }
426 }
427 }
428
429
430
431
432
433
434
435
436
437
438 private File cactifyWebXml(WebXml theWebXml) throws JDOMException,
439 MojoExecutionException
440 {
441 CactifyUtils utils = new CactifyUtils();
442 utils.setLogger(createLogger());
443 utils.addRedirectorDefinitions(theWebXml, redirectors);
444 addJspRedirector();
445 addEjbRefs(theWebXml);
446
447
448
449 if (this.mergeWebXml != null)
450 {
451 try
452 {
453 WebXml parsedMergeWebXml = WebXmlIo.parseWebXmlFromFile(
454 this.mergeWebXml, this.xmlCatalog);
455 WebXmlMerger merger = new WebXmlMerger(theWebXml);
456 merger.setLogger(utils.getLogger());
457
458 merger.merge(parsedMergeWebXml);
459 }
460 catch (IOException e)
461 {
462 throw new MojoExecutionException(
463 "Could not merge deployment descriptors", e);
464 }
465 }
466
467
468
469
470 File tmpDir = createTempFile("cactus", "tmp.dir",
471 new File("."), true);
472 tmpDir.mkdirs();
473 tmpDir.deleteOnExit();
474 File webXmlFile = null;
475 try
476 {
477 tmpDir.mkdir();
478 File[] files = WebXmlIo.writeAll(theWebXml,
479 tmpDir.getAbsolutePath());
480 List includes = new ArrayList();
481 for (int i = 0; i < files.length; i++)
482 {
483 File f = files[i];
484 f.deleteOnExit();
485 if (f.getName().equals("web.xml"))
486 {
487 webXmlFile = f;
488 }
489 else
490 {
491 includes.add(f.getName());
492 }
493 }
494 String[] strIncludes = new String[includes.size()];
495 int i = 0;
496 for (Iterator iter = includes.iterator(); iter.hasNext();)
497 {
498 strIncludes[i] = iter.next().toString();
499 i++;
500 }
501 try
502 {
503 warArchiver.addWebinf(tmpDir, strIncludes, null);
504 }
505 catch (ArchiverException e)
506 {
507 throw new MojoExecutionException(
508 "Error reading the source archive.", e);
509 }
510 }
511 catch (IOException ioe)
512 {
513 throw new MojoExecutionException(
514 "Could not write temporary deployment descriptor", ioe);
515 }
516 return webXmlFile;
517 }
518
519
520
521
522
523
524
525
526
527
528 public File createTempFile(String thePrefix, String theSuffix,
529 File theParentDir, boolean isDeleteOnExit)
530 {
531 File result = null;
532 String parent = (theParentDir == null)
533 ? System.getProperty("java.io.tmpdir")
534 : theParentDir.getPath();
535
536 DecimalFormat fmt = new DecimalFormat("#####");
537 synchronized (rand)
538 {
539 do
540 {
541 result = new File(parent,
542 thePrefix + fmt.format(Math.abs(rand.nextInt()))
543 + theSuffix);
544 }
545 while (result.exists());
546 }
547 if (isDeleteOnExit)
548 {
549 result.deleteOnExit();
550 }
551 return result;
552 }
553
554
555
556
557
558
559 private void addJspRedirector() throws MojoExecutionException
560 {
561
562 File jspRedirectorFile = new File(
563 new File(System.getProperty("java.io.tmpdir")),
564 "jspRedirector.jsp");
565 jspRedirectorFile.deleteOnExit();
566 try
567 {
568 utils.copyResource("/org/apache/cactus/server/jspRedirector.jsp",
569 jspRedirectorFile);
570 }
571 catch (IOException e)
572 {
573 getLog().warn("Could not copy the JSP redirector ("
574 + e.getMessage() + ")");
575 }
576 try
577 {
578 warArchiver.addFile(jspRedirectorFile, jspRedirectorFile.getName());
579 }
580 catch (ArchiverException e)
581 {
582 throw new MojoExecutionException("Failed to add jsp redirector", e);
583 }
584 }
585
586
587
588
589
590
591
592
593
594
595
596 private File addJarWithClass(String theClassName, String theDescription)
597 throws ArchiverException
598 {
599 String resourceName = "/" + theClassName.replace('.', '/') + ".class";
600 if (srcFile != null)
601 {
602 try
603 {
604 WarArchive srcWar = new DefaultWarArchive(
605 new FileInputStream(srcFile));
606 getLog().info("Inspecting..");
607 if (srcWar.containsClass(theClassName))
608 {
609 getLog().info("The " + theDescription + " JAR is "
610 + "already present in the WAR. Will skip.");
611 return null;
612 }
613 }
614 catch (IOException ioe)
615 {
616 getLog().warn("Problem reading source WAR to when "
617 + "trying to detect already present JAR files (" + ioe + ")");
618 }
619 }
620 File file = utils.getResourceLocation(resourceName);
621
622 if (file != null)
623 {
624 getLog().info("Adding: " + file.getName());
625 warArchiver.addLib(file);
626 }
627
628 return file;
629 }
630
631
632
633
634
635
636
637
638
639
640 private WebXml getOriginalWebXml() throws MojoExecutionException,
641 JDOMException
642 {
643
644 WarArchive war = null;
645 try
646 {
647 war = new DefaultWarArchive(new FileInputStream(this.srcFile));
648 WebXml webXml = war.getWebXml();
649 return webXml;
650 }
651 catch (IOException e)
652 {
653 throw new MojoExecutionException("Failed to get the original "
654 + "web.xml", e);
655 }
656 }
657
658
659
660
661
662
663 private void addEjbRefs(WebXml theWebXml)
664 {
665 Iterator i = ejbRefs.iterator();
666 while (i.hasNext())
667 {
668 EjbRef ref = (EjbRef) i.next();
669 WebXmlUtils.addEjbRef(theWebXml, ref);
670 }
671 }
672
673
674
675
676
677 public MavenProject getProject()
678 {
679 return project;
680 }
681
682
683
684
685
686 public void setProject(MavenProject theProject)
687 {
688 this.project = theProject;
689 }
690
691
692
693
694
695 public MavenArchiveConfiguration getArchive()
696 {
697 return archive;
698 }
699
700
701
702
703
704
705
706
707 protected Logger createLogger()
708 {
709 Logger logger;
710 logger = new MavenLogger(getLog());
711 return logger;
712 }
713
714
715
716
717
718
719 public String getContext()
720 {
721 return context;
722 }
723
724
725
726
727
728
729 public File getSrcFile()
730 {
731 return this.srcFile;
732 }
733
734
735
736
737
738
739
740 public void setContext(String theContext)
741 {
742 this.context = theContext;
743 }
744
745
746
747
748
749
750 public final void setVersion(Version theVersion)
751 {
752 this.version = theVersion.getValue();
753 }
754
755
756
757
758
759
760 public final void setSrcFile(File theSrcFile)
761 {
762 this.srcFile = theSrcFile;
763 }
764
765
766
767
768
769
770 public String getFileName()
771 {
772 return FILE_NAME;
773 }
774
775
776
777
778
779
780 public void setDestFile(File theDestFile)
781 {
782 this.destFile = theDestFile;
783 }
784
785
786
787
788
789
790 public final void addConfiguredEjbref(EjbRef theEjbRef)
791 {
792 ejbRefs.add(theEjbRef);
793 }
794
795
796
797
798
799
800
801 public void setWarArchiver(WarArchiver theWarArchiver)
802 {
803 this.warArchiver = theWarArchiver;
804 }
805 }