Skip to content

Commit

Permalink
Added the functionality to specify a checksum algorithm #63
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosjepard committed Jun 16, 2023
1 parent bddeba1 commit d7cb934
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 8 deletions.
16 changes: 16 additions & 0 deletions CHECKSUM_ALGORITHMS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Checksum Algorithms

These are checksum algorithms supported by this project:
- SHA3-512
- SHA-384
- SHA
- SHA3-384
- SHA-224
- SHA-512/256
- SHA-256 (default if no algorithm is specified)
- MD2
- SHA-512/224
- SHA3-256
- SHA-512
- MD5
- SHA3-224
11 changes: 11 additions & 0 deletions src/main/java/org/roda_project/commons_ip2/model/IP.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ public abstract class IP implements IPInterface {

private ValidationReport validationReport;

private String checksumAlgorithm;

public IP() {
this.setId(Utils.generateRandomAndPrefixedUUID());
this.profile = "NOT_DEFINED";
Expand All @@ -65,6 +67,7 @@ public IP() {
this.ancestors = new ArrayList<>();

this.description = "";
this.checksumAlgorithm="SHA-256";

this.descriptiveMetadata = new ArrayList<>();
this.preservationMetadata = new ArrayList<>();
Expand Down Expand Up @@ -97,6 +100,14 @@ public IP setId(final String id) {
return this;
}

public void setChecksum(final String checksum) {
this.checksumAlgorithm = checksum;
}

public String getChecksum() {
return this.checksumAlgorithm;
}

@Override
public String getId() {
return ids.stream().findFirst().orElse("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public static void zip(Map<String, ZipEntryInfo> files, OutputStream out, SIP si
}

Set<String> nonMetsChecksumAlgorithms = new TreeSet<>();
nonMetsChecksumAlgorithms.add(IPConstants.CHECKSUM_ALGORITHM);
nonMetsChecksumAlgorithms.add(sip.getChecksum());
Set<String> metsChecksumAlgorithms = new TreeSet<>();
metsChecksumAlgorithms.addAll(nonMetsChecksumAlgorithms);
metsChecksumAlgorithms.addAll(sip.getExtraChecksumAlgorithms());
Expand Down Expand Up @@ -152,8 +152,8 @@ public static void zip(Map<String, ZipEntryInfo> files, OutputStream out, SIP si
}

LOGGER.debug("Done zipping file");
String checksum = checksums.get(IPConstants.CHECKSUM_ALGORITHM);
String checksumType = IPConstants.CHECKSUM_ALGORITHM;
String checksum = checksums.get(sip.getChecksum());
String checksumType = sip.getChecksum();
file.setChecksum(checksum);
file.setChecksumAlgorithm(checksumType);
if (file instanceof METSFileTypeZipEntryInfo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ public final class CLIConstants {

public static final String CLI_CREATE_OPTION_SUBMITTER_AGENT_ID = "-aid";

/**
* CLI option to give the checksum algorithm.
*/
public static final String CLI_CREATE_OPTION_CHECKSUM_ALG = "-ca";

/* OPTIONS WITHOUT "-" char */

/**
Expand Down Expand Up @@ -178,6 +183,16 @@ public final class CLIConstants {
*/
public static final String CLI_CREATE_LONG_OPTION_REPRESENTATION_ID_WITHOUT_IDENT = "representation-id";

/**
* Long option checksum algorithm.
*/
public static final String CLI_CREATE_LONG_OPTION_CHECKSUM_ALG = "checksum-alg";

/**
* Short option checksum algorithm.
*/
public static final String CLI_CREATE_SHORT_OPTION_CHECKSUM_ALG = "ca";

/**
* Short option representation id without ident.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ public CLICreator() {
representationID.setRequired(false);
parameters.addOption(representationID);

final Option checksumAlg = new Option(CLIConstants.CLI_CREATE_SHORT_OPTION_CHECKSUM_ALG,
CLIConstants.CLI_CREATE_LONG_OPTION_CHECKSUM_ALG, true, "Checksum Algorithms");
checksumAlg.setArgs(1);
checksumAlg.setRequired(false);
parameters.addOption(checksumAlg);

final Option representationType = new Option(CLIConstants.CLI_CREATE_SHORT_OPTION_REPRESENTATION_TYPE_WITHOUT_IDENT,
CLIConstants.CLI_CREATE_LONG_OPTION_REPRESENTATION_TYPE_WITHOUT_IDENT, true, "Representation Type");
representationType.setArgs(1);
Expand Down Expand Up @@ -108,7 +114,7 @@ public CLICreator() {

/**
* Start the creation CLI.
*
*
* @param args
* the args given to the CLI.
* @return a exit code.
Expand Down Expand Up @@ -164,7 +170,10 @@ public int start(final String[] args) {
.getOptionValue(CLIConstants.CLI_CREATE_LONG_OPTION_SUBMITTER_AGENT_ID_WITHOUT_IDENT) == null
? commandLine.getOptionValue(CLIConstants.CLI_CREATE_SHORT_OPTION_SUBMITTER_AGENT_ID_WITHOUT_IDENT)
: commandLine.getOptionValue(CLIConstants.CLI_CREATE_LONG_OPTION_SUBMITTER_AGENT_ID_WITHOUT_IDENT);

final String checkSum = commandLine
.getOptionValue(CLIConstants.CLI_CREATE_LONG_OPTION_CHECKSUM_ALG) == null
? commandLine.getOptionValue(CLIConstants.CLI_CREATE_SHORT_OPTION_CHECKSUM_ALG)
: commandLine.getOptionValue(CLIConstants.CLI_CREATE_LONG_OPTION_CHECKSUM_ALG);
if (!SipCreatorUtils.validateAllOptions(metadataFile, documentation, representationData)) {
CLIUtils.printErrors(System.out,
"You have to add at least one metadata file or documentation file or representation data file");
Expand All @@ -187,11 +196,16 @@ public int start(final String[] args) {
return ExitCodes.EXIT_CODE_CREATE_INVALID_PATHS;
}

if(!SipCreatorUtils.validateChecksumAlg(checkSum)){
CLIUtils.printErrors(System.out, "Make sure that the checksum algorithm is valid. You can check the " +
"existing algorithms here: https://github.com/keeps/commons-ip/blob/master/CHECKSUM_ALGORITHMS.md");
return ExitCodes.EXIT_CODE_CREATE_INVALID_CHECKSUM;
}

try {
final Path eark2SIP = SipCreatorUtils.createEARK2SIP(metadataFile, metadataType, metadataVersion,
representationData, representationType, representationID, sipID, ancestors, documentation,
getClass().getPackage().getImplementationVersion(), path, submitterAgentName, submitterAgentID);
getClass().getPackage().getImplementationVersion(), path, submitterAgentName, submitterAgentID, checkSum);
System.out.println("Created the sip in " + eark2SIP.normalize().toAbsolutePath());
} catch (IPException | InterruptedException e) {
CLIUtils.printErrors(System.out, "Can't create the sip");
Expand Down Expand Up @@ -251,6 +265,9 @@ private static void printUsageCreate(final PrintStream printStream) {
out.append(CLIConstants.TAB).append(CLIConstants.CLI_CREATE_OPTION_SUBMITTER_AGENT_ID)
.append(", --submitter-agent-id").append(CLIConstants.DOUBLE_TAB)
.append("(optional) The identification code of the submitter id").append(CLIConstants.END_OF_LINE);
out.append(CLIConstants.TAB).append(CLIConstants.CLI_CREATE_OPTION_CHECKSUM_ALG)
.append(", --checksum-alg").append(CLIConstants.DOUBLE_TAB)
.append("(optional) Checksum Algorithm").append(CLIConstants.END_OF_LINE);
printStream.append(out).flush();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ public final class ExitCodes {
*/
public static final int EXIT_CODE_CREATE_INVALID_PATHS = 4;

/**
* Exit code when the given checksum algorithms are invalid.
*/
public static final int EXIT_CODE_CREATE_INVALID_CHECKSUM = 5;



private ExitCodes() {
// do nothing.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.security.MessageDigest;

import org.roda_project.commons_ip.utils.IPException;
import org.roda_project.commons_ip2.model.IPContentInformationType;
Expand Down Expand Up @@ -126,6 +128,25 @@ public static boolean validateDocumentationPaths(final String[] documentationPat
return true;
}

/**
* Check if the checksum algorithms exist.
*
* @param checksumAlg
* the checksum algorithm(s).
* @return if exists all the algorithms or not.
*/
public static boolean validateChecksumAlg(final String checksumAlg) {
if (checksumAlg != null) {
try {
MessageDigest.getInstance(checksumAlg);
} catch (NoSuchAlgorithmException e) {
return false;
}
}
return true;
}


/**
* Create the EARK2 SIP with the args passed to the CLI.
*
Expand Down Expand Up @@ -164,7 +185,7 @@ public static boolean validateDocumentationPaths(final String[] documentationPat
public static Path createEARK2SIP(final String metadataFile, final String metadataType, final String metadataVersion,
final String[] representationData, final String representationType, final String representationID,
final String sipID, final String[] ancestors, final String[] documentation, final String softwareVersion,
final String path, final String submitterAgentName, final String submitterAgentID)
final String path, final String submitterAgentName, final String submitterAgentID, final String checksum)
throws IPException, InterruptedException {
String id = sipID;
if (id == null) {
Expand All @@ -183,9 +204,12 @@ public static Path createEARK2SIP(final String metadataFile, final String metada

sip.addCreatorSoftwareAgent("RODA Commons IP", softVersion);
sip.addSubmitterAgent(submitterAgentName, submitterAgentID);

sip.setDescription("SIP created by commons-ip cli tool");

if (checksum != null) {
sip.setChecksum(checksum);
}

if (metadataFile != null) {
try {
addMetadataToSIP(sip, metadataFile, metadataType, metadataVersion);
Expand Down

0 comments on commit d7cb934

Please sign in to comment.