Author: mrdon
Date: Sat Jul 19 07:19:55 2008
New Revision: 678167

URL: http://svn.apache.org/viewvc?rev=678167&view=rev
Log:
Reapplying MNG-3379 with new support for a multiple download console monitor

Modified:
    maven/sandbox/branches/maven/MNG-3379/apache-maven/pom.xml
    maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/pom.xml
    
maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
    
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/AbstractConsoleDownloadMonitor.java
    
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/BatchModeDownloadMonitor.java
    
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/ConsoleDownloadMonitor.java
    
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/AbstractConsoleDownloadMonitorTest.java
    
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/ConsoleDownloadMonitorTest.java

Modified: maven/sandbox/branches/maven/MNG-3379/apache-maven/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/apache-maven/pom.xml?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- maven/sandbox/branches/maven/MNG-3379/apache-maven/pom.xml (original)
+++ maven/sandbox/branches/maven/MNG-3379/apache-maven/pom.xml Sat Jul 19 
07:19:55 2008
@@ -89,6 +89,11 @@
                   <pattern>org.apache.commons.logging</pattern>
                 </relocation>
 
+                <!-- For maven-artifact-manager -->
+                <relocation>
+                  <pattern>edu.emory.mathcs.backport</pattern>
+                </relocation>
+
                 <!-- For jsch wagon -->
                 <relocation>
                   <pattern>com.jcraft</pattern>

Modified: maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/pom.xml?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/pom.xml 
(original)
+++ maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/pom.xml Sat 
Jul 19 07:19:55 2008
@@ -55,6 +55,11 @@
       <artifactId>wagon-provider-api</artifactId>
     </dependency>
     <dependency>
+        <groupId>backport-util-concurrent</groupId>
+        <artifactId>backport-util-concurrent</artifactId>
+        <version>3.1</version>
+    </dependency>
+    <dependency>
       <groupId>easymock</groupId>
       <artifactId>easymock</artifactId>
       <version>1.2_Java1.3</version>

Modified: 
maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- 
maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
 (original)
+++ 
maven/sandbox/branches/maven/MNG-3379/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java
 Sat Jul 19 07:19:55 2008
@@ -39,15 +39,14 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.HashMap;
 
+import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor;
+import edu.emory.mathcs.backport.java.util.concurrent.LinkedBlockingQueue;
+import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
+import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
+
 public class DefaultArtifactResolver
     extends AbstractLogEnabled
     implements ArtifactResolver
@@ -63,6 +62,13 @@
     protected ArtifactFactory artifactFactory;
 
     private ArtifactCollector artifactCollector;
+    private final ThreadPoolExecutor resolveArtifactPool;
+
+    public DefaultArtifactResolver()
+    {
+        super();
+        resolveArtifactPool = new ThreadPoolExecutor(3, 5, 3, 
TimeUnit.SECONDS, new LinkedBlockingQueue());
+    }
 
     // ----------------------------------------------------------------------
     // Implementation
@@ -301,23 +307,37 @@
                                                               localRepository, 
remoteRepositories, source, filter,
                                                               listeners );
 
-        List resolvedArtifacts = new ArrayList();
-        List missingArtifacts = new ArrayList();
+        List resolvedArtifacts = Collections.synchronizedList(new ArrayList());
+        List missingArtifacts = Collections.synchronizedList(new ArrayList());
+        CountDownLatch latch = new 
CountDownLatch(artifactResolutionResult.getArtifactResolutionNodes().size());
+        Map nodesByGroupId = new HashMap();
         for ( Iterator i = 
artifactResolutionResult.getArtifactResolutionNodes().iterator(); i.hasNext(); )
         {
             ResolutionNode node = (ResolutionNode) i.next();
-            try
+            List nodes = (List) 
nodesByGroupId.get(node.getArtifact().getGroupId());
+            if (nodes == null)
             {
-                resolve( node.getArtifact(), node.getRemoteRepositories(), 
localRepository );
-                resolvedArtifacts.add( node.getArtifact() );
+                nodes = new ArrayList();
+                nodesByGroupId.put(node.getArtifact().getGroupId(), nodes);
             }
-            catch ( ArtifactNotFoundException anfe )
-            {
-                getLogger().debug( anfe.getMessage(), anfe );
+            nodes.add(node);
+        }
 
-                missingArtifacts.add( node.getArtifact() );
+        try {
+            for (Iterator i = nodesByGroupId.values().iterator(); i.hasNext(); 
)
+            {
+                List nodes = (List) i.next();
+                resolveArtifactPool.execute(new 
ResolveArtifactTask(resolveArtifactPool, latch, nodes, localRepository, 
resolvedArtifacts, missingArtifacts));
             }
-        }
+            latch.await();
+        } catch (InterruptedException e) {
+            throw new ArtifactResolutionException("Resolution interrupted", 
null, e);
+        } catch (RuntimeException ex) {
+            if (ex.getCause() instanceof ArtifactResolutionException)
+                throw (ArtifactResolutionException) ex.getCause();
+            else
+                throw ex;
+        } 
 
         if ( missingArtifacts.size() > 0 )
         {
@@ -357,4 +377,51 @@
                                     remoteRepositories, source, null, 
listeners );
     }
 
