View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.repository.internal.util;
20  
21  import java.io.PrintStream;
22  import java.text.DecimalFormat;
23  import java.text.DecimalFormatSymbols;
24  import java.util.Locale;
25  import java.util.Map;
26  import java.util.concurrent.ConcurrentHashMap;
27  
28  import org.eclipse.aether.transfer.AbstractTransferListener;
29  import org.eclipse.aether.transfer.TransferEvent;
30  import org.eclipse.aether.transfer.TransferResource;
31  
32  public class ConsoleTransferListener extends AbstractTransferListener {
33  
34      private PrintStream out;
35  
36      private Map<TransferResource, Long> downloads = new ConcurrentHashMap<>();
37  
38      private int lastLength;
39  
40      public ConsoleTransferListener() {
41          this(null);
42      }
43  
44      public ConsoleTransferListener(PrintStream out) {
45          this.out = (out != null) ? out : System.out;
46      }
47  
48      @Override
49      public void transferInitiated(TransferEvent event) {
50          String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
51  
52          println(
53                  "transferInitiated",
54                  message + ": " + event.getResource().getRepositoryUrl()
55                          + event.getResource().getResourceName());
56      }
57  
58      @Override
59      public void transferProgressed(TransferEvent event) {
60          TransferResource resource = event.getResource();
61          downloads.put(resource, event.getTransferredBytes());
62  
63          StringBuilder buffer = new StringBuilder(64);
64  
65          for (Map.Entry<TransferResource, Long> entry : downloads.entrySet()) {
66              long total = entry.getKey().getContentLength();
67              long complete = entry.getValue();
68  
69              buffer.append(getStatus(complete, total)).append("  ");
70          }
71  
72          int pad = lastLength - buffer.length();
73          lastLength = buffer.length();
74          pad(buffer, pad);
75          buffer.append('\r');
76  
77          print("transferProgressed", buffer.toString());
78      }
79  
80      private String getStatus(long complete, long total) {
81          if (total >= 1024) {
82              return toKB(complete) + "/" + toKB(total) + " KB ";
83          } else if (total >= 0) {
84              return complete + "/" + total + " B ";
85          } else if (complete >= 1024) {
86              return toKB(complete) + " KB ";
87          } else {
88              return complete + " B ";
89          }
90      }
91  
92      private void pad(StringBuilder buffer, int spaces) {
93          String block = "                                        ";
94          while (spaces > 0) {
95              int n = Math.min(spaces, block.length());
96              buffer.append(block, 0, n);
97              spaces -= n;
98          }
99      }
100 
101     @Override
102     public void transferSucceeded(TransferEvent event) {
103         transferCompleted(event);
104 
105         TransferResource resource = event.getResource();
106         long contentLength = event.getTransferredBytes();
107         if (contentLength >= 0) {
108             String type = (event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded");
109             String len = contentLength >= 1024 ? toKB(contentLength) + " KB" : contentLength + " B";
110 
111             String throughput = "";
112             long duration = System.currentTimeMillis() - resource.getTransferStartTime();
113             if (duration > 0) {
114                 DecimalFormat format = new DecimalFormat("0.0", new DecimalFormatSymbols(Locale.ENGLISH));
115                 double kbPerSec = (contentLength / 1024.0) / (duration / 1000.0);
116                 throughput = " at " + format.format(kbPerSec) + " KB/sec";
117             }
118 
119             println(
120                     "transferSucceeded",
121                     type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len + throughput
122                             + ")");
123         }
124     }
125 
126     @Override
127     public void transferFailed(TransferEvent event) {
128         transferCompleted(event);
129 
130         println(
131                 "transferFailed",
132                 event.getException().getClass() + ": " + event.getException().getMessage());
133     }
134 
135     private void transferCompleted(TransferEvent event) {
136         downloads.remove(event.getResource());
137 
138         StringBuilder buffer = new StringBuilder(64);
139         pad(buffer, lastLength);
140         buffer.append('\r');
141         out.println(buffer);
142     }
143 
144     @Override
145     public void transferCorrupted(TransferEvent event) {
146         println(
147                 "transferCorrupted",
148                 event.getException().getClass() + ": " + event.getException().getMessage());
149     }
150 
151     protected long toKB(long bytes) {
152         return (bytes + 1023) / 1024;
153     }
154 
155     private void println(String event, String message) {
156         print(event, message);
157         out.println();
158     }
159 
160     private void print(String event, String message) {
161         out.print("Aether Transfer - " + event);
162         if (message != null) {
163             out.print(": ");
164             out.print(message);
165         }
166     }
167 }