uk.org.retep.util.io.ResourceInstaller Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2007, Peter T Mount
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the retep.org.uk nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package uk.org.retep.util.io;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import uk.org.retep.logging.Log;
import uk.org.retep.util.collections.MapUtils;
import uk.org.retep.util.string.PropertyExpansion;
import uk.org.retep.util.string.StringUtils;
/**
* A simple file installer which will copy resources from a jar into the
* local filesystem.
*
* A deployment descriptor is itself a properties file who's keys define the
* resource to copy, and the value defines the relative path to copy to.
*
* The path can be processed by a PropertyExpansion, to allow custom naming
* of the destination.
*
* @author peter
*/
public class ResourceInstaller
{
private static final String DEFAULT_MESSAGE = "Installing %s to %s";
private final Class> resourceClass;
private final File installationDirectory;
private final String descriptor;
private final Map, ?> properties;
private final Map fileList;
private Log log;
private boolean overwrite = true;
private Hook hook;
private String message = DEFAULT_MESSAGE;
public ResourceInstaller( final Class> resourceClass,
final File installationDirectory,
final String descriptor )
throws IOException
{
this( resourceClass,
installationDirectory,
descriptor,
new HashMap() );
}
public ResourceInstaller( final Class> resourceClass,
final File installationDirectory,
final String descriptor,
final Map, ?> properties )
throws IOException
{
this.resourceClass = resourceClass;
this.installationDirectory = installationDirectory;
this.descriptor = descriptor;
this.properties = properties;
final InputStream is = resourceClass.getResourceAsStream( descriptor );
fileList = MapUtils.loadMap( is,
new LinkedHashMap() );
}
public static void install( final Class> resourceClass,
final File installationDirectory,
final String descriptor )
throws IOException
{
new ResourceInstaller( resourceClass,
installationDirectory,
descriptor ).install();
}
public static void install( final Class> resourceClass,
final File installationDirectory,
final String descriptor,
final Map, ?> properties )
throws IOException
{
new ResourceInstaller( resourceClass,
installationDirectory,
descriptor,
properties ).install();
}
public static void install( final Class> resourceClass,
final File installationDirectory,
final String descriptor,
final Log log )
throws IOException
{
new ResourceInstaller( resourceClass,
installationDirectory,
descriptor ).setLog( log ).install();
}
public static void install( final Class> resourceClass,
final File installationDirectory,
final String descriptor,
final Map, ?> properties,
final Log log )
throws IOException
{
new ResourceInstaller( resourceClass,
installationDirectory,
descriptor,
properties ).setLog( log ).install();
}
public ResourceInstaller setLog( Log log )
{
this.log = log;
return this;
}
public String getMessage()
{
return message;
}
public void setMessage( final String message )
{
this.message = message == null ? DEFAULT_MESSAGE : message;
}
private void notice( final String msg, final Object... args )
{
if( log != null )
{
log.info( msg, args );
}
}
public boolean isOverwrite()
{
return overwrite;
}
public void setOverwrite( final boolean overwrite )
{
this.overwrite = overwrite;
}
@SuppressWarnings( "unchecked" )
public Map getProperties()
{
return (Map) properties;
}
public void setHook( final Hook hook )
{
this.hook = hook;
}
public List getDestinationFiles()
{
final List files = new ArrayList( fileList.size() );
// Expand the file list destinations with any properties
final Map map = PropertyExpansion.expandMap( fileList,
properties );
for( Map.Entry entry : map.entrySet() )
{
final File file = new File( installationDirectory, entry.getValue() );
FileUtils.assertFileInsideDirectory( installationDirectory, file );
files.add( file );
}
return files;
}
public void install()
throws IOException
{
// Ensure the installationDirectory directory exists
FileUtils.mkdirs( installationDirectory, log );
final String installationPath = installationDirectory.getAbsolutePath();
// Expand the file list destinations with any properties
final Map map = PropertyExpansion.expandMap( fileList,
properties );
for( Map.Entry entry : map.entrySet() )
{
// The destination file
final File file = new File( installationDirectory, entry.getValue() );
FileUtils.assertFileInsideDirectory( installationDirectory, file );
if( !file.exists() || (isOverwrite() && file.canWrite()) )
{
// Copy the resource
final String src = entry.getKey();
final InputStream is = resourceClass.getResourceAsStream( src );
if( is == null )
{
throw new IOException( "Source resource not found: " + src );
}
try
{
notice( message,
StringUtils.baseName( src ),
file.getPath() );
final FileOutputStream fos = new FileOutputStream( file );
try
{
if( hook != null )
{
hook.preCopy( src, is, fos, file );
}
FileUtils.copy( is, fos );
if( hook != null )
{
hook.postCopy( src, is, fos, file );
}
}
finally
{
fos.close();
}
}
finally
{
is.close();
}
}
}
}
public static interface Hook
{
void preCopy( final String sourceName,
final InputStream is,
final OutputStream os,
final File destinationFile )
throws IOException;
void postCopy( final String sourceName,
final InputStream is,
final OutputStream os,
final File destinationFile )
throws IOException;
}
}