Skip to content

Commit

Permalink
Merge pull request #315 from ontodev/more-consistent-query
Browse files Browse the repository at this point in the history
More consistent query
  • Loading branch information
jamesaoverton authored Jul 23, 2018
2 parents aaf531f + 0c987ff commit e69ef9d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 42 deletions.
14 changes: 13 additions & 1 deletion docs/verify.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,16 @@ Should output as a response:
And the CSV file `results/equivalent.csv` should have:

first,second,firstLabel,secondLabel
http://purl.obolibrary.org/obo/TEST_A,http://purl.obolibrary.org/obo/TEST_B,,
http://purl.obolibrary.org/obo/TEST_A,http://purl.obolibrary.org/obo/TEST_B,,

---

## Error Messages

### Verification Failed

At least one of the query you specifies returned results. The number of failures for each rule will be printed. A CSV file will be generated with the results that matched the rule.

### Missing Query Error

You must specify a query to execute with `--query` or `--queries`.
56 changes: 15 additions & 41 deletions robot-command/src/main/java/org/obolibrary/robot/VerifyCommand.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
package org.obolibrary.robot;

import com.google.common.io.Files;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.ResultSetFactory;
import com.hp.hpl.jena.query.ResultSetRewindable;
import com.hp.hpl.jena.sparql.core.DatasetGraph;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.obolibrary.robot.exceptions.CannotReadQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -36,6 +26,10 @@ public class VerifyCommand implements Command {
private static final String missingQueryError =
NS + "MISSING QUERY ERROR at least one query is required";

/** Error message when no query is provided. */
private static final String verificationFailed =
NS + "VERIFICATION FAILED there were violations of at least one rule";

/** Store the command-line options for the command. */
private Options options;

Expand Down Expand Up @@ -122,44 +116,24 @@ public CommandState execute(CommandState state, String[] args) throws Exception

File outputDir = new File(CommandLineHelper.getDefaultValue(line, "output-dir", "."));

Map<File, Tuple<ResultSetRewindable, OutputStream>> resultMap = new HashMap<>();
String[] queryFilePaths = line.getOptionValues("queries");
if (queryFilePaths.length == 0) {
throw new IllegalArgumentException(missingQueryError);
}
boolean passing = true;
for (String filePath : queryFilePaths) {
File query = new File(filePath);
ResultSet results = QueryOperation.execQuery(graph, fileContents(query));
ResultSetRewindable resultsCopy = ResultSetFactory.copyResults(results);
File queryFile = new File(filePath);
String queryString = FileUtils.readFileToString(queryFile);
String csvPath = FilenameUtils.getBaseName(filePath).concat(".csv");
File resultCsv = outputDir.toPath().resolve(csvPath).toFile();
if (resultsCopy.size() > 0) {
resultMap.put(query, new Tuple<>(resultsCopy, new FileOutputStream(resultCsv)));
} else {
System.out.println("Rule " + resultCsv.getCanonicalPath() + ": 0 violations");
boolean result =
QueryOperation.runVerify(
graph, filePath, queryString, outputDir.toPath().resolve(csvPath), null);
if (result) {
passing = false;
}
}

boolean violationsExist = QueryOperation.execVerify(resultMap);
if (violationsExist) {
System.exit(1);
if (!passing) {
throw new Exception(verificationFailed);
}

return state;
}

/**
* Utility function to get file contents.
*
* @param file the file to read
*/
private static String fileContents(File file) {
try {
return Files.toString(file, Charset.defaultCharset());
} catch (IOException e) {
String message = "Cannot read from " + file + ": " + e.getMessage();
// TODO: Is this necessary?
throw new CannotReadQuery(message, e);
}
}
}
52 changes: 52 additions & 0 deletions robot-core/src/main/java/org/obolibrary/robot/QueryOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.hp.hpl.jena.sparql.core.DatasetGraph;
import com.hp.hpl.jena.sparql.core.DatasetGraphFactory;
import java.io.*;
import java.nio.file.Path;
import java.util.Map;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
Expand Down Expand Up @@ -427,6 +428,57 @@ public static boolean execVerify(
return isViolation;
}

/**
* Execute a SPARQL query and return true if there are any results, false otherwise. Prints
* violations to STDERR.
*
* @param dsg the graph to query over
* @param query the SPARQL query string
* @return true if the are results, false otherwise
*/
public static boolean execVerify(DatasetGraph dsg, String ruleName, String query) {
ResultSetRewindable results = ResultSetFactory.copyResults(execQuery(dsg, query));
System.out.println("Rule " + ruleName + ": " + results.size() + " violation(s)");
if (results.size() == 0) {
System.out.println("PASS Rule " + ruleName + ": 0 violation(s)");
return false;
} else {
ResultSetMgr.write(System.err, results, Lang.CSV);
System.out.println("FAIL Rule " + ruleName + ": " + results.size() + " violation(s)");
return true;
}
}

/**
* Run a SELECT query and write the result to a file. Prints violations to STDERR.
*
* @param dsg The graph to query over.
* @param query The SPARQL query string.
* @param outputPath The file path to write to, if there are results
* @param outputFormat The file format.
* @throws FileNotFoundException if output file is not found
* @return true if the are results (so file is written), false otherwise
*/
public static boolean runVerify(
DatasetGraph dsg, String ruleName, String query, Path outputPath, Lang outputFormat)
throws FileNotFoundException {
if (outputFormat == null) {
outputFormat = Lang.CSV;
}
ResultSetRewindable results = ResultSetFactory.copyResults(execQuery(dsg, query));
if (results.size() == 0) {
System.out.println("PASS Rule " + ruleName + ": 0 violation(s)");
return false;
} else {
System.out.println("FAIL Rule " + ruleName + ": " + results.size() + " violation(s)");
ResultSetMgr.write(System.err, results, Lang.CSV);
results.reset();
FileOutputStream csvFile = new FileOutputStream(outputPath.toFile());
writeResult(results, outputFormat, csvFile);
return true;
}
}

/**
* Count results.
*
Expand Down

0 comments on commit e69ef9d

Please sign in to comment.