blob: d2913b7dfdea64f377ae2e684d8e1c2716f1343e [file] [log] [blame]
package org.apache.maven.it.util;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.maven.shared.utils.io.FileUtils;
import org.apache.maven.shared.utils.io.IOUtil;
/**
* @todo this can be replaced with plexus-archiver
*/
public class ResourceExtractor
{
public static File simpleExtractResources( Class<?> cl, String resourcePath )
throws IOException
{
String tempDirPath = System.getProperty( "maven.test.tmpdir", System.getProperty( "java.io.tmpdir" ) );
File tempDir = new File( tempDirPath );
File testDir = new File( tempDir, resourcePath );
FileUtils.deleteDirectory( testDir );
testDir = ResourceExtractor.extractResourcePath( cl, resourcePath, tempDir, false );
return testDir;
}
public static File extractResourcePath( String resourcePath, File dest )
throws IOException
{
return extractResourcePath( ResourceExtractor.class, resourcePath, dest );
}
public static File extractResourcePath( Class<?> cl, String resourcePath, File dest )
throws IOException
{
return extractResourcePath( cl, resourcePath, dest, false );
}
public static File extractResourcePath( Class<?> cl, String resourcePath, File tempDir, boolean alwaysExtract )
throws IOException
{
File dest = new File( tempDir, resourcePath );
return extractResourceToDestination( cl, resourcePath, dest, alwaysExtract );
}
public static File extractResourceToDestination( Class<?> cl, String resourcePath, File destination,
boolean alwaysExtract )
throws IOException
{
URL url = cl.getResource( resourcePath );
if ( url == null )
{
throw new IllegalArgumentException( "Resource not found: " + resourcePath );
}
if ( "jar".equalsIgnoreCase( url.getProtocol() ) )
{
File jarFile = getJarFileFromUrl( url );
extractResourcePathFromJar( cl, jarFile, resourcePath, destination );
}
else
{
try
{
File resourceFile = new File( new URI( url.toExternalForm() ) );
if ( !alwaysExtract )
{
return resourceFile;
}
if ( resourceFile.isDirectory() )
{
FileUtils.copyDirectoryStructure( resourceFile, destination );
}
else
{
FileUtils.copyFile( resourceFile, destination );
}
}
catch ( URISyntaxException e )
{
throw new RuntimeException( "Couldn't convert URL to File:" + url, e );
}
}
return destination;
}
private static void extractResourcePathFromJar( Class<?> cl, File jarFile, String resourcePath, File dest )
throws IOException
{
ZipFile z = new ZipFile( jarFile, ZipFile.OPEN_READ );
String zipStyleResourcePath = resourcePath.substring( 1 ) + "/";
ZipEntry ze = z.getEntry( zipStyleResourcePath );
if ( ze != null )
{
// DGF If it's a directory, then we need to look at all the entries
for ( Enumeration<? extends ZipEntry> entries = z.entries(); entries.hasMoreElements(); )
{
ze = entries.nextElement();
if ( ze.getName().startsWith( zipStyleResourcePath ) )
{
String relativePath = ze.getName().substring( zipStyleResourcePath.length() );
File destFile = new File( dest, relativePath );
if ( ze.isDirectory() )
{
destFile.mkdirs();
}
else
{
FileOutputStream fos = new FileOutputStream( destFile );
try
{
IOUtil.copy( z.getInputStream( ze ), fos );
}
finally
{
IOUtil.close( fos );
z.close();
}
}
}
}
}
else
{
FileOutputStream fos = new FileOutputStream( dest );
try
{
IOUtil.copy( cl.getResourceAsStream( resourcePath ), fos );
}
finally
{
IOUtil.close( fos );
z.close();
}
}
}
private static File getJarFileFromUrl( URL url )
{
if ( !"jar".equalsIgnoreCase( url.getProtocol() ) )
{
throw new IllegalArgumentException( "This is not a Jar URL:" + url.toString() );
}
String resourceFilePath = url.getFile();
int index = resourceFilePath.indexOf( "!" );
if ( index == -1 )
{
throw new RuntimeException( "Bug! " + url.toExternalForm() + " does not have a '!'" );
}
String jarFileURI = resourceFilePath.substring( 0, index );
try
{
File jarFile = new File( new URI( jarFileURI ) );
return jarFile;
}
catch ( URISyntaxException e )
{
throw new RuntimeException( "Bug! URI failed to parse: " + jarFileURI, e );
}
}
}