/** * Copyright (c) 2013-2016 Angelo ZERR. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation */ package tern.metadata; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import tern.server.ITernModule; /** * {@link Comparator} to sort modules by dependencies. * * This sort is important when a tern plugin B which depends an other plugin A * must be loaded after A. For instance aui1.5.x which depends on yui3 must be * loaded after the yui3 tern plugin. * */ public class ModuleDependenciesComparator implements Comparator<ITernModule> { private final Map<ITernModule, Integer> modulesMap; public ModuleDependenciesComparator(List<ITernModule> modules, TernModuleMetadataManager manager) { modulesMap = new HashMap<ITernModule, Integer>(); for (ITernModule module : modules) { updateRelevant(module, modules, modulesMap, manager); } Collections.sort(modules, this); } /** * Returns the relevant of the given module computed with dependencies * modules. * * @param module * @param modules * @param modulesMap * @param manager * @return the relevant of the given module computed with dependencies * modules. */ private int updateRelevant(ITernModule module, List<ITernModule> modules, Map<ITernModule, Integer> modulesMap, TernModuleMetadataManager manager) { if (modulesMap.containsKey(module)) { // relevant already computed, return it. return modulesMap.get(module); } // Compute relevant by using dependencies int relevant = 1; TernModuleMetadata metadata = manager != null ? manager.getMetadata(module.getType()) : module.getMetadata(); if (metadata != null) { Collection<String> dependencies = metadata.getDependencies(module .getVersion()); if (dependencies != null) { for (String dependency : dependencies) { ITernModule dependencyModule = getModule(dependency, modules); if (dependencyModule != null) { relevant += updateRelevant(dependencyModule, modules, modulesMap, manager); } } } } modulesMap.put(module, relevant); return relevant; } private ITernModule getModule(String name, List<ITernModule> modules) { for (ITernModule module : modules) { if (module.getName().equals(name)) { return module; } } return null; } @Override public int compare(ITernModule mod1, ITernModule mod2) { Integer relevant1 = modulesMap.get(mod1); Integer relevant2 = modulesMap.get(mod2); if (relevant1 != null && relevant2 != null) { return relevant1 - relevant2; } return 0; } }