1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.cli.transfer;
20
21 import java.io.PrintStream;
22 import java.text.DecimalFormat;
23 import java.text.DecimalFormatSymbols;
24 import java.util.Locale;
25
26 import org.apache.commons.lang3.Validate;
27 import org.eclipse.aether.transfer.AbstractTransferListener;
28 import org.eclipse.aether.transfer.TransferCancelledException;
29 import org.eclipse.aether.transfer.TransferEvent;
30 import org.eclipse.aether.transfer.TransferResource;
31
32
33
34
35 public abstract class AbstractMavenTransferListener extends AbstractTransferListener {
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 static class FileSizeFormat {
51 enum ScaleUnit {
52 BYTE {
53 @Override
54 public long bytes() {
55 return 1L;
56 }
57
58 @Override
59 public String symbol() {
60 return "B";
61 }
62 },
63 KILOBYTE {
64 @Override
65 public long bytes() {
66 return 1000L;
67 }
68
69 @Override
70 public String symbol() {
71 return "kB";
72 }
73 },
74 MEGABYTE {
75 @Override
76 public long bytes() {
77 return KILOBYTE.bytes() * KILOBYTE.bytes();
78 }
79
80 @Override
81 public String symbol() {
82 return "MB";
83 }
84 },
85 GIGABYTE {
86 @Override
87 public long bytes() {
88 return MEGABYTE.bytes() * KILOBYTE.bytes();
89 }
90 ;
91
92 @Override
93 public String symbol() {
94 return "GB";
95 }
96 };
97
98 public abstract long bytes();
99
100 public abstract String symbol();
101
102 public static ScaleUnit getScaleUnit(long size) {
103 Validate.isTrue(size >= 0L, "file size cannot be negative: %s", size);
104
105 if (size >= GIGABYTE.bytes()) {
106 return GIGABYTE;
107 } else if (size >= MEGABYTE.bytes()) {
108 return MEGABYTE;
109 } else if (size >= KILOBYTE.bytes()) {
110 return KILOBYTE;
111 } else {
112 return BYTE;
113 }
114 }
115 }
116
117 private DecimalFormat smallFormat;
118 private DecimalFormat largeFormat;
119
120 FileSizeFormat(Locale locale) {
121 smallFormat = new DecimalFormat("#0.0", new DecimalFormatSymbols(locale));
122 largeFormat = new DecimalFormat("###0", new DecimalFormatSymbols(locale));
123 }
124
125 public String format(long size) {
126 return format(size, null);
127 }
128
129 public String format(long size, ScaleUnit unit) {
130 return format(size, unit, false);
131 }
132
133 @SuppressWarnings("checkstyle:magicnumber")
134 public String format(long size, ScaleUnit unit, boolean omitSymbol) {
135 Validate.isTrue(size >= 0L, "file size cannot be negative: %s", size);
136
137 if (unit == null) {
138 unit = ScaleUnit.getScaleUnit(size);
139 }
140
141 double scaledSize = (double) size / unit.bytes();
142 String scaledSymbol = " " + unit.symbol();
143
144 if (omitSymbol) {
145 scaledSymbol = "";
146 }
147
148 if (unit == ScaleUnit.BYTE) {
149 return largeFormat.format(size) + scaledSymbol;
150 }
151
152 if (scaledSize < 0.05 || scaledSize >= 10.0) {
153 return largeFormat.format(scaledSize) + scaledSymbol;
154 } else {
155 return smallFormat.format(scaledSize) + scaledSymbol;
156 }
157 }
158
159 public String formatProgress(long progressedSize, long size) {
160 Validate.isTrue(progressedSize >= 0L, "progressed file size cannot be negative: %s", progressedSize);
161 Validate.isTrue(
162 size < 0L || progressedSize <= size,
163 "progressed file size cannot be greater than size: %s > %s",
164 progressedSize,
165 size);
166
167 if (size >= 0L && progressedSize != size) {
168 ScaleUnit unit = ScaleUnit.getScaleUnit(size);
169 String formattedProgressedSize = format(progressedSize, unit, true);
170 String formattedSize = format(size, unit);
171
172 return formattedProgressedSize + "/" + formattedSize;
173 } else {
174 return format(progressedSize);
175 }
176 }
177 }
178
179 protected PrintStream out;
180
181 protected AbstractMavenTransferListener(PrintStream out) {
182 this.out = out;
183 }
184
185 @Override
186 public void transferInitiated(TransferEvent event) {
187 String action = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
188 String direction = event.getRequestType() == TransferEvent.RequestType.PUT ? "to" : "from";
189
190 TransferResource resource = event.getResource();
191 StringBuilder message = new StringBuilder();
192 message.append(action).append(' ').append(direction).append(' ').append(resource.getRepositoryId());
193 message.append(": ");
194 message.append(resource.getRepositoryUrl()).append(resource.getResourceName());
195
196 out.println(message.toString());
197 }
198
199 @Override
200 public void transferCorrupted(TransferEvent event) throws TransferCancelledException {
201 TransferResource resource = event.getResource();
202
203 out.println("[WARNING] " + event.getException().getMessage() + " from " + resource.getRepositoryId() + " for "
204 + resource.getRepositoryUrl() + resource.getResourceName());
205 }
206
207 @Override
208 public void transferSucceeded(TransferEvent event) {
209 String action = (event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded");
210 String direction = event.getRequestType() == TransferEvent.RequestType.PUT ? "to" : "from";
211
212 TransferResource resource = event.getResource();
213 long contentLength = event.getTransferredBytes();
214 FileSizeFormat format = new FileSizeFormat(Locale.ENGLISH);
215
216 StringBuilder message = new StringBuilder();
217 message.append(action).append(' ').append(direction).append(' ').append(resource.getRepositoryId());
218 message.append(": ");
219 message.append(resource.getRepositoryUrl()).append(resource.getResourceName());
220 message.append(" (").append(format.format(contentLength));
221
222 long duration = System.currentTimeMillis() - resource.getTransferStartTime();
223 if (duration > 0L) {
224 double bytesPerSecond = contentLength / (duration / 1000.0);
225 message.append(" at ").append(format.format((long) bytesPerSecond)).append("/s");
226 }
227
228 message.append(')');
229 out.println(message.toString());
230 }
231 }