{
Map archiveEntries = getFiles();
if ( archiveEntries == null || archiveEntries.size() == 0 )
{
new ArchiverException( "You must set at least one file." );
}
File zipFile = getDestFile();
if ( zipFile == null )
{
new ArchiverException( "You must set the destination " + archiveType + "file." );
}
if ( zipFile.exists() && !zipFile.isFile() )
{
new ArchiverException( zipFile + " isn't a file." );
}
if ( zipFile.exists() && !zipFile.canWrite() )
{
new ArchiverException( zipFile + " is read-only." );
}
// Renamed version of original file, if it exists
File renamedFile = null;
// Whether or not an actual update is required -
// we don't need to update if the original file doesn't exist
addingNewFiles = true;
if ( doUpdate && !zipFile.exists() )
{
doUpdate = false;
getLogger().debug( "ignoring update attribute as " + archiveType + " doesn't exist." );
}
boolean success = false;
try
{
if ( doUpdate )
{
renamedFile =
FileUtils.createTempFile( "zip", ".tmp",
zipFile.getParentFile() );
renamedFile.deleteOnExit();
try
{
FileUtils.rename( zipFile, renamedFile );
}
catch ( SecurityException e )
{
getLogger().debug( e.toString() );
throw new ArchiverException(
"Not allowed to rename old file ("
+ zipFile.getAbsolutePath()
+ ") to temporary file", e );
}
catch ( IOException e )
{
getLogger().debug( e.toString() );
throw new ArchiverException(
"Unable to rename old file ("
+ zipFile.getAbsolutePath()
+ ") to temporary file", e );
}
}
String action = doUpdate ? "Updating " : "Building ";
getLogger().info( action + archiveType + ": " + zipFile.getAbsolutePath() );
ZipOutputStream zOut = null;
try
{
if ( !skipWriting )
{
zOut = new ZipOutputStream( zipFile );
zOut.setEncoding( encoding );
if ( doCompress )
{
zOut.setMethod( ZipOutputStream.DEFLATED );
}
else
{
zOut.setMethod( ZipOutputStream.STORED );
}
}
initZipOutputStream( zOut );
// Add the new files to the archive.
addResources( getResourcesToAdd( zipFile ), zOut );
if ( doUpdate )
{
addResources( getResourcesToUpdate( zipFile ), zOut );
}
finalizeZipOutputStream( zOut );
// If we've been successful on an update, delete the
// temporary file
if ( doUpdate )
{
if ( !renamedFile.delete() )
{
getLogger().warn( "Warning: unable to delete temporary file "
+ renamedFile.getName() );
}
}
success = true;
}
finally
{
// Close the output stream.
try
{
if ( zOut != null )
{
zOut.close();
}
}
catch ( IOException ex )
{
// If we're in this finally clause because of an
// exception, we don't really care if there's an
// exception when closing the stream. E.g. if it
// throws "ZIP file must have at least one entry",
// because an exception happened before we added
// any files, then we must swallow this
// exception. Otherwise, the error that's reported
// will be the close() error, which is not the
// real cause of the problem.
if ( success )
{
throw ex;
}
}
}
}
catch ( IOException ioe )
{
String msg = "Problem creating " + archiveType + ": "
+ ioe.getMessage();
// delete a bogus ZIP file (but only if it's not the original one)
if ( ( !doUpdate || renamedFile != null ) && !zipFile.delete() )
{
msg += " (and the archive is probably corrupt but I could not "
+ "delete it)";
}
if ( doUpdate && renamedFile != null )
{
try
{
FileUtils.rename( renamedFile, zipFile );
}
catch ( IOException e )
{
msg += " (and I couldn't rename the temporary file "
+ renamedFile.getName() + " back)";
}
}
throw new ArchiverException( msg, ioe );
}
finally
{
cleanUp();
}