blob: 8645b6919b65939c12e0194bbae242af2a452211 [file] [log] [blame]
package org.apache.maven.artifact.resolver;
/*
* 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.
*/
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class ResolutionNode
{
private Artifact artifact;
private List children;
private final List parents;
private final int depth;
private final ResolutionNode parent;
private final List remoteRepositories;
private boolean active = true;
private List trail;
public ResolutionNode( Artifact artifact, List remoteRepositories )
{
this.artifact = artifact;
this.remoteRepositories = remoteRepositories;
depth = 0;
parents = Collections.EMPTY_LIST;
parent = null;
}
public ResolutionNode( Artifact artifact, List remoteRepositories, ResolutionNode parent )
{
this.artifact = artifact;
this.remoteRepositories = remoteRepositories;
depth = parent.depth + 1;
parents = new ArrayList();
parents.addAll( parent.parents );
parents.add( parent.getKey() );
this.parent = parent;
}
public void setArtifact( Artifact artifact )
{
this.artifact = artifact;
}
public Artifact getArtifact()
{
return artifact;
}
public Object getKey()
{
return artifact.getDependencyConflictId();
}
public void addDependencies( Set artifacts, List remoteRepositories, ArtifactFilter filter )
throws CyclicDependencyException, OverConstrainedVersionException
{
if ( !artifacts.isEmpty() )
{
children = new ArrayList( artifacts.size() );
for ( Iterator i = artifacts.iterator(); i.hasNext(); )
{
Artifact a = (Artifact) i.next();
if ( parents.contains( a.getDependencyConflictId() ) )
{
a.setDependencyTrail( getDependencyTrail() );
throw new CyclicDependencyException( "A dependency has introduced a cycle", a );
}
children.add( new ResolutionNode( a, remoteRepositories, this ) );
}
}
else
{
children = Collections.EMPTY_LIST;
}
trail = null;
}
/**
* @return {@link List} < {@link String} > with artifact ids
* @throws OverConstrainedVersionException
*/
public List getDependencyTrail()
throws OverConstrainedVersionException
{
List trial = getTrail();
List ret = new ArrayList( trial.size() );
for ( Iterator i = trial.iterator(); i.hasNext(); )
{
Artifact artifact = (Artifact) i.next();
ret.add( artifact.getId() );
}
return ret;
}
private List getTrail()
throws OverConstrainedVersionException
{
if ( trail == null )
{
List ids = new LinkedList();
ResolutionNode node = this;
while ( node != null )
{
Artifact artifact = node.getArtifact();
if ( artifact.getVersion() == null )
{
// set the recommended version
ArtifactVersion selected = artifact.getSelectedVersion();
//MNG-2123: null is a valid response to getSelectedVersion, don't
//assume it won't ever be.
if ( selected != null )
{
artifact.selectVersion( selected.toString() );
}
else
{
throw new OverConstrainedVersionException( "Unable to get a selected Version for "
+ artifact.getArtifactId(), artifact );
}
}
ids.add( 0, artifact );
node = node.parent;
}
trail = ids;
}
return trail;
}
public boolean isResolved()
{
return children != null;
}
public boolean isChildOfRootNode()
{
return parent != null && parent.parent == null;
}
public Iterator getChildrenIterator()
{
return children.iterator();
}
public int getDepth()
{
return depth;
}
public List getRemoteRepositories()
{
return remoteRepositories;
}
public boolean isActive()
{
return active;
}
public void enable()
{
active = true;
// TODO: if it was null, we really need to go find them now... or is this taken care of by the ordering?
if ( children != null )
{
for ( Iterator i = children.iterator(); i.hasNext(); )
{
ResolutionNode node = (ResolutionNode) i.next();
node.enable();
}
}
}
public void disable()
{
active = false;
if ( children != null )
{
for ( Iterator i = children.iterator(); i.hasNext(); )
{
ResolutionNode node = (ResolutionNode) i.next();
node.disable();
}
}
}
public boolean filterTrail( ArtifactFilter filter )
throws OverConstrainedVersionException
{
boolean success = true;
if ( filter != null )
{
for ( Iterator i = getTrail().iterator(); i.hasNext() && success; )
{
Artifact artifact = (Artifact) i.next();
if ( !filter.include( artifact ) )
{
success = false;
}
}
}
return success;
}
public String toString()
{
return artifact.toString() + " (" + depth + "; " + ( active ? "enabled" : "disabled" ) + ")";
}
}