Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

53 shaclinfersh hangs when ttl contains some specific owlimports #185

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0444f77
ci(deps): update docker/build-push-action action to v6.10.0
renovate[bot] Nov 26, 2024
f1eb7df
Merge pull request #67 from ashleycaselli/renovate/docker-build-push-…
ashleycaselli Nov 27, 2024
677ed6b
feat(cli): add -noImports parameter to the validation tool
ashleycaselli Dec 10, 2024
fcc58e6
Merge branch 'TopQuadrant:master' into master
ashleycaselli Jan 10, 2025
156ad68
chore(dockerfile): add binutils package
ashleycaselli Jan 10, 2025
aaf849f
build(deps): update dependency org.apache.maven.plugins:maven-javadoc…
renovate[bot] Jan 10, 2025
d62ab65
chore(core-deps): update dependency org.apache.logging.log4j:log4j-sl…
renovate[bot] Jan 10, 2025
dd95591
chore(core-deps): update dependency org.slf4j:slf4j-api to v2
renovate[bot] Jan 10, 2025
20c9132
Merge pull request #37 from ashleycaselli/renovate/log4j2-monorepo
ashleycaselli Jan 10, 2025
560fe49
Merge pull request #69 from ashleycaselli/renovate/org.apache.maven.p…
ashleycaselli Jan 10, 2025
66d4250
ci(deps): update docker/setup-buildx-action action to v3.8.0
renovate[bot] Jan 10, 2025
b98299a
Merge pull request #70 from ashleycaselli/renovate/docker-setup-build…
ashleycaselli Jan 10, 2025
5720ed5
ci(deps): update docker/build-push-action action to v6.11.0
renovate[bot] Jan 10, 2025
0695769
Merge pull request #74 from ashleycaselli/renovate/docker-build-push-…
ashleycaselli Jan 10, 2025
4cf0cc7
ci(deps): update actions/upload-artifact action to v4.6.0
renovate[bot] Jan 10, 2025
cf7ef9d
ci(deps): update docker/setup-qemu-action action to v3.3.0
renovate[bot] Jan 10, 2025
ba8da45
Merge pull request #71 from ashleycaselli/renovate/actions-upload-art…
ashleycaselli Jan 10, 2025
8e33cf1
Merge pull request #75 from ashleycaselli/renovate/docker-setup-qemu-…
ashleycaselli Jan 10, 2025
9402e41
ci(deps): update actions/setup-java action to v4.6.0
renovate[bot] Jan 10, 2025
33935b4
Merge pull request #72 from ashleycaselli/renovate/actions-setup-java…
ashleycaselli Jan 10, 2025
e685d68
chore(core-deps): update dependency org.slf4j:slf4j-api to v2
renovate[bot] Jan 10, 2025
a95f11b
chore(core-deps): replace log4j-slf4j-impl (v2.20.0) with log4j-slf4j…
ashleycaselli Jan 10, 2025
6b7ed74
Merge branch 'renovate/major-2-slf4j-monorepo' of github.com:ashleyca…
ashleycaselli Jan 10, 2025
87bfa3c
Merge pull request #39 from ashleycaselli/renovate/major-2-slf4j-mono…
ashleycaselli Jan 10, 2025
be044dd
chore(deps): update alpine docker tag to v3.21.2
renovate[bot] Jan 10, 2025
420b675
Merge pull request #68 from ashleycaselli/renovate/alpine-3.x
ashleycaselli Jan 10, 2025
00d6a64
Merge branch 'TopQuadrant:master' into master
ashleycaselli Jan 10, 2025
4fbc866
Merge branch 'master' of github.com:ashleycaselli/shacl into 53-shacl…
ashleycaselli Jan 11, 2025
c34e4f5
chore(readme): update with command line tool parameters
ashleycaselli Jan 11, 2025
01deb92
chore(dockerfile): update entrypoint helper with available commands
ashleycaselli Jan 11, 2025
94fdbd0
chore(readme): update command line tools doc
ashleycaselli Jan 11, 2025
c0e31bc
refactor: update code style ValidationExample
ashleycaselli Jan 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ LABEL org.opencontainers.image.version=${VERSION}

