From ebe9d6e7afb1b086172521030028d30cbddac08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Sun, 1 Mar 2020 15:30:08 +0100 Subject: [PATCH 1/5] GH-1574 validate all target nodes for every transaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håvard Ottestad --- .../rdf4j/sail/shacl/AST/ShaclProperties.java | 4 +- .../rdf4j/sail/shacl/AST/TargetNode.java | 49 +++---- .../sail/shacl/planNodes/GroupByCount.java | 4 +- .../rdf4j/sail/shacl/planNodes/Tuple.java | 2 +- .../shacl/planNodes/ValuesBackedNode.java | 121 ++++++++++++++++++ .../rdf4j/sail/shacl/AbstractShaclTest.java | 18 ++- ...rdering.java => PlanNodeOrderingTest.java} | 2 +- .../sail/shacl/RdfsShaclConnectionTest.java | 1 - .../rdf4j/sail/shacl/UnknownShapesTest.java | 7 + .../org/eclipse/rdf4j/sail/shacl/Utils.java | 24 +++- .../rdf4j/sail/shacl/W3cComplianceTest.java | 1 - .../sail/shacl/mock/MockInputPlanNode.java | 7 +- .../ShaclConcurrencyTest.java | 3 +- .../ShaclIsolationLevelTest.java | 3 +- .../ShaclRepositoryConnectionTest.java | 3 +- .../ShaclRepositoryTest.java | 3 +- .../notTargetNode/invalid/case1/query1.rq | 2 +- .../notTargetNode/invalid/case2/query1.rq | 12 -- .../notTargetNode/invalid/case2/query2.rq | 12 -- .../notTargetNode/valid/case1/query1.rq | 12 -- .../notTargetNode/valid/case2/query1.rq | 12 -- .../notTargetNode/valid/case2/query2.rq | 12 -- .../targetNode2/invalid/case1/query1.rq | 2 +- .../targetNode2/invalid/case2/query1.rq | 12 -- .../targetNode2/invalid/case2/query2.rq | 12 -- .../targetNode2/valid/case1/query1.rq | 12 -- .../targetNode2/valid/case2/query1.rq | 12 -- .../validateTarget/invalid/case1/query1.rq | 12 -- .../validateTarget/invalid/case2/query1.rq | 12 -- .../validateTarget/invalid/case2/query2.rq | 12 -- .../validateTarget/valid/case1/query1.rq | 12 -- .../validateTarget/valid/case2/query1.rq | 12 -- .../validateTarget/valid/case2/query2.rq | 12 -- .../validateTarget/valid/case3/query1.rq | 12 -- .../validateTarget/valid/case3/query2.rq | 12 -- .../validateTarget/valid/case4/query1.rq | 14 -- .../validateTarget/valid/case4/query2.rq | 19 --- .../targetNode/initialData.ttl} | 6 +- .../targetNode/invalid/case1/initialData.ttl | 11 ++ .../targetNode/invalid/case1/query1.rq | 8 +- .../targetNode/invalid/case2/initialData.ttl | 11 ++ .../targetNode/invalid/case2/query1.rq | 14 +- .../targetNode/invalid/case2/query2.rq | 10 -- .../targetNode/invalid/case3/query1.rq | 12 -- .../targetNode/invalid/case3/query2.rq | 11 -- .../targetNode/valid/case1/initialData.ttl | 11 ++ .../targetNode/valid/case2/initialData.ttl | 11 ++ .../targetNode/valid/case3/initialData.ttl | 11 ++ .../targetNode/valid/case4/initialData.ttl | 11 ++ .../targetNode/valid/case5/initialData.ttl | 11 ++ 50 files changed, 307 insertions(+), 324 deletions(-) create mode 100644 core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java rename core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/{TestPlanNodeOrdering.java => PlanNodeOrderingTest.java} (98%) rename core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/{ => rdf4jcompliance}/ShaclConcurrencyTest.java (91%) rename core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/{ => rdf4jcompliance}/ShaclIsolationLevelTest.java (92%) rename core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/{ => rdf4jcompliance}/ShaclRepositoryConnectionTest.java (91%) rename core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/{ => rdf4jcompliance}/ShaclRepositoryTest.java (90%) delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case1/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case1/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case2/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case1/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case1/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query2.rq rename core/sail/shacl/src/test/resources/test-cases/{datatype/validateTarget/shacl.ttl => minCount/targetNode/initialData.ttl} (79%) create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.ttl create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.ttl delete mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query2.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query1.rq delete mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query2.rq create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.ttl create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.ttl create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.ttl create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.ttl create mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.ttl diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java index c12fe37b401..cb87e7aca6d 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java @@ -7,6 +7,7 @@ import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.Value; import org.eclipse.rdf4j.model.vocabulary.SHACL; +import org.eclipse.rdf4j.query.algebra.evaluation.util.ValueComparator; import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,6 +16,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.TreeSet; import java.util.stream.Stream; public class ShaclProperties { @@ -48,7 +50,7 @@ public class ShaclProperties { String flags = ""; Set targetClass = new HashSet<>(0); - Set targetNode = new HashSet<>(0); + TreeSet targetNode = new TreeSet<>(new ValueComparator()); Set targetSubjectsOf = new HashSet<>(0); Set targetObjectsOf = new HashSet<>(0); diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java index 2d44348974e..ad15f604b85 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java @@ -22,10 +22,11 @@ import org.eclipse.rdf4j.sail.shacl.planNodes.SetFilterNode; import org.eclipse.rdf4j.sail.shacl.planNodes.TrimTuple; import org.eclipse.rdf4j.sail.shacl.planNodes.Unique; +import org.eclipse.rdf4j.sail.shacl.planNodes.ValuesBackedNode; import java.util.Arrays; import java.util.Objects; -import java.util.Set; +import java.util.TreeSet; /** * sh:targetNode @@ -34,9 +35,9 @@ */ public class TargetNode extends NodeShape { - private final Set targetNodeSet; + private final TreeSet targetNodeSet; - TargetNode(Resource id, SailRepositoryConnection connection, boolean deactivated, Set targetNode) { + TargetNode(Resource id, SailRepositoryConnection connection, boolean deactivated, TreeSet targetNode) { super(id, connection, deactivated); this.targetNodeSet = targetNode; assert !this.targetNodeSet.isEmpty(); @@ -56,9 +57,8 @@ public PlanNode getPlan(ConnectionsGroup connectionsGroup, boolean printPlans, @Override public PlanNode getPlanAddedStatements(ConnectionsGroup connectionsGroup, PlaneNodeWrapper planeNodeWrapper) { - PlanNode parent = connectionsGroup.getCachedNodeFor( - new Select(connectionsGroup.getAddedStatements(), getQuery("?a", "?c", null), "?a", "?c")); - return new Unique(new TrimTuple(parent, 0, 1)); + + return new ValuesBackedNode(targetNodeSet); } @@ -79,32 +79,33 @@ public boolean requiresEvaluation(SailConnection addedStatements, SailConnection public String getQuery(String subjectVariable, String objectVariable, RdfsSubClassOfReasoner rdfsSubClassOfReasoner) { - return targetNodeSet.stream() - .map(value -> { - if (value instanceof Resource) { - return "<" + value + ">"; + StringBuilder sb = new StringBuilder(); + sb.append("VALUES ( ").append(subjectVariable).append(" ) {\n"); + + targetNodeSet.stream() + .map(targetNode -> { + if (targetNode instanceof Resource) { + return "<" + targetNode + ">"; } - if (value instanceof Literal) { - IRI datatype = ((Literal) value).getDatatype(); + if (targetNode instanceof Literal) { + IRI datatype = ((Literal) targetNode).getDatatype(); if (datatype == null) { - return "\"" + value.stringValue() + "\""; + return "\"" + targetNode.stringValue() + "\""; } - if (((Literal) value).getLanguage().isPresent()) { - return "\"" + value.stringValue() + "\"@" + ((Literal) value).getLanguage().get(); + if (((Literal) targetNode).getLanguage().isPresent()) { + return "\"" + targetNode.stringValue() + "\"@" + ((Literal) targetNode).getLanguage().get(); } - return "\"" + value.stringValue() + "\"^^<" + datatype.stringValue() + ">"; + return "\"" + targetNode.stringValue() + "\"^^<" + datatype.stringValue() + ">"; } - throw new IllegalStateException(value.getClass().getSimpleName()); + throw new IllegalStateException(targetNode.getClass().getSimpleName()); }) - .map(r -> "{{ select * where {BIND(" + r + " as " + subjectVariable + "). " + subjectVariable + " ?b1 " - + objectVariable + " .}}}" - + "\n UNION \n" - + "{{ select * where {BIND(" + r + " as " + subjectVariable + "). " + objectVariable + " ?b1 " - + subjectVariable + " .}}}") - .reduce((a, b) -> a + " UNION " + b) - .get(); + .forEach(targetNode -> sb.append("( ").append(targetNode).append(" )\n")); + + sb.append("}\n"); + + return sb.toString(); } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java index d41c780b912..1c1f0b14396 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java @@ -14,6 +14,7 @@ import org.eclipse.rdf4j.model.impl.SimpleValueFactory; import org.eclipse.rdf4j.sail.SailException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -74,7 +75,8 @@ private void calculateNext() { } - List line = Arrays.asList(subject, SimpleValueFactory.getInstance().createLiteral(count)); + List line = new ArrayList<>( + Arrays.asList(subject, SimpleValueFactory.getInstance().createLiteral(count))); next.line = line; diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java index 6e6d8eb028a..2660c5c308b 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java @@ -39,7 +39,7 @@ public Tuple(List list) { } public Tuple(Value... list) { - line = Arrays.asList(list); + line = new ArrayList<>(Arrays.asList(list)); } public Tuple(List list, Tuple historyTuple) { diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java new file mode 100644 index 00000000000..4e3c8b3c623 --- /dev/null +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2018 Eclipse RDF4J contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + *******************************************************************************/ + +package org.eclipse.rdf4j.sail.shacl.planNodes; + +import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.rdf4j.common.iteration.CloseableIteration; +import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.sail.SailException; +import org.eclipse.rdf4j.sail.memory.MemoryStoreConnection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.Iterator; + +/** + * @author Håvard Ottestad + */ +public class ValuesBackedNode implements PlanNode { + + private static final Logger logger = LoggerFactory.getLogger(ValuesBackedNode.class); + private final Collection collection; + private ValidationExecutionLogger validationExecutionLogger; + boolean printed = false; + + public ValuesBackedNode(Collection collection) { + this.collection = collection; + } + + @Override + public CloseableIteration iterator() { + return new LoggingCloseableIteration(this, validationExecutionLogger) { + + Iterator iterator = collection.iterator(); + + @Override + public void close() throws SailException { + } + + @Override + public boolean localHasNext() throws SailException { + return iterator.hasNext(); + } + + @Override + public Tuple loggingNext() throws SailException { + return new Tuple(iterator.next()); + } + + @Override + public void remove() throws SailException { + + } + }; + } + + @Override + public int depth() { + return 0; + } + + @Override + public void getPlanAsGraphvizDot(StringBuilder stringBuilder) { + if (printed) { + return; + } + printed = true; + stringBuilder.append(getId() + " [label=\"" + StringEscapeUtils.escapeJava(this.toString()) + "\"];") + .append("\n"); + + } + + @Override + public String getId() { + return System.identityHashCode(this) + ""; + } + + @Override + public IteratorData getIteratorDataType() { + return IteratorData.tripleBased; + } + + @Override + public String toString() { + return "ValuesBackedNode{" + + "collection=" + collection + + ", validationExecutionLogger=" + validationExecutionLogger + + ", printed=" + printed + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ValuesBackedNode that = (ValuesBackedNode) o; + return collection.equals(that.collection); + } + + @Override + public int hashCode() { + + return collection.hashCode(); + + } + + @Override + public void receiveLogger(ValidationExecutionLogger validationExecutionLogger) { + this.validationExecutionLogger = validationExecutionLogger; + } +} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java index 4fba9588e80..7723dc17cb3 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java @@ -12,7 +12,6 @@ import org.eclipse.rdf4j.IsolationLevel; import org.eclipse.rdf4j.IsolationLevels; import org.eclipse.rdf4j.common.io.IOUtil; -import org.eclipse.rdf4j.common.iteration.Iterations; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.ValueFactory; @@ -92,7 +91,6 @@ abstract public class AbstractShaclTest { "test-cases/datatype/targetObjectsOf", "test-cases/datatype/targetSubjectsOf", "test-cases/datatype/targetSubjectsOfSingle", - "test-cases/datatype/validateTarget", "test-cases/deactivated/nodeshape", "test-cases/deactivated/or", "test-cases/deactivated/propertyshape", @@ -126,6 +124,7 @@ abstract public class AbstractShaclTest { "test-cases/or/classValidateTarget", "test-cases/or/datatype", "test-cases/or/datatype2", + "test-cases/or/datatype2", "test-cases/or/datatypeDifferentPaths", "test-cases/or/datatypeNodeShape", "test-cases/or/datatypeTargetNode", @@ -246,6 +245,7 @@ static void runTestCase(String shaclPath, String dataPath, ExpectedResult expect try { Utils.loadShapeData(shaclRepository, shaclFile); + Utils.loadInitialData(shaclRepository, dataPath + "initialData.ttl"); } catch (IOException e) { throw new RuntimeException(e); } @@ -259,7 +259,17 @@ static void runTestCase(String shaclPath, String dataPath, ExpectedResult expect ValueFactory vf = connection.getValueFactory(); connection.add(vf.createBNode(), vf.createIRI("http://example.com/jkhsdfiu3r2y9fjr3u0"), vf.createLiteral("auto-generated!"), vf.createBNode()); - connection.commit(); + try { + connection.commit(); + } catch (RepositoryException sailException) { + if (!(sailException.getCause() instanceof ShaclSailValidationException)) { + throw sailException; + } + exception = true; + logger.debug(sailException.getMessage()); + + printResults(sailException); + } } } @@ -379,6 +389,7 @@ static void runTestCaseSingleTransaction(String shaclPath, String dataPath, Expe SailRepository shaclRepository = getShaclSail(); try { Utils.loadShapeData(shaclRepository, shaclPath + "shacl.ttl"); + Utils.loadInitialData(shaclRepository, shaclPath + "initialData.ttl"); } catch (IOException e) { throw new RuntimeException(e); } @@ -449,6 +460,7 @@ static void runTestCaseRevalidate(String shaclPath, String dataPath, ExpectedRes SailRepository shaclRepository = getShaclSail(); try { Utils.loadShapeData(shaclRepository, shaclPath + "shacl.ttl"); + Utils.loadInitialData(shaclRepository, shaclPath + "initialData.ttl"); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TestPlanNodeOrdering.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java similarity index 98% rename from core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TestPlanNodeOrdering.java rename to core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java index 91c30b822d4..c86b4f601b1 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TestPlanNodeOrdering.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java @@ -27,7 +27,7 @@ /** * @author Håvard Ottestad */ -public class TestPlanNodeOrdering { +public class PlanNodeOrderingTest { @Test public void testSelect() { diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/RdfsShaclConnectionTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/RdfsShaclConnectionTest.java index 34669768b7e..ec7bffa55f3 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/RdfsShaclConnectionTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/RdfsShaclConnectionTest.java @@ -8,7 +8,6 @@ package org.eclipse.rdf4j.sail.shacl; -import org.eclipse.rdf4j.common.iteration.Iterations; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.impl.SimpleValueFactory; diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UnknownShapesTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UnknownShapesTest.java index 6b637d29620..16118e2e26c 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UnknownShapesTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/UnknownShapesTest.java @@ -1,3 +1,10 @@ +/******************************************************************************* + * Copyright (c) 2019 Eclipse RDF4J contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + *******************************************************************************/ package org.eclipse.rdf4j.sail.shacl; import ch.qos.logback.classic.spi.ILoggingEvent; diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java index 4caf2bd3fbe..7e403570697 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java @@ -27,8 +27,8 @@ import org.eclipse.rdf4j.sail.memory.MemoryStore; import java.io.IOException; -import java.net.URL; import java.io.InputStream; +import java.net.URL; import java.util.UUID; /** @@ -130,6 +130,28 @@ public static SailRepository getSailRepository(URL resourceName) { return sailRepository; } + public static void loadInitialData(SailRepository repo, String resourceName) throws IOException { + ((ShaclSail) repo.getSail()).disableValidation(); + + try { + try (InputStream initialData = Utils.class.getClassLoader().getResourceAsStream(resourceName)) { + + if (initialData == null) { + return; + } + + try (RepositoryConnection conn = repo.getConnection()) { + conn.begin(IsolationLevels.NONE); + conn.add(initialData, "", RDFFormat.TURTLE); + conn.commit(); + } + } + } finally { + ((ShaclSail) repo.getSail()).enableValidation(); + } + + } + static class Ex { public final static String ns = "http://example.com/ns#"; diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java index 9f42baab0eb..0c9899f279c 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java @@ -1,6 +1,5 @@ package org.eclipse.rdf4j.sail.shacl; -import org.eclipse.rdf4j.common.iteration.Iterations; import org.eclipse.rdf4j.model.Literal; import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.Value; diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/mock/MockInputPlanNode.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/mock/MockInputPlanNode.java index 3f47a4d58e9..1a0f80319a6 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/mock/MockInputPlanNode.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/mock/MockInputPlanNode.java @@ -19,6 +19,7 @@ import org.eclipse.rdf4j.sail.shacl.planNodes.ValidationExecutionLogger; import java.util.Arrays; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; @@ -28,14 +29,14 @@ */ public class MockInputPlanNode implements PlanNode { - List initialData; + Collection initialData; private ValidationExecutionLogger validationExecutionLogger; - public MockInputPlanNode(List initialData) { + public MockInputPlanNode(Collection initialData) { this.initialData = initialData; } - public MockInputPlanNode(List... list) { + public MockInputPlanNode(Collection... list) { initialData = Arrays.stream(list) .map(strings -> strings.stream() diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclConcurrencyTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclConcurrencyTest.java similarity index 91% rename from core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclConcurrencyTest.java rename to core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclConcurrencyTest.java index 0567e7538dc..1a0e11c6e2e 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclConcurrencyTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclConcurrencyTest.java @@ -6,12 +6,13 @@ * http://www.eclipse.org/org/documents/edl-v10.php. *******************************************************************************/ -package org.eclipse.rdf4j.sail.shacl; +package org.eclipse.rdf4j.sail.shacl.rdf4jcompliance; import org.eclipse.rdf4j.sail.Sail; import org.eclipse.rdf4j.sail.SailConcurrencyTest; import org.eclipse.rdf4j.sail.SailException; import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; import org.junit.Ignore; import org.junit.Test; diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclIsolationLevelTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclIsolationLevelTest.java similarity index 92% rename from core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclIsolationLevelTest.java rename to core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclIsolationLevelTest.java index ab09ee0831f..4047a0f4f72 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclIsolationLevelTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclIsolationLevelTest.java @@ -6,13 +6,14 @@ * http://www.eclipse.org/org/documents/edl-v10.php. *******************************************************************************/ -package org.eclipse.rdf4j.sail.shacl; +package org.eclipse.rdf4j.sail.shacl.rdf4jcompliance; import org.eclipse.rdf4j.IsolationLevel; import org.eclipse.rdf4j.sail.Sail; import org.eclipse.rdf4j.sail.SailException; import org.eclipse.rdf4j.sail.SailIsolationLevelTest; import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; public class ShaclIsolationLevelTest extends SailIsolationLevelTest { diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclRepositoryConnectionTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclRepositoryConnectionTest.java similarity index 91% rename from core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclRepositoryConnectionTest.java rename to core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclRepositoryConnectionTest.java index bbb105e8bea..99118863775 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclRepositoryConnectionTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclRepositoryConnectionTest.java @@ -6,13 +6,14 @@ * http://www.eclipse.org/org/documents/edl-v10.php. *******************************************************************************/ -package org.eclipse.rdf4j.sail.shacl; +package org.eclipse.rdf4j.sail.shacl.rdf4jcompliance; import org.eclipse.rdf4j.IsolationLevel; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryConnectionTest; import org.eclipse.rdf4j.repository.sail.SailRepository; import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; public class ShaclRepositoryConnectionTest extends RepositoryConnectionTest { diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclRepositoryTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclRepositoryTest.java similarity index 90% rename from core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclRepositoryTest.java rename to core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclRepositoryTest.java index 017fb6b8cea..73ec16ea368 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclRepositoryTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/rdf4jcompliance/ShaclRepositoryTest.java @@ -6,12 +6,13 @@ * http://www.eclipse.org/org/documents/edl-v10.php. *******************************************************************************/ -package org.eclipse.rdf4j.sail.shacl; +package org.eclipse.rdf4j.sail.shacl.rdf4jcompliance; import org.eclipse.rdf4j.repository.Repository; import org.eclipse.rdf4j.repository.RepositoryTest; import org.eclipse.rdf4j.repository.sail.SailRepository; import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.eclipse.rdf4j.sail.shacl.ShaclSail; public class ShaclRepositoryTest extends RepositoryTest { diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case1/query1.rq index 6a7e24272d8..4c0472c70f7 100644 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case1/query1.rq +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case1/query1.rq @@ -7,6 +7,6 @@ PREFIX xsd: INSERT DATA { -ex:validPerson1 ex:age 2. +ex:validPerson1 ex:age "hello". } diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query1.rq deleted file mode 100644 index 7b46ab3592c..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "test". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query2.rq deleted file mode 100644 index 06b0ae877a3..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/invalid/case2/query2.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 3. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case1/query1.rq deleted file mode 100644 index 4c0472c70f7..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case1/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "hello". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query1.rq deleted file mode 100644 index 0ade9c9263f..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 1. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query2.rq deleted file mode 100644 index 4c0472c70f7..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/notTargetNode/valid/case2/query2.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "hello". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case1/query1.rq index 4c0472c70f7..6a7e24272d8 100644 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case1/query1.rq +++ b/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case1/query1.rq @@ -7,6 +7,6 @@ PREFIX xsd: INSERT DATA { -ex:validPerson1 ex:age "hello". +ex:validPerson1 ex:age 2. } diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query1.rq deleted file mode 100644 index 6a7e24272d8..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 2. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query2.rq deleted file mode 100644 index 4c0472c70f7..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/invalid/case2/query2.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "hello". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case1/query1.rq deleted file mode 100644 index 6a7e24272d8..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case1/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 2. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case2/query1.rq deleted file mode 100644 index 7b46ab3592c..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/targetNode2/valid/case2/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "test". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case1/query1.rq deleted file mode 100644 index cb610268e16..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case1/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "4". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query1.rq deleted file mode 100644 index 06b0ae877a3..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 3. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query2.rq deleted file mode 100644 index cb610268e16..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/invalid/case2/query2.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age "4". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case1/query1.rq deleted file mode 100644 index 06b0ae877a3..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case1/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 3. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query1.rq deleted file mode 100644 index 06b0ae877a3..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 3. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query2.rq deleted file mode 100644 index 4148eefc538..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case2/query2.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson2 ex:age 3. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query1.rq deleted file mode 100644 index 06b0ae877a3..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age 3. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query2.rq deleted file mode 100644 index 2993a5c6fa5..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case3/query2.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - -ex:validPerson1 ex:age []. - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query1.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query1.rq deleted file mode 100644 index 06eed13cecf..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query1.rq +++ /dev/null @@ -1,14 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { - - -ex:validPerson1 - ex:age "123". - -} diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query2.rq b/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query2.rq deleted file mode 100644 index 0271cd39620..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/valid/case4/query2.rq +++ /dev/null @@ -1,19 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -delete { - ex:validPerson1 - ex:age "123". -} insert { - - ex:validPerson1 - ex:age 234 ; - a ex:Person . - -} where { - ?a ?b ?c. -} \ No newline at end of file diff --git a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/shacl.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl similarity index 79% rename from core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/shacl.ttl rename to core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl index 80a3a525bab..5ac82aa9735 100644 --- a/core/sail/shacl/src/test/resources/test-cases/datatype/validateTarget/shacl.ttl +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl @@ -6,8 +6,6 @@ @prefix sh: . @prefix xsd: . -ex:PersonShape - a sh:NodeShape ; - sh:targetNode 3, "4" ; - sh:datatype xsd:integer . +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/query1.rq b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/query1.rq index 662f457f858..2e9b87a2866 100644 --- a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/query1.rq +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case1/query1.rq @@ -5,9 +5,15 @@ PREFIX rdfs: PREFIX sh: PREFIX xsd: -INSERT DATA { +DELETE { + ?a ?b ?c. +} +INSERT { ex:validPerson1 a ex:Person ; ex:ssn "123". } +WHERE { + ?a ?b ?c. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query1.rq b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query1.rq index 7354a2d0833..391d5736f5a 100644 --- a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query1.rq +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query1.rq @@ -5,10 +5,12 @@ PREFIX rdfs: PREFIX sh: PREFIX xsd: -INSERT DATA { -ex:validPerson1 a ex:Person ; - ex:ssn "123", "456". -ex:validPerson2 ex:ssn "123". - -} \ No newline at end of file +DELETE { + ?a ?b ?c. +} +INSERT { +} +WHERE { + ?a ?b ?c. +} diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query2.rq b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query2.rq deleted file mode 100644 index 6194108fba0..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case2/query2.rq +++ /dev/null @@ -1,10 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { -ex:validPerson2 a ex:Person. -} diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query1.rq b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query1.rq deleted file mode 100644 index 4f6ec8cb08a..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query1.rq +++ /dev/null @@ -1,12 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -INSERT DATA { -ex:validPerson1 a ex:Person ; - ex:ssn "123", "456". - -} \ No newline at end of file diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query2.rq b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query2.rq deleted file mode 100644 index b66cba3559b..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/invalid/case3/query2.rq +++ /dev/null @@ -1,11 +0,0 @@ -PREFIX ex: -PREFIX owl: -PREFIX rdf: -PREFIX rdfs: -PREFIX sh: -PREFIX xsd: - -DELETE DATA { -ex:validPerson1 ex:ssn "123". - -} \ No newline at end of file diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case1/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case2/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case3/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case4/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.ttl new file mode 100644 index 00000000000..5ac82aa9735 --- /dev/null +++ b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/valid/case5/initialData.ttl @@ -0,0 +1,11 @@ +@base . +@prefix ex: . +@prefix owl: . +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . + + +ex:validPerson1 ex:ssn 1 , 2. +ex:validPerson2 ex:ssn 1 , 2. From 2663ff3ed5c15b61f5ccbdf49d8ec8d528d6ec2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 18 Mar 2020 20:50:12 +0100 Subject: [PATCH 2/5] GH-1574 fixed some failing tests and added some edge case tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håvard Ottestad --- .../shacl/planNodes/ValuesBackedNode.java | 5 +- .../rdf4j/sail/shacl/AbstractShaclTest.java | 12 +- .../TargetNodeMinCountEdgeCaseTests.java | 171 ++++++++++++++++++ .../minCount/targetNode/initialData.ttl | 11 -- 4 files changed, 178 insertions(+), 21 deletions(-) create mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TargetNodeMinCountEdgeCaseTests.java delete mode 100644 core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java index 4e3c8b3c623..28fc6ea9ff0 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java @@ -89,10 +89,7 @@ public IteratorData getIteratorDataType() { @Override public String toString() { return "ValuesBackedNode{" + - "collection=" + collection + - ", validationExecutionLogger=" + validationExecutionLogger + - ", printed=" + printed + - '}'; + "collection=" + collection + '}'; } @Override diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java index 7723dc17cb3..5a8ee73d78e 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java @@ -389,7 +389,7 @@ static void runTestCaseSingleTransaction(String shaclPath, String dataPath, Expe SailRepository shaclRepository = getShaclSail(); try { Utils.loadShapeData(shaclRepository, shaclPath + "shacl.ttl"); - Utils.loadInitialData(shaclRepository, shaclPath + "initialData.ttl"); + Utils.loadInitialData(shaclRepository, dataPath + "initialData.ttl"); } catch (IOException e) { throw new RuntimeException(e); } @@ -460,7 +460,7 @@ static void runTestCaseRevalidate(String shaclPath, String dataPath, ExpectedRes SailRepository shaclRepository = getShaclSail(); try { Utils.loadShapeData(shaclRepository, shaclPath + "shacl.ttl"); - Utils.loadInitialData(shaclRepository, shaclPath + "initialData.ttl"); + Utils.loadInitialData(shaclRepository, dataPath + "initialData.ttl"); } catch (IOException e) { throw new RuntimeException(e); } @@ -551,17 +551,17 @@ enum ExpectedResult { private static SailRepository getShaclSail() { ShaclSail shaclSail = new ShaclSail(new MemoryStore()); - SailRepository shaclRepository = new SailRepository(shaclSail); + SailRepository repository = new SailRepository(shaclSail); shaclSail.setLogValidationPlans(fullLogging); shaclSail.setCacheSelectNodes(true); shaclSail.setParallelValidation(true); shaclSail.setLogValidationViolations(fullLogging); shaclSail.setGlobalLogValidationExecution(fullLogging); + shaclSail.setSerializableValidation(false); + repository.init(); - shaclRepository.init(); - - return shaclRepository; + return repository; } } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TargetNodeMinCountEdgeCaseTests.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TargetNodeMinCountEdgeCaseTests.java new file mode 100644 index 00000000000..32d675ade5e --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/TargetNodeMinCountEdgeCaseTests.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * Copyright (c) 2020 Eclipse RDF4J contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + *******************************************************************************/ +package org.eclipse.rdf4j.sail.shacl; + +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.model.ValueFactory; +import org.eclipse.rdf4j.model.impl.SimpleValueFactory; +import org.eclipse.rdf4j.model.vocabulary.RDF4J; +import org.eclipse.rdf4j.repository.sail.SailRepository; +import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; +import org.eclipse.rdf4j.rio.RDFFormat; +import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.junit.Test; + +import java.io.StringReader; + +/** + * Some shapes may cause a validation error even if the targets don't exist. These tests check some of those scenarios. + */ +public class TargetNodeMinCountEdgeCaseTests { + + String shaclShapes = String.join("\n", "", + "@base .", + "@prefix ex: .", + "@prefix owl: .", + "@prefix rdf: .", + "@prefix rdfs: .", + "@prefix sh: .", + "@prefix xsd: .", + "", + "ex:PersonShape", + " a sh:NodeShape ;", + " sh:targetNode ex:validPerson1, ex:validPerson2 ;", + " sh:property [", + " sh:path ex:ssn ;", + " sh:minCount 2 ;", + " ] .", + ""); + + String EX = "http://example.com/ns#"; + ValueFactory vf = SimpleValueFactory.getInstance(); + IRI validPerson1 = vf.createIRI(EX, "validPerson1"); + IRI validPerson2 = vf.createIRI(EX, "validPerson2"); + IRI ssn = vf.createIRI(EX, "ssn"); + Value value1 = vf.createLiteral(1); + Value value2 = vf.createLiteral(2); + + @Test(expected = ShaclSailValidationException.class) + public void testMinCountWithEmptyState() throws Throwable { + + SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore())); + + try (SailRepositoryConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.add(new StringReader(shaclShapes), "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH); + connection.commit(); + } catch (Exception e) { + throw e.getCause(); + } + + } + + @Test(expected = ShaclSailValidationException.class) + public void testMinCountWithInvalidInitialDataset() throws Throwable { + + SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore())); + + try (SailRepositoryConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.add(validPerson1, ssn, value1); + connection.add(validPerson2, ssn, value2); + connection.commit(); + + connection.begin(); + connection.add(new StringReader(shaclShapes), "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH); + connection.commit(); + } catch (Exception e) { + throw e.getCause(); + } + + } + + @Test(expected = ShaclSailValidationException.class) + public void testMinCountWithInvalidInitialDataset2() throws Throwable { + + SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore())); + + try (SailRepositoryConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.add(validPerson1, ssn, value1); + connection.add(validPerson1, ssn, value2); + connection.commit(); + + connection.begin(); + connection.add(new StringReader(shaclShapes), "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH); + connection.commit(); + } catch (Exception e) { + throw e.getCause(); + } + + } + + @Test(expected = ShaclSailValidationException.class) + public void testMinCountWithInvalidInitialDataset3() throws Throwable { + + SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore())); + + try (SailRepositoryConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.add(validPerson1, ssn, value1); + connection.add(validPerson1, ssn, value2); + connection.add(new StringReader(shaclShapes), "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH); + connection.commit(); + } catch (Exception e) { + throw e.getCause(); + } + + } + + @Test + public void testMinCountWithValidInitialDataset() throws Throwable { + + SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore())); + + try (SailRepositoryConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.add(validPerson1, ssn, value1); + connection.add(validPerson1, ssn, value2); + connection.add(validPerson2, ssn, value1); + connection.add(validPerson2, ssn, value2); + connection.commit(); + + connection.begin(); + connection.add(new StringReader(shaclShapes), "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH); + connection.commit(); + } catch (Exception e) { + throw e.getCause(); + } + + } + + @Test + public void testMinCountWithValidInitialDataset2() throws Throwable { + + SailRepository sailRepository = new SailRepository(new ShaclSail(new MemoryStore())); + + try (SailRepositoryConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.add(validPerson1, ssn, value1); + connection.add(validPerson1, ssn, value2); + + connection.commit(); + + connection.begin(); + connection.add(new StringReader(shaclShapes), "", RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH); + connection.add(validPerson2, ssn, value1); + connection.add(validPerson2, ssn, value2); + connection.commit(); + } catch (Exception e) { + throw e.getCause(); + } + + } + +} diff --git a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl b/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl deleted file mode 100644 index 5ac82aa9735..00000000000 --- a/core/sail/shacl/src/test/resources/test-cases/minCount/targetNode/initialData.ttl +++ /dev/null @@ -1,11 +0,0 @@ -@base . -@prefix ex: . -@prefix owl: . -@prefix rdf: . -@prefix rdfs: . -@prefix sh: . -@prefix xsd: . - - -ex:validPerson1 ex:ssn 1 , 2. -ex:validPerson2 ex:ssn 1 , 2. From 1d1b7d98cfd413abb8cd84d48c0fc36319ecc7b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 18 Mar 2020 21:17:16 +0100 Subject: [PATCH 3/5] log the property shape and the identifier of the shape when GlobalValidationExecutionLogging is enabled as well as a fix where the wrong identity hash is used when printing plans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håvard Ottestad --- .../org/eclipse/rdf4j/sail/shacl/AST/AndPropertyShape.java | 1 + .../org/eclipse/rdf4j/sail/shacl/AST/ClassPropertyShape.java | 2 ++ .../eclipse/rdf4j/sail/shacl/AST/DatatypePropertyShape.java | 2 ++ .../org/eclipse/rdf4j/sail/shacl/AST/InPropertyShape.java | 2 ++ .../eclipse/rdf4j/sail/shacl/AST/LanguageInPropertyShape.java | 2 ++ .../eclipse/rdf4j/sail/shacl/AST/MaxCountPropertyShape.java | 2 ++ .../rdf4j/sail/shacl/AST/MaxExclusivePropertyShape.java | 1 + .../rdf4j/sail/shacl/AST/MaxInclusivePropertyShape.java | 1 + .../eclipse/rdf4j/sail/shacl/AST/MaxLengthPropertyShape.java | 1 + .../eclipse/rdf4j/sail/shacl/AST/MinCountPropertyShape.java | 1 + .../rdf4j/sail/shacl/AST/MinExclusivePropertyShape.java | 1 + .../rdf4j/sail/shacl/AST/MinInclusivePropertyShape.java | 1 + .../eclipse/rdf4j/sail/shacl/AST/MinLengthPropertyShape.java | 1 + .../eclipse/rdf4j/sail/shacl/AST/NodeKindPropertyShape.java | 1 + .../main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeShape.java | 2 +- .../org/eclipse/rdf4j/sail/shacl/AST/NotPropertyShape.java | 1 + .../org/eclipse/rdf4j/sail/shacl/AST/OrPropertyShape.java | 1 + .../eclipse/rdf4j/sail/shacl/AST/PatternPropertyShape.java | 1 + .../java/org/eclipse/rdf4j/sail/shacl/AST/PropertyShape.java | 4 ++-- .../java/org/eclipse/rdf4j/sail/shacl/AST/TargetClass.java | 1 + .../java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java | 1 + .../org/eclipse/rdf4j/sail/shacl/AST/TargetObjectsOf.java | 1 + .../org/eclipse/rdf4j/sail/shacl/AST/TargetSubjectsOf.java | 1 + .../eclipse/rdf4j/sail/shacl/AST/UniqueLangPropertyShape.java | 1 + .../org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java | 4 ++-- .../java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java | 2 +- 26 files changed, 33 insertions(+), 6 deletions(-) diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/AndPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/AndPropertyShape.java index d54e99e9ce0..2f7ea14e234 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/AndPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/AndPropertyShape.java @@ -161,6 +161,7 @@ public int hashCode() { public String toString() { return "AndPropertyShape{" + "and=" + toString(and) + + ", id=" + id + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ClassPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ClassPropertyShape.java index fced093a4b0..1743ecbeece 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ClassPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ClassPropertyShape.java @@ -404,6 +404,8 @@ public String toString() { return "ClassPropertyShape{" + "classResource=" + classResource + ", path=" + getPath() + + ", id=" + id + + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/DatatypePropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/DatatypePropertyShape.java index 4ffed0a4887..c21e1a1e9a6 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/DatatypePropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/DatatypePropertyShape.java @@ -88,6 +88,8 @@ public String toString() { return "DatatypePropertyShape{" + "datatype=" + datatype + ", path=" + getPath() + + ", id=" + id + + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/InPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/InPropertyShape.java index 09262ca47c8..122a4350001 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/InPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/InPropertyShape.java @@ -92,6 +92,8 @@ public String toString() { return "InPropertyShape{" + "in=" + Arrays.toString(in.toArray()) + ", path=" + getPath() + + ", id=" + id + + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/LanguageInPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/LanguageInPropertyShape.java index af96d74f2cc..17181ec7a23 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/LanguageInPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/LanguageInPropertyShape.java @@ -92,6 +92,8 @@ public String toString() { return "LanguageInPropertyShape{" + "languageIn=" + Arrays.toString(languageIn.toArray()) + ", path=" + getPath() + + ", id=" + id + + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxCountPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxCountPropertyShape.java index dca8643ac2f..8d59625f781 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxCountPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxCountPropertyShape.java @@ -179,6 +179,8 @@ public String toString() { return "MaxCountPropertyShape{" + "maxCount=" + maxCount + ", path=" + getPath() + + ", id=" + id + + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxExclusivePropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxExclusivePropertyShape.java index 4f4a375e72b..c2593111e45 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxExclusivePropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxExclusivePropertyShape.java @@ -89,6 +89,7 @@ public String toString() { return "MaxExclusivePropertyShape{" + "maxExclusive=" + maxExclusive + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxInclusivePropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxInclusivePropertyShape.java index a157fd19cf8..9505f7430f8 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxInclusivePropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxInclusivePropertyShape.java @@ -89,6 +89,7 @@ public String toString() { return "MaxInclusivePropertyShape{" + "maxInclusive=" + maxInclusive + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxLengthPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxLengthPropertyShape.java index 50e21056396..2fa9a85b9a6 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxLengthPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MaxLengthPropertyShape.java @@ -89,6 +89,7 @@ public String toString() { return "MaxLengthPropertyShape{" + "maxLength=" + maxLength + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinCountPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinCountPropertyShape.java index 2384921767d..03f24dec587 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinCountPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinCountPropertyShape.java @@ -198,6 +198,7 @@ public String toString() { return "MinCountPropertyShape{" + "minCount=" + minCount + ", path=" + getPath() + + ", id=" + id + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinExclusivePropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinExclusivePropertyShape.java index 404da912a54..a0634d00c67 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinExclusivePropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinExclusivePropertyShape.java @@ -89,6 +89,7 @@ public String toString() { return "MinExclusivePropertyShape{" + "minExclusive=" + minExclusive + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinInclusivePropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinInclusivePropertyShape.java index 1dc6a12989b..235990649b5 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinInclusivePropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinInclusivePropertyShape.java @@ -88,6 +88,7 @@ public String toString() { return "MinInclusivePropertyShape{" + "minInclusive=" + minInclusive + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinLengthPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinLengthPropertyShape.java index 83f1935ed1d..51a1c38a9d1 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinLengthPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/MinLengthPropertyShape.java @@ -88,6 +88,7 @@ public String toString() { return "MinLengthPropertyShape{" + "minLength=" + minLength + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeKindPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeKindPropertyShape.java index b17052cdee7..4b6559d2b48 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeKindPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeKindPropertyShape.java @@ -116,6 +116,7 @@ public String toString() { return "NodeKindPropertyShape{" + "nodeKind=" + nodeKind + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeShape.java index b92af4aedda..601ade0c060 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NodeShape.java @@ -41,7 +41,7 @@ */ public class NodeShape implements PlanGenerator, RequiresEvalutation, QueryGenerator { - private Resource id; + final Resource id; private List propertyShapes = Collections.emptyList(); private List nodeShapes = Collections.emptyList(); diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NotPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NotPropertyShape.java index 95347b66cf2..73f6b0eb1f1 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NotPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/NotPropertyShape.java @@ -153,6 +153,7 @@ public int hashCode() { public String toString() { return "NotPropertyShape{" + "orPropertyShape=" + orPropertyShape + + ", id=" + id + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/OrPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/OrPropertyShape.java index cbdb208af68..f2b00bcf5aa 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/OrPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/OrPropertyShape.java @@ -254,6 +254,7 @@ public int hashCode() { public String toString() { return "OrPropertyShape{" + "or=" + toString(or) + + ", id=" + id + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PatternPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PatternPropertyShape.java index a0591d02ace..77db1f550eb 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PatternPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PatternPropertyShape.java @@ -92,6 +92,7 @@ public String toString() { "pattern='" + pattern + '\'' + ", flags='" + flags + '\'' + ", path=" + getPath() + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PropertyShape.java index f3474f42bd4..32867e7ff06 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/PropertyShape.java @@ -46,7 +46,7 @@ public abstract class PropertyShape implements PlanGenerator, RequiresEvalutation { final boolean deactivated; - private Resource id; + final Resource id; NodeShape nodeShape; PathPropertyShape parent; @@ -98,7 +98,7 @@ public String getPlanAsGraphvizDot(PlanNode planNode, ConnectionsGroup connectio stringBuilder.append("labelloc=t;\nfontsize=30;\nlabel=\"" + this.getClass().getSimpleName() + "\";") .append("\n"); - stringBuilder.append(System.identityHashCode(connectionsGroup) + stringBuilder.append(System.identityHashCode(connectionsGroup.getBaseConnection()) + " [label=\"Base sail\" nodeShape=pentagon fillcolor=lightblue style=filled];").append("\n"); stringBuilder .append(System.identityHashCode(connectionsGroup.getPreviousStateConnection()) diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetClass.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetClass.java index 73a0dba870c..d792bf10542 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetClass.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetClass.java @@ -152,6 +152,7 @@ public int hashCode() { public String toString() { return "TargetClass{" + "targetClass=" + Arrays.asList(targetClass.toArray()) + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java index ad15f604b85..8d3375f26d6 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetNode.java @@ -138,6 +138,7 @@ public int hashCode() { public String toString() { return "TargetNode{" + "targetNodeSet=" + Arrays.toString(targetNodeSet.toArray()) + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetObjectsOf.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetObjectsOf.java index 018d591e104..afb80946706 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetObjectsOf.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetObjectsOf.java @@ -142,6 +142,7 @@ public int hashCode() { public String toString() { return "TargetObjectsOf{" + "targetObjectsOf=" + Arrays.toString(targetObjectsOf.toArray()) + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetSubjectsOf.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetSubjectsOf.java index 4b290436ae2..6c735579afe 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetSubjectsOf.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/TargetSubjectsOf.java @@ -139,6 +139,7 @@ public int hashCode() { public String toString() { return "TargetSubjectsOf{" + "targetSubjectsOf=" + Arrays.toString(targetSubjectsOf.toArray()) + + ", id=" + id + '}'; } } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/UniqueLangPropertyShape.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/UniqueLangPropertyShape.java index 0a73a30b141..5c84436fa4c 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/UniqueLangPropertyShape.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/UniqueLangPropertyShape.java @@ -146,6 +146,7 @@ public String toString() { return "UniqueLangPropertyShape{" + "uniqueLang=" + uniqueLang + ", path=" + getPath() + + ", id=" + id + '}'; } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java index e2e24452f4f..c5c08fb4f54 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailConnection.java @@ -364,7 +364,7 @@ private static List performValidation(List nodeShapes, boolean if (GlobalValidationExecutionLogging.loggingEnabled) { PropertyShape propertyShape = ((EnrichWithShape) planNode).getPropertyShape(); logger.info("Start execution of plan " + propertyShape.getNodeShape().toString() + " : " - + propertyShape.getId()); + + propertyShape.toString()); } long before = 0; @@ -386,7 +386,7 @@ private static List performValidation(List nodeShapes, boolean PropertyShape propertyShape = ((EnrichWithShape) planNode).getPropertyShape(); logger.info("Finished execution of plan {} : {}", propertyShape.getNodeShape().toString(), - propertyShape.getId()); + propertyShape.toString()); } boolean valid = collect.isEmpty(); diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java index 5a8ee73d78e..b7ad0000cdc 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java @@ -558,7 +558,7 @@ private static SailRepository getShaclSail() { shaclSail.setParallelValidation(true); shaclSail.setLogValidationViolations(fullLogging); shaclSail.setGlobalLogValidationExecution(fullLogging); - shaclSail.setSerializableValidation(false); + repository.init(); return repository; From 0168b23d1ce54a515336628deb92e9582a561094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Thu, 19 Mar 2020 10:34:06 +0100 Subject: [PATCH 4/5] GH-1574 fixed failing W3C tests and created test to force use of TreeSet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håvard Ottestad --- .../rdf4j/sail/shacl/AST/ShaclProperties.java | 102 ++++++++++ .../rdf4j/sail/shacl/OrderingTest.java | 185 ++++++++++++++++++ .../sail/shacl/PlanNodeOrderingTest.java | 56 ------ .../rdf4j/sail/shacl/SortPlanNodeTest.java | 65 ------ .../org/eclipse/rdf4j/sail/shacl/Utils.java | 2 + .../rdf4j/sail/shacl/W3cComplianceTest.java | 25 ++- 6 files changed, 306 insertions(+), 129 deletions(-) create mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/OrderingTest.java delete mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java delete mode 100644 core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SortPlanNodeTest.java diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java index cb87e7aca6d..461bf61318e 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/AST/ShaclProperties.java @@ -58,6 +58,9 @@ public class ShaclProperties { boolean uniqueLang = false; + public ShaclProperties() { + } + public ShaclProperties(Resource propertyShapeId, SailRepositoryConnection connection) { try (Stream stream = connection.getStatements(propertyShapeId, null, null).stream()) { @@ -194,4 +197,103 @@ public ShaclProperties(Resource propertyShapeId, SailRepositoryConnection connec } + public List getClazz() { + return clazz; + } + + public List getOr() { + return or; + } + + public List getAnd() { + return and; + } + + public List getNot() { + return not; + } + + public Long getMinCount() { + return minCount; + } + + public Long getMaxCount() { + return maxCount; + } + + public Resource getDatatype() { + return datatype; + } + + public Resource getIn() { + return in; + } + + public Long getMinLength() { + return minLength; + } + + public Long getMaxLength() { + return maxLength; + } + + public Resource getLanguageIn() { + return languageIn; + } + + public Resource getNodeKind() { + return nodeKind; + } + + public Resource getPath() { + return path; + } + + public Literal getMinExclusive() { + return minExclusive; + } + + public Literal getMaxExclusive() { + return maxExclusive; + } + + public Literal getMinInclusive() { + return minInclusive; + } + + public Literal getMaxInclusive() { + return maxInclusive; + } + + public List getPattern() { + return pattern; + } + + public String getFlags() { + return flags; + } + + public Set getTargetClass() { + return targetClass; + } + + public TreeSet getTargetNode() { + return targetNode; + } + + public Set getTargetSubjectsOf() { + return targetSubjectsOf; + } + + public Set getTargetObjectsOf() { + return targetObjectsOf; + } + + public boolean isDeactivated() { + return deactivated; + } + + public boolean isUniqueLang() { + return uniqueLang; + } } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/OrderingTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/OrderingTest.java new file mode 100644 index 00000000000..4e6e7d6424e --- /dev/null +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/OrderingTest.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2018 Eclipse RDF4J contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Distribution License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + *******************************************************************************/ + +package org.eclipse.rdf4j.sail.shacl; + +import org.eclipse.rdf4j.IsolationLevels; +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.model.ValueFactory; +import org.eclipse.rdf4j.model.impl.SimpleValueFactory; +import org.eclipse.rdf4j.model.vocabulary.FOAF; +import org.eclipse.rdf4j.model.vocabulary.RDF; +import org.eclipse.rdf4j.model.vocabulary.RDFS; +import org.eclipse.rdf4j.model.vocabulary.SHACL; +import org.eclipse.rdf4j.repository.sail.SailRepository; +import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; +import org.eclipse.rdf4j.sail.SailConnection; +import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.eclipse.rdf4j.sail.shacl.AST.ShaclProperties; +import org.eclipse.rdf4j.sail.shacl.mock.MockConsumePlanNode; +import org.eclipse.rdf4j.sail.shacl.planNodes.InnerJoin; +import org.eclipse.rdf4j.sail.shacl.planNodes.PlanNode; +import org.eclipse.rdf4j.sail.shacl.planNodes.Select; +import org.eclipse.rdf4j.sail.shacl.planNodes.Sort; +import org.eclipse.rdf4j.sail.shacl.planNodes.TrimTuple; +import org.eclipse.rdf4j.sail.shacl.planNodes.Tuple; +import org.eclipse.rdf4j.sail.shacl.planNodes.UnBufferedPlanNode; +import org.eclipse.rdf4j.sail.shacl.planNodes.ValuesBackedNode; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +/** + * @author Håvard Ottestad + */ +public class OrderingTest { + + private final static ValueFactory vf = SimpleValueFactory.getInstance(); + + @Test + public void testSelect() { + MemoryStore repository = new MemoryStore(); + repository.init(); + + try (SailConnection connection = repository.getConnection()) { + connection.begin(IsolationLevels.NONE); + connection.addStatement(RDFS.RESOURCE, RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(RDFS.CLASS, RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(RDFS.SUBCLASSOF, RDF.TYPE, RDFS.RESOURCE); + connection.commit(); + + Select select = new Select(connection, "?a <" + RDF.TYPE + "> []", "*"); + List tuples = new MockConsumePlanNode(select).asList(); + + String actual = Arrays.toString(tuples.toArray()); + + Collections.sort(tuples); + + String expected = Arrays.toString(tuples.toArray()); + + assertEquals(expected, actual); + } + } + + @Test + public void testSortPlanNode() { + + MemoryStore sailRepository = new MemoryStore(); + sailRepository.init(); + + try (SailConnection connection = sailRepository.getConnection()) { + connection.begin(); + connection.addStatement(vf.createBNode("1"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("2"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("4"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("3"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("2"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("2"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("100"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("99"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("101"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("98"), RDF.TYPE, RDFS.RESOURCE); + connection.addStatement(vf.createBNode("102"), RDF.TYPE, RDFS.RESOURCE); + connection.commit(); + } + try (SailConnection connection = sailRepository.getConnection()) { + + Select select = new Select(connection, "?a a rdfs:Resource", "?a"); + List sortedBySelect = new MockConsumePlanNode(select).asList(); + + Sort sort = new Sort(new Select(connection, "?a a rdfs:Resource", "?a")); + List sortedBySort = new MockConsumePlanNode(sort).asList(); + + Assert.assertEquals(sortedBySelect, sortedBySort); + + } + + } + + @Test + public void testTargetNode() { + MemoryStore memoryStore = new MemoryStore(); + + IRI target1 = vf.createIRI("http://example.com/target1"); + IRI target2 = vf.createIRI("http://example.com/target2"); + IRI target3 = vf.createIRI("http://example.com/target3"); + IRI target4 = vf.createIRI("http://example.com/target4"); + IRI target5 = vf.createIRI("http://example.com/target5"); + + try (SailConnection connection = memoryStore.getConnection()) { + connection.begin(IsolationLevels.NONE); + + connection.addStatement(target1, FOAF.KNOWS, target1); + connection.addStatement(target2, FOAF.KNOWS, target2); + connection.addStatement(target3, FOAF.KNOWS, target3); + connection.addStatement(target4, FOAF.KNOWS, target4); + connection.addStatement(target5, FOAF.KNOWS, target5); + + connection.commit(); + + ShaclProperties shaclProperties = new ShaclProperties(); + + Set targetNode = shaclProperties.getTargetNode(); + targetNode.add(target1); + targetNode.add(target5); + targetNode.add(target2); + targetNode.add(target4); + targetNode.add(target3); + + Select select = new Select(connection, "?a ?b ?c", "?a", "?c"); + + ValuesBackedNode valuesBackedNode = new ValuesBackedNode(shaclProperties.getTargetNode()); + + PlanNode innerJoin = new InnerJoin(valuesBackedNode, select).getJoined(UnBufferedPlanNode.class); + + List tuples = new MockConsumePlanNode(innerJoin).asList(); + + verify(tuples, + Arrays.asList(target1.toString(), target1.toString()), + Arrays.asList(target2.toString(), target2.toString()), + Arrays.asList(target3.toString(), target3.toString()), + Arrays.asList(target4.toString(), target4.toString()), + Arrays.asList(target5.toString(), target5.toString())); + + } + } + + public void verify(List actual, List... expect) { + + List collect = Arrays.stream(expect) + .map(strings -> strings.stream() + .map(SimpleValueFactory.getInstance()::createLiteral) + .map(l -> (Value) l) + .collect(Collectors.toList())) + .map(Tuple::new) + .collect(Collectors.toList()); + + actual = actual.stream() + .map(tuple -> tuple.line.stream() + .map(Value::stringValue) + .map(SimpleValueFactory.getInstance()::createLiteral) + .map(l -> (Value) l) + .collect(Collectors.toList())) + .map(Tuple::new) + .collect(Collectors.toList()); + + assertEquals(collect, actual); + + } +} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java deleted file mode 100644 index c86b4f601b1..00000000000 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/PlanNodeOrderingTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 Eclipse RDF4J contributors. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Distribution License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - *******************************************************************************/ - -package org.eclipse.rdf4j.sail.shacl; - -import org.eclipse.rdf4j.IsolationLevels; -import org.eclipse.rdf4j.model.vocabulary.RDF; -import org.eclipse.rdf4j.model.vocabulary.RDFS; -import org.eclipse.rdf4j.sail.SailConnection; -import org.eclipse.rdf4j.sail.memory.MemoryStore; -import org.eclipse.rdf4j.sail.shacl.mock.MockConsumePlanNode; -import org.eclipse.rdf4j.sail.shacl.planNodes.Select; -import org.eclipse.rdf4j.sail.shacl.planNodes.Tuple; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static junit.framework.TestCase.assertEquals; - -/** - * @author Håvard Ottestad - */ -public class PlanNodeOrderingTest { - - @Test - public void testSelect() { - MemoryStore repository = new MemoryStore(); - repository.init(); - - try (SailConnection connection = repository.getConnection()) { - connection.begin(IsolationLevels.NONE); - connection.addStatement(RDFS.RESOURCE, RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(RDFS.CLASS, RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(RDFS.SUBCLASSOF, RDF.TYPE, RDFS.RESOURCE); - connection.commit(); - - Select select = new Select(connection, "?a <" + RDF.TYPE + "> []", "*"); - List tuples = new MockConsumePlanNode(select).asList(); - - String actual = Arrays.toString(tuples.toArray()); - - Collections.sort(tuples); - - String expected = Arrays.toString(tuples.toArray()); - - assertEquals(expected, actual); - } - } -} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SortPlanNodeTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SortPlanNodeTest.java deleted file mode 100644 index 80e37882762..00000000000 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/SortPlanNodeTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 Eclipse RDF4J contributors. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Distribution License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - *******************************************************************************/ - -package org.eclipse.rdf4j.sail.shacl; - -import org.eclipse.rdf4j.model.ValueFactory; -import org.eclipse.rdf4j.model.impl.SimpleValueFactory; -import org.eclipse.rdf4j.model.vocabulary.RDF; -import org.eclipse.rdf4j.model.vocabulary.RDFS; -import org.eclipse.rdf4j.sail.SailConnection; -import org.eclipse.rdf4j.sail.memory.MemoryStore; -import org.eclipse.rdf4j.sail.shacl.mock.MockConsumePlanNode; -import org.eclipse.rdf4j.sail.shacl.planNodes.Select; -import org.eclipse.rdf4j.sail.shacl.planNodes.Sort; -import org.eclipse.rdf4j.sail.shacl.planNodes.Tuple; -import org.junit.Test; - -import java.util.List; - -import static org.junit.Assert.assertEquals; - -public class SortPlanNodeTest { - - @Test - public void test() { - - MemoryStore sailRepository = new MemoryStore(); - sailRepository.init(); - - try (SailConnection connection = sailRepository.getConnection()) { - ValueFactory vf = SimpleValueFactory.getInstance(); - connection.begin(); - connection.addStatement(vf.createBNode("1"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("2"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("4"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("3"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("2"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("2"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("100"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("99"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("101"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("98"), RDF.TYPE, RDFS.RESOURCE); - connection.addStatement(vf.createBNode("102"), RDF.TYPE, RDFS.RESOURCE); - connection.commit(); - } - try (SailConnection connection = sailRepository.getConnection()) { - - Select select = new Select(connection, "?a a rdfs:Resource", "?a"); - List sortedBySelect = new MockConsumePlanNode(select).asList(); - - Sort sort = new Sort(new Select(connection, "?a a rdfs:Resource", "?a")); - List sortedBySort = new MockConsumePlanNode(sort).asList(); - - assertEquals(sortedBySelect, sortedBySort); - - } - - } - -} diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java index 7e403570697..08b70acf754 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/Utils.java @@ -73,6 +73,7 @@ public static void loadShapeData(SailRepository repo, String resourceName) throw public static void loadShapeData(SailRepository repo, URL resourceName) throws RDF4JException, UnsupportedRDFormatException, IOException { + ((ShaclSail) repo.getSail()).disableValidation(); try (RepositoryConnection conn = repo.getConnection()) { conn.begin(); @@ -80,6 +81,7 @@ public static void loadShapeData(SailRepository repo, URL resourceName) conn.commit(); } + ((ShaclSail) repo.getSail()).enableValidation(); } diff --git a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java index 0c9899f279c..fc66b3b5c7d 100644 --- a/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java +++ b/core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/W3cComplianceTest.java @@ -9,6 +9,7 @@ import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; import org.eclipse.rdf4j.rio.RDFFormat; import org.eclipse.rdf4j.sail.memory.MemoryStore; +import org.eclipse.rdf4j.sail.shacl.results.ValidationReport; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; @@ -50,10 +51,8 @@ public static Collection data() { @Ignore @Test - public void test() { - + public void test() throws IOException { runTest(testCasePath); - } private static Set getTestFiles() { @@ -120,23 +119,33 @@ public Manifest(URL filename) { } - private void runTest(URL resourceName) { + private void runTest(URL resourceName) throws IOException { W3C_shaclTestValidate expected = new W3C_shaclTestValidate(resourceName); - SailRepository sailRepository = Utils.getInitializedShaclRepository(resourceName); + ShaclSail shaclSail = new ShaclSail(new MemoryStore()); + SailRepository sailRepository = new SailRepository(shaclSail); + + Utils.loadShapeData(sailRepository, resourceName); - boolean failedShacl = false; + boolean actualConforms = false; try (SailRepositoryConnection connection = sailRepository.getConnection()) { + shaclSail.disableValidation(); connection.begin(); connection.add(resourceName, "http://example.org/", RDFFormat.TURTLE); connection.commit(); + shaclSail.enableValidation(); + + connection.begin(); + ValidationReport revalidate = ((ShaclSailConnection) connection.getSailConnection()).revalidate(); + actualConforms = revalidate.conforms(); + connection.commit(); } catch (IOException e) { e.printStackTrace(); } catch (RepositoryException e) { - failedShacl = e.toString().contains("Failed SHACL validation"); + actualConforms = !e.toString().contains("Failed SHACL validation"); } - assertEquals(expected.conforms, !failedShacl); + assertEquals(expected.conforms, actualConforms); } class W3C_shaclTestValidate { From 56b302c5dd91843bb2f4bd72d832c2998f4f6bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Fri, 20 Mar 2020 11:25:58 +0100 Subject: [PATCH 5/5] GH-1574 added comments to help next developer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Håvard Ottestad --- .../org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java | 1 + .../main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java | 1 + .../eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java index 1c1f0b14396..d4ca277a21b 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/GroupByCount.java @@ -75,6 +75,7 @@ private void calculateNext() { } + // Arrays.asList(...) is immutable, wrap in ArrayList to make it mutable List line = new ArrayList<>( Arrays.asList(subject, SimpleValueFactory.getInstance().createLiteral(count))); diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java index 2660c5c308b..84cfe01cb2c 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/Tuple.java @@ -39,6 +39,7 @@ public Tuple(List list) { } public Tuple(Value... list) { + // Arrays.asList(...) is immutable, wrap in ArrayList to make it mutable line = new ArrayList<>(Arrays.asList(list)); } diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java index 28fc6ea9ff0..0a2513e1b4c 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/planNodes/ValuesBackedNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Eclipse RDF4J contributors. + * Copyright (c) 2020 Eclipse RDF4J contributors. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Distribution License v1.0 * which accompanies this distribution, and is available at