Browse Source

[MRM-410] Dependency Tree is not shown in artifact details screen.

Adding support libs.



git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@547277 13f79535-47bb-0310-9956-ffa450edef68
tags/archiva-1.0-alpha-2
Joakim Erdfelt 17 years ago
parent
commit
926610fc53
100 changed files with 25044 additions and 90 deletions
  1. 4
    3
      archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java
  2. 105
    0
      archiva-base/archiva-dependency-graph/pom.xml
  3. 200
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/DependencyGraphFactory.java
  4. 228
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraph.java
  5. 51
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphBuilder.java
  6. 188
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphEdge.java
  7. 79
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphKeys.java
  8. 191
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphNode.java
  9. 289
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphUtils.java
  10. 57
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyResolutionEvent.java
  11. 16
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphListener.java
  12. 79
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphPhaseEvent.java
  13. 44
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphTask.java
  14. 42
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphTaskException.java
  15. 31
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/PotentialCyclicEdgeProducer.java
  16. 55
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeCyclicPredicate.java
  17. 48
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeDisabledPredicate.java
  18. 71
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeExactScopePredicate.java
  19. 54
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeExcludedPredicate.java
  20. 62
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeFromPredicate.java
  21. 49
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeScopeClosure.java
  22. 55
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeToPredicate.java
  23. 54
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeWithinScopePredicate.java
  24. 46
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/NodeFromParentPredicate.java
  25. 54
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/NodeInEdgePredicate.java
  26. 59
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/NodePredicate.java
  27. 56
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/OrphanedNodePredicate.java
  28. 43
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/ToArtifactReferenceTransformer.java
  29. 53
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/UnresolvedGraphNodePredicate.java
  30. 43
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/AbstractReduceEdgeVisitor.java
  31. 218
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/DependencyManagementApplier.java
  32. 152
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/DependencyManagementStack.java
  33. 34
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagCyclicEdgesTask.java
  34. 70
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagCyclicEdgesVisitor.java
  35. 52
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagExcludedEdgesTask.java
  36. 86
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagExcludedEdgesVisitor.java
  37. 81
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/GraphCopier.java
  38. 53
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/PopulateDependencyManagementTask.java
  39. 92
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/PopulateGraphMasterTask.java
  40. 35
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceEnabledEdgesTask.java
  41. 42
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceEnabledEdgesVisitor.java
  42. 50
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceScopeTask.java
  43. 51
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceScopeVisitor.java
  44. 53
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceTransitiveEdgesTask.java
  45. 161
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceTransitiveEdgesVisitor.java
  46. 98
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/RefineConflictsTask.java
  47. 303
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/RefineConflictsVisitor.java
  48. 114
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ResolveGraphTask.java
  49. 35
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/UpdateScopesTask.java
  50. 82
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/UpdateScopesVisitor.java
  51. 73
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/BaseVisitor.java
  52. 76
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/DependencyGraphVisitor.java
  53. 89
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/DependencyGraphWalker.java
  54. 157
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/WalkBreadthFirstSearch.java
  55. 145
    0
      archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/WalkDepthFirstSearch.java
  56. 392
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/AbstractDependencyGraphFactoryTestCase.java
  57. 175
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/AbstractMemoryRepository.java
  58. 51
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/AllTests.java
  59. 77
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaCommonDependencyGraphTest.java
  60. 3469
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaCommonMemoryRepository.java
  61. 200
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaWebappDependencyGraphTest.java
  62. 3469
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaWebappMemoryRepository.java
  63. 86
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaXmlToolsDependencyGraphTest.java
  64. 3469
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaXmlToolsMemoryRepository.java
  65. 98
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ContinuumStoreDependencyGraphTest.java
  66. 4142
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ContinuumStoreMemoryRepository.java
  67. 74
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/DepManDeepVersionDependencyGraphTest.java
  68. 77
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/DepManDeepVersionMemoryRepository.java
  69. 346
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/GraphvizDotTool.java
  70. 47
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/Keys.java
  71. 139
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MavenProjectInfoReportsPluginDependencyGraphTest.java
  72. 1040
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MavenProjectInfoReportsPluginMemoryRepository.java
  73. 35
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MemoryRepository.java
  74. 96
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MemoryRepositoryDependencyGraphBuilder.java
  75. 71
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/SimpleDependencyGraphTest.java
  76. 48
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/SimpleMemoryRepository.java
  77. 104
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/WagonManagerDependencyGraphTest.java
  78. 772
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/WagonManagerMemoryRepository.java
  79. 67
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/functors/ToKeyTransformer.java
  80. 227
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/tasks/DependencyManagementStackTest.java
  81. 231
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/walk/DependencyGraphWalkerTest.java
  82. 98
    0
      archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/walk/WalkCollector.java
  83. 57
    0
      archiva-base/archiva-model/src/main/java/org/apache/maven/archiva/model/DependencyScope.java
  84. 119
    3
      archiva-base/archiva-model/src/main/mdo/archiva-base.xml
  85. 73
    0
      archiva-base/archiva-model/src/test/java/org/apache/maven/archiva/model/DependencyScopeTest.java
  86. 5
    0
      archiva-base/archiva-repository-layer/pom.xml
  87. 47
    14
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/ProjectModelMerge.java
  88. 116
    0
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/dependencies/ProjectModelBasedGraphBuilder.java
  89. 29
    62
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/filters/EffectiveProjectModelFilter.java
  90. 15
    7
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/filters/ProjectModelExpressionFilter.java
  91. 15
    0
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/readers/ProjectModel400Reader.java
  92. 78
    0
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/resolvers/ProjectModelResolutionListener.java
  93. 244
    0
      archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/resolvers/ProjectModelResolverStack.java
  94. 1
    1
      archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/project/filters/EffectiveProjectModelFilterTest.java
  95. 1
    0
      archiva-base/pom.xml
  96. 96
    0
      tools/maven-archivadev-plugin/pom.xml
  97. 133
    0
      tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/CreateArchivaDependencyResolutionTestCaseMojo.java
  98. 63
    0
      tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/functors/ArtifactComparator.java
  99. 44
    0
      tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/functors/DependencyNodeToArtifactTransformer.java
  100. 0
    0
      tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/functors/MatchingDependencyPredicate.java

+ 4
- 3
archiva-base/archiva-consumers/archiva-database-consumers/src/main/java/org/apache/maven/archiva/consumers/database/ProjectModelToDatabaseConsumer.java View File

@@ -300,18 +300,19 @@ public class ProjectModelToDatabaseConsumer
{
synchronized ( effectiveModelFilter )
{
effectiveModelFilter.clearResolvers();
effectiveModelFilter.getProjectModelResolverStack().clearResolvers();

// Add the database resolver first!
effectiveModelFilter.addProjectModelResolver( databaseResolver );
effectiveModelFilter.getProjectModelResolverStack().addProjectModelResolver( databaseResolver );

List ret = this.resolverFactory.getAllResolvers();
Iterator it = ret.iterator();
while ( it.hasNext() )
{
ProjectModelResolver resolver = (ProjectModelResolver) it.next();
// TODO: Use listener to perform database saving of found models, instead of wrapped resolver.
ProjectModelResolver wrapped = new WrappedDatabaseProjectModelResolver( dao, resolver );
effectiveModelFilter.addProjectModelResolver( wrapped );
effectiveModelFilter.getProjectModelResolverStack().addProjectModelResolver( wrapped );
}
}
}

+ 105
- 0
archiva-base/archiva-dependency-graph/pom.xml View File

@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-base</artifactId>
<version>1.0-alpha-2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>archiva-dependency-graph</artifactId>
<name>Archiva Base :: Dependency Graph</name>
<dependencies>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-configuration</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-model</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-xml-tools</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-expression-evaluator</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus.cache</groupId>
<artifactId>plexus-cache-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus.cache</groupId>
<artifactId>plexus-cache-ehcache</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus.registry</groupId>
<artifactId>plexus-registry-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-maven-plugin</artifactId>
<executions>
<execution>
<id>descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

+ 200
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/DependencyGraphFactory.java View File

@@ -0,0 +1,200 @@
package org.apache.maven.archiva.dependency;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.archiva.dependency.graph.GraphListener;
import org.apache.maven.archiva.dependency.graph.GraphPhaseEvent;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.GraphTaskException;
import org.apache.maven.archiva.dependency.graph.PotentialCyclicEdgeProducer;
import org.apache.maven.archiva.dependency.graph.tasks.FlagCyclicEdgesTask;
import org.apache.maven.archiva.dependency.graph.tasks.FlagExcludedEdgesTask;
import org.apache.maven.archiva.dependency.graph.tasks.PopulateGraphMasterTask;
import org.apache.maven.archiva.dependency.graph.tasks.ReduceEnabledEdgesTask;
import org.apache.maven.archiva.dependency.graph.tasks.ReduceScopeTask;
import org.apache.maven.archiva.dependency.graph.tasks.ReduceTransitiveEdgesTask;
import org.apache.maven.archiva.dependency.graph.tasks.RefineConflictsTask;
import org.apache.maven.archiva.dependency.graph.tasks.UpdateScopesTask;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* DependencyGraphFactory
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component role="org.apache.maven.archiva.dependency.DependencyGraphFactory"
*/
public class DependencyGraphFactory
{
private GraphTask taskFlagCyclicEdges;

private PopulateGraphMasterTask taskPopulateGraph;

private ReduceScopeTask taskReduceScope;

private List listeners;

private DependencyGraphBuilder graphBuilder;

private List tasks;

public DependencyGraphFactory()
{
listeners = new ArrayList();

taskFlagCyclicEdges = new FlagCyclicEdgesTask();
taskPopulateGraph = new PopulateGraphMasterTask();
taskReduceScope = new ReduceScopeTask( DependencyScope.TEST );

tasks = new ArrayList();

/* Take the basic graph, and expand the nodes fully, including depman.
*/
tasks.add( taskPopulateGraph );

/* Identify, flag, and disable excluded edges.
*/
tasks.add( new FlagExcludedEdgesTask() );

/* Reduce the edges of the graph to only those that are enabled.
*/
tasks.add( new ReduceEnabledEdgesTask() );

/* Identify dependencies that conflict, resolve to single node.
*
* This will ...
* 1) filter the distant conflicts away for the nearer ones.
* 2) same distance nodes will pick 'newest' version.
*
* This can cause a collapsing of node versions.
*/
tasks.add( new RefineConflictsTask() );

/* Reduce the scope of the graph to those visible by the 'test' scope.
*/
tasks.add( taskReduceScope );

/* Reduce the edges of the graph. Use the transitive reduction algorithm
* to remove redundant edges.
*/
tasks.add( new ReduceTransitiveEdgesTask() );

/* Update the scopes of the edges to conform to the parent setting.
*/
tasks.add( new UpdateScopesTask() );
}

public void addGraphListener( GraphListener listener )
{
this.listeners.add( listener );
}

/**
* Get the Graph for a specific Versioned Project Reference.
*
* @param versionedProjectReference
* @return
*/
public DependencyGraph getGraph( VersionedReference versionedProjectReference )
throws GraphTaskException
{
DependencyGraph graph = graphBuilder.createGraph( versionedProjectReference );

triggerGraphPhase( GraphPhaseEvent.GRAPH_NEW, null, graph );

Iterator it = this.tasks.iterator();
while ( it.hasNext() )
{
GraphTask task = (GraphTask) it.next();
try
{
triggerGraphPhase( GraphPhaseEvent.GRAPH_TASK_PRE, task, graph );
task.executeTask( graph );
if ( task instanceof PotentialCyclicEdgeProducer )
{
taskFlagCyclicEdges.executeTask( graph );
}
triggerGraphPhase( GraphPhaseEvent.GRAPH_TASK_POST, task, graph );
}
catch ( GraphTaskException e )
{
triggerGraphError( e, graph );
throw e;
}
catch ( Exception e )
{
GraphTaskException gte = new GraphTaskException( e.getMessage(), e );
triggerGraphError( gte, graph );
throw gte;
}
}

triggerGraphPhase( GraphPhaseEvent.GRAPH_DONE, null, graph );

return graph;
}

public void removeGraphListener( GraphListener listener )
{
this.listeners.remove( listener );
}

public void setDesiredScope( String scope )
{
taskReduceScope.setScope( scope );
}

public void setGraphBuilder( DependencyGraphBuilder graphBuilder )
{
this.graphBuilder = graphBuilder;
taskPopulateGraph.setBuilder( graphBuilder );
}

private void triggerGraphError( GraphTaskException e, DependencyGraph graph )
{
Iterator it = listeners.iterator();
while ( it.hasNext() )
{
GraphListener listener = (GraphListener) it.next();
listener.graphError( e, graph );
}
}

private void triggerGraphPhase( int type, GraphTask task, DependencyGraph graph )
{
GraphPhaseEvent evt = new GraphPhaseEvent( type, task, graph );

Iterator it = listeners.iterator();
while ( it.hasNext() )
{
GraphListener listener = (GraphListener) it.next();
listener.graphPhaseEvent( evt );
}
}

}

+ 228
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraph.java View File

@@ -0,0 +1,228 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.maven.archiva.dependency.graph.functors.EdgeFromPredicate;
import org.apache.maven.archiva.dependency.graph.functors.EdgeToPredicate;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* DependencyGraph
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyGraph
{
public static final int DISABLED_CYCLIC = 0;

public static final int DISABLED_EXCLUDED = 1;

public static final int DISABLED_OPTIONAL = 2;

public static final int DISABLED_NEARER_DEP = 3;

public static final int DISABLED_NEARER_EDGE = 4;

private DependencyGraphNode rootNode;

private Set edges = new HashSet();

private ListOrderedMap nodes = new ListOrderedMap();

public DependencyGraph( String groupId, String artifactId, String version )
{
ArtifactReference rootRef = new ArtifactReference();
rootRef.setGroupId( groupId );
rootRef.setArtifactId( artifactId );
rootRef.setVersion( version );
rootRef.setClassifier( "" );
rootRef.setType( "pom" );

this.rootNode = new DependencyGraphNode( rootRef );
}

public DependencyGraph( DependencyGraphNode root )
{
this.rootNode = root;
}

public Collection getEdges()
{
return edges;
}

public Collection getNodes()
{
return nodes.values();
}

public DependencyGraphNode getRootNode()
{
return rootNode;
}

public void setRootNode( DependencyGraphNode rootNode )
{
this.rootNode = rootNode;
}

/**
* Add the edge to the {@link DependencyGraph}.
*
* @param edge the edge to add.
*/
public void addEdge( final DependencyGraphEdge edge )
{
if ( edge.getNodeFrom() == null )
{
throw new IllegalArgumentException( "edge.nodeFrom cannot be null." );
}

if ( edge.getNodeTo() == null )
{
throw new IllegalArgumentException( "edge.nodeTo cannot be null." );
}

this.edges.add( edge );
}

public DependencyGraphNode addNode( DependencyGraphNode node )
{
if ( node == null )
{
throw new IllegalArgumentException( "Unable to add a null node." );
}

if ( node.getArtifact() == null )
{
throw new IllegalArgumentException( "Unable to add a node with a null artifact reference." );
}

int prevNodeIdx = this.nodes.indexOf( node );

// Found it in the node tree?
if ( prevNodeIdx >= 0 )
{
// Merge new node into existing node.
DependencyGraphNode previousNode = (DependencyGraphNode) this.nodes.get( prevNodeIdx );

if ( CollectionUtils.isNotEmpty( node.getExcludes() ) )
{
previousNode.getExcludes().addAll( node.getExcludes() );
}

if ( CollectionUtils.isNotEmpty( node.getDependencyManagement() ) )
{
previousNode.getDependencyManagement().addAll( node.getDependencyManagement() );
}

if ( node.isFromParent() )
{
previousNode.setFromParent( true );
}

// Return newly merged node (from existing node)
return previousNode;
}

// This is a new node, didn't exist before, just save it.
this.nodes.put( node.getArtifact(), node );

return node;
}

public boolean hasNode( DependencyGraphNode node )
{
return this.nodes.containsKey( node.getArtifact() );
}

public boolean hasEdge( DependencyGraphEdge edge )
{
return this.edges.contains( edge );
}

/**
* Get the list of edges from the provided node.
*
* @param node the node to use as the 'from' side of an edge.
* @return the edges from the provided node.
*/
public List getEdgesFrom( DependencyGraphNode node )
{
List ret = new ArrayList();
CollectionUtils.select( this.edges, new EdgeFromPredicate( node.getArtifact() ), ret );
return ret;
}

/**
* Get the list of edges to the provided node.
*
* @param node the node to use as the 'to' side of an edge.
* @return the edges to the provided node.
*/
public List getEdgesTo( DependencyGraphNode node )
{
List ret = new ArrayList();
CollectionUtils.select( this.edges, new EdgeToPredicate( node.getArtifact() ), ret );
return ret;
}

/**
* Get the node for the specified artifact reference.
*
* @param ref the artifact reference to use to find the node.
* @return the node that was found. (null if not found)
*/
public DependencyGraphNode getNode( ArtifactReference ref )
{
return (DependencyGraphNode) this.nodes.get( ref );
}

public void removeEdge( DependencyGraphEdge edge )
{
this.edges.remove( edge );
}

public void removeNode( DependencyGraphNode node )
{
List edges = getEdgesFrom( node );
if ( !edges.isEmpty() )
{
System.out.println( "Removing node left <" + edges + "> hanging <from> edges." );
}

edges = getEdgesTo( node );
if ( !edges.isEmpty() )
{
System.out.println( "Removing node left <" + edges + "> hanging <to> edges." );
}

this.nodes.remove( node.getArtifact() );
}
}

+ 51
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphBuilder.java View File

@@ -0,0 +1,51 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.VersionedReference;

/**
* DependencyGraphBuilder
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface DependencyGraphBuilder
{
/**
* Given a node and a versioned project rexpandeference, resolve the details of the node, creating
* any dependencies and edges as needed.
*
* @param graph the graph to add nodes and edges to.
* @param node the node where the resolution should occur.
* @param versionedProjectReference the versioned project reference for the node
* that needs to be resolved.
*/
public void resolveNode( DependencyGraph graph, DependencyGraphNode node,
VersionedReference versionedProjectReference );

/**
* Create a new graph, with the root of the graph for the node specified.
*
* @param versionedProjectReference the root node for the graph.
* @return the new DependencyGraph, complete with root node and direct dependencies.
*/
public DependencyGraph createGraph( VersionedReference versionedProjectReference );
}

+ 188
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphEdge.java View File

@@ -0,0 +1,188 @@
package org.apache.maven.archiva.dependency.graph;

import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.DependencyScope;

/*
* 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.
*/

/**
* DependencyGraphEdge
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyGraphEdge
{
private ArtifactReference nodeFrom;

private ArtifactReference nodeTo;

private String scope;
private boolean disabled = false;

private int disabledType;

private String disabledReason;

public DependencyGraphEdge( ArtifactReference fromNode, ArtifactReference toNode )
{
super();
this.nodeFrom = fromNode;
this.nodeTo = toNode;
this.scope = DependencyScope.COMPILE;
}

public boolean equals( Object obj )
{
if ( this == obj )
{
return true;
}
if ( obj == null )
{
return false;
}
if ( getClass() != obj.getClass() )
{
return false;
}
final DependencyGraphEdge other = (DependencyGraphEdge) obj;
if ( nodeFrom == null )
{
if ( other.nodeFrom != null )
{
return false;
}
}
else if ( !nodeFrom.equals( other.nodeFrom ) )
{
return false;
}
if ( nodeTo == null )
{
if ( other.nodeTo != null )
{
return false;
}
}
else if ( !nodeTo.equals( other.nodeTo ) )
{
return false;
}
return true;
}

public String getDisabledReason()
{
return disabledReason;
}

public int getDisabledType()
{
return disabledType;
}

public ArtifactReference getNodeFrom()
{
return nodeFrom;
}

public ArtifactReference getNodeTo()
{
return nodeTo;
}

public String getScope()
{
return scope;
}

public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + ( ( nodeFrom == null ) ? 0 : nodeFrom.hashCode() );
result = PRIME * result + ( ( nodeTo == null ) ? 0 : nodeTo.hashCode() );
return result;
}

public boolean isDisabled()
{
return disabled;
}

public void setDisabled( boolean disabled )
{
this.disabled = disabled;
if( this.disabled == false )
{
this.disabledReason = null;
this.disabledType = -1;
}
}

public void setDisabledReason( String disabledReason )
{
this.disabledReason = disabledReason;
}

public void setDisabledType( int disabledType )
{
this.disabledType = disabledType;
}
public void setNodeFrom( ArtifactReference ref )
{
this.nodeFrom = ref;
}

public void setNodeFrom( DependencyGraphNode node )
{
this.nodeFrom = node.getArtifact();
}
public void setNodeTo( ArtifactReference ref )
{
this.nodeTo = ref;
}

public void setNodeTo( DependencyGraphNode node )
{
this.nodeTo = node.getArtifact();
}

public void setScope( String scope )
{
this.scope = scope;
}

public String toString()
{
StringBuffer sb = new StringBuffer();

sb.append( "GraphEdge[" );
sb.append( "from=" ).append( DependencyGraphKeys.toKey( nodeFrom ) );
sb.append( ",to=" ).append( DependencyGraphKeys.toKey( nodeTo ) );
sb.append( "]" );

return sb.toString();
}
}

+ 79
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphKeys.java View File

@@ -0,0 +1,79 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.commons.lang.StringUtils;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.Exclusion;

/**
* Key generation for the various objects used within the DependencyGraph.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyGraphKeys
{
public static String toManagementKey( DependencyGraphNode node )
{
return toManagementKey( node.getArtifact() );
}

public static String toManagementKey( ArtifactReference ref )
{
StringBuffer key = new StringBuffer();
key.append( ref.getGroupId() ).append( ":" );
key.append( ref.getArtifactId() );
return key.toString();
}

public static String toManagementKey( Dependency ref )
{
StringBuffer key = new StringBuffer();
key.append( ref.getGroupId() ).append( ":" );
key.append( ref.getArtifactId() );
return key.toString();
}

public static String toManagementKey( Exclusion ref )
{
StringBuffer key = new StringBuffer();
key.append( ref.getGroupId() ).append( ":" );
key.append( ref.getArtifactId() );
return key.toString();
}

public static String toKey( DependencyGraphNode node )
{
return toKey( node.getArtifact() );
}

public static String toKey( ArtifactReference ref )
{
StringBuffer key = new StringBuffer();
key.append( ref.getGroupId() ).append( ":" );
key.append( ref.getArtifactId() ).append( ":" );
key.append( ref.getVersion() ).append( ":" );
key.append( StringUtils.defaultString( ref.getClassifier() ) ).append( ":" );
key.append( ref.getType() );
return key.toString();
}
}

+ 191
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphNode.java View File

@@ -0,0 +1,191 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.Exclusion;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* DependencyGraphNode
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyGraphNode
{
/**
* The artifact reference for this node.
*/
private ArtifactReference artifact;

/**
* The project level dependency management section for this artifact.
*/
private List dependencyManagement = new ArrayList();

/**
* The list of excluded groupId:artifactId for this node's sub-nodes.
*/
private Set excludes = new HashSet();

/**
* Flag indicating that this node has been resolved from disk.
* Initially this is set to false, when the node is added due to a dependency entry in the
* project's pom.
* When the resolver comes through and reads the model for this node, it sets this to true.
*/
private boolean resolved = false;
/**
* Flag indicating that this dependency exists because of a parent dependency.
* TODO: move this to DependencyGraphEdge (where it really belongs)
*/
private boolean fromParent = false;

/**
* Booleaning indicating that this node is in conflict with another node in the graph.
* If this is true, that means this node is flagged for removal.
*/
private boolean conflicted = false;

public DependencyGraphNode( ArtifactReference artifact )
{
super();
this.artifact = artifact;
}

public void addExclude( Exclusion exclusion )
{
this.excludes.add( DependencyGraphKeys.toManagementKey( exclusion ) );
}

public boolean equals( Object obj )
{
if ( this == obj )
{
return true;
}
if ( obj == null )
{
return false;
}
if ( getClass() != obj.getClass() )
{
return false;
}
final DependencyGraphNode other = (DependencyGraphNode) obj;
if ( artifact == null )
{
if ( other.artifact != null )
{
return false;
}
}
else if ( !artifact.equals( other.artifact ) )
{
return false;
}
return true;
}

public ArtifactReference getArtifact()
{
return artifact;
}

public List getDependencyManagement()
{
return dependencyManagement;
}

public Set getExcludes()
{
return excludes;
}

public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + ( ( artifact == null ) ? 0 : artifact.hashCode() );
return result;
}

public boolean isConflicted()
{
return conflicted;
}

public boolean isResolved()
{
return resolved;
}

public void addDependencyManagement( Dependency dep )
{
this.dependencyManagement.add( dep );
}

public void setArtifact( ArtifactReference artifact )
{
this.artifact = artifact;
}

public void setConflicted( boolean conflicted )
{
this.conflicted = conflicted;
}

public void setDependencyManagement( List dependencyManagement )
{
this.dependencyManagement = dependencyManagement;
}

public void setExcludes( Set excludes )
{
this.excludes = excludes;
}

public void setResolved( boolean resolved )
{
this.resolved = resolved;
}

public String toString()
{
return DependencyGraphKeys.toKey( artifact );
}

public boolean isFromParent()
{
return fromParent;
}

public void setFromParent( boolean fromParent )
{
this.fromParent = fromParent;
}
}

+ 289
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyGraphUtils.java View File

