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