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