package org.codehaus.mojo.unix.maven.zip; /* * The MIT License * * Copyright 2009 The Codehaus. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import fj.*; import static fj.Function.*; import fj.data.*; import org.apache.commons.vfs.*; import org.codehaus.mojo.unix.*; import static org.codehaus.mojo.unix.FileAttributes.*; import static org.codehaus.mojo.unix.PackageFileSystem.*; import static org.codehaus.mojo.unix.UnixFsObject.*; import org.codehaus.mojo.unix.java.*; import org.codehaus.mojo.unix.util.*; import static org.codehaus.mojo.unix.util.RelativePath.*; import org.codehaus.plexus.util.*; import org.joda.time.*; import java.io.*; import java.util.concurrent.*; import java.util.zip.*; /** */ public class ZipUnixPackage extends UnixPackage { private PackageFileSystem<F2<UnixFsObject, ZipOutputStream, Callable>> fileSystem; private FileObject workingDirectory; public ZipUnixPackage() { super( "zip" ); } public UnixPackage parameters( PackageParameters parameters ) { return this; } // ----------------------------------------------------------------------- // FileCollector Implementation // ----------------------------------------------------------------------- public FileObject getRoot() { return workingDirectory; } public FileCollector addDirectory( final UnixFsObject.Directory directory ) throws IOException { BasicPackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>> o = new BasicPackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>>( directory, this.directory ); fileSystem = fileSystem.addDirectory( o ); return this; } public FileCollector addFile( FileObject fromFile, UnixFsObject.RegularFile file ) throws IOException { F2<UnixFsObject, ZipOutputStream, Callable> f = uncurryF2( curry( this.file, fromFile ) ); BasicPackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>> o = new BasicPackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>>( file, f ); fileSystem = fileSystem.addFile( o ); return this; } public FileCollector addSymlink( UnixFsObject.Symlink symlink ) throws IOException { return this; } public void apply( F2<UnixFsObject, FileAttributes, FileAttributes> f ) { fileSystem = fileSystem.apply( f ); } // ----------------------------------------------------------------------- // UnixPackage Implementation // ----------------------------------------------------------------------- public ZipUnixPackage workingDirectory( FileObject workingDirectory ) throws FileSystemException { this.workingDirectory = workingDirectory; return this; } public void beforeAssembly( FileAttributes defaultDirectoryAttributes ) throws IOException { Directory rootDirectory = directory( BASE, new LocalDateTime( System.currentTimeMillis() ), EMPTY ); BasicPackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>> fileSystemObject = new BasicPackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>>( rootDirectory, directory ); fileSystem = create( fileSystemObject, fileSystemObject ); } public void packageToFile( File packageFile, ScriptUtil.Strategy strategy ) throws Exception { F2<RelativePath, PackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>>, Boolean> pathFilter = ZipUnixPackage.pathFilter(); List<PackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>>> items = fileSystem. toList(). filter( compose( BooleanF.invert, curry( pathFilter, BASE ) ) ); ZipOutputStream zos = null; try { zos = new ZipOutputStream( new FileOutputStream( packageFile ) ); for ( PackageFileSystemObject<F2<UnixFsObject, ZipOutputStream, Callable>> fileSystemObject : items ) { fileSystemObject.getExtension().f( fileSystemObject.getUnixFsObject(), zos ).call(); } } finally { IOUtil.close( zos ); } } public static <A> F2<RelativePath, PackageFileSystemObject<A>, Boolean> pathFilter() { return new F2<RelativePath, PackageFileSystemObject<A>, Boolean>() { public Boolean f( RelativePath path, PackageFileSystemObject object ) { return object.getUnixFsObject().path.equals( path ); } }; } private final F2<UnixFsObject, ZipOutputStream, Callable> directory = new F2<UnixFsObject, ZipOutputStream, Callable>() { public Callable f( final UnixFsObject unixFsObject, final ZipOutputStream zipOutputStream ) { return new Callable() { public Object call() throws Exception { String path = unixFsObject.path.isBase() ? "." : unixFsObject.path.asAbsolutePath( "./" ) + "/"; zipOutputStream.putNextEntry( new ZipEntry( path ) ); return null; } }; } }; private final F3<FileObject, UnixFsObject, ZipOutputStream, Callable> file = new F3<FileObject, UnixFsObject, ZipOutputStream, Callable>() { public Callable f( final FileObject fromFile, final UnixFsObject unixFsObject, final ZipOutputStream zipOutputStream ) { return new Callable() { public Object call() throws Exception { RegularFile file = (RegularFile) unixFsObject; ZipEntry zipEntry = new ZipEntry( unixFsObject.path.asAbsolutePath( "./" ) ); zipEntry.setSize( file.size ); zipEntry.setTime( file.lastModified.toDateTime().getMillis() ); zipOutputStream.putNextEntry( zipEntry ); InputStream inputStream = null; try { inputStream = fromFile.getContent().getInputStream(); IOUtil.copy( inputStream, zipOutputStream, 1024 * 128 ); } finally { IOUtil.close( inputStream ); } return null; } }; } }; }