+    private class ResolveArtifactTask implements Runnable {
+        private List nodes;
+        private ArtifactRepository localRepository;
+        private List resolvedArtifacts;
+        private List missingArtifacts;
+        private CountDownLatch latch;
+        private ThreadPoolExecutor pool;
+
+        public ResolveArtifactTask(ThreadPoolExecutor pool, CountDownLatch 
latch, List nodes, ArtifactRepository localRepository, List resolvedArtifacts, 
List missingArtifacts) {
+            this.nodes = nodes;
+            this.localRepository = localRepository;
+            this.resolvedArtifacts =  resolvedArtifacts;
+            this.missingArtifacts = missingArtifacts;
+            this.latch = latch;
+            this.pool = pool;
+        }
+
+        public void run() {
+            //getLogger().info("Size of nodes: "+nodes.size()+" on thread: 
"+Thread.currentThread().getId());
+            Iterator i = nodes.iterator();
+            ResolutionNode node = (ResolutionNode) i.next();
+            i.remove();
+            try {
+                resolveArtifact(node);
+                if (i.hasNext())
+                    pool.execute(new ResolveArtifactTask(pool, latch, nodes, 
localRepository, resolvedArtifacts, missingArtifacts));
+            } catch (ArtifactResolutionException e) {
+                throw new RuntimeException(e);
+            }
+            latch.countDown();
+        }
+
+        private void resolveArtifact(ResolutionNode node) throws 
ArtifactResolutionException {
+            try
+                {
+                    resolve( node.getArtifact(), node.getRemoteRepositories(), 
localRepository );
+                    resolvedArtifacts.add( node.getArtifact() );
+            }
+            catch ( ArtifactNotFoundException anfe )
+            {
+                getLogger().debug( anfe.getMessage(), anfe );
+
+                missingArtifacts.add( node.getArtifact() );
+            }
+        }
+    }
+
 }

Modified: 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/AbstractConsoleDownloadMonitor.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/AbstractConsoleDownloadMonitor.java?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/AbstractConsoleDownloadMonitor.java
 (original)
+++ 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/AbstractConsoleDownloadMonitor.java
 Sat Jul 19 07:19:55 2008
@@ -24,6 +24,8 @@
 import org.apache.maven.wagon.events.TransferListener;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 
+import java.io.PrintStream;
+
 /**
  * Abstract console download progress meter.
  * 
@@ -36,6 +38,8 @@
     implements TransferListener
 {
 
+    PrintStream out = System.out;
+
     public void transferInitiated( TransferEvent transferEvent )
     {
         String message = transferEvent.getRequestType() == 
TransferEvent.REQUEST_PUT ? "Uploading" : "Downloading";
@@ -43,7 +47,7 @@
         String url = transferEvent.getWagon().getRepository().getUrl();
 
         // TODO: can't use getLogger() because this isn't currently 
instantiated as a component
-        System.out.println( message + ": " + url + "/" + 
transferEvent.getResource().getName() );
+        out.println( message + ": " + url + "/" + 
transferEvent.getResource().getName() );
     }
 
     /**
@@ -69,14 +73,14 @@
         {
             String type = ( transferEvent.getRequestType() == 
TransferEvent.REQUEST_PUT ? "uploaded" : "downloaded" );
             String l = contentLength >= 1024 ? ( contentLength / 1024 ) + "K" 
: contentLength + "b";
-            System.out.println( l + " " + type );
+            out.println( l + " " + type + "                                  
");
         }
     }
 
     public void transferError( TransferEvent transferEvent )
     {
         // TODO: can't use getLogger() because this isn't currently 
instantiated as a component
-        transferEvent.getException().printStackTrace();
+        transferEvent.getException().printStackTrace(out);
     }
 
     /**

Modified: 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/BatchModeDownloadMonitor.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/BatchModeDownloadMonitor.java?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/BatchModeDownloadMonitor.java
 (original)
+++ 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/BatchModeDownloadMonitor.java
 Sat Jul 19 07:19:55 2008
@@ -37,6 +37,6 @@
         String url = transferEvent.getWagon().getRepository().getUrl();
 
         // TODO: can't use getLogger() because this isn't currently 
instantiated as a component
-        System.out.println( message + ": " + url + "/" + 
transferEvent.getResource().getName() );
+        out.println( message + ": " + url + "/" + 
transferEvent.getResource().getName() );
     }
 }

Modified: 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/ConsoleDownloadMonitor.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/ConsoleDownloadMonitor.java?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/ConsoleDownloadMonitor.java
 (original)
+++ 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/main/java/org/apache/maven/cli/ConsoleDownloadMonitor.java
 Sat Jul 19 07:19:55 2008
@@ -20,10 +20,13 @@
  */
 
 import org.apache.maven.wagon.WagonConstants;
