View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.war;
20  
21  import java.io.File;
22  import java.io.FileFilter;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.LinkedList;
26  import java.util.List;
27  
28  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
29  import org.apache.maven.plugins.war.overlay.DefaultOverlay;
30  import org.codehaus.plexus.util.FileUtils;
31  
32  /**
33   * @author Stephane Nicoll
34   */
35  public class WarOverlaysTest extends AbstractWarExplodedMojoTest {
36  
37      private static File pomFile = new File(getBasedir(), "target/test-classes/unit/waroverlays/default.xml");
38  
39      public void setUp() throws Exception {
40          super.setUp();
41          generateFullOverlayWar("overlay-full-1");
42          generateFullOverlayWar("overlay-full-2");
43          generateFullOverlayWar("overlay-full-3");
44      }
45  
46      protected File getPomFile() {
47          return pomFile;
48      }
49  
50      protected File getTestDirectory() {
51          return new File(getBasedir(), "target/test-classes/unit/waroverlays");
52      }
53  
54      public void testEnvironment() throws Exception {
55          // see setup
56      }
57  
58      public void testNoOverlay() throws Exception {
59          // setup test data
60          final String testId = "no-overlay";
61          final File xmlSource = createXMLConfigDir(testId, new String[] {"web.xml"});
62  
63          final File webAppDirectory = setUpMojo(testId, null);
64          try {
65              mojo.setWebXml(new File(xmlSource, "web.xml"));
66              mojo.execute();
67  
68              // Validate content of the webapp
69              assertDefaultContent(webAppDirectory);
70              assertWebXml(webAppDirectory);
71          } finally {
72              cleanDirectory(webAppDirectory);
73          }
74      }
75  
76      public void testDefaultOverlay() throws Exception {
77          // setup test data
78          final String testId = "default-overlay";
79  
80          // Add an overlay
81          final ArtifactStub overlay = buildWarOverlayStub("overlay-one");
82  
83          final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay});
84          final List<File> assertedFiles = new ArrayList<>();
85          try {
86              mojo.execute();
87              assertedFiles.addAll(assertDefaultContent(webAppDirectory));
88              assertedFiles.addAll(assertWebXml(webAppDirectory));
89              assertedFiles.addAll(assertCustomContent(
90                      webAppDirectory, new String[] {"index.jsp", "login.jsp"}, "overlay file not found"));
91  
92              // index and login come from overlay1
93              assertOverlayedFile(webAppDirectory, "overlay-one", "index.jsp");
94              assertOverlayedFile(webAppDirectory, "overlay-one", "login.jsp");
95  
96              // Ok now check that there is no more files/directories
97              final FileFilter filter = new FileFilterImpl(webAppDirectory, new String[] {MANIFEST_PATH});
98              assertWebAppContent(webAppDirectory, assertedFiles, filter);
99          } finally {
100             cleanDirectory(webAppDirectory);
101         }
102     }
103 
104     public void testDefaultOverlays() throws Exception {
105         // setup test data
106         final String testId = "default-overlays";
107 
108         // Add an overlay
109         final ArtifactStub overlay = buildWarOverlayStub("overlay-one");
110         final ArtifactStub overlay2 = buildWarOverlayStub("overlay-two");
111 
112         final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay, overlay2});
113         final List<File> assertedFiles = new ArrayList<>();
114         try {
115             mojo.execute();
116             assertedFiles.addAll(assertDefaultContent(webAppDirectory));
117             assertedFiles.addAll(assertWebXml(webAppDirectory));
118             assertedFiles.addAll(assertCustomContent(
119                     webAppDirectory, new String[] {"index.jsp", "login.jsp", "admin.jsp"}, "overlay file not found"));
120 
121             // index and login come from overlay1
122             assertOverlayedFile(webAppDirectory, "overlay-one", "index.jsp");
123             assertOverlayedFile(webAppDirectory, "overlay-one", "login.jsp");
124 
125             // admin comes from overlay2
126             // index and login comes from overlay1
127             assertOverlayedFile(webAppDirectory, "overlay-two", "admin.jsp");
128 
129             // Ok now check that there is no more files/directories
130             final FileFilter filter = new FileFilterImpl(webAppDirectory, new String[] {MANIFEST_PATH});
131             assertWebAppContent(webAppDirectory, assertedFiles, filter);
132         } finally {
133             cleanDirectory(webAppDirectory);
134         }
135     }
136 
137     /**
138      * Merge a dependent WAR when a file in the war source directory overrides one found in the WAR.
139      *
140      * It also tests completeness of the resulting war as well as the proper order of dependencies.
141      *
142      * @throws Exception if any error occurs
143      */
144     public void testScenarioOneWithDefaulSettings() throws Exception {
145         // setup test data
146         final String testId = "scenario-one-default-settings";
147 
148         // Add an overlay
149         final ArtifactStub overlay1 = buildWarOverlayStub("overlay-full-1");
150         final ArtifactStub overlay2 = buildWarOverlayStub("overlay-full-2");
151         final ArtifactStub overlay3 = buildWarOverlayStub("overlay-full-3");
152 
153         final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay1, overlay2, overlay3}, new String[] {
154             "org/sample/company/test.jsp", "jsp/b.jsp"
155         });
156 
157         assertScenariOne(testId, webAppDirectory);
158     }
159 
160     /**
161      * Tests that specifying the overlay explicitely has the same behavior as the default (i.e. order, etc).
162      *
163      * The default project is not specified in this case so it is processed first by default
164      *
165      * @throws Exception if an error occurs
166      */
167     public void testScenarioOneWithOverlaySettings() throws Exception {
168         // setup test data
169         final String testId = "scenario-one-overlay-settings";
170 
171         // Add an overlay
172         final ArtifactStub overlay1 = buildWarOverlayStub("overlay-full-1");
173         final ArtifactStub overlay2 = buildWarOverlayStub("overlay-full-2");
174         final ArtifactStub overlay3 = buildWarOverlayStub("overlay-full-3");
175 
176         final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay1, overlay2, overlay3}, new String[] {
177             "org/sample/company/test.jsp", "jsp/b.jsp"
178         });
179 
180         // Add the tags
181         final List<Overlay> overlays = new ArrayList<>();
182         overlays.add(new DefaultOverlay(overlay1));
183         overlays.add(new DefaultOverlay(overlay2));
184         overlays.add(new DefaultOverlay(overlay3));
185         mojo.setOverlays(overlays);
186 
187         // current project ignored. Should be on top of the list
188         assertScenariOne(testId, webAppDirectory);
189     }
190 
191     /**
192      * Tests that specifying the overlay explicitely has the same behavior as the default (i.e. order, etc).
193      *
194      * The default project is explicitely specified so this should match the default.
195      *
196      * @throws Exception if an error occurs
197      */
198     public void testScenarioOneWithFullSettings() throws Exception {
199         // setup test data
200         final String testId = "scenario-one-full-settings";
201 
202         // Add an overlay
203         final ArtifactStub overlay1 = buildWarOverlayStub("overlay-full-1");
204         final ArtifactStub overlay2 = buildWarOverlayStub("overlay-full-2");
205         final ArtifactStub overlay3 = buildWarOverlayStub("overlay-full-3");
206 
207         final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay1, overlay2, overlay3}, new String[] {
208             "org/sample/company/test.jsp", "jsp/b.jsp"
209         });
210 
211         // Add the tags
212         final List<Overlay> overlays = new ArrayList<>();
213 
214         // Add the default project explicitely
215         overlays.add(mojo.getCurrentProjectOverlay());
216 
217         // Other overlays
218         overlays.add(new DefaultOverlay(overlay1));
219         overlays.add(new DefaultOverlay(overlay2));
220         overlays.add(new DefaultOverlay(overlay3));
221         mojo.setOverlays(overlays);
222 
223         // current project ignored. Should be on top of the list
224         assertScenariOne(testId, webAppDirectory);
225     }
226 
227     /**
228      * Runs the mojo and asserts a scenerio with 3 overlays and no includes/excludes settings.
229      *
230      * @param testId thie id of the test
231      * @param webAppDirectory the webapp directory
232      * @throws Exception if an exception occurs
233      */
234     private void assertScenariOne(String testId, File webAppDirectory) throws Exception {
235         final List<File> assertedFiles = new ArrayList<>();
236         try {
237             mojo.execute();
238             assertedFiles.addAll(assertWebXml(webAppDirectory));
239             assertedFiles.addAll(assertCustomContent(
240                     webAppDirectory,
241                     new String[] {
242                         "jsp/a.jsp",
243                         "jsp/b.jsp",
244                         "jsp/c.jsp",
245                         "jsp/d/a.jsp",
246                         "jsp/d/b.jsp",
247                         "jsp/d/c.jsp",
248                         "org/sample/company/test.jsp",
249                         "WEB-INF/classes/a.clazz",
250                         "WEB-INF/classes/b.clazz",
251                         "WEB-INF/classes/c.clazz",
252                         "WEB-INF/lib/a.jar",
253                         "WEB-INF/lib/b.jar",
254                         "WEB-INF/lib/c.jar"
255                     },
256                     "overlay file not found"));
257 
258             // Those files should come from the source webapp without any config
259             assertDefaultFileContent(testId, webAppDirectory, "jsp/b.jsp");
260             assertDefaultFileContent(testId, webAppDirectory, "org/sample/company/test.jsp");
261 
262             // Everything else comes from overlay1 (order of addition in the dependencies)
263             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/a.jsp");
264             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/c.jsp");
265             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/d/a.jsp");
266             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/d/b.jsp");
267             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/d/c.jsp");
268             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/web.xml");
269             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/classes/a.clazz");
270             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/classes/b.clazz");
271             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/classes/c.clazz");
272             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/lib/a.jar");
273             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/lib/b.jar");
274             assertOverlayedFile(webAppDirectory, "overlay-full-1", "WEB-INF/lib/c.jar");
275 
276             // Ok now check that there is no more files/directories
277             final FileFilter filter = new FileFilterImpl(webAppDirectory, new String[] {MANIFEST_PATH});
278             assertWebAppContent(webAppDirectory, assertedFiles, filter);
279         } finally {
280             cleanDirectory(webAppDirectory);
281         }
282     }
283 
284     public void testOverlaysIncludesExcludesWithMultipleDefinitions() throws Exception {
285         // setup test data
286         final String testId = "overlays-includes-excludes-multiple-defs";
287 
288         // Add an overlay
289         final ArtifactStub overlay1 = buildWarOverlayStub("overlay-full-1");
290         final ArtifactStub overlay2 = buildWarOverlayStub("overlay-full-2");
291         final ArtifactStub overlay3 = buildWarOverlayStub("overlay-full-3");
292 
293         final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay1, overlay2, overlay3}, new String[] {
294             "org/sample/company/test.jsp", "jsp/b.jsp"
295         });
296 
297         Overlay over1 = new DefaultOverlay(overlay3);
298         over1.setExcludes("**/a.*,**/c.*,**/*.xml");
299 
300         Overlay over2 = new DefaultOverlay(overlay1);
301         over2.setIncludes("jsp/d/*");
302         over2.setExcludes("jsp/d/a.jsp");
303 
304         Overlay over3 = new DefaultOverlay(overlay3);
305         over3.setIncludes("**/*.jsp");
306 
307         Overlay over4 = new DefaultOverlay(overlay2);
308 
309         mojo.setOverlays(new LinkedList<>());
310         mojo.addOverlay(over1);
311         mojo.addOverlay(over2);
312         mojo.addOverlay(over3);
313         mojo.addOverlay(mojo.getCurrentProjectOverlay());
314         mojo.addOverlay(over4);
315 
316         final List<File> assertedFiles = new ArrayList<>();
317         try {
318             mojo.execute();
319             assertedFiles.addAll(assertWebXml(webAppDirectory));
320             assertedFiles.addAll(assertCustomContent(
321                     webAppDirectory,
322                     new String[] {
323                         "jsp/a.jsp",
324                         "jsp/b.jsp",
325                         "jsp/c.jsp",
326                         "jsp/d/a.jsp",
327                         "jsp/d/b.jsp",
328                         "jsp/d/c.jsp",
329                         "org/sample/company/test.jsp",
330                         "WEB-INF/classes/a.clazz",
331                         "WEB-INF/classes/b.clazz",
332                         "WEB-INF/classes/c.clazz",
333                         "WEB-INF/lib/a.jar",
334                         "WEB-INF/lib/b.jar",
335                         "WEB-INF/lib/c.jar"
336                     },
337                     "overlay file not found"));
338 
339             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/a.jsp");
340             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/b.jsp");
341             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/c.jsp");
342             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/d/a.jsp");
343             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/d/b.jsp");
344             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/d/c.jsp");
345             assertDefaultFileContent(testId, webAppDirectory, "org/sample/company/test.jsp");
346             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/web.xml");
347             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/classes/a.clazz");
348             assertOverlayedFile(webAppDirectory, "overlay-full-3", "WEB-INF/classes/b.clazz");
349             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/classes/c.clazz");
350             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/lib/a.jar");
351             assertOverlayedFile(webAppDirectory, "overlay-full-3", "WEB-INF/lib/b.jar");
352             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/lib/c.jar");
353 
354             // Ok now check that there is no more files/directories
355             final FileFilter filter = new FileFilterImpl(webAppDirectory, new String[] {MANIFEST_PATH});
356             assertWebAppContent(webAppDirectory, assertedFiles, filter);
357         } finally {
358             cleanDirectory(webAppDirectory);
359         }
360     }
361 
362     public void testOverlaysIncludesExcludesWithMultipleDefinitions2() throws Exception {
363         // setup test data
364         final String testId = "overlays-includes-excludes-multiple-defs2";
365 
366         // Add an overlay
367         final ArtifactStub overlay1 = buildWarOverlayStub("overlay-full-1");
368         final ArtifactStub overlay2 = buildWarOverlayStub("overlay-full-2");
369         final ArtifactStub overlay3 = buildWarOverlayStub("overlay-full-3");
370 
371         final File webAppDirectory = setUpMojo(testId, new ArtifactStub[] {overlay1, overlay2, overlay3}, new String[] {
372             "org/sample/company/test.jsp", "jsp/b.jsp"
373         });
374 
375         Overlay over1 = new DefaultOverlay(overlay3);
376         over1.setExcludes("**/a.*,**/c.*,**/*.xml,jsp/b.jsp");
377 
378         Overlay over2 = new DefaultOverlay(overlay1);
379         over2.setIncludes("jsp/d/*");
380         over2.setExcludes("jsp/d/a.jsp");
381 
382         Overlay over3 = new DefaultOverlay(overlay3);
383         over3.setIncludes("**/*.jsp");
384         over3.setExcludes("jsp/b.jsp");
385 
386         Overlay over4 = new DefaultOverlay(overlay2);
387 
388         mojo.setOverlays(new LinkedList<>());
389         mojo.addOverlay(over1);
390         mojo.addOverlay(over2);
391         mojo.addOverlay(over3);
392         mojo.addOverlay(mojo.getCurrentProjectOverlay());
393         mojo.addOverlay(over4);
394 
395         final List<File> assertedFiles = new ArrayList<>();
396         try {
397             mojo.execute();
398             assertedFiles.addAll(assertWebXml(webAppDirectory));
399             assertedFiles.addAll(assertCustomContent(
400                     webAppDirectory,
401                     new String[] {
402                         "jsp/a.jsp",
403                         "jsp/b.jsp",
404                         "jsp/c.jsp",
405                         "jsp/d/a.jsp",
406                         "jsp/d/b.jsp",
407                         "jsp/d/c.jsp",
408                         "org/sample/company/test.jsp",
409                         "WEB-INF/classes/a.clazz",
410                         "WEB-INF/classes/b.clazz",
411                         "WEB-INF/classes/c.clazz",
412                         "WEB-INF/lib/a.jar",
413                         "WEB-INF/lib/b.jar",
414                         "WEB-INF/lib/c.jar"
415                     },
416                     "overlay file not found"));
417 
418             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/a.jsp");
419             assertDefaultFileContent(testId, webAppDirectory, "jsp/b.jsp");
420             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/c.jsp");
421             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/d/a.jsp");
422             assertOverlayedFile(webAppDirectory, "overlay-full-3", "jsp/d/b.jsp");
423             assertOverlayedFile(webAppDirectory, "overlay-full-1", "jsp/d/c.jsp");
424             assertDefaultFileContent(testId, webAppDirectory, "org/sample/company/test.jsp");
425             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/web.xml");
426             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/classes/a.clazz");
427             assertOverlayedFile(webAppDirectory, "overlay-full-3", "WEB-INF/classes/b.clazz");
428             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/classes/c.clazz");
429             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/lib/a.jar");
430             assertOverlayedFile(webAppDirectory, "overlay-full-3", "WEB-INF/lib/b.jar");
431             assertOverlayedFile(webAppDirectory, "overlay-full-2", "WEB-INF/lib/c.jar");
432 
433             // Ok now check that there is no more files/directories
434             final FileFilter filter = new FileFilterImpl(webAppDirectory, new String[] {MANIFEST_PATH});
435             assertWebAppContent(webAppDirectory, assertedFiles, filter);
436         } finally {
437             cleanDirectory(webAppDirectory);
438         }
439     }
440 
441     // Helpers
442 
443     /**
444      * Asserts that the content of an overlayed file is correct.
445      *
446      * Note that the {@code filePath} is relative to both the webapp directory and the overlayed directory, defined by
447      * the {@code overlayId}.
448      *
449      * @param webAppDirectory the webapp directory
450      * @param overlayId the id of the overlay
451      * @param filePath the relative path
452      * @throws IOException if an error occurred while reading the files
453      */
454     protected void assertOverlayedFile(File webAppDirectory, String overlayId, String filePath) throws IOException {
455         final File webAppFile = new File(webAppDirectory, filePath);
456         final File overlayFile = getOverlayFile(overlayId, filePath);
457         assertEquals(
458                 "Wrong content for overlayed file " + filePath,
459                 FileUtils.fileRead(overlayFile),
460                 FileUtils.fileRead(webAppFile));
461     }
462 
463     /**
464      * Asserts that the content of an overlayed file is correct.
465      *
466      * Note that the {@code filePath} is relative to both the webapp directory and the overlayed directory, defined by
467      * the {@code overlayId}.
468      *
469      * @param testId te id of the test
470      * @param webAppDirectory the webapp directory
471      * @param filePath the relative path
472      * @throws IOException if an error occurred while reading the files
473      */
474     protected void assertDefaultFileContent(String testId, File webAppDirectory, String filePath) throws Exception {
475         final File webAppFile = new File(webAppDirectory, filePath);
476         final File sourceFile = new File(getWebAppSource(testId), filePath);
477         final String expectedContent = sourceFile.toString();
478         assertEquals("Wrong content for file " + filePath, expectedContent, FileUtils.fileRead(webAppFile));
479     }
480 
481     protected ArtifactStub generateSimpleWarArtifactStub(String id) throws Exception {
482         return buildWarOverlayStub(id);
483     }
484 }