Skip to content

Commit

Permalink
Add SHACL validation capabilities (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
weisenje authored and GitHub Enterprise committed Sep 21, 2023
1 parent 193dc3d commit 789b030
Show file tree
Hide file tree
Showing 28 changed files with 2,437 additions and 132 deletions.
7 changes: 7 additions & 0 deletions connectionUtils/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@
<artifactId>jena-arq</artifactId>
<version>4.9.0</version>
</dependency>

<!-- License: Apache 2.0 -->
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-rdfconnection</artifactId>
<version>4.9.0</version>
</dependency>

<!-- License: Apache 2.0 -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
** Copyright 2016-2018 General Electric Company
** Copyright 2016-2023 General Electric Company
**
**
** Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -21,6 +21,9 @@
import java.util.ArrayList;
import java.util.Arrays;

import org.apache.jena.graph.Graph;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdfconnection.RDFConnection;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
Expand Down Expand Up @@ -598,4 +601,35 @@ public String getUniqueKey() {
ret.append(this.enableOwlImports ? "owlImports;" : "noImports;");
return ret.toString();
}


/**
* Create a Jena Graph from this SparqlConnection
*/
public Graph getJenaGraph() {
ArrayList<String> fetched = new ArrayList<String>();

Model model = null;
RDFConnection rdfConn = null;
try {
for(SparqlEndpointInterface sei : this.getAllInterfaces()) {
rdfConn = RDFConnection.connect(sei.getServerAndPort());
String graphName = sei.getGraph();
if(fetched.contains(sei.getServerAndPort() + graphName)) {
continue; // skip if already fetched it (e.g. if model graph is the same as data graph)
}
Model m = rdfConn.fetch(graphName);
fetched.add(sei.getServerAndPort() + graphName);
if(model == null) {
model = m;
}else {
model.add(m);
}
rdfConn.close();
}
return model.getGraph();
}finally {
rdfConn.close();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.text.StrSubstitutor;
import org.apache.jena.graph.Graph;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.RDFParser;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
Expand Down Expand Up @@ -347,6 +353,17 @@ public static boolean arraysSameMinusOrder(String[] arr1, String[] arr2) {
return Arrays.equals(arr1Clone, arr2Clone);
}

/**
* Determine if two JSONObjects are equivalent.
* Ignores key order (but not JSONArray list order)
*/
public static boolean equals(JSONObject o1, JSONObject o2) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode json1 = mapper.readTree(o1.toString());
JsonNode json2 = mapper.readTree(o2.toString());
return json1.equals(json2);
}

public static String readFile(String path) throws IOException {
return FileUtils.readFileToString(new File(path));
}
Expand Down Expand Up @@ -1190,5 +1207,36 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
}
});
}

/**
* Create a Jena Graph from Turtle data
* @param ttlInputStream Turtle data in an input stream
* @return the Jena graph
* @throws Exception
*/
public static Graph getJenaGraphFromTurtle(InputStream ttlInputStream) throws Exception {
try {
return RDFParser.source(ttlInputStream).lang(Lang.TTL).toGraph();
}catch(Exception e) {
throw new Exception("Error creating graph from Turtle: " + e.getMessage(), e);
}
}

/**
* Get a Turtle string for a given Jena Graph
* @param graph the graph
* @return the Turtle string
*/
public static String getTurtleFromJenaGraph(Graph graph) throws IOException {
OutputStream outputStream = null;
try {
Model model = ModelFactory.createModelForGraph(graph);
outputStream = new ByteArrayOutputStream();
RDFDataMgr.write(outputStream, model, Lang.TTL);
}finally {
outputStream.close();
}
return outputStream.toString();
}

}
7 changes: 7 additions & 0 deletions sparqlGraphLibrary/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@
<artifactId>jena-arq</artifactId>
<version>4.9.0</version>
</dependency>

<!-- License: Apache 2.0 -->
<dependency>
<groupId>org.apache.jena</groupId>
<artifactId>jena-shacl</artifactId>
<version>4.9.0</version>
</dependency>

<!-- License: Apache 2.0 -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.jena.sparql.lang.SPARQLParserFactory;

import com.ge.research.semtk.sparqlX.SparqlEndpointInterface;
import com.ge.research.semtk.sparqlX.XSDSupportedType;
import com.ge.research.semtk.utility.Utility;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import java.util.HashSet;
import java.util.Hashtable;

import org.apache.jena.atlas.json.JSON;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.stream.Collectors;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.jena.atlas.json.JSON;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
import java.io.InputStreamReader;
import java.net.ConnectException;

import org.apache.jena.shacl.validation.Severity;

import com.ge.research.semtk.connutil.EndpointNotFoundException;
import com.ge.research.semtk.resultSet.SimpleResultSet;
import com.ge.research.semtk.sparqlX.SparqlConnection;

/**
* Client for UtilityService
Expand All @@ -39,6 +43,7 @@ private void cleanUp() {
conf.setServiceEndpoint(null);
this.parametersJSON.clear();
this.fileParameter = null;
this.fileParameterName = "file";
}

/**
Expand Down Expand Up @@ -76,4 +81,37 @@ public BufferedReader execLoadIngestionPackage(File ingestionPackageFile, String
}
}


/**
* Executes a call to run SHACL
* @param shaclTtlFile the SHACL file (in ttl format)
* @param conn the connection
* @param severity return problems with this severity level or higher (Info, Warning, Violation)
* @return jobId
* @throws Exception
*/
@SuppressWarnings("unchecked")
public String execGetShaclResults(File shaclTtlFile, SparqlConnection conn, Severity severity) throws Exception {

if(!shaclTtlFile.exists()) {
throw new Exception("File does not exist: " + shaclTtlFile.getAbsolutePath());
}

this.parametersJSON.clear();
this.fileParameter = shaclTtlFile;
this.fileParameterName = "shaclTtlFile";
this.parametersJSON.put("conn", conn.toJson().toJSONString());
this.parametersJSON.put("severity", severity.level().getLocalName()); // e.g. Info, Warning, Violation
conf.setServiceEndpoint("utility/getShaclResults");
this.conf.setMethod(RestClientConfig.Methods.POST);

try {
SimpleResultSet res = this.executeWithSimpleResultReturn();
res.throwExceptionIfUnsuccessful();
return res.getJobId();
} finally {
this.cleanUp();
}
}

}
Loading

0 comments on commit 789b030

Please sign in to comment.