package com.gitlab.sszuev.df.messages; import org.apache.jena.graph.Graph; import org.apache.jena.graph.compose.MultiUnion; import org.apache.jena.graph.compose.Union; import org.apache.jena.rdf.model.Model; import org.apache.jena.shacl.ShaclValidator; import org.apache.jena.shacl.Shapes; import org.apache.jena.shacl.ValidationReport; import org.apache.jena.shacl.lib.ShLib; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Objects; public class JenaSHACLValidator implements MessageValidator { private static final Logger LOGGER = LoggerFactory.getLogger(JenaSHACLValidator.class); private static final ShaclValidator VALIDATOR = ShaclValidator.get(); private final Model rules; private final Shapes shapes; public JenaSHACLValidator(Model rules) { this.rules = Objects.requireNonNull(rules); this.shapes = VALIDATOR.parse(rules.getGraph()); } @Override public Graph validate(Graph message) { return validate(rules.getGraph(), message); } public Graph validate(Graph profile, Graph message) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Go"); } Graph data = new Union(message, profile); if (shapes.isEmpty()) { throw new IllegalArgumentException("Empty shapes"); } ValidationReport report = VALIDATOR.validate(shapes, data); if (LOGGER.isDebugEnabled()) { debug(report); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Done"); } return report.getGraph(); } private void debug(ValidationReport report) { report.getEntries().forEach(e -> { LOGGER.debug("Node={}", ShLib.displayStr(e.focusNode())); if (e.resultPath() != null) LOGGER.debug(" Path=%{}", e.resultPath()); if (e.value() != null) LOGGER.debug(" Value: {}", ShLib.displayStr(e.value())); if (e.message() != null) LOGGER.debug(" Message: {}", e.message()); }); } }