001/*
002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
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.IOException;
029import java.util.Enumeration;
030import java.util.Iterator;
031import java.util.NoSuchElementException;
032import java.util.zip.ZipEntry;
033import java.util.zip.ZipFile;
034
035/**
036 * An iterator over the entries in a zip file.
037 * <p>
038 * The iterator support filtering using {@link ZipEntryFilter}
039 *
040 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
041 */
042public class ZipFileIterator implements Iterator<ZipEntry> {
043
044    private static final Log log = LogFactory.getLog(ZipFileIterator.class);
045
046    private final ZipFile zip;
047
048    private final ZipEntryFilter filter;
049
050    private final Enumeration<? extends ZipEntry> entries;
051
052    // the current entry
053    private ZipEntry zentry;
054
055    public ZipFileIterator(ZipFile zip, ZipEntryFilter filter) {
056        this.zip = zip;
057        this.filter = filter;
058        entries = zip.entries();
059        initNextEntry();
060    }
061
062    public ZipFileIterator(File file) throws IOException {
063        this(new ZipFile(file), null);
064    }
065
066    public ZipFileIterator(File file, ZipEntryFilter filter) throws IOException {
067        this(new ZipFile(file), filter);
068    }
069
070    public ZipFileIterator(ZipFile zip) {
071        this(zip, null);
072    }
073
074    public boolean hasNext() {
075        return zentry != null;
076    }
077
078    public ZipEntry next() {
079        if (zentry == null) {
080            throw new NoSuchElementException("There no more elements to iterate over");
081        }
082        ZipEntry ze = zentry; // the current entry to return
083        initNextEntry();
084        return ze;
085    }
086
087    private void initNextEntry() {
088        // get next entry
089        if (entries.hasMoreElements()) {
090            zentry = entries.nextElement();
091        } else {
092            zentry = null;
093            return;
094        }
095        // do filtering if needed
096        if (filter != null) {
097            while (!filter.accept(zentry.getName())) {
098                if (entries.hasMoreElements()) {
099                    zentry = entries.nextElement();
100                } else {
101                    zentry = null;
102                    break;
103                }
104            }
105        }
106    }
107
108    public void remove() {
109        throw new UnsupportedOperationException("remove is not supported by this iterator");
110    }
111
112    public ZipFile getZipFile() {
113        return zip;
114    }
115
116    public void close() {
117        if (zip != null) {
118            try {
119                zip.close();
120            } catch (IOException e) {
121                log.error(e);
122            }
123        }
124    }
125
126}