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