001    package org.apache.archiva.checksum;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.security.DigestInputStream;
025    import java.security.MessageDigest;
026    import java.security.NoSuchAlgorithmException;
027    import java.util.List;
028    
029    import org.apache.commons.io.IOUtils;
030    import org.apache.commons.io.output.NullOutputStream;
031    
032    /**
033     * Checksum - simple checksum hashing routines. 
034     *
035     *
036     */
037    public class Checksum
038    {
039        private static final int BUFFER_SIZE = 32768;
040    
041        public static void update( List<Checksum> checksums, InputStream stream )
042            throws IOException
043        {
044            byte[] buffer = new byte[BUFFER_SIZE];
045            int size = stream.read( buffer, 0, BUFFER_SIZE );
046            while ( size >= 0 )
047            {
048                for ( Checksum checksum : checksums )
049                {
050                    checksum.update( buffer, 0, size );
051                }
052                size = stream.read( buffer, 0, BUFFER_SIZE );
053            }
054        }
055    
056        protected final MessageDigest md;
057    
058        private ChecksumAlgorithm checksumAlgorithm;
059    
060        public Checksum( ChecksumAlgorithm checksumAlgorithm )
061        {
062            this.checksumAlgorithm = checksumAlgorithm;
063            try
064            {
065                md = MessageDigest.getInstance( checksumAlgorithm.getAlgorithm() );
066            }
067            catch ( NoSuchAlgorithmException e )
068            {
069                // Not really possible, but here none-the-less
070                throw new IllegalStateException( "Unable to initialize MessageDigest algorithm " + checksumAlgorithm.getAlgorithm()
071                    + " : " + e.getMessage(), e );
072            }
073        }
074    
075        public String getChecksum()
076        {
077            return Hex.encode( md.digest() );
078        }
079    
080        public ChecksumAlgorithm getAlgorithm()
081        {
082            return this.checksumAlgorithm;
083        }
084    
085        public void reset()
086        {
087            md.reset();
088        }
089    
090        public Checksum update( byte[] buffer, int offset, int size )
091        {
092            md.update( buffer, 0, size );
093            return this;
094        }
095    
096        public Checksum update( InputStream stream )
097            throws IOException
098        {
099            DigestInputStream dig = new DigestInputStream( stream, md );
100            IOUtils.copy( dig, new NullOutputStream() );
101    
102            return this;
103        }
104    }