View Javadoc
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.eclipse.aether.util;
20  
21  import java.io.BufferedReader;
22  import java.io.ByteArrayInputStream;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.InputStreamReader;
28  import java.nio.charset.StandardCharsets;
29  import java.security.MessageDigest;
30  import java.security.NoSuchAlgorithmException;
31  import java.util.Collection;
32  import java.util.LinkedHashMap;
33  import java.util.Map;
34  
35  /**
36   * A utility class to assist in the verification and generation of checksums.
37   *
38   * @deprecated The use of class should be avoided, see {@link StringDigestUtil} and file processor in SPI module.
39   */
40  @Deprecated
41  public final class ChecksumUtils {
42  
43      private ChecksumUtils() {
44          // hide constructor
45      }
46  
47      /**
48       * Extracts the checksum from the specified file.
49       *
50       * @param checksumFile The path to the checksum file, must not be {@code null}.
51       * @return The checksum stored in the file, never {@code null}.
52       * @throws IOException If the checksum does not exist or could not be read for other reasons.
53       * @deprecated Use SPI FileProcessor to read and write checksum files.
54       */
55      @Deprecated
56      public static String read(File checksumFile) throws IOException {
57          String checksum = "";
58          try (BufferedReader br = new BufferedReader(
59                  new InputStreamReader(new FileInputStream(checksumFile), StandardCharsets.UTF_8), 512)) {
60              while (true) {
61                  String line = br.readLine();
62                  if (line == null) {
63                      break;
64                  }
65                  line = line.trim();
66                  if (!line.isEmpty()) {
67                      checksum = line;
68                      break;
69                  }
70              }
71          }
72  
73          if (checksum.matches(".+= [0-9A-Fa-f]+")) {
74              int lastSpacePos = checksum.lastIndexOf(' ');
75              checksum = checksum.substring(lastSpacePos + 1);
76          } else {
77              int spacePos = checksum.indexOf(' ');
78  
79              if (spacePos != -1) {
80                  checksum = checksum.substring(0, spacePos);
81              }
82          }
83  
84          return checksum;
85      }
86  
87      /**
88       * Calculates checksums for the specified file.
89       *
90       * @param dataFile The file for which to calculate checksums, must not be {@code null}.
91       * @param algos The names of checksum algorithms (cf. {@link MessageDigest#getInstance(String)} to use, must not be
92       *            {@code null}.
93       * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to
94       *         calculate it, never {@code null}.
95       * @throws IOException If the data file could not be read.
96       * @deprecated Use SPI checksum selector instead.
97       */
98      @Deprecated
99      public static Map<String, Object> calc(File dataFile, Collection<String> algos) throws IOException {
100         return calc(new FileInputStream(dataFile), algos);
101     }
102 
103     /**
104      * @deprecated Use SPI checksum selector instead.
105      */
106     @Deprecated
107     public static Map<String, Object> calc(byte[] dataBytes, Collection<String> algos) throws IOException {
108         return calc(new ByteArrayInputStream(dataBytes), algos);
109     }
110 
111     private static Map<String, Object> calc(InputStream data, Collection<String> algos) throws IOException {
112         Map<String, Object> results = new LinkedHashMap<>();
113 
114         Map<String, MessageDigest> digests = new LinkedHashMap<>();
115         for (String algo : algos) {
116             try {
117                 digests.put(algo, MessageDigest.getInstance(algo));
118             } catch (NoSuchAlgorithmException e) {
119                 results.put(algo, e);
120             }
121         }
122 
123         try (InputStream in = data) {
124             for (byte[] buffer = new byte[32 * 1024]; ; ) {
125                 int read = in.read(buffer);
126                 if (read < 0) {
127                     break;
128                 }
129                 for (MessageDigest digest : digests.values()) {
130                     digest.update(buffer, 0, read);
131                 }
132             }
133         }
134 
135         for (Map.Entry<String, MessageDigest> entry : digests.entrySet()) {
136             byte[] bytes = entry.getValue().digest();
137 
138             results.put(entry.getKey(), toHexString(bytes));
139         }
140 
141         return results;
142     }
143 
144     /**
145      * Creates a hexadecimal representation of the specified bytes. Each byte is converted into a two-digit hex number
146      * and appended to the result with no separator between consecutive bytes.
147      *
148      * @param bytes The bytes to represent in hex notation, may be be {@code null}.
149      * @return The hexadecimal representation of the input or {@code null} if the input was {@code null}.
150      */
151     @SuppressWarnings("checkstyle:magicnumber")
152     public static String toHexString(byte[] bytes) {
153         return StringDigestUtil.toHexString(bytes);
154     }
155 
156     /**
157      * Creates a byte array out of hexadecimal representation of the specified bytes. If input string is {@code null},
158      * {@code null} is returned. Input value must have even length (due hex encoding = 2 chars one byte).
159      *
160      * @param hexString The hexString to convert to byte array, may be {@code null}.
161      * @return The byte array of the input or {@code null} if the input was {@code null}.
162      * @since 1.8.0
163      */
164     @SuppressWarnings("checkstyle:magicnumber")
165     public static byte[] fromHexString(String hexString) {
166         return StringDigestUtil.fromHexString(hexString);
167     }
168 }