EMMA Coverage Report (generated Sat Oct 08 11:41:37 CEST 2011)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [ExtractZipTask.java]

nameclass, %method, %block, %line, %
ExtractZipTask.java100% (1/1)100% (4/4)65%  (206/317)77%  (52.3/68)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ExtractZipTask100% (1/1)100% (4/4)65%  (206/317)77%  (52.3/68)
start (): void 100% (1/1)53%  (101/192)64%  (23.8/37)
extractStreamTo (InputStream, File): void 100% (1/1)78%  (69/89)88%  (18.5/21)
ExtractZipTask (): void 100% (1/1)100% (20/20)100% (5/5)
ExtractZipTask (File, File): void 100% (1/1)100% (16/16)100% (5/5)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2011 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.tools;
17 
18import java.io.BufferedInputStream;
19import java.io.BufferedOutputStream;
20import java.io.File;
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.InputStream;
24import java.util.Enumeration;
25import java.util.Iterator;
26import java.util.LinkedList;
27import java.util.List;
28 
29import org.apache.commons.logging.Log;
30import org.apache.commons.logging.LogFactory;
31import org.apache.tools.zip.ZipEntry;
32import org.apache.tools.zip.ZipFile;
33 
34/**
35 *  Task to extract contents of a ZIP file to a target folder.
36 *
37 * @author    Thomas Aglassinger
38 */
39public class ExtractZipTask extends AbstractTask
40{
41    private static final int BUFFER_SIZE = 4096;
42    private FileTools fileTools;
43    private List filesExtracted;
44    private LocaleTools localeTools;
45    private Log logger;
46    private File sourceZipFile;
47    private File targetDir;
48 
49    /**
50     *  Create a new task to extract <code>newSourceZipFile</code> to <code>newTargetFolder</code>.
51     *
52     * @param  newSourceZipFile  Description of the parameter
53     * @param  newTargetFolder   Description of the parameter
54     */
55    public ExtractZipTask(File newSourceZipFile, File newTargetFolder) {
56        this();
57        sourceZipFile = newSourceZipFile;
58        targetDir = newTargetFolder;
59        setMaxProgress(sourceZipFile.length() + 1);
60    }
61 
62    private ExtractZipTask() {
63        super();
64        logger = LogFactory.getLog(ExtractZipTask.class);
65        fileTools = FileTools.instance();
66        localeTools = LocaleTools.instance();
67    }
68 
69    public void start()
70        throws Exception {
71        ZipFile zipFile = new ZipFile(sourceZipFile);
72        boolean allFilesExtracted = false;
73 
74        filesExtracted = new LinkedList();
75 
76        try {
77            Enumeration zipEntries = zipFile.getEntries();
78 
79            setProgress(0);
80            while (!isInterrupted() && zipEntries.hasMoreElements()) {
81                ZipEntry entry = (ZipEntry) zipEntries.nextElement();
82                String name = entry.getName();
83 
84                if (!entry.isDirectory()) {
85                    File targetFile = new File(targetDir, name);
86                    File targetParent = targetFile.getParentFile();
87 
88                    fileTools.mkdirs(targetParent);
89                    if (logger.isInfoEnabled()) {
90                        logger.info("extract \"" + name + "\" to \"" + targetFile.getAbsolutePath()
91                                + "\"");
92                    }
93                    InputStream in = zipFile.getInputStream(entry);
94 
95                    if (in == null) {
96                        // At least turn Sun bug 4244499 in a clear error
97                        // message.
98                        String message = localeTools.getMessage(
99                                "errors.nonAsciiCharactersMustBeRemoved", name);
100 
101                        throw new IOException(message);
102                    }
103                    extractStreamTo(in, targetFile);
104                } else {
105                    if (logger.isDebugEnabled()) {
106                        logger.debug("ignore \"" + name + "\"");
107                    }
108                }
109            }
110            allFilesExtracted = !isInterrupted();
111            if (allFilesExtracted) {
112                setProgress(getMaxProgress());
113            }
114        } finally {
115            zipFile.close();
116            if (!allFilesExtracted) {
117                if (logger.isInfoEnabled()) {
118                    logger.info("removing files extracted so far");
119                }
120                Iterator fileRider = filesExtracted.iterator();
121 
122                // TODO: Also remove folder structure generated by extracted files.
123                while (fileRider.hasNext()) {
124                    File fileToDelete = (File) fileRider.next();
125 
126                    fileTools.deleteOrWarn(fileToDelete, logger);
127                }
128            }
129        }
130    }
131 
132    private void extractStreamTo(InputStream in, File targetFile)
133        throws IOException {
134        try {
135            BufferedInputStream inBuffered = new BufferedInputStream(in);
136 
137            try {
138                FileOutputStream out = new FileOutputStream(targetFile);
139 
140                try {
141                    byte[] data = new byte[BUFFER_SIZE];
142                    BufferedOutputStream outBuffered = new BufferedOutputStream(out, BUFFER_SIZE);
143 
144                    filesExtracted.add(targetFile);
145                    try {
146                        boolean continueReading = true;
147                        int bytesRead;
148 
149                        while (continueReading) {
150                            bytesRead = inBuffered.read(data);
151                            continueReading = !isInterrupted() && (bytesRead > 0);
152                            if (continueReading) {
153                                outBuffered.write(data, 0, bytesRead);
154                                setProgress(getProgress() + bytesRead);
155                            }
156                        }
157                    } finally {
158                        outBuffered.close();
159                    }
160                } finally {
161                    out.close();
162                }
163            } finally {
164                inBuffered.close();
165            }
166        } finally {
167            in.close();
168        }
169    }
170}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov