/* * Copyright 2002-2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.core; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.springframework.util.Assert; /** * Base class for decorating ClassLoaders such as {@link OverridingClassLoader} * and {@link org.springframework.instrument.classloading.ShadowingClassLoader}, * providing common handling of excluded packages and classes. * * @author Juergen Hoeller * @author Rod Johnson * @since 2.5.2 */ public abstract class DecoratingClassLoader extends ClassLoader { private final Set excludedPackages = new HashSet(); private final Set excludedClasses = new HashSet(); private final Object exclusionMonitor = new Object(); /** * Create a new DecoratingClassLoader with no parent ClassLoader. */ public DecoratingClassLoader() { } /** * Create a new DecoratingClassLoader using the given parent ClassLoader * for delegation. */ public DecoratingClassLoader(ClassLoader parent) { super(parent); } /** * Add a package name to exclude from decoration (e.g. overriding). * <p>Any class whose fully-qualified name starts with the name registered * here will be handled by the parent ClassLoader in the usual fashion. * @param packageName the package name to exclude */ public void excludePackage(String packageName) { Assert.notNull(packageName, "Package name must not be null"); synchronized (this.exclusionMonitor) { this.excludedPackages.add(packageName); } } /** * Add a class name to exclude from decoration (e.g. overriding). * <p>Any class name registered here will be handled by the parent * ClassLoader in the usual fashion. * @param className the class name to exclude */ public void excludeClass(String className) { Assert.notNull(className, "Class name must not be null"); synchronized (this.exclusionMonitor) { this.excludedClasses.add(className); } } /** * Determine whether the specified class is excluded from decoration * by this class loader. * <p>The default implementation checks against excluded packages and classes. * @param className the class name to check * @return whether the specified class is eligible * @see #excludePackage * @see #excludeClass */ protected boolean isExcluded(String className) { synchronized (this.exclusionMonitor) { if (this.excludedClasses.contains(className)) { return true; } for (Iterator it = this.excludedPackages.iterator(); it.hasNext();) { String packageName = (String) it.next(); if (className.startsWith(packageName)) { return true; } } } return false; } }