View Javadoc
1   package org.apache.maven.it.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 java.io.File;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.net.URI;
26  import java.net.URISyntaxException;
27  import java.net.URL;
28  import java.util.Enumeration;
29  import java.util.zip.ZipEntry;
30  import java.util.zip.ZipFile;
31  import org.apache.maven.shared.utils.io.FileUtils;
32  import org.apache.maven.shared.utils.io.IOUtil;
33  
34  
35  /**
36   *  TODO this can be replaced with plexus-archiver
37   */
38  public class ResourceExtractor
39  {
40  
41      public static File simpleExtractResources( Class<?> cl, String resourcePath )
42          throws IOException
43      {
44          String tempDirPath = System.getProperty( "maven.test.tmpdir", System.getProperty( "java.io.tmpdir" ) );
45          File tempDir = new File( tempDirPath );
46  
47          File testDir = new File( tempDir, resourcePath );
48  
49          FileUtils.deleteDirectory( testDir );
50  
51          testDir = ResourceExtractor.extractResourcePath( cl, resourcePath, tempDir, false );
52          return testDir;
53      }
54  
55      public static File extractResourcePath( String resourcePath, File dest )
56          throws IOException
57      {
58          return extractResourcePath( ResourceExtractor.class, resourcePath, dest );
59      }
60  
61      public static File extractResourcePath( Class<?> cl, String resourcePath, File dest )
62          throws IOException
63      {
64          return extractResourcePath( cl, resourcePath, dest, false );
65      }
66  
67      public static File extractResourcePath( Class<?> cl, String resourcePath, File tempDir, boolean alwaysExtract )
68          throws IOException
69      {
70          File dest = new File( tempDir, resourcePath );
71          return extractResourceToDestination( cl, resourcePath, dest, alwaysExtract );
72      }
73  
74      public static File extractResourceToDestination( Class<?> cl, String resourcePath, File destination,
75                                                       boolean alwaysExtract )
76          throws IOException
77      {
78          URL url = cl.getResource( resourcePath );
79          if ( url == null )
80          {
81              throw new IllegalArgumentException( "Resource not found: " + resourcePath );
82          }
83          if ( "jar".equalsIgnoreCase( url.getProtocol() ) )
84          {
85              File jarFile = getJarFileFromUrl( url );
86              extractResourcePathFromJar( cl, jarFile, resourcePath, destination );
87          }
88          else
89          {
90              try
91              {
92                  File resourceFile = new File( new URI( url.toExternalForm() ) );
93                  if ( !alwaysExtract )
94                  {
95                      return resourceFile;
96                  }
97                  if ( resourceFile.isDirectory() )
98                  {
99                      FileUtils.copyDirectoryStructure( resourceFile, destination );
100                 }
101                 else
102                 {
103                     FileUtils.copyFile( resourceFile, destination );
104                 }
105             }
106             catch ( URISyntaxException e )
107             {
108                 throw new RuntimeException( "Couldn't convert URL to File:" + url, e );
109             }
110         }
111         return destination;
112     }
113 
114     private static void extractResourcePathFromJar( Class<?> cl, File jarFile, String resourcePath, File dest )
115         throws IOException
116     {
117         ZipFile z = new ZipFile( jarFile, ZipFile.OPEN_READ );
118         String zipStyleResourcePath = resourcePath.substring( 1 ) + "/";
119         ZipEntry ze = z.getEntry( zipStyleResourcePath );
120         if ( ze != null )
121         {
122             // DGF If it's a directory, then we need to look at all the entries
123             for ( Enumeration<? extends ZipEntry> entries = z.entries(); entries.hasMoreElements(); )
124             {
125                 ze = entries.nextElement();
126                 if ( ze.getName().startsWith( zipStyleResourcePath ) )
127                 {
128                     String relativePath = ze.getName().substring( zipStyleResourcePath.length() );
129                     File destFile = new File( dest, relativePath );
130                     if ( ze.isDirectory() )
131                     {
132                         destFile.mkdirs();
133                     }
134                     else
135                     {
136                         FileOutputStream fos = new FileOutputStream( destFile );
137                         try
138                         {
139                             IOUtil.copy( z.getInputStream( ze ), fos );
140                         }
141                         finally
142                         {
143                             IOUtil.close( fos );
144                             z.close();
145                         }
146                     }
147                 }
148             }
149         }
150         else
151         {
152             FileOutputStream fos = new FileOutputStream( dest );
153             try
154             {
155                 IOUtil.copy( cl.getResourceAsStream( resourcePath ), fos );
156             }
157             finally
158             {
159                 IOUtil.close( fos );
160                 z.close();
161             }
162         }
163     }
164 
165     private static File getJarFileFromUrl( URL url )
166     {
167         if ( !"jar".equalsIgnoreCase( url.getProtocol() ) )
168         {
169             throw new IllegalArgumentException( "This is not a Jar URL:" + url.toString() );
170         }
171         String resourceFilePath = url.getFile();
172         int index = resourceFilePath.indexOf( "!" );
173         if ( index == -1 )
174         {
175             throw new RuntimeException( "Bug! " + url.toExternalForm() + " does not have a '!'" );
176         }
177         String jarFileURI = resourceFilePath.substring( 0, index );
178         try
179         {
180             File jarFile = new File( new URI( jarFileURI ) );
181             return jarFile;
182         }
183         catch ( URISyntaxException e )
184         {
185             throw new RuntimeException( "Bug! URI failed to parse: " + jarFileURI, e );
186         }
187 
188     }
189 }