# BUILD STAGE 1: install minimal Java environment + curl & zip for SHACL API

RUN apk add --no-cache binutils maven curl zip

# Create a custom Java runtime
RUN $JAVA_HOME/bin/jlink \
--add-modules java.base,java.compiler,java.desktop,java.management,java.naming,java.net.http,java.rmi,java.scripting,java.security.jgss,java.security.sasl,java.sql,java.xml.crypto,jdk.unsupported \
Expand All @@ -23,16 +25,14 @@ RUN $JAVA_HOME/bin/jlink \
--compress=2 \
--output /javaruntime

RUN apk add maven curl zip

# Compile with maven, extract binaries and copy into image
COPY . /app
RUN mvn versions:set -DnewVersion=${VERSION} && mvn package -Dmaven.test.skip=true
RUN unzip target/shacl-${VERSION}-bin.zip -d /app/

# BUILD STAGE 2: keep only Java and SHACL

FROM alpine:3.20.3
FROM alpine:3.21.2

ARG VERSION

Expand Down
8 changes: 8 additions & 0 deletions .docker/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ PARAMETER:
input to be validated (only .ttl format supported)
-shapesfile /data/myshapes.ttl [OPTIONAL]
shapes for validation (only .ttl format supported)
-maxiterations 1 [OPTIONAL] - default is 1
iteratively applies the inference rules until the maximum number of iterations is reached (or no new triples are inferred)
-validateShapes [OPTIONAL]
in case you want to include the metashapes (from the tosh namespace in particular)
-addBlankNodes [OPTIONAL]
adds the blank nodes to the validation report
-noImports [OPTIONAL]
disables the import of external ontologies
EOF
exit 1
fi
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0

- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0

# inspired by https://github.com/reloc8/action-latest-release-version
- name: Get release version
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:

- name: Build and push Docker image for x86 and arm64
id: build
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
with:
file: .docker/Dockerfile
push: true
Expand All @@ -93,7 +93,7 @@ jobs:
digest="${{ steps.build.outputs.digest }}"
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: digests-${{ matrix.package }}
path: /tmp/digests/*
Expand Down Expand Up @@ -131,7 +131,7 @@ jobs:
merge-multiple: true

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0

- name: Extract metadata (tags, labels) for Docker
id: meta
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/maven-test-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up JDK
uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4.5.0
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
with:
distribution: ${{ matrix.distribution }}
java-version: ${{ matrix.java }}
Expand Down
40 changes: 22 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ The binary distribution is:

`https://repo1.maven.org/maven2/org/topbraid/shacl/*VER*/shacl-*VER*-bin.zip`.

Two command line utilities are included: shaclvalidate (performs constraint validation) and shaclinfer (performs SHACL rule inferencing).
Two command line utilities are included: `shaclvalidate` (performs constraint validation) and `shaclinfer` (performs SHACL rule inferencing).

To use them, set up your environment similar to https://jena.apache.org/documentation/tools/ (note that the SHACL download includes Jena).

Expand All @@ -72,17 +72,13 @@ export SHACLROOT=/home/holger/shacl/shacl-1.4.3-bin/shacl-1.4.3/bin
export PATH=$SHACLROOT:$PATH
```

Both tools take the following parameters, for example:
After setting up the environment, you can run the command line utilities (i.e. validation) using the following command:

`shaclvalidate.bat -datafile myfile.ttl -shapesfile myshapes.ttl`
- Windows: `shaclvalidate.bat -datafile myfile.ttl -shapesfile myshapes.ttl`

where `-shapesfile` is optional and falls back to using the data graph as shapes graph.
Add -validateShapes in case you want to include the metashapes (from the tosh namespace in particular).
- Linux/Unix: `shaclvalidate.sh -datafile myfile.ttl -shapesfile myshapes.ttl`

For the shaclinfer tool, you can use the `-maxiterations` argument to apply SHACL rule inferencing multiple times; this will add inferred results back to the data graph to see if further triples can be inferred.
The tool will iterate until either (a) the maximum number of iterations is reached, or (b) no new triples are inferred. The flag is optional and defaults to `1` (single iteration).

