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 java.io.IOException;
020 import java.io.InputStream;
021 import java.net.URL;
022 import java.util.Arrays;
023 import java.util.Iterator;
024 import java.util.LinkedHashMap;
025 import java.util.LinkedHashSet;
026 import java.util.Map;
027 import java.util.Set;
028
029 /**
030 * @version $Rev$ $Date$
031 */
032 public class ClassesArchive implements Archive {
033
034 private final Set<ClassLoader> loaders = new LinkedHashSet<ClassLoader>();
035 private final Map<String, Class<?>> classes = new LinkedHashMap<String, Class<?>>();
036
037 public ClassesArchive(Class<?>... classes) {
038 this(Arrays.asList(classes));
039 }
040
041 public ClassesArchive(Iterable<Class<?>> classes) {
042 assert classes != null;
043
044 for (Class<?> clazz : classes) {
045 if (clazz == null) continue;
046 if (clazz.getClassLoader() == null) continue;
047 this.classes.put(clazz.getName(), clazz);
048 loaders.add(clazz.getClassLoader());
049 }
050 }
051
052 @Override
053 public Iterator<String> iterator() {
054 return classes.keySet().iterator();
055 }
056
057 @Override
058 public InputStream getBytecode(String className) throws IOException, ClassNotFoundException {
059 assert className != null;
060
061 int pos = className.indexOf("<");
062 if (pos > -1) {
063 className = className.substring(0, pos);
064 }
065 pos = className.indexOf(">");
066 if (pos > -1) {
067 className = className.substring(0, pos);
068 }
069 if (!className.endsWith(".class")) {
070 className = className.replace('.', '/') + ".class";
071 }
072 for (ClassLoader loader : loaders) {
073 URL resource = loader.getResource(className);
074 if (resource != null) return resource.openStream();
075 }
076
077 throw new ClassNotFoundException(className);
078 }
079
080 @Override
081 public Class<?> loadClass(String className) throws ClassNotFoundException {
082 Class<?> clazz = classes.get(className);
083 if (clazz != null) return clazz;
084
085 for (ClassLoader loader : loaders) {
086 try {
087 return loader.loadClass(className);
088 } catch (ClassNotFoundException e) {
089 }
090 }
091
092 throw new ClassNotFoundException(className);
093 }
094 }