/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.tools; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.logging.Level; /** * @author Nils Woehler * */ public class DominatingClassFinder<T> { /** * @return Returns the next dominating or parent class found in the list of available classes. */ public Class<? extends T> findNextDominatingClass(Class<? extends T> clazz, Collection<Class<? extends T>> availableClasses) { Set<Class<? extends T>> candidates = new HashSet<Class<? extends T>>(); // fetch candidates for (Class<? extends T> candidate : availableClasses) { if (candidate.isAssignableFrom(clazz)) { candidates.add(candidate); } } // iterate over candidates and extract dominated candidates boolean dominatedClassesFound = true; while (dominatedClassesFound) { dominatedClassesFound = false; List<Class<? extends T>> dominatedList = new LinkedList<Class<? extends T>>(); // if more than one candidate is left... if (candidates.size() != 1) { // iterate over all candidate pairs and add all candidates that are dominated by // other candidates into a list for (Class<? extends T> candidate : candidates) { for (Class<? extends T> comperable : candidates) { if (candidate != comperable) { if (comperable.isAssignableFrom(candidate)) { dominatedList.add(candidate); dominatedClassesFound = true; } } } } } // if dominates classes have been found set them as new candidates for the next // iteration if (dominatedClassesFound) { candidates.clear(); candidates.addAll(dominatedList); } } // this loop should break with only one candidate left, BUT: theoretically there can be more // than one // if this is the case, log an error... if (candidates.size() > 1) { LogService .getRoot() .log(Level.INFO, "com.rapidminer.tools.DominatingClassFinder.more_than_one_renderable_candidate_for_the_result_of_classname", clazz.getName()); } // and select the first candidate found if (candidates.isEmpty()) { return null; } else { return candidates.iterator().next(); } } }