+import org.apache.maven.wagon.resource.Resource;
 import org.apache.maven.wagon.events.TransferEvent;
 
+import java.util.*;
+
 /**
- * Console download progress meter.
+ * Console download progress meter.  Properly handles multiple downloads 
simultaneously.
  *
  * @author <a href="mailto:[EMAIL PROTECTED]">Brett Porter</a>
  * @version $Id$
@@ -31,7 +34,12 @@
 public class ConsoleDownloadMonitor
     extends AbstractConsoleDownloadMonitor
 {
-    private long complete;
+    private Map/*<Resource,Integer>*/ downloads;
+
+    public ConsoleDownloadMonitor()
+    {
+        downloads = new LinkedHashMap();
+    }
 
     public void transferInitiated( TransferEvent transferEvent )
     {
@@ -40,9 +48,8 @@
         String url = transferEvent.getWagon().getRepository().getUrl();
 
         // TODO: can't use getLogger() because this isn't currently 
instantiated as a component
-        System.out.println( message + ": " + url + "/" + 
transferEvent.getResource().getName() );
+        out.println( message + ": " + url + "/" + 
transferEvent.getResource().getName() );
 
-        complete = 0;
     }
 
     public void transferStarted( TransferEvent transferEvent )
@@ -50,21 +57,49 @@
         // This space left intentionally blank
     }
 
-    public void transferProgress( TransferEvent transferEvent, byte[] buffer, 
int length )
+    public synchronized void transferProgress( TransferEvent transferEvent, 
byte[] buffer, int length )
+    {
+        Resource resource = transferEvent.getResource();
+        if (!downloads.containsKey(resource))
+        {
+            downloads.put(resource, new Long(length));
+        } else
+        {
+            Long complete = (Long) downloads.get(resource);
+            complete = new Long(complete.longValue() + length);
+            downloads.put(resource, complete);
+        }
+
+        for (Iterator i = downloads.entrySet().iterator(); i.hasNext(); )
+        {
+            Map.Entry entry = (Map.Entry) i.next();
+            Long complete = (Long)entry.getValue();
+            String status = getDownloadStatusForResource(complete.longValue(), 
((Resource)entry.getKey()).getContentLength());
+            out.print(status);
+            if (i.hasNext())
+            {
+                out.print(" ");
+            }
+        }
+        out.print("\r");
+    }
+
+    String getDownloadStatusForResource(long progress, long total)
     {
-        long total = transferEvent.getResource().getContentLength();
-        complete += length;
-        // TODO [BP]: Sys.out may no longer be appropriate, but will \r work 
with getLogger()?
         if ( total >= 1024 )
         {
-            System.out.print(
-                ( complete / 1024 ) + "/" + ( total == 
WagonConstants.UNKNOWN_LENGTH ? "?" : ( total / 1024 ) + "K" ) +
-                    "\r" );
+            return (progress / 1024 ) + "/" + ( total == 
WagonConstants.UNKNOWN_LENGTH ? "?" : ( total / 1024 ) + "K");
         }
         else
         {
-            System.out.print( complete + "/" + ( total == 
WagonConstants.UNKNOWN_LENGTH ? "?" : total + "b" ) + "\r" );
+            return progress + "/" + ( total == WagonConstants.UNKNOWN_LENGTH ? 
"?" : total + "b" );
         }
     }
+
+    public synchronized void transferCompleted( TransferEvent transferEvent )
+    {
+        super.transferCompleted(transferEvent);
+        downloads.remove(transferEvent.getResource());
+    }
 }
 