@@ -0,0 +1,289 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.AndPredicate;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.functors.NodePredicate;
import org.apache.maven.archiva.dependency.graph.functors.OrphanedNodePredicate;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.Exclusion;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
* Utilities for manipulating the DependencyGraph.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyGraphUtils
{
/**
* Standard way to add a model to the graph.
*
* NOTE: Used by archiva-repository-layer runtime and archiva-dependency-graph tests.
*
* @param model the model to add
* @param graph the graph to add it to
* @param fromNode the node to add it from.
*/
public static void addNodeFromModel( ArchivaProjectModel model, DependencyGraph graph, DependencyGraphNode fromNode )
{
if ( model == null )
{
throw new IllegalStateException( "Unable to add null model for "
+ DependencyGraphKeys.toKey( fromNode.getArtifact() ) );
}

if ( model.getRelocation() != null )
{
// We need to CHANGE this node.
ArtifactReference refTO = new ArtifactReference();

refTO.setGroupId( fromNode.getArtifact().getGroupId() );
refTO.setArtifactId( fromNode.getArtifact().getArtifactId() );
refTO.setVersion( fromNode.getArtifact().getVersion() );
refTO.setClassifier( fromNode.getArtifact().getClassifier() );
refTO.setType( fromNode.getArtifact().getType() );

VersionedReference relocation = model.getRelocation();

if ( StringUtils.isNotBlank( relocation.getGroupId() ) )
{
refTO.setGroupId( relocation.getGroupId() );
}

if ( StringUtils.isNotBlank( relocation.getArtifactId() ) )
{
refTO.setArtifactId( relocation.getArtifactId() );
}

if ( StringUtils.isNotBlank( relocation.getVersion() ) )
{
refTO.setVersion( relocation.getVersion() );
}

DependencyGraphNode nodeTO = new DependencyGraphNode( refTO );

graph.addNode( nodeTO );
collapseNodes( graph, fromNode, nodeTO );
return;
}

boolean isRootNode = graph.getRootNode().equals( fromNode );

Iterator it;

if ( CollectionUtils.isNotEmpty( model.getDependencyManagement() ) )
{
it = model.getDependencyManagement().iterator();
while ( it.hasNext() )
{
Dependency dependency = (Dependency) it.next();
fromNode.addDependencyManagement( dependency );
}
}

if ( CollectionUtils.isNotEmpty( model.getDependencies() ) )
{
it = model.getDependencies().iterator();
while ( it.hasNext() )
{
Dependency dependency = (Dependency) it.next();

String scope = dependency.getScope();

// Test scopes *NOT* from root node can be skipped.
if ( DependencyScope.TEST.equals( scope ) && !isRootNode )
{
// skip add of test scope
continue;
}

ArtifactReference artifactRef = new ArtifactReference();
artifactRef.setGroupId( dependency.getGroupId() );
artifactRef.setArtifactId( dependency.getArtifactId() );
artifactRef.setVersion( dependency.getVersion() );
artifactRef.setClassifier( dependency.getClassifier() );
artifactRef.setType( dependency.getType() );

DependencyGraphNode toNode = new DependencyGraphNode( artifactRef );

if ( CollectionUtils.isNotEmpty( dependency.getExclusions() ) )
{
Iterator itexclusion = dependency.getExclusions().iterator();
while ( itexclusion.hasNext() )
{
Exclusion exclusion = (Exclusion) itexclusion.next();
toNode.addExclude( exclusion );
}
}

if ( dependency.isFromParent() )
{
toNode.setFromParent( true );
}

// Add node (to)
graph.addNode( toNode );

DependencyGraphEdge edge = new DependencyGraphEdge( fromNode.getArtifact(), toNode.getArtifact() );
edge.setScope( StringUtils.defaultIfEmpty( dependency.getScope(), DependencyScope.COMPILE ) );

if ( dependency.isOptional() )
{
edge.setDisabled( true );
edge.setDisabledType( DependencyGraph.DISABLED_OPTIONAL );
edge.setDisabledReason( "Optional Dependency" );
}

graph.addEdge( edge );
}
}

fromNode.setResolved( true );
graph.addNode( fromNode );
}

/**
* Clean out any nodes that may have become orphaned in the graph.
*
* @param graph the graph to check.
*/
public static void cleanupOrphanedNodes( DependencyGraph graph )
{
boolean done = false;

Predicate orphanedNodePredicate = new OrphanedNodePredicate( graph );
Predicate notRootNode = NotPredicate.getInstance( new NodePredicate( graph.getRootNode().getArtifact() ) );
Predicate orphanedChildNodePredicate = AndPredicate.getInstance( notRootNode, orphanedNodePredicate );

while ( !done )
{
// Find orphaned node.
DependencyGraphNode orphanedNode = (DependencyGraphNode) CollectionUtils.find( graph.getNodes(),
orphanedChildNodePredicate );

if ( orphanedNode == null )
{
done = true;
break;
}

// Remove edges FROM orphaned node.
List edgesFrom = graph.getEdgesFrom( orphanedNode );

Iterator it = edgesFrom.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
graph.removeEdge( edge );
}

// Remove orphaned node.
graph.removeNode( orphanedNode );
}
}

/**
* Functionaly similar to {@link #collapseVersions(DependencyGraph, ArtifactReference, String, String)}, but
* in a new, easier to use, format.
*
* 1) Removes the FROM edges connected to the FROM node
* 2) Moves the TO edges connected to the FROM node to the TO node.
* 3) Removes the FROM node (which is now orphaned)
*
* @param graph the graph to perform operation on
* @param nodeFrom the node to collapse from
* @param nodeTo the node to collapse to
*/
public static void collapseNodes( DependencyGraph graph, DependencyGraphNode nodeFROM, DependencyGraphNode nodeTO )
{
Iterator it;

Set edgesToRemove = new HashSet();

// 1) Remove all of the edge.from references from nodeFROM
List fromEdges = graph.getEdgesFrom( nodeFROM );
if ( CollectionUtils.isNotEmpty( fromEdges ) )
{
edgesToRemove.addAll( fromEdges );
}

// 2) Swing all of the edge.to references from nodeFROM to nodeTO.
// System.out.println( "Swinging incoming edges from " + nodeFROM );
// System.out.println( " to " + nodeTO );
List toEdges = graph.getEdgesTo( nodeFROM );
it = toEdges.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();

// Identify old edge to remove.
edgesToRemove.add( edge );

// Clone edge, set edge.to and add to graph.
DependencyGraphEdge newedge = clone( edge );
newedge.setNodeTo( nodeTO );
// System.out.println( " edge from: " + edge );
// System.out.println( " to: " + newedge );
graph.addEdge( newedge );
}

// Actually remove the old edges.
it = edgesToRemove.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
graph.removeEdge( edge );
}

// 3) Remove the nodeFROM
graph.removeNode( nodeFROM );
}

/**
* Create a clone of an edge.
*
* @param edge the edge to clone.
* @return the cloned edge.
*/
public static DependencyGraphEdge clone( DependencyGraphEdge edge )
{
DependencyGraphEdge cloned = new DependencyGraphEdge( edge.getNodeFrom(), edge.getNodeTo() );
cloned.setDisabled( edge.isDisabled() );
cloned.setDisabledReason( edge.getDisabledReason() );
cloned.setDisabledType( edge.getDisabledType() );
cloned.setScope( edge.getScope() );

return cloned;
}
}

+ 57
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/DependencyResolutionEvent.java View File

@@ -0,0 +1,57 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.
*/

/**
* DependencyResolutionEvent
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyResolutionEvent
{
public static final int ADDING_MODEL = 1;

public static final int DEP_CONFLICT_OMIT_FOR_NEARER = 2;

public static final int CYCLE_BROKEN = 3;

public static final int APPLYING_DEPENDENCY_MANAGEMENT = 4;

private int type;

private DependencyGraph graph;

public DependencyResolutionEvent( int type, DependencyGraph graph )
{
this.type = type;
this.graph = graph;
}

public DependencyGraph getGraph()
{
return graph;
}

public int getType()
{
return type;
}
}

+ 16
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphListener.java View File

@@ -0,0 +1,16 @@
package org.apache.maven.archiva.dependency.graph;

/**
* GraphListener
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface GraphListener
{
public void graphError( GraphTaskException e, DependencyGraph currentGraph );

public void graphPhaseEvent( GraphPhaseEvent event );

public void dependencyResolutionEvent( DependencyResolutionEvent event );
}

+ 79
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphPhaseEvent.java View File

@@ -0,0 +1,79 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.
*/

/**
* GraphPhaseEvent
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class GraphPhaseEvent
{
/**
* Graph Phase Event Type - New Graph has been created. No tasks have been run yet.
* NOTE: {{@link #getTask()} will be null for this type.
*/
public static final int GRAPH_NEW = 0;

/**
* Graph Phase Event Type - Graph Task is about to run.
*/
public static final int GRAPH_TASK_PRE = 1;

/**
* Graph Phase Event Type - Graph Task has finished.
*/
public static final int GRAPH_TASK_POST = 2;

/**
* Graph Phase Event Type - All Graph Tasks are done.
* NOTE: {{@link #getTask()} will be null for this type.
*/
public static final int GRAPH_DONE = 10;

private int type;
private GraphTask task;

private DependencyGraph graph;

public GraphPhaseEvent( int type, GraphTask task, DependencyGraph graph )
{
this.type = type;
this.task = task;
this.graph = graph;
}

public DependencyGraph getGraph()
{
return graph;
}

public GraphTask getTask()
{
return task;
}

public int getType()
{
return type;
}
}

+ 44
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphTask.java View File

@@ -0,0 +1,44 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.
*/

/**
* A Graph Task.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface GraphTask
{
/**
* Get the id for this task.
*
* @return the id for this task. (used in Exception messages and {@link GraphPhaseEvent})
*/
public String getTaskId();

/**
* Execute the Graph Task.
*
* @param graph the graph to execute the task on.
*/
public void executeTask( DependencyGraph graph )
throws GraphTaskException;
}

+ 42
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/GraphTaskException.java View File

@@ -0,0 +1,42 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.common.ArchivaException;

/**
* GraphTaskException
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class GraphTaskException
extends ArchivaException
{
public GraphTaskException( String message, Throwable cause )
{
super( message, cause );
}

public GraphTaskException( String message )
{
super( message );
}
}

+ 31
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/PotentialCyclicEdgeProducer.java View File

@@ -0,0 +1,31 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.
*/

/**
* A tag for a {@link GraphTask} that has the potential to produce a cyclic edge.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface PotentialCyclicEdgeProducer
{
/* no interface, just a tag */
}

+ 55
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeCyclicPredicate.java View File

@@ -0,0 +1,55 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;

/**
* EdgeCyclicPredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeCyclicPredicate
implements Predicate
{
private static Predicate INSTANCE = new EdgeCyclicPredicate();

public static Predicate getInstance()
{
return INSTANCE;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = ( edge.isDisabled() && ( edge.getDisabledType() == DependencyGraph.DISABLED_CYCLIC ) );
}

return satisfies;
}

}

+ 48
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeDisabledPredicate.java View File

@@ -0,0 +1,48 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;

/**
* EdgeDisabledPredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeDisabledPredicate
implements Predicate
{

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = edge.isDisabled();
}

return satisfies;
}

}

+ 71
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeExactScopePredicate.java View File

@@ -0,0 +1,71 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.model.DependencyScope;

/**
* EdgeExactScopePredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeExactScopePredicate
implements Predicate
{
private String scope;

public EdgeExactScopePredicate( String scope )
{
this.scope = scope;
}

public EdgeExactScopePredicate()
{
// The universal default for scope.
this.scope = DependencyScope.COMPILE;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = StringUtils.equals( edge.getScope(), scope );
}

return satisfies;
}

public String getScope()
{
return scope;
}

public void setScope( String scope )
{
this.scope = scope;
}
}

+ 54
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeExcludedPredicate.java View File

@@ -0,0 +1,54 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;

/**
* EdgeExcludedPredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeExcludedPredicate
implements Predicate
{
private static Predicate INSTANCE = new EdgeExcludedPredicate();

public static Predicate getInstance()
{
return INSTANCE;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = ( edge.isDisabled() && ( edge.getDisabledType() == DependencyGraph.DISABLED_EXCLUDED ) );
}

return satisfies;
}
}

+ 62
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeFromPredicate.java View File

@@ -0,0 +1,62 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.model.ArtifactReference;

/**
* Predicate returns true on any DependencyGraphEdge which has a
* specific FROM node.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeFromPredicate
implements Predicate
{
private ArtifactReference nodeRef;

public EdgeFromPredicate( ArtifactReference ref )
{
this.nodeRef = ref;
}

public EdgeFromPredicate( DependencyGraphNode node )
{
this( node.getArtifact() );
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = edge.getNodeFrom().equals( nodeRef );
}

return satisfies;
}

}

+ 49
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeScopeClosure.java View File

@@ -0,0 +1,49 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Closure;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;

/**
* Closure to set the edge scope.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeScopeClosure
implements Closure
{
private String scope;

public EdgeScopeClosure( String scope )
{
this.scope = scope;
}

public void execute( Object input )
{
if ( input instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) input;
edge.setScope( scope );
}
}
}

+ 55
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeToPredicate.java View File

@@ -0,0 +1,55 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.model.ArtifactReference;

/**
* EdgeToPredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeToPredicate
implements Predicate
{
private ArtifactReference nodeRef;

public EdgeToPredicate( ArtifactReference ref )
{
this.nodeRef = ref;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = edge.getNodeTo().equals( nodeRef );
}

return satisfies;
}

}

+ 54
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/EdgeWithinScopePredicate.java View File

@@ -0,0 +1,54 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.model.DependencyScope;

/**
* EdgeWithinScopePredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class EdgeWithinScopePredicate
implements Predicate
{
private String scope;

public EdgeWithinScopePredicate( String scope )
{
this.scope = scope;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = DependencyScope.isWithinScope( edge.getScope(), scope );
}

return satisfies;
}
}

+ 46
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/NodeFromParentPredicate.java View File

@@ -0,0 +1,46 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;

/**
* Predicate for nodes that are flagged as from parent pom reference.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class NodeFromParentPredicate
implements Predicate
{

public boolean evaluate( Object object )
{
boolean satisfies = false;
if ( object instanceof DependencyGraphNode )
{
DependencyGraphNode node = (DependencyGraphNode) object;
satisfies = node.isFromParent();
}
return satisfies;
}

}

+ 54
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/NodeInEdgePredicate.java View File

@@ -0,0 +1,54 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.model.ArtifactReference;

/**
* NodeInEdgePredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class NodeInEdgePredicate
implements Predicate
{
private ArtifactReference nodeRef;

public NodeInEdgePredicate( ArtifactReference ref )
{
this.nodeRef = ref;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
satisfies = ( edge.getNodeFrom().equals( nodeRef ) || edge.getNodeTo().equals( nodeRef ) );
}

return satisfies;
}
}

+ 59
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/NodePredicate.java View File

@@ -0,0 +1,59 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.model.ArtifactReference;

/**
* NodePredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class NodePredicate
implements Predicate
{
private ArtifactReference ref;

public NodePredicate( ArtifactReference ref )
{
this.ref = ref;
}

public NodePredicate( DependencyGraphNode node )
{
this( node.getArtifact() );
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphNode )
{
DependencyGraphNode node = (DependencyGraphNode) object;
satisfies = ref.equals( node.getArtifact() );
}

return satisfies;
}
}

+ 56
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/OrphanedNodePredicate.java View File

@@ -0,0 +1,56 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;

/**
* OrphanedNodePredicate
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class OrphanedNodePredicate
implements Predicate
{
private DependencyGraph graph;

public OrphanedNodePredicate( DependencyGraph graph )
{
this.graph = graph;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphNode )
{
DependencyGraphNode node = (DependencyGraphNode) object;
satisfies = CollectionUtils.isEmpty( graph.getEdgesTo( node ) );
}

return satisfies;
}

}

+ 43
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/ToArtifactReferenceTransformer.java View File

@@ -0,0 +1,43 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Transformer;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;

/**
* Transform some common dependency graph objects into their
* ArtifactReference form.
*/
public class ToArtifactReferenceTransformer
implements Transformer
{
public Object transform( Object input )
{
if ( input instanceof DependencyGraphNode )
{
return ( (DependencyGraphNode) input ).getArtifact();
}

// TODO: Add more objects to transform here.

return input;
}
}

+ 53
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/functors/UnresolvedGraphNodePredicate.java View File

@@ -0,0 +1,53 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;

/**
* Predicate for unresolved {@link DependencyGraphNode} objects.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class UnresolvedGraphNodePredicate
implements Predicate
{
private static UnresolvedGraphNodePredicate INSTANCE = new UnresolvedGraphNodePredicate();

public static Predicate getInstance()
{
return INSTANCE;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphNode )
{
DependencyGraphNode node = (DependencyGraphNode) object;
satisfies = !( node.isResolved() );
}

return satisfies;
}
}

+ 43
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/AbstractReduceEdgeVisitor.java View File

@@ -0,0 +1,43 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;

/**
* AbstractReduceEdgeVisitor
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractReduceEdgeVisitor
extends BaseVisitor
implements DependencyGraphVisitor
{
public void finishGraph( DependencyGraph graph )
{
super.finishGraph( graph );
DependencyGraphUtils.cleanupOrphanedNodes( graph );
}
}

+ 218
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/DependencyManagementApplier.java View File

@@ -0,0 +1,218 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
import org.apache.maven.archiva.dependency.graph.tasks.DependencyManagementStack.Rules;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* Takes a stack of DependencyManagement objects and applies them to the node in question.
* This merely sets the version / scope / and exclusions on the nodes, as defined by DependencyManagement.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyManagementApplier
extends BaseVisitor
implements DependencyGraphVisitor
{
private DependencyManagementStack depStack = new DependencyManagementStack();

private DependencyGraphBuilder builder;

/**
* Map of changes to node versions (that will likely cause a reorganization of
* the graph), this is tracked until the walk is complete, at which point the
* changes are applied to the graph.
*
* Performing graph changes of this scope during a walk of graph is hazardous,
* as you will be moving nodes around, mergeing nodes, dropping edges, etc.
*/
private Map nodeVersionChanges = new HashMap();

private int nodesAdded = 0;

public void discoverGraph( DependencyGraph graph )
{
super.discoverGraph( graph );
nodeVersionChanges.clear();
depStack.reset();
nodesAdded = 0;
}

public void discoverNode( DependencyGraphNode node )
{
super.discoverNode( node );

depStack.push( node );

List edgesFrom = graph.getEdgesFrom( node );
Iterator it = edgesFrom.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
Rules rules = depStack.getRules( edge );

if ( rules == null )
{
// No rules for edge, skip it.
continue;
}

DependencyGraphNode subnode = graph.getNode( edge.getNodeTo() );

/* There are 3 steps to processing the DependencyManagement. */

/* 1) Add exclusions to node ________________________________________________ */
node.getExcludes().addAll( rules.exclusions );

/* 2) Track version changes to node _________________________________________ */

// This is the version as specified by the rules.
String specifiedVersion = rules.artifact.getVersion();

// This is the version as being tracked by the nodeVersionChanges map.
String trackedVersion = (String) nodeVersionChanges.get( edge.getNodeTo() );

// This is the version of the subnode.
String nodeVersion = subnode.getArtifact().getVersion();

// This is the actual version as determined by tracked and subnode
String actualVersion = StringUtils.defaultString( trackedVersion, nodeVersion );

// If the specified version changes the actual version ...
if ( !StringUtils.equals( specifiedVersion, actualVersion ) )
{
// ... save this new value to be track ( for processing in #finishedGraph )
nodeVersionChanges.put( edge.getNodeTo(), specifiedVersion );
}

/* 3) Update scope to edge __________________________________________________ */

if ( StringUtils.isNotBlank( rules.scope ) )
{
edge.setScope( rules.scope );
}
}
}

public void finishNode( DependencyGraphNode node )
{
super.finishNode( node );

depStack.pop();
}

public void finishGraph( DependencyGraph graph )
{
super.finishGraph( graph );

Iterator it = this.nodeVersionChanges.keySet().iterator();
while ( it.hasNext() )
{
ArtifactReference ref = (ArtifactReference) it.next();
String toVersion = (String) this.nodeVersionChanges.get( ref );

collapseVersions( graph, ref, ref.getVersion(), toVersion );
}
}

/**
* Collapses Versions of nodes.
*
* Takes two nodes, with differing versions.
*
* 1) Removes the FROM edges connected to the FROM node
* 2) Moves the TO edges connected to the FROM node to the TO node.
* 3) Removes the FROM node (which is now orphaned)
*
* @param graph the graph to perform operation on
* @param fromRef the artifact reference of the FROM node.
* @param fromVersion the version of the FROM node
* @param toVersion the version of the TO node
*/
private void collapseVersions( DependencyGraph graph, ArtifactReference fromRef, String fromVersion,
String toVersion )
{
if ( StringUtils.equals( fromVersion, toVersion ) )
{
// No point in doing anything. nothing has changed.
return;
}

ArtifactReference toRef = new ArtifactReference();
toRef.setGroupId( fromRef.getGroupId() );
toRef.setArtifactId( fromRef.getArtifactId() );
toRef.setVersion( toVersion );
toRef.setClassifier( fromRef.getClassifier() );
toRef.setType( fromRef.getType() );

DependencyGraphNode nodeFROM = graph.getNode( fromRef );
DependencyGraphNode nodeTO = graph.getNode( toRef );

if ( nodeTO == null )
{
// new node doesn't exist in graph (yet)
nodeTO = new DependencyGraphNode( toRef );
nodeTO.setResolved( false );

graph.addNode( nodeTO );

VersionedReference projectRef = new VersionedReference();
projectRef.setGroupId( toRef.getGroupId() );
projectRef.setArtifactId( toRef.getArtifactId() );
projectRef.setVersion( toRef.getVersion() );

builder.resolveNode( graph, nodeTO, projectRef );
nodesAdded++;
}

DependencyGraphUtils.collapseNodes( graph, nodeFROM, nodeTO );
}

public DependencyGraphBuilder getBuilder()
{
return builder;
}

public void setBuilder( DependencyGraphBuilder builder )
{
this.builder = builder;
}

public boolean hasCreatedNodes()
{
return ( nodesAdded > 0 );
}
}

+ 152
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/DependencyManagementStack.java View File

@@ -0,0 +1,152 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.collections.iterators.ReverseListIterator;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.Exclusion;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

/**
* DependencyManagementStack
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyManagementStack
{
public class Rules
{
public ArtifactReference artifact;

public String scope;

public Set exclusions = new HashSet();

public void addAllExclusions( List depExclusions )
{
Iterator it = depExclusions.iterator();
while ( it.hasNext() )
{
Exclusion ref = (Exclusion) it.next();
String key = DependencyGraphKeys.toManagementKey( ref );
exclusions.add( key );
}
}
}

private Stack depmanStack = new Stack();

private Map depMap = new HashMap();

private void generateDepMap()
{
depMap.clear();

// Using a reverse iterator to ensure that we read the
// stack from last in to first in
ReverseListIterator it = new ReverseListIterator( depmanStack );
while ( it.hasNext() )
{
DependencyGraphNode node = (DependencyGraphNode) it.next();

addDependencies( node.getDependencyManagement() );
}
}

private void addDependencies( List dependencies )
{
Iterator it = dependencies.iterator();
while ( it.hasNext() )
{
Dependency dep = (Dependency) it.next();
String key = DependencyGraphKeys.toManagementKey( dep );

Rules merged = (Rules) depMap.get( key );
if ( merged == null )
{
// New map entry.
merged = new Rules();
merged.artifact = new ArtifactReference();
merged.artifact.setGroupId( dep.getGroupId() );
merged.artifact.setArtifactId( dep.getArtifactId() );
merged.artifact.setClassifier( dep.getClassifier() );
merged.artifact.setType( dep.getType() );
}

merged.artifact.setVersion( dep.getVersion() );
if ( StringUtils.isNotBlank( dep.getScope() ) )
{
merged.scope = dep.getScope();
}

merged.addAllExclusions( dep.getExclusions() );

depMap.put( key, merged );
}
}

public Rules getRules( DependencyGraphEdge edge )
{
return getRules( edge.getNodeTo() );
}

public Rules getRules( DependencyGraphNode node )
{
return getRules( node.getArtifact() );
}

public Rules getRules( ArtifactReference ref )
{
String key = DependencyGraphKeys.toManagementKey( ref );
return (Rules) depMap.get( key );
}

public void push( DependencyGraphNode node )
{
depmanStack.push( node );
generateDepMap();
}

public DependencyGraphNode pop()
{
DependencyGraphNode node = (DependencyGraphNode) depmanStack.pop();
generateDepMap();
return node;
}

public void reset()
{
depmanStack.clear();
depMap.clear();
}
}

+ 34
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagCyclicEdgesTask.java View File

@@ -0,0 +1,34 @@
package org.apache.maven.archiva.dependency.graph.tasks;

import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* FlagCyclicEdgesTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="flag-cyclic-edges"
* instantiation-strategy="per-lookup"
*/
public class FlagCyclicEdgesTask
implements GraphTask
{

public void executeTask( DependencyGraph graph )
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();
FlagExcludedEdgesVisitor excludedEdgeResolver = new FlagExcludedEdgesVisitor();
walker.visit( graph, excludedEdgeResolver );
}

public String getTaskId()
{
return "flag-cyclic-edges";
}
}

+ 70
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagCyclicEdgesVisitor.java View File

@@ -0,0 +1,70 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.HashSet;
import java.util.Set;

/**
* FlagCyclicEdgesVisitor
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class FlagCyclicEdgesVisitor
extends BaseVisitor
implements DependencyGraphVisitor
{
private DependencyGraphWalker walker;

private Set cyclicEdges = new HashSet();

public FlagCyclicEdgesVisitor( DependencyGraphWalker walker )
{
this.walker = walker;
}

public void discoverEdge( DependencyGraphEdge edge )
{
ArtifactReference artifact = edge.getNodeTo();

// Process for cyclic edges.
if ( walker.getNodeVisitState( artifact ) == DependencyGraphWalker.PROCESSING )
{
edge.setDisabled( true );
edge.setDisabledType( DependencyGraph.DISABLED_CYCLIC );
edge.setDisabledReason( "Cycle detected" );
// TODO: insert into reason the path for the cycle that was detected.
cyclicEdges.add( edge );
}
}

public Set getCyclicEdges()
{
return cyclicEdges;
}
}

+ 52
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagExcludedEdgesTask.java View File

@@ -0,0 +1,52 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* FlagExcludedEdgesTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="flag-excluded-edges"
* instantiation-strategy="per-lookup"
*/
public class FlagExcludedEdgesTask
implements GraphTask
{
public void executeTask( DependencyGraph graph )
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();
FlagExcludedEdgesVisitor excludedEdgeResolver = new FlagExcludedEdgesVisitor();
walker.visit( graph, excludedEdgeResolver );
}

public String getTaskId()
{
return "flag-excluded-edges";
}
}

+ 86
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/FlagExcludedEdgesVisitor.java View File

@@ -0,0 +1,86 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.Iterator;
import java.util.Stack;

