001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2024
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 https://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
047import org.slf4j.Logger;
048import org.slf4j.LoggerFactory;
049
050public class BackgroundUnzipper extends SwingWorker<Long, Long>{
051    
052    private static final Logger logger =
053        LoggerFactory.getLogger(BackgroundUnzipper.class);
054    
055    private final String zipFile;
056    private CountingInputStream countingStream;
057    private ZipInputStream zipStream;
058
059    private long totalSize = 1;
060    
061    private String currentEntry;
062
063    private final ActionListener taskPerformer = new ActionListener() {
064        public void actionPerformed(final ActionEvent e) {
065            getPercentage();
066        }
067    };
068
069    private final Timer taskTimer = new Timer(250, taskPerformer);
070    
071    public BackgroundUnzipper(final String zipFile) {
072        this.zipFile = zipFile;
073    }
074
075    public Long getCurrentBytes() {
076        return countingStream.getTotalBytesRead();
077    }
078
079    public String getCurrentEntry() {
080        return currentEntry;
081    }
082    
083    public long getPercentage() {
084        double current = new Double(countingStream.getTotalBytesRead()).doubleValue();
085        double total = new Double(totalSize).doubleValue();
086        long val = Math.round((current / total) * 100);
087        setProgress(new Long(val).intValue());
088        return val;
089    }
090    
091    protected Long doInBackground() throws Exception {
092        
093        countingStream = new CountingInputStream(getInputStream(zipFile));
094        zipStream = new ZipInputStream(countingStream);
095        totalSize = new File(zipFile).length();
096        taskTimer.start();
097        ZipEntry entry = null;
098        while (!isCancelled() && ((entry = zipStream.getNextEntry()) != null)) {
099            publish(countingStream.getTotalBytesRead());
100            System.err.println("entry="+entry.getName());
101            currentEntry = entry.getName();
102            zipStream.closeEntry();
103        }
104        zipStream.close();
105        countingStream.close();
106        taskTimer.stop();
107        return countingStream.getTotalBytesRead();
108    }
109
110    protected void process(List<Long> durr) {
111        System.err.println("read "+countingStream.getTotalBytesRead()+" bytes so far...");
112    }
113
114    private InputStream getInputStream(final String path) {
115        File f = new File(path.trim());
116        if (!f.exists()) {
117           return null;
118        }
119
120        try {
121            URL url = f.toURI().toURL();
122            URLConnection connection = url.openConnection();
123            return new BufferedInputStream(connection.getInputStream());
124        } catch (IOException e) {
125            logger.error("Problem creating InputStream", e);
126        }
127        return null;
128    }
129
130    public static class CountingInputStream extends FilterInputStream {
131
132        private long totalBytes = 0;
133
134        protected CountingInputStream(final InputStream in) {
135            super(in);
136        }
137
138        public long getTotalBytesRead() {
139            return totalBytes;
140        }
141
142        @Override public int read() throws IOException {
143            int byteValue = super.read();
144            if (byteValue != -1) totalBytes++;
145            return byteValue;
146        }
147
148        @Override public int read(byte[] b) throws IOException {
149            int bytesRead = super.read(b);
150            if (bytesRead != -1)
151                totalBytes += bytesRead;
152            return bytesRead;
153        }
154
155        @Override public int read(byte[] b, int off, int len) throws IOException {
156            int bytesRead = super.read(b,off,len);
157            if (bytesRead != -1)
158                totalBytes += bytesRead;
159            return bytesRead;
160        }
161    }
162
163}