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 java.io.IOException; 020import java.io.InputStream; 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Iterator; 024import java.util.List; 025import java.util.NoSuchElementException; 026 027/** 028 * @version $Rev$ $Date$ 029 */ 030public class CompositeArchive implements Archive { 031 032 private final List<Archive> archives = new ArrayList<Archive>(); 033 034 public CompositeArchive(Archive... archives) { 035 this(Arrays.asList(archives)); 036 } 037 038 public CompositeArchive(Iterable<Archive> archives) { 039 for (Archive archive : archives) { 040 this.archives.add(archive); 041 } 042 } 043 044 public InputStream getBytecode(String className) throws IOException, ClassNotFoundException { 045 for (Archive archive : archives) { 046 try { 047 return archive.getBytecode(className); 048 } catch (ClassNotFoundException e) { 049 } 050 } 051 052 throw new ClassNotFoundException(className); 053 } 054 055 public Class<?> loadClass(String className) throws ClassNotFoundException { 056 for (Archive archive : archives) { 057 try { 058 return archive.loadClass(className); 059 } catch (ClassNotFoundException e) { 060 } 061 } 062 063 throw new ClassNotFoundException(className); 064 } 065 066 public Iterator<Entry> iterator() { 067 if (archives.size() == 1) return archives.get(0).iterator(); 068 return new CompositeIterator(archives); 069 } 070 071 private static class CompositeIterator implements Iterator<Entry> { 072 073 private Iterator<Archive> archives; 074 private Iterator<Entry> current; 075 076 private CompositeIterator(Iterable<Archive> archives) { 077 this.archives = archives.iterator(); 078 if (this.archives.hasNext()) { 079 current = this.archives.next().iterator(); 080 } 081 } 082 083 public boolean hasNext() { 084 if (current == null) return false; 085 if (current.hasNext()) return true; 086 087 if (archives.hasNext()) { 088 current = archives.next().iterator(); 089 return hasNext(); 090 } 091 return false; 092 } 093 094 public Entry next() { 095 if (!hasNext()) throw new NoSuchElementException(); 096 097 return current.next(); 098 } 099 100 public void remove() { 101 throw new UnsupportedOperationException(); 102 } 103 } 104}