/**
* FlagExcludedEdgesVisitor
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class FlagExcludedEdgesVisitor
extends BaseVisitor
implements DependencyGraphVisitor
{
private Stack nodePath = new Stack();

public void discoverEdge( DependencyGraphEdge edge )
{
ArtifactReference artifact = edge.getNodeTo();
// Process for excluded edges.
String toKey = DependencyGraphKeys.toManagementKey( artifact );
Iterator it = this.nodePath.iterator();
while ( it.hasNext() )
{
DependencyGraphNode pathNode = (DependencyGraphNode) it.next();
// Process dependency declared exclusions.
if ( pathNode.getExcludes().contains( toKey ) )
{
edge.setDisabled( true );
edge.setDisabledType( DependencyGraph.DISABLED_EXCLUDED );
String whoExcluded = DependencyGraphKeys.toKey( pathNode );
edge.setDisabledReason( "Specifically Excluded by " + whoExcluded );
break;
}
}
}

public void discoverNode( DependencyGraphNode node )
{
super.discoverNode( node );
nodePath.push( node );
}

public void finishNode( DependencyGraphNode node )
{
super.finishNode( node );
DependencyGraphNode pathNode = (DependencyGraphNode) nodePath.pop();
if ( !node.equals( pathNode ) )
{
String pathNodeKey = ArtifactReference.toKey( pathNode.getArtifact() );
String finishNodeKey = ArtifactReference.toKey( node.getArtifact() );
throw new IllegalStateException( "Encountered bad visitor state. Expected finish on node " + pathNodeKey
+ ", but instead got notified of node " + finishNodeKey );
}
}
}

+ 81
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/GraphCopier.java View File

@@ -0,0 +1,81 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;

/**
* GraphCopier
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class GraphCopier
extends BaseVisitor
implements DependencyGraphVisitor
{
protected DependencyGraph copiedGraph;

public DependencyGraph getGraph()
{
return copiedGraph;
}

public void setGraph( DependencyGraph graph )
{
this.copiedGraph = graph;
}

public void discoverNode( DependencyGraphNode node )
{
if ( copiedGraph == null )
{
copiedGraph = new DependencyGraph( node );
}
}

/**
* Be sure to override and NOT call this method in your sub class,
* if you want to copy edges based on some kind of criteria.
*/
public void discoverEdge( DependencyGraphEdge edge )
{
copyEdge( edge );
}

public void copyEdge( DependencyGraphEdge edge )
{
DependencyGraphNode nodeFrom = graph.getNode( edge.getNodeFrom() );
DependencyGraphNode nodeTo = graph.getNode( edge.getNodeTo() );

this.copiedGraph.addNode( nodeFrom );
this.copiedGraph.addNode( nodeTo );
this.copiedGraph.addEdge( edge );
}

public void reset()
{
this.copiedGraph = null;
}
}

+ 53
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/PopulateDependencyManagementTask.java View File

@@ -0,0 +1,53 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.PotentialCyclicEdgeProducer;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* PopulateDependencyManagementTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="populate-dependency-management"
* instantiation-strategy="per-lookup"
*/
public class PopulateDependencyManagementTask
implements GraphTask, PotentialCyclicEdgeProducer
{
public void executeTask( DependencyGraph graph )
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();
DependencyManagementApplier depManApplier = new DependencyManagementApplier();
walker.visit( graph, depManApplier );
}

public String getTaskId()
{
return "populate-dependency-management";
}
}

+ 92
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/PopulateGraphMasterTask.java View File

@@ -0,0 +1,92 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.GraphTaskException;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* PopulateGraphMasterTask - will perform a resolve / depman apply loop until the graph is fully populated.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="populate-graph"
* instantiation-strategy="per-lookup"
*/
public class PopulateGraphMasterTask
implements GraphTask
{
private DependencyGraphBuilder builder;

private ResolveGraphTask resolveGraphTask = new ResolveGraphTask();

private DependencyManagementApplier depManApplier = new DependencyManagementApplier();

public void executeTask( DependencyGraph graph )
throws GraphTaskException
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();

boolean done = false;
int maxiters = 5;

while ( !done )
{
resolveGraphTask.executeTask( graph );
walker.visit( graph, depManApplier );

if ( !depManApplier.hasCreatedNodes() || ( maxiters < 0 ) )
{
done = true;
break;
}

maxiters--;
}

DependencyGraphUtils.cleanupOrphanedNodes( graph );
}

public String getTaskId()
{
return "populate-graph";
}

public DependencyGraphBuilder getBuilder()
{
return builder;
}

public void setBuilder( DependencyGraphBuilder builder )
{
this.builder = builder;
this.resolveGraphTask.setBuilder( builder );
this.depManApplier.setBuilder( builder );
}

}

+ 35
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceEnabledEdgesTask.java View File

@@ -0,0 +1,35 @@
package org.apache.maven.archiva.dependency.graph.tasks;

import org.apache.commons.collections.functors.TruePredicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* ReduceEnabledEdgesTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="reduce-enabled-edges"
* instantiation-strategy="per-lookup"
*/
public class ReduceEnabledEdgesTask
implements GraphTask
{
public void executeTask( DependencyGraph graph )
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();
walker.setEdgePredicate( TruePredicate.getInstance() );
ReduceEnabledEdgesVisitor reduceEnabledEdgesResolver = new ReduceEnabledEdgesVisitor();
walker.visit( graph, reduceEnabledEdgesResolver );
}

public String getTaskId()
{
return "reduce-enabled-edges";
}
}

+ 42
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceEnabledEdgesVisitor.java View File

@@ -0,0 +1,42 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;

/**
* Removes all disabled edges from the graph.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ReduceEnabledEdgesVisitor
extends AbstractReduceEdgeVisitor
implements DependencyGraphVisitor
{
public void discoverEdge( DependencyGraphEdge edge )
{
if ( edge.isDisabled() )
{
super.graph.removeEdge( edge );
}
}
}

+ 50
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceScopeTask.java View File

@@ -0,0 +1,50 @@
package org.apache.maven.archiva.dependency.graph.tasks;

import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* ReduceScopeTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="reduce-scope"
* instantiation-strategy="per-lookup"
*/
public class ReduceScopeTask
implements GraphTask
{
private String scope;

public ReduceScopeTask( String scope )
{
this.scope = scope;
}

public void executeTask( DependencyGraph graph )
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();
ReduceScopeVisitor reduceScopeResolver = new ReduceScopeVisitor( this.scope );
walker.visit( graph, reduceScopeResolver );
}

public String getScope()
{
return scope;
}

public void setScope( String scope )
{
this.scope = scope;
}

public String getTaskId()
{
return "reduce-scope";
}
}

+ 51
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceScopeVisitor.java View File

@@ -0,0 +1,51 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.functors.EdgeWithinScopePredicate;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;

/**
* ReduceScopeVisitor
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ReduceScopeVisitor
extends AbstractReduceEdgeVisitor
implements DependencyGraphVisitor
{
private Predicate scopedPredicate;

public ReduceScopeVisitor( String scope )
{
scopedPredicate = new EdgeWithinScopePredicate( scope );
}

public void discoverEdge( DependencyGraphEdge edge )
{
if ( !scopedPredicate.evaluate( edge ) )
{
super.graph.removeEdge( edge );
}
}
}

+ 53
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceTransitiveEdgesTask.java View File

@@ -0,0 +1,53 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkBreadthFirstSearch;

/**
* ReduceTransitiveEdgesTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="reduce-transitive-edges"
* instantiation-strategy="per-lookup"
*/
public class ReduceTransitiveEdgesTask
implements GraphTask
{

public void executeTask( DependencyGraph graph )
{
DependencyGraphWalker walker = new WalkBreadthFirstSearch();
ReduceTransitiveEdgesVisitor reduceTransitiveEdgesResolver = new ReduceTransitiveEdgesVisitor();
walker.visit( graph, reduceTransitiveEdgesResolver );
}

public String getTaskId()
{
return "reduce-transitive-edges";
}
}

+ 161
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ReduceTransitiveEdgesVisitor.java View File

@@ -0,0 +1,161 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* Perform a transitive reduction of the graph.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ReduceTransitiveEdgesVisitor
extends AbstractReduceEdgeVisitor
implements DependencyGraphVisitor
{
class EdgeInfo
{
public DependencyGraphEdge edge;

public int depth = Integer.MAX_VALUE;
}

class EdgeInfoDepthComparator
implements Comparator
{
public int compare( Object obj0, Object obj1 )
{
EdgeInfo edgeInfo0 = (EdgeInfo) obj0;
EdgeInfo edgeInfo1 = (EdgeInfo) obj1;

return edgeInfo0.depth - edgeInfo1.depth;
}
}

/**
* A Map of &lt;(Node To) ArtifactReference, Map of &lt;(Node From) ArtifactReference, EdgeInfo&gt;&gt;
*/
private Map /*<ArtifactReference,<ArtifactReference,EdgeInfo>>*/nodeDistanceMap = new HashMap();

private int currentDepth;

public void discoverGraph( DependencyGraph graph )
{
super.discoverGraph( graph );
nodeDistanceMap.clear();
currentDepth = 0;
}

public void discoverEdge( DependencyGraphEdge edge )
{
/* WARNING: it is unwise to remove the edge at this point.
* as modifying the graph as it's being walked is dangerous.
*
* Just record the edge's current depth.
*/

String nodeTo = DependencyGraphKeys.toKey( edge.getNodeTo() );
String nodeFrom = DependencyGraphKeys.toKey( edge.getNodeFrom() );

// Get sub-map
Map edgeInfoMap = (Map) nodeDistanceMap.get( nodeTo );

// Create sub-map if not present (yet)
if ( edgeInfoMap == null )
{
edgeInfoMap = new HashMap();
nodeDistanceMap.put( nodeTo, edgeInfoMap );
}

// Get sub-map-value.
EdgeInfo edgeInfo = (EdgeInfo) edgeInfoMap.get( nodeFrom );

if ( edgeInfo == null )
{
// Create a new edgeinfo.
edgeInfo = new EdgeInfo();
edgeInfo.edge = edge;
edgeInfo.depth = currentDepth;
edgeInfoMap.put( nodeFrom, edgeInfo );
}
// test the current depth, if it is less than previous depth, save it
else if ( currentDepth < edgeInfo.depth )
{
edgeInfo.depth = currentDepth;
edgeInfoMap.put( nodeFrom, edgeInfo );
}

nodeDistanceMap.put( nodeTo, edgeInfoMap );
}

public void discoverNode( DependencyGraphNode node )
{
super.discoverNode( node );
currentDepth++;

}

public void finishNode( DependencyGraphNode node )
{
super.finishNode( node );
currentDepth--;
}

public void finishGraph( DependencyGraph graph )
{
super.finishGraph( graph );

// Now we prune/remove the edges that are transitive in nature.

Comparator edgeInfoDepthComparator = new EdgeInfoDepthComparator();

Iterator it = nodeDistanceMap.values().iterator();
while ( it.hasNext() )
{
Map edgeInfoMap = (Map) it.next();

if ( edgeInfoMap.size() > 1 )
{
List edgeInfos = new ArrayList();
edgeInfos.addAll( edgeInfoMap.values() );
Collections.sort( edgeInfos, edgeInfoDepthComparator );

for ( int i = 1; i < edgeInfos.size(); i++ )
{
EdgeInfo edgeInfo = (EdgeInfo) edgeInfos.get( i );
graph.removeEdge( edgeInfo.edge );
}
}
}
}
}

+ 98
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/RefineConflictsTask.java View File

@@ -0,0 +1,98 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.MultiValueMap;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.PotentialCyclicEdgeProducer;
import org.apache.maven.archiva.dependency.graph.functors.ToArtifactReferenceTransformer;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
* RefineConflictsTask
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="refine-conflicts"
* instantiation-strategy="per-lookup"
*/
public class RefineConflictsTask
implements GraphTask, PotentialCyclicEdgeProducer
{

public void executeTask( DependencyGraph graph )
{
Iterator it;
DependencyGraphWalker walker = new WalkDepthFirstSearch();
RefineConflictsVisitor refineConflictsVisitor = new RefineConflictsVisitor();
MultiValueMap depMap = new MultiValueMap();

// Identify deps that need to be resolved.
it = graph.getNodes().iterator();
while ( it.hasNext() )
{
DependencyGraphNode node = (DependencyGraphNode) it.next();
String key = DependencyGraphKeys.toManagementKey( node.getArtifact() );
// This will add this node to the specified key, not replace a previous one.
depMap.put( key, node );
}

// Process those depMap entries with more than 1 value.
ToArtifactReferenceTransformer nodeToArtifact = new ToArtifactReferenceTransformer();

it = depMap.entrySet().iterator();
while ( it.hasNext() )
{
Map.Entry entry = (Entry) it.next();
Collection nodes = (Collection) entry.getValue();
if ( nodes.size() > 1 )
{
List conflictingArtifacts = new ArrayList();
conflictingArtifacts.addAll( nodes );
CollectionUtils.transform( conflictingArtifacts, nodeToArtifact );

refineConflictsVisitor.resetConflictingArtifacts();
refineConflictsVisitor.addAllConflictingArtifacts( conflictingArtifacts );
walker.visit( graph, refineConflictsVisitor );
}
}
}

public String getTaskId()
{
return "refine-conflicts";
}
}

+ 303
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/RefineConflictsVisitor.java View File

@@ -0,0 +1,303 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.comparators.ReverseComparator;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.collections.list.TypedList;
import org.apache.maven.archiva.common.utils.VersionComparator;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* RefineConflictsVisitor
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class RefineConflictsVisitor
extends BaseVisitor
implements DependencyGraphVisitor
{
class DepthComparator
implements Comparator
{
public int compare( Object obj0, Object obj1 )
{
NodeLocation nodeLoc0 = (NodeLocation) obj0;
NodeLocation nodeLoc1 = (NodeLocation) obj1;

return nodeLoc0.depth - nodeLoc1.depth;
}
}

class NodeLocation
{
public ArtifactReference artifact;

public DependencyGraphEdge edge;

public int depth;

public NodeLocation( ArtifactReference artifact, DependencyGraphEdge edge, int depth )
{
this.artifact = artifact;
this.edge = edge;
this.depth = depth;
}
}

class NodeLocationPredicate
implements Predicate
{
private ArtifactReference artifact;

public NodeLocationPredicate( ArtifactReference artifact )
{
this.artifact = artifact;
}

public NodeLocationPredicate( DependencyGraphNode node )
{
this( node.getArtifact() );
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof NodeLocation )
{
NodeLocation nodeloc = (NodeLocation) object;
satisfies = nodeloc.artifact.equals( artifact );
}

return satisfies;
}

}

class NodeLocationVersionComparator
implements Comparator
{
public int compare( Object o1, Object o2 )
{
if ( o1 == null && o2 == null )
{
return 0;
}

if ( o1 == null && o2 != null )
{
return 1;
}

if ( o1 != null && o2 == null )
{
return -1;
}

if ( ( o1 instanceof NodeLocation ) && ( o2 instanceof NodeLocation ) )
{
String version1 = ( (NodeLocation) o1 ).artifact.getVersion();
String version2 = ( (NodeLocation) o2 ).artifact.getVersion();

VersionComparator.getInstance().compare( version1, version2 );
}

return 0;
}
}

class DistantNodeLocationPredicate
implements Predicate
{
private int cutoff;

public DistantNodeLocationPredicate( int distantCutoff )
{
this.cutoff = distantCutoff;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof NodeLocation )
{
NodeLocation nodeloc = (NodeLocation) object;
satisfies = ( nodeloc.depth >= this.cutoff );
}

return satisfies;
}
}

private List conflictingArtifacts;

private Map foundNodesMap = new HashMap();

private int currentDepth = 0;

private DependencyGraph currentGraph;

public RefineConflictsVisitor()
{
conflictingArtifacts = TypedList.decorate( new ArrayList(), ArtifactReference.class );
}

public void discoverGraph( DependencyGraph graph )
{
super.discoverGraph( graph );
this.currentGraph = graph;
this.foundNodesMap.clear();
}

public void discoverNode( DependencyGraphNode node )
{
super.discoverNode( node );

currentDepth++;

List edgesFrom = currentGraph.getEdgesFrom( node );
Iterator it = edgesFrom.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
if ( this.conflictingArtifacts.contains( edge.getNodeTo() ) )
{
String nodeKey = DependencyGraphKeys.toKey( edge.getNodeTo() );
// Check for existing NodeLocation with same key
NodeLocation nodeloc = (NodeLocation) this.foundNodesMap.get( nodeKey );

if ( ( nodeloc == null ) || ( currentDepth < nodeloc.depth ) )
{
nodeloc = new NodeLocation( edge.getNodeTo(), edge, currentDepth );
this.foundNodesMap.put( nodeKey, nodeloc );
}
}
}
}

public void finishGraph( DependencyGraph graph )
{
super.finishGraph( graph );

if ( MapUtils.isEmpty( this.foundNodesMap ) )
{
return;
}

// Find winning node.
ArtifactReference winningArtifact = findWinningArtifact( this.foundNodesMap.values() );
DependencyGraphNode winningNode = graph.getNode( winningArtifact );

// Gather up Losing Nodes.
Set losingNodes = new HashSet();
Predicate losersPredicate = NotPredicate.getInstance( new NodeLocationPredicate( winningArtifact ) );
CollectionUtils.select( this.foundNodesMap.values(), losersPredicate, losingNodes );

// Swing losing nodes to winning node.
Iterator it = losingNodes.iterator();
while ( it.hasNext() )
{
NodeLocation losingNodeLoc = (NodeLocation) it.next();
DependencyGraphNode losingNode = graph.getNode( losingNodeLoc.artifact );
DependencyGraphUtils.collapseNodes( graph, losingNode, winningNode );
}
}

private ArtifactReference findWinningArtifact( Collection nodes )
{
List remainingNodes = new ArrayList();
remainingNodes.addAll( nodes );

/* .\ Filter by Depth \.____________________________________________________ */

// Sort by depth.
Collections.sort( remainingNodes, new DepthComparator() );

// Determine 'closest' node depth.
NodeLocation nearestNode = (NodeLocation) remainingNodes.get( 0 );
int nearest = nearestNode.depth;

// Filter out distant nodes.
Predicate distantLocations = new DistantNodeLocationPredicate( nearest );
CollectionUtils.filter( remainingNodes, distantLocations );

// Do we have 1 node left?
if ( remainingNodes.size() == 1 )
{
// A winner!
NodeLocation nodeloc = (NodeLocation) remainingNodes.get( 0 );
return nodeloc.artifact;
}

/* .\ Filter by Newest Version \.___________________________________________ */

// We have 2 or more nodes that are equal distance from the root.
// Determine which one is 'newest' based on version id.
Collections.sort( remainingNodes, new ReverseComparator( new NodeLocationVersionComparator() ) );

NodeLocation nodeloc = (NodeLocation) remainingNodes.get( 0 );
return nodeloc.artifact;
}

public void finishNode( DependencyGraphNode node )
{
super.finishNode( node );
currentDepth--;
}

public List getConflictingArtifacts()
{
return conflictingArtifacts;
}

public void addAllConflictingArtifacts( Collection nodes )
{
this.conflictingArtifacts.addAll( nodes );
}

public void resetConflictingArtifacts()
{
this.conflictingArtifacts.clear();
}
}

+ 114
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/ResolveGraphTask.java View File

@@ -0,0 +1,114 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.PotentialCyclicEdgeProducer;
import org.apache.maven.archiva.dependency.graph.functors.UnresolvedGraphNodePredicate;
import org.apache.maven.archiva.model.VersionedReference;

/**
* Loop through the unresolved nodes and resolve them, until there
* are no more unresolved nodes.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="resolve-graph"
* instantiation-strategy="per-lookup"
*/
public class ResolveGraphTask
implements GraphTask, PotentialCyclicEdgeProducer
{
private DependencyGraphBuilder builder;
private int resolvedCount = 0;

private VersionedReference toVersionedReference( DependencyGraphNode node )
{
VersionedReference ref = new VersionedReference();
ref.setGroupId( node.getArtifact().getGroupId() );
ref.setArtifactId( node.getArtifact().getArtifactId() );
ref.setVersion( node.getArtifact().getVersion() );

return ref;
}

public void executeTask( DependencyGraph graph )
{
resolvedCount = 0;
VersionedReference rootRef = toVersionedReference( graph.getRootNode() );

if ( !graph.getRootNode().isResolved() )
{
builder.resolveNode( graph, graph.getRootNode(), rootRef );
resolvedCount++;
}

boolean done = false;

while ( !done )
{
DependencyGraphNode node = findUnresolvedNode( graph );
if ( node == null )
{
done = true;
break;
}

VersionedReference otherRef = toVersionedReference( node );

builder.resolveNode( graph, node, otherRef );
resolvedCount++;
}
}

private DependencyGraphNode findUnresolvedNode( DependencyGraph graph )
{
return (DependencyGraphNode) CollectionUtils
.find( graph.getNodes(), UnresolvedGraphNodePredicate.getInstance() );
}

public DependencyGraphBuilder getBuilder()
{
return builder;
}

public void setBuilder( DependencyGraphBuilder graphBuilder )
{
this.builder = graphBuilder;
}

public String getTaskId()
{
return "resolve-graph";
}

public int getResolvedCount()
{
return resolvedCount;
}
}

+ 35
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/UpdateScopesTask.java View File

@@ -0,0 +1,35 @@
package org.apache.maven.archiva.dependency.graph.tasks;

import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.GraphTask;
import org.apache.maven.archiva.dependency.graph.GraphTaskException;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;

/**
* Update the scopes of the edges to what their parent node says.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @plexus.component
* role="org.apache.maven.archiva.dependency.graph.GraphTask"
* role-hint="update-scopes"
* instantiation-strategy="per-lookup"
*/
public class UpdateScopesTask
implements GraphTask
{
public void executeTask( DependencyGraph graph )
throws GraphTaskException
{
DependencyGraphWalker walker = new WalkDepthFirstSearch();
UpdateScopesVisitor updateScopes = new UpdateScopesVisitor();
walker.visit( graph, updateScopes );
}

public String getTaskId()
{
return "update-scopes";
}
}

+ 82
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/tasks/UpdateScopesVisitor.java View File

@@ -0,0 +1,82 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.functors.EdgeFromPredicate;
import org.apache.maven.archiva.dependency.graph.walk.BaseVisitor;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.model.DependencyScope;

import java.util.Stack;

/**
* UpdateScopesVisitor
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class UpdateScopesVisitor
extends BaseVisitor
implements DependencyGraphVisitor
{
private Stack scopeStack;

private Predicate rootEdgePredicate;

public UpdateScopesVisitor()
{
scopeStack = new Stack();
// Default setting.
scopeStack.add( DependencyScope.COMPILE );
}

public void discoverGraph( DependencyGraph graph )
{
super.discoverGraph( graph );
rootEdgePredicate = new EdgeFromPredicate( graph.getRootNode() );
}

public void discoverEdge( DependencyGraphEdge edge )
{
super.discoverEdge( edge );
String scope = edge.getScope();

if ( !rootEdgePredicate.evaluate( edge ) )
{
// Not a root edge. Set the scope.
scope = (String) scopeStack.peek();
edge.setScope( scope );
}
// Push the scope used onto the stack.
scopeStack.push( scope );
}

public void finishEdge( DependencyGraphEdge edge )
{
super.finishEdge( edge );

scopeStack.pop();
}
}

+ 73
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/BaseVisitor.java View File

@@ -0,0 +1,73 @@
package org.apache.maven.archiva.dependency.graph.walk;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;

/**
* The Baseline Visitor.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class BaseVisitor
implements DependencyGraphVisitor
{
private static DependencyGraphVisitor INSTANCE = new BaseVisitor();
protected DependencyGraph graph;

public static DependencyGraphVisitor getInstance()
{
return INSTANCE;
}

public void discoverEdge( DependencyGraphEdge edge )
{
/* do nothing */
}

public void discoverGraph( DependencyGraph graph )
{
this.graph = graph;
}

public void discoverNode( DependencyGraphNode node )
{
/* do nothing */
}

public void finishEdge( DependencyGraphEdge edge )
{
/* do nothing */
}

public void finishGraph( DependencyGraph graph )
{
/* do nothing */
}

public void finishNode( DependencyGraphNode node )
{
/* do nothing */
}
}

+ 76
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/DependencyGraphVisitor.java View File

@@ -0,0 +1,76 @@
package org.apache.maven.archiva.dependency.graph.walk;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;

/**
* Interface for progress during search.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface DependencyGraphVisitor
{
/**
* Called once, for when the graph itself is discovered.
*
* @param graph the graph that was discovered.
*/
public void discoverGraph( DependencyGraph graph );

/**
* Called for each node, when that node is visited.
*
* @param node the node that is being visited.
*/
public void discoverNode( DependencyGraphNode node );

/**
* Called for each edge, when that edge is visited.
*
* @param edge the edge that is being visited.
*/
public void discoverEdge( DependencyGraphEdge edge );

/**
* Called for each edge, when that edge has been fully visited.
*
* @param edge the edge that was finished being visited.
*/
public void finishEdge( DependencyGraphEdge edge );

/**
* Called for each node, when the node has been fully visited.
*
* @param node the node that was finished being visited.
*/
public void finishNode( DependencyGraphNode node );

/**
* Called once, for when the graph is finished being visited.
*
* @param graph the graph that finished being visited.
*/
public void finishGraph( DependencyGraph graph );

}

+ 89
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/DependencyGraphWalker.java View File

@@ -0,0 +1,89 @@
package org.apache.maven.archiva.dependency.graph.walk;

/*
* 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.commons.collections.Predicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.model.ArtifactReference;

/**
* Walk nodes of the {@link DependencyGraph}.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface DependencyGraphWalker
{
/**
* A {@link #getNodeVisitState(ArtifactReference)} for a node not yet seen in the walker.
*/
public static final Integer UNSEEN = new Integer( 0 );

/**
* A {@link #getNodeVisitState(ArtifactReference)} for a node that is actively being processed,
* but not yet finished processing.
*/
public static final Integer PROCESSING = new Integer( 1 );

/**
* A {@link #getNodeVisitState(ArtifactReference)} for a node that has been seen, and fully processed.
*/
public static final Integer SEEN = new Integer( 2 );

/**
* For a provided node, get the current node visit state.
*
* @param node the node that you are interested in.
* @return the state of that node. (Can be {@link #UNSEEN}, {@link #PROCESSING}, or {@link #SEEN} )
*/
public Integer getNodeVisitState( ArtifactReference artifact );

/**
* Get the predicate used to determine if the walker should traverse an edge (or not).
*
* @return the Predicate that returns true for edges that should be traversed.
*/
public Predicate getEdgePredicate();

/**
* Set the predicate used for edge traversal
*
* @param edgePredicate the Predicate that returns true for edges that should be traversed.
*/
public void setEdgePredicate( Predicate edgePredicate );

/**
* Visit every node and edge in the graph from the startNode.
*
* @param graph the graph to visit.
* @param startNode the node to start the visit on.
* @param visitor the visitor object to use during this visit.
*/
public void visit( DependencyGraph graph, DependencyGraphNode startNode, DependencyGraphVisitor visitor );

/**
* Visit every node and edge in the entire graph.
*
* @param graph the graph to visit.
* @param visitor the visitor object to use during this visit.
*/
public void visit( DependencyGraph graph, DependencyGraphVisitor visitor );
}

+ 157
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/WalkBreadthFirstSearch.java View File

@@ -0,0 +1,157 @@
package org.apache.maven.archiva.dependency.graph.walk;

