org.jmeterplugins.repository.DependencyResolver Maven / Gradle / Ivy
package org.jmeterplugins.repository;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class DependencyResolver {
private static final Logger log = LoggingManager.getLoggerForClass();
public static final String JAVA_CLASS_PATH = "java.class.path";
protected final Set deletions = new HashSet<>();
protected final Set additions = new HashSet<>();
protected final Map libAdditions = new HashMap<>();
protected final Set libDeletions = new HashSet<>();
protected final Map allPlugins;
public DependencyResolver(Map allPlugins) {
this.allPlugins = allPlugins;
resolveFlags();
resolveUpgrades();
resolveDeleteByDependency();
resolveInstallByDependency();
resolveDeleteLibs();
resolveInstallLibs();
}
// TODO: return iterators to make values read-only
public Set getDeletions() {
return deletions;
}
public Set getAdditions() {
return additions;
}
public Map getLibAdditions() {
return libAdditions;
}
public Set getLibDeletions() {
return libDeletions;
}
private Plugin getPluginByID(String id) {
for (Plugin plugin : allPlugins.keySet()) {
if (plugin.getID().equals(id)) {
return plugin;
}
}
throw new RuntimeException("Plugin not found by ID: " + id);
}
private Set getDependants(Plugin plugin) {
Set res = new HashSet<>();
for (Plugin pAll : allPlugins.keySet()) {
for (String depID : pAll.getDepends()) {
if (depID.equals(plugin.getID())) {
res.add(pAll);
}
}
}
return res;
}
private void resolveFlags() {
for (Map.Entry entry : allPlugins.entrySet()) {
if (entry.getKey().isInstalled()) {
if (!entry.getValue()) {
deletions.add(entry.getKey());
}
} else if (entry.getValue()) {
additions.add(entry.getKey());
}
}
}
private void resolveUpgrades() {
// detect upgrades
for (Map.Entry entry : allPlugins.entrySet()) {
Plugin plugin = entry.getKey();
if (entry.getValue() && plugin.isInstalled() && !plugin.getInstalledVersion().equals(plugin.getCandidateVersion())) {
log.debug("Upgrade: " + plugin);
deletions.add(plugin);
additions.add(plugin);
}
}
}
private void resolveDeleteByDependency() {
// delete by depend
boolean hasModifications = true;
while (hasModifications) {
log.debug("Check uninstall dependencies");
hasModifications = false;
for (Plugin plugin : deletions) {
if (!additions.contains(plugin)) {
for (Plugin dep : getDependants(plugin)) {
if (!deletions.contains(dep) && dep.isInstalled()) {
log.debug("Add to deletions: " + dep);
deletions.add(dep);
hasModifications = true;
}
if (additions.contains(dep)) {
log.debug("Remove from additions: " + dep);
additions.remove(dep);
hasModifications = true;
}
}
}
if (hasModifications) {
break; // prevent ConcurrentModificationException
}
}
}
}
private void resolveInstallByDependency() {
// resolve dependencies
boolean hasModifications = true;
while (hasModifications) {
log.debug("Check install dependencies: " + additions);
hasModifications = false;
for (Plugin plugin : additions) {
for (String pluginID : plugin.getDepends()) {
Plugin depend = getPluginByID(pluginID);
if (!depend.isInstalled() || deletions.contains(depend)) {
if (!additions.contains(depend)) {
log.debug("Add to install: " + depend);
additions.add(depend);
hasModifications = true;
}
}
}
if (hasModifications) {
break; // prevent ConcurrentModificationException
}
}
}
}
private void resolveInstallLibs() {
for (Plugin plugin : additions) {
Map libs = plugin.getLibs(plugin.getCandidateVersion());
for (String lib : libs.keySet()) {
if (Plugin.getLibInstallPath(lib) == null) {
libAdditions.put(lib, libs.get(lib));
}
}
}
}
private void resolveDeleteLibs() {
for (Plugin plugin : deletions) {
if (additions.contains(plugin)) { // skip upgrades
continue;
}
Map libs = plugin.getLibs(plugin.getInstalledVersion());
for (String lib : libs.keySet()) {
if (Plugin.getLibInstallPath(lib) != null) {
libDeletions.add(lib);
} else {
log.warn("Did not find library to uninstall it: " + lib);
}
}
}
for (Plugin plugin : allPlugins.keySet()) {
if (additions.contains(plugin) || (plugin.isInstalled() && !deletions.contains(plugin))) {
String ver = additions.contains(plugin) ? plugin.getCandidateVersion() : plugin.getInstalledVersion();
//log.debug("Affects " + plugin + " v" + ver);
Map libs = plugin.getLibs(ver);
for (String lib : libs.keySet()) {
if (libDeletions.contains(lib)) {
log.debug("Won't delete lib " + lib + " since it is used by " + plugin);
libDeletions.remove(lib);
}
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy