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