001    /*
002     * $Id: BackgroundUnzipper.java,v 1.4 2012/02/19 17:35:52 davep Exp $
003     *
004     * This file is part of McIDAS-V
005     *
006     * Copyright 2007-2012
007     * Space Science and Engineering Center (SSEC)
008     * University of Wisconsin - Madison
009     * 1225 W. Dayton Street, Madison, WI 53706, USA
010     * https://www.ssec.wisc.edu/mcidas
011     * 
012     * All Rights Reserved
013     * 
014     * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015     * some McIDAS-V source code is based on IDV and VisAD source code.  
016     * 
017     * McIDAS-V is free software; you can redistribute it and/or modify
018     * it under the terms of the GNU Lesser Public License as published by
019     * the Free Software Foundation; either version 3 of the License, or
020     * (at your option) any later version.
021     * 
022     * McIDAS-V is distributed in the hope that it will be useful,
023     * but WITHOUT ANY WARRANTY; without even the implied warranty of
024     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025     * GNU Lesser Public License for more details.
026     * 
027     * You should have received a copy of the GNU Lesser Public License
028     * along with this program.  If not, see http://www.gnu.org/licenses.
029     */
030    package edu.wisc.ssec.mcidasv.util;
031    
032    import java.awt.event.ActionEvent;
033    import java.awt.event.ActionListener;
034    import java.io.BufferedInputStream;
035    import java.io.File;
036    import java.io.FilterInputStream;
037    import java.io.IOException;
038    import java.io.InputStream;
039    import java.net.MalformedURLException;
040    import java.net.URL;
041    import java.net.URLConnection;
042    import java.util.List;
043    import java.util.zip.ZipEntry;
044    import java.util.zip.ZipInputStream;
045    
046    import javax.swing.SwingWorker;
047    import javax.swing.Timer;
048    
049    public class BackgroundUnzipper extends SwingWorker<Long, Long>{
050    
051        private final String zipFile;
052        private CountingInputStream countingStream;
053        private ZipInputStream zipStream;
054    
055        private long totalSize = 1;
056        
057        private String currentEntry;
058    
059        private final ActionListener taskPerformer = new ActionListener() {
060            public void actionPerformed(final ActionEvent e) {
061                getPercentage();
062            }
063        };
064    
065        private final Timer taskTimer = new Timer(250, taskPerformer);
066        
067        public BackgroundUnzipper(final String zipFile) {
068            this.zipFile = zipFile;
069        }
070    
071        public Long getCurrentBytes() {
072            return countingStream.getTotalBytesRead();
073        }
074    
075        public String getCurrentEntry() {
076            return currentEntry;
077        }
078        
079        public long getPercentage() {
080            double current = new Double(countingStream.getTotalBytesRead()).doubleValue();
081            double total = new Double(totalSize).doubleValue();
082            long val = Math.round((current / total) * 100);
083            setProgress(new Long(val).intValue());
084            return val;
085        }
086        
087        protected Long doInBackground() throws Exception {
088            
089            countingStream = new CountingInputStream(getInputStream(zipFile));
090            zipStream = new ZipInputStream(countingStream);
091            totalSize = new File(zipFile).length();
092            taskTimer.start();
093            ZipEntry entry = null;
094            while (!isCancelled() && ((entry = zipStream.getNextEntry()) != null)) {
095                publish(countingStream.getTotalBytesRead());
096                System.err.println("entry="+entry.getName());
097                currentEntry = entry.getName();
098                zipStream.closeEntry();
099            }
100            zipStream.close();
101            countingStream.close();
102            taskTimer.stop();
103            return countingStream.getTotalBytesRead();
104        }
105    
106        protected void process(List<Long> durr) {
107            System.err.println("read "+countingStream.getTotalBytesRead()+" bytes so far...");
108        }
109    
110        private InputStream getInputStream(final String path) {
111            File f = new File(path.trim());
112            if (!f.exists()) {
113               return null;
114            }
115    
116            try {
117                URL url = f.toURI().toURL();
118                URLConnection connection = url.openConnection();
119                return new BufferedInputStream(connection.getInputStream());
120            } catch (MalformedURLException e) {
121                // TODO Auto-generated catch block
122                e.printStackTrace();
123            } catch (IOException e) {
124                e.printStackTrace();
125            }
126            return null;
127        }
128    
129        public static class CountingInputStream extends FilterInputStream {
130    
131            private long totalBytes = 0;
132    
133            protected CountingInputStream(final InputStream in) {
134                super(in);
135            }
136    
137            public long getTotalBytesRead() {
138                return totalBytes;
139            }
140    
141            @Override public int read() throws IOException {
142                int byteValue = super.read();
143                if (byteValue != -1) totalBytes++;
144                return byteValue;
145            }
146    
147            @Override public int read(byte[] b) throws IOException {
148                int bytesRead = super.read(b);
149                if (bytesRead != -1)
150                    totalBytes += bytesRead;
151                return bytesRead;
152            }
153    
154            @Override public int read(byte[] b, int off, int len) throws IOException {
155                int bytesRead = super.read(b,off,len);
156                if (bytesRead != -1)
157                    totalBytes += bytesRead;
158                return bytesRead;
159            }
160        }
161    
162    }