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 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.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class XmlProcessor implements Processor { private final AbstractOpenAireProfile profile; private ValidationJob validationJob; // private final ValidationIssueRepository validationIssueRepository; private final long maxNumberOfRecords; private int processedRecords; private String status = "SUCCESS"; // private int resultSum; private int scoreSum; public XmlProcessor(final AbstractOpenAireProfile profile, ValidationJob validationJob, final long maxNumberOfRecords){ super(); this.profile = profile; this.validationJob = validationJob; 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"); System.out.println("Identifier: " + recordUrl); List validationRuleResults = new ArrayList<>(); List validationIssues = new ArrayList<>(); 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, profile.name(), recordUrl, ruleName, profile, engineResult); if (validationRuleResult.status.equals("FAILURE") || validationRuleResult.internalError!=null) { this.status = "FAILURE"; } if (engineResult.errors()!= null && engineResult.errors().iterator().hasNext()) { validationRuleResult.hasErrors = true; for (String error:engineResult.errors()) { validationIssues.add(new ValidationIssue(validationJob.id, ruleName, recordUrl, error,"ERROR")); } } if (engineResult.warnings()!= null && engineResult.warnings().iterator().hasNext()) { validationRuleResult.hasWarnings = true; for (String warning:engineResult.warnings()) { validationIssues.add(new ValidationIssue(validationJob.id, ruleName, recordUrl, warning, "WARNING")); } } validationRuleResults.add(validationRuleResult); scoreSum += engineResult.score(); } } processedRecords++; validationJob.recordsTested = processedRecords; validationJob.score = scoreSum/processedRecords; Map resultsMap = new HashMap(); resultsMap.put("results", validationRuleResults); resultsMap.put("issues", validationIssues); exchange.getIn().setBody(resultsMap, Map.class); // System.out.println("Validation Issues: " + validationIssues); if (processedRecords > maxNumberOfRecords) { exchange.getIn().setHeader("MyHeader", "stop"); exchange.getIn().setHeader("validationId", validationJob.id); exchange.getIn().setHeader("baseUrl", validationJob.baseUrl); exchange.getIn().setHeader("startDate", validationJob.startDate); exchange.getIn().setHeader("guidelines", validationJob.guidelines); exchange.getIn().setHeader("status", status); exchange.getIn().setHeader("recordsTested", processedRecords-1); exchange.getIn().setHeader("maxNumberOfRecords", maxNumberOfRecords); exchange.getIn().setHeader("score", scoreSum/processedRecords); } } //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 guidelines, String recordUrl, String ruleName, AbstractOpenAireProfile profile, Guideline.Result engineResult) { validationRuleResult.validationJobId = validationJobId; validationRuleResult.guidelines = guidelines; validationRuleResult.ruleName = ruleName; if (profile.guideline(ruleName) != null) { validationRuleResult.ruleWeight = profile.guideline(ruleName).getWeight(); if (profile.guideline(ruleName).getRequirementLevel() != null && profile.guideline(ruleName).getRequirementLevel().name()!=null) validationRuleResult.requirement_level = profile.guideline(ruleName).getRequirementLevel().name(); if (profile.guideline(ruleName).getDescription() != null) validationRuleResult.description = profile.guideline(ruleName).getDescription(); if (profile.guideline(ruleName).getFairPrinciples() != null) validationRuleResult.fair_principles = profile.guideline(ruleName).getFairPrinciples(); if (profile.guideline(ruleName).getLink() != null) validationRuleResult.link = profile.guideline(ruleName).getLink(); } validationRuleResult.recordUrl = recordUrl; validationRuleResult.score = engineResult.score(); validationRuleResult.status = engineResult.status().toString(); validationRuleResult.internalError = engineResult.internalError(); } }