Skip to content

Commit 083716d

Browse files
authored
[MNG-8150] Backport TransferListener improvements for Maven 3.9.x (#1576)
Backporting #1575 to Maven 3.9.x. - [x] I hereby declare this contribution to be licenced under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) --- https://issues.apache.org/jira/browse/MNG-8150
1 parent 02927b7 commit 083716d

File tree

4 files changed

+139
-23
lines changed

4 files changed

+139
-23
lines changed

maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
*/
3737
public class ConsoleMavenTransferListener extends AbstractMavenTransferListener {
3838

39-
private final Map<TransferResource, Long> transfers =
40-
Collections.synchronizedMap(new LinkedHashMap<TransferResource, Long>());
39+
private final Map<TransferResourceIdentifier, TransferResourceAndSize> transfers =
40+
Collections.synchronizedMap(new LinkedHashMap<TransferResourceIdentifier, TransferResourceAndSize>());
4141

4242
private final boolean printResourceNames;
4343
private int lastLength;
@@ -64,19 +64,20 @@ public void transferCorrupted(TransferEvent event) throws TransferCancelledExcep
6464
@Override
6565
public void transferProgressed(TransferEvent event) throws TransferCancelledException {
6666
TransferResource resource = event.getResource();
67-
transfers.put(resource, event.getTransferredBytes());
67+
transfers.put(
68+
new TransferResourceIdentifier(resource),
69+
new TransferResourceAndSize(resource, event.getTransferredBytes()));
6870

6971
StringBuilder buffer = new StringBuilder(128);
7072
buffer.append("Progress (").append(transfers.size()).append("): ");
7173

7274
synchronized (transfers) {
73-
Iterator<Map.Entry<TransferResource, Long>> entries =
74-
transfers.entrySet().iterator();
75+
Iterator<TransferResourceAndSize> entries = transfers.values().iterator();
7576
while (entries.hasNext()) {
76-
Map.Entry<TransferResource, Long> entry = entries.next();
77-
long total = entry.getKey().getContentLength();
78-
Long complete = entry.getValue();
79-
buffer.append(getStatus(entry.getKey().getResourceName(), complete, total));
77+
TransferResourceAndSize entry = entries.next();
78+
long total = entry.resource.getContentLength();
79+
Long complete = entry.transferredBytes;
80+
buffer.append(getStatus(entry.resource.getResourceName(), complete, total));
8081
if (entries.hasNext()) {
8182
buffer.append(" | ");
8283
}
@@ -131,15 +132,15 @@ private void pad(StringBuilder buffer, int spaces) {
131132

132133
@Override
133134
public void transferSucceeded(TransferEvent event) {
134-
transfers.remove(event.getResource());
135+
transfers.remove(new TransferResourceIdentifier(event.getResource()));
135136
overridePreviousTransfer(event);
136137

137138
super.transferSucceeded(event);
138139
}
139140

140141
@Override
141142
public void transferFailed(TransferEvent event) {
142-
transfers.remove(event.getResource());
143+
transfers.remove(new TransferResourceIdentifier(event.getResource()));
143144
overridePreviousTransfer(event);
144145

145146
super.transferFailed(event);
@@ -155,4 +156,15 @@ private void overridePreviousTransfer(TransferEvent event) {
155156
lastLength = 0;
156157
}
157158
}
159+
160+
private final class TransferResourceAndSize {
161+
162+
private final TransferResource resource;
163+
private final long transferredBytes;
164+
165+
private TransferResourceAndSize(TransferResource resource, long transferredBytes) {
166+
this.resource = resource;
167+
this.transferredBytes = transferredBytes;
168+
}
169+
}
158170
}

maven-embedder/src/main/java/org/apache/maven/cli/transfer/SimplexTransferListener.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
*/
1919
package org.apache.maven.cli.transfer;
2020

21-
import java.io.File;
2221
import java.util.ArrayList;
2322
import java.util.List;
2423
import java.util.concurrent.ArrayBlockingQueue;
@@ -129,7 +128,7 @@ private void demux(List<Exchange> exchanges) {
129128
LOGGER.warn("Invalid TransferEvent.EventType={}; ignoring it", type);
130129
}
131130
} catch (TransferCancelledException e) {
132-
ongoing.put(transferEvent.getResource().getFile(), Boolean.FALSE);
131+
ongoing.put(new TransferResourceIdentifier(transferEvent.getResource()), Boolean.FALSE);
133132
}
134133
});
135134
}
@@ -150,47 +149,47 @@ private void put(TransferEvent event, boolean last) {
150149
}
151150
}
152151

