You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2011/05/24 04:33:00 UTC

svn commit: r1126833 [1/2] - in /maven/maven-3/branches/mirror-group-routing: ./ maven-auto-mirror-model/ maven-auto-mirror-model/src/ maven-auto-mirror-model/src/main/ maven-auto-mirror-model/src/main/java/ maven-auto-mirror-model/src/main/java/org/ m...

Author: jdcasey
Date: Tue May 24 02:32:59 2011
New Revision: 1126833

URL: http://svn.apache.org/viewvc?rev=1126833&view=rev
Log:
message

Added:
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/pom.xml   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirror.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorModelException.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorSerializer.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrors.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/
    maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/RouterMirrorSerializerTest.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfigLoader.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfiguration.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultMirrorRouter.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultRouterMirrorsResolver.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/MirrorRouter.java   (with props)
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RouterMirrorsResolver.java   (with props)
    maven/maven-3/branches/mirror-group-routing/pom.xml.orig
Modified:
    maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
    maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
    maven/maven-3/branches/mirror-group-routing/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
    maven/maven-3/branches/mirror-group-routing/pom.xml

Added: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/pom.xml?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/pom.xml (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/pom.xml Tue May 24 02:32:59 2011
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>maven</artifactId>
+    <groupId>org.apache.maven</groupId>
+    <version>3.0.3-SNAPSHOT</version>
+  </parent>
+  
+  <artifactId>maven-auto-mirror-model</artifactId>
+  <name>Maven Auto-Mirror Data Model</name>
+  <dependencies>
+  	<dependency>
+  		<groupId>com.google.code.gson</groupId>
+  		<artifactId>gson</artifactId>
+  	</dependency>
+  </dependencies>
+</project>

Propchange: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirror.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirror.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirror.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirror.java Tue May 24 02:32:59 2011
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.maven.repository.automirror;
+
+public class RouterMirror
+    implements Comparable<RouterMirror>
+{
+
+    private final String id;
+
+    private final String mirrorUrl;
+
+    private final int weight;
+
+    private final boolean enabled;
+
+    private final String url;
+
+    RouterMirror()
+    {
+        id = null;
+        url = null;
+        mirrorUrl = null;
+        weight = 0;
+        enabled = false;
+    }
+
+    public RouterMirror( final String id, final String url, final String mirrorUrl, final int weight,
+                         final boolean enabled )
+    {
+        this.id = id;
+        this.url = url;
+        this.mirrorUrl = mirrorUrl;
+        this.weight = weight;
+        this.enabled = enabled;
+    }
+
+    public String getId()
+    {
+        return id;
+    }
+
+    public String getMirrorUrl()
+    {
+        return mirrorUrl;
+    }
+
+    public int getWeight()
+    {
+        return weight;
+    }
+
+    public boolean isEnabled()
+    {
+        return enabled;
+    }
+
+    public int compareTo( final RouterMirror o )
+    {
+        return o.weight - weight;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "mirror [id: " + id + ", weight: " + weight + ", url: " + url + ", mirror-url: " + mirrorUrl
+                        + ", enabled: " + enabled + "]";
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( mirrorUrl == null ) ? 0 : mirrorUrl.hashCode() );
+        return result;
+    }
+
+    @Override
+    public boolean equals( final Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+        if ( obj == null )
+        {
+            return false;
+        }
+        if ( getClass() != obj.getClass() )
+        {
+            return false;
+        }
+        final RouterMirror other = (RouterMirror) obj;
+        if ( mirrorUrl == null )
+        {
+            if ( other.mirrorUrl != null )
+            {
+                return false;
+            }
+        }
+        else if ( !mirrorUrl.equals( other.mirrorUrl ) )
+        {
+            return false;
+        }
+        return true;
+    }
+
+    public String getUrl()
+    {
+        return url;
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirror.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorModelException.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorModelException.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorModelException.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorModelException.java Tue May 24 02:32:59 2011
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2011 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.repository.automirror;
+
+public class RouterMirrorModelException
+    extends Exception
+{
+
+    private static final long serialVersionUID = 1L;
+
+    public RouterMirrorModelException( final String message, final Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public RouterMirrorModelException( final String message )
+    {
+        super( message );
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorModelException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorSerializer.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorSerializer.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorSerializer.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorSerializer.java Tue May 24 02:32:59 2011
@@ -0,0 +1,105 @@
+package org.apache.maven.repository.automirror;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.InstanceCreator;
+import com.google.gson.JsonParseException;
+import com.google.gson.reflect.TypeToken;
+
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+public class RouterMirrorSerializer
+{
+
+    // NOTE: Gson is supposed to be threadsafe, so all this static stuff should be fine.
+    private static Gson gson;
+
+    public static void serialize( final RouterMirrors mirrors, final Writer writer )
+        throws RouterMirrorModelException
+    {
+        try
+        {
+            getGson().toJson( mirrors, writer );
+        }
+        catch ( final JsonParseException e )
+        {
+            throw new RouterMirrorModelException( "Cannot read router-mirrors.", e );
+        }
+    }
+
+    public static String serializeToString( final RouterMirrors mirrors )
+        throws RouterMirrorModelException
+    {
+        try
+        {
+            return getGson().toJson( mirrors );
+        }
+        catch ( final JsonParseException e )
+        {
+            throw new RouterMirrorModelException( "Cannot read router-mirrors.", e );
+        }
+    }
+
+    public static RouterMirrors deserialize( final Reader reader )
+        throws RouterMirrorModelException
+    {
+        try
+        {
+            return getGson().fromJson( reader, RouterMirrors.class );
+        }
+        catch ( final JsonParseException e )
+        {
+            throw new RouterMirrorModelException( "Cannot read router-mirrors.", e );
+        }
+    }
+
+    public static RouterMirrors deserialize( final String source )
+        throws RouterMirrorModelException
+    {
+        try
+        {
+            return getGson().fromJson( source, RouterMirrors.class );
+        }
+        catch ( final JsonParseException e )
+        {
+            throw new RouterMirrorModelException( "Cannot read router-mirrors.", e );
+        }
+    }
+
+    private static Gson getGson()
+    {
+        if ( gson == null )
+        {
+            final GsonBuilder builder = new GsonBuilder();
+            builder.disableHtmlEscaping().disableInnerClassSerialization().setPrettyPrinting();
+            builder.registerTypeAdapter( RepositoryMirrorListCreator.getType(), new RepositoryMirrorListCreator() );
+
+            gson = builder.create();
+        }
+
+        return gson;
+    }
+
+    public static final class RepositoryMirrorListCreator
+        implements InstanceCreator<List<RouterMirror>>
+    {
+
+        public List<RouterMirror> createInstance( final Type type )
+        {
+            return new ArrayList<RouterMirror>();
+        }
+
+        public static Type getType()
+        {
+            return new TypeToken<List<RouterMirror>>()
+            {
+            }.getType();
+        }
+
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrorSerializer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrors.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrors.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrors.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrors.java Tue May 24 02:32:59 2011
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.maven.repository.automirror;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+public class RouterMirrors
+    implements Iterable<RouterMirror>
+{
+
+    private List<RouterMirror> mirrors = new ArrayList<RouterMirror>();
+
+    private final transient Random random = new Random();
+
+    private transient Map<String, int[]> indexGrabBags = new HashMap<String, int[]>();
+
+    public synchronized RouterMirrors addMirror( final RouterMirror mirror )
+    {
+        if ( !mirrors.contains( mirror ) )
+        {
+            mirrors.add( mirror );
+            indexGrabBags.remove( mirror.getUrl() );
+        }
+
+        return this;
+    }
+
+    public RouterMirror getHighestPriorityMirror( final String canonicalUrl )
+    {
+        if ( mirrors.isEmpty() )
+        {
+            return null;
+        }
+
+        final List<RouterMirror> available = new ArrayList<RouterMirror>( mirrors );
+
+        // sort by weight.
+        Collections.sort( available );
+
+        for ( final RouterMirror mirror : available )
+        {
+            // return the highest-priority ENABLED mirror.
+            if ( mirror.isEnabled() && canonicalUrl.equals( mirror.getUrl() ) )
+            {
+                return mirror;
+            }
+        }
+
+        return null;
+    }
+
+    public RouterMirror getWeightedRandomSuggestion( final String canonicalUrl )
+    {
+        if ( mirrors.isEmpty() )
+        {
+            return null;
+        }
+
+        int[] indexGrabBag = null;
+        synchronized ( canonicalUrl )
+        {
+            indexGrabBag = indexGrabBags.get( canonicalUrl );
+            if ( indexGrabBag == null )
+            {
+                final List<Integer> gb = new ArrayList<Integer>();
+                for ( int idx = 0; idx < mirrors.size(); idx++ )
+                {
+                    final RouterMirror mirror = mirrors.get( idx );
+                    if ( !mirror.isEnabled() )
+                    {
+                        // only select from enabled mirrors.
+                        continue;
+                    }
+
+                    if ( mirror.getWeight() < 1 )
+                    {
+                        // make sure this mirror has at least one chance of being picked.
+                        gb.add( idx );
+                    }
+                    else
+                    {
+                        // if weight == 9, give this mirror 9 chances of being picked randomly.
+                        for ( int i = 0; i < mirror.getWeight(); i++ )
+                        {
+                            gb.add( idx );
+                        }
+                    }
+                }
+
+                final int[] grabBag = new int[gb.size()];
+                for ( int i = 0; i < grabBag.length; i++ )
+                {
+                    grabBag[i] = gb.get( i );
+                }
+
+                indexGrabBags.put( canonicalUrl, grabBag );
+            }
+        }
+
+        // generate a random number that will correspond to an index stored in the index grab bag.
+        int idx = Math.abs( random.nextInt() ) % indexGrabBag.length;
+
+        // use that random number to select the index of the mirror in the mirrors list.
+        idx = indexGrabBag[idx];
+
+        // lookup the mirror instance associated with the index from the grab bag.
+        return mirrors.get( idx );
+    }
+
+    public int size()
+    {
+        return mirrors.size();
+    }
+
+    public boolean isEmpty()
+    {
+        return mirrors.isEmpty();
+    }
+
+    public boolean contains( final RouterMirror o )
+    {
+        return mirrors.contains( o );
+    }
+
+    public Iterator<RouterMirror> iterator()
+    {
+        return mirrors.iterator();
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ( ( mirrors == null ) ? 0 : mirrors.hashCode() );
+        return result;
+    }
+
+    @Override
+    public boolean equals( final Object obj )
+    {
+        if ( this == obj )
+        {
+            return true;
+        }
+        if ( obj == null )
+        {
+            return false;
+        }
+        if ( getClass() != obj.getClass() )
+        {
+            return false;
+        }
+        final RouterMirrors other = (RouterMirrors) obj;
+        if ( mirrors == null )
+        {
+            if ( other.mirrors != null )
+            {
+                return false;
+            }
+        }
+        else if ( !mirrors.equals( other.mirrors ) )
+        {
+            return false;
+        }
+        return true;
+    }
+
+    List<RouterMirror> getMirrors()
+    {
+        return mirrors;
+    }
+
+    void setMirrors( final List<RouterMirror> mirrors )
+    {
+        this.mirrors = mirrors;
+    }
+
+    public boolean containsMirrorOf( final String canonicalUrl )
+    {
+        for ( final RouterMirror mirror : mirrors )
+        {
+            if ( mirror.isEnabled() && canonicalUrl.equals( mirror.getUrl() ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/main/java/org/apache/maven/repository/automirror/RouterMirrors.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/RouterMirrorSerializerTest.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/RouterMirrorSerializerTest.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/RouterMirrorSerializerTest.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/RouterMirrorSerializerTest.java Tue May 24 02:32:59 2011
@@ -0,0 +1,48 @@
+package org.apache.maven.repository.automirror;
+
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+
+public class RouterMirrorSerializerTest
+    extends TestCase
+{
+
+    public void testSerializeOneMirror()
+        throws Exception
+    {
+        final RouterMirrors mirrorMap =
+            new RouterMirrors().addMirror( new RouterMirror( "central", "http://repo1.maven.org/maven2",
+                                                             "http://localhost:8081/nexus", 99, true ) );
+
+        final StringWriter sw = new StringWriter();
+        RouterMirrorSerializer.serialize( mirrorMap, sw );
+
+        System.out.println( sw );
+    }
+
+    public void testSerializeToStringOneMirror()
+        throws Exception
+    {
+        final RouterMirrors mirrorMap =
+            new RouterMirrors().addMirror( new RouterMirror( "central", "http://repo1.maven.org/maven2",
+                                                             "http://localhost:8081/nexus", 99, true ) );
+
+        System.out.println( RouterMirrorSerializer.serializeToString( mirrorMap ) );
+    }
+
+    public void testRoundTripOneMirror()
+        throws Exception
+    {
+        final RouterMirrors mirrorMap =
+            new RouterMirrors().addMirror( new RouterMirror( "central", "http://repo1.maven.org/maven2",
+                                                             "http://localhost:8081/nexus", 99, true ) );
+
+        final String ser = RouterMirrorSerializer.serializeToString( mirrorMap );
+        final RouterMirrors result = RouterMirrorSerializer.deserialize( ser );
+
+        assertEquals( mirrorMap, result );
+        assertTrue( result.getHighestPriorityMirror( "http://repo1.maven.org/maven2" ).isEnabled() );
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-auto-mirror-model/src/test/java/org/apache/maven/repository/automirror/RouterMirrorSerializerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml?rev=1126833&r1=1126832&r2=1126833&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml Tue May 24 02:32:59 2011
@@ -102,6 +102,14 @@
       <artifactId>commons-jxpath</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+    	<groupId>org.apache.maven</groupId>
+    	<artifactId>maven-auto-mirror-model</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.httpcomponents</groupId>
+    	<artifactId>httpclient</artifactId>
+    </dependency>
   </dependencies>
 
   <build>

Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfigLoader.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfigLoader.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfigLoader.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfigLoader.java Tue May 24 02:32:59 2011
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.maven.configuration.mirror;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+
+@Component( role = AutoMirrorConfigLoader.class )
+public class AutoMirrorConfigLoader
+{
+
+    @Requirement
+    private Logger logger;
+
+    public AutoMirrorConfiguration loadConfiguration( final EMBConfiguration embConfig )
+        throws ExtensionConfigurationException
+    {
+
+        return config;
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfigLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfiguration.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfiguration.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfiguration.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfiguration.java Tue May 24 02:32:59 2011
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.maven.configuration.mirror;
+
+import static org.codehaus.plexus.util.IOUtil.close;
+import static org.codehaus.plexus.util.StringUtils.isNotBlank;
+
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+
+@Component( role = AutoMirrorConfiguration.class )
+public class AutoMirrorConfiguration
+    implements Contextualizable
+{
+
+    private static final String AUTOMIRROR_CONFIG_FILENAME = "automirror.properties";
+
+    private static final String KEY_ROUTER_URL = "router-url";
+
+    private static final String KEY_ROUTER_USER = "router-user";
+
+    private static final String KEY_ROUTER_PASSWORD = "router-password";
+
+    private static final String KEY_DISABLED = "disabled";
+
+    private static final String KEY_DISCOVERY_STRATEGIES = "discovery-strategies";
+
+    private static final String CANONICAL_ROUTER_URL = "http://repository.apache.org/router/mirrors.json";
+
+    public static final String ALL_DISCOVERY_STRATEGIES = "all";
+
+    public static final String NO_DISCOVERY_STRATEGIES = "none";
+
+    private String routerUrl;
+
+    private UsernamePasswordCredentials routerCredentials;
+
+    private boolean disabled = false;
+
+    private String[] discoveryStrategies = { ALL_DISCOVERY_STRATEGIES };
+
+    @Requirement
+    private Logger logger;
+
+    public AutoMirrorConfiguration withRouterCredentials( final String user, final String password )
+    {
+        routerCredentials = new UsernamePasswordCredentials( user, password );
+        return this;
+    }
+
+    public UsernamePasswordCredentials getRouterCredentials()
+    {
+        return routerCredentials;
+    }
+
+    public AutoMirrorConfiguration withRouterUrl( final String routerUrl )
+    {
+        this.routerUrl = routerUrl;
+        return this;
+    }
+
+    public String getRouterUrl()
+    {
+        return routerUrl;
+    }
+
+    public boolean isDisabled()
+    {
+        return disabled;
+    }
+
+    public AutoMirrorConfiguration setDisabled( final boolean disabled )
+    {
+        this.disabled = disabled;
+        return this;
+    }
+
+    public String getCanonicalRouterUrl()
+    {
+        return CANONICAL_ROUTER_URL;
+    }
+
+    public String[] getDiscoveryStrategies()
+    {
+        return discoveryStrategies == null ? new String[0] : discoveryStrategies;
+    }
+
+    public AutoMirrorConfiguration setDiscoveryStrategies( final String... strategies )
+    {
+        discoveryStrategies = strategies;
+        return this;
+    }
+
+    public void contextualize( final Context context )
+    {
+        final File configFile = new File( embConfig.getConfigurationDirectory(), AUTOMIRROR_CONFIG_FILENAME );
+        final AutoMirrorConfiguration config = new AutoMirrorConfiguration();
+
+        if ( configFile.exists() )
+        {
+            logger.info( "Loading configuration file: " + configFile );
+            FileInputStream stream = null;
+            try
+            {
+                stream = new FileInputStream( configFile );
+                final Properties p = new Properties();
+                p.load( stream );
+
+                config.withRouterUrl( p.getProperty( KEY_ROUTER_URL ) )
+                      .setDisabled( Boolean.parseBoolean( p.getProperty( KEY_DISABLED, "false" ) ) );
+
+                final String user = p.getProperty( KEY_ROUTER_USER );
+                final String pass = p.getProperty( KEY_ROUTER_PASSWORD );
+
+                final String[] strat =
+                    p.getProperty( KEY_DISCOVERY_STRATEGIES, AutoMirrorConfiguration.ALL_DISCOVERY_STRATEGIES )
+                     .split( "\\s*,\\s*" );
+
+                config.setDiscoveryStrategies( strat );
+
+                if ( isNotBlank( user ) && isNotBlank( pass ) )
+                {
+                    config.withRouterCredentials( user, pass );
+                }
+            }
+            catch ( final IOException e )
+            {
+                throw new ExtensionConfigurationException( "Failed to read properties: '{0}' from: {1}\nReason: {2}",
+                                                           e, AUTOMIRROR_CONFIG_FILENAME,
+                                                           embConfig.getConfigurationDirectory(), e.getMessage() );
+            }
+            finally
+            {
+                close( stream );
+            }
+        }
+        else
+        {
+            logger.info( "Cannot find configuration file: " + configFile + ". Using defaults." );
+        }
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/configuration/mirror/AutoMirrorConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java?rev=1126833&r1=1126832&r2=1126833&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java Tue May 24 02:32:59 2011
@@ -855,6 +855,8 @@ public class DefaultMavenExecutionReques
     // calculated from request attributes.
     private ProjectBuildingRequest projectBuildingRequest;
 
+    private File extensionConfDir;
+
     public boolean isProjectPresent()
     {
         return isProjectPresent;
@@ -1076,4 +1078,15 @@ public class DefaultMavenExecutionReques
         return this;
     }
 
+    public File getUserExtensionConfDir()
+    {
+        return extensionConfDir;
+    }
+
+    public MavenExecutionRequest setUserExtensionConfDir( File extensionConfDir )
+    {
+        this.extensionConfDir = extensionConfDir;
+        return this;
+    }
+
 }

Modified: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java?rev=1126833&r1=1126832&r2=1126833&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java Tue May 24 02:32:59 2011
@@ -19,11 +19,6 @@ package org.apache.maven.execution;
  * under the License.
  */
 
-import java.io.File;
-import java.util.Date;
-import java.util.List;
-import java.util.Properties;
-
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
 import org.apache.maven.model.Profile;
@@ -36,6 +31,11 @@ import org.sonatype.aether.RepositoryCac
 import org.sonatype.aether.repository.WorkspaceReader;
 import org.sonatype.aether.transfer.TransferListener;
 
+import java.io.File;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
 /**
  * @author Jason van Zyl
  */
@@ -91,14 +91,17 @@ public interface MavenExecutionRequest
 
     // Base directory
     MavenExecutionRequest setBaseDirectory( File basedir );
+
     String getBaseDirectory();
 
     // Timing (remove this)
     MavenExecutionRequest setStartTime( Date start );
+
     Date getStartTime();
 
     // Goals
     MavenExecutionRequest setGoals( List<String> goals );
+
     List<String> getGoals();
 
     // Properties
@@ -106,8 +109,9 @@ public interface MavenExecutionRequest
     /**
      * Sets the system properties to use for interpolation and profile activation. The system properties are collected
      * from the runtime environment like {@link System#getProperties()} and environment variables.
-     *
-     * @param systemProperties The system properties, may be {@code null}.
+     * 
+     * @param systemProperties
+     *            The system properties, may be {@code null}.
      * @return This request, never {@code null}.
      */
     MavenExecutionRequest setSystemProperties( Properties systemProperties );
@@ -115,7 +119,7 @@ public interface MavenExecutionRequest
     /**
      * Gets the system properties to use for interpolation and profile activation. The system properties are collected
      * from the runtime environment like {@link System#getProperties()} and environment variables.
-     *
+     * 
      * @return The system properties, never {@code null}.
      */
     Properties getSystemProperties();
@@ -124,8 +128,9 @@ public interface MavenExecutionRequest
      * Sets the user properties to use for interpolation and profile activation. The user properties have been
      * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
      * line.
-     *
-     * @param userProperties The user properties, may be {@code null}.
+     * 
+     * @param userProperties
+     *            The user properties, may be {@code null}.
      * @return This request, never {@code null}.
      */
     MavenExecutionRequest setUserProperties( Properties userProperties );
@@ -134,153 +139,210 @@ public interface MavenExecutionRequest
      * Gets the user properties to use for interpolation and profile activation. The user properties have been
      * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
      * line.
-     *
+     * 
      * @return The user properties, never {@code null}.
      */
     Properties getUserProperties();
 
     // Reactor
     MavenExecutionRequest setReactorFailureBehavior( String failureBehavior );
+
     String getReactorFailureBehavior();
 
     MavenExecutionRequest setSelectedProjects( List<String> projects );
+
     List<String> getSelectedProjects();
 
     MavenExecutionRequest setResumeFrom( String project );
+
     String getResumeFrom();
 
     MavenExecutionRequest setMakeBehavior( String makeBehavior );
+
     String getMakeBehavior();
 
     void setThreadCount( String threadCount );
+
     String getThreadCount();
+
     boolean isThreadConfigurationPresent();
+
     void setPerCoreThreadCount( boolean perCoreThreadCount );
+
     boolean isPerCoreThreadCount();
 
     // Recursive (really to just process the top-level POM)
     MavenExecutionRequest setRecursive( boolean recursive );
+
     boolean isRecursive();
 
     MavenExecutionRequest setPom( File pom );
+
     File getPom();
 
     // Errors
     MavenExecutionRequest setShowErrors( boolean showErrors );
+
     boolean isShowErrors();
 
     // Transfer listeners
     MavenExecutionRequest setTransferListener( TransferListener transferListener );
+
     TransferListener getTransferListener();
 
     // Logging
     MavenExecutionRequest setLoggingLevel( int loggingLevel );
+
     int getLoggingLevel();
 
     // Update snapshots
     MavenExecutionRequest setUpdateSnapshots( boolean updateSnapshots );
+
     boolean isUpdateSnapshots();
 
     MavenExecutionRequest setNoSnapshotUpdates( boolean noSnapshotUpdates );
+
     boolean isNoSnapshotUpdates();
 
     // Checksum policy
     MavenExecutionRequest setGlobalChecksumPolicy( String globalChecksumPolicy );
+
     String getGlobalChecksumPolicy();
 
     // Local repository
     MavenExecutionRequest setLocalRepositoryPath( String localRepository );
+
     MavenExecutionRequest setLocalRepositoryPath( File localRepository );
+
     File getLocalRepositoryPath();
+
     MavenExecutionRequest setLocalRepository( ArtifactRepository repository );
+
     ArtifactRepository getLocalRepository();
 
     // Interactive
     MavenExecutionRequest setInteractiveMode( boolean interactive );
+
     boolean isInteractiveMode();
 
     // Offline
     MavenExecutionRequest setOffline( boolean offline );
+
     boolean isOffline();
 
     boolean isCacheTransferError();
+
     MavenExecutionRequest setCacheTransferError( boolean cacheTransferError );
 
     boolean isCacheNotFound();
+
     MavenExecutionRequest setCacheNotFound( boolean cacheNotFound );
 
     // Profiles
     List<Profile> getProfiles();
+
     MavenExecutionRequest addProfile( Profile profile );
+
     MavenExecutionRequest setProfiles( List<Profile> profiles );
+
     MavenExecutionRequest addActiveProfile( String profile );
+
     MavenExecutionRequest addActiveProfiles( List<String> profiles );
+
     MavenExecutionRequest setActiveProfiles( List<String> profiles );
+
     List<String> getActiveProfiles();
+
     MavenExecutionRequest addInactiveProfile( String profile );
+
     MavenExecutionRequest addInactiveProfiles( List<String> profiles );
+
     MavenExecutionRequest setInactiveProfiles( List<String> profiles );
+
     List<String> getInactiveProfiles();
 
     // Proxies
     List<Proxy> getProxies();
+
     MavenExecutionRequest setProxies( List<Proxy> proxies );
+
     MavenExecutionRequest addProxy( Proxy proxy );
 
     // Servers
     List<Server> getServers();
+
     MavenExecutionRequest setServers( List<Server> servers );
+
     MavenExecutionRequest addServer( Server server );
 
     // Mirrors
     List<Mirror> getMirrors();
+
     MavenExecutionRequest setMirrors( List<Mirror> mirrors );
+
     MavenExecutionRequest addMirror( Mirror mirror );
 
     // Plugin groups
     List<String> getPluginGroups();
+
     MavenExecutionRequest setPluginGroups( List<String> pluginGroups );
+
     MavenExecutionRequest addPluginGroup( String pluginGroup );
+
     MavenExecutionRequest addPluginGroups( List<String> pluginGroups );
 
     boolean isProjectPresent();
+
     MavenExecutionRequest setProjectPresent( boolean isProjectPresent );
 
     File getUserSettingsFile();
+
     MavenExecutionRequest setUserSettingsFile( File userSettingsFile );
 
     File getGlobalSettingsFile();
+
     MavenExecutionRequest setGlobalSettingsFile( File globalSettingsFile );
 
     MavenExecutionRequest addRemoteRepository( ArtifactRepository repository );
+
     MavenExecutionRequest addPluginArtifactRepository( ArtifactRepository repository );
 
     /**
      * Set a new list of remote repositories to use the execution request. This is necessary if you perform
      * transformations on the remote repositories being used. For example if you replace existing repositories with
      * mirrors then it's easier to just replace the whole list with a new list of transformed repositories.
-     *
+     * 
      * @param repositories
      * @return
      */
     MavenExecutionRequest setRemoteRepositories( List<ArtifactRepository> repositories );
+
     List<ArtifactRepository> getRemoteRepositories();
 
     MavenExecutionRequest setPluginArtifactRepositories( List<ArtifactRepository> repositories );
+
     List<ArtifactRepository> getPluginArtifactRepositories();
 
     MavenExecutionRequest setRepositoryCache( RepositoryCache repositoryCache );
+
     RepositoryCache getRepositoryCache();
 
     WorkspaceReader getWorkspaceReader();
+
     MavenExecutionRequest setWorkspaceReader( WorkspaceReader workspaceReader );
 
     File getUserToolchainsFile();
+
     MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile );
 
     ExecutionListener getExecutionListener();
+
     MavenExecutionRequest setExecutionListener( ExecutionListener executionListener );
 
     ProjectBuildingRequest getProjectBuildingRequest();
 
+    File getUserExtensionConfDir();
+
+    MavenExecutionRequest setUserExtensionConfDir( File extensionConfDir );
+
 }

Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultMirrorRouter.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultMirrorRouter.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultMirrorRouter.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultMirrorRouter.java Tue May 24 02:32:59 2011
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.maven.repository.mirror;
+
+import org.apache.log4j.Logger;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.commonjava.emb.conf.EMBLibrary;
+import org.commonjava.emb.mirror.AutoMirrorException;
+import org.commonjava.emb.mirror.conf.AutoMirrorConfiguration;
+import org.commonjava.emb.mirror.conf.AutoMirrorLibrary;
+import org.commonjava.emb.mirror.discovery.RouterDiscoveryStrategy;
+import org.commonjava.emb.mirror.model.RouterMirror;
+import org.commonjava.emb.mirror.model.RouterMirrors;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Component( role = MirrorRouter.class )
+final class DefaultMirrorRouter
+    implements Initializable, MirrorRouter
+{
+
+    private RouterMirrors mirrorMapping;
+
+    private boolean initialized = false;
+
+    @Requirement( hint = AutoMirrorLibrary.HINT )
+    private EMBLibrary library;
+
+    @Requirement
+    private AutoMirrorConfiguration config;
+
+    @Requirement( role = RouterDiscoveryStrategy.class )
+    private Map<String, RouterDiscoveryStrategy> strategies;
+
+    @Requirement
+    private RouterMirrorsResolver mirrorResolver;
+
+    public synchronized void initialize()
+        throws InitializationException
+    {
+        if ( initialized )
+        {
+            return;
+        }
+
+        if ( !config.isDisabled() )
+        {
+            try
+            {
+                if ( config.getRouterUrl() != null )
+                {
+                    mirrorMapping = mirrorResolver.getMirrorMapping( config.getRouterUrl() );
+                }
+                else
+                {
+                    final String[] discoStrategies = config.getDiscoveryStrategies();
+                    final List<RouterDiscoveryStrategy> strats = new ArrayList<RouterDiscoveryStrategy>();
+                    if ( discoStrategies.length == 1 )
+                    {
+                        final String key = discoStrategies[0];
+                        if ( AutoMirrorConfiguration.NO_DISCOVERY_STRATEGIES.equalsIgnoreCase( key ) )
+                        {
+                            // NOP
+                        }
+                        else if ( AutoMirrorConfiguration.ALL_DISCOVERY_STRATEGIES.equalsIgnoreCase( key ) )
+                        {
+                            strats.addAll( strategies.values() );
+                        }
+                        else
+                        {
+                            final RouterDiscoveryStrategy strat = getDiscoveryStrategy( key );
+                            if ( strat != null )
+                            {
+                                strats.add( strat );
+                            }
+                        }
+                    }
+                    else
+                    {
+                        for ( final String key : discoStrategies )
+                        {
+                            final RouterDiscoveryStrategy strat = getDiscoveryStrategy( key );
+                            if ( strat != null )
+                            {
+                                strats.add( strat );
+                            }
+                        }
+                    }
+
+                    String routerUrl = null;
+                    for ( final RouterDiscoveryStrategy strategy : strats )
+                    {
+                        routerUrl = strategy.findRouter();
+                        if ( routerUrl != null && !routerUrl.trim().isEmpty() )
+                        {
+                            mirrorMapping = mirrorResolver.getMirrorMapping( routerUrl );
+                            if ( mirrorMapping != null )
+                            {
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                final String centralRouterUrl = config.getCanonicalRouterUrl();
+                if ( mirrorMapping == null && centralRouterUrl != null && centralRouterUrl.trim().length() > 0 )
+                {
+                    mirrorMapping = mirrorResolver.getMirrorMapping( config.getRouterUrl() );
+                }
+            }
+            catch ( final AutoMirrorException e )
+            {
+                if ( library.getLogger().isDebugEnabled() )
+                {
+                    library.getLogger().error( "Failed to auto-detect Nexus mirrors: " + e.getMessage(), e );
+                }
+            }
+        }
+
+        if ( mirrorMapping == null )
+        {
+            mirrorMapping = new RouterMirrors();
+        }
+
+        initialized = true;
+    }
+
+    private RouterDiscoveryStrategy getDiscoveryStrategy( final String key )
+    {
+        RouterDiscoveryStrategy strat = strategies.get( key );
+        if ( strat == null )
+        {
+            strat = strategies.get( key.toLowerCase() );
+        }
+
+        if ( strat == null )
+        {
+            library.getLogger().warn( "Cannot find RouterDiscoveryStrategy with hint: '" + key + "'" );
+        }
+
+        return strat;
+    }
+
+    protected Logger getLogger()
+    {
+        return library.getLogger();
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.commonjava.emb.mirror.resolve.MirrorRouter#getWeightedRandomSuggestion(java.lang.String)
+     */
+    @Override
+    public RouterMirror getWeightedRandomSuggestion( final String canonicalUrl )
+    {
+        return mirrorMapping.getWeightedRandomSuggestion( canonicalUrl );
+    }
+
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultMirrorRouter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultRouterMirrorsResolver.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultRouterMirrorsResolver.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultRouterMirrorsResolver.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultRouterMirrorsResolver.java Tue May 24 02:32:59 2011
@@ -0,0 +1,250 @@
+package org.apache.maven.repository.mirror;
+
+import org.apache.http.Header;
+import org.apache.http.HeaderElement;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.maven.repository.automirror.RouterMirrorSerializer;
+import org.apache.maven.repository.automirror.RouterMirrors;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.util.IOUtil;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/*
+ * 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.
+ */
+
+@Component( role = RouterMirrorsResolver.class )
+final class DefaultRouterMirrorsResolver
+    implements Initializable, RouterMirrorsResolver
+{
+
+    private boolean initialized = false;
+
+    @Requirement
+    private Logger logger;
+
+    @Requirement
+    private AutoMirrorConfiguration config;
+
+    @Requirement
+    private EMBConfiguration embConfig;
+
+    @Requirement( hint = "emb" )
+    private Prompter prompter;
+
+    private HttpClient client;
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.RouterMirrorsResolver.emb.mirror.resolve.MirrorsResolver#getMirrorMapping(java.lang.String)
+     */
+    @Override
+    public RouterMirrors getMirrorMapping( final String routerUrl )
+    {
+        if ( config.isDisabled() )
+        {
+            return new RouterMirrors();
+        }
+
+        if ( routerUrl != null && !routerUrl.isEmpty() )
+        {
+            if ( logger.isDebugEnabled() )
+            {
+                logger.debug( "Grabbing mirror mappings from: " + routerUrl.toString() );
+            }
+            System.out.println( "Grabbing mirror mappings from: " + routerUrl );
+
+            final HttpGet get = new HttpGet( routerUrl );
+            get.addHeader( "Accept", "application/json;q=0.9,*/*;q=0.8" );
+
+            try
+            {
+                return client.execute( get, new ResponseHandler<RouterMirrors>()
+                {
+                    public RouterMirrors handleResponse( final HttpResponse response )
+                        throws /* ClientProtocolException, */IOException
+                    {
+                        final int statusCode = response.getStatusLine().getStatusCode();
+                        if ( statusCode == 200 )
+                        {
+                            InputStream stream = null;
+                            try
+                            {
+                                stream = response.getEntity().getContent();
+                                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                                IOUtil.copy( stream, baos );
+
+                                String content = null;
+                                final Header contentType = response.getFirstHeader( "Content-Type" );
+                                if ( contentType != null )
+                                {
+                                    final HeaderElement[] contentTypeElts = contentType.getElements();
+
+                                    if ( contentTypeElts != null )
+                                    {
+                                        for ( final HeaderElement elt : contentTypeElts )
+                                        {
+                                            final NameValuePair nv = elt.getParameterByName( "charset" );
+                                            if ( nv != null )
+                                            {
+                                                content = new String( baos.toByteArray(), nv.getValue() );
+                                            }
+                                        }
+                                    }
+                                }
+
+                                if ( content == null )
+                                {
+                                    content = new String( baos.toByteArray() );
+                                }
+
+                                if ( logger.isDebugEnabled() )
+                                {
+                                    logger.debug( "Response code/message: '" + response.getStatusLine().getStatusCode()
+                                                    + " " + response.getStatusLine().getReasonPhrase()
+                                                    + "'\nContent is:\n\n" + content );
+                                }
+
+                                return RouterMirrorSerializer.deserialize( content );
+                            }
+                            catch ( final JsonParseException e )
+                            {
+                                logger.error( "Failed to retrieve mirror mapping from: " + routerUrl, e );
+                            }
+                            finally
+                            {
+                                close( stream );
+                            }
+                        }
+                        else if ( logger.isDebugEnabled() )
+                        {
+                            logger.debug( "Response: " + response.getStatusLine().getStatusCode() + " "
+                                            + response.getStatusLine().getReasonPhrase() );
+                        }
+
+                        return null;
+                    }
+                } );
+            }
+            catch ( final ClientProtocolException e )
+            {
+                if ( logger.isDebugEnabled() )
+                {
+                    logger.debug( "Failed to read proxied repositories from: '" + routerUrl + "'. Reason: "
+                                                  + e.getMessage(), e );
+                }
+            }
+            catch ( final IOException e )
+            {
+                if ( logger.isDebugEnabled() )
+                {
+                    logger.debug( "Failed to read proxied repositories from: '" + routerUrl + "'. Reason: "
+                                                  + e.getMessage(), e );
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     * 
+     * @see org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable#initialize()
+     */
+    @Override
+    public synchronized void initialize()
+        throws InitializationException
+    {
+        if ( initialized )
+        {
+            return;
+        }
+
+        final DefaultHttpClient client = new DefaultHttpClient();
+        this.client = client;
+
+        client.setCredentialsProvider( new CredentialsProvider()
+        {
+            private final Map<String, UsernamePasswordCredentials> cached =
+                new HashMap<String, UsernamePasswordCredentials>();
+
+            public void setCredentials( final AuthScope authscope, final Credentials credentials )
+            {
+            }
+
+            public synchronized Credentials getCredentials( final AuthScope authscope )
+            {
+                UsernamePasswordCredentials creds = config.getRouterCredentials();
+                if ( creds == null && embConfig.isInteractive() )
+                {
+                    final String key = authscope.getHost() + ":" + authscope.getPort();
+
+                    creds = cached.get( key );
+                    if ( creds == null )
+                    {
+                        final StringBuilder sb =
+                            new StringBuilder().append( authscope.getRealm() )
+                                               .append( " (" )
+                                               .append( key )
+                                               .append( ") requires authentication.\n\nUsername" );
+
+                        try
+                        {
+                            final String user = prompter.prompt( sb.toString() );
+                            final String password = prompter.promptForPassword( "Password" );
+
+                            creds = new UsernamePasswordCredentials( user, password );
+                            cached.put( key, creds );
+                        }
+                        catch ( final PrompterException e )
+                        {
+                            if ( logger.isDebugEnabled() )
+                            {
+                                logger.debug( "Failed to read credentials! Reason: " + e.getMessage(), e );
+                            }
+                        }
+                    }
+                }
+
+                return creds;
+            }
+
+            public void clear()
+            {
+            }
+        } );
+
+        initialized = true;
+    }
+}

Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/DefaultRouterMirrorsResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/MirrorRouter.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/MirrorRouter.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/MirrorRouter.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/MirrorRouter.java Tue May 24 02:32:59 2011
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 2011 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.repository.mirror;
+
+import org.apache.maven.repository.automirror.RouterMirror;
+
+public interface MirrorRouter
+{
+
+    RouterMirror getWeightedRandomSuggestion( final String canonicalUrl );
+
+}
\ No newline at end of file

Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/MirrorRouter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RouterMirrorsResolver.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RouterMirrorsResolver.java?rev=1126833&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RouterMirrorsResolver.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RouterMirrorsResolver.java Tue May 24 02:32:59 2011
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 2011 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.repository.mirror;
+
+import org.apache.maven.repository.automirror.RouterMirrors;
+
+public interface RouterMirrorsResolver
+{
+
+    RouterMirrors getMirrorMapping( final String routerUrl );
+
+}
\ No newline at end of file

Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RouterMirrorsResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/maven-3/branches/mirror-group-routing/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java?rev=1126833&r1=1126832&r2=1126833&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java Tue May 24 02:32:59 2011
@@ -94,6 +94,8 @@ public class MavenCli
         new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/settings.xml" );
 
     public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
+    
+    public static final File DEFAULT_USER_EXT_CONF_DIR = new File( userMavenConfigurationHome, "conf" );
 
     private static final String EXT_CLASS_PATH = "maven.ext.class.path";
 
@@ -926,7 +928,8 @@ public class MavenCli
             .setUpdateSnapshots( updateSnapshots ) // default: false
             .setNoSnapshotUpdates( noSnapshotUpdates ) // default: false
             .setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn
-            .setUserToolchainsFile( userToolchainsFile );
+            .setUserToolchainsFile( userToolchainsFile )
+            .setUserExtensionConfDir( MavenCli.DEFAULT_USER_EXT_CONF_DIR );
 
         if ( alternatePomFile != null )
         {

Modified: maven/maven-3/branches/mirror-group-routing/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/pom.xml?rev=1126833&r1=1126832&r2=1126833&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/pom.xml (original)
+++ maven/maven-3/branches/mirror-group-routing/pom.xml Tue May 24 02:32:59 2011
@@ -1,6 +1,5 @@
 <?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
@@ -8,9 +7,7 @@
     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/xsd/maven-4.0.0.xsd">
+  --><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/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
   <parent>
@@ -143,6 +140,7 @@
     <module>maven-model-builder</module>
     <module>maven-embedder</module>
     <module>maven-compat</module>
+    <module>maven-auto-mirror-model</module>
   </modules>
 
   <scm>
@@ -173,6 +171,11 @@
       <!--bootstrap-start-comment-->
       <dependency>
         <groupId>org.apache.maven</groupId>
+        <artifactId>maven-auto-mirror-model</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
         <artifactId>maven-model</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -341,6 +344,20 @@
         <artifactId>commons-jxpath</artifactId>
         <version>${jxpathVersion}</version>
       </dependency>
+      
+      <!-- START: Used in auto-mirror handling -->
+      <dependency>
+        <groupId>com.google.code.gson</groupId>
+        <artifactId>gson</artifactId>
+        <version>1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.httpcomponents</groupId>
+        <artifactId>httpclient</artifactId>
+        <version>4.0.2</version>
+      </dependency>
+      <!-- END: Used in auto-mirror handling -->
+      
       <dependency>
         <groupId>org.sonatype.plexus</groupId>
         <artifactId>plexus-sec-dispatcher</artifactId>
@@ -541,7 +558,7 @@
             <reportSets>
               <reportSet>
                 <!-- Disabled at it kills the site generation via a NoClassDefFoundError -->
-                <reports />
+                <reports/>
               </reportSet>
             </reportSets>
           </plugin>
@@ -593,9 +610,9 @@
             <configuration>
               <mappingId>customizable</mappingId>
               <configurators>
-                <configurator id="org.maven.ide.eclipse.jdt.javaConfigurator" />
-                <configurator id="org.maven.ide.eclipse.modello.modelloConfigurator" />
-                <configurator id="org.maven.ide.eclipse.plexus.annotations.plexusConfigurator" />
+                <configurator id="org.maven.ide.eclipse.jdt.javaConfigurator"/>
+                <configurator id="org.maven.ide.eclipse.modello.modelloConfigurator"/>
+                <configurator id="org.maven.ide.eclipse.plexus.annotations.plexusConfigurator"/>
               </configurators>
               <mojoExecutions>
                 <mojoExecution>org.apache.maven.plugins:maven-resources-plugin::</mojoExecution>
@@ -606,4 +623,4 @@
       </build>
     </profile>
   </profiles>
-</project>
+</project>
\ No newline at end of file