Skip to content

Commit b0657a5

Browse files
authored
Stop proliferation of static helper IO methods (#1612)
Originally, the `PathProcessor` (before the now deprecated `FileProcessor`) was main component dealing with IO, restore this state. The proliferation of static IO helpers is just bad, as it does not allow (easy) overriding as it is the case of components. This fixes another pain point: the component interface `PathProcessor` (defined in SPI) has to have two (identical, almost) implementations: one in test-utils and one in impl. Stop this madness as well, now one "support" class is provided that implements everything and is published as component in SPI, but allows simple reusability in tests as well. And, same code is being tested finally.
1 parent 998f4dc commit b0657a5

File tree

34 files changed

+512
-205
lines changed

34 files changed

+512
-205
lines changed

maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnector.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@
5454
import org.eclipse.aether.spi.connector.transport.Transporter;
5555
import org.eclipse.aether.spi.connector.transport.TransporterProvider;
5656
import org.eclipse.aether.spi.io.ChecksumProcessor;
57+
import org.eclipse.aether.spi.io.PathProcessor;
5758
import org.eclipse.aether.transfer.ChecksumFailureException;
5859
import org.eclipse.aether.transfer.NoRepositoryConnectorException;
5960
import org.eclipse.aether.transfer.NoRepositoryLayoutException;
6061
import org.eclipse.aether.transfer.TransferEvent;
6162
import org.eclipse.aether.transfer.TransferResource;
6263
import org.eclipse.aether.util.ConfigUtils;
63-
import org.eclipse.aether.util.FileUtils;
6464
import org.eclipse.aether.util.concurrency.RunnableErrorForwarder;
6565
import org.eclipse.aether.util.concurrency.SmartExecutor;
6666
import org.eclipse.aether.util.concurrency.SmartExecutorUtils;
@@ -87,6 +87,8 @@ final class BasicRepositoryConnector implements RepositoryConnector {
8787

8888
private final Map<String, ProvidedChecksumsSource> providedChecksumsSources;
8989

90+
private final PathProcessor pathProcessor;
91+
9092
private final ChecksumProcessor checksumProcessor;
9193

9294
private final RemoteRepository repository;
@@ -113,12 +115,14 @@ final class BasicRepositoryConnector implements RepositoryConnector {
113115

114116
private final AtomicBoolean closed;
115117

118+
@SuppressWarnings("checkstyle:parameternumber")
116119
BasicRepositoryConnector(
117120
RepositorySystemSession session,
118121
RemoteRepository repository,
119122
TransporterProvider transporterProvider,
120123
RepositoryLayoutProvider layoutProvider,
121124
ChecksumPolicyProvider checksumPolicyProvider,
125+
PathProcessor pathProcessor,
122126
ChecksumProcessor checksumProcessor,
123127
Map<String, ProvidedChecksumsSource> providedChecksumsSources)
124128
throws NoRepositoryConnectorException {
@@ -140,6 +144,7 @@ final class BasicRepositoryConnector implements RepositoryConnector {
140144
this.session = session;
141145
this.repository = repository;
142146
this.checksumProcessor = checksumProcessor;
147+
this.pathProcessor = pathProcessor;
143148
this.providedChecksumsSources = providedChecksumsSources;
144149
this.executors = new ConcurrentHashMap<>();
145150
this.closed = new AtomicBoolean(false);
@@ -496,6 +501,7 @@ class GetTaskRunner extends TaskRunner implements ChecksumValidator.ChecksumFetc
496501
checksumValidator = new ChecksumValidator(
497502
file,
498503
checksumAlgorithmFactories,
504+
pathProcessor,
499505
checksumProcessor,
500506
this,
501507
checksumPolicy,
@@ -518,7 +524,7 @@ public boolean fetchChecksum(URI remote, Path local) throws Exception {
518524

519525
@Override
520526
protected void runTask() throws Exception {
521-
try (FileUtils.CollocatedTempFile tempFile = FileUtils.newTempFile(file)) {
527+
try (PathProcessor.CollocatedTempFile tempFile = pathProcessor.newTempFile(file)) {
522528
final Path tmp = tempFile.getPath();
523529
listener.setChecksumCalculator(checksumValidator.newChecksumCalculator(tmp));
524530
for (int firstTrial = 0, lastTrial = 1, trial = firstTrial; ; trial++) {

maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnectorFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
3333
import org.eclipse.aether.spi.connector.transport.TransporterProvider;
3434
import org.eclipse.aether.spi.io.ChecksumProcessor;
35+
import org.eclipse.aether.spi.io.PathProcessor;
3536
import org.eclipse.aether.transfer.NoRepositoryConnectorException;
3637

3738
import static java.util.Objects.requireNonNull;
@@ -50,6 +51,8 @@ public final class BasicRepositoryConnectorFactory implements RepositoryConnecto
5051

5152
private final ChecksumPolicyProvider checksumPolicyProvider;
5253

54+
private final PathProcessor pathProcessor;
55+
5356
private final ChecksumProcessor checksumProcessor;
5457

5558
private final Map<String, ProvidedChecksumsSource> providedChecksumsSources;
@@ -61,11 +64,13 @@ public BasicRepositoryConnectorFactory(
6164
TransporterProvider transporterProvider,
6265
RepositoryLayoutProvider layoutProvider,
6366
ChecksumPolicyProvider checksumPolicyProvider,
67+
PathProcessor pathProcessor,
6468
ChecksumProcessor checksumProcessor,
6569
Map<String, ProvidedChecksumsSource> providedChecksumsSources) {
6670
this.transporterProvider = requireNonNull(transporterProvider, "transporter provider cannot be null");
6771
this.layoutProvider = requireNonNull(layoutProvider, "repository layout provider cannot be null");
6872
this.checksumPolicyProvider = requireNonNull(checksumPolicyProvider, "checksum policy provider cannot be null");
73+
this.pathProcessor = requireNonNull(pathProcessor, "path processor cannot be null");
6974
this.checksumProcessor = requireNonNull(checksumProcessor, "checksum processor cannot be null");
7075
this.providedChecksumsSources =
7176
requireNonNull(providedChecksumsSources, "provided checksum sources cannot be null");
@@ -99,6 +104,7 @@ public RepositoryConnector newInstance(RepositorySystemSession session, RemoteRe
99104
transporterProvider,
100105
layoutProvider,
101106
checksumPolicyProvider,
107+
pathProcessor,
102108
checksumProcessor,
103109
providedChecksumsSources);
104110
}

maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumValidator.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
import org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind;
3232
import org.eclipse.aether.spi.connector.layout.RepositoryLayout.ChecksumLocation;
3333
import org.eclipse.aether.spi.io.ChecksumProcessor;
34+
import org.eclipse.aether.spi.io.PathProcessor;
3435
import org.eclipse.aether.transfer.ChecksumFailureException;
35-
import org.eclipse.aether.util.FileUtils;
3636
import org.slf4j.Logger;
3737
import org.slf4j.LoggerFactory;
3838

@@ -56,6 +56,8 @@ interface ChecksumFetcher {
5656

5757
private final Collection<ChecksumAlgorithmFactory> checksumAlgorithmFactories;
5858

59+
private final PathProcessor pathProcessor;
60+
5961
private final ChecksumProcessor checksumProcessor;
6062

6163
private final ChecksumFetcher checksumFetcher;
@@ -68,16 +70,19 @@ interface ChecksumFetcher {
6870

6971
private final Map<Path, String> checksumExpectedValues;
7072

73+
@SuppressWarnings("checkstyle:parameternumber")
7174
ChecksumValidator(
7275
Path dataPath,
7376
Collection<ChecksumAlgorithmFactory> checksumAlgorithmFactories,
77+
PathProcessor pathProcessor,
7478
ChecksumProcessor checksumProcessor,
7579
ChecksumFetcher checksumFetcher,
7680
ChecksumPolicy checksumPolicy,
7781
Map<String, String> providedChecksums,
7882
Collection<ChecksumLocation> checksumLocations) {
7983
this.dataPath = dataPath;
8084
this.checksumAlgorithmFactories = checksumAlgorithmFactories;
85+
this.pathProcessor = pathProcessor;
8186
this.checksumProcessor = checksumProcessor;
8287
this.checksumFetcher = checksumFetcher;
8388
this.checksumPolicy = checksumPolicy;
@@ -156,7 +161,7 @@ private boolean validateExternalChecksums(Map<String, ?> actualChecksums) throws
156161
continue;
157162
}
158163
Path checksumFile = getChecksumPath(checksumLocation.getChecksumAlgorithmFactory());
159-
try (FileUtils.TempFile tempFile = FileUtils.newTempFile()) {
164+
try (PathProcessor.TempFile tempFile = pathProcessor.newTempFile()) {
160165
Path tmp = tempFile.getPath();
161166
try {
162167
if (!checksumFetcher.fetchChecksum(checksumLocation.getLocation(), tmp)) {

maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/ChecksumValidatorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.eclipse.aether.spi.connector.checksum.ChecksumPolicy;
3737
import org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind;
3838
import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
39+
import org.eclipse.aether.spi.io.PathProcessorSupport;
3940
import org.eclipse.aether.transfer.ChecksumFailureException;
4041
import org.junit.jupiter.api.BeforeEach;
4142
import org.junit.jupiter.api.Test;
@@ -189,6 +190,7 @@ private ChecksumValidator newValidator(Map<String, String> providedChecksums, St
189190
return new ChecksumValidator(
190191
dataFile.toPath(),
191192
checksumAlgorithmFactories,
193+
new PathProcessorSupport(),
192194
new TestChecksumProcessor(),
193195
fetcher,
194196
policy,

maven-resolver-generator-sigstore/src/main/java/org/eclipse/aether/generator/sigstore/SigstoreSignatureArtifactGenerator.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,26 @@
3737
import org.eclipse.aether.artifact.Artifact;
3838
import org.eclipse.aether.generator.sigstore.internal.FulcioOidHelper;
3939
import org.eclipse.aether.spi.artifact.generator.ArtifactGenerator;
40-
import org.eclipse.aether.util.FileUtils;
40+
import org.eclipse.aether.spi.io.PathProcessor;
4141
import org.eclipse.aether.util.artifact.SubArtifact;
4242
import org.slf4j.Logger;
4343
import org.slf4j.LoggerFactory;
4444

4545
final class SigstoreSignatureArtifactGenerator implements ArtifactGenerator {
4646
private static final String ARTIFACT_EXTENSION = ".sigstore.json";
4747
private final Logger logger = LoggerFactory.getLogger(getClass());
48+
private final PathProcessor pathProcessor;
4849
private final ArrayList<Artifact> artifacts;
4950
private final Predicate<Artifact> signableArtifactPredicate;
5051
private final boolean publicStaging;
5152
private final ArrayList<Path> signatureTempFiles;
5253

5354
SigstoreSignatureArtifactGenerator(
54-
Collection<Artifact> artifacts, Predicate<Artifact> signableArtifactPredicate, boolean publicStaging) {
55+
PathProcessor pathProcessor,
56+
Collection<Artifact> artifacts,
57+
Predicate<Artifact> signableArtifactPredicate,
58+
boolean publicStaging) {
59+
this.pathProcessor = pathProcessor;
5560
this.artifacts = new ArrayList<>(artifacts);
5661
this.signableArtifactPredicate = signableArtifactPredicate;
5762
this.publicStaging = publicStaging;
@@ -107,7 +112,7 @@ public Collection<? extends Artifact> generate(Collection<? extends Artifact> ge
107112
+ FulcioOidHelper.getIssuerV2(cert)
108113
+ " IdP)");
109114

110-
FileUtils.writeFile(signatureTempFile, p -> Files.writeString(p, bundle.toJson()));
115+
pathProcessor.write(signatureTempFile, bundle.toJson());
111116

112117
long duration = System.currentTimeMillis() - start;
113118
logger.debug(" > Rekor entry "

maven-resolver-generator-sigstore/src/main/java/org/eclipse/aether/generator/sigstore/SigstoreSignatureArtifactGeneratorFactory.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.eclipse.aether.spi.artifact.ArtifactPredicateFactory;
3232
import org.eclipse.aether.spi.artifact.generator.ArtifactGenerator;
3333
import org.eclipse.aether.spi.artifact.generator.ArtifactGeneratorFactory;
34+
import org.eclipse.aether.spi.io.PathProcessor;
3435
import org.eclipse.aether.util.ConfigUtils;
3536

3637
@Singleton
@@ -40,10 +41,13 @@ public final class SigstoreSignatureArtifactGeneratorFactory implements Artifact
4041
public static final String NAME = "sigstore";
4142

4243
private final ArtifactPredicateFactory artifactPredicateFactory;
44+
private final PathProcessor pathProcessor;
4345

4446
@Inject
45-
public SigstoreSignatureArtifactGeneratorFactory(ArtifactPredicateFactory artifactPredicateFactory) {
47+
public SigstoreSignatureArtifactGeneratorFactory(
48+
ArtifactPredicateFactory artifactPredicateFactory, PathProcessor pathProcessor) {
4649
this.artifactPredicateFactory = artifactPredicateFactory;
50+
this.pathProcessor = pathProcessor;
4751
}
4852

4953
@Override
@@ -68,7 +72,7 @@ private ArtifactGenerator newInstance(RepositorySystemSession session, Collectio
6872
SigstoreConfigurationKeys.CONFIG_PROP_PUBLIC_STAGING);
6973

7074
return new SigstoreSignatureArtifactGenerator(
71-
artifacts, artifactPredicateFactory.newInstance(session)::hasChecksums, publicStaging);
75+
pathProcessor, artifacts, artifactPredicateFactory.newInstance(session)::hasChecksums, publicStaging);
7276
}
7377

7478
@Override

maven-resolver-generator-sigstore/src/test/java/org/eclipse/aether/generator/sigstore/SigstoreSignerFactoryTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.eclipse.aether.spi.artifact.ArtifactPredicate;
3535
import org.eclipse.aether.spi.artifact.ArtifactPredicateFactory;
3636
import org.eclipse.aether.spi.artifact.generator.ArtifactGenerator;
37+
import org.eclipse.aether.spi.io.PathProcessorSupport;
3738
import org.junit.jupiter.api.Disabled;
3839
import org.junit.jupiter.api.Test;
3940

@@ -57,7 +58,7 @@ private SigstoreSignatureArtifactGeneratorFactory createFactory() throws Excepti
5758
when(artifactPredicateFactory.newInstance(any(RepositorySystemSession.class)))
5859
.thenReturn(artifactPredicate);
5960

60-
return new SigstoreSignatureArtifactGeneratorFactory(artifactPredicateFactory);
61+
return new SigstoreSignatureArtifactGeneratorFactory(artifactPredicateFactory, new PathProcessorSupport());
6162
}
6263

6364
private RepositorySystemSession createSession() {

maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultPathProcessor.java

Lines changed: 3 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -21,95 +21,11 @@
2121
import javax.inject.Named;
2222
import javax.inject.Singleton;
2323

24-
import java.io.BufferedInputStream;
25-
import java.io.BufferedOutputStream;
26-
import java.io.IOException;
27-
import java.io.InputStream;
28-
import java.io.OutputStream;
29-
import java.nio.ByteBuffer;
30-
import java.nio.charset.StandardCharsets;
31-
import java.nio.file.AccessDeniedException;
32-
import java.nio.file.FileSystemException;
33-
import java.nio.file.Files;
34-
import java.nio.file.Path;
35-
import java.nio.file.StandardCopyOption;
36-
import java.nio.file.attribute.FileTime;
37-
38-
import org.eclipse.aether.spi.io.PathProcessor;
39-
import org.eclipse.aether.util.FileUtils;
40-
import org.slf4j.Logger;
41-
import org.slf4j.LoggerFactory;
24+
import org.eclipse.aether.spi.io.PathProcessorSupport;
4225

4326
/**
44-
* A utility class helping with file-based operations.
27+
* Exposing path processor (from SPI).
4528
*/
4629
@Singleton
4730
@Named
48-
public class DefaultPathProcessor implements PathProcessor {
49-
private final Logger logger = LoggerFactory.getLogger(getClass());
50-
51-
@Override
52-
public void setLastModified(Path path, long value) throws IOException {
53-
try {
54-
Files.setLastModifiedTime(path, FileTime.fromMillis(value));
55-
} catch (FileSystemException e) {
56-
// MRESOLVER-536: Java uses generic FileSystemException for some weird cases,
57-
// but some subclasses like AccessDeniedEx should be re-thrown
58-
if (e instanceof AccessDeniedException) {
59-
throw e;
60-
}
61-
logger.trace("Failed to set last modified date: {}", path, e);
62-
}
63-
}
64-
65-
@Override
66-
public void write(Path target, String data) throws IOException {
67-
FileUtils.writeFile(target, p -> Files.write(p, data.getBytes(StandardCharsets.UTF_8)));
68-
}
69-
70-
@Override
71-
public void write(Path target, InputStream source) throws IOException {
72-
FileUtils.writeFile(target, p -> Files.copy(source, p, StandardCopyOption.REPLACE_EXISTING));
73-
}
74-
75-
@Override
76-
public long copy(Path source, Path target, ProgressListener listener) throws IOException {
77-
try (InputStream in = new BufferedInputStream(Files.newInputStream(source));
78-
FileUtils.CollocatedTempFile tempTarget = FileUtils.newTempFile(target);
79-
OutputStream out = new BufferedOutputStream(Files.newOutputStream(tempTarget.getPath()))) {
80-
long result = copy(out, in, listener);
81-
tempTarget.move();
82-
return result;
83-
}
84-
}
85-
86-
private long copy(OutputStream os, InputStream is, ProgressListener listener) throws IOException {
87-
long total = 0L;
88-
byte[] buffer = new byte[1024 * 32];
89-
while (true) {
90-
int bytes = is.read(buffer);
91-
if (bytes < 0) {
92-
break;
93-
}
94-
95-
os.write(buffer, 0, bytes);
96-
97-
total += bytes;
98-
99-
if (listener != null && bytes > 0) {
100-
try {
101-
listener.progressed(ByteBuffer.wrap(buffer, 0, bytes));
102-
} catch (Exception e) {
103-
// too bad
104-
}
105-
}
106-
}
107-
108-
return total;
109-
}
110-
111-
@Override
112-
public void move(Path source, Path target) throws IOException {
113-
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
114-
}
115-
}
31+
public class DefaultPathProcessor extends PathProcessorSupport {}

0 commit comments

Comments
 (0)