Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* This file is part of ClassGraph.
*
* Author: Luke Hutchison
*
* Hosted at: https://github.com/classgraph/classgraph
*
* --
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Luke Hutchison
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
* EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
* OR OTHER DEALINGS IN THE SOFTWARE.
*/
package nonapi.com.hazelcast.io.github.classgraph.classpath;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.hazelcast.io.github.classgraph.ClassGraph;
import nonapi.com.hazelcast.io.github.classgraph.classloaderhandler.ClassLoaderHandler;
import nonapi.com.hazelcast.io.github.classgraph.classloaderhandler.ClassLoaderHandlerRegistry;
import nonapi.com.hazelcast.io.github.classgraph.classloaderhandler.ClassLoaderHandlerRegistry.ClassLoaderHandlerRegistryEntry;
import nonapi.com.hazelcast.io.github.classgraph.utils.LogNode;
/** A class to find all unique classloaders. */
public class ClassLoaderOrder {
/** The {@link ClassLoader} order. */
private final List> classLoaderOrder = new ArrayList<>();
/**
* The set of all {@link ClassLoader} instances that have been added to the order so far, so that classloaders
* don't get added twice.
*/
// Need to use IdentityHashMap for maps and sets here, because TomEE weirdly makes instances of
// CxfContainerClassLoader equal to (via .equals()) the instance of TomEEWebappClassLoader that it
// delegates to (#515)
private final Set added = Collections.newSetFromMap(new IdentityHashMap());
/**
* The set of all {@link ClassLoader} instances that have been delegated to so far, to prevent an infinite loop
* in delegation.
*/
private final Set delegatedTo = Collections
.newSetFromMap(new IdentityHashMap());
/**
* The set of all parent {@link ClassLoader} instances that have been delegated to so far, to enable
* {@link ClassGraph#ignoreParentClassLoaders()}.
*/
private final Set allParentClassLoaders = Collections
.newSetFromMap(new IdentityHashMap());
/** A map from {@link ClassLoader} to {@link ClassLoaderHandlerRegistryEntry}. */
private final Map classLoaderToClassLoaderHandlerRegistryEntry = //
new IdentityHashMap<>();
// -------------------------------------------------------------------------------------------------------------
/**
* Get the {@link ClassLoader} order.
*
* @return the {@link ClassLoader} order, as a pair: {@link ClassLoader},
* {@link ClassLoaderHandlerRegistryEntry}.
*/
public List> getClassLoaderOrder() {
return classLoaderOrder;
}
/**
* Get the all parent classloaders.
*
* @return all parent classloaders
*/
public Set getAllParentClassLoaders() {
return allParentClassLoaders;
}
/**
* Find the {@link ClassLoaderHandler} that can handle a given {@link ClassLoader} instance.
*
* @param classLoader
* the {@link ClassLoader}.
* @param log
* the log
* @return the {@link ClassLoaderHandlerRegistryEntry} for the {@link ClassLoader}.
*/
private ClassLoaderHandlerRegistryEntry getRegistryEntry(final ClassLoader classLoader, final LogNode log) {
ClassLoaderHandlerRegistryEntry entry = classLoaderToClassLoaderHandlerRegistryEntry.get(classLoader);
if (entry == null) {
// Try all superclasses of classloader in turn
for (Class currClassLoaderClass = classLoader.getClass(); //
currClassLoaderClass != Object.class && currClassLoaderClass != null; //
currClassLoaderClass = currClassLoaderClass.getSuperclass()) {
// Find a ClassLoaderHandler that can handle the ClassLoader
for (final ClassLoaderHandlerRegistryEntry ent : ClassLoaderHandlerRegistry.CLASS_LOADER_HANDLERS) {
if (ent.canHandle(currClassLoaderClass, log)) {
// This ClassLoaderHandler can handle the ClassLoader class, or one of its superclasses
entry = ent;
break;
}
}
if (entry != null) {
// Don't iterate to next superclass if a matching ClassLoaderHandler was found
break;
}
}
if (entry == null) {
// Use fallback handler
entry = ClassLoaderHandlerRegistry.FALLBACK_HANDLER;
}
classLoaderToClassLoaderHandlerRegistryEntry.put(classLoader, entry);
}
return entry;
}
/**
* Add a {@link ClassLoader} to the ClassLoader order at the current position.
*
* @param classLoader
* the class loader
* @param log
* the log
*/
public void add(final ClassLoader classLoader, final LogNode log) {
if (classLoader == null) {
return;
}
if (added.add(classLoader)) {
final ClassLoaderHandlerRegistryEntry entry = getRegistryEntry(classLoader, log);
if (entry != null) {
classLoaderOrder.add(new SimpleEntry<>(classLoader, entry));
}
}
}
/**
* Recursively delegate to another {@link ClassLoader}.
*
* @param classLoader
* the class loader
* @param isParent
* true if this is a parent of another classloader
* @param log
* the log
*/
public void delegateTo(final ClassLoader classLoader, final boolean isParent, final LogNode log) {
if (classLoader == null) {
return;
}
// Check if this is a parent before checking if the classloader is already in the delegatedTo set,
// so that if the classloader is a context classloader but also a parent, it still gets marked as
// a parent classloader.
if (isParent) {
allParentClassLoaders.add(classLoader);
}
// Don't delegate to a classloader twice
if (delegatedTo.add(classLoader)) {
// Find ClassLoaderHandlerRegistryEntry for this classloader
final ClassLoaderHandlerRegistryEntry entry = getRegistryEntry(classLoader, log);
// Delegate to this classloader, by recursing to that classloader to get its classloader order
entry.findClassLoaderOrder(classLoader, this, log);
}
}
}