001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/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: mschneider $
056     *
057     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
058     */
059    public class ZipUtils {
060    
061        private static ILogger LOG = LoggerFactory.getLogger( ZipUtils.class );
062    
063        private StringBuffer details = null;
064    
065        /**
066         * packs the passed files into a zip-archive, deletes the files if desired and returns the name
067         * of the archive
068         *
069         * @deprecated please don't use this method any more. For the same result you might use
070         *             doZip(dirName,archiveName,fileNames,deleteFiles,true);
071         *
072         * @param dirName
073         *            name of the directory where to store the archive
074         * @param archiveName
075         *            desired archive name
076         * @param fileNames
077         *            names of the files to be packed into the zip archive
078         * @param deleteFiles
079         *            if true all files will be deleted after zip-file has been created
080         * @return the name of the archive
081         * @throws FileNotFoundException
082         * @throws IOException
083         */
084        @Deprecated
085        public String doZip( String dirName, String archiveName, String[] fileNames, boolean deleteFiles )
086                                throws FileNotFoundException, IOException {
087    
088            return doZip( dirName, archiveName, fileNames, deleteFiles, true );
089    
090            // byte[] b = new byte[512];
091            //
092            // File file = new File( archiveName );
093            // String archive = archiveName;
094            // if ( !file.isAbsolute() ) {
095            // archive = dirName + '/' + archiveName;
096            // }
097            // ZipOutputStream zout = new ZipOutputStream( new FileOutputStream( archive ) );
098            //
099            // details = new StringBuffer();
100            //
101            // for ( int i = 0; i < fileNames.length; i++ ) {
102            // file = new File( fileNames[i] );
103            //
104            // if ( !file.isAbsolute() ) {
105            // fileNames[i] = dirName + '/' + fileNames[i];
106            // }
107            // InputStream in = new FileInputStream( fileNames[i] );
108            // ZipEntry e = new ZipEntry( fileNames[i] );
109            // zout.putNextEntry( e );
110            //
111            // int len = 0;
112            //
113            // while ( ( len = in.read( b ) ) != -1 ) {
114            // zout.write( b, 0, len );
115            // }
116            //
117            // in.close();
118            // zout.closeEntry();
119            // details.append( createZipDetails( e ) + "\n" );
120            // }
121            //
122            // if ( deleteFiles ) {
123            // for ( int i = 0; i < fileNames.length; i++ ) {
124            // file = new File( fileNames[i] );
125            //
126            // LOG.logInfo( fileNames[i] + " deleted: " + file.delete() );
127            // }
128            // }
129            //
130            // zout.close();
131            //
132            // return archive;
133        }
134    
135        /**
136         * packs the passed files into a zip-archive, deletes the files if desired and returns the name
137         * of the archive as absolute path
138         *
139         * @param dirName
140         *            name of the directory where the files are found (see fileNames) and where the
141         *            archive will be stored. Needs to be an absolute path.
142         * @param archiveName
143         *            desired name of the archive. It will be stored in the directory given in dirName.
144         * @param fileNames
145         *            names of the files to be packed into the zip archive. The files are expected to be
146         *            in the directory given in dirName.
147         * @param deleteFiles
148         *            if true all files will be deleted after zip-file has been created
149         * @param storeFolderPathInZip
150         *            if true, the files are stored in the zip according to their folder structur (with
151         *            absolute paths); if false, the files are stored under their file name only.
152         * @return the name of the zip file (combined dirName and archiveName)
153         * @throws FileNotFoundException
154         * @throws IOException
155         */
156        public String doZip( String dirName, String archiveName, String[] fileNames, boolean deleteFiles,
157                             boolean storeFolderPathInZip )
158                                throws FileNotFoundException, IOException {
159    
160            byte[] b = new byte[512];
161    
162            // make sure, that directory name ends with a file separator ("/" on Linux, or "\" on
163            // Windows)
164            if ( !dirName.endsWith( "/" ) && !dirName.endsWith( "\\" ) ) {
165                dirName = dirName + File.separator;
166            }
167    
168            File file = new File( archiveName );
169            String archive = archiveName;
170            if ( !file.isAbsolute() ) {
171                archive = dirName + archiveName;
172            }
173            LOG.logDebug( "archive name: " + archive );
174    
175            ZipOutputStream zout = new ZipOutputStream( new FileOutputStream( archive ) );
176            details = new StringBuffer();
177            String[] absFileNames = new String[fileNames.length];
178    
179            for ( int i = 0; i < fileNames.length; i++ ) {
180                file = new File( fileNames[i] );
181                if ( !file.isAbsolute() ) {
182                    absFileNames[i] = dirName + fileNames[i];
183                } else {
184                    absFileNames[i] = fileNames[i];
185                }
186    
187                InputStream in = new FileInputStream( absFileNames[i] );
188                ZipEntry e = null;
189                if ( storeFolderPathInZip ) {
190                    e = new ZipEntry( absFileNames[i] );
191                } else {
192                    e = new ZipEntry( file.getName() );
193                }
194                zout.putNextEntry( e );
195    
196                int len = 0;
197                while ( ( len = in.read( b ) ) != -1 ) {
198                    zout.write( b, 0, len );
199                }
200                in.close();
201                zout.closeEntry();
202                details.append( createZipDetails( e ) + "\n" );
203            }
204    
205            if ( deleteFiles ) {
206                for ( int i = 0; i < absFileNames.length; i++ ) {
207                    file = new File( absFileNames[i] );
208                    LOG.logInfo( absFileNames[i] + " deleted: " + file.delete() );
209                }
210            }
211    
212            zout.close();
213            return archive;
214        }
215    
216        /**
217         * @return details about the zipping
218         */
219        public String getZipDetails() {
220            return details.toString();
221        }
222    
223        /**
224         * returns some information about the zip process of the current <code>ZipEntry</code>.
225         *
226         * @param e
227         * @return information on the zip process
228         */
229        private StringBuffer createZipDetails( ZipEntry e ) {
230    
231            StringBuffer sb = new StringBuffer();
232    
233            sb.append( "added " + e.getName() );
234    
235            if ( e.getMethod() == ZipEntry.DEFLATED ) {
236                long size = e.getSize();
237    
238                if ( size > 0 ) {
239                    long csize = e.getCompressedSize();
240                    long ratio = ( ( size - csize ) * 100 ) / size;
241                    sb.append( " (deflated " + ratio + "%)" );
242                } else {
243                    sb.append( " (deflated 0%)" );
244                }
245            } else {
246                sb.append( " (stored 0%)" );
247            }
248    
249            return sb;
250        }
251    
252        /**
253         * @param file
254         * @param outdir
255         * @throws IOException
256         */
257        public void doUnzip( File file, String outdir )
258                                throws IOException {
259            this.doUnzip( new FileInputStream( file ), outdir );
260        }
261    
262        /**
263         * @param is
264         * @param outdir
265         * @throws IOException
266         */
267        public void doUnzip( InputStream is, String outdir )
268                                throws IOException {
269            int read = 0;
270            byte[] data = new byte[1024];
271            ZipEntry entry;
272            // Archiv öffnen und mit Stream verbinden
273            ZipInputStream in = new ZipInputStream( is );
274            // Alle Einträge des Archivs auslesen
275            while ( ( entry = in.getNextEntry() ) != null ) {
276                if ( entry.getMethod() == ZipEntry.DEFLATED )
277                    System.out.println( "  Inflating: " + entry.getName() );
278                else
279                    System.out.println( " Extracting: " + entry.getName() );
280                // Anlegen der Ausgabedatei für den aktuellen Eintrag
281                FileOutputStream out = new FileOutputStream( outdir + entry.getName() );
282                // Daten des Eintrags aus dem Archiv lesen und in die
283                // Ausgabedatei schreiben
284                while ( ( read = in.read( data, 0, 1024 ) ) != -1 )
285                    out.write( data, 0, read );
286                out.close();
287            }
288            in.close();
289            System.out.println();
290        }
291    
292    }