001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 *  Unless required by applicable law or agreed to in writing, software
012 *  distributed under the License is distributed on an "AS IS" BASIS,
013 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 *  See the License for the specific language governing permissions and
015 *  limitations under the License.
016 */
017package org.apache.xbean.finder.archive;
018
019import org.apache.xbean.finder.filter.Filter;
020
021import java.io.IOException;
022import java.io.InputStream;
023import java.util.Iterator;
024import java.util.NoSuchElementException;
025
026/**
027 * @version $Rev$ $Date$
028 */
029public class FilteredArchive implements Archive {
030
031    private final Archive archive;
032
033    private final Filter filter;
034
035    public FilteredArchive(Archive archive, Filter filter) {
036        this.archive = archive;
037        this.filter = filter;
038    }
039
040    public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
041        return archive.getBytecode(className);
042    }
043
044    public Class<?> loadClass(String className) throws ClassNotFoundException {
045        return archive.loadClass(className);
046    }
047
048    public Iterator<Entry> iterator() {
049        return new FilteredIterator(archive.iterator());
050    }
051
052    private final class FilteredIterator implements Iterator<Entry> {
053        private final Iterator<Entry> it;
054
055        private Entry next;
056
057        private FilteredIterator(Iterator<Entry> it) {
058            this.it = it;
059        }
060
061        public boolean hasNext() {
062            if (next != null) return true;
063            if (!it.hasNext()) return false;
064            seek();
065            return hasNext();
066        }
067
068        public Entry next() {
069            if (!hasNext()) throw new NoSuchElementException();
070
071            Entry s = next;
072            next = null;
073
074            return s;
075        }
076
077        public void remove() {
078            it.remove();
079        }
080
081        private void seek() {
082            while (next == null && it.hasNext()) {
083
084                next = it.next();
085
086                if (filter.accept(next.getName())) return;
087
088                next = null;
089            }
090        }
091
092    }
093}