implement resolution listener

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@192959 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-06-22 17:33:17 +00:00
parent 777cbc968c
commit 68417deebf
10 changed files with 270 additions and 248 deletions

View File

@ -0,0 +1,84 @@
package org.apache.maven.artifact.resolver;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.codehaus.plexus.logging.Logger;
/**
* Send resolution events to the debug log.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class DebugResolutionListener
implements ResolutionListener
{
private Logger logger;
private String indent = "";
public DebugResolutionListener( Logger logger )
{
this.logger = logger;
}
public void testArtifact( Artifact node )
{
}
public void startProcessChildren( Artifact artifact )
{
indent += " ";
}
public void endProcessChildren( Artifact artifact )
{
indent = indent.substring( 1 );
}
public void includeArtifact( Artifact artifact )
{
logger.debug( indent + artifact.getId() + " (selected)" );
}
public void omitForNearer( Artifact omitted, Artifact kept )
{
logger.debug( indent + omitted.getId() + " (removed - nearer found: " + kept.getVersion() + ")" );
}
public void updateScope( Artifact artifact, String scope )
{
logger.debug( indent + artifact.getId() + " (settings scope to: " + scope + ")" );
}
public void manageArtifact( Artifact artifact, Artifact replacement )
{
String msg = indent + artifact.getId();
msg += " (";
if ( replacement.getVersion() != null )
{
msg += "applying version: " + replacement.getVersion() + ";";
}
if ( replacement.getScope() != null )
{
msg += "applying scope: " + replacement.getScope();
}
msg += ")";
logger.debug( msg );
}
}

View File

@ -28,9 +28,9 @@ import org.apache.maven.artifact.transform.ArtifactTransformation;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
@ -71,11 +71,6 @@ public class DefaultArtifactResolver
// request for resolution has been satisfied.
// ----------------------------------------------------------------------
Logger logger = getLogger();
logger.debug(
"Resolving: " + artifact.getId() + " from:\n" + "{localRepository: " + localRepository + "}\n" +
"{remoteRepositories: " + remoteRepositories + "}" );
String localPath = localRepository.pathOf( artifact );
artifact.setFile( new File( localRepository.getBasedir(), localPath ) );
@ -158,9 +153,16 @@ public class DefaultArtifactResolver
{
ArtifactResolutionResult artifactResolutionResult;
// TODO: this is simplistic
List listeners = new ArrayList();
if ( getLogger().isDebugEnabled() )
{
listeners.add( new DebugResolutionListener( getLogger() ) );
}
artifactResolutionResult = artifactCollector.collect( artifacts, originatingArtifact, managedVersions,
localRepository, remoteRepositories, source, filter,
artifactFactory );
artifactFactory, listeners );
for ( Iterator i = artifactResolutionResult.getArtifacts().iterator(); i.hasNext(); )
{

View File

@ -105,4 +105,6 @@ public interface Artifact
List getDependencyTrail();
void setDependencyTrail( List dependencyTrail );
void setScope( String scope );
}

View File

@ -48,7 +48,7 @@ public class DefaultArtifact
private final String classifier;
private final String scope;
private String scope;
private List metadataList;
@ -360,4 +360,9 @@ public class DefaultArtifact
{
this.dependencyTrail = dependencyTrail;
}
public void setScope( String scope )
{
this.scope = scope;
}
}

View File

@ -23,8 +23,8 @@ import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Set;
/**
* Artifact collector - takes a set of original artifacts and resolves all of the best versions to use
@ -37,12 +37,12 @@ public interface ArtifactCollector
{
ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, ArtifactRepository localRepository,
List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter,
ArtifactFactory artifactFactory )
ArtifactFactory artifactFactory, List listeners )
throws ArtifactResolutionException;
ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions,
ArtifactRepository localRepository, List remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
ArtifactFactory artifactFactory )
ArtifactFactory artifactFactory, List listeners )
throws ArtifactResolutionException;
}

View File

@ -44,17 +44,17 @@ public class DefaultArtifactCollector
public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact,
ArtifactRepository localRepository, List remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
ArtifactFactory artifactFactory )
ArtifactFactory artifactFactory, List listeners )
throws ArtifactResolutionException
{
return collect( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories,
source, filter, artifactFactory );
source, filter, artifactFactory, listeners );
}
public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions,
ArtifactRepository localRepository, List remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
ArtifactFactory artifactFactory )
ArtifactFactory artifactFactory, List listeners )
throws ArtifactResolutionException
{
Map resolvedArtifacts = new HashMap();
@ -63,7 +63,7 @@ public class DefaultArtifactCollector
root.addDependencies( artifacts, filter );
recurse( root, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter,
artifactFactory );
artifactFactory, listeners );
Set set = new HashSet();
@ -89,28 +89,84 @@ public class DefaultArtifactCollector
private void recurse( ResolutionNode node, Map resolvedArtifacts, Map managedVersions,
ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source,
ArtifactFilter filter, ArtifactFactory artifactFactory )
ArtifactFilter filter, ArtifactFactory artifactFactory, List listeners )
throws CyclicDependencyException, TransitiveArtifactResolutionException
{
fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node );
// TODO: conflict resolvers, shouldn't be munging original artifact perhaps?
Object key = node.getKey();
if ( managedVersions.containsKey( key ) )
{
Artifact artifact = (Artifact) managedVersions.get( key );
// TODO: apply scope. assign whole artifact, except that the missing bits must be filled in
fireEvent( ResolutionListener.MANAGE_ARTIFACT, listeners, node, artifact );
if ( artifact.getVersion() != null )
{
node.getArtifact().setVersion( artifact.getVersion() );
}
if ( artifact.getScope() != null )
{
node.getArtifact().setScope( artifact.getScope() );
}
}
ResolutionNode previous = (ResolutionNode) resolvedArtifacts.get( key );
if ( previous != null )
{
// TODO: conflict resolvers
// TODO: use as conflict resolver(s), chain and introduce version mediation
// previous one is more dominant
if ( previous.getDepth() <= node.getDepth() )
{
checkScopeUpdate( node, previous, artifactFactory, listeners );
}
else
{
checkScopeUpdate( previous, node, artifactFactory, listeners );
}
if ( previous.getDepth() <= node.getDepth() )
{
fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, node, previous.getArtifact() );
return;
}
}
resolvedArtifacts.put( key, node );
fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node );
fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node );
for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
{
ResolutionNode child = (ResolutionNode) i.next();
if ( !child.isResolved() )
{
try
{
Set artifacts = source.retrieve( child.getArtifact(), localRepository, remoteRepositories );
child.addDependencies( artifacts, filter );
}
catch ( ArtifactMetadataRetrievalException e )
{
child.getArtifact().setDependencyTrail( node.getDependencyTrail() );
throw new TransitiveArtifactResolutionException( e.getMessage(), child.getArtifact(),
remoteRepositories, e );
}
recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter,
artifactFactory, listeners );
}
}
fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node );
}
private void checkScopeUpdate( ResolutionNode node, ResolutionNode previous, ArtifactFactory artifactFactory,
List listeners )
{
boolean updateScope = false;
Artifact newArtifact = node.getArtifact();
@ -131,71 +187,53 @@ public class DefaultArtifactCollector
if ( updateScope )
{
fireEvent( ResolutionListener.UPDATE_SCOPE, listeners, previous, newArtifact );
Artifact artifact = artifactFactory.createArtifact( previousArtifact.getGroupId(),
previousArtifact.getArtifactId(),
previousArtifact.getVersion(),
newArtifact.getScope(),
previousArtifact.getVersion(), newArtifact.getScope(),
previousArtifact.getType() );
// TODO: can I just change the scope?
previous.setArtifact( artifact );
}
return;
}
else
{
boolean updateScope = false;
Artifact previousArtifact = previous.getArtifact();
Artifact newArtifact = node.getArtifact();
if ( Artifact.SCOPE_RUNTIME.equals( previousArtifact.getScope() ) &&
( Artifact.SCOPE_TEST.equals( newArtifact.getScope() ) ||
Artifact.SCOPE_PROVIDED.equals( newArtifact.getScope() ) ) )
{
updateScope = true;
}
if ( Artifact.SCOPE_COMPILE.equals( previousArtifact.getScope() ) &&
!Artifact.SCOPE_COMPILE.equals( newArtifact.getScope() ) )
private void fireEvent( int event, List listeners, ResolutionNode node )
{
updateScope = true;
fireEvent( event, listeners, node, null );
}
if ( updateScope )
private void fireEvent( int event, List listeners, ResolutionNode node, Artifact replacement )
{
Artifact artifact = artifactFactory.createArtifact( newArtifact.getGroupId(),
newArtifact.getArtifactId(),
newArtifact.getVersion(),
previousArtifact.getScope(),
newArtifact.getType() );
// TODO: can I just change the scope?
node.setArtifact( artifact );
}
for ( Iterator i = listeners.iterator(); i.hasNext(); )
{
ResolutionListener listener = (ResolutionListener) i.next();
}
}
resolvedArtifacts.put( key, node );
for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
switch ( event )
{
ResolutionNode child = (ResolutionNode) i.next();
if ( !child.isResolved() )
{
try
{
Set artifacts = source.retrieve( child.getArtifact(), localRepository, remoteRepositories );
child.addDependencies( artifacts, filter );
}
catch ( ArtifactMetadataRetrievalException e )
{
child.getArtifact().setDependencyTrail( node.getDependencyTrail() );
throw new TransitiveArtifactResolutionException( e.getMessage(), child.getArtifact(),
remoteRepositories, e );
}
recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter,
artifactFactory );
case ResolutionListener.TEST_ARTIFACT:
listener.testArtifact( node.getArtifact() );
break;
case ResolutionListener.PROCESS_CHILDREN:
listener.startProcessChildren( node.getArtifact() );
break;
case ResolutionListener.FINISH_PROCESSING_CHILDREN:
listener.endProcessChildren( node.getArtifact() );
break;
case ResolutionListener.INCLUDE_ARTIFACT:
listener.includeArtifact( node.getArtifact() );
break;
case ResolutionListener.OMIT_FOR_NEARER:
listener.omitForNearer( node.getArtifact(), replacement );
break;
case ResolutionListener.UPDATE_SCOPE:
listener.updateScope( node.getArtifact(), replacement.getScope() );
break;
case ResolutionListener.MANAGE_ARTIFACT:
listener.manageArtifact( node.getArtifact(), replacement );
break;
default:
throw new IllegalStateException( "Unknown event: " + event );
}
}
}

View File

@ -1,169 +0,0 @@
package org.apache.maven.artifact.resolver;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Previous implementation of the artifact collector.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id: DefaultArtifactCollector.java 191748 2005-06-22 00:31:33Z brett $
* @deprecated
*/
public class LegacyArtifactCollector
implements ArtifactCollector
{
public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact,
ArtifactRepository localRepository, List remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
ArtifactFactory artifactFactory )
throws ArtifactResolutionException
{
return collect( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories,
source, filter, artifactFactory );
}
public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions,
ArtifactRepository localRepository, List remoteRepositories,
ArtifactMetadataSource source, ArtifactFilter filter,
ArtifactFactory artifactFactory )
throws ArtifactResolutionException
{
ArtifactResolutionResult result = new ArtifactResolutionResult();
Map resolvedArtifacts = new HashMap();
List queue = new LinkedList();
queue.add( artifacts );
while ( !queue.isEmpty() )
{
Set currentArtifacts = (Set) queue.remove( 0 );
for ( Iterator i = currentArtifacts.iterator(); i.hasNext(); )
{
Artifact newArtifact = (Artifact) i.next();
String id = newArtifact.getDependencyConflictId();
if ( resolvedArtifacts.containsKey( id ) )
{
Artifact knownArtifact = (Artifact) resolvedArtifacts.get( id );
String newVersion = newArtifact.getVersion();
String knownVersion = knownArtifact.getVersion();
if ( !newVersion.equals( knownVersion ) )
{
addConflict( result, knownArtifact, newArtifact );
}
// TODO: scope handler
boolean updateScope = false;
if ( Artifact.SCOPE_RUNTIME.equals( newArtifact.getScope() ) &&
Artifact.SCOPE_TEST.equals( knownArtifact.getScope() ) )
{
updateScope = true;
}
if ( Artifact.SCOPE_COMPILE.equals( newArtifact.getScope() ) &&
!Artifact.SCOPE_COMPILE.equals( knownArtifact.getScope() ) )
{
updateScope = true;
}
if ( updateScope )
{
Artifact artifact = artifactFactory.createArtifact( knownArtifact.getGroupId(),
knownArtifact.getArtifactId(), knownVersion,
newArtifact.getScope(),
knownArtifact.getType() );
resolvedArtifacts.put( artifact.getDependencyConflictId(), artifact );
}
}
else
{
// ----------------------------------------------------------------------
// It's the first time we have encountered this artifact
// ----------------------------------------------------------------------
if ( filter != null && !filter.include( newArtifact ) )
{
continue;
}
resolvedArtifacts.put( id, newArtifact );
Set referencedDependencies = null;
try
{
referencedDependencies = source.retrieve( newArtifact, localRepository, remoteRepositories );
}
catch ( ArtifactMetadataRetrievalException e )
{
throw new TransitiveArtifactResolutionException( e.getMessage(), newArtifact,
remoteRepositories, e );
}
// the pom for given dependency exisit we will add it to the
// queue
queue.add( referencedDependencies );
}
}
}
result.setArtifacts( new HashSet( resolvedArtifacts.values() ) );
return result;
}
private void addConflict( ArtifactResolutionResult result, Artifact knownArtifact, Artifact newArtifact )
{
List conflicts;
conflicts = (List) result.getConflicts().get( newArtifact.getDependencyConflictId() );
if ( conflicts == null )
{
conflicts = new LinkedList();
conflicts.add( knownArtifact );
result.getConflicts().put( newArtifact.getDependencyConflictId(), conflicts );
}
conflicts.add( newArtifact );
}
}

