001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 * 
016 * Contributors:
017 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.common.utils;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026
027import java.io.File;
028import java.io.FileInputStream;
029import java.io.IOException;
030import java.io.InputStream;
031import java.net.URL;
032import java.util.Iterator;
033import java.util.zip.ZipEntry;
034import java.util.zip.ZipInputStream;
035
036/**
037 * An iterator over the entries in a ZIP file.
038 * <p>
039 * The iterator support filtering using {@link ZipEntryFilter}
040 *
041 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
042 */
043public class ZipIterator implements Iterator<ZipEntry> {
044
045    private static final Log log = LogFactory.getLog(ZipIterator.class);
046
047    private final ZipInputStream zin;
048
049    private final ZipEntryFilter filter;
050
051    private ZipEntry zentry;
052
053    public ZipIterator(ZipInputStream zin, ZipEntryFilter filter) throws IOException {
054        this.zin = zin;
055        this.filter = filter;
056        zentry = zin.getNextEntry();
057    }
058
059    public ZipIterator(URL url) throws IOException {
060        this(url.openStream(), null);
061    }
062
063    public ZipIterator(URL url, ZipEntryFilter filter) throws IOException {
064        this(url.openStream(), filter);
065    }
066
067    public ZipIterator(File file) throws IOException {
068        this(new FileInputStream(file), null);
069    }
070
071    public ZipIterator(File file, ZipEntryFilter filter) throws IOException {
072        this(new FileInputStream(file), filter);
073    }
074
075    public ZipIterator(InputStream in) throws IOException {
076        this(new ZipInputStream(in), null);
077    }
078
079    public ZipIterator(InputStream in, ZipEntryFilter filter) throws IOException {
080        this(new ZipInputStream(in), filter);
081    }
082
083    public ZipEntry getNextEntry() throws IOException {
084        ZipEntry ze = zin.getNextEntry();
085        if (ze == null) {
086            return null;
087        }
088        if (filter != null) {
089            while (!filter.accept(ze.getName())) {
090                ze = zin.getNextEntry();
091                if (ze == null) {
092                    return null;
093                }
094            }
095        }
096        return ze;
097    }
098
099    public void remove() {
100        throw new UnsupportedOperationException("remove is not supported by this iterator");
101    }
102
103    public boolean hasNext() {
104        return zentry != null;
105    }
106
107    public ZipEntry next() {
108        ZipEntry oldEntry = zentry;
109        try {
110            zentry = getNextEntry();
111        } catch (IOException e) {
112            log.error(e);
113            zentry = null;
114        }
115        return oldEntry;
116    }
117
118    public InputStream getInputStream() {
119        return zin;
120    }
121
122    public void close() {
123        if (zin != null) {
124            try {
125                zin.close();
126            } catch (IOException e) {
127                log.error(e);
128            }
129        }
130    }
131
132}