Skip to content

Commit 511339d

Browse files
authored
Merge pull request eclipse-rdf4j#4222 from eclipse/main
Merge main into develop
2 parents 683463c + 10f4e7b commit 511339d

File tree

11 files changed

+168
-116
lines changed

11 files changed

+168
-116
lines changed

core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ast/PropertyShape.java

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ public ValidationQuery generateSparqlValidationQuery(ConnectionsGroup connection
136136
return ValidationQuery.Deactivated.getInstance();
137137
}
138138

139+
if (!getPath().isSupported()) {
140+
logger.error("Unsupported SHACL feature detected: {}. Shape ignored!\n{}", path, this);
141+
return ValidationQuery.Deactivated.getInstance();
142+
}
143+
139144
ValidationQuery validationQuery = constraintComponents.stream()
140145
.map(c -> {
141146
ValidationQuery validationQuery1 = c.generateSparqlValidationQuery(connectionsGroup,
@@ -177,38 +182,14 @@ public PlanNode generateTransactionalValidationPlan(ConnectionsGroup connections
177182
return EmptyNode.getInstance();
178183
}
179184

180-
PlanNode union = EmptyNode.getInstance();
185+
if (!getPath().isSupported()) {
186+
logger.error("Unsupported SHACL feature detected: {}. Shape ignored!\n{}", path, this);
187+
return EmptyNode.getInstance();
188+
}
181189

182-
// if (negatePlan) {
183-
// assert overrideTargetNode == null : "Negated property shape with override target is not supported at the moment!";
184-
//
185-
// PlanNode ret = EmptyNode.getInstance();
186-
//
187-
// for (ConstraintComponent constraintComponent : constraintComponents) {
188-
// PlanNode planNode = constraintComponent.generateTransactionalValidationPlan(connectionsGroup,
189-
// logValidationPlans, () -> getAllLocalTargetsPlan(connectionsGroup, negatePlan), negateChildren,
190-
// false, Scope.propertyShape);
191-
//
192-
// PlanNode allTargetsPlan = getAllLocalTargetsPlan(connectionsGroup, negatePlan);
193-
//
194-
// Unique invalid = Unique.getInstance(planNode);
195-
//
196-
// PlanNode discardedLeft = new InnerJoin(allTargetsPlan, invalid)
197-
// .getDiscardedLeft(BufferedPlanNode.class);
198-
//
199-
// ret = UnionNode.getInstance(ret, discardedLeft);
200-
//
201-
// }
202-
//
203-
// return ret;
204-
//
205-
// }
190+
PlanNode union = EmptyNode.getInstance();
206191

207192
for (ConstraintComponent constraintComponent : constraintComponents) {
208-
if (!getPath().isSupported()) {
209-
logger.error("Unsupported path detected. Shape ignored!\n" + this);
210-
continue;
211-
}
212193

213194
PlanNode validationPlanNode = constraintComponent
214195
.generateTransactionalValidationPlan(connectionsGroup, validationSettings, overrideTargetNode,
@@ -276,6 +257,17 @@ public Path getPath() {
276257
return path;
277258
}
278259

260+
@Override
261+
public boolean requiresEvaluation(ConnectionsGroup connectionsGroup, Scope scope, Resource[] dataGraph,
262+
StatementMatcher.StableRandomVariableProvider stableRandomVariableProvider) {
263+
if (!getPath().isSupported()) {
264+
logger.error("Unsupported SHACL feature detected: {}. Shape ignored!\n{}", path, this);
265+
return false;
266+
}
267+
268+
return super.requiresEvaluation(connectionsGroup, scope, dataGraph, stableRandomVariableProvider);
269+
}
270+
279271
@Override
280272
public ConstraintComponent deepClone() {
281273
PropertyShape nodeShape = new PropertyShape(this);

core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/AbstractShaclTest.java

Lines changed: 29 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,7 @@ public String toString() {
333333
private static Stream<TestCase> findTestCases(String testCase, ExpectedResult baseCase) {
334334
String shacl;
335335

336-
try (InputStream resourceAsStream = AbstractShaclTest.class.getClassLoader()
337-
.getResourceAsStream(testCase + "/shacl.trig")) {
336+
try (InputStream resourceAsStream = getResourceAsStream(testCase + "/shacl.trig")) {
338337
assert Objects.nonNull(resourceAsStream) : "Could not find: " + testCase + "/shacl.trig";
339338
shacl = IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8);
340339

@@ -347,7 +346,7 @@ private static Stream<TestCase> findTestCases(String testCase, ExpectedResult ba
347346
return Stream.empty();
348347
}
349348

350-
return Arrays.stream(new File(resource.getFile()).list())
349+
return Arrays.stream(Objects.requireNonNull(new File(resource.getFile()).list()))
351350
.filter(s -> !s.startsWith("."))
352351
.sorted()
353352
.map(caseName -> {
@@ -443,8 +442,6 @@ void runTestCase(TestCase testCase, IsolationLevel isolationLevel, boolean prelo
443442

444443
}
445444

446-
Model validationReportActual = new LinkedHashModel();
447-
448445
for (File queryFile : testCase.getQueries()) {
449446
try {
450447
String query = FileUtils.readFileToString(queryFile, StandardCharsets.UTF_8);
@@ -466,8 +463,6 @@ void runTestCase(TestCase testCase, IsolationLevel isolationLevel, boolean prelo
466463

467464
exception = true;
468465
logger.debug(sailException.getMessage());
469-
validationReportActual = ((ShaclSailValidationException) sailException.getCause())
470-
.validationReportAsModel();
471466
printResults(sailException);
472467
}
473468
} catch (IOException e) {
@@ -506,17 +501,18 @@ private void printTestCase(TestCase testCase) {
506501

507502
private static void testValidationReport(String dataPath, Model validationReportActual) {
508503
try {
509-
InputStream resourceAsStream = AbstractShaclTest.class.getClassLoader()
510-
.getResourceAsStream(dataPath + "report.ttl");
504+
InputStream resourceAsStream = getResourceAsStream(dataPath + "report.ttl");
511505
if (resourceAsStream == null) {
512-
logger.error(dataPath + "report.ttl did not exist. Creating an empty file!");
506+
logger.warn(dataPath + "report.ttl did not exist, attempting to create an empty file!");
513507

514508
String file = Objects.requireNonNull(AbstractShaclTest.class.getClassLoader()
515509
.getResource(dataPath))
516510
.getFile()
517511
.replace("/target/test-classes/", "/src/test/resources/");
518512
boolean newFile = new File(file + "report.ttl").createNewFile();
519-
513+
if (!newFile) {
514+
logger.error(dataPath + "report.ttl did not exist and could not create an empty file!");
515+
}
520516
}
521517
Model validationReportExpected = getModel(resourceAsStream);
522518

@@ -533,6 +529,10 @@ private static void testValidationReport(String dataPath, Model validationReport
533529
}
534530
}
535531

532+
private static InputStream getResourceAsStream(String dataPath) {
533+
return AbstractShaclTest.class.getClassLoader().getResourceAsStream(dataPath);
534+
}
535+
536536
private static void writeActualModelToExpectedModelForDevPurposes(String dataPath, Model report)
537537
throws IOException {
538538
String file = Objects.requireNonNull(AbstractShaclTest.class.getClassLoader()
@@ -631,8 +631,7 @@ void referenceImplementationTestCaseValidation(TestCase testCase) {
631631
org.apache.jena.rdf.model.Model data = JenaUtil.createMemoryModel();
632632

633633
if (testCase.hasInitialData()) {
634-
try (InputStream resourceAsStream = AbstractShaclTest.class.getClassLoader()
635-
.getResourceAsStream(testCase.getInitialData())) {
634+
try (InputStream resourceAsStream = getResourceAsStream(testCase.getInitialData())) {
636635
data.read(resourceAsStream, "", org.apache.jena.util.FileUtils.langTurtle);
637636
} catch (IOException e) {
638637
throw new IllegalStateException(e);
@@ -668,8 +667,7 @@ void referenceImplementationTestCaseValidation(TestCase testCase) {
668667
RDFFormat.TRIG);
669668

670669
try {
671-
InputStream resourceAsStream = AbstractShaclTest.class.getClassLoader()
672-
.getResourceAsStream(testCase.getTestCasePath() + "report.ttl");
670+
InputStream resourceAsStream = getResourceAsStream(testCase.getTestCasePath() + "report.ttl");
673671

674672
Model validationReportActual = getModel(resourceAsStream);
675673

@@ -717,8 +715,7 @@ private static Model getModel(InputStream resourceAsStream) throws IOException {
717715

718716
private static void checkShapesConformToW3cShaclRecommendation(org.apache.jena.rdf.model.Model shacl) {
719717
org.apache.jena.rdf.model.Model w3cShacl = JenaUtil.createMemoryModel();
720-
try (InputStream resourceAsStream = AbstractShaclTest.class.getClassLoader()
721-
.getResourceAsStream("w3cshacl.ttl")) {
718+
try (InputStream resourceAsStream = getResourceAsStream("w3cshacl.ttl")) {
722719
w3cShacl.read(resourceAsStream, "", org.apache.jena.util.FileUtils.langTurtle);
723720
} catch (IOException e) {
724721
throw new IllegalStateException(e);
@@ -870,7 +867,7 @@ private void printFile(String filename) {
870867
try {
871868
System.out.println("### " + filename + " ###");
872869
String s = IOUtils.toString(
873-
Objects.requireNonNull(AbstractShaclTest.class.getClassLoader().getResourceAsStream(filename)),
870+
Objects.requireNonNull(getResourceAsStream(filename)),
874871
StandardCharsets.UTF_8);
875872

876873
s = removeLeadingPrefixStatements(s);
@@ -883,29 +880,30 @@ private void printFile(String filename) {
883880
}
884881

885882
private static String removeLeadingPrefixStatements(String s) {
886-
String[] split = s.split("\n");
887-
s = "";
883+
String[] splitByNewLine = s.split("\n");
884+
888885
boolean skippingPrefixes = true;
889886

890-
for (String s1 : split) {
887+
StringBuilder stringBuilder = new StringBuilder();
888+
for (String line : splitByNewLine) {
891889
if (skippingPrefixes) {
892-
if (!(s1.trim().equals("") ||
893-
s1.trim().toLowerCase().startsWith("@prefix") ||
894-
s1.trim().toLowerCase().startsWith("@base") ||
895-
s1.trim().toLowerCase().startsWith("prefix"))) {
890+
if (!(line.trim().equals("") ||
891+
line.trim().toLowerCase().startsWith("@prefix") ||
892+
line.trim().toLowerCase().startsWith("@base") ||
893+
line.trim().toLowerCase().startsWith("prefix"))) {
896894
skippingPrefixes = false;
897895
}
898896
}
899897

900898
if (!skippingPrefixes) {
901-
s += s1 + "\n";
899+
stringBuilder.append(line).append("\n");
902900
}
903901

904902
}
905-
return s;
903+
return stringBuilder.toString();
906904
}
907905

908-
void runTestCaseSingleTransaction(TestCase testCase, IsolationLevel isolationLevel) {
906+
void runTestCaseSingleTransaction(TestCase testCase) {
909907

910908
SailRepository shaclRepository = getShaclSail(testCase, true);
911909

@@ -915,7 +913,7 @@ void runTestCaseSingleTransaction(TestCase testCase, IsolationLevel isolationLev
915913
Model validationReportActual = new LinkedHashModel();
916914

917915
try (SailRepositoryConnection shaclSailConnection = shaclRepository.getConnection()) {
918-
shaclSailConnection.begin(isolationLevel);
916+
shaclSailConnection.begin(IsolationLevels.NONE);
919917

920918
for (File queryFile : testCase.getQueries()) {
921919
try {
@@ -1028,7 +1026,6 @@ void runParsingTest(TestCase testCase) {
10281026
.getDataAndRelease();
10291027

10301028
Model actual = new DynamicModelFactory().createEmptyModel();
1031-
HashSet<Resource> dedupe = new HashSet<>();
10321029
shapes.forEach(shape -> shape.toModel(actual));
10331030

10341031
Model expected = new LinkedHashModel(testCase.getShacl());
@@ -1093,8 +1090,8 @@ private void printResults(ValidationReport report) {
10931090
}
10941091

10951092
private void printResults(RepositoryException sailException) {
1096-
ValidationReport validationReport = ((ShaclSailValidationException) sailException.getCause())
1097-
.getValidationReport();
1093+
var shaclSailValidationException = (ShaclSailValidationException) sailException.getCause();
1094+
ValidationReport validationReport = shaclSailValidationException.getValidationReport();
10981095
printResults(validationReport);
10991096
}
11001097

@@ -1159,27 +1156,6 @@ void runWithAutomaticLogging(Runnable r) {
11591156
}
11601157
}
11611158

1162-
/**
1163-
* Sort and output testCasePaths
1164-
*
1165-
* @param args
1166-
*/
1167-
public static void main(String[] args) {
1168-
1169-
System.out.println("\n\tprivate static final List<String> testCasePaths = Stream.of(");
1170-
String testCasesString = testCasePaths
1171-
.stream()
1172-
.map(a -> "\t\t\"" + a + "\"")
1173-
.reduce((a, b) -> a + ",\n" + b)
1174-
.orElse("");
1175-
1176-
System.out.println(testCasesString);
1177-
System.out.println("\t)\n" +
1178-
"\t\t.distinct()\n" +
1179-
"\t\t.sorted()\n" +
1180-
"\t\t.collect(Collectors.toList());");
1181-
}
1182-
11831159
enum ExpectedResult {
11841160
valid,
11851161
invalid

core/sail/shacl/src/test/java/org/eclipse/rdf4j/sail/shacl/ShaclTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
package org.eclipse.rdf4j.sail.shacl;
1313

1414
import org.eclipse.rdf4j.common.transaction.IsolationLevel;
15-
import org.eclipse.rdf4j.common.transaction.IsolationLevels;
1615
import org.junit.jupiter.params.ParameterizedTest;
1716
import org.junit.jupiter.params.provider.MethodSource;
1817

@@ -30,7 +29,7 @@ public void test(TestCase testCase, IsolationLevel isolationLevel) {
3029
@ParameterizedTest
3130
@MethodSource("testCases")
3231
public void testSingleTransaction(TestCase testCase) {
33-
runWithAutomaticLogging(() -> runTestCaseSingleTransaction(testCase, IsolationLevels.NONE));
32+
runWithAutomaticLogging(() -> runTestCaseSingleTransaction(testCase));
3433
}
3534

3635
@ParameterizedTest

0 commit comments

Comments
 (0)