michael-o commented on a change in pull request #139:
URL: https://github.com/apache/maven-resolver/pull/139#discussion_r784760358



##########
File path: 
maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnector.java
##########
@@ -571,25 +587,26 @@ private void uploadChecksums( File file, byte[] bytes )
             }
             try
             {
-                Set<String> algos = new HashSet<>();
-                for ( RepositoryLayout.Checksum checksum : checksums )
+                ArrayList<ChecksumAlgorithmFactory> algorithms = new 
ArrayList<>();
+                for ( RepositoryLayout.ChecksumLocation checksumLocation : 
checksums )
                 {
-                    algos.add( checksum.getAlgorithm() );
+                    algorithms.add( 
checksumLocation.getChecksumAlgorithmFactory() );
                 }
 
-                Map<String, Object> sumsByAlgo;
+                Map<String, String> sumsByAlgo;
                 if ( bytes != null )
                 {
-                    sumsByAlgo = ChecksumUtils.calc( bytes, algos );
+                    sumsByAlgo = ChecksumAlgorithmHelper.calculate( bytes, 
algorithms );
                 }
                 else
                 {
-                    sumsByAlgo = ChecksumUtils.calc( file, algos );
+                    sumsByAlgo = ChecksumAlgorithmHelper.calculate( file, 
algorithms );
                 }
 
-                for ( RepositoryLayout.Checksum checksum : checksums )
+                for ( RepositoryLayout.ChecksumLocation checksum : checksums )

Review comment:
       Same here

##########
File path: 
maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnector.java
##########
@@ -495,16 +510,16 @@ protected void runTask()
     }
 
     class PutTaskRunner