/*
* 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.commons.collections.Predicate;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.functors.EdgeDisabledPredicate;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* WalkBreadthFirstSearch
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class WalkBreadthFirstSearch
implements DependencyGraphWalker
{
private Map nodeVisitStates = new HashMap();

private Predicate edgePredicate;

public WalkBreadthFirstSearch()
{
this.edgePredicate = NotPredicate.getInstance( new EdgeDisabledPredicate() );
}

public Predicate getEdgePredicate()
{
return this.edgePredicate;
}

public void setEdgePredicate( Predicate edgePredicate )
{
this.edgePredicate = edgePredicate;
}

public Integer getNodeVisitState( DependencyGraphNode node )
{
return (Integer) nodeVisitStates.get( node.getArtifact() );
}

public Integer getNodeVisitState( ArtifactReference artifact )
{
return (Integer) nodeVisitStates.get( artifact );
}

public void setNodeVisitState( DependencyGraphNode node, Integer state )
{
this.nodeVisitStates.put( node.getArtifact(), state );
}

public void setNodeVisitState( ArtifactReference artifact, Integer state )
{
this.nodeVisitStates.put( artifact, state );
}

private void visitEdge( DependencyGraph graph, DependencyGraphEdge e, DependencyGraphVisitor visitor )
{
visitor.discoverEdge( e );

DependencyGraphNode node = graph.getNode( e.getNodeTo() );

if ( getNodeVisitState( node ) == UNSEEN )
{
setNodeVisitState( node, PROCESSING );
}

visitor.finishEdge( e );
}

private void visitNode( DependencyGraph graph, DependencyGraphNode node, DependencyGraphVisitor visitor )
{
setNodeVisitState( node, PROCESSING );

visitor.discoverNode( node );

Iterator edges;
// First dive down edges.
edges = graph.getEdgesFrom( node ).iterator();
while ( edges.hasNext() )
{
DependencyGraphEdge e = (DependencyGraphEdge) edges.next();
if ( this.edgePredicate.evaluate( e ) )
{
visitEdge( graph, e, visitor );
}
}

// Next move down edges.
edges = graph.getEdgesFrom( node ).iterator();
while ( edges.hasNext() )
{
DependencyGraphEdge e = (DependencyGraphEdge) edges.next();

if ( this.edgePredicate.evaluate( e ) )
{
DependencyGraphNode nodeTo = graph.getNode( e.getNodeTo() );
Integer state = getNodeVisitState( nodeTo );
if ( ( state == UNSEEN ) || ( state == PROCESSING ) )
{
visitNode( graph, nodeTo, visitor );
}
}
}

visitor.finishNode( node );

setNodeVisitState( node, SEEN );
}

public void visit( DependencyGraph graph, DependencyGraphVisitor visitor )
{
visit( graph, graph.getRootNode(), visitor );
}

public void visit( DependencyGraph graph, DependencyGraphNode startNode, DependencyGraphVisitor visitor )
{
nodeVisitStates.clear();

Iterator nodes = graph.getNodes().iterator();
while ( nodes.hasNext() )
{
setNodeVisitState( (DependencyGraphNode) nodes.next(), UNSEEN );
}

visitor.discoverGraph( graph );

visitNode( graph, startNode, visitor );

visitor.finishGraph( graph );
}
}

+ 145
- 0
archiva-base/archiva-dependency-graph/src/main/java/org/apache/maven/archiva/dependency/graph/walk/WalkDepthFirstSearch.java View File

@@ -0,0 +1,145 @@
package org.apache.maven.archiva.dependency.graph.walk;

/*
* 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.commons.collections.Predicate;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.functors.EdgeDisabledPredicate;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* Perform a walk of the graph using the DepthFirstSearch algorithm.
*
* NOTE: Default edgePredicate is to NOT traverse disabled edges.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class WalkDepthFirstSearch
implements DependencyGraphWalker
{
private Map nodeVisitStates = new HashMap();

private Predicate edgePredicate;

public WalkDepthFirstSearch()
{
this.edgePredicate = NotPredicate.getInstance( new EdgeDisabledPredicate() );
}

public Predicate getEdgePredicate()
{
return this.edgePredicate;
}

public void setEdgePredicate( Predicate edgePredicate )
{
this.edgePredicate = edgePredicate;
}

public Integer getNodeVisitState( DependencyGraphNode node )
{
if ( node == null )
{
return SEEN;
}

return (Integer) nodeVisitStates.get( node.getArtifact() );
}

public Integer getNodeVisitState( ArtifactReference artifact )
{
return (Integer) nodeVisitStates.get( artifact );
}

public void setNodeVisitState( DependencyGraphNode node, Integer state )
{
this.nodeVisitStates.put( node.getArtifact(), state );
}

public void setNodeVisitState( ArtifactReference artifact, Integer state )
{
this.nodeVisitStates.put( artifact, state );
}

private void visitEdge( DependencyGraph graph, DependencyGraphEdge e, DependencyGraphVisitor visitor )
{
visitor.discoverEdge( e );

DependencyGraphNode node = graph.getNode( e.getNodeTo() );

if ( getNodeVisitState( node ) == UNSEEN )
{
visitNode( graph, node, visitor );
}

visitor.finishEdge( e );
}

private void visitNode( DependencyGraph graph, DependencyGraphNode node, DependencyGraphVisitor visitor )
{
setNodeVisitState( node, PROCESSING );

visitor.discoverNode( node );

Iterator edges = graph.getEdgesFrom( node ).iterator();
while ( edges.hasNext() )
{
DependencyGraphEdge e = (DependencyGraphEdge) edges.next();
if ( this.edgePredicate.evaluate( e ) )
{
visitEdge( graph, e, visitor );
}
}

visitor.finishNode( node );

setNodeVisitState( node, SEEN );
}

public void visit( DependencyGraph graph, DependencyGraphVisitor visitor )
{
visit( graph, graph.getRootNode(), visitor );
}

public void visit( DependencyGraph graph, DependencyGraphNode startNode, DependencyGraphVisitor visitor )
{
nodeVisitStates.clear();

Iterator nodes = graph.getNodes().iterator();
while ( nodes.hasNext() )
{
setNodeVisitState( (DependencyGraphNode) nodes.next(), UNSEEN );
}

visitor.discoverGraph( graph );

visitNode( graph, startNode, visitor );

visitor.finishGraph( graph );
}
}

+ 392
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/AbstractDependencyGraphFactoryTestCase.java View File

@@ -0,0 +1,392 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.functors.AndPredicate;
import org.apache.commons.collections.functors.NotPredicate;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.functors.EdgeExactScopePredicate;
import org.apache.maven.archiva.dependency.graph.functors.EdgeFromPredicate;
import org.apache.maven.archiva.dependency.graph.functors.NodeFromParentPredicate;
import org.apache.maven.archiva.dependency.graph.functors.NodePredicate;
import org.apache.maven.archiva.dependency.graph.functors.ToKeyTransformer;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.VersionedReference;
import org.codehaus.plexus.PlexusTestCase;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
* AbstractDependencyGraphFactoryTestCase
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractDependencyGraphFactoryTestCase
extends PlexusTestCase
{
public class ExpectedEdge
{
public String from;

public String to;

public ExpectedEdge( String from, String to )
{
this.from = from;
this.to = to;
}
}

public class GraphEdgePredicate
implements Predicate
{
private String edgeFrom;

private String edgeTo;

public GraphEdgePredicate( String edgeFrom, String edgeTo )
{
this.edgeFrom = edgeFrom;
this.edgeTo = edgeTo;
}

public boolean evaluate( Object object )
{
boolean satisfies = false;

if ( object instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) object;
String actualFrom = ArtifactReference.toKey( edge.getNodeFrom() );
String actualTo = ArtifactReference.toKey( edge.getNodeTo() );

satisfies = ( StringUtils.equals( edgeFrom, actualFrom ) && StringUtils.equals( edgeTo, actualTo ) );
}

return satisfies;
}
}

protected void assertDirectNodes( DependencyGraph graph, List expectedNodes, String scope )
{
Iterator it;
DependencyGraphNode rootNode = graph.getRootNode();
List rootEdges = graph.getEdgesFrom( rootNode );
List actualEdges = new ArrayList();

Predicate directDep = NotPredicate.getInstance( new NodeFromParentPredicate() );
Predicate scopedDirectDeps = AndPredicate.getInstance( new EdgeExactScopePredicate( scope ), directDep );
CollectionUtils.select( rootEdges, scopedDirectDeps, actualEdges );
// CollectionUtils.select( rootEdges, new EdgeExactScopePredicate( scope ), actualEdges );

if ( expectedNodes.size() != actualEdges.size() )
{
StringBuffer sb = new StringBuffer();

sb.append( "Direct node.count with <" ).append( scope ).append( "> edges from [" );
sb.append( DependencyGraphKeys.toKey( rootNode.getArtifact() ) ).append( "]" ).append( " expected:<" );
sb.append( expectedNodes.size() ).append( "> but was:<" );
sb.append( actualEdges.size() ).append( ">" );

CollectionUtils.transform( actualEdges, new ToKeyTransformer() );

Collection missingActualKeys = CollectionUtils.subtract( actualEdges, expectedNodes );
it = missingActualKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Actual) " ).append( (String) it.next() );
}

Collection missingExpectedKeys = CollectionUtils.subtract( expectedNodes, actualEdges );
it = missingExpectedKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Expected) " ).append( (String) it.next() );
}

fail( sb.toString() );
}

it = actualEdges.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
String actualKey = DependencyGraphKeys.toKey( edge.getNodeTo() );
assertTrue( "Direct <" + scope + "> node To [" + actualKey + "] exists in expectedNodes.", expectedNodes
.contains( actualKey ) );
}
}

protected void assertEdges( DependencyGraph graph, List expectedEdges )
{
assertNotNull( "Graph.edges should never be null.", graph.getEdges() );
assertEquals( "Graph.edges.size()", expectedEdges.size(), graph.getEdges().size() );

Iterator it = expectedEdges.iterator();
while ( it.hasNext() )
{
ExpectedEdge expectedEdge = (ExpectedEdge) it.next();
Predicate edgePredicate = new GraphEdgePredicate( expectedEdge.from, expectedEdge.to );

DependencyGraphEdge edge = (DependencyGraphEdge) CollectionUtils.find( graph.getEdges(), edgePredicate );
if ( edge == null )
{
fail( "Unable to find expected edge from:<" + expectedEdge.from + "> to:<" + expectedEdge.to + ">" );
}
}
}

protected void assertGraph( DependencyGraph graph, String rootRefKey, List expectedNodeKeys )
{
assertNotNull( "Graph.nodes should never be null.", graph.getNodes() );
assertTrue( "Graph.nodes.size() should always be 1 or better.", graph.getNodes().size() >= 1 );

ArtifactReference rootRef = graph.getRootNode().getArtifact();
StringBuffer actualRootRef = new StringBuffer();
actualRootRef.append( rootRef.getGroupId() ).append( ":" );
actualRootRef.append( rootRef.getArtifactId() ).append( ":" );
actualRootRef.append( rootRef.getVersion() );

assertEquals( "Graph.root", rootRefKey, actualRootRef.toString() );

Iterator it;
List actualNodes = new ArrayList();

Predicate notRootNode = NotPredicate.getInstance( new NodePredicate( graph.getRootNode() ) );
CollectionUtils.select( graph.getNodes(), notRootNode, actualNodes );

boolean fail = false;
StringBuffer sb = new StringBuffer();
if ( expectedNodeKeys.size() != actualNodes.size() )
{
sb.append( "node.count expected:<" );
sb.append( expectedNodeKeys.size() ).append( "> but was:<" );
sb.append( actualNodes.size() ).append( ">" );
fail = true;
}

CollectionUtils.transform( actualNodes, new ToKeyTransformer() );

Collection missingActualKeys = CollectionUtils.subtract( actualNodes, expectedNodeKeys );
it = missingActualKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Actual) " ).append( (String) it.next() );
fail = true;
}

Collection missingExpectedKeys = CollectionUtils.subtract( expectedNodeKeys, actualNodes );
it = missingExpectedKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Expected) " ).append( (String) it.next() );
fail = true;
}

if( fail )
{
fail( sb.toString() );
}

/*
it = actualNodes.iterator();
while ( it.hasNext() )
{
DependencyGraphNode node = (DependencyGraphNode) it.next();
assertNotNull( "Artifact reference in node should not be null.", node.getArtifact() );
String key = ArtifactReference.toKey( node.getArtifact() );
assertTrue( "Artifact reference [" + key + "] should be in expectedNodeKeys.", expectedNodeKeys
.contains( key ) );
}
*/
}

protected void assertNodes( DependencyGraph graph, List expectedNodeKeys )
{
assertNotNull( "Graph.nodes should never be null.", graph.getNodes() );
assertTrue( "Graph.nodes.size() should always be 1 or better.", graph.getNodes().size() >= 1 );
// assertEquals( "Graph.nodes.size()", expectedNodeKeys.size(), graph.getNodes().size() );

Iterator it;
List actualNodes = new ArrayList();
actualNodes.addAll( graph.getNodes() );

if ( expectedNodeKeys.size() != actualNodes.size() )
{
StringBuffer sb = new StringBuffer();

sb.append( "node.count expected:<" );
sb.append( expectedNodeKeys.size() ).append( "> but was:<" );
sb.append( actualNodes.size() ).append( ">" );

CollectionUtils.transform( actualNodes, new ToKeyTransformer() );

Collection missingActualKeys = CollectionUtils.subtract( actualNodes, expectedNodeKeys );
it = missingActualKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Actual) " ).append( (String) it.next() );
}

Collection missingExpectedKeys = CollectionUtils.subtract( expectedNodeKeys, actualNodes );
it = missingExpectedKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Expected) " ).append( (String) it.next() );
}

fail( sb.toString() );
}

it = graph.getNodes().iterator();
while ( it.hasNext() )
{
DependencyGraphNode node = (DependencyGraphNode) it.next();
assertNotNull( "Artifact reference in node should not be null.", node.getArtifact() );
String key = ArtifactReference.toKey( node.getArtifact() );
assertTrue( "Artifact reference [" + key + "] should be in expectedNodeKeys.", expectedNodeKeys
.contains( key ) );
}
}

protected void assertRootNode( DependencyGraph graph, String expectedKey )
{
DependencyGraphNode node = graph.getRootNode();

String actualKey = DependencyGraphKeys.toKey( node.getArtifact() );
assertEquals( "Root Node", expectedKey, actualKey );
}

protected void assertTransientNodes( DependencyGraph graph, List expectedNodes, String scope )
{
Iterator it;

// Gather up the transient nodes from the DependencyGraph.
List actualEdges = new ArrayList();

DependencyGraphNode rootNode = graph.getRootNode();

Predicate transientDep = NotPredicate.getInstance( new EdgeFromPredicate( rootNode.getArtifact() ) );
Predicate edgeByExactScope = new EdgeExactScopePredicate( scope );
Predicate transitiveEdgesByScopePredicate = AndPredicate.getInstance( transientDep, edgeByExactScope );

CollectionUtils.select( graph.getEdges(), transitiveEdgesByScopePredicate, actualEdges );

if ( expectedNodes.size() != actualEdges.size() )
{
StringBuffer sb = new StringBuffer();

sb.append( "Transient node.count with <" ).append( scope ).append( "> edges from [" );
sb.append( DependencyGraphKeys.toKey( rootNode.getArtifact() ) ).append( "]" ).append( " expected:<" );
sb.append( expectedNodes.size() ).append( "> but was:<" );
sb.append( actualEdges.size() ).append( ">" );

CollectionUtils.transform( actualEdges, new ToKeyTransformer() );

Collection missingActualKeys = CollectionUtils.subtract( actualEdges, expectedNodes );
it = missingActualKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Actual) " ).append( (String) it.next() );
}

Collection missingExpectedKeys = CollectionUtils.subtract( expectedNodes, actualEdges );
it = missingExpectedKeys.iterator();
while ( it.hasNext() )
{
sb.append( "\n (Extra Expected) " ).append( (String) it.next() );
}

fail( sb.toString() );
}

it = actualEdges.iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();
String actualKey = DependencyGraphKeys.toKey( edge.getNodeTo() );
assertTrue( "Transient Node To [" + actualKey + "] exists in expectedNodes.", expectedNodes
.contains( actualKey ) );
}
}

protected Dependency toDependency( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

assertEquals( "Dependency key [" + key + "] should be 5 parts.", 5, parts.length );

Dependency dep = new Dependency();

dep.setGroupId( parts[0] );
dep.setArtifactId( parts[1] );
dep.setVersion( parts[2] );
dep.setClassifier( parts[3] );
dep.setType( parts[4] );

return dep;
}

protected ArchivaProjectModel toModel( String key, Dependency deps[] )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

assertEquals( "Dependency key [" + key + "] should be 3 parts.", 3, parts.length );

ArchivaProjectModel model = new ArchivaProjectModel();
model.setGroupId( parts[0] );
model.setArtifactId( parts[1] );
model.setVersion( parts[2] );
model.setOrigin( "testcase" );
model.setPackaging( "jar" );

if ( deps != null )
{
for ( int i = 0; i < deps.length; i++ )
{
Dependency dep = deps[i];
model.addDependency( dep );
}
}

return model;
}

protected VersionedReference toVersionedReference( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );
assertEquals( "Versioned Reference [" + key + "] part count.", 3, parts.length );

VersionedReference ref = new VersionedReference();
ref.setGroupId( parts[0] );
ref.setArtifactId( parts[1] );
ref.setVersion( parts[2] );
return ref;
}
}

+ 175
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/AbstractMemoryRepository.java View File

@@ -0,0 +1,175 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.commons.lang.StringUtils;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.Exclusion;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* AbstractMemoryRepository
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public abstract class AbstractMemoryRepository
implements MemoryRepository
{
private Map modelMap = new HashMap();

public AbstractMemoryRepository()
{
initialize();
}

public void addModel( ArchivaProjectModel model )
{
String key = Keys.toKey( model );
modelMap.put( key, model );
}

public ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version )
{
String key = Keys.toKey( groupId, artifactId, version );

return (ArchivaProjectModel) modelMap.get( key );
}

public abstract void initialize();

protected void addExclusion( Dependency dependency, String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

if ( parts.length != 2 )
{
throw new IllegalArgumentException( "Exclusion key [" + key + "] should be 2 parts. (detected "
+ parts.length + " instead)" );
}

Exclusion exclusion = new Exclusion();
exclusion.setGroupId( parts[0] );
exclusion.setArtifactId( parts[1] );

dependency.addExclusion( exclusion );
}

protected Dependency toDependency( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

if ( parts.length != 5 )
{
throw new IllegalArgumentException( "Dependency key [" + key + "] should be 5 parts. (detected "
+ parts.length + " instead)" );
}

Dependency dep = new Dependency();

dep.setGroupId( parts[0] );
dep.setArtifactId( parts[1] );
dep.setVersion( parts[2] );
dep.setClassifier( parts[3] );
dep.setType( parts[4] );

return dep;
}

protected Dependency toDependency( String key, String scope )
{
Dependency dependency = toDependency( key );
dependency.setScope( scope );

return dependency;
}

protected ArchivaProjectModel toModel( String key )
{
return toModel( key, Collections.EMPTY_LIST );
}

protected ArchivaProjectModel toModel( String key, Dependency deps[] )
{
List depList = new ArrayList();

if ( deps != null )
{
depList.addAll( Arrays.asList( deps ) );
}

return toModel( key, depList );
}

protected ArchivaProjectModel toModel( String key, List deps )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

if ( parts.length != 3 )
{
throw new IllegalArgumentException( "Project/Model key [" + key + "] should be 3 parts. (detected "
+ parts.length + " instead)" );
}

ArchivaProjectModel model = new ArchivaProjectModel();
model.setGroupId( parts[0] );
model.setArtifactId( parts[1] );
model.setVersion( parts[2] );
model.setOrigin( "testcase" );
model.setPackaging( "jar" );

Iterator it = deps.iterator();
while ( it.hasNext() )
{
Dependency dep = (Dependency) it.next();
model.addDependency( dep );
}

return model;
}

protected VersionedReference toParent( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

if ( parts.length != 3 )
{
throw new IllegalArgumentException( "Parent key [" + key + "] should be 3 parts. (detected " + parts.length
+ " instead)" );
}

VersionedReference ref = new VersionedReference();
ref.setGroupId( parts[0] );
ref.setArtifactId( parts[1] );
ref.setVersion( parts[2] );

return ref;
}

}

+ 51
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/AllTests.java View File

@@ -0,0 +1,51 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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 junit.framework.Test;
import junit.framework.TestSuite;

