1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.impl;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.*;
26 import java.nio.ByteBuffer;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.util.*;
30 import java.util.stream.Collectors;
31
32 import org.apache.maven.api.services.*;
33 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
34 import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
35
36 import static org.apache.maven.internal.impl.Utils.nonNull;
37
38 @Named
39 @Singleton
40 public class DefaultChecksumAlgorithmService implements ChecksumAlgorithmService {
41 private final ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
42
43 @Inject
44 public DefaultChecksumAlgorithmService(ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector) {
45 this.checksumAlgorithmFactorySelector =
46 nonNull(checksumAlgorithmFactorySelector, "checksumAlgorithmFactorySelector");
47 }
48
49 @Override
50 public Collection<String> getChecksumAlgorithmNames() {
51 return checksumAlgorithmFactorySelector.getChecksumAlgorithmFactories().stream()
52 .map(ChecksumAlgorithmFactory::getName)
53 .collect(Collectors.toList());
54 }
55
56 @Override
57 public ChecksumAlgorithm select(String algorithmName) {
58 nonNull(algorithmName, "algorithmName");
59 try {
60 return new DefaultChecksumAlgorithm(checksumAlgorithmFactorySelector.select(algorithmName));
61 } catch (IllegalArgumentException e) {
62 throw new ChecksumAlgorithmServiceException("unsupported algorithm", e);
63 }
64 }
65
66 @Override
67 public Collection<ChecksumAlgorithm> select(Collection<String> algorithmNames) {
68 nonNull(algorithmNames, "algorithmNames");
69 try {
70 return checksumAlgorithmFactorySelector.selectList(new ArrayList<>(algorithmNames)).stream()
71 .map(DefaultChecksumAlgorithm::new)
72 .collect(Collectors.toList());
73 } catch (IllegalArgumentException e) {
74 throw new ChecksumAlgorithmServiceException("unsupported algorithm", e);
75 }
76 }
77
78 @Override
79 public Map<ChecksumAlgorithm, String> calculate(byte[] data, Collection<ChecksumAlgorithm> algorithms) {
80 nonNull(data, "data");
81 nonNull(algorithms, "algorithms");
82 try {
83 return calculate(new ByteArrayInputStream(data), algorithms);
84 } catch (IOException e) {
85 throw new UncheckedIOException(e);
86 }
87 }
88
89 @Override
90 public Map<ChecksumAlgorithm, String> calculate(ByteBuffer data, Collection<ChecksumAlgorithm> algorithms) {
91 nonNull(data, "data");
92 nonNull(algorithms, "algorithms");
93 LinkedHashMap<ChecksumAlgorithm, ChecksumCalculator> algMap = new LinkedHashMap<>();
94 algorithms.forEach(f -> algMap.put(f, f.getCalculator()));
95 data.mark();
96 for (ChecksumCalculator checksumCalculator : algMap.values()) {
97 checksumCalculator.update(data);
98 data.reset();
99 }
100 LinkedHashMap<ChecksumAlgorithm, String> result = new LinkedHashMap<>();
101 algMap.forEach((k, v) -> result.put(k, v.checksum()));
102 return result;
103 }
104
105 @Override
106 public Map<ChecksumAlgorithm, String> calculate(Path file, Collection<ChecksumAlgorithm> algorithms)
107 throws IOException {
108 nonNull(file, "file");
109 nonNull(algorithms, "algorithms");
110 try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(file))) {
111 return calculate(inputStream, algorithms);
112 }
113 }
114
115 @Override
116 public Map<ChecksumAlgorithm, String> calculate(InputStream stream, Collection<ChecksumAlgorithm> algorithms)
117 throws IOException {
118 nonNull(stream, "stream");
119 nonNull(algorithms, "algorithms");
120 LinkedHashMap<ChecksumAlgorithm, ChecksumCalculator> algMap = new LinkedHashMap<>();
121 algorithms.forEach(f -> algMap.put(f, f.getCalculator()));
122 final byte[] buffer = new byte[1024 * 32];
123 for (; ; ) {
124 int read = stream.read(buffer);
125 if (read < 0) {
126 break;
127 }
128 for (ChecksumCalculator checksumCalculator : algMap.values()) {
129 checksumCalculator.update(ByteBuffer.wrap(buffer, 0, read));
130 }
131 }
132 LinkedHashMap<ChecksumAlgorithm, String> result = new LinkedHashMap<>();
133 algMap.forEach((k, v) -> result.put(k, v.checksum()));
134 return result;
135 }
136
137 private static class DefaultChecksumAlgorithm implements ChecksumAlgorithm {
138 private final ChecksumAlgorithmFactory factory;
139
140 DefaultChecksumAlgorithm(ChecksumAlgorithmFactory factory) {
141 this.factory = factory;
142 }
143
144 @Override
145 public String getName() {
146 return factory.getName();
147 }
148
149 @Override
150 public String getFileExtension() {
151 return factory.getFileExtension();
152 }
153
154 @Override
155 public ChecksumCalculator getCalculator() {
156 return new DefaultChecksumCalculator(factory.getAlgorithm());
157 }
158
159 @Override
160 public boolean equals(Object o) {
161 if (this == o) {
162 return true;
163 }
164 if (o == null || getClass() != o.getClass()) {
165 return false;
166 }
167 DefaultChecksumAlgorithm that = (DefaultChecksumAlgorithm) o;
168 return Objects.equals(factory.getName(), that.factory.getName());
169 }
170
171 @Override
172 public int hashCode() {
173 return Objects.hash(factory.getName());
174 }
175 }
176
177 private static class DefaultChecksumCalculator implements ChecksumCalculator {
178 private final org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithm algorithm;
179
180 DefaultChecksumCalculator(org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithm algorithm) {
181 this.algorithm = algorithm;
182 }
183
184 @Override
185 public void update(ByteBuffer input) {
186 algorithm.update(input);
187 }
188
189 @Override
190 public String checksum() {
191 return algorithm.checksum();
192 }
193 }
194 }