View File

@ -0,0 +1,58 @@
package org.apache.maven.artifact.resolver;
import org.apache.maven.artifact.Artifact;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed 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.
*/
/**
* TODO: describe
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public interface ResolutionListener
{
String ROLE = ResolutionListener.class.getName();
int TEST_ARTIFACT = 1;
int PROCESS_CHILDREN = 2;
int FINISH_PROCESSING_CHILDREN = 3;
int INCLUDE_ARTIFACT = 4;
int OMIT_FOR_NEARER = 5;
int UPDATE_SCOPE = 6;
int MANAGE_ARTIFACT = 7;
void testArtifact( Artifact node );
void startProcessChildren( Artifact artifact );
void endProcessChildren( Artifact artifact );
void includeArtifact( Artifact artifact );
void omitForNearer( Artifact omitted, Artifact kept );
void updateScope( Artifact artifact, String scope );
void manageArtifact( Artifact artifact, Artifact replacement );
}

View File

@ -22,4 +22,5 @@ package org.apache.maven.artifact.resolver.conflict;
*/
public interface ConflictResolver
{
static String ROLE = ConflictResolver.class.getName();
}

View File

@ -264,21 +264,21 @@ public class DefaultArtifactCollectorTest
throws ArtifactResolutionException
{
return artifactCollector.collect( artifacts, projectArtifact.artifact, null, null, source, null,
artifactFactory );
artifactFactory, Collections.EMPTY_LIST );
}
private ArtifactResolutionResult collect( ArtifactSpec a )
throws ArtifactResolutionException
{
return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null,
source, null, artifactFactory );
source, null, artifactFactory, Collections.EMPTY_LIST );
}
private ArtifactResolutionResult collect( ArtifactSpec a, ArtifactFilter filter )
throws ArtifactResolutionException
{
return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null,
source, filter, artifactFactory );
source, filter, artifactFactory, Collections.EMPTY_LIST );
}
private ArtifactResolutionResult collect( ArtifactSpec a, Artifact managedVersion )
@ -286,7 +286,8 @@ public class DefaultArtifactCollectorTest
{
Map managedVersions = Collections.singletonMap( managedVersion.getDependencyConflictId(), managedVersion );
return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact,
managedVersions, null, null, source, null, artifactFactory );
managedVersions, null, null, source, null, artifactFactory,
Collections.EMPTY_LIST );
}
private ArtifactSpec createArtifact( String id, String version )