153-
private final ConcurrentHashMap<File, Boolean> ongoing = new ConcurrentHashMap<>();
152+
private final ConcurrentHashMap<TransferResourceIdentifier, Boolean> ongoing = new ConcurrentHashMap<>();
154153

155154
@Override
156155
public void transferInitiated(TransferEvent event) {
157-
ongoing.putIfAbsent(event.getResource().getFile(), Boolean.TRUE);
156+
ongoing.putIfAbsent(new TransferResourceIdentifier(event.getResource()), Boolean.TRUE);
158157
put(event, false);
159158
}
160159

161160
@Override
162161
public void transferStarted(TransferEvent event) throws TransferCancelledException {
163-
if (ongoing.get(event.getResource().getFile()) == Boolean.FALSE) {
162+
if (ongoing.get(new TransferResourceIdentifier(event.getResource())) == Boolean.FALSE) {
164163
throw new TransferCancelledException();
165164
}
166165
put(event, false);
167166
}
168167

169168
@Override
170169
public void transferProgressed(TransferEvent event) throws TransferCancelledException {
171-
if (ongoing.get(event.getResource().getFile()) == Boolean.FALSE) {
170+
if (ongoing.get(new TransferResourceIdentifier(event.getResource())) == Boolean.FALSE) {
172171
throw new TransferCancelledException();
173172
}
174173
put(event, false);
175174
}
176175

177176
@Override
178177
public void transferCorrupted(TransferEvent event) throws TransferCancelledException {
179-
if (ongoing.get(event.getResource().getFile()) == Boolean.FALSE) {
178+
if (ongoing.get(new TransferResourceIdentifier(event.getResource())) == Boolean.FALSE) {
180179
throw new TransferCancelledException();
181180
}
182181
put(event, false);
183182
}
184183

185184
@Override
186185
public void transferSucceeded(TransferEvent event) {
187-
ongoing.remove(event.getResource().getFile());
186+
ongoing.remove(new TransferResourceIdentifier(event.getResource()));
188187
put(event, ongoing.isEmpty());
189188
}
190189

191190
@Override
192191
public void transferFailed(TransferEvent event) {
193-
ongoing.remove(event.getResource().getFile());
192+
ongoing.remove(new TransferResourceIdentifier(event.getResource()));
194193
put(event, ongoing.isEmpty());
195194
}
196195

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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.cli.transfer;
20+
21+
import java.io.File;
22+
import java.util.Objects;
23+
24+
import org.eclipse.aether.transfer.TransferResource;
25+
import org.eclipse.sisu.Nullable;
26+
27+
/**
28+
* Immutable identifier of a {@link TransferResource}.
29+
* The {@link TransferResource} is not immutable and does not implement {@code Objects#equals} and {@code Objects#hashCode} methods,
30+
* making it not very suitable for usage in collections.
31+
*/
32+
final class TransferResourceIdentifier {
33+
34+
private final String repositoryId;
35+
private final String repositoryUrl;
36+
private final String resourceName;
37+
38+
@Nullable
39+
private final File file;
40+
41+
private TransferResourceIdentifier(
42+
String repositoryId, String repositoryUrl, String resourceName, @Nullable File file) {
43+
this.repositoryId = repositoryId;
44+
this.repositoryUrl = repositoryUrl;
45+
this.resourceName = resourceName;
46+
this.file = file;
47+
}
48+
49+
TransferResourceIdentifier(TransferResource resource) {
50+
this(resource.getRepositoryId(), resource.getRepositoryUrl(), resource.getResourceName(), resource.getFile());
51+
}
52+
53+
@Override
54+
public boolean equals(Object obj) {
55+
if (obj == this) {
56+
return true;
57+
}
58+
59+
if (obj == null || obj.getClass() != this.getClass()) {
60+
return false;
61+
}
62+
63+
TransferResourceIdentifier that = (TransferResourceIdentifier) obj;
64+
return Objects.equals(this.repositoryId, that.repositoryId)
65+
&& Objects.equals(this.repositoryUrl, that.repositoryUrl)
66+
&& Objects.equals(this.resourceName, that.resourceName)
67+
&& Objects.equals(this.file, that.file);
68+
}
69+
70+
@Override
71+
public int hashCode() {
72+
return Objects.hash(repositoryId, repositoryUrl, resourceName, file);
73+
}
74+
}

maven-embedder/src/test/java/org/apache/maven/cli/transfer/SimplexTransferListenerTest.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
import java.io.File;
2222

2323
import org.eclipse.aether.DefaultRepositorySystemSession;
24+
import org.eclipse.aether.RepositorySystemSession;
2425
import org.eclipse.aether.transfer.TransferCancelledException;
2526
import org.eclipse.aether.transfer.TransferEvent;
2627
import org.eclipse.aether.transfer.TransferListener;
2728
import org.eclipse.aether.transfer.TransferResource;
2829
import org.junit.Test;
30+
import org.mockito.Mockito;
2931

3032
import static org.junit.Assert.fail;
3133

@@ -67,9 +69,7 @@ public void transferFailed(TransferEvent event) {}
6769
DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
6870

6971
// for technical reasons we cannot throw here, even if delegate does cancel transfer
70-
listener.transferInitiated(new TransferEvent.Builder(session, resource)
71-
.setType(TransferEvent.EventType.INITIATED)
72-
.build());
72+
listener.transferInitiated(event(session, resource, TransferEvent.EventType.INITIATED));
7373

7474
Thread.sleep(500); // to make sure queue is processed, cancellation applied
7575

@@ -83,4 +83,35 @@ public void transferFailed(TransferEvent event) {}
8383
// good
8484
}
8585
}
86+
87+
@Test
88+
public void handlesAbsentTransferSource() throws InterruptedException, TransferCancelledException {
89+
TransferResource resource = new TransferResource(null, null, "http://maven.org/test/test-resource", null, null);
90+
91+
RepositorySystemSession session = Mockito.mock(RepositorySystemSession.class);
92+
TransferListener delegate = Mockito.mock(TransferListener.class);
93+
SimplexTransferListener listener = new SimplexTransferListener(delegate);
94+
95+
TransferEvent transferInitiatedEvent = event(session, resource, TransferEvent.EventType.INITIATED);
96+
TransferEvent transferStartedEvent = event(session, resource, TransferEvent.EventType.STARTED);
97+
TransferEvent transferProgressedEvent = event(session, resource, TransferEvent.EventType.PROGRESSED);
98+
TransferEvent transferSucceededEvent = event(session, resource, TransferEvent.EventType.SUCCEEDED);
99+
100+
listener.transferInitiated(transferInitiatedEvent);
101+
listener.transferStarted(transferStartedEvent);
102+
listener.transferProgressed(transferProgressedEvent);
103+
listener.transferSucceeded(transferSucceededEvent);
104+
105+
Thread.sleep(500); // to make sure queue is processed, cancellation applied
106+
107+
Mockito.verify(delegate).transferInitiated(transferInitiatedEvent);
108+
Mockito.verify(delegate).transferStarted(transferStartedEvent);
109+
Mockito.verify(delegate).transferProgressed(transferProgressedEvent);
110+
Mockito.verify(delegate).transferSucceeded(transferSucceededEvent);
111+
}
112+
113+
private static TransferEvent event(
114+
RepositorySystemSession session, TransferResource resource, TransferEvent.EventType type) {
115+
return new TransferEvent.Builder(session, resource).setType(type).build();
116+
}
86117
}

0 commit comments

Comments
 (0)