View Javadoc
1   package org.apache.maven.plugins.war;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
23  import org.apache.maven.plugins.war.WarExplodedMojo;
24  import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
25  import org.codehaus.plexus.util.FileUtils;
26  
27  import java.io.File;
28  import java.io.FileFilter;
29  import java.io.IOException;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.LinkedList;
34  import java.util.List;
35  
36  /**
37   * @author Stephane Nicoll
38   */
39  public abstract class AbstractWarExplodedMojoTest
40      extends AbstractWarMojoTest
41  {
42  
43      protected WarExplodedMojo mojo;
44  
45      public void setUp()
46          throws Exception
47      {
48          super.setUp();
49          mojo = (WarExplodedMojo) lookupMojo( "exploded", getPomFile() );
50      }
51  
52      /**
53       * Returns the pom configuration to use.
54       *
55       * @return the pom configuration
56       */
57      protected abstract File getPomFile();
58  
59      /**
60       * Returns the test directory to use.
61       *
62       * @return the test directory
63       */
64      protected abstract File getTestDirectory();
65  
66      /**
67       * Configures the exploded mojo for the specified test.
68       * 
69       * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
70       *
71       * @param testId the id of the test
72       * @param artifactStubs the dependencies (may be null)
73       * @param sourceFiles the source files to create (may be null)
74       * @return the webapp directory
75       * @throws Exception if an error occurs while configuring the mojo
76       */
77      protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs, String[] sourceFiles )
78          throws Exception
79      {
80          final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
81          final File webAppDirectory = new File( getTestDirectory(), testId );
82  
83          // Create the webapp sources
84          File webAppSource;
85          if ( sourceFiles == null )
86          {
87              webAppSource = createWebAppSource( testId );
88          }
89          else
90          {
91              webAppSource = createWebAppSource( testId, false );
92              for ( String sourceFile : sourceFiles )
93              {
94                  File sample = new File( webAppSource, sourceFile );
95                  createFile( sample );
96  
97              }
98  
99          }
100 
101         final File classesDir = createClassesDir( testId, true );
102         final File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
103         createDir( workDirectory );
104 
105         if ( artifactStubs != null )
106         {
107             for ( ArtifactStub artifactStub : artifactStubs )
108             {
109                 project.addArtifact( artifactStub );
110             }
111         }
112 
113         configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
114         setVariableValueToObject( mojo, "workDirectory", workDirectory );
115 
116         return webAppDirectory;
117     }
118 
119     /**
120      * Configures the exploded mojo for the specified test.
121      *
122      * @param testId the id of the test
123      * @param artifactStubs the dependencies (may be null)
124      * @return the webapp directory
125      * @throws Exception if an error occurs while configuring the mojo
126      */
127     protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs )
128         throws Exception
129     {
130         return setUpMojo( testId, artifactStubs, null );
131     }
132 
133     /**
134      * Cleans up a directory.
135      *
136      * @param directory the directory to remove
137      * @throws IOException if an error occurred while removing the directory
138      */
139     protected void cleanDirectory( File directory )
140         throws IOException
141     {
142         if ( directory != null && directory.isDirectory() && directory.exists() )
143         {
144             FileUtils.deleteDirectory( directory );
145         }
146     }
147 
148     /**
149      * Asserts the default content of the war based on the specified webapp directory.
150      *
151      * @param webAppDirectory the webapp directory
152      * @return a list of File objects that have been asserted
153      */
154     protected List<File> assertDefaultContent( File webAppDirectory )
155     {
156         // Validate content of the webapp
157         File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
158         File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
159 
160         assertTrue( "source file not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
161         assertTrue( "source file not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
162 
163         final List<File> content = new ArrayList<File>();
164         content.add( expectedWebSourceFile );
165         content.add( expectedWebSource2File );
166 
167         return content;
168     }
169 
170     /**
171      * Asserts the web.xml file of the war based on the specified webapp directory.
172      *
173      * @param webAppDirectory the webapp directory
174      * @return a list with the web.xml File object
175      */
176     protected List<File> assertWebXml( File webAppDirectory )
177     {
178         File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
179         assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
180 
181         final List<File> content = new ArrayList<File>();
182         content.add( expectedWEBXMLFile );
183 
184         return content;
185     }
186 
187     /**
188      * Asserts custom content of the war based on the specified webapp directory.
189      *
190      * @param webAppDirectory the webapp directory
191      * @param filePaths an array of file paths relative to the webapp directory
192      * @param customMessage a custom message if an assertion fails
193      * @return a list of File objects that have been inspected
194      */
195     protected List<File> assertCustomContent( File webAppDirectory, String[] filePaths, String customMessage )
196     {
197         final List<File> content = new ArrayList<File>();
198         for ( String filePath : filePaths )
199         {
200             final File expectedFile = new File( webAppDirectory, filePath );
201             if ( customMessage != null )
202             {
203                 assertTrue( customMessage + " - " + expectedFile.toString(), expectedFile.exists() );
204             }
205             else
206             {
207                 assertTrue( "source file not found: " + expectedFile.toString(), expectedFile.exists() );
208             }
209             content.add( expectedFile );
210         }
211         return content;
212     }
213 
214     /**
215      * Asserts that the webapp contains only the specified files.
216      *
217      * @param webAppDirectory the webapp directory
218      * @param expectedFiles the expected files
219      * @param filter an optional filter to ignore some resources
220      */
221     protected void assertWebAppContent( File webAppDirectory, List<File> expectedFiles, FileFilter filter )
222     {
223         final List<File> webAppContent = new ArrayList<File>();
224         if ( filter != null )
225         {
226             buildFilesList( webAppDirectory, filter, webAppContent );
227         }
228         else
229         {
230             buildFilesList( webAppDirectory, new FileFilterImpl( webAppDirectory, null ), webAppContent );
231         }
232 
233         // Now we have the files, sort them.
234         Collections.sort( expectedFiles );
235         Collections.sort( webAppContent );
236         assertEquals( "Invalid webapp content, expected " + expectedFiles.size() + "file(s) " + expectedFiles
237             + " but got " + webAppContent.size() + " file(s) " + webAppContent, expectedFiles, webAppContent );
238     }
239 
240     /**
241      * Builds the list of files and directories from the specified dir.
242      * 
243      * Note that the filter is not used the usual way. If the filter does not accept the current file, it's not added
244      * but yet the subdirectories are added if any.
245      *
246      * @param dir the base directory
247      * @param filter the filter
248      * @param content the current content, updated recursivly
249      */
250     private void buildFilesList( final File dir, FileFilter filter, final List<File> content )
251     {
252         final File[] files = dir.listFiles();
253 
254         for ( File file : files )
255         {
256             // Add the file if the filter is ok with it
257             if ( filter.accept( file ) )
258             {
259                 content.add( file );
260             }
261 
262             // Even if the file is not accepted and is a directory, add it
263             if ( file.isDirectory() )
264             {
265                 buildFilesList( file, filter, content );
266             }
267 
268         }
269     }
270 
271     class FileFilterImpl
272         implements FileFilter
273     {
274 
275         private final List<String> rejectedFilePaths;
276 
277         private final int webAppDirIndex;
278 
279         public FileFilterImpl( File webAppDirectory, String[] rejectedFilePaths )
280         {
281             if ( rejectedFilePaths != null )
282             {
283                 this.rejectedFilePaths = Arrays.asList( rejectedFilePaths );
284             }
285             else
286             {
287                 this.rejectedFilePaths = new ArrayList<String>();
288             }
289             this.webAppDirIndex = webAppDirectory.getAbsolutePath().length() + 1;
290         }
291 
292         public boolean accept( File file )
293         {
294             String effectiveRelativePath = buildRelativePath( file );
295             return !( rejectedFilePaths.contains( effectiveRelativePath ) || file.isDirectory() );
296         }
297 
298         private String buildRelativePath( File f )
299         {
300             return f.getAbsolutePath().substring( webAppDirIndex );
301         }
302     }
303 
304 }