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.IOException;
23  import java.util.Date;
24  import java.util.List;
25  
26  import org.apache.maven.execution.DefaultMavenExecutionRequest;
27  import org.apache.maven.execution.MavenExecutionRequest;
28  import org.apache.maven.execution.MavenSession;
29  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
30  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
31  import org.apache.maven.plugins.war.stub.MavenProjectBasicStub;
32  import org.apache.maven.plugins.war.stub.WarOverlayStub;
33  import org.apache.maven.shared.filtering.MavenFileFilter;
34  import org.codehaus.plexus.PlexusContainer;
35  import org.codehaus.plexus.archiver.ArchiverException;
36  import org.codehaus.plexus.archiver.jar.JarArchiver;
37  import org.codehaus.plexus.util.FileUtils;
38  import org.eclipse.aether.RepositorySystemSession;
39  
40  public abstract class AbstractWarMojoTest extends AbstractMojoTestCase {
41  
42      protected static final File OVERLAYS_TEMP_DIR = new File(getBasedir(), "target/test-overlays/");
43  
44      protected static final File OVERLAYS_ROOT_DIR = new File(getBasedir(), "target/test-classes/overlays/");
45  
46      protected static final String MANIFEST_PATH = "META-INF" + File.separator + "MANIFEST.MF";
47  
48      protected abstract File getTestDirectory() throws Exception;
49  
50      /**
51       * initialize required parameters
52       *
53       * @param mojo The mojo to be tested.
54       * @param filters The list of filters.
55       * @param classesDir The classes directory.
56       * @param webAppSource The webAppSource.
57       * @param webAppDir The webAppDir folder.
58       * @param project The Maven project.
59       * @throws Exception in case of errors
60       */
61      protected void configureMojo(
62              AbstractWarMojo mojo,
63              List<String> filters,
64              File classesDir,
65              File webAppSource,
66              File webAppDir,
67              MavenProjectBasicStub project)
68              throws Exception {
69          setVariableValueToObject(mojo, "filters", filters);
70          setVariableValueToObject(mojo, "mavenFileFilter", lookup(MavenFileFilter.class.getName()));
71          setVariableValueToObject(mojo, "useJvmChmod", Boolean.TRUE);
72  
73          MavenExecutionRequest request = new DefaultMavenExecutionRequest()
74                  .setSystemProperties(System.getProperties())
75                  .setStartTime(new Date());
76  
77          MavenSession mavenSession =
78                  new MavenSession((PlexusContainer) null, (RepositorySystemSession) null, request, null);
79          setVariableValueToObject(mojo, "session", mavenSession);
80          setVariableValueToObject(mojo, "outdatedCheckPath", "WEB-INF/lib/");
81          mojo.setClassesDirectory(classesDir);
82          mojo.setWarSourceDirectory(webAppSource);
83          mojo.setWebappDirectory(webAppDir);
84          mojo.setProject(project);
85      }
86  
87      /**
88       * create an isolated xml dir
89       *
90       * @param id The id.
91       * @param xmlFiles array of xml files.
92       * @return The created file.
93       * @throws Exception in case of errors.
94       */
95      protected File createXMLConfigDir(String id, String[] xmlFiles) throws Exception {
96          File xmlConfigDir = new File(getTestDirectory(), "/" + id + "-test-data/xml-config");
97          File XMLFile;
98  
99          createDir(xmlConfigDir);
100 
101         if (xmlFiles != null) {
102             for (String o : xmlFiles) {
103                 XMLFile = new File(xmlConfigDir, o);
104                 createFile(XMLFile);
105             }
106         }
107 
108         return xmlConfigDir;
109     }
110 
111     /**
112      * Returns the webapp source directory for the specified id.
113      *
114      * @param id the id of the test
115      * @return the source directory for that test
116      * @throws Exception if an exception occurs
117      */
118     protected File getWebAppSource(String id) throws Exception {
119         return new File(getTestDirectory(), "/" + id + "-test-data/source");
120     }
121 
122     /**
123      * create an isolated web source with a sample jsp file
124      *
125      * @param id The id.
126      * @param createSamples Create example files yes or no.
127      * @return The created file.
128      * @throws Exception in case of errors.
129      */
130     protected File createWebAppSource(String id, boolean createSamples) throws Exception {
131         File webAppSource = getWebAppSource(id);
132         if (createSamples) {
133             File simpleJSP = new File(webAppSource, "pansit.jsp");
134             File jspFile = new File(webAppSource, "org/web/app/last-exile.jsp");
135 
136             createFile(simpleJSP);
137             createFile(jspFile);
138         }
139         return webAppSource;
140     }
141 
142     protected File createWebAppSource(String id) throws Exception {
143         return createWebAppSource(id, true);
144     }
145 
146     /**
147      * create a class directory with or without a sample class
148      *
149      * @param id The id.
150      * @param empty true to create a class files false otherwise.
151      * @return The created class file.
152      * @throws Exception in case of errors.
153      */
154     protected File createClassesDir(String id, boolean empty) throws Exception {
155         File classesDir = new File(getTestDirectory() + "/" + id + "-test-data/classes/");
156 
157         createDir(classesDir);
158 
159         if (!empty) {
160             createFile(new File(classesDir + "/sample-servlet.clazz"));
161         }
162 
163         return classesDir;
164     }
165 
166     protected void createDir(File dir) {
167         if (!dir.exists()) {
168             assertTrue("can not create test dir: " + dir.toString(), dir.mkdirs());
169         }
170     }
171 
172     protected void createFile(File testFile, String body) throws Exception {
173         createDir(testFile.getParentFile());
174         FileUtils.fileWrite(testFile.toString(), body);
175 
176         assertTrue("could not create file: " + testFile, testFile.exists());
177     }
178 
179     protected void createFile(File testFile) throws Exception {
180         createFile(testFile, testFile.toString());
181     }
182 
183     /**
184      * Generates test war.
185      * Generates war with such a structure:
186      * <ul>
187      * <li>jsp
188      * <ul>
189      * <li>d
190      * <ul>
191      * <li>a.jsp</li>
192      * <li>b.jsp</li>
193      * <li>c.jsp</li>
194      * </ul>
195      * </li>
196      * <li>a.jsp</li>
197      * <li>b.jsp</li>
198      * <li>c.jsp</li>
199      * </ul>
200      * </li>
201      * <li>WEB-INF
202      * <ul>
203      * <li>classes
204      * <ul>
205      * <li>a.clazz</li>
206      * <li>b.clazz</li>
207      * <li>c.clazz</li>
208      * </ul>
209      * </li>
210      * <li>lib
211      * <ul>
212      * <li>a.jar</li>
213      * <li>b.jar</li>
214      * <li>c.jar</li>
215      * </ul>
216      * </li>
217      * <li>web.xml</li>
218      * </ul>
219      * </li>
220      * </ul>
221      * Each of the files will contain: id+'-'+path
222      *
223      * @param id the id of the overlay containing the full structure
224      * @return the war file
225      * @throws Exception if an error occurs
226      */
227     protected File generateFullOverlayWar(String id) throws Exception {
228         final File destFile = new File(OVERLAYS_TEMP_DIR, id + ".war");
229         if (destFile.exists()) {
230             return destFile;
231         }
232 
233         // Archive was not yet created for that id so let's create it
234         final File rootDir = new File(OVERLAYS_ROOT_DIR, id);
235         rootDir.mkdirs();
236         String[] filePaths = new String[] {
237             "jsp/d/a.jsp",
238             "jsp/d/b.jsp",
239             "jsp/d/c.jsp",
240             "jsp/a.jsp",
241             "jsp/b.jsp",
242             "jsp/c.jsp",
243             "WEB-INF/classes/a.clazz",
244             "WEB-INF/classes/b.clazz",
245             "WEB-INF/classes/c.clazz",
246             "WEB-INF/lib/a.jar",
247             "WEB-INF/lib/b.jar",
248             "WEB-INF/lib/c.jar",
249             "WEB-INF/web.xml"
250         };
251 
252         for (String filePath : filePaths) {
253             createFile(new File(rootDir, filePath), id + "-" + filePath);
254         }
255 
256         createArchive(rootDir, destFile);
257         return destFile;
258     }
259 
260     // Overlay utilities
261 
262     /**
263      * Builds a test overlay.
264      *
265      * @param id the id of the overlay (see test/resources/overlays)
266      * @return a test war artifact with the content of the given test overlay
267      */
268     protected ArtifactStub buildWarOverlayStub(String id) {
269         // Create war file
270         final File destFile = new File(OVERLAYS_TEMP_DIR, id + ".war");
271         if (!destFile.exists()) {
272             createArchive(new File(OVERLAYS_ROOT_DIR, id), destFile);
273         }
274 
275         return new WarOverlayStub(getBasedir(), id, destFile);
276     }
277 
278     protected File getOverlayFile(String id, String filePath) {
279         final File overlayDir = new File(OVERLAYS_ROOT_DIR, id);
280         final File file = new File(overlayDir, filePath);
281 
282         // Make sure the file exists
283         assertTrue(
284                 "Overlay file " + filePath + " does not exist for overlay " + id + " at " + file.getAbsolutePath(),
285                 file.exists());
286         return file;
287     }
288 
289     protected void createArchive(final File directory, final File destinationFile) {
290         try {
291             JarArchiver archiver = new JarArchiver();
292 
293             archiver.setDestFile(destinationFile);
294             archiver.addDirectory(directory);
295 
296             archiver.createArchive();
297 
298         } catch (ArchiverException e) {
299             e.printStackTrace();
300             fail("Failed to create overlay archive " + e.getMessage());
301         } catch (IOException e) {
302             e.printStackTrace();
303             fail("Unexpected exception " + e.getMessage());
304         }
305     }
306 }