Skip to content

Commit

Permalink
[MENFORCER-458] Move Require*Checksum to new API
Browse files Browse the repository at this point in the history
  • Loading branch information
slawekjaranowski committed Jan 12, 2023
1 parent 48ca986 commit b122ca1
Show file tree
Hide file tree
Showing 12 changed files with 344 additions and 125 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.enforcer.rules.utils;
package org.apache.maven.enforcer.rules.checksum;

import java.io.FilterReader;
import java.io.IOException;
Expand All @@ -25,7 +25,7 @@
/**
* Converts Unix line separators to Windows ones and vice-versa.
*/
public class NormalizeLineSeparatorReader extends FilterReader {
class NormalizeLineSeparatorReader extends FilterReader {

private static final int EOL = -1;

Expand Down Expand Up @@ -84,7 +84,7 @@ public MatchResult matches(char currentCharacter, Character previousCharacter) {

Character previousCharacter;

public NormalizeLineSeparatorReader(Reader reader, LineSeparator lineSeparator) {
NormalizeLineSeparatorReader(Reader reader, LineSeparator lineSeparator) {
super(reader);
this.lineSeparator = lineSeparator;
bufferedCharacter = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.plugins.enforcer;
package org.apache.maven.enforcer.rules.checksum;

import javax.inject.Named;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.maven.enforcer.rule.api.EnforcerRuleError;
import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
import org.apache.maven.enforcer.rules.AbstractStandardEnforcerRule;

/**
* Rule to validate a binary file to match the specified checksum.
Expand All @@ -34,9 +37,10 @@
* @author Lyubomyr Shaydariv
* @see RequireTextFileChecksum
*/
public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
@Named("requireFileChecksum")
public class RequireFileChecksum extends AbstractStandardEnforcerRule {

protected File file;
private File file;

private String checksum;

Expand All @@ -45,17 +49,17 @@ public class RequireFileChecksum extends AbstractNonCacheableEnforcerRule {
private String nonexistentFileMessage;

@Override
public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
public void execute() throws EnforcerRuleException {
if (this.file == null) {
throw new EnforcerRuleException("Input file unspecified");
throw new EnforcerRuleError("Input file unspecified");
}

if (this.type == null) {
throw new EnforcerRuleException("Hash type unspecified");
throw new EnforcerRuleError("Hash type unspecified");
}

if (this.checksum == null) {
throw new EnforcerRuleException("Checksum unspecified");
throw new EnforcerRuleError("Checksum unspecified");
}

if (!this.file.exists()) {
Expand All @@ -67,12 +71,11 @@ public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
}

if (this.file.isDirectory()) {
throw new EnforcerRuleException(
"Cannot calculate the checksum of directory: " + this.file.getAbsolutePath());
throw new EnforcerRuleError("Cannot calculate the checksum of directory: " + this.file.getAbsolutePath());
}

if (!this.file.canRead()) {
throw new EnforcerRuleException("Cannot read file: " + this.file.getAbsolutePath());
throw new EnforcerRuleError("Cannot read file: " + this.file.getAbsolutePath());
}

String checksum = calculateChecksum();
Expand All @@ -96,6 +99,10 @@ public void setFile(File file) {
this.file = file;
}

public File getFile() {
return file;
}

/**
* The expected checksum value.
*
Expand All @@ -105,6 +112,10 @@ public void setChecksum(String checksum) {
this.checksum = checksum;
}

public String getChecksum() {
return checksum;
}

/**
* The checksum algorithm to use. Possible values: "md5", "sha1", "sha256", "sha384", "sha512".
*
Expand All @@ -114,6 +125,10 @@ public void setType(String type) {
this.type = type;
}

public String getType() {
return type;
}

/**
* The friendly message to use when the file does not exist.
*
Expand All @@ -123,29 +138,40 @@ public void setNonexistentFileMessage(String nonexistentFileMessage) {
this.nonexistentFileMessage = nonexistentFileMessage;
}

public String getNonexistentFileMessage() {
return nonexistentFileMessage;
}

protected String calculateChecksum() throws EnforcerRuleException {
try (InputStream inputStream = Files.newInputStream(this.file.toPath())) {
return calculateChecksum(inputStream);
} catch (IOException e) {
throw new EnforcerRuleException("Unable to calculate checksum", e);
throw new EnforcerRuleError("Unable to calculate checksum", e);
}
}

protected String calculateChecksum(InputStream inputStream) throws IOException, EnforcerRuleException {
String checksum;
String result;
if ("md5".equals(this.type)) {
checksum = DigestUtils.md5Hex(inputStream);
result = DigestUtils.md5Hex(inputStream);
} else if ("sha1".equals(this.type)) {
checksum = DigestUtils.sha1Hex(inputStream);
result = DigestUtils.sha1Hex(inputStream);
} else if ("sha256".equals(this.type)) {
checksum = DigestUtils.sha256Hex(inputStream);
result = DigestUtils.sha256Hex(inputStream);
} else if ("sha384".equals(this.type)) {
checksum = DigestUtils.sha384Hex(inputStream);
result = DigestUtils.sha384Hex(inputStream);
} else if ("sha512".equals(this.type)) {
checksum = DigestUtils.sha512Hex(inputStream);
result = DigestUtils.sha512Hex(inputStream);
} else {
throw new EnforcerRuleException("Unsupported hash type: " + this.type);
throw new EnforcerRuleError("Unsupported hash type: " + this.type);
}
return checksum;
return result;
}

@Override
public String toString() {
return String.format(
"RequireFileChecksum[file=%s, checksum=%s, type=%s, nonexistentFileMessage=%s, level=%s]",
file, checksum, type, nonexistentFileMessage, getLevel());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,44 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.plugins.enforcer;
package org.apache.maven.enforcer.rules.checksum;

import javax.inject.Inject;
import javax.inject.Named;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Objects;

import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.enforcer.rule.api.EnforcerRuleError;
import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
import org.apache.maven.enforcer.rules.utils.NormalizeLineSeparatorReader;
import org.apache.maven.enforcer.rules.utils.NormalizeLineSeparatorReader.LineSeparator;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
import org.apache.maven.enforcer.rules.checksum.NormalizeLineSeparatorReader.LineSeparator;
import org.apache.maven.project.MavenProject;

/**
* Rule to validate a text file to match the specified checksum.
*
* @author Konrad Windszus
* @see RequireFileChecksum
*/
@Named("requireTextFileChecksum")
public class RequireTextFileChecksum extends RequireFileChecksum {

private NormalizeLineSeparatorReader.LineSeparator normalizeLineSeparatorTo = LineSeparator.UNIX;

Charset encoding;
private Charset encoding;

private final MavenProject project;

@Inject
public RequireTextFileChecksum(MavenProject project) {
this.project = Objects.requireNonNull(project);
}

public void setNormalizeLineSeparatorTo(NormalizeLineSeparatorReader.LineSeparator normalizeLineSeparatorTo) {
this.normalizeLineSeparatorTo = normalizeLineSeparatorTo;
Expand All @@ -51,38 +63,47 @@ public void setEncoding(String encoding) {
this.encoding = Charset.forName(encoding);
}

public Charset getEncoding() {
return encoding;
}

@Override
public void execute(EnforcerRuleHelper helper) throws EnforcerRuleException {
public void execute() throws EnforcerRuleException {
// set defaults
if (encoding == null) {
// https://maven.apache.org/plugins/maven-resources-plugin/examples/encoding.html
try {
String encoding = (String) helper.evaluate("${project.build.sourceEncoding}");
if (StringUtils.isBlank(encoding)) {
encoding = System.getProperty("file.encoding");
helper.getLog()
.warn("File encoding has not been set, using platform encoding " + encoding
+ ". Build is platform dependent!");
}
this.encoding = Charset.forName(encoding);
} catch (ExpressionEvaluationException e) {
throw new EnforcerRuleException(
"Unable to retrieve the project's build source encoding "
+ "(${project.build.sourceEncoding}): ",
e);
String projectEncoding = project.getProperties().getProperty("project.build.sourceEncoding", null);
if (StringUtils.isBlank(projectEncoding)) {
projectEncoding = System.getProperty("file.encoding");
getLog().warn("File encoding has not been set, using platform encoding " + projectEncoding
+ ". Build is platform dependent! - https://maven.apache.org/general.html#encoding-warning");
}
encoding = Charset.forName(projectEncoding);
}
super.execute(helper);
super.execute();
}

@Override
protected String calculateChecksum() throws EnforcerRuleException {
try (Reader reader = new NormalizeLineSeparatorReader(
Files.newBufferedReader(file.toPath(), encoding), normalizeLineSeparatorTo);
Files.newBufferedReader(getFile().toPath(), encoding), normalizeLineSeparatorTo);
InputStream inputStream = new ReaderInputStream(reader, encoding)) {
return super.calculateChecksum(inputStream);
} catch (IOException e) {
throw new EnforcerRuleException("Unable to calculate checksum (with normalized line separators)", e);
throw new EnforcerRuleError("Unable to calculate checksum (with normalized line separators)", e);
}
}

@Override
public String toString() {
return String.format(
"RequireFileChecksum[file=%s, checksum=%s, type=%s, encoding=%s, normalizeLineSeparatorTo=%s, nonexistentFileMessage=%s, level=%s]",
getFile(),
getChecksum(),
getType(),
encoding,
normalizeLineSeparatorTo,
getNonexistentFileMessage(),
getLevel());
}
}
20 changes: 10 additions & 10 deletions enforcer-rules/src/site/apt/requireFileChecksum.apt.vm
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ Require Files Checksum

The following parameters are supported by this rule:

* message - an optional message to the user if the rule fails. If not set a default message will be used.
* <<message>> - an optional message to the user if the rule fails. If not set a default message will be used.

* nonexistentFileMessage - an optional message to the user if the file is missing. If not set a default message will be used.
* <<nonexistentFileMessage>> - an optional message to the user if the file is missing. If not set a default message will be used.

* file - A file to check.
* <<file>> - A file to check.

* checksum - Expected file checksum.
* <<checksum>> - Expected file checksum.

* type - Type of hashing algorithm to calculate the checksum. May be one of "md5", "sha1", "sha256", "sha384", or "sha512".
* <<type>> - Type of hashing algorithm to calculate the checksum. May be one of "md5", "sha1", "sha256", "sha384", or "sha512".

[]

Expand All @@ -64,27 +64,27 @@ Require Files Checksum
<configuration>
<rules>
<requireFileChecksum>
<file>${project.build.outputDirectory}/foo.txt</file>
<file>\${project.build.outputDirectory}/foo.txt</file>
<checksum>d41d8cd98f00b204e9800998ecf8427e</checksum>
<type>md5</type>
</requireFileChecksum>
<requireFileChecksum>
<file>${project.build.outputDirectory}/bar.txt</file>
<file>\${project.build.outputDirectory}/bar.txt</file>
<checksum>da39a3ee5e6b4b0d3255bfef95601890afd80709</checksum>
<type>sha1</type>
</requireFileChecksum>
<requireFileChecksum>
<file>${project.build.outputDirectory}/baz.txt</file>
<file>\${project.build.outputDirectory}/baz.txt</file>
<checksum>e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</checksum>
<type>sha256</type>
</requireFileChecksum>
<requireFileChecksum>
<file>${project.build.outputDirectory}/qux.txt</file>
<file>\${project.build.outputDirectory}/qux.txt</file>
<checksum>38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b</checksum>
<type>sha384</type>
</requireFileChecksum>
<requireFileChecksum>
<file>${project.build.outputDirectory}/quux.txt</file>
<file>\${project.build.outputDirectory}/quux.txt</file>
<checksum>cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e</checksum>
<type>sha512</type>
</requireFileChecksum>
Expand Down
Loading

0 comments on commit b122ca1

Please sign in to comment.