-        extends TaskRunner
+            extends TaskRunner
     {
 
         private final File file;
 
         private final FileTransformer fileTransformer;
 
-        private final Collection<RepositoryLayout.Checksum> checksums;
+        private final Collection<RepositoryLayout.ChecksumLocation> checksums;

Review comment:
       `checksums` => `checksumLocations`?

##########
File path: 
maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/BasicRepositoryConnector.java
##########
@@ -571,25 +587,26 @@ private void uploadChecksums( File file, byte[] bytes )
             }
             try
             {
-                Set<String> algos = new HashSet<>();
-                for ( RepositoryLayout.Checksum checksum : checksums )
+                ArrayList<ChecksumAlgorithmFactory> algorithms = new 
ArrayList<>();
+                for ( RepositoryLayout.ChecksumLocation checksumLocation : 
checksums )
                 {
-                    algos.add( checksum.getAlgorithm() );
+                    algorithms.add( 
checksumLocation.getChecksumAlgorithmFactory() );
                 }
 
-                Map<String, Object> sumsByAlgo;
+                Map<String, String> sumsByAlgo;

Review comment:
       Since the value is not an object anymore `uploadChecksum()` cannot throw 
with `checksum instanceof Exception`. Can you explain how this is supposed to 
work?

##########
File path: 
maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java
##########
@@ -46,50 +47,32 @@
 
     static class Checksum
     {
-        final String algorithm;
+        final ChecksumAlgorithmFactory checksumAlgorithmFactory;
 
-        final MessageDigest digest;
+        ChecksumAlgorithm algorithm;
 
         Exception error;
 
-        Checksum( String algorithm )
+        Checksum( ChecksumAlgorithmFactory checksumAlgorithmFactory )
         {
-            this.algorithm = algorithm;
-            MessageDigest digest = null;
-            try
-            {
-                digest = MessageDigest.getInstance( algorithm );
-            }
-            catch ( NoSuchAlgorithmException e )
-            {
-                error = e;
-            }
-            this.digest = digest;
+            this.checksumAlgorithmFactory = requireNonNull( 
checksumAlgorithmFactory );
+            this.algorithm = checksumAlgorithmFactory.getAlgorithm();
         }
 
-        public void update( ByteBuffer buffer )
+        public void reset()
         {
-            if ( digest != null )
-            {
-                digest.update( buffer );
-            }
+            this.algorithm = checksumAlgorithmFactory.getAlgorithm();

Review comment:
       So the `ChecksumAlgorithm` does not support a `reset()` directly and a 
new object is required?

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/layout/RepositoryLayout.java
##########
@@ -36,45 +37,45 @@
 {
 
     /**
-     * A descriptor for a checksum file. This descriptor simply associates the 
location of a checksum file with the
-     * underlying algorithm used to calculate/verify it. Checksum algorithms 
are denoted by names as used with
-     * {@link java.security.MessageDigest#getInstance(String)}, e.g. {@code 
"SHA-1"} or {@code "MD5"}.
+     * A descriptor for a checksum location. This descriptor simply associates 
the location of a checksum file with the
+     * underlying checksum algorithm used to calculate/verify it.
      */
-    final class Checksum
+    final class ChecksumLocation

Review comment:
       Reasonable rename since the class does not contain a checksum.

##########
File path: 
maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumCalculator.java
##########
@@ -116,16 +100,16 @@ public static ChecksumCalculator newInstance( File 
targetFile, Collection<Reposi
         return new ChecksumCalculator( targetFile, checksums );
     }
 
-    private ChecksumCalculator( File targetFile, 
Collection<RepositoryLayout.Checksum> checksums )
+    private ChecksumCalculator( File targetFile,
+                                Collection<RepositoryLayout.ChecksumLocation> 
checksums )
     {
         this.checksums = new ArrayList<>();
         Set<String> algos = new HashSet<>();
-        for ( RepositoryLayout.Checksum checksum : checksums )
+        for ( RepositoryLayout.ChecksumLocation checksum : checksums )

Review comment:
       Rename `checksum`

##########
File path: 
maven-resolver-connector-basic/src/test/java/org/eclipse/aether/connector/basic/ChecksumCalculatorTest.java
##########
@@ -39,22 +42,16 @@
 public class ChecksumCalculatorTest
 {
 
-    private static final String SHA512 = "SHA-512";
-
-    private static final String SHA256 = "SHA-256";
-
-    private static final String SHA1 = "SHA-1";
-
-    private static final String MD5 = "MD5";
-
     private File file;
 
+    private final TestChecksumAlgorithmSelector selector = new 
TestChecksumAlgorithmSelector();
+
     private ChecksumCalculator newCalculator( String... algos )
     {
-        List<RepositoryLayout.Checksum> checksums = new ArrayList<>();
+        List<RepositoryLayout.ChecksumLocation> checksums = new ArrayList<>();

Review comment:
       Rename

##########
File path: 
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/Maven2RepositoryLayoutFactory.java
##########
@@ -83,23 +106,33 @@ public RepositoryLayout newInstance( 
RepositorySystemSession session, RemoteRepo
             throw new NoRepositoryLayoutException( repository );
         }
         boolean forSignature = ConfigUtils.getBoolean( session, false, 
CONFIG_PROP_SIGNATURE_CHECKSUMS );
-        List<String> checksumsAlgorithms = Arrays.asList( 
ConfigUtils.getString( session,
-                DEFAULT_CHECKSUMS_ALGORITHMS, CONFIG_PROP_CHECKSUMS_ALGORITHMS 
).split( "," ) );
+        // ensure order of (potentially user set) algorithm list is kept and 
is unique
+        LinkedHashSet<String> checksumsAlgorithmNames = new LinkedHashSet<>( 
Arrays.asList(

Review comment:
       We don't do this for other config options. I don't know whether we 
should do this just for one.

##########
File path: 
maven-resolver-connector-basic/src/main/java/org/eclipse/aether/connector/basic/ChecksumValidator.java
##########
@@ -63,21 +62,23 @@ boolean fetchChecksum( URI remote, File local )
 
     private final ChecksumPolicy checksumPolicy;
 
-    private final Collection<Checksum> checksums;
+    private final Collection<ChecksumLocation> checksums;

Review comment:
       Rename

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithmFactorySelector.java
##########
@@ -0,0 +1,44 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+
+/**
+ * Component performing selection of {@link ChecksumAlgorithmFactory} based on 
known factory names.
+ *
+ * @since TBD
+ */
+public interface ChecksumAlgorithmFactorySelector
+{
+    /**
+     * Returns factory for given algorithm name, or throws if algorithm not 
supported.
+     *
+     * @throws IllegalArgumentException if asked algorithm name is not 
supported.
+     */
+    ChecksumAlgorithmFactory select( String algorithmName ) throws 
IllegalArgumentException;
+
+    /**
+     * Returns a set of supported algorithm names. This set represents ALL the 
algorithms supported by Resolver, and is
+     * NOT in any relation to given repository layout used checksums, returned 
by method {@link
+     * 
org.eclipse.aether.spi.connector.layout.RepositoryLayout#getChecksumAlgorithmNames()}
 (is super set of it).
+     */
+    Set<String> getChecksumAlgorithmNames();

Review comment:
       Do we need the semantics of `Set` or a a read-only collection suffcient?

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithmHelper.java
##########
@@ -0,0 +1,106 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper for checksum operations.
+ *
+ * @since TBD
+ */
+public final class ChecksumAlgorithmHelper
+{
+    private ChecksumAlgorithmHelper()
+    {
+        // nop
+    }
+
+    /**
+     * Calculates checksums for specified data.
+     *
+     * @param data        The content for which to calculate checksums, must 
not be {@code null}.
+     * @param factories   The checksum algorithm factories to use, must not be 
{@code null}.
+     * @return The calculated checksums, indexed by algorithm name, or the 
exception that occurred while trying to
+     * calculate it, never {@code null}.
+     * @throws IOException In case of any problem.
+     */
+    public static Map<String, String> calculate( byte[] data, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        return calculate( new ByteArrayInputStream( data ), factories );
+    }
+
+    /**
+     * Calculates checksums for specified file.
+     *
+     * @param file        The file for which to calculate checksums, must not 
be {@code null}.
+     * @param factories   The checksum algorithm factories to use, must not be 
{@code null}.
+     * @return The calculated checksums, indexed by algorithm name, or the 
exception that occurred while trying to
+     * calculate it, never {@code null}.
+     * @throws IOException In case of any problem.
+     */
+    public static Map<String, String> calculate( File file, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        return calculate( new BufferedInputStream( new FileInputStream( file ) 
), factories );

Review comment:
       This should be rather in a try-with-resources clause.

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithmHelper.java
##########
@@ -0,0 +1,106 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper for checksum operations.
+ *
+ * @since TBD
+ */
+public final class ChecksumAlgorithmHelper
+{
+    private ChecksumAlgorithmHelper()
+    {
+        // nop
+    }
+
+    /**
+     * Calculates checksums for specified data.
+     *
+     * @param data        The content for which to calculate checksums, must 
not be {@code null}.
+     * @param factories   The checksum algorithm factories to use, must not be 
{@code null}.
+     * @return The calculated checksums, indexed by algorithm name, or the 
exception that occurred while trying to
+     * calculate it, never {@code null}.
+     * @throws IOException In case of any problem.
+     */
+    public static Map<String, String> calculate( byte[] data, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        return calculate( new ByteArrayInputStream( data ), factories );
+    }
+
+    /**
+     * Calculates checksums for specified file.
+     *
+     * @param file        The file for which to calculate checksums, must not 
be {@code null}.
+     * @param factories   The checksum algorithm factories to use, must not be 
{@code null}.
+     * @return The calculated checksums, indexed by algorithm name, or the 
exception that occurred while trying to
+     * calculate it, never {@code null}.
+     * @throws IOException In case of any problem.
+     */
+    public static Map<String, String> calculate( File file, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        return calculate( new BufferedInputStream( new FileInputStream( file ) 
), factories );
+    }
+
+    private static Map<String, String> calculate( InputStream inputStream, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        LinkedHashMap<String, ChecksumAlgorithm> algorithms = new 
LinkedHashMap<>();
+        factories.forEach( f -> algorithms.put( f.getName(), f.getAlgorithm() 
) );
+        try ( InputStream in = inputStream )

Review comment:
       I don't like this. We haven't opened the IS, we should not close this.

##########
File path: 
maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/synccontext/named/DiscriminatingNameMapper.java
##########
@@ -115,25 +113,22 @@ private String createDiscriminator( final 
RepositorySystemSession session )
             String hostname = ConfigUtils.getString( session, this.hostname, 
CONFIG_PROP_HOSTNAME );
             File basedir = session.getLocalRepository().getBasedir();
             discriminator = hostname + ":" + basedir;
-            try
-            {
-                Map<String, Object> checksums = ChecksumUtils
-                        .calc( discriminator.getBytes( StandardCharsets.UTF_8 
), Collections.singletonList( "SHA-1" ) );
-                Object checksum = checksums.get( "SHA-1" );
-
-                if ( checksum instanceof Exception )
-                {
-                    throw (Exception) checksum;
-                }
-
-                return String.valueOf( checksum );
-            }
-            catch ( Exception e )
-            {
-                LOGGER.warn( "Failed to calculate discriminator digest, using 
'{}'", DEFAULT_DISCRIMINATOR_DIGEST, e );
-                return DEFAULT_DISCRIMINATOR_DIGEST;
-            }
+            return sha1String( discriminator );

Review comment:
       Can we leave this block as-is right now since it is not related for 
artifact/metadata checksums at all? I actually need a fixed length nash to 
properly map input data.

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithmHelper.java
##########
@@ -0,0 +1,106 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper for checksum operations.
+ *
+ * @since TBD
+ */
+public final class ChecksumAlgorithmHelper
+{
+    private ChecksumAlgorithmHelper()
+    {
+        // nop
+    }
+
+    /**
+     * Calculates checksums for specified data.
+     *
+     * @param data        The content for which to calculate checksums, must 
not be {@code null}.
+     * @param factories   The checksum algorithm factories to use, must not be 
{@code null}.
+     * @return The calculated checksums, indexed by algorithm name, or the 
exception that occurred while trying to
+     * calculate it, never {@code null}.
+     * @throws IOException In case of any problem.
+     */
+    public static Map<String, String> calculate( byte[] data, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        return calculate( new ByteArrayInputStream( data ), factories );
+    }
+
+    /**
+     * Calculates checksums for specified file.
+     *
+     * @param file        The file for which to calculate checksums, must not 
be {@code null}.
+     * @param factories   The checksum algorithm factories to use, must not be 
{@code null}.
+     * @return The calculated checksums, indexed by algorithm name, or the 
exception that occurred while trying to
+     * calculate it, never {@code null}.
+     * @throws IOException In case of any problem.
+     */
+    public static Map<String, String> calculate( File file, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        return calculate( new BufferedInputStream( new FileInputStream( file ) 
), factories );
+    }
+
+    private static Map<String, String> calculate( InputStream inputStream, 
List<ChecksumAlgorithmFactory> factories )
+            throws IOException
+    {
+        LinkedHashMap<String, ChecksumAlgorithm> algorithms = new 
LinkedHashMap<>();
+        factories.forEach( f -> algorithms.put( f.getName(), f.getAlgorithm() 
) );
+        try ( InputStream in = inputStream )
+        {
+            ByteBuffer byteBuffer = ByteBuffer.allocate( 32 * 1024 );

Review comment:
       What is the benefit of a byte buffer compared to a pure byte array?

##########
File path: src/site/markdown/about-checksums.md
##########
@@ -0,0 +1,72 @@
+# About checksums
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+Maven Resolver uses "checksums" to verify the consistency of the downloaded 
+artifacts. Checksums are usually laid out in repositories next to the file in 
question, with file 
+extension telling the checksum algorithm that produced the given checksum file 
content. Current Maven Repository 
+layout contains SHA-1 and MD5 checksums by default (they are produced by 
Resolver by default).
+
+Historically, Maven Resolver used `java.security.MessageDigest` to implement 
checksums. So to say, secure one-way
+hashes provided by Java Cryptography Architecture were (mis)used to implement 
checksums for transport integrity 
+validation. There is no misunderstanding here, secure hashes MAY be used as 
checksums, as there is quite some 
+overlap between "checksums" and "hashes" in general. But this simplicity comes 
at a price: cryptographically "safe" 
+algorithms require way more CPU cycles to calculate checksum, while all their 
purpose is just 
+"integrity validation", nothing more. There is no "security", "trust" or 
whatever else implied or expected from

Review comment:
       Very good.

##########
File path: src/site/markdown/about-checksums.md
##########
@@ -0,0 +1,72 @@
+# About checksums
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+Maven Resolver uses "checksums" to verify the consistency of the downloaded 

Review comment:
       Why in quotes?

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/layout/RepositoryLayout.java
##########
@@ -83,39 +84,34 @@ public static Checksum forLocation( URI location, String 
algorithm )
             {
                 throw new IllegalArgumentException( "resource location must 
not have a fragment: " + location );
             }
-            String extension = '.' + algorithm.replace( "-", "" ).toLowerCase( 
Locale.ENGLISH );
-            return new Checksum( algorithm, URI.create( location.toString() + 
extension ) );
+            return new ChecksumLocation( URI.create( location + "." + 
checksumAlgorithmFactory.getExtension() ),
+                    checksumAlgorithmFactory );
         }
 
-        private static void verify( String algorithm, URI location )
+        private static void verify( URI location, ChecksumAlgorithmFactory 
checksumAlgorithmFactory )
         {
-            requireNonNull( algorithm, "checksum algorithm cannot be null" );
-            if ( algorithm.length() == 0 )
-            {
-                throw new IllegalArgumentException( "checksum algorithm cannot 
be empty" );
-            }
             requireNonNull( location, "checksum location cannot be null" );
             if ( location.isAbsolute() )
             {
                 throw new IllegalArgumentException( "checksum location must be 
relative" );
             }
+            requireNonNull( checksumAlgorithmFactory, "checksum algorithm 
cannot be null" );

Review comment:
       factory missing

##########
File path: src/site/markdown/about-checksums.md
##########
@@ -0,0 +1,72 @@
+# About checksums
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+Maven Resolver uses "checksums" to verify the consistency of the downloaded 
+artifacts. Checksums are usually laid out in repositories next to the file in 
question, with file 
+extension telling the checksum algorithm that produced the given checksum file 
content. Current Maven Repository 
+layout contains SHA-1 and MD5 checksums by default (they are produced by 
Resolver by default).
+
+Historically, Maven Resolver used `java.security.MessageDigest` to implement 
checksums. So to say, secure one-way
+hashes provided by Java Cryptography Architecture were (mis)used to implement 
checksums for transport integrity 
+validation. There is no misunderstanding here, secure hashes MAY be used as 
checksums, as there is quite some 
+overlap between "checksums" and "hashes" in general. But this simplicity comes 
at a price: cryptographically "safe" 
+algorithms require way more CPU cycles to calculate checksum, while all their 
purpose is just 
+"integrity validation", nothing more. There is no "security", "trust" or 
whatever else implied or expected from
+them.
+
+If you are interested in "trust" in your artifacts, it is Artifact Signatures 
(for example
+[GPG Signatures](https://maven.apache.org/plugins/maven-gpg-plugin/)) that you 
should look for.
+
+Hence, the usual argument that "XXX algorithm is unsafe, deprecated, not 
secure anymore" does not stand in use case
+of Maven Resolver: there is nothing "secure" being involved with checksums. 
Moreover, this is true not only for SHA-1
+algorithm, but even for it's "elder brother" MD5. Both algorithms are still 
widely used today as "transport integrity

Review comment:
       its

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithmFactory.java
##########
@@ -0,0 +1,48 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * A component representing a checksum factory: provides {@link 
ChecksumAlgorithm} instances, name and extension to be
+ * used with this algorithm. While directly injecting components of this type 
is possible, it is not recommended. To
+ * obtain factory instances use {@link ChecksumAlgorithmFactorySelector} 
instead.
+ *
+ * @since TBD
+ */
+public interface ChecksumAlgorithmFactory
+{
+    /**
+     * Returns the algorithm name, usually used as key, never {@code null} 
value. The name is a standard name of
+     * algorithm (if applicable) or any other designator that is algorithm 
commonly referred with. Example: "SHA-1".
+     */
+    String getName();
+
+    /**
+     * Returns the file extension to be used for given checksum file (without 
leading dot), never {@code null}. The
+     * extension should be file and URL path friendly, and usually differs 
from value returned by {@link #getName()}.
+     * Example: "sha1".
+     */
+    String getExtension();

Review comment:
       Maybe this should rather be `getFileExtension()`/`getPathExtension()`. 
The context of "extension" isn't clear w/o reading the Javadoc.

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithm.java
##########
@@ -0,0 +1,46 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.nio.ByteBuffer;
+
+/**
+ * Implementation performing checksum calculation for specific algorithm. 
Instances of this interface are stateful,
+ * non-thread safe, and should not be reused.
+ *
+ * @since TBD
+ */
+public interface ChecksumAlgorithm
+{
+    /**
+     * Updates the checksum algorithm inner state with input.
+     */
+    void update( ByteBuffer input );

Review comment:
       Do we receive data as `ByteBuffer` or rather `byte[]`?

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/checksum/ChecksumAlgorithmFactorySelector.java
##########
@@ -0,0 +1,44 @@
+package org.eclipse.aether.spi.connector.checksum;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Set;
+
+/**
+ * Component performing selection of {@link ChecksumAlgorithmFactory} based on 
known factory names.
+ *
+ * @since TBD
+ */
+public interface ChecksumAlgorithmFactorySelector
+{
+    /**
+     * Returns factory for given algorithm name, or throws if algorithm not 
supported.
+     *
+     * @throws IllegalArgumentException if asked algorithm name is not 
supported.
+     */
+    ChecksumAlgorithmFactory select( String algorithmName ) throws 
IllegalArgumentException;

Review comment:
       No need for `throws`. It is a runtime exception. No effect.

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/layout/RepositoryLayout.java
##########
@@ -36,45 +37,45 @@
 {
 
     /**
-     * A descriptor for a checksum file. This descriptor simply associates the 
location of a checksum file with the
-     * underlying algorithm used to calculate/verify it. Checksum algorithms 
are denoted by names as used with
-     * {@link java.security.MessageDigest#getInstance(String)}, e.g. {@code 
"SHA-1"} or {@code "MD5"}.
+     * A descriptor for a checksum location. This descriptor simply associates 
the location of a checksum file with the
+     * underlying checksum algorithm used to calculate/verify it.
      */
-    final class Checksum
+    final class ChecksumLocation
     {
-
-        private final String algorithm;
-
         private final URI location;
 
+        private final ChecksumAlgorithmFactory checksumAlgorithmFactory;
+
         /**
          * Creates a new checksum file descriptor with the specified algorithm 
and location. The method
-         * {@link #forLocation(URI, String)} is usually more convenient though.
-         * 
-         * @param algorithm The algorithm used to calculate the checksum, must 
not be {@code null}.
-         * @param location The relative URI to the checksum file within a 
repository, must not be {@code null}.
+         * {@link #forLocation(URI, ChecksumAlgorithmFactory)} is usually more 
convenient though.
+         *
+         * @param location                 The relative URI to the checksum 
file within a repository, must not be {@code
+         *                                 null}.
+         * @param checksumAlgorithmFactory The checksum type used to calculate 
the checksum, must not be {@code null}.
          */
-        public Checksum( String algorithm, URI location )
+        public ChecksumLocation( URI location, ChecksumAlgorithmFactory 
checksumAlgorithmFactory )
         {
-            verify( algorithm, location );
-            this.algorithm = algorithm;
+            verify( location, checksumAlgorithmFactory );
             this.location = location;
+            this.checksumAlgorithmFactory = checksumAlgorithmFactory;
         }
 
         /**
-         * Creates a checksum file descriptor for the specified 
artifact/metadata location and algorithm. The location
+         * Creates a checksum descriptor for the specified artifact/metadata 
location and algorithm. The location
          * of the checksum file itself is derived from the supplied resource 
URI by appending the file extension
          * corresponding to the algorithm. The file extension in turn is 
derived from the algorithm name by stripping
          * out any hyphen ('-') characters and lower-casing the name, e.g. 
"SHA-1" is mapped to ".sha1".

Review comment:
       There two lines aren't correct anymore since most of it is handled of to 
the chksum factory.

##########
File path: 
maven-resolver-spi/src/main/java/org/eclipse/aether/spi/connector/layout/RepositoryLayout.java
##########
@@ -126,55 +122,63 @@ public URI getLocation()
         @Override
         public String toString()
         {
-            return location + " (" + algorithm + ")";
+            return location + " (" + checksumAlgorithmFactory.getName() + ")";
         }
-
     }
 
+    /**
+     * Returns the collection of checksum names this instance of layout uses, 
never {@code null}.
+     *
+     * @since TBD
+     */
+    List<String> getChecksumAlgorithmNames();

Review comment:
       This one is a list, up earlier it was a set...




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to