| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.rya.shell; |
| |
| import static java.util.Objects.requireNonNull; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.charset.StandardCharsets; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.text.DecimalFormat; |
| import java.util.Objects; |
| |
| import org.apache.rya.api.client.RyaClient; |
| import org.apache.rya.api.client.RyaClientException; |
| import org.apache.rya.shell.SharedShellState.ShellState; |
| import org.apache.rya.shell.util.ConsolePrinter; |
| import org.apache.rya.shell.util.SparqlPrompt; |
| import org.openrdf.rio.RDFFormat; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.shell.core.CommandMarker; |
| import org.springframework.shell.core.annotation.CliAvailabilityIndicator; |
| import org.springframework.shell.core.annotation.CliCommand; |
| import org.springframework.shell.core.annotation.CliOption; |
| import org.springframework.stereotype.Component; |
| |
| import com.google.common.base.Optional; |
| |
| /** |
| * Rya Shell commands that have to do with common tasks (loading and querying data) |
| */ |
| @Component |
| public class RyaCommands implements CommandMarker { |
| |
| private static final Logger log = LoggerFactory.getLogger(RyaCommands.class); |
| |
| public static final String LOAD_DATA_CMD = "load-data"; |
| public static final String SPARQL_QUERY_CMD = "sparql-query"; |
| |
| private final SharedShellState state; |
| private final SparqlPrompt sparqlPrompt; |
| private final ConsolePrinter consolePrinter; |
| |
| /** |
| * Constructs an instance of {@link RyaCommands}. |
| * |
| * @param state - Holds shared state between all of the command classes. (not null) |
| * @param sparqlPrompt - Prompts a user for a SPARQL query. (not null) |
| * @param consolePrinter - Allows the command to print feedback to the user. (not null) |
| */ |
| @Autowired |
| public RyaCommands(final SharedShellState state, final SparqlPrompt sparqlPrompt, |
| final ConsolePrinter consolePrinter) { |
| this.state = Objects.requireNonNull(state); |
| this.sparqlPrompt = requireNonNull(sparqlPrompt); |
| this.consolePrinter = Objects.requireNonNull(consolePrinter); |
| } |
| |
| /** |
| * Enables commands that are always available once the Shell is connected to a Rya Instance. |
| */ |
| @CliAvailabilityIndicator({ LOAD_DATA_CMD, SPARQL_QUERY_CMD }) |
| public boolean areInstanceCommandsAvailable() { |
| switch (state.getShellState().getConnectionState()) { |
| case CONNECTED_TO_INSTANCE: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| @CliCommand(value = LOAD_DATA_CMD, help = "Loads RDF Statement data from a local file to the connected Rya instance.") |
| public String loadData( |
| @CliOption(key = { "file" }, mandatory = true, help = "A local file containing RDF Statements that is to be loaded.") |
| final String file, |
| @CliOption(key = { "format" }, mandatory = false, help = "The format of the supplied RDF Statements file. [RDF/XML, N-Triples, Turtle, N3, TriX, TriG, BinaryRDF, N-Quads, JSON-LD, RDF/JSON, RDFa]") |
| final String format |
| ) { |
| // Fetch the command that is connected to the store. |
| final ShellState shellState = state.getShellState(); |
| final RyaClient commands = shellState.getConnectedCommands().get(); |
| final Optional<String> ryaInstanceName = shellState.getRyaInstanceName(); |
| try { |
| final long start = System.currentTimeMillis(); |
| |
| // If the provided path is relative, then make it rooted in the user's home. |
| Path rootedFile = Paths.get( file.replaceFirst("^~", System.getProperty("user.home")) ); |
| |
| RDFFormat rdfFormat = null; |
| // If a format was provided, then go with that. |
| if (format != null) { |
| rdfFormat = RDFFormat.valueOf(format); |
| if (rdfFormat == null) { |
| throw new RuntimeException("Unsupported RDF Statement data input format: " + format); |
| } |
| } |
| |
| // Otherwise try to figure it out using the filename. |
| else if (rdfFormat == null) { |
| rdfFormat = RDFFormat.forFileName(rootedFile.getFileName().toString()); |
| if (rdfFormat == null) { |
| throw new RuntimeException("Unable to detect RDF Statement data input format for file: " + rootedFile); |
| } else { |
| consolePrinter.println("Detected RDF Format: " + rdfFormat); |
| consolePrinter.flush(); |
| } |
| } |
| commands.getLoadStatementsFile().loadStatements(ryaInstanceName.get(), rootedFile, rdfFormat); |
| |
| final String seconds = new DecimalFormat("0.0##").format((System.currentTimeMillis() - start) / 1000.0); |
| return "Loaded the file: '" + file + "' successfully in " + seconds + " seconds."; |
| |
| } catch (final RyaClientException | IOException e) { |
| log.error("Error", e); |
| throw new RuntimeException("Can not load the RDF Statement data. Reason: " + e.getMessage(), e); |
| } |
| } |
| |
| @CliCommand(value = SPARQL_QUERY_CMD, help = "Executes the provided SPARQL Query on the connected Rya instance.") |
| public String sparqlQuery( |
| @CliOption(key = { "file" }, mandatory = false, help = "A local file containing the SPARQL Query that is to be read and executed.") |
| final String file) { |
| // Fetch the command that is connected to the store. |
| final ShellState shellState = state.getShellState(); |
| final RyaClient commands = shellState.getConnectedCommands().get(); |
| final Optional<String> ryaInstanceName = shellState.getRyaInstanceName(); |
| |
| try { |
| // file option specified |
| String sparqlQuery; |
| if (file != null) { |
| sparqlQuery = new String(Files.readAllBytes(new File(file).toPath()), StandardCharsets.UTF_8); |
| consolePrinter.println("Loaded Query:"); |
| consolePrinter.println(sparqlQuery); |
| } else { |
| // No Options specified. Show the user the SPARQL Prompt |
| final Optional<String> sparqlQueryOpt = sparqlPrompt.getSparql(); |
| if (sparqlQueryOpt.isPresent()) { |
| sparqlQuery = sparqlQueryOpt.get(); |
| } else { |
| return ""; // user aborted the SPARQL prompt. |
| } |
| } |
| |
| consolePrinter.println("Executing Query..."); |
| consolePrinter.flush(); |
| return commands.getExecuteSparqlQuery().executeSparqlQuery(ryaInstanceName.get(), sparqlQuery); |
| } catch (final RyaClientException | IOException e) { |
| log.error("Error", e); |
| throw new RuntimeException("Can not execute the SPARQL Query. Reason: " + e.getMessage(), e); |
| } |
| } |
| } |