diff --git a/pom.xml b/pom.xml index 8cbe171..72267b3 100644 --- a/pom.xml +++ b/pom.xml @@ -246,7 +246,7 @@ org.roda-project commons-ip2 - 2.6.2 + 2.9.0-SNAPSHOT diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/builder/CITSBuilder.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/builder/CITSBuilder.java index ccd693e..238cd36 100644 --- a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/builder/CITSBuilder.java +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/builder/CITSBuilder.java @@ -1,33 +1,93 @@ package org.keeps.digitalpreservation.commonsip.citserms.builder; + +import org.roda_project.commons_ip.utils.IPEnums; +import org.roda_project.commons_ip2.cli.model.args.RepresentationGroup; import org.roda_project.commons_ip.utils.IPException; +import org.roda_project.commons_ip2.cli.model.args.MetadataGroup; +import org.roda_project.commons_ip2.cli.model.exception.SIPBuilderException; +import org.roda_project.commons_ip2.cli.utils.SIPBuilder; +import org.roda_project.commons_ip2.cli.utils.SIPBuilderUtils; +import org.roda_project.commons_ip2.model.IPContentType; +import org.roda_project.commons_ip2.model.impl.eark.EARKSIP; import org.roda_project.commons_ip2.model.IPContentInformationType; import org.roda_project.commons_ip2.model.IPRepresentation; -import org.roda_project.commons_ip2.model.impl.eark.EARKSIP; +import org.roda_project.commons_ip2.model.impl.eark.out.writers.factory.ZipWriteStrategyFactory; +import org.roda_project.commons_ip2.model.impl.eark.out.writers.strategy.WriteStrategy; +import org.roda_project.commons_ip2.model.impl.eark.out.writers.strategy.ZipWriteStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; public class CITSBuilder { - public void build() throws IPException, InterruptedException { + private static final Logger LOGGER = LoggerFactory.getLogger(CITSBuilder.class);; + private List metadataArgs = new ArrayList<>(); + private List representationArgs = new ArrayList<>(); + private boolean targetOnly; + private String path; + private String submitterAgentName; + private String submitterAgentId; + private String sipId; + private List ancestors; + private List documentation = new ArrayList<>(); + + private String softwareVersion; + private Boolean overrideSchema; + + + public CITSBuilder setMetadataArgs(List metadataArgs) { + this.metadataArgs = metadataArgs; + return this; + } + + public CITSBuilder setRepresentationArgs(List representationArgs) { + this.representationArgs = representationArgs; + return this; + } + + public CITSBuilder setSubmitterAgentName(String submitterAgentName) { + this.submitterAgentName = submitterAgentName; + return this; + } + + public void build() throws InterruptedException, IPException, IPException, SIPBuilderException { EARKSIP earksip = new EARKSIP(); - earksip.setProfile("https://citssiard.dilcis.eu/profile/E-ARK-SIARD-ROOT.xml"); + //Isto ainda n se sabe + //earksip.setProfile("https://citssiard.dilcis.eu/profile/E-ARK-SIARD-ROOT.xml"); + + + IPContentInformationType erms = new IPContentInformationType("citserms_v2_1"); + erms.setOtherType("citserms_v2_1"); + + earksip.addSubmitterAgent(submitterAgentName, submitterAgentId); - IPContentInformationType siard2 = new IPContentInformationType("SIARD2"); - siard2.setOtherType("SIARD_2.1"); + earksip.setContentType(IPContentType.getDataset()); - earksip.setContentInformationType(siard2); + earksip.setContentInformationType(erms); - earksip.setId("test"); + try { + SIPBuilderUtils.addMetadataGroupsToSIP(earksip, metadataArgs); + } catch (IPException e) { + LOGGER.debug("Cannot add metadata to the SIP", e); + throw new SIPBuilderException("Cannot add metadata to the SIP."); + } - IPRepresentation ipRepresentation = new IPRepresentation(); + try { + SIPBuilderUtils.addRepresentationGroupsToErmsSIP(earksip, representationArgs, true); + } catch (IPException e) { + LOGGER.debug("Cannot add representation to the SIP", e); + throw new SIPBuilderException("Cannot add representation to the SIP"); + } - ipRepresentation.setContentInformationType(new IPContentInformationType(IPContentInformationType.IPContentInformationTypeEnum.SIARD2)); + WriteStrategy writeStrategy = new ZipWriteStrategyFactory().create(Paths.get(System.getProperty("user.dir"))); - earksip.addRepresentation(ipRepresentation); + Path build = earksip.build(writeStrategy, null, IPEnums.SipType.ERMS); - Path build = earksip.build(Paths.get("/home/mguimaraes/Desktop")); System.out.printf(build.toString()); } } diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Create.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Create.java index 8c922b3..e556295 100644 --- a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Create.java +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Create.java @@ -1,11 +1,13 @@ package org.keeps.digitalpreservation.commonsip.citserms.cli; import org.keeps.digitalpreservation.commonsip.citserms.builder.CITSBuilder; -import org.keeps.digitalpreservation.commonsip.citserms.cli.exception.CLIException; import org.keeps.digitalpreservation.commonsip.citserms.cli.model.ExitCodes; -import org.keeps.digitalpreservation.commonsip.citserms.cli.model.args.MetadataGroup; -import org.keeps.digitalpreservation.commonsip.citserms.cli.model.args.RepresentationGroup; +import org.roda_project.commons_ip2.cli.model.args.RepresentationGroup; import org.roda_project.commons_ip.utils.IPException; +import org.roda_project.commons_ip2.cli.model.args.MetadataGroup; +import org.roda_project.commons_ip2.cli.model.exception.InvalidPathException; +import org.roda_project.commons_ip2.cli.model.exception.SIPBuilderException; +import org.roda_project.commons_ip2.cli.utils.CLI.CreateCommandUtils; import picocli.CommandLine; import java.util.ArrayList; @@ -15,7 +17,7 @@ /** * @author Miguel Guimarães */ -@CommandLine.Command(name = "create", description = "Creates E-ARK CITS SIARD packages%n", showDefaultValues = true) +@CommandLine.Command(name = "create", description = "Creates E-ARK CITS ERMS packages%n", showDefaultValues = true) public class Create implements Callable { @CommandLine.ArgGroup(exclusive = false, multiplicity = "0..*", heading = "%nThis is the descriptive metadata section:%n") @@ -24,6 +26,9 @@ public class Create implements Callable { @CommandLine.ArgGroup(exclusive = false, multiplicity = "0..*", heading = "%nThis is the representation section:%n") List representationListArgs = new ArrayList<>(); + @CommandLine.Option(names = {"--submitter-name"}, description = "Submitter agent name", paramLabel = "") + String submitterAgentName; + @CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = "Show this help message and exit.") boolean help; @@ -35,15 +40,20 @@ public class Create implements Callable { List documentation = new ArrayList<>(); @Override - public Integer call() throws CLIException { + public Integer call() throws InvalidPathException { + + if (!CreateCommandUtils.validateMetadataSchemaPaths(metadataListArgs)) { + throw new InvalidPathException("Make sure if all the descriptive metadata schema paths exists"); + } + //if (representationListArgs.isEmpty()) { // throw new CLIException("There MUST be a minimum of one representation"); // } CITSBuilder builder = new CITSBuilder(); try { - builder.build(); - } catch (IPException | InterruptedException e) { + builder.setMetadataArgs(metadataListArgs).setRepresentationArgs(representationListArgs).setSubmitterAgentName(submitterAgentName).build(); + } catch (InterruptedException | IPException | SIPBuilderException e) { System.out.printf(e.getMessage()); System.out.println("TESTE!!!!"); } diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Main.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Main.java index b05f49a..96db46d 100644 --- a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Main.java +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Main.java @@ -15,7 +15,7 @@ /** * @author Miguel Guimarães */ -@CommandLine.Command(name = "commons-ip-cits-siard", subcommands = {Create.class, +@CommandLine.Command(name = "commons-ip-cits-ERMS", subcommands = {Create.class, Validate.class}, mixinStandardHelpOptions = true, versionProvider = VersionProvider.class) public class Main implements Runnable { diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Validate.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Validate.java index af77615..4662ee7 100644 --- a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Validate.java +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/cli/Validate.java @@ -1,10 +1,119 @@ package org.keeps.digitalpreservation.commonsip.citserms.cli; +import org.keeps.digitalpreservation.commonsip.citserms.validator.EARKERMSValidator; +import org.roda_project.commons_ip2.cli.model.ExitCodes; +import org.roda_project.commons_ip2.cli.model.enums.ReportTypeEnums; +import org.roda_project.commons_ip2.cli.model.exception.CLIException; +import org.roda_project.commons_ip2.cli.model.exception.ValidationException; +import org.roda_project.commons_ip2.cli.utils.CLI.ValidateCommandUtils; +import org.roda_project.commons_ip2.utils.LogSystem; +import org.roda_project.commons_ip2.validator.EARKPyIPValidator; +import org.roda_project.commons_ip2.validator.EARKSIPValidator; +import org.roda_project.commons_ip2.validator.observer.ProgressValidationLoggerObserver; +import org.roda_project.commons_ip2.validator.reporter.ValidationReportOutputJSONPyIP; +import org.roda_project.commons_ip2.validator.reporter.ValidationReportOutputJson; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; import picocli.CommandLine; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.concurrent.Callable; + +import static org.roda_project.commons_ip2.cli.model.enums.ReportTypeEnums.ReportType.COMMONS_IP; + /** * @author Miguel Guimarães */ @CommandLine.Command(name = "validate", showDefaultValues = true, description = "Validates E-ARK CITS SIARD packages against the specification") -public class Validate { +public class Validate implements Callable { + + private static final Logger LOGGER = LoggerFactory.getLogger(org.roda_project.commons_ip2.cli.Validate.class); + @CommandLine.Spec + CommandLine.Model.CommandSpec spec; + @CommandLine.Option(names = {"-h", "--help"}, usageHelp = true, description = "display this help and exit") + boolean help; + + @CommandLine.Option(names = {"-i", + "--inputs"}, split = ",", required = true, description = "Paths to the SIPs archive file or files", paramLabel = "") + List sipPaths; + + @CommandLine.Option(names = {"-r", + "--reporter-type"}, paramLabel = "", description = "Report type (possible values: ${COMPLETION-CANDIDATES})") + ReportTypeEnums.ReportType reportType = COMMONS_IP; + + @CommandLine.Option(names = {"-o", + "--output-report-dir"}, paramLabel = "", description = "Path to save the validation report. If not set a report will be generated in the same folder as the IP package.") + String reportPathDir = System.getProperty("user.dir"); + + @CommandLine.Option(names = {"-v", + "--verbose"}, description = "Verbose command line output with all validation steps") + boolean verbose; + + @CommandLine.Option(names = {"--specification-version"}, description = "E-ARK CSIP version") + String version = "2.1.0"; + + public Integer call() throws ValidationException, CLIException { + for (String sip : sipPaths) { + try { + handleSipValidation(sip, reportPathDir, verbose); + } catch (IOException e) { + throw new ValidationException("Unable to create necessary files to start validation"); + } catch (ParserConfigurationException | SAXException | NoSuchAlgorithmException e) { + throw new ValidationException("Failed to validate"); + } + } + + return ExitCodes.EXIT_CODE_OK; + } + + private void handleSipValidation(final String sip, final String reportPathDir, + final boolean verbose) + throws IOException, ParserConfigurationException, SAXException, CLIException, NoSuchAlgorithmException { + final Path sipPath = Paths.get(sip); + + Path reportPath = ValidateCommandUtils.obtainReportPath(sipPath, reportPathDir); + CommandLine cmd = spec.commandLine(); + String commandLineString = String.join(" ", cmd.getParseResult().originalArgs()); + + + LogSystem.logOperatingSystemInfo(); + LOGGER.debug("command executed: {}", commandLineString); + switch (reportType) { + case COMMONS_IP -> { + final OutputStream outputStream = ValidateCommandUtils.createReportOutputStream(reportPath); + if (outputStream != null) { + final ValidationReportOutputJson jsonReporter = new ValidationReportOutputJson(sipPath, outputStream); + final EARKSIPValidator earksipValidator = new EARKSIPValidator(jsonReporter, version); + final EARKERMSValidator earkermsValidator = new EARKERMSValidator(jsonReporter, version); + if (verbose) { + earksipValidator.addObserver(new ProgressValidationLoggerObserver()); + } + earksipValidator.validate(version); + earkermsValidator.validate(version); + } + } + case PYIP -> { + final ValidationReportOutputJSONPyIP jsonReporter = new ValidationReportOutputJSONPyIP(reportPath, sipPath); + final EARKPyIPValidator earkPyIPValidator = new EARKPyIPValidator(jsonReporter, version); + if (verbose) { + earkPyIPValidator.addObserver(new ProgressValidationLoggerObserver()); + } + earkPyIPValidator.validate(); + } + default -> throw new CLIException("Unexpected value: " + reportType); + } + + + new CommandLine(this).getOut().printf("E-ARK SIP validation report at '%s'%n", + reportPath.normalize().toAbsolutePath()); + } + } diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/model/ErmsWrapper.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/model/ErmsWrapper.java new file mode 100644 index 0000000..edfc906 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/model/ErmsWrapper.java @@ -0,0 +1,36 @@ +package org.keeps.digitalpreservation.commonsip.citserms.model; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ErmsType; + +import java.nio.file.Path; + +/** + * @author Carlos Afonso + */ +public class ErmsWrapper { + private ErmsType erms; + private Path ermsPath; + + public ErmsWrapper(ErmsType erms, Path ermsPath) { + super(); + this.erms = erms; + this.ermsPath = ermsPath; + } + + public ErmsType getErms() { + return erms; + } + + public void setErms(ErmsType mets) { + this.erms = erms; + } + + public Path getErmsPath() { + return ermsPath; + } + + public void setErmsPath(Path ermsPath) { + this.ermsPath = ermsPath; + } + +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/model/IPErmsConstants.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/model/IPErmsConstants.java new file mode 100644 index 0000000..2eb78a4 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/model/IPErmsConstants.java @@ -0,0 +1,19 @@ +package org.keeps.digitalpreservation.commonsip.citserms.model; + +/** + * @author Carlos Afonso + */ +public class IPErmsConstants { + + public static final String SCHEMA_ERMS_RELATIVE_PATH_FROM_RESOURCES = "/schema/v2/ERMS.xsd"; + public static final String SCHEMA_ERMS_FILENAME_WITH_VERSION = "ERMS.xsd"; + + public static final String ERMS_FILE = "ERMS.xml"; + + public static final String ERMS_FILE_NAME = "ERMS"; + + public static final String ERMS_FILE_EXTENSION = ".xml"; + + public static boolean ERMS_ENCODE_AND_DECODE_HREF = true; + +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/utils/ERMSUtils.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/utils/ERMSUtils.java new file mode 100644 index 0000000..e1d5597 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/utils/ERMSUtils.java @@ -0,0 +1,278 @@ +package org.keeps.digitalpreservation.commonsip.citserms.utils; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; + +import javax.xml.XMLConstants; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; + +import org.keeps.digitalpreservation.commonsip.citserms.model.ErmsWrapper; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ErmsType; +import org.roda_project.commons_ip.utils.IPException; +import org.roda_project.commons_ip.utils.METSEnums.LocType; +import org.roda_project.commons_ip.utils.ZipEntryInfo; +import org.roda_project.commons_ip2.mets_v1_12.beans.FileType; +import org.roda_project.commons_ip2.mets_v1_12.beans.FileType.FLocat; +import org.roda_project.commons_ip2.mets_v1_12.beans.MdSecType.MdRef; +import org.roda_project.commons_ip2.mets_v1_12.beans.Mets; +import org.roda_project.commons_ip2.mets_v1_12.beans.MetsType.MetsHdr.Agent; +import org.roda_project.commons_ip2.mets_v1_12.beans.MetsType.MetsHdr.Agent.Note; +import org.roda_project.commons_ip2.model.IPAgent; +import org.roda_project.commons_ip2.model.IPConstants; +import org.roda_project.commons_ip2.model.MetsWrapper; +import org.roda_project.commons_ip2.utils.IanaMediaTypes; +import org.roda_project.commons_ip2.utils.ResourceResolver; +import org.roda_project.commons_ip2.utils.Utils; +import org.roda_project.commons_ip2.utils.ZIPUtils; +import org.keeps.digitalpreservation.commonsip.citserms.model.IPErmsConstants; +import org.slf4j.Logger; +import org.xml.sax.SAXException; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.Unmarshaller; + +public final class ERMSUtils { + + private ERMSUtils() { + // do nothing + } + + public static Mets instantiateERMSFromFile(Path ermsFile) throws JAXBException, SAXException, IOException { + JAXBContext jaxbContext = JAXBContext.newInstance(ErmsType.class); + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + factory.setResourceResolver(new ResourceResolver()); + InputStream ermsSchemaInputStream = ERMSUtils.class + .getResourceAsStream(IPErmsConstants.SCHEMA_ERMS_RELATIVE_PATH_FROM_RESOURCES); + Source ermsSchemaSource = new StreamSource(ermsSchemaInputStream); + Schema schema = factory.newSchema(ermsSchemaSource); + jaxbUnmarshaller.setSchema(schema); + return (Mets) jaxbUnmarshaller.unmarshal(new BufferedInputStream(Files.newInputStream(ermsFile.toAbsolutePath()))); + } + + public static Path marshallERMS(ErmsType erms, Path tempERMSFile, boolean rootERMS) + throws JAXBException, IOException, IPException { + JAXBContext context = JAXBContext.newInstance(ErmsType.class); + Marshaller m = context.createMarshaller(); + m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + if (rootERMS) { + m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, + "http://www.loc.gov/METS/ schemas/" + IPErmsConstants.SCHEMA_ERMS_FILENAME_WITH_VERSION + + " http://www.w3.org/1999/xlink schemas/" + IPConstants.SCHEMA_XLINK_FILENAME); + } + + try (OutputStream metsOutputStream = Files.newOutputStream(tempERMSFile)) { + m.marshal(erms, metsOutputStream); + } + + return tempERMSFile; + } +/* + public static void addMainERMSToZip(Map zipEntries, ErmsWrapper ermsWrapper, String ermsPath, + Path buildDir) throws IPException { + try { + addERMSToZip(zipEntries, ermsWrapper, ermsPath, buildDir, true, null); + } catch (JAXBException | IOException e) { + throw new IPException(e.getMessage(), e); + } + } + + + */ + /*public static void addMainERMSToZip(Map zipEntries, ErmsWrapper mainERMSWrapper, Path buildDir) + throws IPException { + addMainERMSToZip(zipEntries, mainERMSWrapper, IPErmsConstants.ERMS_FILE, buildDir); + } + + */ + + /* public static void addERMSToZip(Map zipEntries, ErmsWrapper ermsWrapper, String ermsPath, + Path buildDir, boolean mainErms, FileType fileType) throws JAXBException, IOException, IPException { + Path temp = Files.createTempFile(buildDir, IPErmsConstants.ERMS_FILE_NAME, IPErmsConstants.ERMS_FILE_EXTENSION); + ZIPUtils.addERMSFileToZip(zipEntries, temp, ermsPath, ermsWrapper.getErms(), mainErms, fileType); + } + + */ + + /*public static Agent createERMSAgent(IPAgent ipAgent) { + Agent agent = new Agent(); + agent.setName(ipAgent.getName()); + Note note = new Note(); + note.setValue(ipAgent.getNote()); + note.setNOTETYPE(ipAgent.getNoteType().asString()); + agent.getNote().add(note); + + agent.setROLE(ipAgent.getRole()); + agent.setOTHERROLE(ipAgent.getOtherRole()); + agent.setTYPE(ipAgent.getType().toString()); + agent.setOTHERTYPE(ipAgent.getOtherType()); + return agent; + } + + */ + + /*public static FLocat createFileLocation(String filePath) { + FLocat fileLocation = new FLocat(); + fileLocation.setType(IPErmsConstants.ERMS_TYPE_SIMPLE); + fileLocation.setLOCTYPE(LocType.URL.toString()); + fileLocation.setHref(encodeHref(filePath)); + return fileLocation; + } + + */ + + /*public static FLocat createShallowFileLocation(String filePath) { + FLocat fileLocation = new FLocat(); + fileLocation.setType(IPErmsConstants.ERMS_TYPE_SIMPLE); + fileLocation.setLOCTYPE(LocType.URL.toString()); + fileLocation.setHref(filePath); + return fileLocation; + } + + */ + + public static MdRef setFileBasicInformation(Path file, MdRef mdRef) throws IPException, InterruptedException { + // mimetype info. + try { + mdRef.setMIMETYPE(getFileMimetype(file)); + } catch (IOException e) { + throw new IPException("Error probing file content (" + file + ")", e); + } + + // date creation info. + try { + mdRef.setCREATED(Utils.getCurrentCalendar()); + } catch (DatatypeConfigurationException e) { + throw new IPException("Error getting current calendar", e); + } + + // size info. + try { + mdRef.setSIZE(Files.size(file)); + } catch (IOException e) { + throw new IPException("Error getting file size (" + file + ")", e); + } + + return mdRef; + } + + public static void setFileBasicInformation(Logger logger, Path file, FileType fileType) + throws IPException, InterruptedException { + // mimetype info. + try { + logger.debug("Setting mimetype {}", file); + fileType.setMIMETYPE(getFileMimetype(file)); + logger.debug("Done setting mimetype"); + } catch (IOException e) { + throw new IPException("Error probing content-type (" + file.toString() + ")", e); + } + + // date creation info. + try { + fileType.setCREATED(Utils.getCurrentCalendar()); + } catch (DatatypeConfigurationException e) { + throw new IPException("Error getting curent calendar (" + file.toString() + ")", e); + } + + // size info. + try { + logger.debug("Setting file size {}", file); + fileType.setSIZE(Files.size(file)); + logger.debug("Done setting file size"); + } catch (IOException e) { + throw new IPException("Error getting file size (" + file.toString() + ")", e); + } + } + + private static String getFileMimetype(Path file) throws IOException { + String probedContentType = Files.probeContentType(file); + if (probedContentType == null) { + probedContentType = "application/octet-stream"; + } else { + if (!IanaMediaTypes.getIanaMediaTypesList().contains(probedContentType)) { + probedContentType = "application/octet-stream"; + } + } + return probedContentType; + } + + /** + * Decodes a value from a METS HREF attribute. + * + *

+ * 20170511 hsilva: a global variable called + * {//@link IPErmsConstants.ERMS_ENCODE_AND_DECODE_HREF} is used to enable/disable the + * effective decode (done this way to avoid lots of changes in the methods that + * use this method) + *

+ */ + public static String decodeHref(String value) { + if (IPErmsConstants.ERMS_ENCODE_AND_DECODE_HREF) { + try { + value = URLDecoder.decode(value, "UTF-8"); + } catch (NullPointerException | UnsupportedEncodingException e) { + // do nothing + } + } + return value; + } + + /** + * Encodes a value to put in METS HREF attribute. + * + *

+ * 20170511 hsilva: a global variable called + * {//@link IPErmsConstants.ERMS_ENCODE_AND_DECODE_HREF} is used to enable/disable the + * effective encode (done this way to avoid lots of changes in the methods that + * use this method). This method is not multi-thread safe when using different + * SIP formats. + *

+ */ + public static String encodeHref(String value) { + if (IPErmsConstants.ERMS_ENCODE_AND_DECODE_HREF) { + value = escapeSpecialCharacters(value); + } + return value; + } + + public static String escapeSpecialCharacters(String input) { + StringBuilder resultStr = new StringBuilder(); + for (char ch : input.toCharArray()) { + if (isSafeChar(ch)) { + resultStr.append(ch); + } else { + resultStr.append(encodeUnsafeChar(ch)); + } + } + return resultStr.toString(); + } + + private static boolean isSafeChar(char ch) { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') + || ":/$-_.!*'(),".indexOf(ch) >= 0; + } + + private static String encodeUnsafeChar(char ch) { + String ret = String.valueOf(ch); + try { + ret = URLEncoder.encode(ret, "UTF-8"); + } catch (NullPointerException | UnsupportedEncodingException e) { + // do nothing & return original value + } + return ret; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/utils/Message.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/utils/Message.java new file mode 100644 index 0000000..7702b19 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/utils/Message.java @@ -0,0 +1,86 @@ +package org.keeps.digitalpreservation.commonsip.citserms.utils; + +import org.roda_project.commons_ip2.validator.constants.Constants; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Map; + +/** {@author João Gomes }. */ +public final class Message { + + private Message() { + // do nothing + } + + /** + * Generates an error message. + * + * @param message + * The message. + * @param path + * The path to add to the message + * @param isRootMets + * Flag if is root mets or not. + * @return {@link String}. + */ + public static String createErrorMessage(final String message, final String path) { + return String.format(message, path); + } + + /* + + /** + * Creates message with number of files missing in some validation methods. + * + * @param missedMetadataFiles + * the {@link Map} with the missing files. + * @param initialMessage + * the {@link String} with the initial message + * @param isZip + * flag if IP is in zip format or is a folder. + * @param split + * the {@link String} with the path we don't want in the message. + * @return a message {@link String}. + */ + public static String createMissingFilesMessage(final Map missedMetadataFiles, + final String initialMessage, final boolean isZip, final String split) { + final StringBuilder message = new StringBuilder(); + message.append(initialMessage); + final int size = missedMetadataFiles.size(); + final int limit = Constants.LIMIT_MISSING_FILES; + if (size < limit) { + for (Map.Entry entry : missedMetadataFiles.entrySet()) { + message.append(calculateInnerMessage(isZip, entry.getKey(), split)); + } + } else { + int i = 0; + for (Map.Entry entry : missedMetadataFiles.entrySet()) { + if (i != limit) { + message.append(calculateInnerMessage(isZip, entry.getKey(), split)); + } else { + break; + } + i++; + } + } + message.append(" and ").append(size - limit).append(" more ").append("in %1$s"); + return message.toString(); + } + + private static String calculateInnerMessage(final boolean isZip, final String key, final String split) { + final StringBuilder message = new StringBuilder(); + Path keyPath = Paths.get(key); + Path splitPath = Paths.get(split); + String subtracted = splitPath.relativize(keyPath).toString(); + + if (isZip) { + message.append(subtracted.startsWith(Constants.SEPARATOR) ? subtracted + : Constants.SEPARATOR + subtracted).append(", "); + } else { + message.append(subtracted); + } + return message.toString(); + } + +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/EARKERMSValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/EARKERMSValidator.java new file mode 100644 index 0000000..32c4d1f --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/EARKERMSValidator.java @@ -0,0 +1,381 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLStreamException; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.common.InstatiateErms; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ErmsValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator.ErmsControlComponentValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.components.StructureValidatorImpl; +import org.roda_project.commons_ip2.validator.components.fileComponent.StructureComponentValidator210; +import org.roda_project.commons_ip2.validator.observer.ValidationObserver; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; +import org.roda_project.commons_ip2.validator.reporter.ValidationReportOutputJson; +import org.roda_project.commons_ip2.validator.state.StructureValidatorState; +import org.roda_project.commons_ip2.validator.utils.ResultsUtils; +import org.xml.sax.SAXException; + +import jakarta.xml.bind.JAXBException; + +/** + * {@author João Gomes }. + */ +public class EARKERMSValidator { + /** + * IP path. + */ + private final Path earkermsPath; + + /** + * {@link ValidationReportOutputJson}. + */ + private final ValidationReportOutputJson validationReportOutputJson; + /** + * {@link StructureValidatorImpl}. + */ + private final StructureValidatorImpl structureComponent; + /** + * the contextual structural state {@link StructureValidatorState}. + */ + private final StructureValidatorState structureValidatorState; + /** + * List of ERMS components to validate. + */ + private final List ermsComponents = new ArrayList<>(); + /** + * The contextual mets state {@link ErmsValidatorState}. + */ + private final ErmsValidatorState ermsValidatorState; + + private final String version; + + /** + * Initializes Validation Objects. + * + * @param reportOutputJson + * the {@link ValidationReportOutputJson} + * @throws IOException + * if some I/O error occurs. + * @throws ParserConfigurationException + * if some error occurred. + * @throws SAXException + * if some error occurred. + */ + public EARKERMSValidator(final ValidationReportOutputJson reportOutputJson, String version) + throws IOException, ParserConfigurationException, SAXException { + + this.earkermsPath = reportOutputJson.getSipPath().toAbsolutePath().normalize(); + + this.validationReportOutputJson = reportOutputJson; + + this.version = version; + + this.structureValidatorState = new StructureValidatorState( + reportOutputJson.getSipPath().toAbsolutePath().normalize()); + + this.structureComponent = new StructureComponentValidator210(); + + // if (version.equals("2.1.0")) { + // this.structureComponent = new StructureComponentValidator210(); + // } else { + // this.structureComponent = new StructureComponentValidator204(); + // } + this.ermsValidatorState = new ErmsValidatorState(); + setupComponents(version); + } + + /** + * Setup Validation Components. + * + * @throws IOException + * if some I/O error occurs. + * @throws ParserConfigurationException + * if some error occur. + * @throws SAXException + * if some error occur. + */ + private void setupComponents(String version) throws IOException, ParserConfigurationException, SAXException { + this.ermsComponents.addAll(getComponentsForVersion(version)); + } + + /** + * Add {@link ValidationObserver} to the lists of observers. + * + * @param observer + * the {@link ValidationObserver} + */ + public void addObserver(final ValidationObserver observer) { + structureComponent.addObserver(observer); + ermsComponents.forEach(c -> c.addObserver(observer)); + } + + /** + * Remove {@link ValidationObserver} from the lists of observers. + * + * @param observer + * the {@link ValidationObserver} + */ + public void removeObserver(final ValidationObserver observer) { + structureComponent.removeObserver(observer); + ermsComponents.forEach(c -> c.removeObserver(observer)); + } + + /** + * Validates the Information Package. + * + * @return if the Information package is valid or not + * @throws IOException + * if some I/O error occurs. + */ + public boolean validate(String version) throws IOException { + structureComponent.notifyObserversIPValidationStarted(); + final Map structureValidationResults = structureComponent + .validate(structureValidatorState); + validationReportOutputJson.getResults().putAll(structureValidationResults); + validateErms(); + + /* + * if (validationReportOutputJson.validFileComponent()) { final Map subMets; if (structureValidatorState.isZipFileFlag()) { + * ermsValidatorState.setErmsFiles(structureValidatorState.getZipManager(). + * getFiles(earkermsPath)); subMets = + * structureValidatorState.getZipManager().getSubMets(earkermsPath); } else { + * metsValidatorState.setMetsFiles(structureValidatorState.getFolderManager(). + * getFiles(earkermsPath)); subMets = + * structureValidatorState.getFolderManager().getSubMets(earkermsPath); } + * + * if (subMets.size() > 0) { validateSubMets(subMets, + * structureValidatorState.isZipFileFlag()); } validateRootMets(); + * + * if (!validationReportOutputJson.getResults() + * .containsKey(ConstantsCSIPspec.VALIDATION_REPORT_SPECIFICATION_CSIP0_ID)) { + * final ReporterDetails csipStr0 = new + * ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION + version, + * "", true, false); + * csipStr0.setSpecification(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION + + * version); validationReportOutputJson.getResults().put(ConstantsCSIPspec. + * VALIDATION_REPORT_SPECIFICATION_CSIP0_ID, csipStr0); } } + * writeReport(version); return validationReportOutputJson.getErrors() == 0; + */ + return true; + } + + /** + * Iterates over all components and merge all results from components + * validations. + * + * @throws IOException + * if some I/O error occurs. + */ + private void validateComponents() throws IOException { + for (ErmsValidator component : ermsComponents) { + final Map componentResults = component.validate(structureValidatorState, + ermsValidatorState); + ResultsUtils.mergeResults(validationReportOutputJson.getResults(), componentResults); + } + ermsValidatorState.flushEntries(); + validateIpTypeExtendedComponents(); + } + + /** + * Validate METS files inside representations. + * + * @param subMets + * the {@link Map } with path to sub METS and InputStream of file. + * @param isZip + * flag if the Information Package is in compact format or if it is a + * folder. + */ + /* + * private void validateSubMets(final Map subMets, final + * boolean isZip) { for (Map.Entry entry : + * subMets.entrySet()) { + * + * final InstatiateErms instatiateMets = new InstatiateErms(entry.getValue()); + * try { ermsValidatorState.setErms(instatiateMets.instatiateMetsFile()); + * setupMetsValidatorState(entry.getKey(), isZip, false); validateComponents(); + * } catch (IOException | JAXBException | SAXException e) { final String message + * = createExceptionMessage(e, entry.getKey()); final ReporterDetails csipStr0 = + * new ReporterDetails(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION, message, + * false, false); + * csipStr0.setSpecification(Constants.VALIDATION_REPORT_HEADER_CSIP_VERSION); + * ResultsUtils.addResult(validationReportOutputJson.getResults(), + * ConstantsCSIPspec.VALIDATION_REPORT_SPECIFICATION_CSIP0_ID, csipStr0); } } } + * + */ + + /** + * Creates Message for Exception. + * + * @param e + * the {@link Exception} + * @param mets + * the path to METS file + * @return a message + */ + /* + * private String createExceptionMessage(final Exception e, final String mets) { + * final StringBuilder message = new StringBuilder(); + * + * Throwable cause = e; if (e.getMessage() != null) { + * message.append(Constants.OPEN_SQUARE_BRACKET).append(e.getClass(). + * getSimpleName()) + * .append(Constants.CLOSE_SQUARE_BRACKET).append(Constants.EMPTY_SPACE).append( + * e.getMessage()); } while (cause.getCause() != null) { cause = + * cause.getCause(); if (message.length() > 0) { message.append(" caused by "); + * } + * + * message.append(Constants.OPEN_SQUARE_BRACKET).append(cause.getClass(). + * getSimpleName()) + * .append(Constants.CLOSE_SQUARE_BRACKET).append(Constants.EMPTY_SPACE).append( + * cause.getMessage()); + * + * if (cause instanceof SAXParseException e1) { + * message.append(" (file: ").append(mets).append(", line: ").append(e1. + * getLineNumber()).append(", column: ") + * .append(e1.getColumnNumber()).append(")"); } } + * + * return message.toString(); } + * + */ + + /** + * Validates METS file in root of Information Package. + */ + private void validateErms() { + final InputStream ermsStream; + final String ipPath; + try { + + if (structureValidatorState.isZipFileFlag()) { + ermsStream = structureValidatorState.getZipManager().getErmsInputStream(earkermsPath); + ipPath = earkermsPath.toString(); + } else { + ermsStream = structureValidatorState.getFolderManager().getErmsInputStream(earkermsPath); + ipPath = earkermsPath.resolve(Constants.ERMS_FILE).toString(); + } + + final InstatiateErms erms = new InstatiateErms(); + ermsValidatorState.setErmsPath(earkermsPath.toString()); + ermsValidatorState.setErmsName(ipPath); + + ermsValidatorState.setErms(erms.instatiateErmsFile(ermsStream)); + // erms.setIpType(metsValidatorState.getMets().getMetsHdr().getOAISPACKAGETYPE()); + validateComponents(); + } catch (IOException | JAXBException | SAXException e) { + // final String message = createExceptionMessage(e, + // earkermsPath.toString() + Constants.SEPARATOR + Constants.ERMS_FILE); + // final ReporterDetails ermsStr0 = new + // ReporterDetails(Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION, message, + // false, false); + // ermsStr0.setSpecification(Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION); + // ResultsUtils.addResult(validationReportOutputJson.getResults(), + // ConstantsERMSspec.VALIDATION_REPORT_SPECIFICATION_CSIP0_ID, ermsStr0); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } + } + + /** + * Setup State of METS. + * + * @param key + * the METS file path + * @param isZip + * Flag if Information package is compacted or not + * @param isRootMets + * Flag if METS file is root or representation METS + */ + /* + * private void setupMetsValidatorState(final String key, final boolean isZip, + * final boolean isRootMets) { this.metsValidatorState.setMetsName(key); + * this.metsValidatorState.setIsRootMets(isRootMets); if (isZip) { final + * StringBuilder metsPath = new StringBuilder(); for (String path : + * key.split(Constants.SEPARATOR)) { if (!path.equals(Constants.METS_FILE)) { + * metsPath.append(path).append("/"); } } + * this.metsValidatorState.setMetsPath(metsPath.toString()); } else { + * this.metsValidatorState.setMetsPath(Paths.get(key).getParent().toString()); } + * } + * + */ + + /** + * Notify all observers. + */ + public void notifyIndicatorsObservers() { + structureComponent.notifyIndicators(this.validationReportOutputJson.getErrors(), + this.validationReportOutputJson.getSuccess(), this.validationReportOutputJson.getWarnings(), + this.validationReportOutputJson.getNotes(), this.validationReportOutputJson.getSkipped()); + } + + /** + * Validate SIP specifications or AIP Specifications if the type is SIP or AIP. + * + * @throws IOException + * if some I/O error occurs. + */ + private void validateIpTypeExtendedComponents() throws IOException { + if (ermsValidatorState.getIpType() != null && ermsValidatorState.getIpType().equals("ERMS")) { + validateERMSComponents(); + } + } + + /** + * Iterate over ERMS components and merge the results with CSIP validations. + * + * @throws IOException + * if some I/O error occurs. + */ + private void validateERMSComponents() throws IOException { + + } + + /** + * Iterate over AIP components and merges the results with CSIP validations + * results. + * + * @throws IOException + * if some I/O error occurs. + */ + + /** + * Write the report. + * + * @throws IOException + * if some I/O error occurs. + */ + private void writeReport(String version) throws IOException { + if (ermsValidatorState.getErms() != null) { + validationReportOutputJson.setIpType(ermsValidatorState.getIpType()); + } + + validationReportOutputJson.init(version); + validationReportOutputJson.validationResults(); + validationReportOutputJson.writeFinalResult(); + notifyIndicatorsObservers(); + validationReportOutputJson.close(); + structureComponent.notifyObserversIPValidationFinished(); + } + + private List getComponentsForVersion(String version) + throws IOException, ParserConfigurationException, SAXException { + List values = new ArrayList<>(); + // if (version.equals("2.0.4")) { + // values.add(new ErmsValidatorComponentValidator20); + // } else { + values.add(new ErmsControlComponentValidator()); + // } + + return values; + } + +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/common/InstatiateErms.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/common/InstatiateErms.java new file mode 100644 index 0000000..4c11cc4 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/common/InstatiateErms.java @@ -0,0 +1,54 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.common; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Unmarshaller; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ErmsType; +import org.keeps.digitalpreservation.commonsip.citserms.utils.ERMSUtils; +import org.keeps.digitalpreservation.commonsip.citserms.model.IPErmsConstants; +import org.roda_project.commons_ip2.utils.ResourceResolver; +import org.xml.sax.SAXException; + +import javax.xml.XMLConstants; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import java.io.InputStream; + +/** {@author João Gomes }. */ +public class InstatiateErms { + public InstatiateErms() { + // empty constructor + } + + /** + * Creates the {@link ErmsType} object from ERMS file. + * + * @return the {@link ErmsType} object. + * @throws JAXBException if some schema error occurs. + * @throws SAXException if some parse error occurs. + */ + public ErmsType instatiateErmsFile(InputStream stream) throws JAXBException, SAXException, XMLStreamException { + final JAXBContext jaxbContext = JAXBContext.newInstance(ErmsType.class); + final Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + factory.setResourceResolver(new ResourceResolver()); + final InputStream ermsSchemaInputStream = ERMSUtils.class + .getResourceAsStream(IPErmsConstants.SCHEMA_ERMS_RELATIVE_PATH_FROM_RESOURCES); + final Source ermsSchemaSource = new StreamSource(ermsSchemaInputStream); + final Schema schema = factory.newSchema(ermsSchemaSource); + jaxbUnmarshaller.setSchema(schema); + + XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); + XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(stream); + + JAXBElement unmarshal = jaxbUnmarshaller.unmarshal(reader, ErmsType.class); + + return unmarshal.getValue(); + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ErmsValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ErmsValidator.java new file mode 100644 index 0000000..5f69a6c --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ErmsValidator.java @@ -0,0 +1,44 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components; + +import java.io.IOException; +import java.util.Map; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.observer.ValidationObserver; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; +import org.roda_project.commons_ip2.validator.state.MetsValidatorState; +import org.roda_project.commons_ip2.validator.state.StructureValidatorState; + +/** {@author João Gomes }. */ +public interface ErmsValidator { + + /** + * Adds the observer to the {@link java.util.List} of observers. + * + * @param observer + * {@link ValidationObserver} + */ + void addObserver(ValidationObserver observer); + + /** + * Removes the observer of the {@link java.util.List} of observers. + * + * @param observer + * {@link ValidationObserver} + */ + void removeObserver(ValidationObserver observer); + + /** + * Validates the IP. + * + * @param structureValidatorState + * {@link StructureValidatorState} + * @param ermsValidatorState + * {@link ErmsValidatorState} + * @return {@link Map} with the results. + * @throws IOException + * if some error occurs. + */ + Map validate(StructureValidatorState structureValidatorState, + ErmsValidatorState ermsValidatorState) throws IOException; +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ErmsValidatorImpl.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ErmsValidatorImpl.java new file mode 100644 index 0000000..2d90ef2 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ErmsValidatorImpl.java @@ -0,0 +1,43 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components; + +import org.roda_project.commons_ip2.validator.observer.ValidationObserver; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsValidatorImpl implements ErmsValidator { + + /** + * {@link List} of {@link ValidationObserver}. + */ + private List observers = new ArrayList<>(); + + + + @Override + public void addObserver(final ValidationObserver observer) { + this.observers.add(observer); + } + + @Override + public void removeObserver(final ValidationObserver observer) { + this.observers.remove(observer); + } + + public void notifyObserversValidationStarted(final String moduleName, final String id) { + for (ValidationObserver observer : observers) { + observer.notifyStartValidationModule(moduleName, id); + observer.notifyStartStep(id); + } + } + + public void notifyObserversFinishModule(final String moduleName) { + for (ValidationObserver observer : observers) { + observer.notifyFinishModule(moduleName); + } + } + +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationComponentValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationComponentValidator.java new file mode 100644 index 0000000..a445de6 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationComponentValidator.java @@ -0,0 +1,164 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsAdditionalInformationComponentValidator; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.AdditionalInformation; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ErmsValidatorImpl; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; +import org.roda_project.commons_ip2.validator.state.StructureValidatorState; +import org.roda_project.commons_ip2.validator.utils.ResultsUtils; +import org.xml.sax.SAXException; + +/** + * @author Carlos Afonso + */ +public class ErmsAdditionalInformationComponentValidator extends ErmsValidatorImpl { + + private AdditionalInformation additionalInformation; + + /** + * {@link String} moduleName. + */ + private final String moduleName; + + public ErmsAdditionalInformationComponentValidator() throws ParserConfigurationException, SAXException { + this.moduleName = Constants.ERMS_MODULE_NAME_3; + // this.oaisPackageTypes = ControlledVocabularyParser + // .parse(Constants.PATH_RESOURCES_CSIP_VOCABULARY_OAIS_PACKAGE_TYPE); + } + + @Override + public Map validate(StructureValidatorState structureValidatorState, + ErmsValidatorState ermsValidatorState) throws IOException { + + additionalInformation = ermsValidatorState.getErms().getAdditionalInformation(); + + ErmsAdditionalInformationValidatorFactory ermsInformationValidatorFactory = new ErmsAdditionalInformationValidatorFactory(); + ErmsAdditionalInformationValidator generator = ermsInformationValidatorFactory.getGenerator("2.1.0"); + + final Map results = new HashMap<>(); + + /* ERMS28 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS28_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS28_ID, + generator.validateERMS28(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + if (ResultsUtils.isResultValid(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS28_ID)) { + + /* ERMS29 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS29_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS29_ID, generator + .validateERMS29(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS30 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS30_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS30_ID, generator + .validateERMS30(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS31 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS31_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS31_ID, generator + .validateERMS31(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS32 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS32_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS32_ID, generator + .validateERMS32(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS33 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS33_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS33_ID, generator + .validateERMS33(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS34 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS34_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS34_ID, generator + .validateERMS34(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS35 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS35_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS35_ID, generator + .validateERMS35(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS36 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS36_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS36_ID, generator + .validateERMS36(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS37 */ + +// notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS10_ID); +// ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS10_ID, generator +// .validateERMS37(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + /* ERMS38 */ + +// notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS38_ID); +// ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS38_ID, generator +// .validateERMS38(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + + + /* ERMS39 */ + +/* notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS39_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS39_ID, generator + .validateERMS39(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + + */ + } + + /* ERMS40 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS40_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS40_ID, + generator.validateERMS40(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + + /* ERMS41 */ +/* + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS41_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS41_ID, + generator.validateERMS41(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + */ + /* ERMS42 */ +/* + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS42_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS42_ID, + generator.validateERMS42(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + */ + /* ERMS43 */ +/* + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS43_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS43_ID, + generator.validateERMS43(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + */ + /* ERMS44 */ +/* + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS44_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS44_ID, + generator.validateERMS44(ermsValidatorState, additionalInformation).setSpecification(generator.getERMSVersion())); + + */ + return null; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator.java new file mode 100644 index 0000000..e7d7e43 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator.java @@ -0,0 +1,334 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsAdditionalInformationComponentValidator; + +import java.util.List; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.AdditionalInformation; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.AppendixType; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ExtendingComplexType; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.OwnElement; +import org.keeps.digitalpreservation.commonsip.citserms.utils.Message; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsAdditionalInformationValidator { + + /* + * additionalInformation/appendix Grouping of additional information in the form + * of a link to a document + */ + protected ReporterDetails validateERMS28(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + if (appendix.isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix can't be empty, in %1$s the additionalInformation/appendix does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * additionalInformation/appendix/@disposable Boolean indicator if the appendix + * can be disposed of. + */ + + // ADICIONAR NOME DO DISPOSABLE QUE ESTA A FALHAR + protected ReporterDetails validateERMS29(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.isDisposable() == null) + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@disposable can't be null, in %1$s the additionalInformation/appendix/@disposable with name %1$s does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * additionalInformation/appendix/@name The name of the appendix + */ + + protected ReporterDetails validateERMS30(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.getName() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@name can't be null, in %1$s the additionalInformation/appendix/@name does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/@description A description of the appendix + */ + + protected ReporterDetails validateERMS31(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.getDescription() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@description can't be null, in %1$s the additionalInformation/appendix/@description does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/@FileFormat The file format for the appendix + */ + + protected ReporterDetails validateERMS32(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.getFileFormat() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@FileFormat can't be null, in %1$s the additionalInformation/appendix/@FileFormat does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/@originalFileFormat If the appendix has been + * transformed to the current format and the format the transformation occurred + * from are registered, this element can contain the original file format + * information + */ + + protected ReporterDetails validateERMS33(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.getOriginalFileFormat() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@originalFileFormat can't be null, in %1$s the additionalInformation/appendix/@originalFileFormat does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/@Path The path to the appendix + */ + + protected ReporterDetails validateERMS34(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.getPath() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@Path can't be null, in %1$s the additionalInformation/appendix/@Path does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/@eSignatureHasExisted Boolean indicating if an + * eSignature has been present but disposed of before transfer. + */ + + protected ReporterDetails validateERMS35(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.isESignatureHasExisted() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/@eSignatureHasExisted can't be null, in %1$s the additionalInformation/appendix/@eSignatureHasExisted does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/eSignature The appendix can have a saved + * eSignature described in a grouping element. + */ + + protected ReporterDetails validateERMS36(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List appendix = additionalInformation.getAppendix(); + for (AppendixType at : appendix) { + if (at.getESignature() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "additionalInformation/appendix/eSignature can't be null, in %1$s the additionalInformation/appendix/eSignature does not exist", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * additionalInformation/appendix/eSignature/@present Boolean indicating the + * presence of an eSignature + */ + + // FALTA 37,38 E 39 + /* + * protected ReporterDetails validateERMS37(final ErmsValidatorState + * ermsValidatorState, AdditionalInformation additionalInformation) { final + * ReporterDetails details = new ReporterDetails(); List appendix + * = additionalInformation.getAppendix(); for (AppendixType at : appendix) { if + * (at.getESignature() != null) { details.setValid(false); + * details.addIssue(Message.createErrorMessage( + * "additionalInformation/appendix/eSignature can't be null, in %1$s the additionalInformation/appendix/eSignature does not exist" + * , ermsValidatorState.getErmsName())); } } return details; } + * + * protected ReporterDetails validateERMS38(final ErmsValidatorState + * ermsValidatorState, AdditionalInformation additionalInformation) { final + * ReporterDetails details = new ReporterDetails(); List appendix + * = additionalInformation.getAppendix(); for (AppendixType at : appendix) { if + * (at.getESignature() == null) { details.setValid(false); + * details.addIssue(Message.createErrorMessage( + * "additionalInformation/appendix/eSignature can't be null, in %1$s the additionalInformation/appendix/eSignature does not exist" + * , ermsValidatorState.getErmsName())); } } return details; } + * + */ + + /* + * additionalInformation/ownElement Additional information in the form of + * creation of small number of extending elements creation a grouping by using + * elements present for generic construction. + */ + + protected ReporterDetails validateERMS40(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List elements = additionalInformation.getOwnElement(); + + if (elements.isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a additionalInformation/ownElement, in %1$s the additionalInformation/ownElement does not exist", + ermsValidatorState.getErmsName())); + } + + return details; + } + + /* + * additionalInformation/ownElement/ownElementDescription A description of the + * own elements purpose + */ + + protected ReporterDetails validateERMS41(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + List elements = additionalInformation.getOwnElement(); + + for (OwnElement oe : elements) { + + if (oe.getOwnElementDescription() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file should contain a additionalInformation/ownElement/ownElementDescription, in %1$s the additionalInformation/ownElement/ownElementDescription does not exist", + ermsValidatorState.getErmsName())); + } + } + + return details; + } + + /* + * additionalInformation/ownElement/ The elements and attributes for the own + * element are seen in the example + */ + // PENSO QUE A ESPECIFICACAO ESTA MAL + // protected ReporterDetails validateERMS42(final ErmsValidatorState + // ermsValidatorState, + // AdditionalInformation additionalInformation) { + // final ReporterDetails details = new ReporterDetails(); + // List elements = additionalInformation.getOwnElement(); + // + // for (OwnElement oe : elements) { + // + // if (oe.getOwnElementDescription() == null) { + // details.setValid(false); + // details.addIssue(Message.createErrorMessage( + // "ERMS file should contain a + // additionalInformation/ownElement/ownElementDescription, in %1$s the + // additionalInformation/ownElement/ownElementDescription does not exist", + // ermsValidatorState.getErmsName())); + // } + // } + // + // return details; + // } + + /* + * additionalInformation/additionalXMLData Additional information in the form of + * extending XML data that is inserted. + */ + + protected ReporterDetails validateERMS43(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + + List xmlData = additionalInformation.getAdditionalXMLData(); + + if (xmlData.isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a additionalInformation/additionalXMLData, in %1$s the additionalInformation/additionalXMLData does not exist", + ermsValidatorState.getErmsName())); + } + + return details; + } + + /* + * additionalInformation/additionalBinData in the form of inserted binary 64 + * data. + */ + + protected ReporterDetails validateERMS44(final ErmsValidatorState ermsValidatorState, + AdditionalInformation additionalInformation) { + final ReporterDetails details = new ReporterDetails(); + + List binData = additionalInformation.getAdditionalBinData(); + + if (binData.isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a additionalInformation/additionalBinData, in %1$s the additionalInformation/additionalBinData does not exist", + ermsValidatorState.getErmsName())); + } + + return details; + } + + + protected abstract String getERMSVersion(); +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator204.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator204.java new file mode 100644 index 0000000..d2067c8 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator204.java @@ -0,0 +1,12 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsAdditionalInformationComponentValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator.ErmsControlValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +/** + * @author Carlos Afonso + */ +public class ErmsAdditionalInformationValidator204 extends ErmsAdditionalInformationValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator210.java new file mode 100644 index 0000000..e18ada6 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidator210.java @@ -0,0 +1,12 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsAdditionalInformationComponentValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator.ErmsControlValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +/** + * @author Carlos Afonso + */ +public class ErmsAdditionalInformationValidator210 extends ErmsAdditionalInformationValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidatorFactory.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidatorFactory.java new file mode 100644 index 0000000..2f63692 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsAdditionalInformationComponentValidator/ErmsAdditionalInformationValidatorFactory.java @@ -0,0 +1,19 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsAdditionalInformationComponentValidator; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator.ErmsControlValidator; + +/** + * @author Carlos Afonso + */ +public class ErmsAdditionalInformationValidatorFactory { + public ErmsAdditionalInformationValidatorFactory() { + // empty constructor + } + + public ErmsAdditionalInformationValidator getGenerator(String version) { + if (version.equals("2.0.4")) { + return new ErmsAdditionalInformationValidator204(); + } + return new ErmsAdditionalInformationValidator210(); + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsValidator/ErmsValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsValidator/ErmsValidator.java new file mode 100644 index 0000000..fa99895 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsValidator/ErmsValidator.java @@ -0,0 +1,7 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsValidator; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsValidator { +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsValidator/ErmsValidatorComponentValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsValidator/ErmsValidatorComponentValidator210.java new file mode 100644 index 0000000..c69c285 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsAdditionalInformation/ermsValidator/ErmsValidatorComponentValidator210.java @@ -0,0 +1,30 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsAdditionalInformation.ermsValidator; + +import java.io.IOException; +import java.util.Map; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ErmsValidatorImpl; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.observer.ValidationObserver; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; +import org.roda_project.commons_ip2.validator.state.StructureValidatorState; + +/** + * @author Carlos Afonso + */ +public class ErmsValidatorComponentValidator210 extends ErmsValidatorImpl { + @Override + public void addObserver(ValidationObserver observer) { + + } + + @Override + public void removeObserver(ValidationObserver observer) { + + } + + @Override + public Map validate(StructureValidatorState structureValidatorState, ErmsValidatorState ermsValidatorState) throws IOException { + return null; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlComponentValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlComponentValidator.java new file mode 100644 index 0000000..ec81943 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlComponentValidator.java @@ -0,0 +1,259 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ControlType; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ErmsValidatorImpl; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsDateValidator.ErmsDateValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsDateValidator.ErmsDateValidatorFactory; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.observer.ValidationObserver; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; +import org.roda_project.commons_ip2.validator.state.StructureValidatorState; +import org.roda_project.commons_ip2.validator.utils.ResultsUtils; +import org.xml.sax.SAXException; + +/** + * @author Carlos Afonso + */ +public class ErmsControlComponentValidator extends ErmsValidatorImpl { + /** + * {@link String} moduleName. + */ + private final String moduleName; + /** + * {@link List} of {@link String} with OAIS package types. + */ + // private final List oaisPackageTypes; + /** + * {@link ControlType}. + */ + private ControlType controlType; + + public ErmsControlComponentValidator() throws IOException, ParserConfigurationException, SAXException { + this.moduleName = Constants.ERMS_MODULE_NAME_2; + // this.oaisPackageTypes = ControlledVocabularyParser + // .parse(Constants.PATH_RESOURCES_CSIP_VOCABULARY_OAIS_PACKAGE_TYPE); + } + + @Override + public void addObserver(ValidationObserver observer) { + + } + + @Override + public void removeObserver(ValidationObserver observer) { + + } + + @Override + public Map validate(StructureValidatorState structureValidatorState, + ErmsValidatorState ermsValidatorState) throws IOException { + + controlType = ermsValidatorState.getErms().getControl(); + + ErmsControlValidatorFactory ermsControlValidatorFactory = new ErmsControlValidatorFactory(); + ErmsControlValidator generator = ermsControlValidatorFactory.getGenerator("2.1.0"); + + final Map results = new HashMap<>(); + + /* ERMS1 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS1_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS1_ID, + generator.validateERMS1(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS2 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS2_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS2_ID, + generator.validateERMS2(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS3 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS3_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS3_ID, + generator.validateERMS3(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS4 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS4_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS4_ID, + generator.validateERMS4(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + if (ResultsUtils.isResultValid(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS4_ID)) { + + /* ERMS5 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS5_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS5_ID, + generator.validateERMS5(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS6 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS6_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS6_ID, + generator.validateERMS6(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS7 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS7_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS7_ID, + generator.validateERMS7(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + } + + /* ERMS8 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS8_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS8_ID, + generator.validateERMS8(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS9 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS9_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS9_ID, + generator.validateERMS9(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + if (ResultsUtils.isResultValid(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS9_ID)) { + + ErmsDateValidatorFactory ermsDateValidatorFactory = new ErmsDateValidatorFactory(); + ErmsDateValidator dateGenerator = ermsDateValidatorFactory.getGenerator("2.1.0"); + + /* ERMS45 */ + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS45_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS45_ID, dateGenerator + .validateERMS45(ermsValidatorState, controlType.getDates()).setSpecification(generator.getERMSVersion())); + + /* ERMS46 */ + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS46_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS46_ID, dateGenerator + .validateERMS46(ermsValidatorState, controlType.getDates()).setSpecification(generator.getERMSVersion())); + + /* ERMS47 */ + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS47_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS47_ID, dateGenerator + .validateERMS47(ermsValidatorState, controlType.getDates()).setSpecification(generator.getERMSVersion())); + + /* ERMS48 */ + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS48_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS48_ID, dateGenerator + .validateERMS48(ermsValidatorState, controlType.getDates()).setSpecification(generator.getERMSVersion())); + + } + + /* ERMS10 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS10_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS10_ID, + generator.validateERMS10(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + if (ResultsUtils.isResultValid(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS10_ID)) { + + /* ERMS11 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS11_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS11_ID, + generator.validateERMS11(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS12 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS12_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS12_ID, + generator.validateERMS12(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS13 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS13_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS13_ID, + generator.validateERMS13(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS14 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS14_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS14_ID, + generator.validateERMS14(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS15 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS15_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS15_ID, + generator.validateERMS15(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS16 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS16_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS16_ID, + generator.validateERMS16(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + /* ERMS17 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS17_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS17_ID, + generator.validateERMS17(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS18 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS18_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS18_ID, + generator.validateERMS18(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS19 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS19_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS19_ID, + generator.validateERMS19(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS20 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS20_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS20_ID, + generator.validateERMS20(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS21 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS21_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS21_ID, + generator.validateERMS21(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS22 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS22_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS22_ID, + generator.validateERMS22(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS23 */ + + } + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS23_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS23_ID, + generator.validateERMS23(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS24 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS24_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS24_ID, + generator.validateERMS24(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + if (ResultsUtils.isResultValid(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS24_ID)) { + + /* ERMS25 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS25_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS25_ID, + generator.validateERMS25(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS26 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS26_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS26_ID, + generator.validateERMS26(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + /* ERMS27 */ + + notifyObserversValidationStarted(moduleName, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS27_ID); + ResultsUtils.addResult(results, Constants.VALIDATION_REPORT_SPECIFICATION_ERMS27_ID, + generator.validateERMS27(ermsValidatorState, controlType).setSpecification(generator.getERMSVersion())); + + } + return null; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator.java new file mode 100644 index 0000000..c0ff218 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator.java @@ -0,0 +1,488 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator; + +import java.util.List; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ClassificationSchema; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ClassificationSchema.TextualDescriptionOfClassificationSchema; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ControlType; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.Identification; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.MaintenanceType; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.MaintenanceType.MaintenanceAgency; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.MaintenanceType.MaintenanceHistory.MaintenanceEvent; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.MaintenanceType.MaintenanceStatus; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.SystemInfoType; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.SystemInfoType.Agents; +import org.keeps.digitalpreservation.commonsip.citserms.utils.Message; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsControlValidator { + + /* + * emrs/control/identification Identification of the ERMS document itself. + */ + protected ReporterDetails validateERMS1(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + List identification = controlType.getIdentification(); + if (identification.isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/identification can't be null, in %1$s the erms/control/identification does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * emrs/control/identification/@identificationType A description of the + * identifier. + */ + protected ReporterDetails validateERMS2(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + List identification = controlType.getIdentification(); + + for (Identification id : identification) { + if (id.getIdentificationType() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/identification/@identificationType can't be null, in %1$s the erms/control/identification/@identification does not exist", + ermsValidatorState.getErmsName())); + return details; + } + } + return details; + } + + /* + * erms/control/informationClass Information class for the whole document based + * on information security classification. + */ + protected ReporterDetails validateERMS3(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + String informationClass = controlType.getInformationClass(); + + if (informationClass == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file should contain a erms/control/informationClass, in %1$s the erms/control/informationClass does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/classificationSchema/ A grouping element for a description of + * the classification schema used for the records management system. + */ + protected ReporterDetails validateERMS4(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + ClassificationSchema classificationSchema = controlType.getClassificationSchema(); + + if (classificationSchema == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file should contain a erms/control/classificationSchema, in %1$s the erms/control/classificationSchema does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/classificationSchema/textualDescriptionOfClassificationSchema/ A + * textual description of the classification schema used + */ + protected ReporterDetails validateERMS5(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + ClassificationSchema classificationSchema = controlType.getClassificationSchema(); + TextualDescriptionOfClassificationSchema tdcs = classificationSchema.getTextualDescriptionOfClassificationSchema(); + + if (tdcs == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a erms/control/classificationSchema/textualDescriptionOfClassificationSchema/, in %1$s the erms/control/classificationSchema/textualDescriptionOfClassificationSchema/ does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/classificationSchema/textualDescriptionOfClassificationSchema/p + * The textual description is carried out in one or more paragraph elements + * (abbreviated p-elements). + */ + + protected ReporterDetails validateERMS6(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + ClassificationSchema classificationSchema = controlType.getClassificationSchema(); + TextualDescriptionOfClassificationSchema tdcs = classificationSchema.getTextualDescriptionOfClassificationSchema(); + if (tdcs.getP().isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/classificationSchema/textualDescriptionOfClassificationSchema/p can't be null, in %1$s the erms/control/classificationSchema/textualDescriptionOfClassificationSchema/p does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/classificationSchema/additionalInformation Link to a document or + * webpage describing the classification and to add the infromation in the + * document + */ + protected ReporterDetails validateERMS7(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + ClassificationSchema classificationSchema = controlType.getClassificationSchema(); + if (classificationSchema.getAdditionalInformation() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a erms/control/classificationSchema/additionalInformation, in %1$s the erms/control/classificationSchema/additionalInformation does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/securityClass Security class for the whole document + */ + protected ReporterDetails validateERMS8(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + if (controlType.getSecurityClass() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file should contain a erms/control/securityClass, in %1$s the erms/control/securityClass does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/dates Grouping elemnt for dates to the whole document + */ + protected ReporterDetails validateERMS9(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + if (controlType.getDates() == null) { + details.setValid(false); + details.addIssue( + Message.createErrorMessage("ERMS file may contain a erms/control/dates, in %1$s the erms/control/dates does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation Grouping elemnt for the maintenance + * information + */ + protected ReporterDetails validateERMS10(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + if (controlType.getMaintenanceInformation() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation can't be null, in %1$s the erms/control/maintenanceInformation does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceStatus/@value The maintenance + * status of the document + */ + protected ReporterDetails validateERMS11(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceStatus mstatus = controlType.getMaintenanceInformation().getMaintenanceStatus(); + if (mstatus == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceStatus can't be null, in %1$s the erms/control/maintenanceInformation/maintenanceStatus does not exist", + ermsValidatorState.getErmsName())); + } else if (mstatus.getValue().isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceStatus/@value can't be null, in %1$s the erms/control/maintenanceInformation/maintenanceStatus/@value does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency Grouping element for + * describing the agency + */ + protected ReporterDetails validateERMS12(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceAgency can't be null, in %1$s the erms/control/maintenanceInformation/maintenanceAgency does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency/agencyCode The + * identifying code for the agency + */ + protected ReporterDetails validateERMS13(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency.getAgencyCode() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file should contain aerms/control/maintenanceInformation/maintenanceAgency/agencyCode, in %1$s the erms/control/maintenanceInformation/maintenanceAgency/agencyCode does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency/@type The type of + * identification code + */ + + /* + * REVER ISTO + */ + protected ReporterDetails validateERMS14(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency.getAgencyCode().getType() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceAgency/@type can't be null, in %1$s the erms/control/maintenanceInformation/maintenanceAgency/@type does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency/otherAgencyCode + * Identification code + */ + protected ReporterDetails validateERMS15(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency.getOtherAgencyCode().isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a erms/control/maintenanceInformation/maintenanceAgency/otherAgencyCode, in %1$s the erms/control/maintenanceInformation/maintenanceAgency/otherAgencyCode does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency/AgencyCode/@type Type + * of the other identification code + */ + protected ReporterDetails validateERMS16(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency.getAgencyCode().getType() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceAgency/agencyCode/@type can't be null, in %1$s the erms/control/maintenanceInformation/maintenanceAgency/agencyCode/@type does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency/agencyName The name of + * the agency + */ + protected ReporterDetails validateERMS17(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency.getAgencyName().isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceAgency/agencyName can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceAgency/agencyName does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceAgency/note A note describing + * the agency + */ + protected ReporterDetails validateERMS18(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceAgency agency = controlType.getMaintenanceInformation().getMaintenanceAgency(); + if (agency.getNote() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceAgency/note can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceAgency/note does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceHistory Maintenance history of + * the document + */ + protected ReporterDetails validateERMS19(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceType maintenanceInformation = controlType.getMaintenanceInformation(); + if (maintenanceInformation.getMaintenanceHistory() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceHistory can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceHistory does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceHistory/maintenanceEvent + * Maintenance events pertaining to the document + */ + protected ReporterDetails validateERMS20(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + MaintenanceType maintenanceInformation = controlType.getMaintenanceInformation(); + if (maintenanceInformation.getMaintenanceHistory().getMaintenanceEvent().isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceHistory/maintenanceEvent can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceHistory/maitenanceEvent does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceHistory/eventtype/@value + * Maintenance events pertaining to the document + */ + protected ReporterDetails validateERMS21(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + List maintenanceEvents = controlType.getMaintenanceInformation().getMaintenanceHistory() + .getMaintenanceEvent(); + for (MaintenanceEvent me : maintenanceEvents) { + if (me.getEventType().getValue() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceHistory/eventtype/@value can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceHistory/eventtype/@value does not exist", + ermsValidatorState.getErmsName())); + break; + } + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceHistory/eventDateTime The date + * and time the event occured + */ + protected ReporterDetails validateERMS22(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + List maintenanceEvents = controlType.getMaintenanceInformation().getMaintenanceHistory() + .getMaintenanceEvent(); + for (MaintenanceEvent me : maintenanceEvents) { + if (me.getEventDateTime() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceHistory/eventDateTime can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceHistory/eventDateTime does not exist", + ermsValidatorState.getErmsName())); + break; + } + } + return details; + } + + /* + * erms/control/maintenanceInformation/maintenanceHistory/agent The agent + * responsible for the event + */ + + protected ReporterDetails validateERMS23(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + List maintenanceEvents = controlType.getMaintenanceInformation().getMaintenanceHistory() + .getMaintenanceEvent(); + for (MaintenanceEvent me : maintenanceEvents) { + if (me.getAgent() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/maintenanceInformation/maintenanceHistory/agent can't be empty, in %1$s the erms/control/maintenanceInformation/maintenanceHistory/agent does not exist", + ermsValidatorState.getErmsName())); + break; + } + } + return details; + } + + /* + * erms/control/systemInformation Grouping elemnt where the exporting system can + * add extra information + */ + + protected ReporterDetails validateERMS24(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + SystemInfoType systemInfoType = controlType.getSystemInformation(); + + if (systemInfoType == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/systemInformation can't be empty, in %1$s the erms/control/systemInformation does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/systemInformation/extraMetadataInformation Exporting system can + * include system information in its own XML format. + */ + + protected ReporterDetails validateERMS25(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + SystemInfoType systemInfoType = controlType.getSystemInformation(); + + if (systemInfoType.getExtraMetadataInformation() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/systemInformation/extraMetadataInformation can't be empty, in %1$s the erms/control/systemInformation/extraMetadataInformation does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/systemInformation/extraMetadataInformation Information about + * system agents + */ + + protected ReporterDetails validateERMS26(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + SystemInfoType systemInfoType = controlType.getSystemInformation(); + + if (systemInfoType.getAgents() == null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "erms/control/systemInformation/agents can't be empty, in %1$s the erms/control/systemInformation/agents does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * erms/control/systemInformation/extraMetadataInformation Information about + * system agents + */ + + // AINDA NAO DA + protected ReporterDetails validateERMS27(final ErmsValidatorState ermsValidatorState, ControlType controlType) { + final ReporterDetails details = new ReporterDetails(); + Agents agents = controlType.getSystemInformation().getAgents(); + agents.getAgent(); + return details; + } + + protected abstract String getERMSVersion(); +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator204.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator204.java new file mode 100644 index 0000000..f0c1099 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator204.java @@ -0,0 +1,11 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +/** + * @author Carlos Afonso + */ +public class ErmsControlValidator204 extends ErmsControlValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator210.java new file mode 100644 index 0000000..2933ba6 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidator210.java @@ -0,0 +1,11 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +/** + * @author Carlos Afonso + */ +public class ErmsControlValidator210 extends ErmsControlValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidatorFactory.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidatorFactory.java new file mode 100644 index 0000000..5b6b8ad --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsComponentValidator/ErmsControlValidatorFactory.java @@ -0,0 +1,21 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsComponentValidator; + +import org.roda_project.commons_ip2.validator.components.metsRootComponent.metsHeaderValidator.MetsHeaderValidator; +import org.roda_project.commons_ip2.validator.components.metsRootComponent.metsHeaderValidator.MetsHeaderValidator204; +import org.roda_project.commons_ip2.validator.components.metsRootComponent.metsHeaderValidator.MetsHeaderValidator210; + +/** + * @author Carlos Afonso + */ +public class ErmsControlValidatorFactory { + public ErmsControlValidatorFactory() { + // empty constructor + } + + public ErmsControlValidator getGenerator(String version) { + if (version.equals("2.0.4")) { + return new ErmsControlValidator204(); + } + return new ErmsControlValidator210(); + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsValidator/ErmsValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsValidator/ErmsValidator.java new file mode 100644 index 0000000..26f8610 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsValidator/ErmsValidator.java @@ -0,0 +1,7 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsValidator; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsValidator { +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsValidator/ErmsValidatorComponentValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsValidator/ErmsValidatorComponentValidator210.java new file mode 100644 index 0000000..cca984f --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsControl/ermsValidator/ErmsValidatorComponentValidator210.java @@ -0,0 +1,30 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsControl.ermsValidator; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.components.ErmsValidatorImpl; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.observer.ValidationObserver; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; +import org.roda_project.commons_ip2.validator.state.StructureValidatorState; + +import java.io.IOException; +import java.util.Map; + +/** + * @author Carlos Afonso + */ +public class ErmsValidatorComponentValidator210 extends ErmsValidatorImpl { + @Override + public void addObserver(ValidationObserver observer) { + + } + + @Override + public void removeObserver(ValidationObserver observer) { + + } + + @Override + public Map validate(StructureValidatorState structureValidatorState, ErmsValidatorState ermsValidatorState) throws IOException { + return null; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator.java new file mode 100644 index 0000000..da02c7f --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator.java @@ -0,0 +1,88 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsDateValidator; + +import java.util.List; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.DateTypeComplex; +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.DatesType; +import org.keeps.digitalpreservation.commonsip.citserms.utils.Message; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsDateValidator { + + /* + * Dates A grouping element for all different kinds of dates occurring in the + * document + */ + public ReporterDetails validateERMS45(final ErmsValidatorState ermsValidatorState, DatesType dates) { + final ReporterDetails details = new ReporterDetails(); + if (dates == null) { + details.setValid(false); + details.addIssue( + Message.createErrorMessage("ERMS file should contain a Dates element, in %1$s the Dates does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * dates/date One date element is present for each type of date described + */ + public ReporterDetails validateERMS46(final ErmsValidatorState ermsValidatorState, DatesType dates) { + final ReporterDetails details = new ReporterDetails(); + + if (dates.getDate().isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage("dates/date can't be null, in %1$s the value is null", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * dates/date/@dateType Classification of the type of date described. + */ + public ReporterDetails validateERMS47(final ErmsValidatorState ermsValidatorState, DatesType dates) { + final ReporterDetails details = new ReporterDetails(); + + List date = dates.getDate(); + + for (DateTypeComplex d : date) { + + if (d.getDateType().equals("")) { + details.setValid(false); + details.addIssue(Message.createErrorMessage("dates/date/@dateType can't be null, in %1$s the value is null", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + /* + * dates/date[@dateType="other"]/@otherDateType When the date type is set to the + * value "other" the otherDateType attribute is used to give the type of date + * being described. + */ + public ReporterDetails validateERMS48(final ErmsValidatorState ermsValidatorState, DatesType dates) { + final ReporterDetails details = new ReporterDetails(); + + List date = dates.getDate(); + + for (DateTypeComplex d : date) { + + if (d.getDateType().equals("other") && (d.getOtherDateType() == null)) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "Date element should have a dates/date[@dateType=\"other\"]/@otherDateType, in %1$s the value is null", + ermsValidatorState.getErmsName())); + + } + } + return details; + } + + protected abstract String getERMSVersion(); +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator204.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator204.java new file mode 100644 index 0000000..4bd6b20 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator204.java @@ -0,0 +1,11 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsDateValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +/** + * @author Carlos Afonso + */ +public class ErmsDateValidator204 extends ErmsDateValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator210.java new file mode 100644 index 0000000..5ea4669 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidator210.java @@ -0,0 +1,11 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsDateValidator; +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; +/** + * @author Carlos Afonso + */ +public class ErmsDateValidator210 extends ErmsDateValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidatorFactory.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidatorFactory.java new file mode 100644 index 0000000..a04992b --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsDateValidator/ErmsDateValidatorFactory.java @@ -0,0 +1,17 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsDateValidator; + +/** + * @author Carlos Afonso + */ +public class ErmsDateValidatorFactory { + public ErmsDateValidatorFactory() { + // empty constructor + } + + public ErmsDateValidator getGenerator(String version) { + if (version.equals("2.0.4")) { + return new ErmsDateValidator204(); + } + return new ErmsDateValidator210(); + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator.java new file mode 100644 index 0000000..ed8fe1c --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator.java @@ -0,0 +1,64 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsNoteValidator; + +import java.util.List; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.Note; +import org.keeps.digitalpreservation.commonsip.citserms.utils.Message; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsNoteValidator { + + /* + * note A note regarding, for example, an aggregation or a record + */ + public ReporterDetails validateERMS49(final ErmsValidatorState ermsValidatorState, List notes) { + final ReporterDetails details = new ReporterDetails(); + if (notes.isEmpty()) { + details.setValid(false); + details.addIssue( + Message.createErrorMessage("ERMS file may contain a Note list element, in %1$s the Note list does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * note/@noteType A description of the identifier + */ + public ReporterDetails validateERMS50(final ErmsValidatorState ermsValidatorState, List notes) { + final ReporterDetails details = new ReporterDetails(); + + for (Note note : notes) { + if (note.getNoteType().equals("")) { + details.setValid(false); + details.addIssue(Message.createErrorMessage("Note may contain a note/@noteType, in %1$s the value is null", + ermsValidatorState.getErmsName())); + + } + } + return details; + } + + /* + * note/@noteDate A description of the identifier + */ + public ReporterDetails validateERMS51(final ErmsValidatorState ermsValidatorState, List notes) { + final ReporterDetails details = new ReporterDetails(); + + for (Note note : notes) { + if (note.getNoteDate()==null) { + details.setValid(false); + details.addIssue(Message.createErrorMessage("Note may contain a note/@noteDate, in %1$s the value is null", + ermsValidatorState.getErmsName())); + + } + } + return details; + } + + protected abstract String getERMSVersion(); +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator204.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator204.java new file mode 100644 index 0000000..f249c64 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator204.java @@ -0,0 +1,13 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsNoteValidator; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; + +/** + * @author Carlos Afonso + */ +public class ErmsNoteValidator204 extends ErmsNoteValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator210.java new file mode 100644 index 0000000..41aaef2 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidator210.java @@ -0,0 +1,13 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsNoteValidator; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; + +/** + * @author Carlos Afonso + */ +public class ErmsNoteValidator210 extends ErmsNoteValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidatorFactory.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidatorFactory.java new file mode 100644 index 0000000..04788ff --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsNoteValidator/ErmsNoteValidatorFactory.java @@ -0,0 +1,17 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsNoteValidator; + +/** + * @author Carlos Afonso + */ +public class ErmsNoteValidatorFactory { + public ErmsNoteValidatorFactory() { + // empty constructor + } + + public ErmsNoteValidator getGenerator(String version) { + if (version.equals("2.0.4")) { + return new ErmsNoteValidator204(); + } + return new ErmsNoteValidator210(); + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator.java new file mode 100644 index 0000000..24df85f --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator.java @@ -0,0 +1,68 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsRelation; + +import java.util.List; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.Relation; +import org.keeps.digitalpreservation.commonsip.citserms.utils.Message; +import org.keeps.digitalpreservation.commonsip.citserms.validator.state.ErmsValidatorState; +import org.roda_project.commons_ip2.validator.reporter.ReporterDetails; + +/** + * @author Carlos Afonso + */ +public abstract class ErmsRelationValidator { + + /* + * relation Each relation is described with a relation element. + */ + public ReporterDetails validateERMS52(final ErmsValidatorState ermsValidatorState, List relations) { + final ReporterDetails details = new ReporterDetails(); + if (relations.isEmpty()) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "ERMS file may contain a Relation list element, in %1$s the Relation list does not exist", + ermsValidatorState.getErmsName())); + } + return details; + } + + /* + * relation/@relationType Classification of the type of relationship described + */ + public ReporterDetails validateERMS53(final ErmsValidatorState ermsValidatorState, List relations) { + final ReporterDetails details = new ReporterDetails(); + + for (Relation relation : relations) { + if (relation.getRelationType().equals("")) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "relation/relationType can't be null, in %1$s the relation/relationType does not exist", + ermsValidatorState.getErmsName())); + + } + } + return details; + } + + /* + * dates/date[@dateType="other"]/@otherDateType When the date type is set to the + * value "other" the otherDateType attribute is used to give the type of date + * being described. + */ + public ReporterDetails validateERMS54(final ErmsValidatorState ermsValidatorState, List relations) { + final ReporterDetails details = new ReporterDetails(); + + for (Relation rel : relations) { + + if (rel.getRelationType().equals("own_relation_definition") && (rel.getOtherRelationType() == null)) { + details.setValid(false); + details.addIssue(Message.createErrorMessage( + "Relation element should have a relation[@relationType=\"own_relation_definition\"]/@otherRelationType, in %1$s the value is null", + ermsValidatorState.getErmsName())); + } + } + return details; + } + + protected abstract String getERMSVersion(); +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator204.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator204.java new file mode 100644 index 0000000..ee94802 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator204.java @@ -0,0 +1,13 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsRelation; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; + +/** + * @author Carlos Afonso + */ +public class ErmsRelationValidator204 extends ErmsRelationValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator210.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator210.java new file mode 100644 index 0000000..7a769a7 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidator210.java @@ -0,0 +1,13 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsRelation; + +import org.keeps.digitalpreservation.commonsip.citserms.validator.constants.Constants; + +/** + * @author Carlos Afonso + */ +public class ErmsRelationValidator210 extends ErmsRelationValidator { + @Override + protected String getERMSVersion() { + return Constants.VALIDATION_REPORT_HEADER_ERMS_VERSION; + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidatorFactory.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidatorFactory.java new file mode 100644 index 0000000..e22bba7 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/components/ermsRelation/ErmsRelationValidatorFactory.java @@ -0,0 +1,17 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.components.ermsRelation; + +/** + * @author Carlos Afonso + */ +public class ErmsRelationValidatorFactory { + public ErmsRelationValidatorFactory() { + // empty constructor + } + + public ErmsRelationValidator getGenerator(String version) { + if (version.equals("2.0.4")) { + return new ErmsRelationValidator204(); + } + return new ErmsRelationValidator210(); + } +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/constants/Constants.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/constants/Constants.java new file mode 100644 index 0000000..b080729 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/constants/Constants.java @@ -0,0 +1,67 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.constants; + +/** + * @author Carlos Afonso + */ +public class Constants { + public static final String ERMS_FILE = "ERMS.xml"; + + public static final String VALIDATION_REPORT_HEADER_ERMS_VERSION = "ERMS-"; + + public static final String SEPARATOR = "/"; + + public static final String ERMS_MODULE_NAME_2 = "Use of the ERMS control (element component)"; + public static final String ERMS_MODULE_NAME_3 = "Use of the ERMS additional information (element additional information)"; + + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS1_ID = "ERMS1"; + + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS2_ID = "ERMS2"; + + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS3_ID = "ERMS3"; + + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS4_ID = "ERMS4"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS5_ID = "ERMS5"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS6_ID = "ERMS6"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS7_ID = "ERMS7"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS8_ID = "ERMS8"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS9_ID = "ERMS9"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS10_ID = "ERMS10"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS11_ID = "ERMS11"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS12_ID = "ERMS12"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS13_ID = "ERMS13"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS14_ID = "ERMS14"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS15_ID = "ERMS15"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS16_ID = "ERMS16"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS17_ID = "ERMS17"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS18_ID = "ERMS18"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS19_ID = "ERMS19"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS20_ID = "ERMS20"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS21_ID = "ERMS21"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS22_ID = "ERMS22"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS23_ID = "ERMS23"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS24_ID = "ERMS24"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS25_ID = "ERMS25"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS26_ID = "ERMS26"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS27_ID = "ERMS27"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS28_ID = "ERMS28"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS29_ID = "ERMS29"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS30_ID = "ERMS30"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS31_ID = "ERMS31"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS32_ID = "ERMS32"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS33_ID = "ERMS33"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS34_ID = "ERMS34"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS35_ID = "ERMS35"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS36_ID = "ERMS36"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS37_ID = "ERMS37"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS38_ID = "ERMS38"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS39_ID = "ERMS39"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS40_ID = "ERMS40"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS41_ID = "ERMS41"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS42_ID = "ERMS42"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS43_ID = "ERMS43"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS44_ID = "ERMS44"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS45_ID = "ERMS45"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS46_ID = "ERMS46"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS47_ID = "ERMS47"; + public static final String VALIDATION_REPORT_SPECIFICATION_ERMS48_ID = "ERMS48"; +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/constants/ConstantsERMSspec.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/constants/ConstantsERMSspec.java new file mode 100644 index 0000000..85c2545 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/constants/ConstantsERMSspec.java @@ -0,0 +1,7 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.constants; + +/** + * @author Carlos Afonso + */ +public class ConstantsERMSspec { +} diff --git a/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/state/ErmsValidatorState.java b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/state/ErmsValidatorState.java new file mode 100644 index 0000000..4535136 --- /dev/null +++ b/src/main/java/org/keeps/digitalpreservation/commonsip/citserms/validator/state/ErmsValidatorState.java @@ -0,0 +1,63 @@ +package org.keeps.digitalpreservation.commonsip.citserms.validator.state; + +import org.keeps.digitalpreservation.commonsip.citserms.model.beans.ErmsType; +import org.roda_project.commons_ip2.mets_v1_12.beans.Mets; + +import java.util.ArrayList; + +/** + * @author Carlos Afonso + */ +public class ErmsValidatorState { + /** + * {@link Erms}. + */ + private ErmsType erms = null; + /** + * Type of the ip. + */ + private String ipType = null; + /** + * Mets name. + */ + private String ermsName = null; + /** + * Mets path. + */ + private String ermsPath = null; + /** + * {@link ArrayList} with the internal ids. + */ + private ArrayList ermsInternalIds = new ArrayList<>(); + + + public ErmsType getErms() { + return erms; + } + + public void setErms(ErmsType instatiateErmsFile) { + this.erms = instatiateErmsFile; + } + + public String getIpType() { + return ipType; + } + + /** + * Delete all entries from metsInternalIds list + */ + public void flushEntries() { + ermsInternalIds.clear(); + } + + public void setErmsPath(String ermsPath) { + this.ermsPath = ermsPath; + } + + public void setErmsName(String ermsName) { + this.ermsName=ermsName; + } + + public String getErmsName() { return ermsName; } + +}