Currently only Turtle (.ttl) files are supported.
Both tools (Windows, Linux) take the parameters described in the [Dockerfile Usage](#dockerfile-usage) section. **Currently, only Turtle (.ttl) files are supported.**

The tools print the validation report or the inferences graph to the output screen.

Expand Down Expand Up @@ -113,15 +109,23 @@ Any other command after `ghcr.io/topquadrant/shacl:1.4.3` will print the followi
Please use this docker image as follows:
docker run -v /path/to/data:/data ghcr.io/topquadrant/shacl:1.4.3 [COMMAND] [PARAMETERS]
COMMAND:
validate
to run validation
infer
to run rule inferencing
validate
to run validation
infer
to run rule inferencing
PARAMETERS:
-datafile /data/myfile.ttl [MANDATORY]
input to be validated (only .ttl format supported)
-shapesfile /data/myshapes.ttl [OPTIONAL]
shapes for validation (only .ttl format supported)
-datafile /data/myfile.ttl [MANDATORY]
input to be validated (only .ttl format supported)
-shapesfile /data/myshapes.ttl [OPTIONAL]
shapes for validation (only .ttl format supported)
-maxiterations 1 [OPTIONAL] - default is 1
iteratively applies the inference rules until the maximum number of iterations is reached (or no new triples are inferred)
-validateShapes [OPTIONAL]
in case you want to include the metashapes (from the tosh namespace in particular)
-addBlankNodes [OPTIONAL]
adds the blank nodes to the validation report
-noImports [OPTIONAL]
disables the import of external ontologies
```

If you'd like to build the image locally in an `x86` architecture, use:
Expand All @@ -134,4 +138,4 @@ If your architecture is `arm`, use:

```
docker build -f .docker/Dockerfile -t ghcr.io/topquadrant/shacl:1.4.3 --build-arg VERSION=1.4.3 --build-arg ARCH_BASE=amazoncorretto:11-alpine3.18-jdk .
```
```
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<ver.jena>5.2.0</ver.jena>
<ver.junit>4.13.2</ver.junit>
<ver.slf4j>1.7.36</ver.slf4j>
<ver.log4j2>2.20.0</ver.log4j2>
<ver.slf4j>2.0.16</ver.slf4j>
<ver.log4j2>2.24.3</ver.log4j2>
<java.version>17</java.version>
</properties>

Expand Down Expand Up @@ -99,7 +99,7 @@
<!-- Require a logging implementation -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>${ver.log4j2}</version>
<optional>true</optional>
</dependency>
Expand Down Expand Up @@ -210,7 +210,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.11.1</version>
<version>3.11.2</version>
<executions>
<execution>
<id>attach-javadocs</id>
Expand Down
151 changes: 73 additions & 78 deletions src/main/java/org/topbraid/shacl/tools/AbstractTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
*/
package org.topbraid.shacl.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.jena.ontology.OntDocumentManager;
import org.apache.jena.ontology.OntModel;
import org.apache.jena.ontology.OntModelSpec;
Expand All @@ -34,78 +29,78 @@
import org.topbraid.shacl.vocabulary.SH;
import org.topbraid.shacl.vocabulary.TOSH;

import java.io.*;

class AbstractTool {

private final static String DATA_FILE = "-datafile";

private final static String SHAPES_FILE = "-shapesfile";

private final static String MAX_ITERATIONS = "-maxiterations";


private OntDocumentManager dm = new OntDocumentManager();

private OntModelSpec spec = new OntModelSpec(OntModelSpec.OWL_MEM);


AbstractTool() {

InputStream shaclTTL = SHACLSystemModel.class.getResourceAsStream("/rdf/shacl.ttl");
Model shacl = JenaUtil.createMemoryModel();
shacl.read(shaclTTL, SH.BASE_URI, FileUtils.langTurtle);
shacl.add(SystemTriples.getVocabularyModel());
dm.addModel(SH.BASE_URI, shacl);

InputStream dashTTL = SHACLSystemModel.class.getResourceAsStream("/rdf/dash.ttl");
Model dash = JenaUtil.createMemoryModel();
dash.read(dashTTL, SH.BASE_URI, FileUtils.langTurtle);
dm.addModel(DASH.BASE_URI, dash);

InputStream toshTTL = SHACLSystemModel.class.getResourceAsStream("/rdf/tosh.ttl");
Model tosh = JenaUtil.createMemoryModel();
tosh.read(toshTTL, SH.BASE_URI, FileUtils.langTurtle);
dm.addModel(TOSH.BASE_URI, tosh);

spec.setDocumentManager(dm);
}

protected int getMaxIterations(String[] args) {
for(int i = 0; i < args.length - 1; i++) {
if(MAX_ITERATIONS.equals(args[i])) {
return Integer.parseInt(args[i + 1]);
}
}
return 1;
}

protected Model getDataModel(String[] args) throws IOException {
for(int i = 0; i < args.length - 1; i++) {
if(DATA_FILE.equals(args[i])) {
String dataFileName = args[i + 1];
OntModel dataModel = ModelFactory.createOntologyModel(spec);
File file = new File(dataFileName);
String lang = FileUtils.langTurtle;
dataModel.read(new FileInputStream(file), "urn:x:base", lang);
return dataModel;
}
}
System.err.println("Missing -datafile, e.g.: -datafile myfile.ttl");
System.exit(0);
return null;
}


protected Model getShapesModel(String[] args) throws IOException {
for(int i = 0; i < args.length - 1; i++) {
if(SHAPES_FILE.equals(args[i])) {
String fileName = args[i + 1];
OntModel model = ModelFactory.createOntologyModel(spec);
File file = new File(fileName);
String lang = FileUtils.langTurtle;
model.read(new FileInputStream(file), "urn:x:base", lang);
return model;
}
}
return null;
}
}
private final static String DATA_FILE = "-datafile";

private final static String SHAPES_FILE = "-shapesfile";

private final static String MAX_ITERATIONS = "-maxiterations";

protected final OntDocumentManager dm = new OntDocumentManager();

private OntModelSpec spec = new OntModelSpec(OntModelSpec.OWL_MEM);


AbstractTool() {

InputStream shaclTTL = SHACLSystemModel.class.getResourceAsStream("/rdf/shacl.ttl");
Model shacl = JenaUtil.createMemoryModel();
shacl.read(shaclTTL, SH.BASE_URI, FileUtils.langTurtle);
shacl.add(SystemTriples.getVocabularyModel());
dm.addModel(SH.BASE_URI, shacl);

InputStream dashTTL = SHACLSystemModel.class.getResourceAsStream("/rdf/dash.ttl");
Model dash = JenaUtil.createMemoryModel();
dash.read(dashTTL, SH.BASE_URI, FileUtils.langTurtle);
dm.addModel(DASH.BASE_URI, dash);

InputStream toshTTL = SHACLSystemModel.class.getResourceAsStream("/rdf/tosh.ttl");
Model tosh = JenaUtil.createMemoryModel();
tosh.read(toshTTL, SH.BASE_URI, FileUtils.langTurtle);
dm.addModel(TOSH.BASE_URI, tosh);

spec.setDocumentManager(dm);
}

protected int getMaxIterations(String[] args) {
for (int i = 0; i < args.length - 1; i++) {
if (MAX_ITERATIONS.equals(args[i])) {
return Integer.parseInt(args[i + 1]);
}
}
return 1;
}

protected Model getDataModel(String[] args) throws IOException {
for (int i = 0; i < args.length - 1; i++) {
if (DATA_FILE.equals(args[i])) {
return getModel(args, i);
}
}
System.err.println("Missing -datafile, e.g.: -datafile myfile.ttl");
System.exit(0);
return null;
}

protected Model getShapesModel(String[] args) throws IOException {
for (int i = 0; i < args.length - 1; i++) {
if (SHAPES_FILE.equals(args[i])) {
return getModel(args, i);
}
}
return null;
}

private Model getModel(String[] args, int i) throws FileNotFoundException {
String fileName = args[i + 1];
OntModel dataModel = ModelFactory.createOntologyModel(spec);
File file = new File(fileName);
String lang = FileUtils.langTurtle;
dataModel.read(new FileInputStream(file), "urn:x:base", lang);
return dataModel;
}

}
Loading
Loading