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     */
017    package org.apache.xbean.finder.archive;
018    
019    import org.apache.xbean.finder.filter.Filter;
020    
021    import java.io.IOException;
022    import java.io.InputStream;
023    import java.util.Iterator;
024    import java.util.NoSuchElementException;
025    
026    /**
027     * @version $Rev$ $Date$
028     */
029    public 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        @Override
041        public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
042            return archive.getBytecode(className);
043        }
044    
045        @Override
046        public Class<?> loadClass(String className) throws ClassNotFoundException {
047            return archive.loadClass(className);
048        }
049    
050        @Override
051        public Iterator<String> iterator() {
052            return new FilteredIterator(archive.iterator());
053        }
054    
055        private final class FilteredIterator implements Iterator<String> {
056            private final Iterator<String> it;
057    
058            private String next;
059    
060            private FilteredIterator(Iterator<String> it) {
061                this.it = it;
062            }
063    
064            @Override
065            public boolean hasNext() {
066                if (next != null) return true;
067                if (!it.hasNext()) return false;
068                seek();
069                return hasNext();
070            }
071    
072            @Override
073            public String next() {
074                if (!hasNext()) throw new NoSuchElementException();
075    
076                String s = next;
077                next = null;
078    
079                return s;
080            }
081    
082            @Override
083            public void remove() {
084                it.remove();
085            }
086    
087            private void seek() {
088                while (next == null && it.hasNext()) {
089    
090                    next = it.next();
091    
092                    if (filter.accept(next)) return;
093    
094                    next = null;
095                }
096            }
097    
098        }
099    }