001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.osgi.util;
013
014import java.io.File;
015import java.io.FileFilter;
016import java.net.MalformedURLException;
017import java.net.URL;
018import java.util.Enumeration;
019import java.util.Iterator;
020import java.util.LinkedList;
021import java.util.NoSuchElementException;
022import java.util.Queue;
023
024/**
025 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
026 */
027public class FileIterator implements Iterator<File>, Enumeration<File> {
028
029    protected FileFilter filter;
030
031    protected Queue<File> files;
032
033    protected File file;
034
035    protected boolean skipDirs = false;
036
037    public static Iterator<URL> asUrlIterator(final Iterator<File> it) {
038        return new Iterator<URL>() {
039            @Override
040            public boolean hasNext() {
041                return it.hasNext();
042            }
043
044            @Override
045            public URL next() {
046                try {
047                    return it.next().toURI().toURL();
048                } catch (MalformedURLException e) {
049                    throw new RuntimeException(e);
050                }
051            }
052
053            @Override
054            public void remove() {
055                it.remove();
056            }
057        };
058    }
059
060    public static Enumeration<URL> asUrlEnumeration(final Iterator<File> it) {
061        return new Enumeration<URL>() {
062            @Override
063            public boolean hasMoreElements() {
064                return it.hasNext();
065            }
066
067            @Override
068            public URL nextElement() {
069                try {
070                    return it.next().toURI().toURL();
071                } catch (MalformedURLException e) {
072                    throw new RuntimeException(e);
073                }
074            }
075        };
076    }
077
078    public FileIterator(File file) {
079        this(file, null);
080    }
081
082    public FileIterator(File file, FileFilter filter) {
083        this.files = new LinkedList<File>();
084        this.filter = filter;
085        feed(file);
086    }
087
088    public void setSkipDirs(boolean skipDirs) {
089        this.skipDirs = skipDirs;
090    }
091
092    public boolean getSkipDirs() {
093        return skipDirs;
094    }
095
096    @Override
097    public boolean hasNext() {
098        if (file != null) {
099            return true;
100        }
101        file = files.poll();
102        if (file == null) {
103            return false;
104        }
105        if (skipDirs) { // feed and get next file
106            while (file != null && file.isDirectory()) {
107                feed(file);
108                file = files.poll();
109            }
110        } else {
111            feed(file);
112        }
113        return file != null;
114    }
115
116    @Override
117    public File next() {
118        if (file == null) {
119            hasNext();
120            if (file == null) {
121                throw new NoSuchElementException();
122            }
123        }
124        File f = file;
125        file = null;
126        return f;
127    }
128
129    @Override
130    public void remove() {
131        throw new UnsupportedOperationException("remove ot supported");
132    }
133
134    /**
135     * Feed the iterator with the given directory content if any
136     *
137     * @param file
138     */
139    public void feed(File file) {
140        File[] content = file.listFiles(filter);
141        if (content != null) {
142            for (File f : content) {
143                files.add(f);
144            }
145        }
146    }
147
148    /** Enumeration API */
149
150    @Override
151    public boolean hasMoreElements() {
152        return hasNext();
153    }
154
155    @Override
156    public File nextElement() {
157        return next();
158    }
159
160}