/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.plugins; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; public class PluginDependencyResolver { private final Map<PluginInfo,File> infoToFileMap; public PluginDependencyResolver(PluginLoader pluginLoader, Iterable<File> pluginFiles) throws IOException { infoToFileMap = new HashMap<PluginInfo,File>(); for (File pluginFile : pluginFiles) { infoToFileMap.put(pluginLoader.loadPluginInfoFrom(pluginFile, Collections.<JarClassLoader>emptySet()), pluginFile); } } public List<File> determineLoadOrder() throws IOException { List<PluginInfo> infoList = new ArrayList<PluginInfo>(infoToFileMap.keySet()); Collections.sort(infoList, new PluginDependencyComparator()); List<File> resultList = new ArrayList<File>(); for (PluginInfo pluginInfo : infoList) { resultList.add(infoToFileMap.get(pluginInfo)); } return resultList; } public Collection<PluginInfo> findAllDependencies(PluginInfo plugin) { Set<PluginInfo> allDependencies = new HashSet<PluginInfo>(); for (PluginInfo dependency : plugin.getDependencies()) { PluginInfo realDependency = findDependency(dependency.getId()); if (realDependency != null) { allDependencies.add(realDependency); allDependencies.addAll(findAllDependencies(realDependency)); } } return allDependencies; } private PluginInfo findDependency(PluginId id) { for (PluginInfo plugin : infoToFileMap.keySet()) { if (plugin.getId().equals(id)) { return plugin; } } return null; } public Collection<PluginInfo> findAllDependencies(File pluginFile) { for (Map.Entry<PluginInfo, File> entry : infoToFileMap.entrySet()) { if (entry.getValue().equals(pluginFile)) { return findAllDependencies(entry.getKey()); } } return Collections.emptySet(); } public void addPlugin(PluginInfo rootPlugin, File readytest) { infoToFileMap.put(rootPlugin, readytest); } public void removePlugin(PluginInfo pluginId) { infoToFileMap.remove(pluginId); } public List<PluginInfo> getPluginInfoListFromFiles(List<File> files) { List<PluginInfo> result = new ArrayList<PluginInfo>(); for (File file : files) { for (Map.Entry<PluginInfo, File> entry : infoToFileMap.entrySet()) { if (entry.getValue().equals(file)) { result.add(entry.getKey()); break; } } } return result; } private class PluginDependencyComparator implements Comparator<PluginInfo> { @Override public int compare(PluginInfo first, PluginInfo second) { if (first.getDependencies().isEmpty()) { return -1; } else if (second.getDependencies().isEmpty()) { return 1; } else { if (dependsOn(first, second)) { return 1; } else { if (dependsOn(second, first)) { return -1; } else { return 0; } } } } private boolean dependsOn(PluginInfo first, PluginInfo second) { return findAllDependencies(first).contains(second); } } }