/**
* Utility class to aide IDE developers.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class AllTests
{

public static Test suite()
{
TestSuite suite = new TestSuite( "Test for org.apache.maven.archiva.repository.project.dependencies" );
//$JUnit-BEGIN$
suite.addTestSuite( ArchivaWebappDependencyGraphTest.class );
suite.addTestSuite( GraphvizDotTool.class );
suite.addTestSuite( DepManDeepVersionDependencyGraphTest.class );
suite.addTestSuite( SimpleDependencyGraphTest.class );
suite.addTestSuite( MavenProjectInfoReportsPluginDependencyGraphTest.class );
suite.addTestSuite( ArchivaCommonDependencyGraphTest.class );
suite.addTestSuite( WagonManagerDependencyGraphTest.class );
suite.addTestSuite( ContinuumStoreDependencyGraphTest.class );
suite.addTestSuite( ArchivaXmlToolsDependencyGraphTest.class );
//$JUnit-END$
return suite;
}

}

+ 77
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaCommonDependencyGraphTest.java View File

@@ -0,0 +1,77 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* ArchivaCommonDependencyGraphTest
*
* DependencyGraphTest for testing <code>org.apache.maven.archiva:archiva-common:1.0-alpha-2-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class ArchivaCommonDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder =
new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new ArchivaCommonMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.archiva:archiva-common:1.0-alpha-2-SNAPSHOT");

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "org.apache.maven.archiva:archiva-common:1.0-alpha-2-SNAPSHOT";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "commons-lang:commons-lang:2.2::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-component-api:1.0-alpha-22::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-container-default:1.0-alpha-22::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-utils:1.4::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 3469
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaCommonMemoryRepository.java
File diff suppressed because it is too large
View File


+ 200
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaWebappDependencyGraphTest.java View File

@@ -0,0 +1,200 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* ArchivaWebappDependencyGraphTest
*
* DependencyGraphTest for testing <code>org.apache.maven.archiva:archiva-webapp:1.0-alpha-2-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class ArchivaWebappDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder =
new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new ArchivaWebappMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.archiva:archiva-webapp:1.0-alpha-2-SNAPSHOT");

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "org.apache.maven.archiva:archiva-webapp:1.0-alpha-2-SNAPSHOT";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "ant:ant-optional:1.5.1::jar" );
expectedNodes.add( "backport-util-concurrent:backport-util-concurrent:3.0::jar" );
expectedNodes.add( "classworlds:classworlds:1.1::jar" );
expectedNodes.add( "commons-beanutils:commons-beanutils:1.7.0::jar" );
expectedNodes.add( "commons-beanutils:commons-beanutils-bean-collections:1.7.0::jar" );
expectedNodes.add( "commons-codec:commons-codec:1.3::jar" );
expectedNodes.add( "commons-collections:commons-collections:3.2::jar" );
expectedNodes.add( "commons-configuration:commons-configuration:1.3::jar" );
expectedNodes.add( "commons-digester:commons-digester:1.6::jar" );
expectedNodes.add( "commons-io:commons-io:1.2::jar" );
expectedNodes.add( "commons-jxpath:commons-jxpath:1.2::jar" );
expectedNodes.add( "commons-lang:commons-lang:2.2::jar" );
expectedNodes.add( "commons-logging:commons-logging:1.0.4::jar" );
expectedNodes.add( "commons-logging:commons-logging-api:1.0.4::jar" );
expectedNodes.add( "dom4j:dom4j:1.6.1::jar" );
expectedNodes.add( "freemarker:freemarker:2.3.4::jar" );
expectedNodes.add( "geronimo-spec:geronimo-spec-jta:1.0.1B-rc2::jar" );
expectedNodes.add( "it.could:webdav:0.4::jar" );
expectedNodes.add( "javax.activation:activation:1.1::jar" );
expectedNodes.add( "javax.jdo:jdo2-api:2.0::jar" );
expectedNodes.add( "javax.mail:mail:1.4::jar" );
expectedNodes.add( "javax.resource:connector:1.0::jar" );
expectedNodes.add( "javax.servlet:jsp-api:2.0::jar" );
expectedNodes.add( "javax.servlet:jstl:1.1.2::jar" );
expectedNodes.add( "javax.servlet:servlet-api:2.4::jar" );
expectedNodes.add( "javax.transaction:jta:1.0.1B::jar" );
expectedNodes.add( "jaxen:jaxen:1.1::jar" );
expectedNodes.add( "jdom:jdom:1.0::jar" );
expectedNodes.add( "jpox:jpox:1.1.7::jar" );
expectedNodes.add( "jtidy:jtidy:4aug2000r7-dev::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
expectedNodes.add( "log4j:log4j:1.2.8::jar" );
expectedNodes.add( "net.java.dev.stax-utils:stax-utils:20060502::jar" );
expectedNodes.add( "net.sf.ehcache:ehcache:1.2.4::jar" );
expectedNodes.add( "ognl:ognl:2.6.7::jar" );
expectedNodes.add( "opensymphony:oscore:2.2.4::jar" );
expectedNodes.add( "opensymphony:sitemesh:2.2.1::jar" );
expectedNodes.add( "opensymphony:webwork:2.2.4::jar" );
expectedNodes.add( "opensymphony:xwork:1.2.1::jar" );
expectedNodes.add( "org.apache.derby:derby:10.1.3.1::jar" );
expectedNodes.add( "org.apache.lucene:lucene-core:2.0.0::jar" );
expectedNodes.add( "org.apache.maven:maven-artifact:2.0.5::jar" );
expectedNodes.add( "org.apache.maven:maven-artifact-manager:2.0.5::jar" );
expectedNodes.add( "org.apache.maven:maven-model:2.0.5::jar" );
expectedNodes.add( "org.apache.maven:maven-profile:2.0.5::jar" );
expectedNodes.add( "org.apache.maven:maven-project:2.0.5::jar" );
expectedNodes.add( "org.apache.maven:maven-repository-metadata:2.0.5::jar" );
expectedNodes.add( "org.apache.maven:maven-settings:2.0.5::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-applet:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-artifact-reports:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-common:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-configuration:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-consumer-api:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-core-consumers:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-database:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-database-consumers:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-indexer:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-lucene-consumers:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-model:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-policies:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-proxy:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-report-manager:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-repository-layer:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-scheduled:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-security:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-signature-consumers:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-xml-tools:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.shared:maven-app-configuration-model:1.0::jar" );
expectedNodes.add( "org.apache.maven.shared:maven-app-configuration-web:1.0::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-file:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-http-lightweight:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-http-shared:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-provider-api:1.0-beta-2::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-component-api:1.0-alpha-22::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-container-default:1.0-alpha-22::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-digest:1.1::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-ehcache:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-expression-evaluator:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-jdo2:1.0-alpha-8::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-mail-sender-api:1.0-alpha-6::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-mail-sender-javamail:1.0-alpha-6::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-quartz:1.0-alpha-3::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-slf4j-logging:1.1-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-taskqueue:1.0-alpha-6::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-utils:1.4::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-velocity:1.1.2::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-xwork-integration:1.0-alpha-6::jar" );
expectedNodes.add( "org.codehaus.plexus.cache:plexus-cache-api:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.plexus.cache:plexus-cache-ehcache:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-authentication-api:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-authentication-keys:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-authentication-users:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-authorization-api:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-authorization-rbac:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-common-jdo:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-configuration:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-keys-api:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-keys-cached:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-keys-jdo:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-policy:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-rbac-cached:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-rbac-jdo:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-rbac-model:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-rbac-role-manager:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-system:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-taglib:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-users-api:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-users-cached:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-users-jdo:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-xwork-content:1.0-alpha-1::war" );
expectedNodes.add( "org.codehaus.plexus.redback:redback-xwork-integration:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.registry:plexus-registry-api:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.plexus.registry:plexus-registry-commons:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.plexus.webdav:plexus-webdav-api:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.plexus.webdav:plexus-webdav-simple:1.0-alpha-2::jar" );
expectedNodes.add( "org.codehaus.woodstox:wstx-asl:3.2.1::jar" );
expectedNodes.add( "org.extremecomponents:extremecomponents:1.0.1::jar" );
expectedNodes.add( "org.rifers:rife-continuations:0.0.2::jar" );
expectedNodes.add( "org.slf4j:slf4j-api:1.2::jar" );
expectedNodes.add( "org.slf4j:slf4j-log4j12:1.2::jar" );
expectedNodes.add( "org.slf4j:slf4j-simple:1.2::jar" );
expectedNodes.add( "quartz:quartz:1.4.5::jar" );
expectedNodes.add( "stax:stax-api:1.0.1::jar" );
expectedNodes.add( "taglibs:standard:1.1.2::jar" );
expectedNodes.add( "velocity:velocity:1.4::jar" );
expectedNodes.add( "velocity:velocity-dep:1.4::jar" );
expectedNodes.add( "xerces:xercesImpl:2.6.2::jar" );
expectedNodes.add( "xml-apis:xml-apis:1.3.03::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 3469
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaWebappMemoryRepository.java
File diff suppressed because it is too large
View File


+ 86
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaXmlToolsDependencyGraphTest.java View File

@@ -0,0 +1,86 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* ArchivaXmlToolsDependencyGraphTest
*
* DependencyGraphTest for testing <code>org.apache.maven.archiva:archiva-xml-tools:1.0-alpha-2-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class ArchivaXmlToolsDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder =
new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new ArchivaXmlToolsMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.archiva:archiva-xml-tools:1.0-alpha-2-SNAPSHOT");

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "org.apache.maven.archiva:archiva-xml-tools:1.0-alpha-2-SNAPSHOT";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "commons-collections:commons-collections:3.2::jar" );
expectedNodes.add( "commons-lang:commons-lang:2.2::jar" );
expectedNodes.add( "dom4j:dom4j:1.6.1::jar" );
expectedNodes.add( "jaxen:jaxen:1.1::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
expectedNodes.add( "log4j:log4j:1.2.8::jar" );
expectedNodes.add( "org.apache.maven.archiva:archiva-common:1.0-alpha-2-SNAPSHOT::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-component-api:1.0-alpha-22::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-container-default:1.0-alpha-22::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-utils:1.4::jar" );
expectedNodes.add( "org.slf4j:slf4j-api:1.2::jar" );
expectedNodes.add( "org.slf4j:slf4j-log4j12:1.2::jar" );
expectedNodes.add( "xerces:xercesImpl:2.6.2::jar" );
expectedNodes.add( "xml-apis:xml-apis:1.0.b2::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 3469
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ArchivaXmlToolsMemoryRepository.java
File diff suppressed because it is too large
View File


+ 98
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ContinuumStoreDependencyGraphTest.java View File

@@ -0,0 +1,98 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* ContinuumStoreDependencyGraphTest
*
* DependencyGraphTest for testing <code>org.apache.maven.continuum:continuum-store:1.1-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class ContinuumStoreDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder =
new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new ContinuumStoreMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.continuum:continuum-store:1.1-SNAPSHOT");

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "org.apache.maven.continuum:continuum-store:1.1-SNAPSHOT";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "ant:ant:1.6::jar" );
expectedNodes.add( "geronimo-spec:geronimo-spec-jta:1.0.1B-rc2::jar" );
expectedNodes.add( "hsqldb:hsqldb:1.7.3.3::jar" );
expectedNodes.add( "jakarta-regexp:jakarta-regexp:1.4::jar" );
expectedNodes.add( "javax.jdo:jdo2-api:2.0::jar" );
expectedNodes.add( "javax.resource:connector:1.0::jar" );
expectedNodes.add( "javax.transaction:jta:1.0.1B::jar" );
expectedNodes.add( "jmock:jmock:1.0.1::jar" );
expectedNodes.add( "jpox:jpox:1.1.7::jar" );
expectedNodes.add( "jpox:jpox-enhancer:1.1.7::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
expectedNodes.add( "log4j:log4j:1.2.8::jar" );
expectedNodes.add( "net.java.dev.stax-utils:stax-utils:20060502::jar" );
expectedNodes.add( "ognl:ognl:2.6.7::jar" );
expectedNodes.add( "org.apache.bcel:bcel:5.2::jar" );
expectedNodes.add( "org.apache.maven.continuum:continuum-api:1.1-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.continuum:continuum-model:1.1-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.continuum:continuum-test:1.1-SNAPSHOT::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-component-api:1.0-alpha-20::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-container-default:1.0-alpha-20::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-formica:1.0-beta-13::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-i18n:1.0-beta-6::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-jdo2:1.0-alpha-8::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-utils:1.4::jar" );
expectedNodes.add( "oro:oro:2.0.6::jar" );
expectedNodes.add( "stax:stax-api:1.0.1::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 4142
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/ContinuumStoreMemoryRepository.java
File diff suppressed because it is too large
View File


+ 74
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/DepManDeepVersionDependencyGraphTest.java View File

@@ -0,0 +1,74 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* DepManDeepVersionDependencyGraphTest
*
* DependencyGraphTest for testing <code>net.example.depman.deepversion:A:1.0</code>
*
* @version $Id$
*/
public class DepManDeepVersionDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder = new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new DepManDeepVersionMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "net.example.depman.deepversion:A:1.0" );

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "net.example.depman.deepversion:A:1.0";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "net.example.depman.deepversion:B:1.0::jar" );
expectedNodes.add( "net.example.depman.deepversion:C:1.0::jar" );
expectedNodes.add( "net.example.depman.deepversion:D:2.0::jar" );
expectedNodes.add( "net.example.depman.deepversion:E:3.0::jar" );
expectedNodes.add( "net.example.depman.deepversion:F:1.0::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 77
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/DepManDeepVersionMemoryRepository.java View File

@@ -0,0 +1,77 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArchivaProjectModel;

/**
* DepManDeepVersionMemoryRepository
*
* MemoryRepository for testing <code>net.example.depman.deepversion:A:1.0</code>
*
* @version $Id$
*/
public class DepManDeepVersionMemoryRepository
extends AbstractMemoryRepository
{
public void initialize()
{
ArchivaProjectModel model;

model = toModel( "net.example.depman.deepversion:A:1.0" );
model.addDependency( toDependency( "net.example.depman.deepversion:B:1.0::jar" ) );
model.addDependency( toDependency( "net.example.depman.deepversion:C:1.0::jar" ) );
model.addDependencyManagement( toDependency( "net.example.depman.deepversion:D:2.0::jar" ) );
addModel( model );
/* Having a depman in A for D:2.0 will cause an orphaned E:2.0 during the depman
* application phase.
*
* This is intentional, to test out the depman application and recovery.
*/

model = toModel( "net.example.depman.deepversion:B:1.0" );
model.addDependency( toDependency( "net.example.depman.deepversion:D:1.0::jar" ) );
addModel( model );

model = toModel( "net.example.depman.deepversion:E:2.0" );
addModel( model );
model = toModel( "net.example.depman.deepversion:E:3.0" );
model.addDependency( toDependency( "net.example.depman.deepversion:F:1.0::jar" ) );
addModel( model );
model = toModel( "net.example.depman.deepversion:F:1.0" );
addModel( model );

model = toModel( "net.example.depman.deepversion:C:1.0" );
model.addDependency( toDependency( "net.example.depman.deepversion:D:1.0::jar" ) );
addModel( model );

model = toModel( "net.example.depman.deepversion:D:1.0" );
model.addDependency( toDependency( "net.example.depman.deepversion:E:2.0::jar" ) );
addModel( model );

model = toModel( "net.example.depman.deepversion:D:2.0" );
model.addDependency( toDependency( "net.example.depman.deepversion:E:3.0::jar" ) );
addModel( model );

}
}

+ 346
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/GraphvizDotTool.java View File

@@ -0,0 +1,346 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;
import org.codehaus.plexus.PlexusTestCase;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

/**
* GraphvizDotTool - testing utility to help understand the graph.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class GraphvizDotTool
extends PlexusTestCase
implements GraphListener
{
private int phaseNumber = 0;

protected VersionedReference toVersionedReference( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );
assertEquals( "Versioned Reference [" + key + "] part count.", 3, parts.length );

VersionedReference ref = new VersionedReference();
ref.setGroupId( parts[0] );
ref.setArtifactId( parts[1] );
ref.setVersion( parts[2] );
return ref;
}

private DependencyGraph getDependencyGraph( MemoryRepository repository, String rootRefKey )
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder = new MemoryRepositoryDependencyGraphBuilder();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );
factory.addGraphListener( this );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( rootRefKey );

// Perform the resolution.
phaseNumber = 0;
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

return graph;
}

public void testGenerateDots()
throws GraphTaskException
{
getDependencyGraph( new ArchivaWebappMemoryRepository(),
"org.apache.maven.archiva:archiva-webapp:1.0-alpha-2-SNAPSHOT" );

// getDependencyGraph( new ArchivaCommonMemoryRepository(),
// "org.apache.maven.archiva:archiva-common:1.0-alpha-2-SNAPSHOT" );
//
// getDependencyGraph( new ArchivaXmlToolsMemoryRepository(),
// "org.apache.maven.archiva:archiva-xml-tools:1.0-alpha-2-SNAPSHOT" );
//
// getDependencyGraph( new ContinuumStoreMemoryRepository(),
// "org.apache.maven.continuum:continuum-store:1.1-SNAPSHOT" );
//
// getDependencyGraph( new MavenProjectInfoReportsPluginMemoryRepository(),
// "org.apache.maven.plugins:maven-project-info-reports-plugin:2.1-SNAPSHOT" );
//
// getDependencyGraph( new WagonManagerMemoryRepository(), "org.apache.maven.wagon:wagon-manager:2.0-SNAPSHOT" );

getDependencyGraph( new DepManDeepVersionMemoryRepository(), "net.example.depman.deepversion:A:1.0" );
}

public void dependencyResolutionEvent( DependencyResolutionEvent event )
{
/* do nothing */
}

public void graphError( GraphTaskException e, DependencyGraph currentGraph )
{
/* do nothing */
}

public void graphPhaseEvent( GraphPhaseEvent event )
{
String graphId = event.getGraph().getRootNode().getArtifact().getArtifactId();
String title = "Graph: " + graphId;

switch ( event.getType() )
{
case GraphPhaseEvent.GRAPH_TASK_POST:
phaseNumber++;
title += " - Phase: " + phaseNumber + " - Task: " + event.getTask().getTaskId();
writeDot( "target/graph_" + graphId + "_" + phaseNumber + "_" + event.getTask().getTaskId() + ".dot",
event.getGraph(), title );
break;
case GraphPhaseEvent.GRAPH_DONE:
title += " FINISHED";
writeDot( "target/graph_" + graphId + ".dot", event.getGraph(), title );
break;
}
}

private void writeDot( String outputFilename, DependencyGraph graph, String title )
{
System.out.println( "Writing Graphviz output: " + outputFilename );
try
{
File outputFile = new File( outputFilename );
PrintWriter dot = new PrintWriter( outputFile );

dot.println( "// Auto generated dot file from plexus-graph-visualizer-graphviz." );

dot.println( "digraph example {" );

dot.println( "" );

dot.println( " // Graph Defaults" );
dot.println( " graph [" );
dot.println( " bgcolor=\"#ffffff\"," );
dot.println( " fontname=\"Helvetica\"," );
dot.println( " fontsize=\"11\"," );
dot.println( " label=\"" + title + "\"," );
dot.println( " labeljust=\"l\"" );
dot.println( " rankdir=\"LR\"" );
dot.println( " ];" );

// Node Defaults.

dot.println( "" );
dot.println( " // Node Defaults." );
dot.println( " node [" );
dot.println( " fontname=\"Helvetica\"," );
dot.println( " fontsize=\"11\"," );
dot.println( " shape=\"box\"" );
dot.println( " ];" );

// Edge Defaults.

dot.println( "" );
dot.println( " // Edge Defaults." );
dot.println( " edge [" );
dot.println( " arrowsize=\"0.8\"" );
dot.println( " fontsize=\"11\"," );
dot.println( " ];" );

Iterator it;

it = graph.getNodes().iterator();
while ( it.hasNext() )
{
DependencyGraphNode node = (DependencyGraphNode) it.next();

writeNode( dot, graph, node );
}

it = graph.getEdges().iterator();
while ( it.hasNext() )
{
DependencyGraphEdge edge = (DependencyGraphEdge) it.next();

DependencyGraphNode from = graph.getNode( edge.getNodeFrom() );
DependencyGraphNode to = graph.getNode( edge.getNodeTo() );

writeEdge( dot, edge, from, to );
}

dot.println( "}" );
dot.flush();
dot.close();
}
catch ( IOException e )
{
System.err.println( "Unable to write GraphViz file " + outputFilename + " : " + e.getMessage() );
e.printStackTrace( System.err );
}
}

private String toLabel( DependencyGraphNode node )
{
StringBuffer lbl = new StringBuffer();

lbl.append( node.getArtifact().getGroupId() ).append( "\n" );
lbl.append( node.getArtifact().getArtifactId() ).append( "\n" );
lbl.append( node.getArtifact().getVersion() );

return StringEscapeUtils.escapeJava( lbl.toString() );
}

private String toId( DependencyGraphNode node )
{
StringBuffer id = new StringBuffer();

String raw = DependencyGraphKeys.toKey( node.getArtifact() );

for ( int i = 0; i < raw.length(); i++ )
{
char c = raw.charAt( i );
if ( Character.isLetterOrDigit( c ) )
{
id.append( Character.toUpperCase( c ) );
}
else if ( ( c == '-' ) || ( c == '_' ) )
{
id.append( "_" );
}
}

return id.toString();
}

private void writeNode( PrintWriter dot, DependencyGraph graph, DependencyGraphNode node )
{
dot.println( "" );
dot.println( " // Node" );
dot.println( " \"" + toId( node ) + "\" [" );
dot.println( " label=\"" + toLabel( node ) + "\"," );

List edgesTo = graph.getEdgesTo( node );
boolean orphan = CollectionUtils.isEmpty( edgesTo );

if ( node.isFromParent() )
{
dot.println( " color=\"#FF0000\"," );
dot.println( " shape=ellipse," );
}
else
{
dot.println( " shape=box," );
}

if ( node.isConflicted() )
{
// dot.println( " fontcolor=\"#FF88FF\"," );
dot.println( " style=filled," );
dot.println( " fillcolor=\"#88FF88\"," );
}
else if ( orphan )
{
dot.println( " style=filled," );
dot.println( " fillcolor=\"#8888FF\"," );
}

dot.println( " ];" );
}

private void writeEdge( PrintWriter dot, DependencyGraphEdge edge, DependencyGraphNode from, DependencyGraphNode to )
{
dot.println( "" );
dot.println( " // Edge" );

dot.println( " \"" + toId( from ) + "\" -> \"" + toId( to ) + "\" [" );

if ( edge.isDisabled() )
{
switch ( edge.getDisabledType() )
{
case DependencyGraph.DISABLED_CYCLIC:
dot.println( " color=\"#FF0000\"," );
break;
case DependencyGraph.DISABLED_OPTIONAL:
dot.println( " color=\"#FF00FF\"," );
break;
case DependencyGraph.DISABLED_NEARER_DEP:
dot.println( " color=\"#00FF00\"," );
break;
case DependencyGraph.DISABLED_NEARER_EDGE:
dot.println( " color=\"#88FF88\"," );
break;
default:
case DependencyGraph.DISABLED_EXCLUDED:
dot.println( " color=\"#0000FF\"," );
break;
}

dot.println( " label=\"" + edge.getDisabledReason() + "\"," );
dot.println( " fontsize=\"8\"," );
}
else if ( DependencyScope.TEST.equals( edge.getScope() ) )
{
dot.println( " style=\"dashed\"," );
dot.println( " color=\"#DDDDDD\"," );
}
else if ( DependencyScope.RUNTIME.equals( edge.getScope() ) )
{
dot.println( " style=\"dashed\"," );
dot.println( " color=\"#DDFFDD\"," );
dot.println( " label=\"runtime\"," );
dot.println( " fontsize=\"8\"," );
}
else if ( DependencyScope.PROVIDED.equals( edge.getScope() ) )
{
dot.println( " style=\"dashed\"," );
dot.println( " color=\"#DDDDFF\"," );
dot.println( " label=\"provided\"," );
dot.println( " fontsize=\"8\"," );
}
else if ( DependencyScope.SYSTEM.equals( edge.getScope() ) )
{
dot.println( " style=\"dashed\"," );
dot.println( " color=\"#FFDDDD\"," );
dot.println( " label=\"system\"," );
dot.println( " fontsize=\"8\"," );
}

dot.println( " arrowtail=none," );
dot.println( " arrowhead=normal" );

dot.println( " ];" );
}

}

+ 47
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/Keys.java View File

@@ -0,0 +1,47 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArchivaProjectModel;