Modified: 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/AbstractConsoleDownloadMonitorTest.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/AbstractConsoleDownloadMonitorTest.java?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/AbstractConsoleDownloadMonitorTest.java
 (original)
+++ 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/AbstractConsoleDownloadMonitorTest.java
 Sat Jul 19 07:19:55 2008
@@ -38,7 +38,7 @@
     extends TestCase
 {
 
-    private AbstractConsoleDownloadMonitor monitor;
+    protected AbstractConsoleDownloadMonitor monitor;
 
     public AbstractConsoleDownloadMonitorTest()
     {
@@ -92,9 +92,10 @@
         monitor.debug( "msg" );
     }
 
-    private class TransferEventMock
+    static class TransferEventMock
         extends TransferEvent
     {
+
         public TransferEventMock()
             throws ConnectionException, AuthenticationException
         {
@@ -104,6 +105,15 @@
             getWagon().connect( repository );
         }
 
+        public TransferEventMock(Resource resource, int length)
+            throws ConnectionException, AuthenticationException
+        {
+            super( new FileWagon(), resource, 
TransferEvent.TRANSFER_INITIATED, TransferEvent.REQUEST_GET );
+            getResource().setContentLength(length);
+            Repository repository = new Repository();
+            getWagon().connect( repository );
+        }
+
         public TransferEventMock( Exception exception )
             throws ConnectionException, AuthenticationException
         {

Modified: 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/ConsoleDownloadMonitorTest.java
URL: 
http://svn.apache.org/viewvc/maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/ConsoleDownloadMonitorTest.java?rev=678167&r1=678166&r2=678167&view=diff
==============================================================================
--- 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/ConsoleDownloadMonitorTest.java
 (original)
+++ 
maven/sandbox/branches/maven/MNG-3379/maven-core/src/test/java/org/apache/maven/cli/ConsoleDownloadMonitorTest.java
 Sat Jul 19 07:19:55 2008
@@ -1,5 +1,12 @@
 package org.apache.maven.cli;
 
+import org.apache.maven.wagon.resource.Resource;
+import org.apache.maven.wagon.WagonConstants;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.io.PrintStream;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -28,11 +35,48 @@
 public class ConsoleDownloadMonitorTest
     extends AbstractConsoleDownloadMonitorTest
 {
-
+    ByteArrayOutputStream bout;
     protected void setUp()
         throws Exception
     {
         super.setMonitor( new ConsoleDownloadMonitor() );
         super.setUp();
+        bout = new ByteArrayOutputStream();
+        monitor.out = new PrintStream(bout);
+    }
+
+    public void testTransferProgress()
+        throws Exception
+    {
+        byte[] buffer = new byte[1024];
+        monitor.transferProgress( new TransferEventMock(new Resource(), 
10000), buffer, 1024 );
+        assertEquals("1/9K\r", new String(bout.toByteArray()));
+    }
+
+    public void testTransferProgressTwoFiles()
+        throws Exception
+    {
+        byte[] buffer = new byte[2048];
+        monitor.transferProgress( new TransferEventMock(new Resource("foo"), 
10000), buffer, 1024 );
+        assertEquals("1/9K\r", new String(bout.toByteArray()));
+        bout.reset();
+        monitor.transferProgress( new TransferEventMock(new Resource("bar"), 
10000), buffer, 2048 );
+        assertEquals("1/9K 2/9K\r", new String(bout.toByteArray()));
+        bout.reset();
+        monitor.transferProgress( new TransferEventMock(new Resource("bar"), 
10000), buffer, 2048 );
+        assertEquals("1/9K 4/9K\r", new String(bout.toByteArray()));
+        bout.reset();
+        monitor.transferProgress( new TransferEventMock(new Resource("foo"), 
10000), buffer, 2048 );
+        assertEquals("3/9K 4/9K\r", new String(bout.toByteArray()));
+    }
+
+    public void testGetDownloadStatusForResource() 
+    {
+        ConsoleDownloadMonitor cm = (ConsoleDownloadMonitor)monitor;
+        assertEquals("200/400b", cm.getDownloadStatusForResource(200, 400));
+        assertEquals("1/2K", cm.getDownloadStatusForResource(1024, 2048));
+        assertEquals("0/2K", cm.getDownloadStatusForResource(10, 2048));
+        assertEquals("10/?", cm.getDownloadStatusForResource(10, 
WagonConstants.UNKNOWN_LENGTH));
+        assertEquals("1024/?", cm.getDownloadStatusForResource(1024, 
WagonConstants.UNKNOWN_LENGTH));
     }
 }


Reply via email to