You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jv...@apache.org on 2008/05/25 05:07:03 UTC

svn commit: r659899 [2/2] - in /maven/sandbox/trunk/mercury: ./ src/main/java/org/apache/maven/mercury/representation/ src/main/java/org/apache/maven/mercury/representation/conflict/ src/main/java/org/apache/maven/mercury/representation/transform/ src/...

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolutionPolicy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolutionPolicy.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolver.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolver.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolver.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolver.java Sat May 24 20:07:02 2008
@@ -0,0 +1,243 @@
+package org.apache.maven.mercury.representation.conflict;
+
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
+
+import org.apache.maven.mercury.ArtifactScopeEnum;
+import org.apache.maven.mercury.representation.ArtifactMetadata;
+import org.apache.maven.mercury.representation.MetadataGraph;
+import org.apache.maven.mercury.representation.MetadataGraphEdge;
+import org.apache.maven.mercury.representation.MetadataGraphVertex;
+import org.apache.maven.mercury.representation.MetadataResolutionException;
+
+/*
+ * Default conflict resolver.Implements closer newer first policy by default, but could be
+ * configured via plexus
+ * 
+ * @plexus.component
+ * 
+ * @author <a href="mailto:oleg@codehaus.org">Oleg Gusakov</a>
+ * 
+ * @version $Id$
+ */
+
+public class DefaultConflictResolver
+    implements ConflictResolver
+{
+    /**
+     * artifact, closer to the entry point, is selected
+     * 
+     * @plexus.requirement role="org.apache.maven.artifact.resolver.conflict.GraphConflictResolutionPolicy"
+     */
+    protected ConflictResolutionPolicy policy;
+
+    public MetadataGraph resolveConflicts( MetadataGraph graph, ArtifactScopeEnum scope )
+        throws ConflictResolutionException
+    {
+        if ( policy == null )
+        {
+            throw new ConflictResolutionException( "no GraphConflictResolutionPolicy injected" );
+        }
+
+        if ( graph == null )
+        {
+            return null;
+        }
+
+        MetadataGraphVertex entry = graph.getEntry();
+        if ( entry == null )
+        {
+            return null;
+        }
+
+        if ( graph.isEmpty() )
+        {
+            throw new ConflictResolutionException( "graph with an entry, but not vertices do not exist" );
+        }
+
+        if ( graph.isEmptyEdges() )
+        {
+            return null; // no edges - nothing to worry about
+        }
+
+        final TreeSet<MetadataGraphVertex> vertices = graph.getVertices();
+
+        try
+        {
+            // edge case - single vertex graph
+            if ( vertices.size() == 1 )
+            {
+                return new MetadataGraph( entry );
+            }
+
+            final ArtifactScopeEnum requestedScope = ArtifactScopeEnum.checkScope( scope );
+
+            MetadataGraph res = new MetadataGraph( vertices.size() );
+            res.setVersionedVertices( false );
+            res.setScopedVertices( false );
+
+            MetadataGraphVertex resEntry = res.addVertex( entry.getMd() );
+            res.setEntry( resEntry );
+
+            res.setScope( requestedScope );
+
+            for ( MetadataGraphVertex v : vertices )
+            {
+                final List<MetadataGraphEdge> ins = graph.getIncidentEdges( v );
+                final MetadataGraphEdge edge = cleanEdges( v, ins, requestedScope );
+
+                if ( edge == null )
+                { // no edges - don't need this vertex any more
+                    if ( entry.equals( v ) )
+                    { // unless it's an entry point. 
+                        // currently processing the entry point - it should not have any entry incident edges
+                        res.getEntry().getMd().setWhy( "This is a graph entry point. No links." );
+                    }
+                    else
+                    {
+                        //System.out.println("--->"+v.getMd().toDomainString()
+                        //+" has been terminated on this entry set\n-------------------\n"
+                        //+ins 
+                        //+"\n-------------------\n"
+                        //);
+                    }
+                }
+                else
+                {
+                    //System.out.println("+++>"+v.getMd().toDomainString()+" still has "+edge.toString() );
+                    // fill in domain md with actual version data
+                    ArtifactMetadata md = v.getMd();
+                    ArtifactMetadata newMd = new ArtifactMetadata( md.getGroupId(), md.getArtifactId(), edge.getVersion(), md.getType(), md.getScopeAsEnum(), md.getClassifier(),
+                                                                   edge.getArtifactUri(), edge.getSource() == null ? "" : edge.getSource().getMd().toString(), edge.isResolved(),
+                                                                   edge.getTarget() == null ? null : edge.getTarget().getMd().getError() );
+                    MetadataGraphVertex newV = res.addVertex( newMd );
+                    MetadataGraphVertex sourceV = res.addVertex( edge.getSource().getMd() );
+
+                    res.addEdge( sourceV, newV, edge );
+                }
+            }
+            MetadataGraph linkedRes = findLinkedSubgraph( res );
+            //System.err.println("Original graph("+graph.getVertices().size()+"):\n"+graph.toString());
+            //System.err.println("Cleaned("+requestedScope+") graph("+res.getVertices().size()+"):\n"+res.toString());
+            //System.err.println("Linked("+requestedScope+") subgraph("+linkedRes.getVertices().size()+"):\n"+linkedRes.toString());
+            return linkedRes;
+        }
+        catch ( MetadataResolutionException e )
+        {
+            throw new ConflictResolutionException( e );
+        }
+    }
+
+    private final MetadataGraph findLinkedSubgraph( MetadataGraph g )
+    {
+        if ( g.getVertices().size() == 1 )
+        {
+            return g;
+        }
+
+        List<MetadataGraphVertex> visited = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
+        visit( g.getEntry(), visited, g );
+
+        List<MetadataGraphVertex> dropList = new ArrayList<MetadataGraphVertex>( g.getVertices().size() );
+
+        // collect drop list
+        for ( MetadataGraphVertex v : g.getVertices() )
+        {
+            if ( !visited.contains( v ) )
+            {
+                dropList.add( v );
+            }
+        }
+
+        if ( dropList.size() < 1 )
+        {
+            return g;
+        }
+
+        // now - drop vertices
+        TreeSet<MetadataGraphVertex> vertices = g.getVertices();
+        for ( MetadataGraphVertex v : dropList )
+        {
+            vertices.remove( v );
+        }
+
+        return g;
+    }
+
+    private final void visit( MetadataGraphVertex from, List<MetadataGraphVertex> visited, MetadataGraph graph )
+    {
+        if ( visited.contains( from ) )
+        {
+            return;
+        }
+
+        visited.add( from );
+
+        List<MetadataGraphEdge> exitList = graph.getExcidentEdges( from );
+        //String s = "|---> "+from.getMd().toString()+" - "+(exitList == null ? -1 : exitList.size()) + " exit links";
+        if ( exitList != null && exitList.size() > 0 )
+        {
+            for ( MetadataGraphEdge e : graph.getExcidentEdges( from ) )
+            {
+                visit( e.getTarget(), visited, graph );
+            }
+        }
+    }
+
+    private final MetadataGraphEdge cleanEdges( MetadataGraphVertex v, List<MetadataGraphEdge> edges, ArtifactScopeEnum scope )
+    {
+        if ( edges == null || edges.isEmpty() )
+        {
+            return null;
+        }
+
+        if ( edges.size() == 1 )
+        {
+            MetadataGraphEdge e = edges.get( 0 );
+
+            if ( scope.encloses( e.getScope() ) )
+            {
+                return e;
+            }
+
+            return null;
+        }
+
+        MetadataGraphEdge res = null;
+
+        for ( MetadataGraphEdge e : edges )
+        {
+            if ( !scope.encloses( e.getScope() ) )
+            {
+                continue;
+            }
+
+            if ( res == null )
+            {
+                res = e;
+            }
+            else
+            {
+                res = policy.apply( e, res );
+            }
+        }
+
+        return res;
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/conflict/DefaultConflictResolver.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathContainer.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathContainer.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathContainer.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathContainer.java Sat May 24 20:07:02 2008
@@ -0,0 +1,124 @@
+package org.apache.maven.mercury.representation.transform;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.maven.mercury.ArtifactScopeEnum;
+import org.apache.maven.mercury.representation.ArtifactMetadata;
+import org.apache.maven.mercury.representation.MetadataResolutionException;
+import org.apache.maven.mercury.representation.MetadataTreeNode;
+
+/*
+ * classpath container that is aware of the classpath scope
+ * 
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public class ClasspathContainer
+    implements Iterable<ArtifactMetadata>
+{
+    private List<ArtifactMetadata> classpath;
+
+    private ArtifactScopeEnum scope;
+
+    //-------------------------------------------------------------------------------------------
+    public ClasspathContainer( ArtifactScopeEnum scope )
+    {
+        this.scope = ArtifactScopeEnum.checkScope( scope );
+    }
+
+    //-------------------------------------------------------------------------------------------
+    public ClasspathContainer( List<ArtifactMetadata> classpath, ArtifactScopeEnum scope )
+    {
+        this( scope );
+        this.classpath = classpath;
+    }
+
+    //-------------------------------------------------------------------------------------------
+    public Iterator<ArtifactMetadata> iterator()
+    {
+        return classpath == null ? null : classpath.iterator();
+    }
+
+    //-------------------------------------------------------------------------------------------
+    public ClasspathContainer add( ArtifactMetadata md )
+    {
+        if ( classpath == null )
+        {
+            classpath = new ArrayList<ArtifactMetadata>( 16 );
+        }
+
+        classpath.add( md );
+
+        return this;
+    }
+
+    //-------------------------------------------------------------------------------------------
+    public List<ArtifactMetadata> getClasspath()
+    {
+        return classpath;
+    }
+
+    //-------------------------------------------------------------------------------------------
+    public MetadataTreeNode getClasspathAsTree()
+        throws MetadataResolutionException
+    {
+        if ( classpath == null || classpath.size() < 1 )
+            return null;
+
+        MetadataTreeNode tree = null;
+        MetadataTreeNode parent = null;
+        MetadataTreeNode node = null;
+
+        for ( ArtifactMetadata md : classpath )
+        {
+            node = new MetadataTreeNode( md, parent, md.isResolved(), md.getArtifactScope() );
+            if ( tree == null )
+            {
+                tree = node;
+            }
+
+            if ( parent != null )
+            {
+                parent.setNChildren( 1 );
+                parent.addChild( 0, node );
+            }
+
+            parent = node;
+
+        }
+        return tree;
+    }
+
+    public void setClasspath( List<ArtifactMetadata> classpath )
+    {
+        this.classpath = classpath;
+    }
+
+    public ArtifactScopeEnum getScope()
+    {
+        return scope;
+    }
+
+    public void setScope( ArtifactScopeEnum scope )
+    {
+        this.scope = scope;
+    }
+
+    //-------------------------------------------------------------------------------------------
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder( 256 );
+        sb.append( "[scope=" + scope.getScope() );
+        if ( classpath != null )
+            for ( ArtifactMetadata md : classpath )
+            {
+                sb.append( ": " + md.toString() + '{' + md.getArtifactUri() + '}' );
+            }
+        sb.append( ']' );
+        return sb.toString();
+    }
+    //-------------------------------------------------------------------------------------------
+    //-------------------------------------------------------------------------------------------
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathContainer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathContainer.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathTransformation.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathTransformation.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathTransformation.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathTransformation.java Sat May 24 20:07:02 2008
@@ -0,0 +1,27 @@
+package org.apache.maven.mercury.representation.transform;
+
+import org.apache.maven.mercury.ArtifactScopeEnum;
+import org.apache.maven.mercury.representation.MetadataGraph;
+
+/*
+ * Helper class to conver an Md Graph into some form of a classpath
+ * 
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public interface ClasspathTransformation
+{
+    String ROLE = ClasspathTransformation.class.getName();
+
+    /**
+     * Transform Graph into a Collection of metadata objects that
+     * could serve as a classpath for a particular scope
+     * 
+     * @param dirtyGraph - dependency graph
+     * @param scope - which classpath to extract
+     * @param resolve - whether to resolve artifacts.
+     * @return Collection of metadata objects in the linked subgraph of the graph which 
+     *             contains the graph.getEntry() vertice
+     */
+    ClasspathContainer transform( MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve )
+        throws MetadataGraphTransformationException;
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathTransformation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/ClasspathTransformation.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/DefaultClasspathTransformation.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/DefaultClasspathTransformation.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/DefaultClasspathTransformation.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/DefaultClasspathTransformation.java Sat May 24 20:07:02 2008
@@ -0,0 +1,153 @@
+package org.apache.maven.mercury.representation.transform;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.maven.mercury.ArtifactScopeEnum;
+import org.apache.maven.mercury.representation.ArtifactMetadata;
+import org.apache.maven.mercury.representation.MetadataGraph;
+import org.apache.maven.mercury.representation.MetadataGraphEdge;
+import org.apache.maven.mercury.representation.MetadataGraphVertex;
+import org.apache.maven.mercury.representation.conflict.ConflictResolutionException;
+import org.apache.maven.mercury.representation.conflict.ConflictResolver;
+
+/*
+ * default implementation of the metadata classpath transformer
+ * 
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ * 
+ * @plexus.component
+ */
+public class DefaultClasspathTransformation
+    implements ClasspathTransformation
+{
+    /** @plexus.requirement */
+    ConflictResolver conflictResolver;
+
+    //----------------------------------------------------------------------------------------------------
+    public ClasspathContainer transform( MetadataGraph dirtyGraph, ArtifactScopeEnum scope, boolean resolve )
+        throws MetadataGraphTransformationException
+    {
+        try
+        {
+            if ( dirtyGraph == null || dirtyGraph.isEmpty() )
+                return null;
+
+            MetadataGraph cleanGraph = conflictResolver.resolveConflicts( dirtyGraph, scope );
+
+            if ( cleanGraph == null || cleanGraph.isEmpty() )
+                return null;
+
+            ClasspathContainer cpc = new ClasspathContainer( scope );
+            if ( cleanGraph.isEmptyEdges() )
+            {
+                // single entry in the classpath, populated from itself
+                ArtifactMetadata amd = cleanGraph.getEntry().getMd();
+                cpc.add( amd );
+            }
+            else
+            {
+                ClasspathGraphVisitor v = new ClasspathGraphVisitor( cleanGraph, cpc );
+                MetadataGraphVertex entry = cleanGraph.getEntry();
+                ArtifactMetadata md = entry.getMd();
+                // entry point
+                v.visit( entry ); //, md.getVersion(), md.getArtifactUri() );
+            }
+
+            return cpc;
+        }
+        catch ( ConflictResolutionException e )
+        {
+            throw new MetadataGraphTransformationException( e );
+        }
+    }
+
+    //===================================================================================================
+    /**
+     * Helper class to traverse graph. Required to make the containing method thread-safe
+     * and yet use class level data to lessen stack usage in recursion
+     */
+    private class ClasspathGraphVisitor
+    {
+        MetadataGraph graph;
+
+        ClasspathContainer cpc;
+
+        List<MetadataGraphVertex> visited;
+
+        //-----------------------------------------------------------------------
+        protected ClasspathGraphVisitor( MetadataGraph cleanGraph, ClasspathContainer cpc )
+        {
+            this.cpc = cpc;
+            this.graph = cleanGraph;
+
+            visited = new ArrayList<MetadataGraphVertex>( cleanGraph.getVertices().size() );
+        }
+
+        //-----------------------------------------------------------------------
+        protected void visit( MetadataGraphVertex node ) //, String version, String artifactUri )
+        {
+            ArtifactMetadata md = node.getMd();
+            if ( visited.contains( node ) )
+                return;
+
+            cpc.add( md );
+            //
+            //    		TreeSet<MetadataGraphEdge> deps = new TreeSet<MetadataGraphEdge>(
+            //    					new Comparator<MetadataGraphEdge>() 
+            //    					{
+            //    						public int compare( MetadataGraphEdge e1
+            //    										  , MetadataGraphEdge e2
+            //    										  )
+            //    						{
+            //    							if( e1.getDepth() == e2.getDepth() )
+            //    							{
+            //    								if( e2.getPomOrder() == e1.getPomOrder() )
+            //    									return e1.getTarget().toString().compareTo(e2.getTarget().toString() );
+            //
+            //    								return e2.getPomOrder() - e1.getPomOrder();
+            //    							}
+            //
+            //    							return e2.getDepth() - e1.getDepth();
+            //    						}
+            //    					}
+            //    				);
+
+            List<MetadataGraphEdge> exits = graph.getExcidentEdges( node );
+
+            if ( exits != null && exits.size() > 0 )
+            {
+                MetadataGraphEdge[] sortedExits = exits.toArray( new MetadataGraphEdge[exits.size()] );
+                Arrays.sort( sortedExits, new Comparator<MetadataGraphEdge>()
+                {
+                    public int compare( MetadataGraphEdge e1, MetadataGraphEdge e2 )
+                    {
+                        if ( e1.getDepth() == e2.getDepth() )
+                        {
+                            if ( e2.getPomOrder() == e1.getPomOrder() )
+                                return e1.getTarget().toString().compareTo( e2.getTarget().toString() );
+                            return e2.getPomOrder() - e1.getPomOrder();
+                        }
+
+                        return e2.getDepth() - e1.getDepth();
+                    }
+                } );
+
+                for ( MetadataGraphEdge e : sortedExits )
+                {
+                    MetadataGraphVertex targetNode = e.getTarget();
+                    targetNode.getMd().setArtifactScope( e.getScope() );
+                    targetNode.getMd().setWhy( e.getSource().getMd().toString() );
+                    visit( targetNode );
+                }
+            }
+
+        }
+        //-----------------------------------------------------------------------
+        //-----------------------------------------------------------------------
+    }
+    //----------------------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------------------------------------
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/DefaultClasspathTransformation.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/DefaultClasspathTransformation.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/MetadataGraphTransformationException.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/MetadataGraphTransformationException.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/MetadataGraphTransformationException.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/MetadataGraphTransformationException.java Sat May 24 20:07:02 2008
@@ -0,0 +1,29 @@
+package org.apache.maven.mercury.representation.transform;
+
+/*
+ * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
+ */
+public class MetadataGraphTransformationException
+    extends Exception
+{
+    private static final long serialVersionUID = -4029897098314019152L;
+
+    public MetadataGraphTransformationException()
+    {
+    }
+
+    public MetadataGraphTransformationException( String message )
+    {
+        super( message );
+    }
+
+    public MetadataGraphTransformationException( Throwable cause )
+    {
+        super( cause );
+    }
+
+    public MetadataGraphTransformationException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/MetadataGraphTransformationException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/transform/MetadataGraphTransformationException.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ArtifactVersion.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ArtifactVersion.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ArtifactVersion.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ArtifactVersion.java Sat May 24 20:07:02 2008
@@ -0,0 +1,34 @@
+package org.apache.maven.mercury.representation.version;
+
+/*
+ * 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.
+ */
+
+public interface ArtifactVersion
+    extends Comparable
+{
+    int getMajorVersion();
+
+    int getMinorVersion();
+
+    int getIncrementalVersion();
+
+    int getBuildNumber();
+
+    String getQualifier();
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ArtifactVersion.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ArtifactVersion.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ComparableVersion.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ComparableVersion.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ComparableVersion.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ComparableVersion.java Sat May 24 20:07:02 2008
@@ -0,0 +1,436 @@
+package org.apache.maven.mercury.representation.version;
+
+/*
+ * 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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.Stack;
+
+/*
+ * Generic implementation of version comparison.
+ * 
+ * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a>
+ * 
+ * @author <a href="mailto:hboutemy@apache.org">Herve Boutemy</a>
+ * 
+ * @version $Id$
+ */
+public class ComparableVersion
+    implements Comparable
+{
+    private String value;
+
+    private String canonical;
+
+    private ListItem items;
+
+    private interface Item
+    {
+        public static final int INTEGER_ITEM = 0;
+
+        public static final int STRING_ITEM = 1;
+
+        public static final int LIST_ITEM = 2;
+
+        public int compareTo( Item item );
+
+        public int getType();
+
+        public boolean isNull();
+    }
+
+    /**
+     * Represents a numeric item in the version item list.
+     */
+    private static class IntegerItem
+        implements Item
+    {
+        private Integer value;
+
+        public IntegerItem( Integer i )
+        {
+            this.value = i;
+        }
+
+        public int getType()
+        {
+            return INTEGER_ITEM;
+        }
+
+        public boolean isNull()
+        {
+            return ( value == 0 );
+        }
+
+        public int compareTo( Item item )
+        {
+            if ( item == null )
+            {
+                return value == 0 ? 0 : 1; // 1.0 == 1, 1.1 > 1
+            }
+
+            switch ( item.getType() )
+            {
+                case INTEGER_ITEM:
+                    return value.compareTo( ( (IntegerItem) item ).value );
+
+                case STRING_ITEM:
+                    return 1; // 1.1 > 1-sp
+
+                case LIST_ITEM:
+                    return 1; // 1.1 > 1-1
+
+                default:
+                    throw new RuntimeException( "invalid item: " + item.getClass() );
+            }
+        }
+
+        public String toString()
+        {
+            return value.toString();
+        }
+    }
+
+    /**
+     * Represents a string in the version item list, usually a qualifier.
+     */
+    private static class StringItem
+        implements Item
+    {
+        private final static String[] QUALIFIERS = { "snapshot", "alpha", "beta", "milestone", "rc", "", "sp" };
+
+        private final static List _QUALIFIERS = Arrays.asList( QUALIFIERS );
+
+        private final static Properties ALIASES = new Properties();
+        static
+        {
+            ALIASES.put( "ga", "" );
+            ALIASES.put( "final", "" );
+            ALIASES.put( "cr", "rc" );
+        }
+
+        /**
+         * A comparable for the empty-string qualifier. This one is used to determine if a given qualifier makes the
+         * version older than one without a qualifier, or more recent.
+         */
+        private static Comparable RELEASE_VERSION_INDEX = String.valueOf( _QUALIFIERS.indexOf( "" ) );
+
+        private String value;
+
+        public StringItem( String value, boolean followedByDigit )
+        {
+            if ( followedByDigit && value.length() == 1 )
+            {
+                // a1 = alpha-1, b1 = beta-1, m1 = milestone-1
+                switch ( value.charAt( 0 ) )
+                {
+                    case 'a':
+                        value = "alpha";
+                        break;
+                    case 'b':
+                        value = "beta";
+                        break;
+                    case 'm':
+                        value = "milestone";
+                        break;
+                }
+            }
+            this.value = ALIASES.getProperty( value, value );
+        }
+
+        public int getType()
+        {
+            return STRING_ITEM;
+        }
+
+        public boolean isNull()
+        {
+            return ( comparableQualifier( value ).compareTo( RELEASE_VERSION_INDEX ) == 0 );
+        }
+
+        /**
+         * Returns a comparable for a qualifier.
+         *
+         * This method both takes into account the ordering of known qualifiers as well as lexical ordering for unknown
+         * qualifiers.
+         *
+         * just returning an Integer with the index here is faster, but requires a lot of if/then/else to check for -1
+         * or QUALIFIERS.size and then resort to lexical ordering. Most comparisons are decided by the first character,
+         * so this is still fast. If more characters are needed then it requires a lexical sort anyway.
+         *
+         * @param qualifier
+         * @return
+         */
+        public static Comparable comparableQualifier( String qualifier )
+        {
+            int i = _QUALIFIERS.indexOf( qualifier );
+
+            return i == -1 ? _QUALIFIERS.size() + "-" + qualifier : String.valueOf( i );
+        }
+
+        public int compareTo( Item item )
+        {
+            if ( item == null )
+            {
+                // 1-rc < 1, 1-ga > 1
+                return comparableQualifier( value ).compareTo( RELEASE_VERSION_INDEX );
+            }
+            switch ( item.getType() )
+            {
+                case INTEGER_ITEM:
+                    return -1; // 1.any < 1.1 ?
+
+                case STRING_ITEM:
+                    return comparableQualifier( value ).compareTo( comparableQualifier( ( (StringItem) item ).value ) );
+
+                case LIST_ITEM:
+                    return -1; // 1.any < 1-1
+
+                default:
+                    throw new RuntimeException( "invalid item: " + item.getClass() );
+            }
+        }
+
+        public String toString()
+        {
+            return value;
+        }
+    }
+
+    /**
+     * Represents a version list item. This class is used both for the global item list and for sub-lists (which start
+     * with '-(number)' in the version specification).
+     */
+    private static class ListItem
+        extends ArrayList
+        implements Item
+    {
+        public int getType()
+        {
+            return LIST_ITEM;
+        }
+
+        public boolean isNull()
+        {
+            return ( size() == 0 );
+        }
+
+        void normalize()
+        {
+            for ( ListIterator iterator = listIterator( size() ); iterator.hasPrevious(); )
+            {
+                Item item = (Item) iterator.previous();
+                if ( item.isNull() )
+                {
+                    iterator.remove(); // remove null trailing items: 0, "", empty list
+                }
+                else
+                {
+                    break;
+                }
+            }
+        }
+
+        public int compareTo( Item item )
+        {
+            if ( item == null )
+            {
+                if ( size() == 0 )
+                {
+                    return 0; // 1-0 = 1- (normalize) = 1
+                }
+                Item first = (Item) get( 0 );
+                return first.compareTo( null );
+            }
+            switch ( item.getType() )
+            {
+                case INTEGER_ITEM:
+                    return -1; // 1-1 < 1.0.x
+
+                case STRING_ITEM:
+                    return 1; // 1-1 > 1-sp
+
+                case LIST_ITEM:
+                    Iterator left = iterator();
+                    Iterator right = ( (ListItem) item ).iterator();
+
+                    while ( left.hasNext() || right.hasNext() )
+                    {
+                        Item l = left.hasNext() ? (Item) left.next() : null;
+                        Item r = right.hasNext() ? (Item) right.next() : null;
+
+                        // if this is shorter, then invert the compare and mul with -1
+                        int result = l == null ? -1 * r.compareTo( l ) : l.compareTo( r );
+
+                        if ( result != 0 )
+                        {
+                            return result;
+                        }
+                    }
+
+                    return 0;
+
+                default:
+                    throw new RuntimeException( "invalid item: " + item.getClass() );
+            }
+        }
+
+        public String toString()
+        {
+            StringBuffer buffer = new StringBuffer( "(" );
+            for ( Iterator iter = iterator(); iter.hasNext(); )
+            {
+                buffer.append( iter.next() );
+                if ( iter.hasNext() )
+                {
+                    buffer.append( ',' );
+                }
+            }
+            buffer.append( ')' );
+            return buffer.toString();
+        }
+    }
+
+    public ComparableVersion( String version )
+    {
+        parseVersion( version );
+    }
+
+    public final void parseVersion( String version )
+    {
+        this.value = version;
+
+        items = new ListItem();
+
+        version = version.toLowerCase( Locale.ENGLISH );
+
+        ListItem list = items;
+
+        Stack stack = new Stack();
+        stack.push( list );
+
+        boolean isDigit = false;
+
+        int startIndex = 0;
+
+        for ( int i = 0; i < version.length(); i++ )
+        {
+            char c = version.charAt( i );
+
+            if ( c == '.' )
+            {
+                if ( i == startIndex )
+                {
+                    list.add( new IntegerItem( 0 ) );
+                }
+                else
+                {
+                    list.add( parseItem( isDigit, version.substring( startIndex, i ) ) );
+                }
+                startIndex = i + 1;
+            }
+            else if ( c == '-' )
+            {
+                if ( i == startIndex )
+                {
+                    list.add( new IntegerItem( 0 ) );
+                }
+                else
+                {
+                    list.add( parseItem( isDigit, version.substring( startIndex, i ) ) );
+                }
+                startIndex = i + 1;
+
+                if ( isDigit )
+                {
+                    list.normalize(); // 1.0-* = 1-*
+
+                    if ( ( i + 1 < version.length() ) && Character.isDigit( version.charAt( i + 1 ) ) )
+                    {
+                        // new ListItem only if previous were digits and new char is a digit,
+                        // ie need to differentiate only 1.1 from 1-1
+                        list.add( list = new ListItem() );
+
+                        stack.push( list );
+                    }
+                }
+            }
+            else if ( Character.isDigit( c ) )
+            {
+                if ( !isDigit && i > startIndex )
+                {
+                    list.add( new StringItem( version.substring( startIndex, i ), true ) );
+                    startIndex = i;
+                }
+
+                isDigit = true;
+            }
+            else
+            {
+                if ( isDigit && i > startIndex )
+                {
+                    list.add( parseItem( true, version.substring( startIndex, i ) ) );
+                    startIndex = i;
+                }
+
+                isDigit = false;
+            }
+        }
+
+        if ( version.length() > startIndex )
+        {
+            list.add( parseItem( isDigit, version.substring( startIndex ) ) );
+        }
+
+        while ( !stack.isEmpty() )
+        {
+            list = (ListItem) stack.pop();
+            list.normalize();
+        }
+
+        canonical = items.toString();
+    }
+
+    private static Item parseItem( boolean isDigit, String buf )
+    {
+        return isDigit ? new IntegerItem( new Integer( buf ) ) : new StringItem( buf, false );
+    }
+
+    public int compareTo( Object o )
+    {
+        return items.compareTo( ( (ComparableVersion) o ).items );
+    }
+
+    public String toString()
+    {
+        return value;
+    }
+
+    public boolean equals( Object o )
+    {
+        return ( o instanceof ComparableVersion ) && canonical.equals( ( (ComparableVersion) o ).canonical );
+    }
+
+    public int hashCode()
+    {
+        return canonical.hashCode();
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ComparableVersion.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/ComparableVersion.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/DefaultArtifactVersion.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/DefaultArtifactVersion.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/DefaultArtifactVersion.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/DefaultArtifactVersion.java Sat May 24 20:07:02 2008
@@ -0,0 +1,221 @@
+package org.apache.maven.mercury.representation.version;
+
+/*
+ * 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 java.util.StringTokenizer;
+
+/*
+ * Default implementation of artifact versioning.
+ * 
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * 
+ * @version $Id$
+ */
+public class DefaultArtifactVersion
+    implements ArtifactVersion
+{
+    private Integer majorVersion;
+
+    private Integer minorVersion;
+
+    private Integer incrementalVersion;
+
+    private Integer buildNumber;
+
+    private String qualifier;
+
+    private ComparableVersion comparable;
+
+    public DefaultArtifactVersion( String version )
+    {
+        parseVersion( version );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return 11 + comparable.hashCode();
+    }
+
+    @Override
+    public boolean equals( Object other )
+    {
+        return compareTo( other ) == 0;
+    }
+
+    public int compareTo( Object o )
+    {
+        DefaultArtifactVersion otherVersion = (DefaultArtifactVersion) o;
+        return this.comparable.compareTo( otherVersion.comparable );
+    }
+
+    public int getMajorVersion()
+    {
+        return majorVersion != null ? majorVersion : 0;
+    }
+
+    public int getMinorVersion()
+    {
+        return minorVersion != null ? minorVersion : 0;
+    }
+
+    public int getIncrementalVersion()
+    {
+        return incrementalVersion != null ? incrementalVersion : 0;
+    }
+
+    public int getBuildNumber()
+    {
+        return buildNumber != null ? buildNumber : 0;
+    }
+
+    public String getQualifier()
+    {
+        return qualifier;
+    }
+
+    public final void parseVersion( String version )
+    {
+        comparable = new ComparableVersion( version );
+
+        int index = version.indexOf( "-" );
+
+        String part1;
+        String part2 = null;
+
+        if ( index < 0 )
+        {
+            part1 = version;
+        }
+        else
+        {
+            part1 = version.substring( 0, index );
+            part2 = version.substring( index + 1 );
+        }
+
+        if ( part2 != null )
+        {
+            try
+            {
+                if ( ( part2.length() == 1 ) || !part2.startsWith( "0" ) )
+                {
+                    buildNumber = Integer.valueOf( part2 );
+                }
+                else
+                {
+                    qualifier = part2;
+                }
+            }
+            catch ( NumberFormatException e )
+            {
+                qualifier = part2;
+            }
+        }
+
+        if ( ( part1.indexOf( "." ) < 0 ) && !part1.startsWith( "0" ) )
+        {
+            try
+            {
+                majorVersion = Integer.valueOf( part1 );
+            }
+            catch ( NumberFormatException e )
+            {
+                // qualifier is the whole version, including "-"
+                qualifier = version;
+                buildNumber = null;
+            }
+        }
+        else
+        {
+            boolean fallback = false;
+            StringTokenizer tok = new StringTokenizer( part1, "." );
+            try
+            {
+                majorVersion = getNextIntegerToken( tok );
+                if ( tok.hasMoreTokens() )
+                {
+                    minorVersion = getNextIntegerToken( tok );
+                }
+                if ( tok.hasMoreTokens() )
+                {
+                    incrementalVersion = getNextIntegerToken( tok );
+                }
+                if ( tok.hasMoreTokens() )
+                {
+                    fallback = true;
+                }
+            }
+            catch ( NumberFormatException e )
+            {
+                fallback = true;
+            }
+
+            if ( fallback )
+            {
+                // qualifier is the whole version, including "-"
+                qualifier = version;
+                majorVersion = null;
+                minorVersion = null;
+                incrementalVersion = null;
+                buildNumber = null;
+            }
+        }
+    }
+
+    private static Integer getNextIntegerToken( StringTokenizer tok )
+    {
+        String s = tok.nextToken();
+        if ( ( s.length() > 1 ) && s.startsWith( "0" ) )
+        {
+            throw new NumberFormatException( "Number part has a leading 0: '" + s + "'" );
+        }
+        return Integer.valueOf( s );
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        if ( majorVersion != null )
+        {
+            buf.append( majorVersion );
+        }
+        if ( minorVersion != null )
+        {
+            buf.append( "." );
+            buf.append( minorVersion );
+        }
+        if ( incrementalVersion != null )
+        {
+            buf.append( "." );
+            buf.append( incrementalVersion );
+        }
+        if ( buildNumber != null )
+        {
+            buf.append( "-" );
+            buf.append( buildNumber );
+        }
+        else if ( qualifier != null )
+        {
+            if ( buf.length() > 0 )
+            {
+                buf.append( "-" );
+            }
+            buf.append( qualifier );
+        }
+        return buf.toString();
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/DefaultArtifactVersion.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/representation/version/DefaultArtifactVersion.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ArtifactRetriever.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ArtifactRetriever.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ArtifactRetriever.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ArtifactRetriever.java Sat May 24 20:07:02 2008
@@ -0,0 +1,34 @@
+package org.apache.maven.mercury.retrieve;
+
+
+/*
+ * 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.
+ */
+
+/**
+ * Responsible for retrieving a set of artifacts.
+ * 
+ * @author Jason van Zyl
+ */
+public interface ArtifactRetriever
+{
+    String ROLE = ArtifactRetriever.class.getName();
+
+    /** @since 3.0 */
+    ResolutionResult retrieve( ResolutionRequest request );
+}
\ No newline at end of file

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ArtifactRetriever.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ArtifactRetriever.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/DefaultArtifactRetriever.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/DefaultArtifactRetriever.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/DefaultArtifactRetriever.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/DefaultArtifactRetriever.java Sat May 24 20:07:02 2008
@@ -0,0 +1,82 @@
+package org.apache.maven.mercury.retrieve;
+
+/*
+ * 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 java.io.File;
+
+import org.apache.maven.mercury.ArtifactRepository;
+import org.apache.maven.mercury.ArtifactRepositoryLayout;
+import org.apache.maven.mercury.DefaultRepositoryLayout;
+import org.apache.maven.mercury.client.Binding;
+import org.apache.maven.mercury.client.MercuryException;
+import org.apache.maven.mercury.client.retrieve.DefaultRetrievalRequest;
+import org.apache.maven.mercury.client.retrieve.DefaultRetriever;
+import org.apache.maven.mercury.client.retrieve.RetrievalRequest;
+import org.apache.maven.mercury.client.retrieve.RetrievalResponse;
+import org.apache.maven.mercury.client.retrieve.Retriever;
+
+/**
+ * @author Jason van Zyl
+ * @plexus.component
+ */
+public class DefaultArtifactRetriever
+    implements ArtifactRetriever
+{
+    ArtifactRepositoryLayout layout = new DefaultRepositoryLayout();
+
+    public ResolutionResult retrieve( ResolutionRequest request )
+    {
+        ResolutionResult result = new ResolutionResult();
+
+        // Setup the HTTP client
+        
+        Retriever retriever;
+                
+        try
+        {
+            retriever = new DefaultRetriever();
+        }
+        catch ( MercuryException e )
+        {
+            result.addException( e );
+            
+            return result;
+        }
+                        
+        for ( ArtifactRepository remoteRepository : request.getRemoteRepostories() )
+        {
+            RetrievalRequest rr = new DefaultRetrievalRequest();                
+            String remoteUrl = remoteRepository.getUrl() + "/" + layout.pathOf( request.getArtifact() );            
+            File localFile = new File( request.getLocalRepository().getBasedir(), layout.pathOf( request.getArtifact() ) );            
+            Binding binding = new Binding( remoteUrl, localFile, true );            
+            RetrievalResponse response = retriever.retrieve( rr );
+            
+            // Not found versus an error. We need to know for each repository exactly what happened.
+            
+            if ( !response.hasExceptions() )
+            {
+                // What do I want to send back to make the graph trackable
+                return result;
+            }            
+        }
+                
+        return result;
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/DefaultArtifactRetriever.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/DefaultArtifactRetriever.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionRequest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionRequest.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionRequest.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionRequest.java Sat May 24 20:07:02 2008
@@ -0,0 +1,136 @@
+package org.apache.maven.mercury.retrieve;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.mercury.Artifact;
+import org.apache.maven.mercury.ArtifactRepository;
+
+/**
+ * A resolution request allows you to either use an existing MavenProject, or a coordinate (gid:aid:version)
+ * to process a POMs dependencies.
+ *
+ * @author Jason van Zyl
+ */
+public class ResolutionRequest
+{
+    private Artifact artifact;
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String version;
+
+    private ArtifactRepository localRepository;
+
+    private List<ArtifactRepository> remoteRepostories;
+
+    private List listeners = new ArrayList();
+
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    public ResolutionRequest setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+
+        return this;
+    }
+
+    public boolean hasArtifact()
+    {
+        return artifact != null;
+    }
+
+    public String getGroupId()
+    {
+        if ( artifact != null )
+        {
+            return artifact.getGroupId();
+        }
+
+        return groupId;
+    }
+
+    public ResolutionRequest setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+
+        return this;
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifact != null )
+        {
+            return artifact.getArtifactId();
+        }
+
+        return artifactId;
+    }
+
+    public ResolutionRequest setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+
+        return this;
+    }
+
+    public String getVersion()
+    {
+        if ( artifact != null )
+        {
+            return artifact.getVersion();
+        }
+
+        return version;
+    }
+
+    public ResolutionRequest setVersion( String version )
+    {
+        this.version = version;
+
+        return this;
+    }
+
+    public ArtifactRepository getLocalRepository()
+    {
+        return localRepository;
+    }
+
+    public ResolutionRequest setLocalRepository( ArtifactRepository localRepository )
+    {
+        this.localRepository = localRepository;
+
+        return this;
+    }
+
+    public List<ArtifactRepository> getRemoteRepostories()
+    {
+        return remoteRepostories;
+    }
+
+    public ResolutionRequest setRemoteRepostories( List<ArtifactRepository> remoteRepostories )
+    {
+        this.remoteRepostories = remoteRepostories;
+
+        return this;
+    }
+
+    // ------------------------------------------------------------------------
+    //
+    // ------------------------------------------------------------------------
+
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer()
+            .append( "groupId = " + getGroupId() )
+            .append( "artifactId = " + getArtifactId() )
+            .append( "version = " + getVersion() );
+
+        return sb.toString();
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionRequest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionResult.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionResult.java?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionResult.java (added)
+++ maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionResult.java Sat May 24 20:07:02 2008
@@ -0,0 +1,85 @@
+package org.apache.maven.mercury.retrieve;
+
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.mercury.Artifact;
+import org.apache.maven.mercury.ArtifactRepository;
+
+/*
+ * @author Jason van Zyl
+ */
+public class ResolutionResult
+{
+    private Artifact artifact;
+
+    private List<ArtifactRepository> repositories;
+
+    private List<Exception> exceptions;
+
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    public void setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+    }
+
+    public List<ArtifactRepository> getRepositories()
+    {
+        return repositories;
+    }
+
+    public void setRepositories( List<ArtifactRepository> repositories )
+    {
+        this.repositories = repositories;
+    }
+
+    public List<Exception> getExceptions()
+    {
+        return exceptions;
+    }
+
+    public void addException( Exception e )
+    {
+        if ( exceptions == null )
+        {
+            exceptions = new ArrayList();
+        }
+        
+        exceptions.add( e );
+    }
+    
+    public void setExceptions( List<Exception> exceptions )
+    {
+        this.exceptions = exceptions;
+    }
+
+    public boolean hasExceptions()
+    {
+        return exceptions != null;
+    }
+}

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/sandbox/trunk/mercury/src/main/java/org/apache/maven/mercury/retrieve/ResolutionResult.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/sandbox/trunk/mercury/src/main/mdo/metadata.mdo
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/src/main/mdo/metadata.mdo?rev=659899&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/src/main/mdo/metadata.mdo (added)
+++ maven/sandbox/trunk/mercury/src/main/mdo/metadata.mdo Sat May 24 20:07:02 2008
@@ -0,0 +1,318 @@
+<!--
+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.
+-->
+
+<model>
+  <id>repository-metadata</id>
+  <name>Metadata</name>
+  <description>Per-directory repository metadata.</description>
+  <defaults>
+    <default>
+      <key>package</key>
+      <value>org.apache.maven.artifact.repository.metadata</value>
+    </default>
+  </defaults>
+  <classes>
+    <class rootElement="true">
+      <name>Metadata</name>
+      <version>1.0.0</version>
+      <fields>
+        <field>
+          <name>groupId</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>The groupId that is directory represents, if any.</description>
+        </field>
+        <field>
+          <name>artifactId</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>The artifactId that is directory represents, if any.</description>
+        </field>
+        <field>
+          <name>version</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>The version that is directory represents, if any.</description>
+        </field>
+        <field>
+          <name>versioning</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Versioning</type>
+          </association>
+          <description>Versioning information for the artifact.</description>
+        </field>
+        <field>
+          <name>plugins</name>
+          <version>1.0.0</version>
+          <description>The set of plugin mappings for the group</description>
+          <association>
+            <type>Plugin</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+      <codeSegments>
+        <codeSegment>
+          <version>1.0.0</version>
+          <code><![CDATA[
+    public boolean merge( Metadata sourceMetadata )
+    {
+        boolean changed = false;
+
+        for ( java.util.Iterator i = sourceMetadata.getPlugins().iterator(); i.hasNext(); )
+        {
+            Plugin plugin = (Plugin) i.next();
+            boolean found = false;
+
+            for ( java.util.Iterator it = getPlugins().iterator(); it.hasNext() && !found; )
+            {
+                Plugin preExisting = (Plugin) it.next();
+
+                if ( preExisting.getPrefix().equals( plugin.getPrefix() ) )
+                {
+                    found = true;
+                }
+            }
+
+            if ( !found )
+            {
+                Plugin mappedPlugin = new Plugin();
+
+                mappedPlugin.setArtifactId( plugin.getArtifactId() );
+
+                mappedPlugin.setPrefix( plugin.getPrefix() );
+
+                mappedPlugin.setName( plugin.getName() );
+
+                addPlugin( mappedPlugin );
+
+                changed = true;
+            }
+        }
+
+        Versioning versioning = sourceMetadata.getVersioning();
+        if ( versioning != null )
+        {
+            Versioning v = getVersioning();
+            if ( v == null )
+            {
+                v = new Versioning();
+                setVersioning( v );
+                changed = true;
+            }
+
+            for ( java.util.Iterator i = versioning.getVersions().iterator(); i.hasNext(); )
+            {
+                String version = (String) i.next();
+                if ( !v.getVersions().contains( version ) )
+                {
+                    changed = true;
+                    v.getVersions().add( version );
+                }
+            }
+          
+            if ( "null".equals( versioning.getLastUpdated() ) )
+            {
+                versioning.setLastUpdated( null );
+            }
+
+            if ( "null".equals( v.getLastUpdated() ) )
+            {
+                v.setLastUpdated( null );
+            }
+
+            if ( versioning.getLastUpdated() == null || versioning.getLastUpdated().length() == 0 )
+            {
+                // this should only be for historical reasons - we assume local is newer
+                versioning.setLastUpdated( v.getLastUpdated() );
+            }
+
+            if ( v.getLastUpdated() == null || v.getLastUpdated().length() == 0 ||
+                 versioning.getLastUpdated().compareTo( v.getLastUpdated() ) >= 0 )
+            {
+                changed = true;
+                v.setLastUpdated( versioning.getLastUpdated() );
+
+                if ( versioning.getRelease() != null )
+                {
+                    changed = true;
+                    v.setRelease( versioning.getRelease() );
+                }
+                if ( versioning.getLatest() != null )
+                {
+                    changed = true;
+                    v.setLatest( versioning.getLatest() );
+                }
+
+                Snapshot s = v.getSnapshot();
+                Snapshot snapshot = versioning.getSnapshot();
+                if ( snapshot != null )
+                {
+                    if ( s == null )
+                    {
+                        s = new Snapshot();
+                        v.setSnapshot( s );
+                        changed = true;
+                    }
+
+                    // overwrite
+                    if ( s.getTimestamp() == null ? snapshot.getTimestamp() != null
+                        : !s.getTimestamp().equals( snapshot.getTimestamp() ) )
+                    {
+                        s.setTimestamp( snapshot.getTimestamp() );
+                        changed = true;
+                    }
+                    if ( s.getBuildNumber() != snapshot.getBuildNumber() )
+                    {
+                        s.setBuildNumber( snapshot.getBuildNumber() );
+                        changed = true;
+                    }
+                    if ( s.isLocalCopy() != snapshot.isLocalCopy() )
+                    {
+                        s.setLocalCopy( snapshot.isLocalCopy() );
+                        changed = true;
+                    }
+                }
+            }
+        }
+        return changed;
+    }
+          ]]></code>
+        </codeSegment>
+      </codeSegments>
+    </class>
+    <class>
+      <name>Versioning</name>
+      <version>1.0.0</version>
+      <description>Versioning information for an artifact</description>
+      <fields>
+        <field>
+          <name>latest</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>What the latest version in the directory is, including snapshots</description>
+        </field>
+        <field>
+          <name>release</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>What the latest version in the directory is, of the releases</description>
+        </field>
+        <field>
+          <name>snapshot</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Snapshot</type>
+          </association>
+          <description>The current snapshot data in use for this version</description>
+        </field>
+        <field>
+          <name>versions</name>
+          <version>1.0.0</version>
+          <description>Versions available for the artifact</description>
+          <association>
+            <type>String</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        <field>
+          <name>lastUpdated</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>When the metadata was last updated</description>
+        </field>
+      </fields>
+      <codeSegments>
+        <codeSegment>
+          <version>1.0.0</version>
+          <code>
+            public void updateTimestamp()
+            {
+                setLastUpdatedTimestamp( new java.util.Date() );
+            }
+
+            public void setLastUpdatedTimestamp( java.util.Date date )
+            {
+                java.util.TimeZone timezone = java.util.TimeZone.getTimeZone( "UTC" );
+                java.text.DateFormat fmt = new java.text.SimpleDateFormat( "yyyyMMddHHmmss" );
+                fmt.setTimeZone( timezone );
+                setLastUpdated( fmt.format( date ) );
+            }
+          </code>
+        </codeSegment>
+      </codeSegments>
+    </class>
+    <class>
+      <name>Snapshot</name>
+      <version>1.0.0</version>
+      <description>Snapshot data for the current version</description>
+      <fields>
+        <field>
+          <name>timestamp</name>
+          <version>1.0.0</version>
+          <description>The time it was deployed</description>
+          <type>String</type>
+        </field>
+        <field>
+          <name>buildNumber</name>
+          <version>1.0.0</version>
+          <description>The incremental build number</description>
+          <type>int</type>
+        </field>
+        <field>
+          <name>localCopy</name>
+          <version>1.0.0</version>
+          <description>Whether to use a local copy instead (with filename that includes the base version)</description>
+          <type>boolean</type>
+          <defaultValue>false</defaultValue>
+        </field>
+      </fields>
+    </class>
+    <class>
+      <name>Plugin</name>
+      <version>1.0.0</version>
+      <description>Mapping information for a single plugin within this group</description>
+      <comment>NOTE: plugin version is _NOT_ included here, since it is resolved using a separate algorithm.</comment>
+      <fields>
+        <field>
+          <name>name</name>
+          <type>String</type>
+          <required>true</required>
+          <version>1.0.0</version>
+          <description>Display name for the plugin.</description>
+        </field>
+        <field>
+          <name>prefix</name>
+          <type>String</type>
+          <required>true</required>
+          <version>1.0.0</version>
+          <description>The plugin invocation prefix (i.e. eclipse for eclipse:eclipse)</description>
+        </field>
+        <field>
+          <name>artifactId</name>
+          <type>String</type>
+          <required>true</required>
+          <version>1.0.0</version>
+          <description>The plugin artifactId</description>
+        </field>
+      </fields>
+    </class>
+  </classes>
+</model>