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; 030 031/** 032 * Rule to validate a binary file to match the specified checksum. 033 * 034 * @author Edward Samson 035 * @author Lyubomyr Shaydariv 036 * @see RequireTextFileChecksum 037 */ 038public class RequireFileChecksum 039 extends AbstractNonCacheableEnforcerRule 040{ 041 042 protected File file; 043 044 private String checksum; 045 046 private String type; 047 048 private String nonexistentFileMessage; 049 050 @Override 051 public void execute( EnforcerRuleHelper helper ) 052 throws EnforcerRuleException 053 { 054 if ( this.file == null ) 055 { 056 throw new EnforcerRuleException( "Input file unspecified" ); 057 } 058 059 if ( this.type == null ) 060 { 061 throw new EnforcerRuleException( "Hash type unspecified" ); 062 } 063 064 if ( this.checksum == null ) 065 { 066 throw new EnforcerRuleException( "Checksum unspecified" ); 067 } 068 069 if ( !this.file.exists() ) 070 { 071 String message = nonexistentFileMessage; 072 if ( message == null ) 073 { 074 message = "File does not exist: " + this.file.getAbsolutePath(); 075 } 076 throw new EnforcerRuleException( message ); 077 } 078 079 if ( this.file.isDirectory() ) 080 { 081 throw new EnforcerRuleException( "Cannot calculate the checksum of directory: " 082 + this.file.getAbsolutePath() ); 083 } 084 085 if ( !this.file.canRead() ) 086 { 087 throw new EnforcerRuleException( "Cannot read file: " + this.file.getAbsolutePath() ); 088 } 089 090 String checksum = calculateChecksum(); 091 092 if ( !checksum.equalsIgnoreCase( this.checksum ) ) 093 { 094 String exceptionMessage = getMessage(); 095 if ( exceptionMessage == null ) 096 { 097 exceptionMessage = this.type + " hash of " + this.file + " was " + checksum 098 + " but expected " + this.checksum; 099 } 100 throw new EnforcerRuleException( exceptionMessage ); 101 } 102 } 103 104 /** 105 * The file to check. 106 * 107 * @param file file 108 */ 109 public void setFile( File file ) 110 { 111 this.file = file; 112 } 113 114 /** 115 * The expected checksum value. 116 * 117 * @param checksum checksum 118 */ 119 public void setChecksum( String checksum ) 120 { 121 this.checksum = checksum; 122 } 123 124 /** 125 * The checksum algorithm to use. Possible values: "md5", "sha1", "sha256", "sha384", "sha512". 126 * 127 * @param type algorithm 128 */ 129 public void setType( String type ) 130 { 131 this.type = type; 132 } 133 134 /** 135 * The friendly message to use when the file does not exist. 136 * 137 * @param nonexistentFileMessage message 138 */ 139 public void setNonexistentFileMessage( String nonexistentFileMessage ) 140 { 141 this.nonexistentFileMessage = nonexistentFileMessage; 142 } 143 144 protected String calculateChecksum() 145 throws EnforcerRuleException 146 { 147 try ( InputStream inputStream = new FileInputStream( this.file ) ) 148 { 149 return calculateChecksum( inputStream ); 150 } 151 catch ( IOException e ) 152 { 153 throw new EnforcerRuleException( "Unable to calculate checksum", e ); 154 } 155 } 156 157 protected String calculateChecksum( InputStream inputStream ) 158 throws IOException, EnforcerRuleException 159 { 160 String checksum; 161 if ( "md5".equals( this.type ) ) 162 { 163 checksum = DigestUtils.md5Hex( inputStream ); 164 } 165 else if ( "sha1".equals( this.type ) ) 166 { 167 checksum = DigestUtils.sha1Hex( inputStream ); 168 } 169 else if ( "sha256".equals( this.type ) ) 170 { 171 checksum = DigestUtils.sha256Hex( inputStream ); 172 } 173 else if ( "sha384".equals( this.type ) ) 174 { 175 checksum = DigestUtils.sha384Hex( inputStream ); 176 } 177 else if ( "sha512".equals( this.type ) ) 178 { 179 checksum = DigestUtils.sha512Hex( inputStream ); 180 } 181 else 182 { 183 throw new EnforcerRuleException( "Unsupported hash type: " + this.type ); 184 } 185 return checksum; 186 } 187}