package org.linkeddatafragments.client; import com.google.gson.Gson; import com.google.gson.stream.JsonReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Iterator; import org.apache.jena.graph.Triple; import org.apache.jena.query.*; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.shared.PrefixMapping; import org.linkeddatafragments.model.LinkedDataFragmentGraph; import org.linkeddatafragments.utils.Config; /** * A QueryResultsWriter executes a query on a graph and writes its results to a stream. * @author Laurens De Vocht * @author Ruben Verborgh */ public class QueryResultsWriter { private final Model model; private final Query query; /** * Creates a new QueryResultsWriter. * @param model The model to query. * @param query The query to execute. */ public QueryResultsWriter(final Model model, final Query query) { this.model = model; this.query = query; } /** * Write the results of the query to the stream. * @param outputStream The output stream. */ public void writeResults(final PrintStream outputStream) { final QueryExecution executor = QueryExecutionFactory.create(query, model); switch (query.getQueryType()) { case Query.QueryTypeSelect: final ResultSet rs = executor.execSelect(); while (rs.hasNext()) outputStream.println(rs.next()); break; case Query.QueryTypeAsk: outputStream.println(executor.execAsk()); break; case Query.QueryTypeConstruct: case Query.QueryTypeDescribe: final Iterator<Triple> triples = executor.execConstructTriples(); while (triples.hasNext()) outputStream.println(triples.next()); break; default: throw new Error("Unsupported query type"); } } /** * Starts a standalone version of the results writer. * @param args The command-line arguments. */ public static void main(final String[] args) { // Verify arguments if (args.length < 1 || args.length > 2 || args[0].matches("/^--?h(elp)?$/")) error("usage: java -jar ldf-client.jar [config.json] query"); final boolean hasConfig = args.length >= 2; // Read the configuration final File configFile = hasConfig ? new File(args[0]) : new File("./config-default.json"); JsonReader configReader; try { configReader = new JsonReader(new FileReader(configFile)); } catch (FileNotFoundException e) { error("Config file could not be found."); return; } final Config config = new Gson().fromJson(configReader, Config.class); // Read the query final String queryFilePath = hasConfig ? args[1] : args[0]; String queryText; try { queryText = new String(Files.readAllBytes(Paths.get(queryFilePath)), StandardCharsets.UTF_8); } catch (IOException e) { error("Query file could not be read."); return; } // Query prefixes must be applied before the query is parsed. final Query query = QueryFactory.create(); PrefixMapping pm = PrefixMapping.Factory.create(); pm.setNsPrefixes(config.prefixes); query.setPrefixMapping(pm); QueryFactory.parse(query, queryText, null, Syntax.syntaxSPARQL); // Execute the query over the graph and write its results final LinkedDataFragmentGraph graph = new LinkedDataFragmentGraph(config.datasource); new QueryResultsWriter(ModelFactory.createModelForGraph(graph), query).writeResults(System.out); System.exit(0); } /** * Writes the error message and exits the application. * @param message The error message. */ private static void error(String message) { System.err.println(message); System.exit(1); } }