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 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"); 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 (engineResult.errors()!= null && engineResult.errors().iterator().hasNext()) { validationRuleResult.hasErrors = true; for (String error:engineResult.errors()) { validationIssues.add(new ValidationIssue(validationJob.id, recordUrl, ruleName, error,"ERROR")); } } if (engineResult.warnings()!= null && engineResult.warnings().iterator().hasNext()) { validationRuleResult.hasWarnings = true; for (String warning:engineResult.warnings()) { validationIssues.add(new ValidationIssue(validationJob.id, recordUrl, ruleName, warning, "WARNING")); } } //validationResultRepository.save(validationRuleResult); 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); if (processedRecords == maxNumberOfRecords) { exchange.getIn().setHeader("MyHeader", "stop"); } } //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; validationRuleResult.ruleWeight = profile.guideline(ruleName).getWeight(); validationRuleResult.recordUrl = recordUrl; validationRuleResult.score = engineResult.score(); validationRuleResult.status = engineResult.status().toString(); validationRuleResult.internalError = engineResult.internalError(); } }