001    //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/framework/util/ZipUtils.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    package org.deegree.framework.util;
037    
038    import java.io.File;
039    import java.io.FileInputStream;
040    import java.io.FileNotFoundException;
041    import java.io.FileOutputStream;
042    import java.io.IOException;
043    import java.io.InputStream;
044    import java.util.zip.ZipEntry;
045    import java.util.zip.ZipInputStream;
046    import java.util.zip.ZipOutputStream;
047    
048    import org.deegree.framework.log.ILogger;
049    import org.deegree.framework.log.LoggerFactory;
050    
051    /**
052     *
053     *
054     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
055     * @author last edited by: $Author: apoth $
056     *
057     * @version $Revision: 29950 $, $Date: 2011-03-09 13:09:31 +0100 (Wed, 09 Mar 2011) $
058     */
059    public class ZipUtils {
060    
061        private static ILogger LOG = LoggerFactory.getLogger( ZipUtils.class );
062    
063        private StringBuffer details = null;
064    
065       
066    
067        /**
068         * packs the passed files into a zip-archive, deletes the files if desired and returns the name
069         * of the archive as absolute path
070         *
071         * @param dirName
072         *            name of the directory where the files are found (see fileNames) and where the
073         *            archive will be stored. Needs to be an absolute path.
074         * @param archiveName
075         *            desired name of the archive. It will be stored in the directory given in dirName.
076         * @param fileNames
077         *            names of the files to be packed into the zip archive. The files are expected to be
078         *            in the directory given in dirName.
079         * @param deleteFiles
080         *            if true all files will be deleted after zip-file has been created
081         * @param storeFolderPathInZip
082         *            if true, the files are stored in the zip according to their folder structur (with
083         *            absolute paths); if false, the files are stored under their file name only.
084         * @return the name of the zip file (combined dirName and archiveName)
085         * @throws FileNotFoundException
086         * @throws IOException
087         */
088        public String doZip( String dirName, String archiveName, String[] fileNames, boolean deleteFiles,
089                             boolean storeFolderPathInZip )
090                                throws FileNotFoundException, IOException {
091    
092            byte[] b = new byte[512];
093    
094            // make sure, that directory name ends with a file separator ("/" on Linux, or "\" on
095            // Windows)
096            if ( !dirName.endsWith( "/" ) && !dirName.endsWith( "\\" ) ) {
097                dirName = dirName + File.separator;
098            }
099    
100            File file = new File( archiveName );
101            String archive = archiveName;
102            if ( !file.isAbsolute() ) {
103                archive = dirName + archiveName;
104            }
105            LOG.logDebug( "archive name: " + archive );
106    
107            ZipOutputStream zout = new ZipOutputStream( new FileOutputStream( archive ) );
108            details = new StringBuffer();
109            String[] absFileNames = new String[fileNames.length];
110    
111            for ( int i = 0; i < fileNames.length; i++ ) {
112                file = new File( fileNames[i] );
113                if ( !file.isAbsolute() ) {
114                    absFileNames[i] = dirName + fileNames[i];
115                } else {
116                    absFileNames[i] = fileNames[i];
117                }
118    
119                InputStream in = new FileInputStream( absFileNames[i] );
120                ZipEntry e = null;
121                if ( storeFolderPathInZip ) {
122                    e = new ZipEntry( absFileNames[i] );
123                } else {
124                    e = new ZipEntry( file.getName() );
125                }
126                zout.putNextEntry( e );
127    
128                int len = 0;
129                while ( ( len = in.read( b ) ) != -1 ) {
130                    zout.write( b, 0, len );
131                }
132                in.close();
133                zout.closeEntry();
134                details.append( createZipDetails( e ) + "\n" );
135            }
136    
137            if ( deleteFiles ) {
138                for ( int i = 0; i < absFileNames.length; i++ ) {
139                    file = new File( absFileNames[i] );
140                    LOG.logInfo( absFileNames[i] + " deleted: " + file.delete() );
141                }
142            }
143    
144            zout.close();
145            return archive;
146        }
147    
148        /**
149         * @return details about the zipping
150         */
151        public String getZipDetails() {
152            return details.toString();
153        }
154    
155        /**
156         * returns some information about the zip process of the current <code>ZipEntry</code>.
157         *
158         * @param e
159         * @return information on the zip process
160         */
161        private StringBuffer createZipDetails( ZipEntry e ) {
162    
163            StringBuffer sb = new StringBuffer();
164    
165            sb.append( "added " + e.getName() );
166    
167            if ( e.getMethod() == ZipEntry.DEFLATED ) {
168                long size = e.getSize();
169    
170                if ( size > 0 ) {
171                    long csize = e.getCompressedSize();
172                    long ratio = ( ( size - csize ) * 100 ) / size;
173                    sb.append( " (deflated " + ratio + "%)" );
174                } else {
175                    sb.append( " (deflated 0%)" );
176                }
177            } else {
178                sb.append( " (stored 0%)" );
179            }
180    
181            return sb;
182        }
183    
184        /**
185         * @param file
186         * @param outdir
187         * @throws IOException
188         */
189        public void doUnzip( File file, String outdir )
190                                throws IOException {
191            this.doUnzip( new FileInputStream( file ), outdir );
192        }
193    
194        /**
195         * @param is
196         * @param outdir
197         * @throws IOException
198         */
199        public void doUnzip( InputStream is, String outdir )
200                                throws IOException {
201            int read = 0;
202            byte[] data = new byte[1024];
203            ZipEntry entry;
204            // Archiv öffnen und mit Stream verbinden
205            ZipInputStream in = new ZipInputStream( is );
206            // Alle Einträge des Archivs auslesen
207            while ( ( entry = in.getNextEntry() ) != null ) {
208                if ( entry.getMethod() == ZipEntry.DEFLATED )
209                    System.out.println( "  Inflating: " + entry.getName() );
210                else
211                    System.out.println( " Extracting: " + entry.getName() );
212                // Anlegen der Ausgabedatei für den aktuellen Eintrag
213                FileOutputStream out = new FileOutputStream( outdir + entry.getName() );
214                // Daten des Eintrags aus dem Archiv lesen und in die
215                // Ausgabedatei schreiben
216                while ( ( read = in.read( data, 0, 1024 ) ) != -1 )
217                    out.write( data, 0, read );
218                out.close();
219            }
220            in.close();
221            System.out.println();
222        }
223    
224    }