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.bcel.util; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.util.HashMap; 022import java.util.Map; 023 024import org.apache.bcel.classfile.ClassParser; 025import org.apache.bcel.classfile.JavaClass; 026import org.apache.bcel.classfile.Utility; 027 028/** 029 * The repository maintains information about which classes have been loaded. 030 * 031 * It loads its data from the ClassLoader implementation passed into its constructor. 032 * 033 * @see org.apache.bcel.Repository 034 */ 035public class ClassLoaderRepository implements Repository { 036 037 private final java.lang.ClassLoader loader; 038 private final Map<String, JavaClass> loadedClasses = new HashMap<>(); // CLASSNAME X JAVACLASS 039 040 public ClassLoaderRepository(final java.lang.ClassLoader loader) { 041 this.loader = loader; 042 } 043 044 /** 045 * Clear all entries from cache. 046 */ 047 @Override 048 public void clear() { 049 loadedClasses.clear(); 050 } 051 052 /** 053 * Find an already defined JavaClass. 054 */ 055 @Override 056 public JavaClass findClass(final String className) { 057 return loadedClasses.get(className); 058 } 059 060 /* 061 * @return null 062 */ 063 @Override 064 public ClassPath getClassPath() { 065 return null; 066 } 067 068 @Override 069 public JavaClass loadClass(final Class<?> clazz) throws ClassNotFoundException { 070 return loadClass(clazz.getName()); 071 } 072 073 /** 074 * Lookup a JavaClass object from the Class Name provided. 075 */ 076 @Override 077 public JavaClass loadClass(final String className) throws ClassNotFoundException { 078 final String classFile = Utility.packageToPath(className); 079 JavaClass RC = findClass(className); 080 if (RC != null) { 081 return RC; 082 } 083 try (InputStream is = loader.getResourceAsStream(classFile + JavaClass.EXTENSION)) { 084 if (is == null) { 085 throw new ClassNotFoundException(className + " not found."); 086 } 087 final ClassParser parser = new ClassParser(is, className); 088 RC = parser.parse(); 089 storeClass(RC); 090 return RC; 091 } catch (final IOException e) { 092 throw new ClassNotFoundException(className + " not found: " + e, e); 093 } 094 } 095 096 /** 097 * Remove class from repository 098 */ 099 @Override 100 public void removeClass(final JavaClass clazz) { 101 loadedClasses.remove(clazz.getClassName()); 102 } 103 104 /** 105 * Store a new JavaClass into this Repository. 106 */ 107 @Override 108 public void storeClass(final JavaClass clazz) { 109 loadedClasses.put(clazz.getClassName(), clazz); 110 clazz.setRepository(this); 111 } 112}