/**
* Keys - utility methods for converting common objects into string keys.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class Keys
{
public static String toKey( ArchivaProjectModel model )
{
return toKey( model.getGroupId(), model.getArtifactId(), model.getVersion() );
}

public static String toKey( String groupId, String artifactId, String version )
{
StringBuffer key = new StringBuffer();

key.append( groupId ).append( ":" );
key.append( artifactId ).append( ":" );
key.append( version );

return key.toString();
}
}

+ 139
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MavenProjectInfoReportsPluginDependencyGraphTest.java View File

@@ -0,0 +1,139 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* MavenProjectInfoReportsPluginDependencyGraphTest
*
* DependencyGraphTest for testing <code>org.apache.maven.plugins:maven-project-info-reports-plugin:2.1-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class MavenProjectInfoReportsPluginDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder =
new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new MavenProjectInfoReportsPluginMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.plugins:maven-project-info-reports-plugin:2.1-SNAPSHOT");

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "org.apache.maven.plugins:maven-project-info-reports-plugin:2.1-SNAPSHOT";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "classworlds:classworlds:1.1-alpha-2::jar" );
expectedNodes.add( "com.jcraft:jsch:0.1.27::jar" );
expectedNodes.add( "commons-beanutils:commons-beanutils:1.7.0::jar" );
expectedNodes.add( "commons-cli:commons-cli:1.0::jar" );
expectedNodes.add( "commons-collections:commons-collections:3.1::jar" );
expectedNodes.add( "commons-digester:commons-digester:1.6::jar" );
expectedNodes.add( "commons-logging:commons-logging:1.0.4::jar" );
expectedNodes.add( "commons-validator:commons-validator:1.2.0::jar" );
expectedNodes.add( "httpunit:httpunit:1.6::jar" );
expectedNodes.add( "jakarta-regexp:jakarta-regexp:1.4::jar" );
expectedNodes.add( "javax.servlet:servlet-api:2.3::jar" );
expectedNodes.add( "jtidy:jtidy:4aug2000r7-dev::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
expectedNodes.add( "nekohtml:nekohtml:0.9.1::jar" );
expectedNodes.add( "org.apache.bcel:bcel:5.2::jar" );
expectedNodes.add( "org.apache.maven:maven-artifact:2.0.4::jar" );
expectedNodes.add( "org.apache.maven:maven-artifact-manager:2.0.2::jar" );
expectedNodes.add( "org.apache.maven:maven-core:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-error-diagnostics:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-model:2.0.4::jar" );
expectedNodes.add( "org.apache.maven:maven-monitor:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-plugin-api:2.0.4::jar" );
expectedNodes.add( "org.apache.maven:maven-plugin-descriptor:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-plugin-parameter-documenter:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-plugin-registry:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-profile:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-project:2.0.4::jar" );
expectedNodes.add( "org.apache.maven:maven-repository-metadata:2.0::jar" );
expectedNodes.add( "org.apache.maven:maven-settings:2.0.4::jar" );
expectedNodes.add( "org.apache.maven.doxia:doxia-core:1.0-alpha-8::jar" );
expectedNodes.add( "org.apache.maven.doxia:doxia-decoration-model:1.0-alpha-8::jar" );
expectedNodes.add( "org.apache.maven.doxia:doxia-sink-api:1.0-alpha-8::jar" );
expectedNodes.add( "org.apache.maven.doxia:doxia-site-renderer:1.0-alpha-8::jar" );
expectedNodes.add( "org.apache.maven.reporting:maven-reporting-api:2.0.4::jar" );
expectedNodes.add( "org.apache.maven.reporting:maven-reporting-impl:2.0.4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-api:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-manager-plexus:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-clearcase:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-cvs-commons:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-cvsexe:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-perforce:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-starteam:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-svn-commons:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.scm:maven-scm-provider-svnexe:1.0-beta-4::jar" );
expectedNodes.add( "org.apache.maven.shared:maven-dependency-tree:1.0-alpha-2::jar" );
expectedNodes.add( "org.apache.maven.shared:maven-plugin-testing-harness:1.0::jar" );
expectedNodes.add( "org.apache.maven.shared:maven-shared-jar:1.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-file:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-http-lightweight:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-http-shared:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-provider-api:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-ssh:1.0-beta-2::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-ssh-common:1.0-beta-2::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-container-default:1.0-alpha-9::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-digest:1.0::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-i18n:1.0-beta-6::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-4::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-utils:1.1::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-velocity:1.1.3::jar" );
expectedNodes.add( "oro:oro:2.0.7::jar" );
expectedNodes.add( "plexus:plexus-utils:1.0.2::jar" );
expectedNodes.add( "regexp:regexp:1.3::jar" );
expectedNodes.add( "rhino:js:1.5R4.1::jar" );
expectedNodes.add( "velocity:velocity:1.4::jar" );
expectedNodes.add( "velocity:velocity-dep:1.4::jar" );
expectedNodes.add( "xerces:xercesImpl:2.6.2::jar" );
expectedNodes.add( "xerces:xmlParserAPIs:2.2.1::jar" );
expectedNodes.add( "xml-apis:xml-apis:1.0.b2::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 1040
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MavenProjectInfoReportsPluginMemoryRepository.java
File diff suppressed because it is too large
View File


+ 35
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MemoryRepository.java View File

@@ -0,0 +1,35 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArchivaProjectModel;

/**
* MemoryRepository
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface MemoryRepository
{
public abstract void addModel( ArchivaProjectModel model );

public abstract ArchivaProjectModel getProjectModel( String groupId, String artifactId, String version );
}

+ 96
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/MemoryRepositoryDependencyGraphBuilder.java View File

@@ -0,0 +1,96 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.VersionedReference;

/**
* MemoryRepositoryProjectResolver
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class MemoryRepositoryDependencyGraphBuilder
implements DependencyGraphBuilder
{
private MemoryRepository memoryRepository;

public ArchivaProjectModel resolveProjectModel( VersionedReference reference )
{
ArtifactReference artifact = new ArtifactReference();
artifact.setGroupId( reference.getGroupId() );
artifact.setArtifactId( reference.getArtifactId() );
artifact.setVersion( reference.getVersion() );
artifact.setType( "pom" );

return resolveProjectModel( artifact );
}

public ArchivaProjectModel resolveProjectModel( ArtifactReference reference )
{
ArchivaProjectModel model = memoryRepository
.getProjectModel( reference.getGroupId(), reference.getArtifactId(), reference.getVersion() );

if ( model == null )
{
throw new NullPointerException( "Unable to find model for " + DependencyGraphKeys.toKey( reference ) );
}

if ( model.getParentProject() != null )
{
ArchivaProjectModel parentModel = resolveProjectModel( model.getParentProject() );

model.getDependencies().addAll( parentModel.getDependencies() );
model.getDependencyManagement().addAll( parentModel.getDependencyManagement() );
}

return model;
}

public MemoryRepository getMemoryRepository()
{
return memoryRepository;
}

public void setMemoryRepository( MemoryRepository memoryRepository )
{
this.memoryRepository = memoryRepository;
}

public DependencyGraph createGraph( VersionedReference versionedProjectReference )
{
String groupId = versionedProjectReference.getGroupId();
String artifactId = versionedProjectReference.getArtifactId();
String version = versionedProjectReference.getVersion();

DependencyGraph graph = new DependencyGraph( groupId, artifactId, version );
return graph;
}

public void resolveNode( DependencyGraph graph, DependencyGraphNode fromNode,
VersionedReference versionedProjectReference )
{
ArchivaProjectModel model = resolveProjectModel( fromNode.getArtifact() );

DependencyGraphUtils.addNodeFromModel( model, graph, fromNode );
}
}

+ 71
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/SimpleDependencyGraphTest.java View File

@@ -0,0 +1,71 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* SimpleDependencyGraphTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class SimpleDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolveDependenciesBasic() throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder = new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new SimpleMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.archiva:archiva-commons:1.0" );

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

List expectedNodes = new ArrayList();
expectedNodes.add( "org.apache.maven.archiva:archiva-commons:1.0::pom" );
expectedNodes.add( "org.codehaus.plexus:plexus-digest:1.0::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
assertNodes( graph, expectedNodes );

List expectedEdges = new ArrayList();
expectedEdges.add( new ExpectedEdge( "org.apache.maven.archiva:archiva-commons:1.0::pom",
"org.codehaus.plexus:plexus-digest:1.0::jar" ) );
expectedEdges.add( new ExpectedEdge( "org.codehaus.plexus:plexus-digest:1.0::jar", "junit:junit:3.8.1::jar" ) );

assertEdges( graph, expectedEdges );
}
}

+ 48
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/SimpleMemoryRepository.java View File

@@ -0,0 +1,48 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArchivaProjectModel;

/**
* SimpleMemoryRepository
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class SimpleMemoryRepository
extends AbstractMemoryRepository
{
public void initialize()
{
ArchivaProjectModel model;

model = toModel( "org.codehaus.plexus:plexus-digest:1.0" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar" ) );
addModel( model );

model = toModel( "junit:junit:3.8.1" );
addModel( model );

model = toModel( "org.apache.maven.archiva:archiva-commons:1.0" );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-digest:1.0::jar" ) );
addModel( model );
}
}

+ 104
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/WagonManagerDependencyGraphTest.java View File

@@ -0,0 +1,104 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.dependency.DependencyGraphFactory;
import org.apache.maven.archiva.model.DependencyScope;
import org.apache.maven.archiva.model.VersionedReference;

import java.util.ArrayList;
import java.util.List;

/**
* WagonManagerDependencyGraphTest
*
* DependencyGraphTest for testing <code>org.apache.maven.wagon:wagon-manager:2.0-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class WagonManagerDependencyGraphTest
extends AbstractDependencyGraphFactoryTestCase
{
public void testResolvedDepsToNodes()
throws GraphTaskException
{
MemoryRepositoryDependencyGraphBuilder graphBuilder =
new MemoryRepositoryDependencyGraphBuilder();
MemoryRepository repository = new WagonManagerMemoryRepository();
graphBuilder.setMemoryRepository( repository );

// Create the factory, and add the test resolver.
DependencyGraphFactory factory = new DependencyGraphFactory();
factory.setGraphBuilder( graphBuilder );
factory.setDesiredScope( DependencyScope.TEST );

// Get the model to resolve from
VersionedReference rootRef = toVersionedReference( "org.apache.maven.wagon:wagon-manager:2.0-SNAPSHOT");

// Perform the resolution.
DependencyGraph graph = factory.getGraph( rootRef );

// Test the results.
assertNotNull( "Graph shouldn't be null.", graph );

String expectedRootRef = "org.apache.maven.wagon:wagon-manager:2.0-SNAPSHOT";
List expectedNodes = new ArrayList();

// Check for all nodes, regardless of scope.
expectedNodes.clear();
expectedNodes.add( "classworlds:classworlds:1.1-alpha-2::jar" );
expectedNodes.add( "com.jcraft:jsch:0.1.27::jar" );
expectedNodes.add( "commons-httpclient:commons-httpclient:2.0.2::jar" );
expectedNodes.add( "commons-lang:commons-lang:2.1::jar" );
expectedNodes.add( "commons-logging:commons-logging:1.0.4::jar" );
expectedNodes.add( "commons-net:commons-net:1.4.1::jar" );
expectedNodes.add( "de.zeigermann.xml:xml-im-exporter:1.1::jar" );
expectedNodes.add( "it.could:webdav:0.4::jar" );
expectedNodes.add( "javax.servlet:servlet-api:2.3::jar" );
expectedNodes.add( "jdom:jdom:1.0::jar" );
expectedNodes.add( "jtidy:jtidy:4aug2000r7-dev::jar" );
expectedNodes.add( "junit:junit:3.8.1::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-file:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-ftp:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-http-lightweight:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-http-shared:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-provider-api:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-ssh:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-ssh-common:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-ssh-external:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.apache.maven.wagon:wagon-webdav:2.0-SNAPSHOT::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-component-api:1.0-alpha-16::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-container-default:1.0-alpha-9::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-6::jar" );
expectedNodes.add( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" );
expectedNodes.add( "org.codehaus.plexus.webdav:plexus-webdav-api:1.0-alpha-1::jar" );
expectedNodes.add( "org.codehaus.plexus.webdav:plexus-webdav-simple:1.0-alpha-1::jar" );
expectedNodes.add( "org.mortbay.jetty:jetty:6.0.2::jar" );
expectedNodes.add( "org.mortbay.jetty:jetty-util:6.0.2::jar" );
expectedNodes.add( "org.mortbay.jetty:servlet-api-2.5:6.0.2::jar" );
expectedNodes.add( "oro:oro:2.0.8::jar" );
expectedNodes.add( "slide:slide-webdavlib:2.1::jar" );

assertGraph( graph, expectedRootRef, expectedNodes );
}

}

+ 772
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/WagonManagerMemoryRepository.java View File

@@ -0,0 +1,772 @@
package org.apache.maven.archiva.dependency.graph;

/*
* 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.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.model.VersionedReference;

/**
* WagonManagerMemoryRepository
*
* MemoryRepository for testing <code>org.apache.maven.wagon:wagon-manager:2.0-SNAPSHOT</code>
*
* Generated by <code>archivadev:generate-dependency-tests</code> plugin
* @version $Id$
*/
public class WagonManagerMemoryRepository
extends AbstractMemoryRepository
{
public void initialize()
{
ArchivaProjectModel model;
Dependency dep;

model = toModel( "org.apache.maven.wagon:wagon-manager:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-9::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-api:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-file:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ftp:2.0-SNAPSHOT::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-http-lightweight:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ssh:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ssh-external:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-webdav:2.0-SNAPSHOT::jar", "test" ) );
dep = toDependency( "org.codehaus.plexus.webdav:plexus-webdav-simple:1.0-alpha-1::jar", "test" );
addExclusion( dep, "org.codehaus.plexus:plexus-component-api" );
model.addDependency( dep );
model.addDependency( toDependency( "org.mortbay.jetty:jetty:6.0.2::jar", "test" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-provider-api:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-provider-test:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-ssh-common-test:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-ssh-common:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "junit:junit:3.8.1::jar" ) );
dep = toDependency( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-6::jar" );
addExclusion( dep, "plexus:plexus-utils" );
addExclusion( dep, "org.codehaus.plexus:plexus-container-default" );
addExclusion( dep, "classworlds:classworlds" );
model.addDependencyManagement( dep );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-9::jar", "test" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven:maven-parent:5" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-provider-api:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-provider-test:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-ssh-common-test:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-ssh-common:2.0-SNAPSHOT::jar" ) );
model.addDependencyManagement( toDependency( "junit:junit:3.8.1::jar" ) );
dep = toDependency( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-6::jar" );
addExclusion( dep, "plexus:plexus-utils" );
addExclusion( dep, "org.codehaus.plexus:plexus-container-default" );
addExclusion( dep, "classworlds:classworlds" );
model.addDependencyManagement( dep );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-9::jar", "test" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-parent:5" );
model.setParentProject( toParent( "org.apache:apache:3" ) );
addModel( model );

model = toModel( "org.apache:apache:3" );
addModel( model );

model = toModel( "junit:junit:3.8.1" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-provider-api:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.11" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus:1.0.11" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-provider-test:2.0-SNAPSHOT" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-ssh-common-test:2.0-SNAPSHOT" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-ssh-common:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-6::jar" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-api:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-test:2.0-SNAPSHOT::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-6" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-interactivity:1.0-alpha-6" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.4::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-interactivity:1.0-alpha-6" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-components:1.1.9" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-components:1.1.9" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.10" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-16::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-16::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus:1.0.10" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-component-api:1.0-alpha-16" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-containers:1.0-alpha-16" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-containers:1.0-alpha-16" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.9" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-16::jar" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-utils:1.3::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus:1.0.9" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.9" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-utils:1.3" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.8" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus:1.0.8" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-container-default:1.0-alpha-16" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-containers:1.0-alpha-16" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-16::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.3::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-7::jar" ) );
model.addDependency( toDependency( "jmock:jmock:1.0.1::jar", "test" ) );
addModel( model );

model = toModel( "jmock:jmock:1.0.1" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-utils:1.4" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.9" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-container-default:1.0-alpha-9" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-containers:1.0.3" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-containers:1.0.3" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.4" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus:1.0.4" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-utils:1.0.4" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "classworlds:classworlds:1.1-alpha-2" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-file:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-ftp:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "commons-net:commons-net:1.4.1::jar" ) );
dep = toDependency( "org.codehaus.plexus:plexus-ftpd:1.0-alpha-1::jar", "test" );
addExclusion( dep, "plexus:plexus-container-default" );
model.addDependency( dep );
addModel( model );

model = toModel( "commons-net:commons-net:1.4.1" );
model.addDependency( toDependency( "oro:oro:2.0.8::jar" ) );
addModel( model );

model = toModel( "oro:oro:2.0.8" );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-ftpd:1.0-alpha-1" );
model.addDependency( toDependency( "concurrent:concurrent:1.3.4::jar", "compile" ) );
model.addDependency( toDependency( "cornerstone-threads:cornerstone-threads-api:1.0::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "cornerstone-sockets:cornerstone-sockets-api:1.0::jar", "compile" ) );
model.addDependency( toDependency( "cornerstone-connection:cornerstone-connection-impl:1.0::jar", "compile" ) );
model.addDependency( toDependency( "excalibur-pool:excalibur-pool-impl:2.0::jar", "compile" ) );
model.addDependency( toDependency( "excalibur-thread:excalibur-thread:1.1.1::jar", "compile" ) );
model.addDependency( toDependency( "cornerstone-sockets:cornerstone-sockets-impl:1.0::jar", "compile" ) );
model.addDependency( toDependency( "cornerstone-connection:cornerstone-connection-api:1.0::jar", "compile" ) );
model.addDependency( toDependency( "commons-collections:commons-collections:3.0::jar", "compile" ) );
model.addDependency( toDependency( "avalon:avalon-framework:4.1.4::jar", "compile" ) );
model.addDependency( toDependency( "cornerstone-threads:cornerstone-threads-impl:1.0::jar", "compile" ) );
model.addDependency( toDependency( "excalibur-pool:excalibur-pool-api:2.0::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-avalon-personality:0.13::jar", "compile" ) );
model.addDependency( toDependency( "plexus:plexus-container-default:1.0-alpha-2::jar", "compile" ) );
addModel( model );

model = toModel( "concurrent:concurrent:1.3.4" );
addModel( model );

model = toModel( "cornerstone-threads:cornerstone-threads-api:1.0" );
addModel( model );

model = toModel( "cornerstone-sockets:cornerstone-sockets-api:1.0" );
addModel( model );

model = toModel( "cornerstone-connection:cornerstone-connection-impl:1.0" );
addModel( model );

model = toModel( "excalibur-pool:excalibur-pool-impl:2.0" );
addModel( model );

model = toModel( "excalibur-thread:excalibur-thread:1.1.1" );
addModel( model );

model = toModel( "cornerstone-sockets:cornerstone-sockets-impl:1.0" );
addModel( model );

model = toModel( "cornerstone-connection:cornerstone-connection-api:1.0" );
addModel( model );

model = toModel( "commons-collections:commons-collections:3.0" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "avalon:avalon-framework:4.1.4" );
addModel( model );

model = toModel( "cornerstone-threads:cornerstone-threads-impl:1.0" );
addModel( model );

model = toModel( "excalibur-pool:excalibur-pool-api:2.0" );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-avalon-personality:0.13" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "avalon:avalon-framework:4.1.4::jar", "compile" ) );
model.addDependency( toDependency( "plexus:plexus-container-default:1.0-alpha-2::jar", "compile" ) );
addModel( model );

model = toModel( "plexus:plexus-container-default:1.0-alpha-2" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-http-lightweight:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-http-shared:2.0-SNAPSHOT::jar" ) );
dep = toDependency( "plexus:plexus-jetty-httpd:1.0-beta-1::jar", "test" );
addExclusion( dep, "plexus:plexus-container-default" );
model.addDependency( dep );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-http-shared:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "jtidy:jtidy:4aug2000r7-dev::jar" ) );
addModel( model );

model = toModel( "jtidy:jtidy:4aug2000r7-dev" );
addModel( model );

model = toModel( "plexus:plexus-jetty-httpd:1.0-beta-1" );
model.setParentProject( toParent( "plexus:plexus-components:1.0" ) );
model.addDependency( toDependency( "jetty:jetty:4.2.10::jar" ) );
model.addDependency( toDependency( "servletapi:servletapi:2.3::jar" ) );
addModel( model );

model = toModel( "plexus:plexus-components:1.0" );
model.setParentProject( toParent( "plexus:plexus-root:1.0" ) );
model.addDependency( toDependency( "plexus:plexus-container-default:1.0-alpha-2::jar" ) );
addModel( model );

model = toModel( "plexus:plexus-root:1.0" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "jetty:jetty:4.2.10" );
model.addDependency( toDependency( "javax.servlet:servlet-api:2.3::jar", "runtime" ) );
addModel( model );

model = toModel( "javax.servlet:servlet-api:2.3" );
addModel( model );

model = toModel( "servletapi:servletapi:2.3" );
model.setRelocation( new VersionedReference() );
model.getRelocation().setGroupId( "javax.servlet" );
model.getRelocation().setArtifactId( "servlet-api" );
model.getRelocation().setVersion( "2.3" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-ssh:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "com.jcraft:jsch:0.1.27::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-6::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ssh-common:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ssh-common-test:2.0-SNAPSHOT::jar", "test" ) );
addModel( model );

model = toModel( "com.jcraft:jsch:0.1.27" );
dep = toDependency( "com.jcraft:jzlib:1.0.7::jar" );
dep.setOptional( true );
model.addDependency( dep );
addModel( model );

model = toModel( "com.jcraft:jzlib:1.0.7" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-ssh-external:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ssh-common:2.0-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-ssh-common-test:2.0-SNAPSHOT::jar", "test" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-webdav:2.0-SNAPSHOT" );
model.setParentProject( toParent( "org.apache.maven.wagon:wagon-providers:2.0-SNAPSHOT" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.4.2-SNAPSHOT::jar" ) );
model.addDependency( toDependency( "slide:slide-webdavlib:2.1::jar" ) );
model.addDependency( toDependency( "commons-logging:commons-logging:1.0.4::jar", "runtime" ) );
model.addDependency( toDependency( "it.could:webdav:0.4::jar", "test" ) );
addModel( model );

model = toModel( "slide:slide-webdavlib:2.1" );
model.addDependency( toDependency( "commons-httpclient:commons-httpclient:2.0.2::jar" ) );
model.addDependency( toDependency( "jdom:jdom:1.0::jar" ) );
model.addDependency( toDependency( "de.zeigermann.xml:xml-im-exporter:1.1::jar" ) );
addModel( model );

model = toModel( "commons-httpclient:commons-httpclient:2.0.2" );
model.addDependency( toDependency( "commons-logging:commons-logging:1.0.3::jar" ) );
addModel( model );

model = toModel( "commons-logging:commons-logging:1.0.3" );
dep = toDependency( "log4j:log4j:1.2.6::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "logkit:logkit:1.0.1::jar" );
dep.setOptional( true );
model.addDependency( dep );
model.addDependency( toDependency( "junit:junit:3.7::jar", "test" ) );
addModel( model );

model = toModel( "log4j:log4j:1.2.6" );
addModel( model );

model = toModel( "logkit:logkit:1.0.1" );
addModel( model );

model = toModel( "junit:junit:3.7" );
addModel( model );

model = toModel( "jdom:jdom:1.0" );
dep = toDependency( "xerces:xercesImpl:2.6.0::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "xml-apis:xml-apis:1.0.b2::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "jaxen:jaxen:1.0-FCS::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "saxpath:saxpath:1.0-FCS::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "xalan:xalan:2.5.0::jar" );
dep.setOptional( true );
model.addDependency( dep );
addModel( model );

model = toModel( "xerces:xercesImpl:2.6.0" );
addModel( model );

model = toModel( "xml-apis:xml-apis:1.0.b2" );
addModel( model );

model = toModel( "jaxen:jaxen:1.0-FCS" );
addModel( model );

model = toModel( "saxpath:saxpath:1.0-FCS" );
addModel( model );

model = toModel( "xalan:xalan:2.5.0" );
addModel( model );

model = toModel( "de.zeigermann.xml:xml-im-exporter:1.1" );
addModel( model );

model = toModel( "commons-logging:commons-logging:1.0.4" );
dep = toDependency( "log4j:log4j:1.2.6::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "logkit:logkit:1.0.1::jar" );
dep.setOptional( true );
model.addDependency( dep );
model.addDependency( toDependency( "junit:junit:3.7::jar", "test" ) );
dep = toDependency( "avalon-framework:avalon-framework:4.1.3::jar" );
dep.setOptional( true );
model.addDependency( dep );
addModel( model );

model = toModel( "avalon-framework:avalon-framework:4.1.3" );
addModel( model );

model = toModel( "it.could:webdav:0.4" );
model.addDependency( toDependency( "javax.servlet:servlet-api:2.3::jar", "runtime" ) );
addModel( model );

model = toModel( "org.codehaus.plexus.webdav:plexus-webdav-simple:1.0-alpha-1" );
model.setParentProject( toParent( "org.codehaus.plexus.webdav:plexus-webdav-providers-parent:1.0-alpha-1" ) );
model.addDependency( toDependency( "commons-lang:commons-lang:2.1::jar" ) );
model.addDependency( toDependency( "it.could:webdav:0.4::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus.webdav:plexus-webdav-providers-parent:1.0-alpha-1" );
model.setParentProject( toParent( "org.codehaus.plexus.webdav:plexus-webdav-parent:1.0-alpha-1" ) );
model.addDependency( toDependency( "org.codehaus.plexus.webdav:plexus-webdav-api:1.0-alpha-1::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus.webdav:plexus-webdav-test:1.0-alpha-1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus.webdav:plexus-webdav-parent:1.0-alpha-1" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-components:1.1.8" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-components:1.1.8" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.9" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-15::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-15::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-component-api:1.0-alpha-15" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-containers:1.0-alpha-15" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-6::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-containers:1.0-alpha-15" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.9" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-6::jar" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-15::jar" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-utils:1.3::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-6" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus:1.0.9" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-container-default:1.0-alpha-15" );
model.setParentProject( toParent( "org.codehaus.plexus:plexus-containers:1.0-alpha-15" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-15::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.3::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-classworlds:1.2-alpha-6::jar" ) );
model.addDependency( toDependency( "jmock:jmock:1.0.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus.webdav:plexus-webdav-api:1.0-alpha-1" );
model.setParentProject( toParent( "org.codehaus.plexus.webdav:plexus-webdav-parent:1.0-alpha-1" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-component-api:1.0-alpha-16::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-16::jar" ) );
model.addDependency( toDependency( "javax.servlet:servlet-api:2.3::jar" ) );
model.addDependency( toDependency( "commons-lang:commons-lang:2.1::jar" ) );
addModel( model );

model = toModel( "commons-lang:commons-lang:2.1" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus.webdav:plexus-webdav-test:1.0-alpha-1" );
addModel( model );

model = toModel( "org.mortbay.jetty:jetty:6.0.2" );
model.setParentProject( toParent( "org.mortbay.jetty:project:6.0.2" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "org.mortbay.jetty:jetty-util:6.0.2::jar" ) );
model.addDependency( toDependency( "org.mortbay.jetty:servlet-api-2.5:6.0.2::jar" ) );
addModel( model );

model = toModel( "org.mortbay.jetty:project:6.0.2" );
model.addDependencyManagement( toDependency( "org.apache.maven:maven-plugin-tools-api:2.0::jar" ) );
model.addDependencyManagement( toDependency( "junit:junit:3.8.1::jar" ) );
model.addDependencyManagement( toDependency( "org.slf4j:jcl104-over-slf4j:1.0.1::jar" ) );
model.addDependencyManagement( toDependency( "org.slf4j:slf4j-simple:1.0.1::jar" ) );
model.addDependencyManagement( toDependency( "mx4j:mx4j:3.0.1::jar" ) );
model.addDependencyManagement( toDependency( "mx4j:mx4j-tools:3.0.1::jar" ) );
model.addDependencyManagement( toDependency( "xerces:xercesImpl:${xerces-version}::jar" ) );
model.addDependencyManagement( toDependency( "commons-el:commons-el:1.0::jar" ) );
model.addDependencyManagement( toDependency( "ant:ant:1.6.5::jar" ) );
model.addDependencyManagement( toDependency( "javax.mail:mail:1.4::jar" ) );
model.addDependencyManagement( toDependency( "javax.activation:activation:1.1::jar" ) );
model.addProperty( "jasper-version", "5.5.15" );
model.addProperty( "junit-version", "3.8.1" );
model.addProperty( "ant-version", "1.6.5" );
model.addProperty( "mail-version", "1.4" );
model.addProperty( "commons-el-version", "1.0" );
model.addProperty( "slf4j-version", "1.0.1" );
model.addProperty( "eclipse-compiler-version", "3.1.1" );
model.addProperty( "mx4j-version", "3.0.1" );
model.addProperty( "jta-spec-version", "1.0.1B-rc4" );
model.addProperty( "activation-version", "1.1" );
addModel( model );

model = toModel( "org.apache.maven:maven-plugin-tools-api:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven-plugin-tools:2.0" ) );
model.addDependency( toDependency( "org.apache.maven:maven-project:2.0::jar" ) );
model.addDependency( toDependency( "org.apache.maven:maven-plugin-descriptor:2.0::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-plugin-tools:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
addModel( model );

model = toModel( "org.apache.maven:maven:2.0" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar" ) );
model.addDependencyManagement( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-provider-api:1.0-alpha-5::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-ssh:1.0-alpha-5::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-file:1.0-alpha-5::jar" ) );
model.addDependencyManagement( toDependency( "org.apache.maven.wagon:wagon-http-lightweight:1.0-alpha-5::jar" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8" );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar", "compile" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-provider-api:1.0-alpha-5" );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-ssh:1.0-alpha-5" );
model.addDependency( toDependency( "com.jcraft:jsch:0.1.23::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-api:1.0-alpha-5::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar", "compile" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar", "compile" ) );
model.addDependency( toDependency( "plexus:plexus-utils:1.0.2::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-4::jar", "compile" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-test:1.0-alpha-5::jar", "test" ) );
addModel( model );

model = toModel( "com.jcraft:jsch:0.1.23" );
addModel( model );

model = toModel( "plexus:plexus-utils:1.0.2" );
model.setParentProject( toParent( "plexus:plexus-root:1.0.3" ) );
addModel( model );

model = toModel( "plexus:plexus-root:1.0.3" );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-interactivity-api:1.0-alpha-4" );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-7::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar", "compile" ) );
model.addDependency( toDependency( "plexus:plexus-utils:1.0.2::jar", "compile" ) );
addModel( model );

model = toModel( "org.codehaus.plexus:plexus-container-default:1.0-alpha-7" );
model.setParentProject( toParent( "plexus:plexus-containers:1.0.2" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "compile" ) );
model.addDependency( toDependency( "plexus:plexus-utils:1.0.2::jar" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar" ) );
addModel( model );

model = toModel( "plexus:plexus-containers:1.0.2" );
model.setParentProject( toParent( "plexus:plexus-root:1.0.3" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-provider-test:1.0-alpha-5" );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-file:1.0-alpha-5" );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-api:1.0-alpha-5::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar", "test" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-test:1.0-alpha-5::jar", "test" ) );
addModel( model );

model = toModel( "org.apache.maven.wagon:wagon-http-lightweight:1.0-alpha-5" );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar", "compile" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-api:1.0-alpha-5::jar", "compile" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar", "test" ) );
model.addDependency( toDependency( "servletapi:servletapi:2.3::jar", "test" ) );
model.addDependency( toDependency( "classworlds:classworlds:1.1-alpha-2::jar", "test" ) );
model.addDependency( toDependency( "jetty:jetty:4.2.10::jar", "test" ) );
model.addDependency( toDependency( "plexus:plexus-jetty-httpd:1.0-beta-1::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-test:1.0-alpha-5::jar", "test" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-project:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.apache.maven:maven-artifact-test:2.0::jar", "test" ) );
model.addDependency( toDependency( "org.apache.maven:maven-profile:2.0::jar" ) );
model.addDependency( toDependency( "org.apache.maven:maven-model:2.0::jar" ) );
model.addDependency( toDependency( "org.apache.maven:maven-artifact-manager:2.0::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
model.addDependency( toDependency( "org.apache.maven:maven-artifact:2.0::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-artifact-test:2.0" );
addModel( model );

model = toModel( "org.apache.maven:maven-profile:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.apache.maven:maven-model:2.0::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-model:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-artifact-manager:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.apache.maven:maven-repository-metadata:2.0::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-file:1.0-alpha-5::jar", "test" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
model.addDependency( toDependency( "org.apache.maven:maven-artifact:2.0::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar" ) );
model.addDependency( toDependency( "org.apache.maven.wagon:wagon-provider-api:1.0-alpha-5::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-repository-metadata:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-artifact:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-utils:1.0.4::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar", "test" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-plugin-descriptor:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "org.apache.maven:maven-plugin-api:2.0::jar" ) );
model.addDependency( toDependency( "org.apache.maven:maven-artifact:2.0::jar" ) );
model.addDependency( toDependency( "org.codehaus.plexus:plexus-container-default:1.0-alpha-8::jar" ) );
addModel( model );

model = toModel( "org.apache.maven:maven-plugin-api:2.0" );
model.setParentProject( toParent( "org.apache.maven:maven:2.0" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
addModel( model );

model = toModel( "org.slf4j:jcl104-over-slf4j:1.0.1" );
addModel( model );

model = toModel( "org.slf4j:slf4j-simple:1.0.1" );
addModel( model );

model = toModel( "mx4j:mx4j:3.0.1" );
addModel( model );

model = toModel( "mx4j:mx4j-tools:3.0.1" );
addModel( model );

model = toModel( "xerces:xercesImpl:${xerces-version}" );
addModel( model );

model = toModel( "commons-el:commons-el:1.0" );
model.addDependency( toDependency( "servletapi:servletapi:2.4-20040521::jar", "provided" ) );
model.addDependency( toDependency( "jspapi:jsp-api:2.0-20040521::jar", "provided" ) );
model.addDependency( toDependency( "commons-logging:commons-logging:1.0.3::jar" ) );
addModel( model );

model = toModel( "servletapi:servletapi:2.4-20040521" );
addModel( model );

model = toModel( "jspapi:jsp-api:2.0-20040521" );
addModel( model );

model = toModel( "ant:ant:1.6.5" );
dep = toDependency( "xerces:xerces-impl:2.6.2::jar" );
dep.setOptional( true );
model.addDependency( dep );
dep = toDependency( "xml-apis:xml-apis:2.6.2::jar" );
dep.setOptional( true );
model.addDependency( dep );
addModel( model );

model = toModel( "xerces:xerces-impl:2.6.2" );
addModel( model );

model = toModel( "xml-apis:xml-apis:2.6.2" );
addModel( model );

model = toModel( "javax.mail:mail:1.4" );
model.addDependency( toDependency( "javax.activation:activation:1.1::jar" ) );
addModel( model );

model = toModel( "javax.activation:activation:1.1" );
addModel( model );

model = toModel( "org.mortbay.jetty:jetty-util:6.0.2" );
model.setParentProject( toParent( "org.mortbay.jetty:project:6.0.2" ) );
model.addDependency( toDependency( "junit:junit:3.8.1::jar", "test" ) );
model.addDependency( toDependency( "org.mortbay.jetty:servlet-api-2.5:6.0.2::jar", "provided" ) );
addModel( model );

model = toModel( "org.mortbay.jetty:servlet-api-2.5:6.0.2" );
model.setParentProject( toParent( "org.mortbay.jetty:project:6.0.2" ) );
addModel( model );

}
}

+ 67
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/functors/ToKeyTransformer.java View File

@@ -0,0 +1,67 @@
package org.apache.maven.archiva.dependency.graph.functors;

/*
* 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.commons.collections.Transformer;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.Keys;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArtifactReference;

/**
* ToKeyTransformer
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ToKeyTransformer
implements Transformer
{

public Object transform( Object input )
{
if ( input instanceof ArchivaProjectModel )
{
return Keys.toKey( (ArchivaProjectModel) input );
}

if ( input instanceof DependencyGraphNode )
{
return DependencyGraphKeys.toKey( ((DependencyGraphNode) input).getArtifact() );
}

if ( input instanceof DependencyGraphEdge )
{
DependencyGraphEdge edge = (DependencyGraphEdge) input;
// Potentially Confusing, but this is called "To"KeyTransformer after all.
return DependencyGraphKeys.toKey( edge.getNodeTo() );
}

if ( input instanceof ArtifactReference )
{
return DependencyGraphKeys.toKey( ((ArtifactReference) input) );
}

return input;
}

}

+ 227
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/tasks/DependencyManagementStackTest.java View File

@@ -0,0 +1,227 @@
package org.apache.maven.archiva.dependency.graph.tasks;

/*
* 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.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.tasks.DependencyManagementStack;
import org.apache.maven.archiva.dependency.graph.tasks.DependencyManagementStack.Rules;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.Dependency;

import junit.framework.TestCase;

/**
* DependencyManagementStackTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyManagementStackTest
extends TestCase
{
public DependencyGraphNode toNode( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ":" );
assertEquals( "toNode(" + key + ") requires 5 parts", 5, parts.length );

ArtifactReference ref = new ArtifactReference();
ref.setGroupId( parts[0] );
ref.setArtifactId( parts[1] );
ref.setVersion( parts[2] );
ref.setClassifier( parts[3] );
ref.setType( parts[4] );

return new DependencyGraphNode( ref );
}

protected Dependency toDependency( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );

assertEquals( "Dependency key [" + key + "] should be 5 parts.", 5, parts.length );

Dependency dep = new Dependency();

dep.setGroupId( parts[0] );
dep.setArtifactId( parts[1] );
dep.setVersion( parts[2] );
dep.setClassifier( parts[3] );
dep.setType( parts[4] );

return dep;
}

public void testPushPopSimple()
{
DependencyGraphNode node = toNode( "org.apache.maven.archiva:depmanstack-testcase:1.0::jar" );
Dependency dep = toDependency( "junit:junit:3.8.1::jar" );
dep.setScope( "test" );
node.addDependencyManagement( dep );

DependencyManagementStack stack = new DependencyManagementStack();
stack.push( node );
DependencyGraphNode oldnode = stack.pop();
assertEquals( "added node to old node", node, oldnode );
}

public void testPushPopTwoDeep()
{
DependencyManagementStack stack = new DependencyManagementStack();
Dependency dep;

// top node.
DependencyGraphNode projectNode = toNode( "org.apache.maven.archiva:depmanstack-testcase:1.0::jar" );
dep = toDependency( "junit:junit:3.8.1::jar" );
dep.setScope( "test" );
projectNode.addDependencyManagement( dep );
stack.push( projectNode );

// direct node.
DependencyGraphNode directNode = toNode( "org.apache.maven.archiva:depmanstack-common:1.0::jar" );
dep = toDependency( "junit:junit:3.7::jar" );
dep.setScope( "test" );
directNode.addDependencyManagement( dep );
stack.push( directNode );

// transitive node.
DependencyGraphNode transNode = toNode( "org.apache.maven.archiva:depmanstack-model:1.0::jar" );
dep = toDependency( "junit:junit:3.7::jar" );
transNode.addDependencyManagement( dep );
stack.push( transNode );

// Test it
assertEquals( "popped node is trans node", transNode, stack.pop() );
assertEquals( "popped node is direct node", directNode, stack.pop() );
assertEquals( "popped node is project node", projectNode, stack.pop() );
}

public void testApplyNodeVersionParentWins()
{
DependencyManagementStack stack = new DependencyManagementStack();
Dependency dep;

// top node.
DependencyGraphNode projectNode = toNode( "org.apache.maven.archiva:depmanstack-testcase:1.0::jar" );
dep = toDependency( "junit:junit:3.8.1::jar" );
dep.setScope( "test" );
projectNode.addDependencyManagement( dep );
stack.push( projectNode );

// direct node.
DependencyGraphNode directNode = toNode( "org.apache.maven.archiva:depmanstack-common:1.0::jar" );
dep = toDependency( "junit:junit:3.7::jar" );
dep.setScope( "test" );
directNode.addDependencyManagement( dep );
stack.push( directNode );

// transitive node.
DependencyGraphNode transNode = toNode( "org.apache.maven.archiva:depmanstack-model:1.0::jar" );
dep = toDependency( "junit:junit:3.7.1::jar" );
transNode.addDependencyManagement( dep );
stack.push( transNode );

// Test it
DependencyGraphNode junitNode = toNode( "junit:junit:1.0::jar" );

assertRules( "junit (lvl:trans)", stack, junitNode, "3.8.1", "test", null );
stack.pop();
assertRules( "junit (lvl:direct)", stack, junitNode, "3.8.1", "test", null );
stack.pop();
assertRules( "junit (lvl:project)", stack, junitNode, "3.8.1", "test", null );
}

/**
* This test is based off of Carlos Sanchez's depman example use case.
*
* In a simple project chain of A:1.0 -&gt; B:1.0 -&gt; C:1.0 -&gt; D:1.0
* If B:1.0 has a dependency management section stating dep D should be version 2.0
* Then the dep D when viewed from A should be version 2.0
*/
public void testApplyNodeVersionCarlosABCD()
{
DependencyManagementStack stack = new DependencyManagementStack();
Dependency dep;

// project node, A
DependencyGraphNode nodeA = toNode( "org.apache.maven.archiva:carlos-A:1.0::jar" );
stack.push( nodeA );

// sub node, B
DependencyGraphNode nodeB = toNode( "org.apache.maven.archiva:carlos-B:1.0::jar" );
dep = toDependency( "org.apache.maven.archiva:carlos-D:2.0::jar" );
nodeB.addDependencyManagement( dep );
stack.push( nodeB );

// sub node, C
DependencyGraphNode nodeC = toNode( "org.apache.maven.archiva:carlos-C:1.0::jar" );
stack.push( nodeC );

// sub node, D
// Not added to the stack, as this is the node that is having the rules applied to it.
DependencyGraphNode nodeD = toNode( "org.apache.maven.archiva:carlos-D:1.0::jar" );

// Test it
assertRules( "node D (lvl:C)", stack, nodeD, "2.0", null, null );
stack.pop();
assertRules( "node D (lvl:B)", stack, nodeD, "2.0", null, null );
stack.pop();
assertNoRules( "node D (lvl:A)", stack, nodeD, "2.0", null, null );
}

/**
* Test for expected rules, that should be enforced for the provided node.
* NOTE: This test will update the node.artifact.version to whatever is stated in the rules.
*/
private void assertRules( String msg, DependencyManagementStack stack, DependencyGraphNode node,
String expectedVersion, String expectedScope, String expectedExclusions[] )
{
Rules rules = stack.getRules( node );
assertNotNull( msg + " rules should not be null.", rules );

node.getArtifact().setVersion( rules.artifact.getVersion() );

assertEquals( msg + ": version", expectedVersion, rules.artifact.getVersion() );
assertEquals( msg + ": scope", expectedScope, rules.scope );

if ( expectedExclusions != null )
{
// TODO: test for exclusion settings.
}
}

/**
* Test for when there are no rules being enforced for the provided node.
* Similar to assertRules() above.
*/
private void assertNoRules( String msg, DependencyManagementStack stack, DependencyGraphNode node,
String expectedVersion, String expectedScope, String expectedExclusions[] )
{
Rules rules = stack.getRules( node );
assertNull( msg + " rules should be null.", rules );

assertEquals( msg + ": version", expectedVersion, node.getArtifact().getVersion() );

if ( expectedExclusions != null )
{
// TODO: test for exclusion settings.
}
}
}

+ 231
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/walk/DependencyGraphWalkerTest.java View File

@@ -0,0 +1,231 @@
package org.apache.maven.archiva.dependency.graph.walk;

/*
* 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.commons.lang.StringUtils;
import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.tasks.FlagCyclicEdgesTask;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphWalker;
import org.apache.maven.archiva.dependency.graph.walk.WalkDepthFirstSearch;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.List;

import junit.framework.TestCase;

/**
* DependencyGraphWalkerTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyGraphWalkerTest
extends TestCase
{
/**
* <pre>
* [foo-util] ---&gt; [foo-common]
* \
* ---------&gt; [foo-xml] ---&gt; [xercesImpl] ---&gt; [xmlParserAPIs]
* \ \
* \ ---&gt; [jdom] ----+
* \ |
* ----&gt; [jaxen] &lt;--+
* </pre>
*/
public void testModerateWalk()
{
DependencyGraph graph = new DependencyGraph( "org.foo", "foo-util", "1.0" );
String rootKey = DependencyGraphKeys.toKey( graph.getRootNode().getArtifact() );
addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-common:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-xml:1.0::jar" ) );

addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "xerces:xercesImpl:2.2.1::jar" ) );
addEdgeAndNodes( graph, toEdge( "xerces:xercesImpl:2.2.1::jar", "xerces:xmlParserAPIs:2.2.1::jar" ) );
addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jdom:jdom:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( "jdom:jdom:1.0::jar", "jaxen:jaxen:1.0::jar" ) );

DependencyGraphWalker walker = new WalkDepthFirstSearch();
WalkCollector walkCollector = new WalkCollector();
walker.visit( graph, walkCollector );

String expectedPath[] = new String[] {
rootKey,
"org.foo:foo-common:1.0::jar",
"org.foo:foo-xml:1.0::jar",
"jaxen:jaxen:1.0::jar",
"xerces:xercesImpl:2.2.1::jar",
"xerces:xmlParserAPIs:2.2.1::jar",
"jdom:jdom:1.0::jar" };

assertVisitor( walkCollector, 1, 7, 7 );
assertPath( expectedPath, walkCollector.getCollectedPath() );
}

/**
* <pre>
* [foo-util] ---&gt; [foo-common]
* \
* ---------&gt; [foo-xml] ---&gt; [xercesImpl] ---&gt; [xmlParserAPIs]
* </pre>
*/
public void testSimpleWalk()
{
DependencyGraph graph = new DependencyGraph( "org.foo", "foo-util", "1.0" );
String rootKey = DependencyGraphKeys.toKey( graph.getRootNode().getArtifact() );
addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-common:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-xml:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "xerces:xercesImpl:2.2.1::jar" ) );
addEdgeAndNodes( graph, toEdge( "xerces:xercesImpl:2.2.1::jar", "xerces:xmlParserAPIs:2.2.1::jar" ) );

DependencyGraphWalker walker = new WalkDepthFirstSearch();
WalkCollector walkCollector = new WalkCollector();
walker.visit( graph, walkCollector );

String expectedPath[] = new String[] {
rootKey,
"org.foo:foo-common:1.0::jar",
"org.foo:foo-xml:1.0::jar",
"xerces:xercesImpl:2.2.1::jar",
"xerces:xmlParserAPIs:2.2.1::jar" };

assertVisitor( walkCollector, 1, 5, 4 );
assertPath( expectedPath, walkCollector.getCollectedPath() );
}

/**
* <pre>
* [foo-util] ---&gt; [foo-common]
* \
* \ +----------------------------------------+
* \ v |
* -------&gt; [foo-xml] ---&gt; [xercesImpl] ---&gt; [xmlParserAPIs]
* \ \
* \ ---&gt; [jdom] ----+
* \ |
* ----&gt; [jaxen] &lt;--+
* </pre>
*/
public void testDeepNodeWalk()
{
DependencyGraph graph = new DependencyGraph( "org.foo", "foo-util", "1.0" );
String rootKey = DependencyGraphKeys.toKey( graph.getRootNode().getArtifact() );
addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-common:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-xml:1.0::jar" ) );

addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "xerces:xercesImpl:2.2.1::jar" ) );
addEdgeAndNodes( graph, toEdge( "xerces:xercesImpl:2.2.1::jar", "xerces:xmlParserAPIs:2.2.1::jar" ) );
addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jdom:jdom:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
addEdgeAndNodes( graph, toEdge( "jdom:jdom:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
// introduce cyclic dep. intentional. should only result in walking to foo-xml once.
addEdgeAndNodes( graph, toEdge( "xerces:xmlParserAPIs:2.2.1::jar", "org.foo:foo-xml:1.0::jar" ) );

new FlagCyclicEdgesTask().executeTask( graph );

DependencyGraphWalker walker = new WalkDepthFirstSearch();
WalkCollector walkCollector = new WalkCollector();
ArtifactReference startRef = toArtifactReference( "org.foo:foo-xml:1.0::jar" );
DependencyGraphNode startNode = new DependencyGraphNode( startRef );
walker.visit( graph, startNode, walkCollector );

String expectedPath[] = new String[] {
"org.foo:foo-xml:1.0::jar",
"jaxen:jaxen:1.0::jar",
"xerces:xercesImpl:2.2.1::jar",
"xerces:xmlParserAPIs:2.2.1::jar",
"jdom:jdom:1.0::jar" };

assertVisitor( walkCollector, 1, 5, 6 );
assertPath( expectedPath, walkCollector.getCollectedPath() );
}

private void addEdgeAndNodes( DependencyGraph graph, DependencyGraphEdge edge )
{
ensureNodeExists( graph, edge.getNodeFrom() );
ensureNodeExists( graph, edge.getNodeTo() );
graph.addEdge( edge );
}

private void ensureNodeExists( DependencyGraph graph, ArtifactReference artifact )
{
DependencyGraphNode node = graph.getNode( artifact );
if ( node == null )
{
node = new DependencyGraphNode( artifact );
graph.addNode( node );
}
}

private void assertPath( String[] expectedPath, List collectedPath )
{
assertEquals( "Path.length", expectedPath.length, collectedPath.size() );

for ( int i = 0; i < expectedPath.length; i++ )
{
assertEquals( "Walk path[" + i + "]", expectedPath[i], (String) collectedPath.get( i ) );
}
}

private void assertVisitor( WalkCollector walkCollector, int countGraphs, int countNodes, int countEdges )
{
assertEquals( "Count of graph discovery.", countGraphs, walkCollector.getCountDiscoverGraph() );
assertEquals( "Count of graph finished.", countGraphs, walkCollector.getCountFinishGraph() );
assertEquals( "Discover - Finish = 0 (on graph counts)", 0,
( walkCollector.getCountDiscoverGraph() - walkCollector.getCountFinishGraph() ) );

assertEquals( "Count of node discovery.", countNodes, walkCollector.getCountDiscoverNode() );
assertEquals( "Count of node finished.", countNodes, walkCollector.getCountFinishNode() );
assertEquals( "Discover - Finish = 0 (on node counts)", 0,
( walkCollector.getCountDiscoverNode() - walkCollector.getCountFinishNode() ) );

assertEquals( "Count of edge discovery.", countEdges, walkCollector.getCountDiscoverEdge() );
assertEquals( "Count of edge finished.", countEdges, walkCollector.getCountFinishEdge() );
assertEquals( "Discover - Finish = 0 (on edge counts)", 0,
( walkCollector.getCountDiscoverEdge() - walkCollector.getCountFinishEdge() ) );
}

private DependencyGraphEdge toEdge( String fromKey, String toKey )
{
ArtifactReference nodeFrom = toArtifactReference( fromKey );
ArtifactReference nodeTo = toArtifactReference( toKey );

return new DependencyGraphEdge( nodeFrom, nodeTo );
}

private ArtifactReference toArtifactReference( String key )
{
String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );
assertEquals( "ArtifactReference [" + key + "] parts should equal 5", 5, parts.length );

ArtifactReference artifact = new ArtifactReference();
artifact.setGroupId( parts[0] );
artifact.setArtifactId( parts[1] );
artifact.setVersion( parts[2] );
artifact.setClassifier( parts[3] );
artifact.setType( parts[4] );

return artifact;
}
}

+ 98
- 0
archiva-base/archiva-dependency-graph/src/test/java/org/apache/maven/archiva/dependency/graph/walk/WalkCollector.java View File

@@ -0,0 +1,98 @@
/**
*
*/
package org.apache.maven.archiva.dependency.graph.walk;

import org.apache.maven.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.walk.DependencyGraphVisitor;
import org.apache.maven.archiva.model.ArtifactReference;

import java.util.ArrayList;
import java.util.List;

class WalkCollector
implements DependencyGraphVisitor
{
private List walkPath = new ArrayList();

private int countDiscoverGraph = 0;

private int countFinishGraph = 0;

private int countDiscoverNode = 0;

private int countFinishNode = 0;

private int countDiscoverEdge = 0;

private int countFinishEdge = 0;

public void discoverEdge( DependencyGraphEdge edge )
{
countDiscoverEdge++;
}

public void discoverGraph( DependencyGraph graph )
{
countDiscoverGraph++;
}

public void discoverNode( DependencyGraphNode node )
{
countDiscoverNode++;
walkPath.add( ArtifactReference.toKey( node.getArtifact() ) );
}

public void finishEdge( DependencyGraphEdge edge )
{
countFinishEdge++;
}

public void finishGraph( DependencyGraph graph )
{
countFinishGraph++;
}

public void finishNode( DependencyGraphNode node )
{
countFinishNode++;
}

public List getCollectedPath()
{
return walkPath;
}

public int getCountDiscoverEdge()
{
return countDiscoverEdge;
}

public int getCountDiscoverGraph()
{
return countDiscoverGraph;
}

public int getCountDiscoverNode()
{
return countDiscoverNode;
}

public int getCountFinishEdge()
{
return countFinishEdge;
}

public int getCountFinishGraph()
{
return countFinishGraph;
}

public int getCountFinishNode()
{
return countFinishNode;
}

}

+ 57
- 0
archiva-base/archiva-model/src/main/java/org/apache/maven/archiva/model/DependencyScope.java View File

@@ -19,6 +19,7 @@ package org.apache.maven.archiva.model;
* under the License.
*/

import org.apache.commons.collections.map.MultiValueMap;
import org.apache.commons.lang.StringUtils;

/**
@@ -39,8 +40,64 @@ public class DependencyScope

public static final String TEST = "test";

private static final MultiValueMap scopeMap;

static
{
// Store the map of scopes to what other scopes are 'within' that scope.
scopeMap = new MultiValueMap();

scopeMap.put( COMPILE, COMPILE );
scopeMap.put( COMPILE, RUNTIME );
scopeMap.put( COMPILE, PROVIDED );
scopeMap.put( COMPILE, SYSTEM );

scopeMap.put( TEST, COMPILE );
scopeMap.put( TEST, RUNTIME );
scopeMap.put( TEST, PROVIDED );
scopeMap.put( TEST, SYSTEM );
scopeMap.put( TEST, TEST );
scopeMap.put( RUNTIME, RUNTIME );
scopeMap.put( RUNTIME, PROVIDED );
scopeMap.put( RUNTIME, SYSTEM );
scopeMap.put( PROVIDED, RUNTIME );
scopeMap.put( PROVIDED, PROVIDED );
scopeMap.put( PROVIDED, SYSTEM );
scopeMap.put( SYSTEM, SYSTEM );
}

public static boolean isSystemScoped( Dependency dep )
{
return StringUtils.equals( SYSTEM, dep.getScope() );
}

/**
* Test the provided scope against the desired scope to see if it is
* within that scope's pervue.
*
* Examples:
* actual:compile, desired:test = true
* actual:compile, desired:compile = true
* actual:test, desired:compile = false
* actual:provided, desired:compile = false
*
* @param actualScope
* @param desiredScope
* @return
*/
public static boolean isWithinScope( String actualScope, String desiredScope )
{
if ( StringUtils.isBlank( desiredScope ) )
{
// nothing desired? everything should fail.
return false;
}

String scope = StringUtils.defaultIfEmpty( actualScope, COMPILE );

return scopeMap.containsValue( desiredScope, scope );
}
}

+ 119
- 3
archiva-base/archiva-model/src/main/mdo/archiva-base.xml View File

@@ -979,6 +979,104 @@
}
]]></code>
</codeSegment>
<codeSegment>
<version>1.0.0+</version>
<code><![CDATA[
public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + ( ( groupId == null ) ? 0 : groupId.hashCode() );
result = PRIME * result + ( ( artifactId == null ) ? 0 : artifactId.hashCode() );
result = PRIME * result + ( ( version == null ) ? 0 : version.hashCode() );
result = PRIME * result + ( ( classifier == null ) ? 0 : classifier.hashCode() );
result = PRIME * result + ( ( type == null ) ? 0 : type.hashCode() );
return result;
}

public boolean equals( Object obj )
{
if ( this == obj )
{
return true;
}
if ( obj == null )
{
return false;
}
if ( getClass() != obj.getClass() )
{
return false;
}

final ArtifactReference other = (ArtifactReference) obj;

if ( groupId == null )
{
if ( other.groupId != null )
{
return false;
}
}
else if ( !groupId.equals( other.groupId ) )
{
return false;
}

if ( artifactId == null )
{
if ( other.artifactId != null )
{
return false;
}
}
else if ( !artifactId.equals( other.artifactId ) )
{
return false;
}

if ( version == null )
{
if ( other.version != null )
{
return false;
}
}
else if ( !version.equals( other.version ) )
{
return false;
}

if ( classifier == null )
{
if ( other.classifier != null )
{
return false;
}
}
else if ( !classifier.equals( other.classifier ) )
{
return false;
}
if ( type == null )
{
if ( other.type != null )
{
return false;
}
}
else if ( !type.equals( other.type ) )
{
return false;
}
return true;
}
]]></code>
</codeSegment>
</codeSegments>
</class>

@@ -1269,6 +1367,16 @@
<multiplicity>*</multiplicity>
</association>
</field>
<field>
<name>relocation</name>
<version>1.0.0+</version>
<description>If relocated, this is the new location reference</description>
<association stash.part="true"
jpox.join="false">
<type>VersionedReference</type>
<multiplicity>1</multiplicity>
</association>
</field>
</fields>
<codeSegments>
<codeSegment>
@@ -1678,10 +1786,18 @@
<field>
<name>transitive</name>
<version>1.0.0+</version>
<required>true</required>
<description>True if the dependency node is only here due a transitive lookup</description>
<required>false</required>
<description>True if the dependency is only here due a transitive resolution</description>
<type>boolean</type>
<defaultValue>false</defaultValue>
<!-- <defaultValue>false</defaultValue> -->
</field>
<field>
<name>fromParent</name>
<version>1.0.0+</version>
<required>false</required>
<description>True if the dependency is only here due a parent pom</description>
<type>boolean</type>
<!-- <defaultValue>false</defaultValue> -->
</field>
<field stash.maxsize="256">
<name>url</name>

+ 73
- 0
archiva-base/archiva-model/src/test/java/org/apache/maven/archiva/model/DependencyScopeTest.java View File

@@ -0,0 +1,73 @@
package org.apache.maven.archiva.model;

/*
* 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 junit.framework.TestCase;

/**
* DependencyScopeTest
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyScopeTest
extends TestCase
{
public void testIsWithinScope()
{
// Test on blank / empty desired scopes.
assertFalse( DependencyScope.isWithinScope( "compile", null ) );
assertFalse( DependencyScope.isWithinScope( "test", null ) );
assertFalse( DependencyScope.isWithinScope( "runtime", null ) );
assertFalse( DependencyScope.isWithinScope( "provided", null ) );
assertFalse( DependencyScope.isWithinScope( "compile", "" ) );
assertFalse( DependencyScope.isWithinScope( "test", "" ) );
assertFalse( DependencyScope.isWithinScope( "runtime", "" ) );
assertFalse( DependencyScope.isWithinScope( "provided", "" ) );

// Tests on blank / empty actual scopes.
assertTrue( DependencyScope.isWithinScope( "", DependencyScope.COMPILE ) );
assertTrue( DependencyScope.isWithinScope( null, DependencyScope.COMPILE ) );
assertTrue( DependencyScope.isWithinScope( "", DependencyScope.TEST ) );
assertTrue( DependencyScope.isWithinScope( null, DependencyScope.TEST ) );
assertFalse( DependencyScope.isWithinScope( "", DependencyScope.PROVIDED ) );
assertFalse( DependencyScope.isWithinScope( null, DependencyScope.PROVIDED ) );
assertFalse( DependencyScope.isWithinScope( "", DependencyScope.RUNTIME ) );
assertFalse( DependencyScope.isWithinScope( null, DependencyScope.RUNTIME ) );

// Tests on compile desired scopes.
assertTrue( DependencyScope.isWithinScope( "compile", DependencyScope.COMPILE ) );
assertFalse( DependencyScope.isWithinScope( "test", DependencyScope.COMPILE ) );

// Tests on test desired scopes.
assertTrue( DependencyScope.isWithinScope( "compile", DependencyScope.TEST ) );
assertTrue( DependencyScope.isWithinScope( "test", DependencyScope.TEST ) );

// Tests on oddball scopes.
assertFalse( DependencyScope.isWithinScope( "compile", DependencyScope.PROVIDED ) );
assertFalse( DependencyScope.isWithinScope( "test", DependencyScope.PROVIDED ) );
assertTrue( DependencyScope.isWithinScope( "provided", DependencyScope.PROVIDED ) );

assertFalse( DependencyScope.isWithinScope( "compile", DependencyScope.RUNTIME ) );
assertFalse( DependencyScope.isWithinScope( "test", DependencyScope.RUNTIME ) );
assertTrue( DependencyScope.isWithinScope( "provided", DependencyScope.RUNTIME ) );
assertTrue( DependencyScope.isWithinScope( "runtime", DependencyScope.RUNTIME ) );
}
}

+ 5
- 0
archiva-base/archiva-repository-layer/pom.xml View File

@@ -32,6 +32,11 @@
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-configuration</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-dependency-graph</artifactId>
<version>1.0-alpha-2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-consumer-api</artifactId>

+ 47
- 14
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/ProjectModelMerge.java View File

@@ -36,15 +36,19 @@ import org.apache.maven.archiva.model.Scm;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;

/**
* ProjectModelMerge
*
* TODO: Should call this ProjectModelAncestry as it deals with the current project and its parent.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
@@ -75,6 +79,7 @@ public class ProjectModelMerge
// Unmerged.
merged.setArtifactId( mainProject.getArtifactId() );
merged.setPackaging( StringUtils.defaultIfEmpty( mainProject.getPackaging(), "jar" ) );
merged.setRelocation( mainProject.getRelocation() );

// Merged
merged.setGroupId( merge( mainProject.getGroupId(), parentProject.getGroupId() ) );
@@ -98,7 +103,7 @@ public class ProjectModelMerge
merged.setPlugins( mergePlugins( mainProject.getPlugins(), parentProject.getPlugins() ) );
merged.setReports( mergeReports( mainProject.getReports(), parentProject.getReports() ) );
merged.setProperties( merge( mainProject.getProperties(), parentProject.getProperties() ) );
return merged;
}

@@ -245,11 +250,15 @@ public class ProjectModelMerge

if ( mainDep == null )
{
return ArchivaModelCloner.clone( parentDep );
Dependency dep = ArchivaModelCloner.clone( parentDep );
dep.setFromParent( true );
return dep;
}

Dependency merged = new Dependency();

merged.setFromParent( true );

// Unmerged.
merged.setGroupId( mainDep.getGroupId() );
merged.setArtifactId( mainDep.getArtifactId() );
@@ -415,28 +424,40 @@ public class ProjectModelMerge

if ( mainDependencies == null )
{
return ArchivaModelCloner.cloneDependencies( parentDependencies );
List merged = ArchivaModelCloner.cloneDependencies( parentDependencies );
Iterator it = merged.iterator();
while ( it.hasNext() )
{
Dependency dep = (Dependency) it.next();
dep.setFromParent( true );
}
return merged;
}

List merged = ArchivaModelCloner.cloneDependencies( mainDependencies );
List merged = new ArrayList();

Map mainDepMap = createDependencyMap( mainDependencies );
Map parentDepMap = createDependencyMap( parentDependencies );
Set uniqueKeys = new HashSet();
uniqueKeys.addAll( mainDepMap.keySet() );
uniqueKeys.addAll( parentDepMap.keySet() );

Iterator it = parentDepMap.entrySet().iterator();
Iterator it = uniqueKeys.iterator();
while ( it.hasNext() )
{
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
Dependency parentDep = (Dependency) entry.getValue();
String key = (String) it.next();
Dependency parentDep = (Dependency) parentDepMap.get( key );
Dependency mainDep = (Dependency) mainDepMap.get( key );

if ( parentDep == null )
{
// Means there is no parent dep to override main dep.
merged.add( mainDep );
}
else
{
// Parent dep exists (main doesn't have to).
// Merge the parent over the main dep.
merged.add( merge( mainDep, parentDep ) );
}
}
@@ -453,28 +474,40 @@ public class ProjectModelMerge

if ( mainDepMgmt == null )
{
return ArchivaModelCloner.cloneDependencies( parentDepMgmt );
List merged = ArchivaModelCloner.cloneDependencies( parentDepMgmt );
Iterator it = merged.iterator();
while ( it.hasNext() )
{
Dependency dep = (Dependency) it.next();
dep.setFromParent( true );
}
return merged;
}

List merged = ArchivaModelCloner.cloneDependencies( mainDepMgmt );
List merged = new ArrayList();

Map mainDepMap = createDependencyMap( mainDepMgmt );
Map parentDepMap = createDependencyMap( parentDepMgmt );
Set uniqueKeys = new HashSet();
uniqueKeys.addAll( mainDepMap.keySet() );
uniqueKeys.addAll( parentDepMap.keySet() );

Iterator it = parentDepMap.entrySet().iterator();
Iterator it = uniqueKeys.iterator();
while ( it.hasNext() )
{
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
Dependency parentDep = (Dependency) entry.getValue();
String key = (String) it.next();
Dependency parentDep = (Dependency) parentDepMap.get( key );
Dependency mainDep = (Dependency) mainDepMap.get( key );

if ( parentDep == null )
{
// Means there is no parent depMan entry to override main depMan.
merged.add( mainDep );
}
else
{
// Parent depMan entry exists (main doesn't have to).
// Merge the parent over the main depMan entry.
merged.add( merge( mainDep, parentDep ) );
}
}

+ 116
- 0
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/dependencies/ProjectModelBasedGraphBuilder.java View File

@@ -0,0 +1,116 @@
package org.apache.maven.archiva.repository.project.dependencies;

/*
* 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.archiva.dependency.graph.DependencyGraph;
import org.apache.maven.archiva.dependency.graph.DependencyGraphBuilder;
import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
import org.apache.maven.archiva.dependency.graph.DependencyGraphUtils;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.filters.EffectiveProjectModelFilter;
import org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolverStack;

/**
* ProjectModelBasedGraphBuilder
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProjectModelBasedGraphBuilder
implements DependencyGraphBuilder
{
private ProjectModelResolverStack modelResolver;

private EffectiveProjectModelFilter effectiveFilter = new EffectiveProjectModelFilter();

public DependencyGraph createGraph( VersionedReference versionedProjectReference )
{
String groupId = versionedProjectReference.getGroupId();
String artifactId = versionedProjectReference.getArtifactId();
String version = versionedProjectReference.getVersion();

DependencyGraph graph = new DependencyGraph( groupId, artifactId, version );
return graph;
}

public void resolveNode( DependencyGraph graph, DependencyGraphNode fromNode,
VersionedReference versionedProjectReference )
{
ArchivaProjectModel model = resolveModel( fromNode.getArtifact() );
DependencyGraphUtils.addNodeFromModel( model, graph, fromNode );
}

private ArchivaProjectModel resolveModel( ArtifactReference reference )
{
VersionedReference projectRef = new VersionedReference();

projectRef.setGroupId( reference.getGroupId() );
projectRef.setArtifactId( reference.getArtifactId() );
projectRef.setVersion( reference.getVersion() );

ArchivaProjectModel model = modelResolver.findProject( projectRef );

if ( model == null )
{
return createDefaultModel( reference );
}

try
{
effectiveFilter.setProjectModelResolverStack( modelResolver );

ArchivaProjectModel processedModel = effectiveFilter.filter( model );

return processedModel;
}
catch ( ProjectModelException e )
{
e.printStackTrace( System.err );
return createDefaultModel( reference );
}
}

private ArchivaProjectModel createDefaultModel( ArtifactReference reference )
{
ArchivaProjectModel model = new ArchivaProjectModel();

// Create default (dummy) model
model = new ArchivaProjectModel();
model.setGroupId( reference.getGroupId() );
model.setArtifactId( reference.getArtifactId() );
model.setVersion( reference.getVersion() );
model.setPackaging( reference.getType() );
return model;
}

public ProjectModelResolverStack getModelResolver()
{
return modelResolver;
}

public void setModelResolver( ProjectModelResolverStack modelResolver )
{
this.modelResolver = modelResolver;
}
}

+ 29
- 62
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/filters/EffectiveProjectModelFilter.java View File

@@ -19,6 +19,7 @@ package org.apache.maven.archiva.repository.project.filters;
* under the License.
*/

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.model.ArchivaModelCloner;
import org.apache.maven.archiva.model.ArchivaProjectModel;
@@ -27,10 +28,11 @@ import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelFilter;
import org.apache.maven.archiva.repository.project.ProjectModelMerge;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;
import org.apache.maven.archiva.repository.project.resolvers.ProjectModelResolverStack;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -48,26 +50,23 @@ public class EffectiveProjectModelFilter
extends AbstractLogEnabled
implements ProjectModelFilter
{
/**
* @plexus.requirement role-hint="expression"
*/
private ProjectModelFilter expressionFilter;
private ProjectModelFilter expressionFilter = new ProjectModelExpressionFilter();

private List projectModelResolvers;
private ProjectModelResolverStack projectModelResolverStack;

public EffectiveProjectModelFilter()
{
projectModelResolvers = new ArrayList();
projectModelResolverStack = new ProjectModelResolverStack();
}

public void addProjectModelResolver( ProjectModelResolver resolver )
public void setProjectModelResolverStack( ProjectModelResolverStack resolverStack )
{
if ( resolver == null )
{
return;
}
this.projectModelResolverStack = resolverStack;
}

this.projectModelResolvers.add( resolver );
public ProjectModelResolverStack getProjectModelResolverStack()
{
return this.projectModelResolverStack;
}

/**
@@ -90,7 +89,7 @@ public class EffectiveProjectModelFilter
return null;
}

if ( this.projectModelResolvers.isEmpty() )
if ( this.projectModelResolverStack.isEmpty() )
{
throw new IllegalStateException( "Unable to build effective pom with no project model resolvers defined." );
}
@@ -113,25 +112,26 @@ public class EffectiveProjectModelFilter
return effectiveProject;
}

public void removeResolver( ProjectModelResolver resolver )
{
this.projectModelResolvers.remove( resolver );
}
private Logger logger;

public void clearResolvers()
protected Logger getLogger()
{
this.projectModelResolvers.clear();
if ( logger == null )
{
logger = super.getLogger();
if ( logger == null )
{
logger = new ConsoleLogger( ConsoleLogger.LEVEL_INFO, this.getClass().getName() );
}
}

return logger;
}

private void applyDependencyManagement( ArchivaProjectModel pom )
{
if ( ( pom.getDependencyManagement() == null ) || ( pom.getDependencies() == null ) )
{
// Nothing to do. All done!
return;
}

if ( pom.getDependencyManagement().isEmpty() || pom.getDependencies().isEmpty() )
if ( CollectionUtils.isEmpty( pom.getDependencyManagement() )
|| CollectionUtils.isEmpty( pom.getDependencies() ) )
{
// Nothing to do. All done!
return;
@@ -156,39 +156,6 @@ public class EffectiveProjectModelFilter
}
}

private ArchivaProjectModel findProject( VersionedReference projectRef )
{
getLogger().debug( "Trying to find project: " + projectRef );
Iterator it = this.projectModelResolvers.iterator();

while ( it.hasNext() )
{
ProjectModelResolver resolver = (ProjectModelResolver) it.next();

try
{
getLogger().debug( "Trying to find in " + resolver.getClass().getName() );
ArchivaProjectModel model = resolver.resolveProjectModel( projectRef );

if ( model != null )
{
getLogger().debug( "Found it!: " + model );
return model;
}
getLogger().debug( "Not found." );
}
catch ( ProjectModelException e )
{
// TODO: trigger notifier of problem?
e.printStackTrace();
}
}

// TODO: Document that project was not found. (Use monitor?)

return null;
}

private ArchivaProjectModel mergeParent( ArchivaProjectModel pom )
throws ProjectModelException
{
@@ -204,7 +171,7 @@ public class EffectiveProjectModelFilter
getLogger().debug( "Has parent: " + parentRef );

// Find parent using resolvers.
ArchivaProjectModel parentProject = findProject( parentRef );
ArchivaProjectModel parentProject = this.projectModelResolverStack.findProject( parentRef );

if ( parentProject != null )
{

+ 15
- 7
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/filters/ProjectModelExpressionFilter.java View File

@@ -20,11 +20,13 @@ package org.apache.maven.archiva.repository.project.filters;
*/

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiva.model.ArchivaModelCloner;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.Dependency;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelFilter;
import org.codehaus.plexus.evaluator.DefaultExpressionEvaluator;
import org.codehaus.plexus.evaluator.EvaluatorException;
import org.codehaus.plexus.evaluator.ExpressionEvaluator;
import org.codehaus.plexus.evaluator.sources.PropertiesExpressionSource;
@@ -32,6 +34,7 @@ import org.codehaus.plexus.evaluator.sources.SystemPropertyExpressionSource;

import java.util.Iterator;
import java.util.List;
import java.util.Properties;

/**
* ProjectModelExpressionFilter
@@ -45,10 +48,7 @@ import java.util.List;
public class ProjectModelExpressionFilter
implements ProjectModelFilter
{
/**
* @plexus.requirement
*/
private ExpressionEvaluator evaluator;
private ExpressionEvaluator evaluator = new DefaultExpressionEvaluator();

/**
* Find and Evaluate the Expressions present in the model.
@@ -58,13 +58,21 @@ public class ProjectModelExpressionFilter
public ArchivaProjectModel filter( final ArchivaProjectModel model )
throws ProjectModelException
{
Properties props = new Properties();

if ( model.getProperties() != null )
{
PropertiesExpressionSource propsSource = new PropertiesExpressionSource();
propsSource.setProperties( model.getProperties() );
evaluator.addExpressionSource( propsSource );
props.putAll( model.getProperties() );
}

props.setProperty( "pom.artifactId", model.getArtifactId() );

props.setProperty( "pom.groupId", StringUtils.defaultString( model.getGroupId() ) );
props.setProperty( "pom.version", StringUtils.defaultString( model.getVersion() ) );

PropertiesExpressionSource propsSource = new PropertiesExpressionSource();
propsSource.setProperties( props );
evaluator.addExpressionSource( propsSource );
evaluator.addExpressionSource( new SystemPropertyExpressionSource() );

ArchivaProjectModel ret = ArchivaModelCloner.clone( model );

+ 15
- 0
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/readers/ProjectModel400Reader.java View File

@@ -107,6 +107,8 @@ public class ProjectModel400Reader

model.setBuildExtensions( getBuildExtensions( xml ) );

model.setRelocation( getRelocation( xml ) );

return model;
}
catch ( XMLException e )
@@ -453,6 +455,19 @@ public class ProjectModel400Reader
return ret;
}

private VersionedReference getRelocation( XMLReader xml )
throws XMLException
{
Element elemRelocation = xml.getElement( "//project/distributionManagement/relocation" );

if ( elemRelocation != null )
{
return getVersionedReference( elemRelocation );
}

return null;
}

private List getReports( XMLReader xml )
throws XMLException
{

+ 78
- 0
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/resolvers/ProjectModelResolutionListener.java View File

@@ -0,0 +1,78 @@
package org.apache.maven.archiva.repository.project.resolvers;

import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;

import java.util.List;

/**
* ProjectModelResolutionListener
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public interface ProjectModelResolutionListener
{
/**
* Indicates that the resolution process has started for a specific project.
*
* @param projectRef the project reference.
* @param resolverList the {@link List} of {@link ProjectModelResolver}'s that will be searched.
* @see #resolutionSuccess(VersionedReference, ProjectModelResolver, ArchivaProjectModel)
* @see #resolutionNotFound(VersionedReference, List)
*/
public void resolutionStart( VersionedReference projectRef, List resolverList );

/**
* Indicates that a resolution against a specific resolver is about
* to occur.
*
* @param projectRef the project reference.
* @param resolver the resolver to attempt resolution on.
*/
public void resolutionAttempting( VersionedReference projectRef, ProjectModelResolver resolver );
/**
* Indicates that a resolution against a specific resolver resulted
* in in a missed resolution.
*
* "Miss" in this case refers to an attempt against a resolver, and that
* resolver essentially responds with a "not found here" response.
*
* @param projectRef the project reference.
* @param resolver the resolver the attempt was made on.
*/
public void resolutionMiss( VersionedReference projectRef, ProjectModelResolver resolver );
/**
* Indicates that a resolution against the specific resolver has
* caused an error.
*
* @param projectRef the project reference.
* @param resolver the (optional) resolver on which the error occured.
* @param cause the cause of the error.
*/
public void resolutionError( VersionedReference projectRef, ProjectModelResolver resolver, Exception cause );
/**
* Indicates that a resolution process has finished, and the requested
* projectRef has been found.
*
* @param projectRef the project reference.
* @param resolver the resolver on which success occured.
* @param model the resolved model.
* @see #resolutionStart(VersionedReference, List)
*/
public void resolutionSuccess( VersionedReference projectRef, ProjectModelResolver resolver, ArchivaProjectModel model );
/**
* Indicates that the resolution process has finished, and the requested
* projectRef could not be found.
*
* @param projectRef the project reference.
* @param resolverList the {@link List} of {@link ProjectModelResolver}'s that was be searched.
* @see #resolutionStart(VersionedReference, List)
*/
public void resolutionNotFound( VersionedReference projectRef, List resolverList );
}

+ 244
- 0
archiva-base/archiva-repository-layer/src/main/java/org/apache/maven/archiva/repository/project/resolvers/ProjectModelResolverStack.java View File

@@ -0,0 +1,244 @@
package org.apache.maven.archiva.repository.project.resolvers;

/*
* 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.commons.collections.CollectionUtils;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelResolver;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* Represents a stack of {@link ProjectModelResolver} resolvers for
* finding/resolving an ArchivaProjectModel from multiple sources.
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ProjectModelResolverStack
{
private List resolvers;

private List listeners;

public ProjectModelResolverStack()
{
this.resolvers = new ArrayList();
this.listeners = new ArrayList();
}

public void addListener( ProjectModelResolutionListener listener )
{
if ( listener == null )
{
return;
}

this.listeners.add( listener );
}

public void addProjectModelResolver( ProjectModelResolver resolver )
{
if ( resolver == null )
{
return;
}

this.resolvers.add( resolver );
}

public void clearResolvers()
{
this.resolvers.clear();
}

public ArchivaProjectModel findProject( VersionedReference projectRef )
{
if ( CollectionUtils.isEmpty( this.resolvers ) )
{
throw new IllegalStateException( "No resolvers have been defined." );
}

triggerResolutionStart( projectRef, this.resolvers );

Iterator it = this.resolvers.iterator();

while ( it.hasNext() )
{
ProjectModelResolver resolver = (ProjectModelResolver) it.next();

try
{
triggerResolutionAttempting( projectRef, resolver );
ArchivaProjectModel model = resolver.resolveProjectModel( projectRef );

if ( model != null )
{
// Project was found.
triggerResolutionSuccess( projectRef, resolver, model );
return model;
}
triggerResolutionMiss( projectRef, resolver );
}
catch ( ProjectModelException e )
{
triggerResolutionError( projectRef, resolver, e );
}
}

// Project was not found in entire resolver list.
triggerResolutionNotFound( projectRef, this.resolvers );

return null;
}

public boolean isEmpty()
{
return this.resolvers.isEmpty();
}

public void removeListener( ProjectModelResolutionListener listener )
{
if ( listener == null )
{
return;
}

this.listeners.add( listener );
}

public void removeResolver( ProjectModelResolver resolver )
{
this.resolvers.remove( resolver );
}

private void triggerResolutionAttempting( VersionedReference projectRef, ProjectModelResolver resolver )
{
Iterator it = this.listeners.iterator();
while ( it.hasNext() )
{
ProjectModelResolutionListener listener = (ProjectModelResolutionListener) it.next();

try
{
listener.resolutionAttempting( projectRef, resolver );
}
catch ( Exception e )
{
// do nothing with exception.
}
}
}

private void triggerResolutionError( VersionedReference projectRef, ProjectModelResolver resolver, Exception cause )
{
Iterator it = this.listeners.iterator();
while ( it.hasNext() )
{
ProjectModelResolutionListener listener = (ProjectModelResolutionListener) it.next();

try
{
listener.resolutionError( projectRef, resolver, cause );
}
catch ( Exception e )
{
// do nothing with exception.
}
}
}

private void triggerResolutionMiss( VersionedReference projectRef, ProjectModelResolver resolver )
{
Iterator it = this.listeners.iterator();
while ( it.hasNext() )
{
ProjectModelResolutionListener listener = (ProjectModelResolutionListener) it.next();

try
{
listener.resolutionMiss( projectRef, resolver );
}
catch ( Exception e )
{
// do nothing with exception.
}
}
}

private void triggerResolutionNotFound( VersionedReference projectRef, List resolvers )
{
Iterator it = this.listeners.iterator();
while ( it.hasNext() )
{
ProjectModelResolutionListener listener = (ProjectModelResolutionListener) it.next();

try
{
listener.resolutionNotFound( projectRef, resolvers );
}
catch ( Exception e )
{
// do nothing with exception.
}
}
}

private void triggerResolutionStart( VersionedReference projectRef, List resolvers )
{
Iterator it = this.listeners.iterator();
while ( it.hasNext() )
{
ProjectModelResolutionListener listener = (ProjectModelResolutionListener) it.next();

try
{
listener.resolutionStart( projectRef, resolvers );
}
catch ( Exception e )
{
// do nothing with exception.
}
}
}

private void triggerResolutionSuccess( VersionedReference projectRef, ProjectModelResolver resolver,
ArchivaProjectModel model )
{
Iterator it = this.listeners.iterator();
while ( it.hasNext() )
{
ProjectModelResolutionListener listener = (ProjectModelResolutionListener) it.next();

try
{
listener.resolutionSuccess( projectRef, resolver, model );
}
catch ( Exception e )
{
// do nothing with exception.
}
}
}
}

+ 1
- 1
archiva-base/archiva-repository-layer/src/test/java/org/apache/maven/archiva/repository/project/filters/EffectiveProjectModelFilterTest.java View File

@@ -85,7 +85,7 @@ public class EffectiveProjectModelFilterTest
{
EffectiveProjectModelFilter filter = lookupEffective();

filter.addProjectModelResolver( createDefaultRepositoryResolver() );
filter.getProjectModelResolverStack().addProjectModelResolver( createDefaultRepositoryResolver() );

ArchivaProjectModel startModel = createArchivaProjectModel( DEFAULT_REPOSITORY
+ "/org/apache/maven/archiva/archiva-model/1.0-SNAPSHOT/archiva-model-1.0-SNAPSHOT.pom" );

+ 1
- 0
archiva-base/pom.xml View File

@@ -35,6 +35,7 @@
<module>archiva-consumers</module>
<module>archiva-indexer</module>
<module>archiva-model</module>
<module>archiva-dependency-graph</module>
<module>archiva-repository-layer</module>
<module>archiva-xml-tools</module>
<module>archiva-proxy</module>

+ 96
- 0
tools/maven-archivadev-plugin/pom.xml View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<prerequisites>
<maven>2.0.4</maven>
</prerequisites>

<groupId>org.apache.maven.archiva.tools</groupId>
<artifactId>maven-archivadev-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.0-SNAPSHOT</version>

<name>Archiva Dev Maven Plugin</name>

<inceptionYear>2007</inceptionYear>

<developers>
<developer>
<id>joakime</id>
<name>Joakim Erdfelt</name>
<email>joakime@apache.org</email>
<roles>
<role>Developer</role>
</roles>
<timezone>-5</timezone>
</developer>
</developers>

<dependencies>
<!-- maven plugin deps -->
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-common</artifactId>
<version>1.0-alpha-1</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-api</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-impl</artifactId>
<version>${maven.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-dependency-tree</artifactId>
<version>1.0-alpha-2</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>1.2</version>
</dependency>
<!-- testing deps -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<version>1.0-beta-1</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<maven.version>2.0.4</maven.version>
</properties>
</project>

+ 133
- 0
tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/CreateArchivaDependencyResolutionTestCaseMojo.java View File

@@ -0,0 +1,133 @@
package org.apache.maven.archiva.plugins.dev;

/*
* 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.archiva.plugins.dev.testgen.DependencyGraphTestCreator;
import org.apache.maven.archiva.plugins.dev.testgen.MemoryRepositoryCreator;
import org.apache.maven.archiva.plugins.dev.utils.VariableNames;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactCollector;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;

import java.io.File;

/**
* CreateArchivaDependencyResolutionTestCaseMojo
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*
* @goal generate-dependency-tests
*/
public class CreateArchivaDependencyResolutionTestCaseMojo
extends AbstractMojo
{
/**
* The project of the current build.
*
* @parameter default-value="${project}"
* @required
* @readonly
*/
private MavenProject project;

/**
* The artifact respository to use.
*
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
private ArtifactRepository localRepository;
/**
* The destination directory to generate the test files.
*
* @parameter expression="${archivadev.outputdir}" default-value="${project.build.directory}"
* @required
*/
private File destDir;

/**
* The artifact factory to use.
*
* @component
*/
private ArtifactFactory artifactFactory;
/**
* @component
*/
private DependencyTreeBuilder dependencyTreeBuilder;
/**
* @component
*/
protected ArtifactMetadataSource artifactMetadataSource;

/**
* @component
*/
private ArtifactCollector collector;

public void execute()
throws MojoExecutionException, MojoFailureException
{
String classPrefix = VariableNames.toClassName( project.getArtifactId() );
getLog().info( "Generating into " + destDir );
createMemoryRepository( classPrefix );
createDependencyGraphTest( classPrefix );
}
private void createDependencyGraphTest( String classPrefix ) throws MojoExecutionException
{
DependencyGraphTestCreator creator = new DependencyGraphTestCreator();
creator.setLog( getLog() );
creator.setOutputDir( destDir );
creator.setProject( project );
creator.setArtifactFactory( artifactFactory );
creator.setLocalRepository( localRepository );
creator.setDependencyTreeBuilder( dependencyTreeBuilder );
creator.setArtifactMetadataSource( artifactMetadataSource );
creator.setCollector( collector );
creator.create( classPrefix );
}

private void createMemoryRepository( String classPrefix ) throws MojoExecutionException
{
MemoryRepositoryCreator creator = new MemoryRepositoryCreator();
creator.setLog( getLog() );
creator.setOutputDir( destDir );
creator.setProject( project );
creator.setArtifactFactory( artifactFactory );
creator.setLocalRepository( localRepository );
creator.create( classPrefix );
}
}

+ 63
- 0
tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/functors/ArtifactComparator.java View File

@@ -0,0 +1,63 @@
package org.apache.maven.archiva.plugins.dev.functors;

/*
* 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 java.util.Comparator;

/**
* ArtifactComparator
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class ArtifactComparator
implements Comparator
{

public int compare( Object arg0, Object arg1 )
{
if( arg0 == null || arg1 == null )
{
return -1;
}
Artifact artifact1 = (Artifact) arg0;
Artifact artifact2 = (Artifact) arg1;
int diff;
diff = artifact1.getGroupId().compareTo( artifact2.getGroupId() );
if( diff != 0 )
{
return diff;
}
diff = artifact1.getArtifactId().compareTo( artifact2.getArtifactId() );
if( diff != 0 )
{
return diff;
}
return artifact1.getVersion().compareTo( artifact2.getVersion() );
}

}

+ 44
- 0
tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/functors/DependencyNodeToArtifactTransformer.java View File

@@ -0,0 +1,44 @@
package org.apache.maven.archiva.plugins.dev.functors;

/*
* 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.commons.collections.Transformer;
import org.apache.maven.shared.dependency.tree.DependencyNode;

/**
* DependencyNodeToArtifactTransformer
*
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
public class DependencyNodeToArtifactTransformer
implements Transformer
{
public Object transform( Object input )
{
if( input instanceof DependencyNode )
{
DependencyNode node = (DependencyNode) input;
return node.getArtifact();
}
return input;
}
}

+ 0
- 0
tools/maven-archivadev-plugin/src/main/java/org/apache/maven/archiva/plugins/dev/functors/MatchingDependencyPredicate.java View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save