package eu.dnetlib.validatorapi.processors; import eu.dnetlib.validator2.validation.XMLApplicationProfile; import eu.dnetlib.validator2.validation.guideline.Guideline; import eu.dnetlib.validator2.validation.guideline.openaire.AbstractOpenAireProfile; import eu.dnetlib.validatorapi.entities.ValidationIssue; import eu.dnetlib.validatorapi.entities.ValidationJob; import eu.dnetlib.validatorapi.entities.ValidationRuleResult; import eu.dnetlib.validatorapi.repositories.ValidationIssueRepository; import eu.dnetlib.validatorapi.repositories.ValidationResultRepository; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.StringReader; import java.util.Map; public class XmlProcessor implements Processor { private final AbstractOpenAireProfile profile; private ValidationJob validationJob; private final ValidationIssueRepository validationIssueRepository; private final ValidationResultRepository validationResultRepository; private final long maxNumberOfRecords; private int processedRecords; // private int resultSum; private int scoreSum; public XmlProcessor(final AbstractOpenAireProfile profile, ValidationJob validationJob, final ValidationIssueRepository validationIssueRepository, final ValidationResultRepository validationResultRepository, final long maxNumberOfRecords){ super(); this.profile = profile; this.validationJob = validationJob; this.validationIssueRepository = validationIssueRepository; this.validationResultRepository = validationResultRepository; this.maxNumberOfRecords = maxNumberOfRecords; } @Override public void process(Exchange exchange) throws Exception { String recordXml = exchange.getIn().getBody(String.class); final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); final DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); Document doc = documentBuilder.parse(new InputSource(new StringReader(recordXml))); String recordUrl = extractRecordUrl(doc, "identifier"); if (profile != null) { XMLApplicationProfile.ValidationResult validationResult = profile.validate("id", doc); //what id is that? Map results = validationResult.results(); ValidationRuleResult validationRuleResult; for (Map.Entry entry : results.entrySet()) { //for each rule of the record final Guideline.Result engineResult = (Guideline.Result) entry.getValue(); String ruleName = entry.getKey().toString(); validationRuleResult = new ValidationRuleResult(); constructValidationRuleResult(validationRuleResult, validationJob.id, recordUrl, ruleName, profile, engineResult); if (engineResult.errors()!= null && engineResult.errors().iterator().hasNext()) { validationRuleResult.hasErrors = true; saveValidationIssues(validationJob.id, recordUrl, ruleName, engineResult.errors(), "ERROR"); } if (engineResult.warnings()!= null && engineResult.warnings().iterator().hasNext()) { validationRuleResult.hasWarnings = true; saveValidationIssues(validationJob.id, recordUrl, ruleName, engineResult.warnings(), "WARNING"); } validationResultRepository.save(validationRuleResult); scoreSum += engineResult.score(); } } processedRecords++; validationJob.recordsTested = processedRecords; validationJob.score = scoreSum/processedRecords; //System.out.println("\n\n\nvalidation job: " + validationJob.recordsTested); if (processedRecords > maxNumberOfRecords) { exchange.getIn().setHeader("MyHeader", "stop"); } } private void saveValidationIssues(int validationJobId, String recordUrl, String ruleName, Iterable issues, String issueType) { for (String issue:issues) { ValidationIssue validationIssue = new ValidationIssue(); validationIssue.validationJobId = validationJobId; validationIssue.ruleName = ruleName; validationIssue.recordUrl = recordUrl; validationIssue.issueType = issueType; validationIssue.issueText = issue; validationIssueRepository.save(validationIssue); } } //TODO consider throwing exception - UTIL class? private String extractRecordUrl(final Document document, final String xmlField) { NodeList identifierNodes = document.getElementsByTagName(xmlField); if (identifierNodes.getLength() > 0) { Element identifierElement = (Element) identifierNodes.item(0); return identifierElement.getTextContent(); } return "-"; } private void constructValidationRuleResult(ValidationRuleResult validationRuleResult, int validationJobId, String recordUrl, String ruleName, AbstractOpenAireProfile profile, Guideline.Result engineResult) { validationRuleResult.validationJobId = validationJobId; validationRuleResult.ruleName = ruleName; validationRuleResult.ruleWeight = profile.guideline(ruleName).getWeight(); validationRuleResult.recordUrl = recordUrl; validationRuleResult.score = engineResult.score(); validationRuleResult.status = engineResult.status().toString(); validationRuleResult.internalError = engineResult.internalError(); } }