package org.jboss.windup.graph; import java.util.ArrayList; import java.util.List; import org.jboss.forge.furnace.Furnace; import org.jboss.forge.furnace.addons.Addon; import org.jboss.forge.furnace.addons.AddonDependency; import org.jboss.forge.furnace.addons.AddonFilter; import org.jboss.forge.furnace.container.simple.lifecycle.SimpleContainer; import org.jboss.windup.util.FurnaceCompositeClassLoader; /** * Provides a composite classloader of all addons that depend on the graph addon. * */ public class GraphApiCompositeClassLoaderProvider { private Addon addon; private Furnace furnace; public GraphApiCompositeClassLoaderProvider() { this.furnace = SimpleContainer.getFurnace(GraphApiCompositeClassLoaderProvider.class.getClassLoader()); for (Addon addon : this.furnace.getAddonRegistry().getAddons()) { if (addon.getClassLoader() != null && addon.getClassLoader().equals(GraphApiCompositeClassLoaderProvider.class.getClassLoader())) { this.addon = addon; break; } } } /** * Creates a classloader which combines classloaders of all addons depending on Graph API. This insures that * FramedGraph can always load all the relevant types of *Model classes (as all model classes will be in Addons that * depend on Graph API). */ public ClassLoader getCompositeClassLoader() { List<ClassLoader> loaders = new ArrayList<>(); AddonFilter filter = new AddonFilter() { @Override public boolean accept(Addon addon) { return addonDependsOnGraphApi(addon); } }; for (Addon addon : furnace.getAddonRegistry().getAddons(filter)) { loaders.add(addon.getClassLoader()); } return new FurnaceCompositeClassLoader(getClass().getClassLoader(), loaders); } private boolean addonDependsOnGraphApi(Addon addon) { for (AddonDependency dep : addon.getDependencies()) { if (dep.getDependency().equals(this.addon)) { return true; } boolean subDep = addonDependsOnGraphApi(dep.getDependency()); if (subDep) { return true; } } return false; } }