All Downloads are FREE. Search and download functionalities are using the official Maven repository.

liquibase.change.CheckSum Maven / Gradle / Ivy

There is a newer version: 3.6.2.5.inovus
Show newest version
package liquibase.change;

import liquibase.util.MD5Util;
import liquibase.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.text.Normalizer;

/**
 * CheckSums are used by liquibase to determine if a Change has been modified since it was originally ran.
 * CheckSums can be computed on either a String or an {@link InputStream}.
 * The CheckSum contains a version number which can be used to determine whether the algorithm for computing a
 * storedCheckSum has changed since the last time it was computed. If the algorithm changes, we cannot rely on
 * the storedCheckSum value.
 * 

* It is not up to this class to determine what should be storedCheckSum-ed, it simply hashes what is passed to it. */ public final class CheckSum { public static final int CURRENT_CHECKSUM_ALGORITHM_VERSION = 8; private int version; private String storedCheckSum; /** * Constructor. Stores a given checksum generated by a given algorithm version into the new CheckSum object. * @param checksum Generated checksum (format depends on version) * @param version The version of the Liquibase checksum generator used */ private CheckSum(String checksum, int version) { this.storedCheckSum = checksum; this.version = version; } /** * Parse the given storedCheckSum string value and return a new CheckSum object. */ public static CheckSum parse(String checksumValue) { final int CHECKSUM_OFFSET_IN_STRING = 2; if (checksumValue == null) { return null; } // The general layout of a checksum is: // <1 digit: algorithm version number>:<1..n characters alphanumeric checksum> // Example: 7:2cdf9876e74347162401315d34b83746 if (checksumValue.matches("^\\d:.*")) { // String has the information about the used checksum algorithm version return new CheckSum(checksumValue.substring(CHECKSUM_OFFSET_IN_STRING), Integer.parseInt(checksumValue.substring(0,1))); } else { // No version information found return new CheckSum(checksumValue, 1); } } /** * Return the current CheckSum algorithm version. */ public static int getCurrentVersion() { return CURRENT_CHECKSUM_ALGORITHM_VERSION; } /** * Compute a storedCheckSum of the given string. */ public static CheckSum compute(String valueToChecksum) { return new CheckSum(MD5Util.computeMD5( //remove "Unknown" unicode char 65533 Normalizer.normalize( StringUtils.standardizeLineEndings(valueToChecksum) .replaceAll("\\uFFFD", "") , Normalizer.Form.NFC) ), getCurrentVersion()); } /** * Compute a CheckSum of the given data stream (no normalization of line endings!) */ public static CheckSum compute(final InputStream stream, boolean standardizeLineEndings) { InputStream newStream = stream; if (standardizeLineEndings) { newStream = new InputStream() { @Override public int read() throws IOException { int read = stream.read(); if (read == '\r') { return read(); } else { return read; } } }; } return new CheckSum(MD5Util.computeMD5(newStream), getCurrentVersion()); } @Override public String toString() { return version+":"+this.storedCheckSum; } /** * Return the Checksum Algorithm version for this CheckSum */ public int getVersion() { return version; } @Override public int hashCode() { return toString().hashCode(); } @Override public boolean equals(Object obj) { return (obj instanceof CheckSum) && this.toString().equals(obj.toString()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy