blob: 287527e2e3c743a4f3d0123a6eb04c197bef0c9c [file] [log] [blame]
/*
* 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()]);
}
}