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.Arrays;
26  import java.util.Collections;
27  import java.util.List;
28  
29  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
30  import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
31  import org.codehaus.plexus.util.FileUtils;
32  
33  /**
34   * @author Stephane Nicoll
35   */
36  public abstract class AbstractWarExplodedMojoTest extends AbstractWarMojoTest {
37  
38      protected WarExplodedMojo mojo;
39  
40      public void setUp() throws Exception {
41          super.setUp();
42          mojo = (WarExplodedMojo) lookupMojo("exploded", getPomFile());
43      }
44  
45      /**
46       * Returns the pom configuration to use.
47       *
48       * @return the pom configuration
49       */
50      protected abstract File getPomFile();
51  
52      /**
53       * Returns the test directory to use.
54       *
55       * @return the test directory
56       */
57      protected abstract File getTestDirectory();
58  
59      /**
60       * Configures the exploded mojo for the specified test.
61       *
62       * If the {@code sourceFiles} parameter is {@code null}, sample JSPs are created by default.
63       *
64       * @param testId the id of the test
65       * @param artifactStubs the dependencies (may be null)
66       * @param sourceFiles the source files to create (may be null)
67       * @return the webapp directory
68       * @throws Exception if an error occurs while configuring the mojo
69       */
70      protected File setUpMojo(final String testId, ArtifactStub[] artifactStubs, String[] sourceFiles) throws Exception {
71          final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
72          final File webAppDirectory = new File(getTestDirectory(), testId);
73  
74          // Create the webapp sources
75          File webAppSource;
76          if (sourceFiles == null) {
77              webAppSource = createWebAppSource(testId);
78          } else {
79              webAppSource = createWebAppSource(testId, false);
80              for (String sourceFile : sourceFiles) {
81                  File sample = new File(webAppSource, sourceFile);
82                  createFile(sample);
83              }
84          }
85  
86          final File classesDir = createClassesDir(testId, true);
87          final File workDirectory = new File(getTestDirectory(), "/war/work-" + testId);
88          createDir(workDirectory);
89  
90          if (artifactStubs != null) {
91              for (ArtifactStub artifactStub : artifactStubs) {
92                  project.addArtifact(artifactStub);
93              }
94          }
95  
96          configureMojo(mojo, classesDir, webAppSource, webAppDirectory, project);
97          setVariableValueToObject(mojo, "workDirectory", workDirectory);
98  
99          return webAppDirectory;
100     }
101 
102     /**
103      * Configures the exploded mojo for the specified test.
104      *
105      * @param testId the id of the test
106      * @param artifactStubs the dependencies (may be null)
107      * @return the webapp directory
108      * @throws Exception if an error occurs while configuring the mojo
109      */
110     protected File setUpMojo(final String testId, ArtifactStub[] artifactStubs) throws Exception {
111         return setUpMojo(testId, artifactStubs, null);
112     }
113 
114     /**
115      * Cleans up a directory.
116      *
117      * @param directory the directory to remove
118      * @throws IOException if an error occurred while removing the directory
119      */
120     protected void cleanDirectory(File directory) throws IOException {
121         if (directory != null && directory.isDirectory() && directory.exists()) {
122             FileUtils.deleteDirectory(directory);
123         }
124     }
125 
126     /**
127      * Asserts the default content of the war based on the specified webapp directory.
128      *
129      * @param webAppDirectory the webapp directory
130      * @return a list of File objects that have been asserted
131      */
132     protected List<File> assertDefaultContent(File webAppDirectory) {
133         // Validate content of the webapp
134         File expectedWebSourceFile = new File(webAppDirectory, "pansit.jsp");
135         File expectedWebSource2File = new File(webAppDirectory, "org/web/app/last-exile.jsp");
136 
137         assertTrue("source file not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists());
138         assertTrue("source file not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists());
139 
140         final List<File> content = new ArrayList<>();
141         content.add(expectedWebSourceFile);
142         content.add(expectedWebSource2File);
143 
144         return content;
145     }
146 
147     /**
148      * Asserts the web.xml file of the war based on the specified webapp directory.
149      *
150      * @param webAppDirectory the webapp directory
151      * @return a list with the web.xml File object
152      */
153     protected List<File> assertWebXml(File webAppDirectory) {
154         File expectedWEBXMLFile = new File(webAppDirectory, "WEB-INF/web.xml");
155         assertTrue("web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists());
156 
157         final List<File> content = new ArrayList<>();
158         content.add(expectedWEBXMLFile);
159 
160         return content;
161     }
162 
163     /**
164      * Asserts custom content of the war based on the specified webapp directory.
165      *
166      * @param webAppDirectory the webapp directory
167      * @param filePaths an array of file paths relative to the webapp directory
168      * @param customMessage a custom message if an assertion fails
169      * @return a list of File objects that have been inspected
170      */
171     protected List<File> assertCustomContent(File webAppDirectory, String[] filePaths, String customMessage) {
172         final List<File> content = new ArrayList<>();
173         for (String filePath : filePaths) {
174             final File expectedFile = new File(webAppDirectory, filePath);
175             if (customMessage != null) {
176                 assertTrue(customMessage + " - " + expectedFile.toString(), expectedFile.exists());
177             } else {
178                 assertTrue("source file not found: " + expectedFile.toString(), expectedFile.exists());
179             }
180             content.add(expectedFile);
181         }
182         return content;
183     }
184 
185     /**
186      * Asserts that the webapp contains only the specified files.
187      *
188      * @param webAppDirectory the webapp directory
189      * @param expectedFiles the expected files
190      * @param filter an optional filter to ignore some resources
191      */
192     protected void assertWebAppContent(File webAppDirectory, List<File> expectedFiles, FileFilter filter) {
193         final List<File> webAppContent = new ArrayList<>();
194         if (filter != null) {
195             buildFilesList(webAppDirectory, filter, webAppContent);
196         } else {
197             buildFilesList(webAppDirectory, new FileFilterImpl(webAppDirectory, null), webAppContent);
198         }
199 
200         // Now we have the files, sort them.
201         Collections.sort(expectedFiles);
202         Collections.sort(webAppContent);
203         assertEquals(
204                 "Invalid webapp content, expected " + expectedFiles.size() + "file(s) " + expectedFiles + " but got "
205                         + webAppContent.size() + " file(s) " + webAppContent,
206                 expectedFiles,
207                 webAppContent);
208     }
209 
210     /**
211      * Builds the list of files and directories from the specified dir.
212      *
213      * Note that the filter is not used the usual way. If the filter does not accept the current file, it's not added
214      * but yet the subdirectories are added if any.
215      *
216      * @param dir the base directory
217      * @param filter the filter
218      * @param content the current content, updated recursively
219      */
220     private void buildFilesList(final File dir, FileFilter filter, final List<File> content) {
221         final File[] files = dir.listFiles();
222 
223         for (File file : files) {
224             // Add the file if the filter is ok with it
225             if (filter.accept(file)) {
226                 content.add(file);
227             }
228 
229             // Even if the file is not accepted and is a directory, add it
230             if (file.isDirectory()) {
231                 buildFilesList(file, filter, content);
232             }
233         }
234     }
235 
236     class FileFilterImpl implements FileFilter {
237 
238         private final List<String> rejectedFilePaths;
239 
240         private final int webAppDirIndex;
241 
242         FileFilterImpl(File webAppDirectory, String[] rejectedFilePaths) {
243             if (rejectedFilePaths != null) {
244                 this.rejectedFilePaths = Arrays.asList(rejectedFilePaths);
245             } else {
246                 this.rejectedFilePaths = new ArrayList<>();
247             }
248             this.webAppDirIndex = webAppDirectory.getAbsolutePath().length() + 1;
249         }
250 
251         public boolean accept(File file) {
252             String effectiveRelativePath = buildRelativePath(file);
253             return !(rejectedFilePaths.contains(effectiveRelativePath) || file.isDirectory());
254         }
255 
256         private String buildRelativePath(File f) {
257             return f.getAbsolutePath().substring(webAppDirIndex);
258         }
259     }
260 }