View Javadoc
1   package org.codehaus.mojo.webstart.util;
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.MojoExecutionException;
23  import org.codehaus.plexus.archiver.Archiver;
24  import org.codehaus.plexus.component.annotations.Component;
25  import org.codehaus.plexus.component.annotations.Requirement;
26  import org.codehaus.plexus.logging.AbstractLogEnabled;
27  import org.codehaus.plexus.util.DirectoryScanner;
28  import org.codehaus.plexus.util.FileUtils;
29  
30  import java.io.File;
31  import java.io.FileFilter;
32  import java.io.FileOutputStream;
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.io.OutputStream;
36  import java.net.MalformedURLException;
37  import java.net.URI;
38  import java.net.URL;
39  import java.util.List;
40  import java.util.zip.ZipFile;
41  
42  /**
43   * Helper for all IO operations.
44   *
45   * @author tchemit <chemit@codelutin.com>
46   * @since 1.0-beta-4
47   */
48  @Component( role = IOUtil.class, hint = "default" )
49  public class DefaultIOUtil
50      extends AbstractLogEnabled
51      implements IOUtil
52  {
53  
54      /**
55       * The Zip archiver.
56       */
57      @Requirement( hint = "zip" )
58      private Archiver zipArchiver;
59  
60      /**
61       * {@inheritDoc}
62       */
63      public void copyResources( File sourceDirectory, File targetDirectory )
64          throws MojoExecutionException
65      {
66          if ( !sourceDirectory.exists() )
67          {
68              getLogger().info( "Directory does not exist " + sourceDirectory.getAbsolutePath() );
69          }
70          else
71          {
72              if ( !sourceDirectory.isDirectory() )
73              {
74                  getLogger().debug( "Not a directory: " + sourceDirectory.getAbsolutePath() );
75              }
76              else
77              {
78                  getLogger().debug( "Copying resources from " + sourceDirectory.getAbsolutePath() );
79  
80                  // this may needs to be parametrized somehow
81                  String excludes = concat( DirectoryScanner.DEFAULTEXCLUDES, ", " );
82                  copyDirectoryStructure( sourceDirectory, targetDirectory, "**", excludes );
83              }
84  
85          }
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      public void copyFile( File sourceFile, File targetFile )
92          throws MojoExecutionException
93      {
94          makeDirectoryIfNecessary( targetFile.getParentFile() );
95          try
96          {
97              FileUtils.copyFile( sourceFile, targetFile );
98          }
99          catch ( IOException e )
100         {
101             throw new MojoExecutionException( "Could not copy file " + sourceFile + " to " + targetFile, e );
102         }
103     }
104 
105 
106     /**
107      * {@inheritDoc}
108      */
109     public void copyDirectoryStructure( File sourceDirectory, File targetDirectory )
110         throws MojoExecutionException
111     {
112 
113         makeDirectoryIfNecessary( targetDirectory );
114 
115         // hopefully available from FileUtils 1.0.5-SNAPSHOT
116         try
117         {
118             FileUtils.copyDirectoryStructure( sourceDirectory, targetDirectory );
119         }
120         catch ( IOException e )
121         {
122             throw new MojoExecutionException(
123                 "Could not copy directory structure from " + sourceDirectory + " to " + targetDirectory, e );
124         }
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     public boolean shouldCopyFile( File sourceFile, File targetFile )
131     {
132         boolean shouldCopy = !targetFile.exists() || ( targetFile.lastModified() < sourceFile.lastModified() );
133         return shouldCopy;
134     }
135 
136     /**
137      * {@inheritDoc}
138      */
139     public boolean copyFileToDirectoryIfNecessary( File sourceFile, File targetDirectory )
140         throws MojoExecutionException
141     {
142 
143         if ( sourceFile == null )
144         {
145             throw new IllegalArgumentException( "sourceFile is null" );
146         }
147 
148         File targetFile = new File( targetDirectory, sourceFile.getName() );
149 
150         boolean shouldCopy = shouldCopyFile( sourceFile, targetFile );
151 
152         if ( shouldCopy )
153         {
154             try
155             {
156                 FileUtils.copyFileToDirectory( sourceFile, targetDirectory );
157             }
158             catch ( IOException e )
159             {
160                 throw new MojoExecutionException(
161                     "Could not copy file " + sourceFile + " to directory " + targetDirectory, e );
162             }
163         }
164         else
165         {
166             getLogger().debug(
167                 "Source file hasn't changed. Do not overwrite " + targetFile + " with " + sourceFile + "." );
168 
169         }
170 
171         return shouldCopy;
172     }
173 
174     /**
175      * {@inheritDoc}
176      */
177     public void removeDirectory( File dir )
178         throws MojoExecutionException
179     {
180         if ( dir != null )
181         {
182             if ( dir.exists() && dir.isDirectory() )
183             {
184                 getLogger().debug( "Deleting directory " + dir.getAbsolutePath() );
185                 try
186                 {
187                     FileUtils.deleteDirectory( dir );
188                 }
189                 catch ( IOException e )
190                 {
191                     throw new MojoExecutionException( "Could not delete directory: " + dir, e );
192                 }
193             }
194         }
195     }
196 
197     /**
198      * {@inheritDoc}
199      */
200     public void makeDirectoryIfNecessary( File dir )
201         throws MojoExecutionException
202     {
203 
204         if ( !dir.exists() && !dir.mkdirs() )
205         {
206             throw new MojoExecutionException( "Failed to create directory: " + dir );
207         }
208 
209     }
210 
211     /**
212      * {@inheritDoc}
213      */
214     public int deleteFiles( File directory, FileFilter fileFilter )
215         throws MojoExecutionException
216     {
217         File[] files = directory.listFiles( fileFilter );
218 
219         if ( getLogger().isDebugEnabled() )
220         {
221             getLogger().debug( "deleteFiles in " + directory + " found " + files.length + " file(s) to delete" );
222         }
223 
224         if ( files.length == 0 )
225         {
226             return 0;
227         }
228 
229         for ( File file : files )
230         {
231             deleteFile( file );
232         }
233         return files.length;
234     }
235 
236     /**
237      * {@inheritDoc}
238      */
239     public void deleteFile( File file )
240         throws MojoExecutionException
241     {
242         if ( file.exists() && !file.delete() )
243         {
244             throw new MojoExecutionException( "Could not delete file: " + file );
245         }
246     }
247 
248     /**
249      * {@inheritDoc}
250      */
251     public void renameTo( File source, File target )
252         throws MojoExecutionException
253     {
254         boolean result = source.renameTo( target );
255         if ( !result )
256         {
257             throw new MojoExecutionException( "Could not rename " + source + " to " + target );
258         }
259     }
260 
261     /**
262      * {@inheritDoc}
263      */
264     public void copyResources( URI uri, ClassLoader classLoader, File target )
265         throws MojoExecutionException
266     {
267         URL url;
268 
269         String scheme = uri.getScheme();
270         if ( "classpath".equals( scheme ) )
271         {
272 
273             // get resource from class-path
274             String path = uri.getPath();
275 
276             if ( path == null )
277             {
278                 // can happen when using classpath:myFile
279                 path = uri.toString().substring( scheme.length() + 1 );
280             }
281 
282             if ( path.startsWith( "/" ) )
283             {
284                 // remove first car
285                 path = path.substring( 1 );
286             }
287             url = classLoader.getResource( path );
288         }
289         else
290         {
291             // classic url from uri
292             try
293             {
294                 url = uri.toURL();
295             }
296             catch ( MalformedURLException e )
297             {
298                 throw new MojoExecutionException( "Bad uri syntax " + uri, e );
299             }
300         }
301 
302         InputStream inputStream;
303 
304         try
305         {
306             inputStream = url.openStream();
307         }
308         catch ( IOException e )
309         {
310             throw new MojoExecutionException( "Could not open resource " + url, e );
311         }
312 
313         if ( inputStream == null )
314         {
315             throw new MojoExecutionException( "Could not find resource " + url );
316         }
317         try
318         {
319             OutputStream outputStream = null;
320 
321             try
322             {
323                 outputStream = new FileOutputStream( target );
324                 org.codehaus.plexus.util.IOUtil.copy( inputStream, outputStream );
325                 outputStream.close();
326                 inputStream.close();
327             }
328             catch ( IOException e )
329             {
330                 throw new MojoExecutionException( "Could not copy resource from " + url + " to " + target, e );
331             }
332             finally
333             {
334                 if ( outputStream != null )
335                 {
336                     org.codehaus.plexus.util.IOUtil.close( outputStream );
337                 }
338             }
339         }
340 
341         finally
342         {
343             org.codehaus.plexus.util.IOUtil.close( inputStream );
344         }
345 
346     }
347 
348     /**
349      * {@inheritDoc}
350      */
351     public void close( ZipFile closeable )
352     {
353         try
354         {
355             if ( closeable != null )
356             {
357                 closeable.close();
358             }
359         }
360         catch ( IOException ignore )
361         {
362         }
363     }
364 
365     /**
366      * {@inheritDoc}
367      */
368     public void createArchive( File directory, File archive )
369         throws MojoExecutionException
370     {
371 
372         // package the zip. Note this is very simple. Look at the JarMojo which does more things.
373         // we should perhaps package as a war when inside a project with war packaging ?
374 
375         makeDirectoryIfNecessary( archive.getParentFile() );
376 
377         deleteFile( archive );
378 
379         zipArchiver.addDirectory( directory );
380         zipArchiver.setDestFile( archive );
381 
382         try
383         {
384             zipArchiver.createArchive();
385         }
386         catch ( IOException e )
387         {
388             throw new MojoExecutionException( "Could not create zip archive: " + archive, e );
389         }
390     }
391 
392     private void copyDirectoryStructure( File sourceDirectory, File destinationDirectory, String includes,
393                                          String excludes )
394         throws MojoExecutionException
395     {
396         if ( !sourceDirectory.exists() )
397         {
398             return;
399         }
400 
401         List<File> files;
402         try
403         {
404             files = FileUtils.getFiles( sourceDirectory, includes, excludes );
405         }
406         catch ( IOException e )
407         {
408             throw new MojoExecutionException( "Could not obtain files from " + sourceDirectory, e );
409         }
410 
411         for ( File file : files )
412         {
413 
414             getLogger().debug( "Copying " + file + " to " + destinationDirectory );
415 
416             String path = file.getAbsolutePath().substring( sourceDirectory.getAbsolutePath().length() + 1 );
417 
418             File destDir = new File( destinationDirectory, path );
419 
420             getLogger().debug( "Copying " + file + " to " + destDir );
421 
422             if ( file.isDirectory() )
423             {
424                 makeDirectoryIfNecessary( destDir );
425             }
426             else
427             {
428                 try
429                 {
430                     FileUtils.copyFileToDirectory( file, destDir.getParentFile() );
431                 }
432                 catch ( IOException e )
433                 {
434                     throw new MojoExecutionException( "Could not copy file " + file + " to directory" + destDir, e );
435                 }
436             }
437         }
438     }
439 
440     private String concat( String[] array, String delim )
441     {
442         StringBuilder buffer = new StringBuilder();
443         for ( int i = 0; i < array.length; i++ )
444         {
445             if ( i > 0 )
446             {
447                 buffer.append( delim );
448             }
449             String s = array[i];
450             buffer.append( s ).append( delim );
451         }
452         return buffer.toString();
453     }
454 }