| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.lucene.validation.ivyde; |
| |
| import org.apache.ivy.core.module.id.ModuleRevisionId; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| |
| /** |
| * Assists in the further separation of concerns between the view and the Ivy resolve report. The view looks at the |
| * IvyNode in a unique way that can lead to expensive operations if we do not achieve this separation. |
| * |
| * This class is copied from org/apache/ivyde/eclipse/resolvevisualizer/model/IvyNodeElement.java at |
| * https://svn.apache.org/repos/asf/ant/ivy/ivyde/trunk/org.apache.ivyde.eclipse.resolvevisualizer/src/ |
| * |
| * Changes include: uncommenting generics and converting to diamond operators where appropriate; |
| * removing unnecessary casts; removing javadoc tags with no description; and adding a hashCode() implementation. |
| */ |
| public class IvyNodeElement { |
| private ModuleRevisionId moduleRevisionId; |
| private boolean evicted = false; |
| private int depth = Integer.MAX_VALUE / 10; |
| private Collection<IvyNodeElement> dependencies = new HashSet<>(); |
| private Collection<IvyNodeElement> callers = new HashSet<>(); |
| private Collection<IvyNodeElement> conflicts = new HashSet<>(); |
| |
| /** |
| * The caller configurations that caused this node to be reached in the resolution, grouped by caller. |
| */ |
| private Map<IvyNodeElement,String[]>callerConfigurationMap = new HashMap<>(); |
| |
| /** |
| * We try to avoid building the list of this nodes deep dependencies by storing them in this cache by depth level. |
| */ |
| private IvyNodeElement[] deepDependencyCache; |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj instanceof IvyNodeElement) { |
| IvyNodeElement elem = (IvyNodeElement) obj; |
| if (elem.getOrganization().equals(getOrganization()) && elem.getName().equals(getName()) |
| && elem.getRevision().equals(getRevision())) |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public int hashCode() { |
| int result = 1; |
| result = result * 31 + (null == getOrganization() ? 0 : getOrganization().hashCode()); |
| result = result * 31 + (null == getName() ? 0 : getName().hashCode()); |
| result = result * 31 + (null == getRevision() ? 0 : getRevision().hashCode()); |
| return result; |
| } |
| |
| public IvyNodeElement[] getDependencies() { |
| return dependencies.toArray(new IvyNodeElement[dependencies.size()]); |
| } |
| |
| /** |
| * Recursive dependency retrieval |
| * |
| * @return The array of nodes that represents a node's immediate and transitive dependencies down to an arbitrary |
| * depth. |
| */ |
| public IvyNodeElement[] getDeepDependencies() { |
| if (deepDependencyCache == null) { |
| Collection<IvyNodeElement> deepDependencies = getDeepDependencies(this); |
| deepDependencyCache = deepDependencies.toArray(new IvyNodeElement[deepDependencies.size()]); |
| } |
| return deepDependencyCache; |
| } |
| |
| /** |
| * Recursive dependency retrieval |
| */ |
| private Collection<IvyNodeElement> getDeepDependencies(IvyNodeElement node) { |
| Collection<IvyNodeElement> deepDependencies = new HashSet<>(); |
| deepDependencies.add(node); |
| |
| IvyNodeElement[] directDependencies = node.getDependencies(); |
| for (int i = 0; i < directDependencies.length; i++) { |
| deepDependencies.addAll(getDeepDependencies(directDependencies[i])); |
| } |
| |
| return deepDependencies; |
| } |
| |
| /** |
| * @return An array of configurations by which this module was resolved |
| */ |
| public String[] getCallerConfigurations(IvyNodeElement caller) { |
| return callerConfigurationMap.get(caller); |
| } |
| |
| public void setCallerConfigurations(IvyNodeElement caller, String[] configurations) { |
| callerConfigurationMap.put(caller, configurations); |
| } |
| |
| public String getOrganization() { |
| return moduleRevisionId.getOrganisation(); |
| } |
| |
| public String getName() { |
| return moduleRevisionId.getName(); |
| } |
| |
| public String getRevision() { |
| return moduleRevisionId.getRevision(); |
| } |
| |
| public boolean isEvicted() { |
| return evicted; |
| } |
| |
| public void setEvicted(boolean evicted) { |
| this.evicted = evicted; |
| } |
| |
| public int getDepth() { |
| return depth; |
| } |
| |
| /** |
| * Set this node's depth and recursively update the node's children to relative to the new value. |
| */ |
| public void setDepth(int depth) { |
| this.depth = depth; |
| for (Iterator<IvyNodeElement> iter = dependencies.iterator(); iter.hasNext();) { |
| IvyNodeElement dependency = iter.next(); |
| dependency.setDepth(depth + 1); |
| } |
| } |
| |
| public IvyNodeElement[] getConflicts() { |
| return conflicts.toArray(new IvyNodeElement[conflicts.size()]); |
| } |
| |
| public void setConflicts(Collection<IvyNodeElement> conflicts) { |
| this.conflicts = conflicts; |
| } |
| |
| public ModuleRevisionId getModuleRevisionId() { |
| return moduleRevisionId; |
| } |
| |
| public void setModuleRevisionId(ModuleRevisionId moduleRevisionId) { |
| this.moduleRevisionId = moduleRevisionId; |
| } |
| |
| public void addCaller(IvyNodeElement caller) { |
| callers.add(caller); |
| caller.dependencies.add(this); |
| } |
| |
| public IvyNodeElement[] getCallers() { |
| return callers.toArray(new IvyNodeElement[callers.size()]); |
| } |
| } |