diff --git a/src/main/java/org/roda_project/commons_ip2/validator/EARKPyIPValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/EARKPyIPValidator.java index 5bdc26f0..290d1e38 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/EARKPyIPValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/EARKPyIPValidator.java @@ -12,6 +12,7 @@ import javax.xml.parsers.ParserConfigurationException; import org.roda_project.commons_ip2.cli.model.exception.UnmarshallerException; +import org.roda_project.commons_ip2.mets_v1_12.beans.MetsType; import org.roda_project.commons_ip2.validator.common.InstatiateMets; import org.roda_project.commons_ip2.validator.components.MetsValidator; import org.roda_project.commons_ip2.validator.components.StructureValidatorImpl; @@ -264,7 +265,8 @@ private void validateSubMets(final Map subMets, final boole for (Map.Entry entry : subMets.entrySet()) { final InstatiateMets instatiateMets = new InstatiateMets(entry.getValue()); metsValidatorState.setMets(instatiateMets.instatiateMetsFile(entry.getKey())); - metsValidatorState.setIpType(metsValidatorState.getMets().getMetsHdr().getOAISPACKAGETYPE()); + final MetsType.MetsHdr subMetsHdr = metsValidatorState.getMets().getMetsHdr(); + metsValidatorState.setIpType(subMetsHdr == null ? null : subMetsHdr.getOAISPACKAGETYPE()); setupMetsValidatorState(entry.getKey(), isZip, false); validateComponents(); } diff --git a/src/main/java/org/roda_project/commons_ip2/validator/EARKSIPValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/EARKSIPValidator.java index a06ad550..b00718c7 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/EARKSIPValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/EARKSIPValidator.java @@ -11,6 +11,7 @@ import javax.xml.parsers.ParserConfigurationException; import org.roda_project.commons_ip2.cli.model.exception.UnmarshallerException; +import org.roda_project.commons_ip2.mets_v1_12.beans.MetsType; import org.roda_project.commons_ip2.validator.common.InstatiateMets; import org.roda_project.commons_ip2.validator.components.MetsValidator; import org.roda_project.commons_ip2.validator.components.StructureValidatorImpl; @@ -245,7 +246,8 @@ private void validateSubMets(final Map subMets, final boole final InstatiateMets instatiateMets = new InstatiateMets(entry.getValue()); try { metsValidatorState.setMets(instatiateMets.instatiateMetsFile(entry.getKey())); - metsValidatorState.setIpType(metsValidatorState.getMets().getMetsHdr().getOAISPACKAGETYPE()); + final MetsType.MetsHdr subMetsHdr = metsValidatorState.getMets().getMetsHdr(); + metsValidatorState.setIpType(subMetsHdr == null ? null : subMetsHdr.getOAISPACKAGETYPE()); setupMetsValidatorState(entry.getKey(), isZip, false); validateComponents(); } catch (IOException | UnmarshallerException e) { @@ -319,7 +321,8 @@ private void validateRootMets() { metsValidatorState.setIsRootMets(true); metsValidatorState.setMets(metsRoot.instatiateMetsFile(Constants.METS_FILE)); - metsValidatorState.setIpType(metsValidatorState.getMets().getMetsHdr().getOAISPACKAGETYPE()); + final MetsType.MetsHdr rootMetsHdr = metsValidatorState.getMets().getMetsHdr(); + metsValidatorState.setIpType(rootMetsHdr == null ? null : rootMetsHdr.getOAISPACKAGETYPE()); validateComponents(); } catch (IOException | UnmarshallerException e) { final String message = createExceptionMessage(e, diff --git a/src/main/java/org/roda_project/commons_ip2/validator/components/administritiveMetadataComponent/AmdSecValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/components/administritiveMetadataComponent/AmdSecValidator.java index 97c7c1f0..7efa92e7 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/components/administritiveMetadataComponent/AmdSecValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/components/administritiveMetadataComponent/AmdSecValidator.java @@ -3,6 +3,8 @@ import java.io.IOException; import java.io.InputStream; import java.net.URLDecoder; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -174,9 +176,18 @@ protected ReporterDetails validateCSIP31(final StructureValidatorState structure final String hrefDecoded = URLDecoder.decode(DecoderUtils.normalizePath(mdRef.getHref()), Constants.UTF_8); if (hrefDecoded != null) { - final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); - if (metadataFiles.containsKey(path)) { - metadataFiles.replace(path, true); + try { + final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); + if (metadataFiles.containsKey(path)) { + metadataFiles.replace(path, true); + } + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/digiprovMD/mdRef/@href (" + hrefDecoded + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); } } } @@ -189,9 +200,18 @@ protected ReporterDetails validateCSIP31(final StructureValidatorState structure final String hrefDecoded = URLDecoder.decode(DecoderUtils.normalizePath(mdRef.getHref()), Constants.UTF_8); if (hrefDecoded != null) { - final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); - if (metadataFiles.containsKey(path)) { - metadataFiles.replace(path, true); + try { + final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); + if (metadataFiles.containsKey(path)) { + metadataFiles.replace(path, true); + } + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/dmdSec/mdRef/@href (" + hrefDecoded + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); } } } @@ -444,10 +464,20 @@ protected ReporterDetails validateCSIP38(final StructureValidatorState structure message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(href))) { - message.append("mets/amdSec/digiprovMD/mdRef/@xlink:href (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(href)).append(") doesn't exists (%1$s)"); + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/digiprovMD/mdRef/@xlink:href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/amdSec/digiprovMD/mdRef/@xlink:href (").append(resolvedPath) + .append(") doesn't exists (%1$s)"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, message.toString(), false, false); } @@ -564,26 +594,25 @@ protected ReporterDetails validateCSIP41(final StructureValidatorState structure message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (metsValidatorState.isRootMets()) { - if (!structureValidatorState.getFolderManager() - .verifySize(structureValidatorState.getIpPath().resolve(href), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(structureValidatorState.getIpPath().resolve(href)).append(") isn't equal"); - return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, - Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), - metsValidatorState.isRootMets()), - false, false); - } - } else { - if (!structureValidatorState.getFolderManager() - .verifySize(Paths.get(metsValidatorState.getMetsPath()).resolve(href), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(href)).append(") isn't equal"); - return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, - Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), - metsValidatorState.isRootMets()), - false, false); - } + final Path resolvedPath; + try { + resolvedPath = metsValidatorState.isRootMets() ? structureValidatorState.getIpPath().resolve(href) + : Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/digiprovMD/mdRef/@href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifySize(resolvedPath, size)) { + message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") + .append(resolvedPath).append(") isn't equal"); + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), + metsValidatorState.isRootMets()), + false, false); } } } @@ -673,10 +702,21 @@ protected ReporterDetails validateCSIP43(final StructureValidatorState structure false, false); } } else { - if (!structureValidatorState.getFolderManager() - .verifyChecksum(Paths.get(metsValidatorState.getMetsPath()).resolve(href), checksumType, checksum)) { + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/digiprovMD/mdRef/@href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifyChecksum(resolvedPath, checksumType, + checksum)) { message.append("mets/dmdSec/mdRef/@CHECKSUM ").append(checksum).append(" in %1$s and size of file (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(href)).append(") isn't equal"); + .append(resolvedPath).append(") isn't equal"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), @@ -972,10 +1012,19 @@ protected ReporterDetails validateCSIP51(final StructureValidatorState structure message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(href))) { - message.append("mets/amdSec/rightsMD/mdRef/@xlink:href ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(href)) + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/rightsMD/mdRef/@xlink:href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/amdSec/rightsMD/mdRef/@xlink:href ").append(resolvedPath) .append(" doesn't exists (in %1$s)"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, Message.createErrorMessage( message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); @@ -1095,26 +1144,25 @@ protected ReporterDetails validateCSIP54(final StructureValidatorState structure false, false); } } else { - if (metsValidatorState.isRootMets()) { - if (!structureValidatorState.getFolderManager() - .verifySize(structureValidatorState.getIpPath().resolve(href), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(structureValidatorState.getIpPath().resolve(href)).append(") isn't equal"); - return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, - Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), - metsValidatorState.isRootMets()), - false, false); - } - } else { - if (!structureValidatorState.getFolderManager() - .verifySize(Paths.get(metsValidatorState.getMetsPath()).resolve(href), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(href)).append(") isn't equal"); - return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, - Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), - metsValidatorState.isRootMets()), - false, false); - } + final Path resolvedPath; + try { + resolvedPath = metsValidatorState.isRootMets() ? structureValidatorState.getIpPath().resolve(href) + : Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/rightsMD/mdRef/@href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifySize(resolvedPath, size)) { + message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") + .append(resolvedPath).append(") isn't equal"); + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), + metsValidatorState.isRootMets()), + false, false); } } } @@ -1193,20 +1241,35 @@ protected ReporterDetails validateCSIP56(final StructureValidatorState structure } if (!structureValidatorState.getZipManager().verifyChecksum(structureValidatorState.getIpPath(), filePath.toString(), checksumType, checksum)) { + Path displayPath; + try { + displayPath = Paths.get(metsValidatorState.getMetsPath()).resolve(filePath.toString()); + } catch (InvalidPathException e) { + displayPath = null; + } message.append("mets/dmdSec/mdRef/@CHECKSUM ").append(checksum).append(" and checksum of file (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath.toString())) - .append(") isn't equal (%1$s)"); + .append(displayPath != null ? displayPath : filePath).append(") isn't equal (%1$s)"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (!structureValidatorState.getFolderManager().verifyChecksum( - Paths.get(metsValidatorState.getMetsPath()).resolve(href), checksumType, checksum)) { + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/amdSec/rightsMD/mdRef/@href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifyChecksum(resolvedPath, checksumType, + checksum)) { message.append("mets/dmdSec/mdRef/@CHECKSUM ").append(checksum).append(" and checksum of file (") - .append(Paths.get(metsValidatorState.getMetsPath()) - .resolve(Paths.get(metsValidatorState.getMetsPath()).resolve(href))) + .append(Paths.get(metsValidatorState.getMetsPath()).resolve(resolvedPath)) .append(") isn't equal (in %1$s)"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), diff --git a/src/main/java/org/roda_project/commons_ip2/validator/components/descriptiveMetadataComponent/DmdSecValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/components/descriptiveMetadataComponent/DmdSecValidator.java index 4ab8b3f8..200f027c 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/components/descriptiveMetadataComponent/DmdSecValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/components/descriptiveMetadataComponent/DmdSecValidator.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URLDecoder; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; @@ -92,8 +93,15 @@ protected ReporterDetails validateCSIP17(final StructureValidatorState structure if (mdRef != null && mdRef.getHref() != null) { String hrefDecoded = URLDecoder.decode(DecoderUtils.normalizePath(mdRef.getHref()), Constants.UTF_8); - Path path = Paths.get(hrefDecoded); - hrefDecoded = path.normalize().toString(); + try { + hrefDecoded = Paths.get(hrefDecoded).normalize().toString(); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/dmdSec/mdRef/@href (" + hrefDecoded + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } if (metsValidatorState.isRootMets()) { if (metadataFiles.containsKey(mets.getOBJID() + Constants.SEPARATOR + hrefDecoded)) { metadataFiles.replace(mets.getOBJID() + Constants.SEPARATOR + hrefDecoded, true); @@ -183,9 +191,17 @@ protected ReporterDetails validateCSIP17(final StructureValidatorState structure final String hrefDecoded = URLDecoder.decode(DecoderUtils.normalizePath(mdRef.getHref()), Constants.UTF_8); if (hrefDecoded != null) { - final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); - if (metadataFiles.containsKey(path)) { - metadataFiles.replace(path, true); + try { + final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); + if (metadataFiles.containsKey(path)) { + metadataFiles.replace(path, true); + } + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/dmdSec/mdRef/@href (" + hrefDecoded + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); } } } @@ -198,9 +214,19 @@ protected ReporterDetails validateCSIP17(final StructureValidatorState structure final String hrefDecoded = URLDecoder.decode(DecoderUtils.normalizePath(mdRef.getHref()), Constants.UTF_8); if (hrefDecoded != null) { - final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded).toString(); - if (metadataFiles.containsKey(path)) { - metadataFiles.replace(path, true); + try { + final String path = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded) + .toString(); + if (metadataFiles.containsKey(path)) { + metadataFiles.replace(path, true); + } + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/amdSec/*/mdRef/@href (" + hrefDecoded + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); } } } @@ -444,22 +470,28 @@ protected ReporterDetails validateCSIP24(final StructureValidatorState structure metsValidatorState.isRootMets())); } } else { - if (StringUtils.isBlank(href)){ - message.append("mets/dmdSec/mdRef/@xlink:href ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded)) - .append(" in %1$s is empty"); + Path resolvedPath = null; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded); + } catch (InvalidPathException e) { details.setValid(false); - details.addIssue(Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), - metsValidatorState.isRootMets())); + details.addIssue(Message.createErrorMessage( + "mets/dmdSec/mdRef/@xlink:href (" + hrefDecoded + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets())); } - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded))) { - message.append("mets/dmdSec/mdRef/@xlink:href ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded)) - .append(" in %1$s does not exist"); - details.setValid(false); - details.addIssue(Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), - metsValidatorState.isRootMets())); + if (resolvedPath != null) { + if (StringUtils.isBlank(href)) { + message.append("mets/dmdSec/mdRef/@xlink:href ").append(resolvedPath).append(" in %1$s is empty"); + details.setValid(false); + details.addIssue(Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), + metsValidatorState.isRootMets())); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/dmdSec/mdRef/@xlink:href ").append(resolvedPath).append(" in %1$s does not exist"); + details.setValid(false); + details.addIssue(Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), + metsValidatorState.isRootMets())); + } } } } else { @@ -567,22 +599,23 @@ protected ReporterDetails validateCSIP27(final StructureValidatorState structure metsValidatorState.isRootMets()),false, false); } } else { - if (metsValidatorState.isRootMets()) { - if (!structureValidatorState.getFolderManager() - .verifySize(structureValidatorState.getIpPath().resolve(hrefDecoded), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(structureValidatorState.getIpPath().resolve(hrefDecoded)).append(") isn't equal"); - return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage( - message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); - } - } else { - if (!structureValidatorState.getFolderManager() - .verifySize(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(structureValidatorState.getIpPath().resolve(hrefDecoded).toString()).append(") isn't equal"); - return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage( - message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); - } + final Path resolvedHrefPath; + try { + resolvedHrefPath = metsValidatorState.isRootMets() + ? structureValidatorState.getIpPath().resolve(hrefDecoded) + : Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/dmdSec/mdRef/@href (" + hrefDecoded + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifySize(resolvedHrefPath, size)) { + message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") + .append(resolvedHrefPath).append(") isn't equal"); + return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } } else { @@ -662,11 +695,20 @@ protected ReporterDetails validateCSIP29(final StructureValidatorState structure false, false); } } else { - if (!structureValidatorState.getFolderManager() - .verifyChecksum(Paths.get(metsValidatorState.getMetsPath()).resolve(file), checksumType, checksum)) { + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(file); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/dmdSec/mdRef/@href (" + file + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifyChecksum(resolvedPath, checksumType, + checksum)) { message.append("mets/dmdSec/mdRef/@CHECKSUM ").append(checksum) - .append(" in %1$s and checksum of file (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(file)).append(") isn't equal"); + .append(" in %1$s and checksum of file (").append(resolvedPath).append(") isn't equal"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), diff --git a/src/main/java/org/roda_project/commons_ip2/validator/components/fileComponent/StructValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/components/fileComponent/StructValidator.java index e8e6d2a7..18626045 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/components/fileComponent/StructValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/components/fileComponent/StructValidator.java @@ -533,6 +533,10 @@ protected ReporterDetails validateCSIPSTR16(final StructureValidatorState struct * @return if the IP is a ZIP file */ protected boolean isZipFile(Path ipPath, byte[] zipMagicNumber, String moduleName) { + if (Files.isDirectory(ipPath)) { + return false; + } + boolean isZip = true; byte[] buffer = new byte[zipMagicNumber.length]; diff --git a/src/main/java/org/roda_project/commons_ip2/validator/components/fileSectionComponent/FileSecValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/components/fileSectionComponent/FileSecValidator.java index 1905f5a2..6c4b4bce 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/components/fileSectionComponent/FileSecValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/components/fileSectionComponent/FileSecValidator.java @@ -4,6 +4,8 @@ import java.io.InputStream; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -118,10 +120,19 @@ protected ReporterDetails validateCSIP60(final StructureValidatorState structure for (FileType.FLocat flocat : fLocats) { final String filePath = URLDecoder.decode(DecoderUtils.normalizePath(flocat.getHref()), StandardCharsets.UTF_8); - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath))) { - message.append("mets/fileSec/fileGrp[@USE=’Documentation’] ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath)) + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(filePath); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/fileSec/fileGrp[@USE=’Documentation’] (" + filePath + ") is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/fileSec/fileGrp[@USE=’Documentation’] ").append(resolvedPath) .append(" doesn't exists (in %1$s)"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); @@ -171,10 +182,18 @@ protected ReporterDetails validateCSIP113(final StructureValidatorState structur } else { for (FileType.FLocat flocat : fLocats) { final String filePath = URLDecoder.decode(DecoderUtils.normalizePath(flocat.getHref()), StandardCharsets.UTF_8); - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath))) { - message.append("mets/fileSec/fileGrp[@USE=’Schemas’] ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath)) + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(filePath); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/fileSec/fileGrp[@USE=’Schemas’] (" + filePath + ") is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/fileSec/fileGrp[@USE=’Schemas’] ").append(resolvedPath) .append(" doesn't exists (%1$s)"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); @@ -222,10 +241,19 @@ protected ReporterDetails validateCSIP114(final StructureValidatorState structur } else { for (FileType.FLocat flocat : fLocats) { final String filePath = URLDecoder.decode(DecoderUtils.normalizePath(flocat.getHref()), StandardCharsets.UTF_8); - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath))) { - message.append("mets/fileSec/fileGrp[@USE=’Representations’] ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath)) + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(filePath); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/fileSec/fileGrp[@USE=’Representations’] (" + filePath + ") is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/fileSec/fileGrp[@USE=’Representations’] ").append(resolvedPath) .append(" doesn't exists (%1$s)"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); @@ -385,11 +413,20 @@ protected ReporterDetails validateCSIP64(final StructureValidatorState structure metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (!structureValidatorState.getFolderManager() - .checkDirectory(Paths.get(metsValidatorState.getMetsPath()).resolve(use.toLowerCase()))) { + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(use.toLowerCase()); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "Value " + use + " in %1$s for mets/fileSec/fileGrp/@USE is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkDirectory(resolvedPath)) { message.append("Value ").append(use) .append(" in %1$s for mets/fileSec/fileGrp/@USE " + "doesn't match with any directory in sip(") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(use.toLowerCase())).append(")"); + .append(resolvedPath).append(")"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } @@ -462,7 +499,16 @@ protected ReporterDetails validateCSIP66(final StructureValidatorState structure filePath.append(metsValidatorState.getMetsPath()).append(hrefDecoded); } } else { - filePath.append(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded)); + try { + filePath.append(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded)); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/fileSec/fileGrp/file/FLocat/@href (" + hrefDecoded + + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } } if (metsValidatorState.getMetsFiles().containsKey(filePath.toString())) { metsValidatorState.getMetsFiles().replace(filePath.toString(), true); @@ -576,26 +622,23 @@ protected ReporterDetails validateCSIP69(final StructureValidatorState structure metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (metsValidatorState.isRootMets()) { - if (!structureValidatorState.getFolderManager() - .verifySize(structureValidatorState.getIpPath().resolve(href), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(structureValidatorState.getIpPath() - .resolve(structureValidatorState.getIpPath().resolve(href))) - .append(") isn't equal"); - return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), - metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); - } - } else { - if (!structureValidatorState.getFolderManager() - .verifySize(Paths.get(metsValidatorState.getMetsPath()).resolve(href), size)) { - message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") - .append(structureValidatorState.getIpPath() - .resolve(Paths.get(metsValidatorState.getMetsPath()).resolve(href))) - .append(") isn't equal"); - return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), - metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); - } + final Path resolvedHrefPath; + try { + resolvedHrefPath = metsValidatorState.isRootMets() + ? structureValidatorState.getIpPath().resolve(href) + : Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/dmdSec/mdRef/@href (" + href + ") in %1$s is not a valid path: " + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifySize(resolvedHrefPath, size)) { + message.append("mets/dmdSec/mdRef/@SIZE ").append(size).append(" in %1$s and size of file (") + .append(structureValidatorState.getIpPath().resolve(resolvedHrefPath)).append(") isn't equal"); + return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } } else { @@ -715,11 +758,21 @@ protected ReporterDetails validateCSIP71(final StructureValidatorState structure metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (!structureValidatorState.getFolderManager().verifyChecksum( - Paths.get(metsValidatorState.getMetsPath()).resolve(filePath), checksumType, checksum)) { + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(filePath); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/fileSec/fileGrp/file/flocat/@href (" + filePath + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().verifyChecksum(resolvedPath, checksumType, + checksum)) { message.append("mets/dmdSec/mdRef/@CHECKSUM ").append(checksum) - .append(" in %1$s and checksum of file (") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(filePath)).append(") isn't equal"); + .append(" in %1$s and checksum of file (").append(resolvedPath).append(") isn't equal"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } @@ -1047,10 +1100,19 @@ protected ReporterDetails validateCSIP79(final StructureValidatorState structure metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); } } else { - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded))) { - message.append("mets/fileSec/fileGrp/file/@xlink:href ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded)) + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(hrefDecoded); + } catch (InvalidPathException e) { + return new ReporterDetails(getCSIPVersion(), + Message.createErrorMessage( + "mets/fileSec/fileGrp/file/@xlink:href (" + hrefDecoded + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/fileSec/fileGrp/file/@xlink:href ").append(resolvedPath) .append(" does not exist (%1$s)"); return new ReporterDetails(getCSIPVersion(), Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), false, false); diff --git a/src/main/java/org/roda_project/commons_ip2/validator/components/structuralMapComponent/StructMapValidator.java b/src/main/java/org/roda_project/commons_ip2/validator/components/structuralMapComponent/StructMapValidator.java index ee7d557c..e0a60df0 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/components/structuralMapComponent/StructMapValidator.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/components/structuralMapComponent/StructMapValidator.java @@ -3,6 +3,8 @@ import java.io.IOException; import java.io.InputStream; import java.net.URLDecoder; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; @@ -1102,7 +1104,7 @@ protected ReporterDetails validateCSIP104(final MetsValidatorState metsValidator if (structMap != null) { if (fileGrps != null && !fileGrps.isEmpty()) { for (MetsType.FileSec.FileGrp fileGrp : fileGrps) { - if (fileGrp.getUSE().equals("Representations")) { + if ("Representations".equals(fileGrp.getUSE())) { fileGrpRepresentations++; } } @@ -1166,7 +1168,7 @@ protected ReporterDetails validateCSIP119(final MetsValidatorState metsValidator for (DivType.Fptr fptr : ftprs) { final String fileid = ((MetsType.FileSec.FileGrp) fptr.getFILEID()).getID(); for (MetsType.FileSec.FileGrp fileGrp : fileGrps) { - if (fileGrp.getUSE().equals("Representations")) { + if ("Representations".equals(fileGrp.getUSE())) { final String id = fileGrp.getID(); if (id.equals(fileid)) { found = true; @@ -1320,11 +1322,20 @@ protected ReporterDetails validateCSIP107(final StructureValidatorState structur } else { normalizedLable = label.toLowerCase(); } - if (!structureValidatorState.getFolderManager() - .checkDirectory(Paths.get(metsValidatorState.getMetsPath()).resolve(normalizedLable))) { + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(normalizedLable); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/structMap[@LABEL='CSIP']/div/div/@LABEL (" + label + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkDirectory(resolvedPath)) { message.append("mets/structMap[@LABEL='CSIP']/div/div/@LABEL in %1$s ( ").append(label).append(" )") - .append("does not lead to a directory ( ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(label.toLowerCase())).append(" )"); + .append("does not lead to a directory ( ").append(resolvedPath).append(" )"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), @@ -1469,10 +1480,19 @@ protected ReporterDetails validateCSIP110(final StructureValidatorState structur false, false); } } else { - if (!structureValidatorState.getFolderManager() - .checkPathExists(Paths.get(metsValidatorState.getMetsPath()).resolve(href))) { - message.append("mets/structMap/div/div/mptr/@xlink:href ") - .append(Paths.get(metsValidatorState.getMetsPath()).resolve(href)) + final Path resolvedPath; + try { + resolvedPath = Paths.get(metsValidatorState.getMetsPath()).resolve(href); + } catch (InvalidPathException e) { + return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, + Message.createErrorMessage( + "mets/structMap/div/div/mptr/@xlink:href (" + href + ") in %1$s is not a valid path: " + + e.getReason(), + metsValidatorState.getMetsName(), metsValidatorState.isRootMets()), + false, false); + } + if (!structureValidatorState.getFolderManager().checkPathExists(resolvedPath)) { + message.append("mets/structMap/div/div/mptr/@xlink:href ").append(resolvedPath) .append(" doesn't exists (in %1$s)"); return new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, Message.createErrorMessage(message.toString(), metsValidatorState.getMetsName(), diff --git a/src/main/java/org/roda_project/commons_ip2/validator/utils/DecoderUtils.java b/src/main/java/org/roda_project/commons_ip2/validator/utils/DecoderUtils.java index 5c7c2a72..a8d0f977 100644 --- a/src/main/java/org/roda_project/commons_ip2/validator/utils/DecoderUtils.java +++ b/src/main/java/org/roda_project/commons_ip2/validator/utils/DecoderUtils.java @@ -1,5 +1,6 @@ package org.roda_project.commons_ip2.validator.utils; +import java.nio.file.InvalidPathException; import java.nio.file.Paths; /** @@ -9,8 +10,15 @@ public class DecoderUtils { public static String normalizePath(String href) { - return Paths.get(href).normalize() // Removes unnecessary elements (like "." or "..") - .toString().replace("\\", "/"); // Assure it returns in unix-style format + try { + return Paths.get(href).normalize() // Removes unnecessary elements (like "." or "..") + .toString().replace("\\", "/"); // Assure it returns in unix-style format + } catch (InvalidPathException e) { + // href contains a character that isn't valid in a filesystem path (e.g. a NUL + // character); return it unchanged so callers can still report it as an issue + // instead of crashing. + return href; + } }