001package org.apache.maven.plugins.enforcer;
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
022import java.io.File;
023import java.io.FileInputStream;
024import java.io.IOException;
025import java.io.InputStream;
026
027import org.apache.commons.codec.digest.DigestUtils;
028import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
029import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
030import org.codehaus.plexus.util.IOUtil;
031
032/**
033 * Rule to validate a file to match the specified checksum.
034 *
035 * @author Edward Samson
036 * @author Lyubomyr Shaydariv
037 */
038public class RequireFileChecksum
039    extends AbstractNonCacheableEnforcerRule
040{
041
042    private File file;
043
044    private String checksum;
045
046    private String type;
047
048    @Override
049    public void execute( EnforcerRuleHelper helper )
050        throws EnforcerRuleException
051    {
052        if ( this.file == null )
053        {
054            throw new EnforcerRuleException( "Input file unspecified" );
055        }
056
057        if ( this.type == null )
058        {
059            throw new EnforcerRuleException( "Hash type unspecified" );
060        }
061
062        if ( this.checksum == null )
063        {
064            throw new EnforcerRuleException( "Checksum unspecified" );
065        }
066
067        InputStream inputStream = null;
068        try
069        {
070            if ( this.file.isDirectory() || !this.file.canRead() )
071            {
072                throw new EnforcerRuleException( "Cannot read file: " + this.file.getAbsolutePath() );
073            }
074
075            inputStream = new FileInputStream( this.file );
076            String checksum;
077            if ( "md5".equals( this.type ) )
078            {
079                checksum = DigestUtils.md5Hex( inputStream );
080            }
081            else if ( "sha1".equals( this.type ) )
082            {
083                checksum = DigestUtils.shaHex( inputStream );
084            }
085            else if ( "sha256".equals( this.type ) )
086            {
087                checksum = DigestUtils.sha256Hex( inputStream );
088            }
089            else if ( "sha384".equals( this.type ) )
090            {
091                checksum = DigestUtils.sha384Hex( inputStream );
092            }
093            else if ( "sha512".equals( this.type ) )
094            {
095                checksum = DigestUtils.sha512Hex( inputStream );
096            }
097            else
098            {
099                throw new EnforcerRuleException( "Unsupported hash type: " + this.type );
100            }
101            if ( !checksum.equalsIgnoreCase( this.checksum ) )
102            {
103                throw new EnforcerRuleException( this.type + " hash of " + this.file + " was " + checksum
104                    + " but expected " + this.checksum );
105            }
106        }
107        catch ( IOException e )
108        {
109            throw new EnforcerRuleException( "Unable to calculate checksum", e );
110        }
111        finally
112        {
113            IOUtil.close( inputStream );
114        }
115    }
116
117    /**
118     * The file to check.
119     *
120     * @param file file
121     */
122    public void setFile( File file )
123    {
124        this.file = file;
125    }
126
127    /**
128     * The expected checksum value.
129     *
130     * @param checksum checksum
131     */
132    public void setChecksum( String checksum )
133    {
134        this.checksum = checksum;
135    }
136
137    /**
138     * The checksum algorithm to use. Possible values: "md5", "sha1", "sha256", "sha384", "sha512".
139     *
140     * @param type algorithm
141     */
142    public void setType( String type )
143    {
144        this.type = type;
145    }
146
147}