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