create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / file / iterator / ZipDirectoryIterator.java
1 package net.sf.openrocket.file.iterator;
2
3 import java.io.File;
4 import java.io.FileFilter;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.util.Enumeration;
8 import java.util.zip.ZipEntry;
9 import java.util.zip.ZipFile;
10
11 import net.sf.openrocket.logging.LogHelper;
12 import net.sf.openrocket.startup.Application;
13 import net.sf.openrocket.util.Pair;
14
15 /**
16  * A DirectoryIterator that reads files from the specified directory of a
17  * ZIP (or JAR) file.
18  * 
19  * TODO: MEDIUM: This is always a recursive search.
20  * 
21  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
22  */
23 public class ZipDirectoryIterator extends FileIterator {
24         
25         private static final LogHelper logger = Application.getLogger();
26
27         private final File zipFileName;
28         private final String directory;
29         private final FileFilter filter;
30         
31         private ZipFile zipFile;
32         private Enumeration<? extends ZipEntry> entries;
33         
34         
35         /**
36          * Sole constructor.
37          * 
38          * @param zipFileName   the ZIP file to read.
39          * @param directory             the directory within the ZIP file to read, relative to the
40          *                                              base (an empty string corresponds to the root directory)
41          * @param filter                the filter for accepted files.
42          * @throws IOException  if the ZIP file could not be read.
43          */
44         public ZipDirectoryIterator(File zipFileName, String directory, FileFilter filter) 
45                         throws IOException {
46
47                 // Process directory and extension
48                 if (!directory.endsWith("/")) {
49                         directory += "/";
50                 }
51                 
52                 this.zipFileName = zipFileName;
53                 this.directory = directory;
54                 this.filter = filter;
55
56                 
57                 // Loop through ZIP entries searching for files to load
58                 this.zipFile = new ZipFile(zipFileName);
59                 entries = zipFile.entries();
60
61         }
62         
63
64         @Override
65         public void close() {
66                 super.close();
67                 if (zipFile != null) {
68                         try {
69                                 zipFile.close();
70                         } catch (IOException e) {
71                                 logger.error("Closing ZIP file failed", e);
72                         }
73                         zipFile = null;
74                         entries = null;
75                 }
76         }
77         
78         
79         @Override
80         protected Pair<String, InputStream> findNext() {
81                 if (entries == null) {
82                         return null;
83                 }
84
85                 while (entries.hasMoreElements()) {
86                         ZipEntry entry = entries.nextElement();
87                         String name = entry.getName();
88                         File file = new File(name);
89                         if (name.startsWith(directory) && filter.accept(file)) {
90                                 try {
91                                         InputStream is = zipFile.getInputStream(entry);
92                                         return new Pair<String, InputStream>(name, is);
93                                 } catch (IOException e) {
94                                         logger.error("IOException when reading ZIP file " + zipFileName, e);
95                                 }
96                         }
97                 }
98                 
99                 return null;
100         }
101
102
103 }