You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2016/01/05 13:46:08 UTC
[14/20] jena git commit: JENA-1108 : jena-cmds module
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/query.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/query.java b/jena-cmds/src/main/java/arq/query.java
new file mode 100644
index 0000000..9a9ed5f
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/query.java
@@ -0,0 +1,257 @@
+/*
+ * 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 arq;
+
+import arq.cmdline.* ;
+import jena.cmd.ArgDecl;
+import jena.cmd.CmdException;
+import jena.cmd.TerminationException;
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.query.* ;
+import org.apache.jena.riot.RiotException ;
+import org.apache.jena.riot.RiotNotFoundException ;
+import org.apache.jena.riot.SysRIOT ;
+import org.apache.jena.shared.JenaException ;
+import org.apache.jena.sparql.ARQInternalErrorException ;
+import org.apache.jena.sparql.mgt.Explain ;
+import org.apache.jena.sparql.resultset.ResultSetException ;
+import org.apache.jena.sparql.resultset.ResultsFormat ;
+import org.apache.jena.sparql.util.QueryExecUtils ;
+
+public class query extends CmdARQ
+{
+ private ArgDecl argRepeat = new ArgDecl(ArgDecl.HasValue, "repeat") ;
+ private ArgDecl argExplain = new ArgDecl(ArgDecl.NoValue, "explain") ;
+ private ArgDecl argOptimize = new ArgDecl(ArgDecl.HasValue, "opt", "optimize") ;
+
+ protected int repeatCount = 1 ;
+ protected int warmupCount = 0 ;
+ protected boolean queryOptimization = true ;
+
+ protected ModTime modTime = new ModTime() ;
+ protected ModQueryIn modQuery = null;
+ protected ModDataset modDataset = null ;
+ protected ModResultsOut modResults = new ModResultsOut() ;
+ protected ModEngine modEngine = new ModEngine() ;
+
+ public static void main (String... argv)
+ {
+ new query(argv).mainRun() ;
+ }
+
+ public query(String[] argv)
+ {
+ super(argv) ;
+ modQuery = new ModQueryIn(getDefaultSyntax()) ;
+ modDataset = setModDataset() ;
+
+ super.addModule(modQuery) ;
+ super.addModule(modResults) ;
+ super.addModule(modDataset) ;
+ super.addModule(modEngine) ;
+ super.addModule(modTime) ;
+
+ super.getUsage().startCategory("Control") ;
+ super.add(argExplain, "--explain", "Explain and log query execution") ;
+ super.add(argRepeat, "--repeat=N or N,M", "Do N times or N warmup and then M times (use for timing to overcome start up costs of Java)");
+ super.add(argOptimize, "--optimize=", "Turn the query optimizer on or off (default: on)") ;
+ }
+
+ /** Default syntax used when the syntax can not be determined from the command name or file extension
+ * The order of determination is:
+ * <ul>
+ * <li>Explicitly given --syntax</li>
+ * <li>File extension</li>
+ * <li>Command default</li>
+ * <li>System default</li>
+ * </ul>
+ *
+ */
+ protected Syntax getDefaultSyntax() { return Syntax.defaultQuerySyntax ; }
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ super.processModulesAndArgs() ;
+ if ( contains(argRepeat) )
+ {
+ String[] x = getValue(argRepeat).split(",") ;
+ if ( x.length == 1 )
+ {
+ try { repeatCount = Integer.parseInt(x[0]) ; }
+ catch (NumberFormatException ex)
+ { throw new CmdException("Can't parse "+x[0]+" in arg "+getValue(argRepeat)+" as an integer") ; }
+
+ }
+ else if ( x.length == 2 )
+ {
+ try { warmupCount = Integer.parseInt(x[0]) ; }
+ catch (NumberFormatException ex)
+ { throw new CmdException("Can't parse "+x[0]+" in arg "+getValue(argRepeat)+" as an integer") ; }
+ try { repeatCount = Integer.parseInt(x[1]) ; }
+ catch (NumberFormatException ex)
+ { throw new CmdException("Can't parse "+x[1]+" in arg "+getValue(argRepeat)+" as an integer") ; }
+ }
+ else
+ throw new CmdException("Wrong format for repeat count: "+getValue(argRepeat)) ;
+ }
+ if ( isVerbose() )
+ ARQ.getContext().setTrue(ARQ.symLogExec) ;
+
+ if ( hasArg(argExplain) )
+ ARQ.setExecutionLogging(Explain.InfoLevel.ALL) ;
+
+ if ( hasArg(argOptimize) )
+ {
+ String x1 = getValue(argOptimize) ;
+ if ( hasValueOfTrue(argOptimize) || x1.equalsIgnoreCase("on") || x1.equalsIgnoreCase("yes") )
+ queryOptimization = true ;
+ else if ( hasValueOfFalse(argOptimize) || x1.equalsIgnoreCase("off") || x1.equalsIgnoreCase("no") )
+ queryOptimization = false ;
+ else throw new CmdException("Optimization flag must be true/false/on/off/yes/no. Found: "+getValue(argOptimize)) ;
+ }
+ }
+
+ protected ModDataset setModDataset()
+ {
+ return new ModDatasetGeneralAssembler() ;
+ }
+
+ @Override
+ protected void exec()
+ {
+ if ( ! queryOptimization )
+ ARQ.getContext().setFalse(ARQ.optimization) ;
+ if ( cmdStrictMode )
+ ARQ.getContext().setFalse(ARQ.optimization) ;
+
+ // Warm up.
+ for ( int i = 0 ; i < warmupCount ; i++ )
+ {
+ queryExec(false, ResultsFormat.FMT_NONE) ;
+ }
+
+ for ( int i = 0 ; i < repeatCount ; i++ )
+ queryExec(modTime.timingEnabled(), modResults.getResultsFormat()) ;
+
+ if ( modTime.timingEnabled() && repeatCount > 1 )
+ {
+ long avg = totalTime/repeatCount ;
+ String avgStr = modTime.timeStr(avg) ;
+ System.err.println("Total time: "+modTime.timeStr(totalTime)+" sec for repeat count of "+repeatCount+ " : average: "+avgStr) ;
+ }
+ }
+
+ @Override
+ protected String getCommandName() { return Lib.className(this) ; }
+
+ @Override
+ protected String getSummary() { return getCommandName()+" --data=<file> --query=<query>" ; }
+
+ protected Dataset getDataset() {
+ try {
+ Dataset ds = modDataset.getDataset();
+ if ( ds == null )
+ ds = dealWithNoDataset();
+ return ds;
+ }
+ catch (RiotNotFoundException ex) {
+ System.err.println("Failed to load data: " + ex.getMessage());
+ throw new TerminationException(1);
+ }
+ catch (RiotException ex) {
+ System.err.println("Failed to load data");
+ throw new TerminationException(1);
+ }
+ }
+
+ protected Dataset dealWithNoDataset() {
+ return DatasetFactory.create() ;
+ //throw new CmdException("No dataset provided") ;
+ }
+
+ protected long totalTime = 0 ;
+ protected void queryExec(boolean timed, ResultsFormat fmt)
+ {
+ try{
+ Query query = modQuery.getQuery() ;
+ if ( isVerbose() )
+ {
+ IndentedWriter out = new IndentedWriter(System.out, true) ;
+ query.serialize(out) ;
+ out.flush() ;
+ System.out.println();
+ }
+
+ if ( isQuiet() )
+ LogCtl.setError(SysRIOT.riotLoggerName) ;
+ Dataset dataset = getDataset() ;
+ modTime.startTimer() ;
+ QueryExecution qe = QueryExecutionFactory.create(query, dataset) ;
+ // Check there is a dataset
+
+ if ( dataset == null && ! query.hasDatasetDescription() )
+ {
+ System.err.println("Dataset not specified in query nor provided on command line.");
+ throw new TerminationException(1) ;
+ }
+ try { QueryExecUtils.executeQuery(query, qe, fmt) ; }
+ catch (QueryCancelledException ex) {
+ System.out.flush() ;
+ System.err.println("Query timed out") ;
+ }
+
+ long time = modTime.endTimer() ;
+ if ( timed )
+ {
+ totalTime += time ;
+ System.err.println("Time: "+modTime.timeStr(time)+" sec") ;
+ }
+ qe.close() ;
+ }
+ catch (ARQInternalErrorException intEx)
+ {
+ System.err.println(intEx.getMessage()) ;
+ if ( intEx.getCause() != null )
+ {
+ System.err.println("Cause:") ;
+ intEx.getCause().printStackTrace(System.err) ;
+ System.err.println() ;
+ }
+ intEx.printStackTrace(System.err) ;
+ }
+ catch (ResultSetException ex)
+ {
+ System.err.println(ex.getMessage()) ;
+ ex.printStackTrace(System.err) ;
+ }
+ catch (QueryException qEx)
+ {
+ //System.err.println(qEx.getMessage()) ;
+ throw new CmdException("Query Exeception", qEx) ;
+ }
+ catch (JenaException | CmdException ex) { throw ex ; }
+ catch (Exception ex)
+ {
+ throw new CmdException("Exception", ex) ;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/rdfdiff.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/rdfdiff.java b/jena-cmds/src/main/java/arq/rdfdiff.java
new file mode 100644
index 0000000..78a51bb
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/rdfdiff.java
@@ -0,0 +1,312 @@
+/*
+ * 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 arq;
+
+import static org.apache.jena.atlas.logging.LogCtl.setCmdLogging;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.io.FileInputStream;
+
+import org.apache.jena.rdf.model.*;
+import org.apache.jena.sparql.util.Closure;
+
+/**
+ * A program which read two RDF models and provides a basic triple level diff
+ *
+ * <p>
+ * This program will read two RDF models, in a variety of languages, and compare
+ * them providing a basic triple level diff output. Since blank nodes are a
+ * complicating factor diffs for blank node containing portions of the graph are
+ * reported in terms of sub-graphs rather than individual triples.
+ * </p>
+ * <p>
+ * Input can be read either from a URL or from a file. The program writes its
+ * results to the standard output stream and sets its exit code to 0 if the
+ * models are equal, to 1 if they are not and to -1 if it encounters an error.
+ * </p>
+ *
+ * <p>
+ * </p>
+ *
+ * <pre>
+ * java jena.rdfcompare model1 model2 [lang1 [lang2]]
+ *
+ * model1 and model2 can be file names or URL's
+ * lang1 and lang2 specify the language of the input and can be:
+ * RDF/XML
+ * N-TRIPLE
+ * N3
+ * </pre>
+ */
+public class rdfdiff extends java.lang.Object {
+
+ static {
+ setCmdLogging();
+ }
+
+ /**
+ * @param args
+ * the command line arguments
+ */
+ public static void main(String... args) {
+ if (args.length < 2 || args.length > 6) {
+ usage();
+ System.exit(-1);
+ }
+
+ String in1 = args[0];
+ String in2 = args[1];
+ String lang1 = "RDF/XML";
+ if (args.length >= 3) {
+ lang1 = args[2];
+ }
+ String lang2 = "N-TRIPLE";
+ if (args.length >= 4) {
+ lang2 = args[3];
+ }
+ String base1 = null;
+ if (args.length >= 5) {
+ base1 = args[4];
+ }
+ String base2 = base1;
+ if (args.length >= 6) {
+ base2 = args[5];
+ }
+
+ System.out.println(in1 + " " + in2 + " " + lang1 + " " + lang2 + " " + base1 + " " + base2);
+ try {
+ Model m1 = ModelFactory.createDefaultModel();
+ Model m2 = ModelFactory.createDefaultModel();
+
+ read(m1, in1, lang1, base1);
+ read(m2, in2, lang2, base2);
+
+ if (m1.isIsomorphicWith(m2)) {
+ System.out.println("models are equal");
+ System.out.println();
+ System.exit(0);
+ } else {
+ System.out.println("models are unequal");
+ System.out.println();
+
+ if (m1.size() != m2.size()) {
+ System.out.println(String.format("< %,d triples", m1.size()));
+ System.out.println(String.format("> %,d triples", m2.size()));
+ }
+
+ // Calculate differences
+ Map<AnonId, Model> m1SubGraphs = new HashMap<>();
+ StmtIterator iter = m1.listStatements();
+ while (iter.hasNext()) {
+ Statement stmt = iter.next();
+ if (stmt.asTriple().isConcrete()) {
+ if (!m2.contains(stmt)) {
+ System.out.print("< ");
+ System.out.println(stmt.toString());
+ }
+ } else {
+ // Handle blank nodes via sub-graphs
+ addToSubGraph(stmt, m1SubGraphs);
+ }
+ }
+
+ Map<AnonId, Model> m2SubGraphs = new HashMap<>();
+ iter = m2.listStatements();
+ while (iter.hasNext()) {
+ Statement stmt = iter.next();
+ if (stmt.asTriple().isConcrete()) {
+ if (!m1.contains(stmt)) {
+ System.out.print("> ");
+ System.out.println(stmt.toString());
+ }
+ } else {
+ // Handle blank nodes via sub-graphs
+ addToSubGraph(stmt, m2SubGraphs);
+ }
+ }
+
+ // Compute sub-graph differences
+
+ // Reduce to sets
+ Set<Model> m1SubGraphSet = new TreeSet<>(new ModelReferenceComparator());
+ m1SubGraphSet.addAll(m1SubGraphs.values());
+ Set<Model> m2SubGraphSet = new TreeSet<>(new ModelReferenceComparator());
+ m2SubGraphSet.addAll(m2SubGraphs.values());
+
+ if (m1SubGraphSet.size() != m2SubGraphSet.size()) {
+ System.out.println("< " + m1SubGraphs.size() + " sub-graphs");
+ System.out.println("> " + m2SubGraphs.size() + " sub-graphs");
+ }
+ if (m1SubGraphSet.size() > 0) {
+ diffSubGraphs(m1SubGraphSet, m2SubGraphSet, "< ");
+ }
+ if (m2SubGraphSet.size() > 0) {
+ diffSubGraphs(m2SubGraphSet, m1SubGraphSet, "> ");
+ }
+
+ System.exit(1);
+ }
+ } catch (Exception e) {
+ System.err.println("Unhandled exception:");
+ System.err.println(" " + e.toString());
+ System.exit(-1);
+ }
+ }
+
+ private static void diffSubGraphs(Set<Model> m1SubGraphSet, Set<Model> m2SubGraphSet, String prefix) {
+ for (Model subGraph : m1SubGraphSet) {
+ // Find candidate matches
+ List<Model> candidates = new ArrayList<>();
+ for (Model subGraphCandidate : m2SubGraphSet) {
+ if (subGraph.size() == subGraphCandidate.size()) {
+ candidates.add(subGraph);
+ }
+ }
+
+ if (candidates.size() == 0) {
+ // No match
+ printNonMatchingSubGraph(prefix, subGraph);
+ } else if (candidates.size() == 1) {
+ // Precisely 1 candidate
+ if (!subGraph.isIsomorphicWith(candidates.get(0))) {
+ printNonMatchingSubGraph(prefix, subGraph);
+ } else {
+ m2SubGraphSet.remove(candidates.get(0));
+ }
+ } else {
+ // Multiple candidates
+ boolean matched = false;
+ for (Model subGraphCandidate : candidates) {
+ if (subGraph.isIsomorphicWith(subGraphCandidate)) {
+ // Found a match
+ matched = true;
+ m2SubGraphSet.remove(subGraphCandidate);
+ break;
+ }
+ }
+
+ if (!matched) {
+ // Didn't find a match
+ printNonMatchingSubGraph(prefix, subGraph);
+ }
+ }
+ }
+ }
+
+ private static void printNonMatchingSubGraph(String prefix, Model subGraph) {
+ StmtIterator sIter = subGraph.listStatements();
+ while (sIter.hasNext()) {
+ System.out.print(prefix);
+ System.out.println(sIter.next().toString());
+ }
+ }
+
+ private static void addToSubGraph(Statement stmt, Map<AnonId, Model> subGraphs) {
+ Set<AnonId> ids = new HashSet<>();
+
+ addToIdList(stmt, ids);
+
+ // Here we take a copy of the IDs
+ Model subGraph = null;
+ for (AnonId id : ids) {
+ if (!subGraphs.containsKey(id)) {
+ subGraph = Closure.closure(stmt);
+ subGraph.add(stmt);
+ break;
+ }
+ }
+
+ // May already have built the sub-graph that includes this statement
+ if (subGraph == null)
+ return;
+
+ // Find any further IDs that occur in the sub-graph
+ StmtIterator sIter = subGraph.listStatements();
+ while (sIter.hasNext()) {
+ addToIdList(sIter.next(), ids);
+ }
+
+ // Associate the sub-graph with all mentioned blank node IDs
+ for (AnonId id : ids) {
+ if (subGraphs.containsKey(id))
+ throw new IllegalStateException(String.format("ID %s occurs in multiple sub-graphs", id));
+ subGraphs.put(id, subGraph);
+ }
+ }
+
+ private static void addToIdList(Statement stmt, Set<AnonId> ids) {
+ if (stmt.getSubject().isAnon()) {
+ ids.add(stmt.getSubject().getId());
+ }
+ if (stmt.getObject().isAnon()) {
+ ids.add(stmt.getObject().asResource().getId());
+ }
+ }
+
+ protected static void usage() {
+ System.err.println("usage:");
+ System.err.println(" java jena.rdfdiff source1 source2 [lang1 [lang2 [base1 [base2]]]]");
+ System.err.println();
+ System.err.println(" source1 and source2 can be URL's or filenames");
+ System.err.println(" lang1 and lang2 can take values:");
+ System.err.println(" RDF/XML");
+ System.err.println(" N-TRIPLE");
+ System.err.println(" N3");
+ System.err.println(" lang1 defaults to RDF/XML, lang2 to N-TRIPLE");
+ System.err.println(" base1 and base2 are URIs");
+ System.err.println(" base1 defaults to null");
+ System.err.println(" base2 defaults to base1");
+ System.err.println(" If no base URIs are specified Jena determines the base URI based on the input source");
+
+ System.err.println();
+ }
+
+ protected static void read(Model model, String in, String lang, String base) throws java.io.FileNotFoundException {
+ try {
+ URL url = new URL(in);
+ model.read(in, base, lang);
+ } catch (java.net.MalformedURLException e) {
+ model.read(new FileInputStream(in), base, lang);
+ }
+ }
+
+ private static class ModelReferenceComparator implements Comparator<Model> {
+
+ @Override
+ public int compare(Model o1, Model o2) {
+ if (o1 == o2)
+ return 0;
+ int h1 = System.identityHashCode(o1);
+ int h2 = System.identityHashCode(o2);
+
+ if (h1 == h2)
+ return 0;
+ return h1 < h2 ? -1 : 1;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/rset.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/rset.java b/jena-cmds/src/main/java/arq/rset.java
new file mode 100644
index 0000000..b1cbc3e
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/rset.java
@@ -0,0 +1,73 @@
+/*
+ * 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 arq;
+
+import org.apache.jena.query.ResultSet ;
+import arq.cmdline.CmdARQ ;
+import arq.cmdline.ModResultsIn ;
+import arq.cmdline.ModResultsOut ;
+
+/** Read and write result sets */
+
+public class rset extends CmdARQ
+{
+ ModResultsIn modInput = new ModResultsIn() ;
+ ModResultsOut modOutput = new ModResultsOut() ;
+
+ static String usage = rset.class.getName()+
+ " [--in syntax] [--out syntax] [--file FILE | FILE ]" ;
+
+ public static void main(String... argv)
+ {
+ new rset(argv).mainRun() ;
+ }
+
+ public rset(String[] argv)
+ {
+ super(argv) ;
+ super.addModule(modInput) ;
+ super.addModule(modOutput) ;
+ }
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ super.processModulesAndArgs() ;
+ }
+
+ @Override
+ protected String getSummary()
+ {
+ return usage ;
+ }
+
+ @Override
+ protected void exec()
+ {
+ ResultSet rs = modInput.getResultSet() ;
+ modOutput.printResultSet(rs, null) ;
+ }
+
+ @Override
+ protected String getCommandName()
+ {
+ return "rset" ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/rsparql.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/rsparql.java b/jena-cmds/src/main/java/arq/rsparql.java
new file mode 100644
index 0000000..bf87dfd
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/rsparql.java
@@ -0,0 +1,95 @@
+/*
+ * 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 arq;
+
+import jena.cmd.CmdException;
+
+import org.apache.jena.query.Query ;
+import org.apache.jena.query.QueryExecution ;
+import org.apache.jena.query.QueryExecutionFactory ;
+import org.apache.jena.query.Syntax ;
+import org.apache.jena.sparql.engine.http.HttpQuery ;
+import org.apache.jena.sparql.engine.http.QueryExceptionHTTP ;
+import org.apache.jena.sparql.util.QueryExecUtils ;
+
+import arq.cmdline.CmdARQ ;
+import arq.cmdline.ModQueryIn ;
+import arq.cmdline.ModRemote ;
+import arq.cmdline.ModResultsOut ;
+
+public class rsparql extends CmdARQ
+{
+ protected ModQueryIn modQuery = new ModQueryIn(Syntax.syntaxSPARQL_11) ;
+ protected ModRemote modRemote = new ModRemote() ;
+ protected ModResultsOut modResults = new ModResultsOut() ;
+
+ public static void main (String... argv)
+ {
+ new rsparql(argv).mainRun() ;
+ }
+
+
+ public rsparql(String[] argv)
+ {
+ super(argv) ;
+ super.addModule(modRemote) ;
+ super.addModule(modQuery) ;
+ super.addModule(modResults) ;
+ }
+
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ super.processModulesAndArgs() ;
+ if ( modRemote.getServiceURL() == null )
+ throw new CmdException("No SPARQL endpoint specificied") ;
+ }
+
+ @Override
+ protected void exec()
+ {
+ Query query = modQuery.getQuery() ;
+
+ try {
+ String serviceURL = modRemote.getServiceURL() ;
+ QueryExecution qe = QueryExecutionFactory.sparqlService(serviceURL, query) ;
+ if ( modRemote.usePost() )
+ HttpQuery.urlLimit = 0 ;
+
+ QueryExecUtils.executeQuery(query, qe, modResults.getResultsFormat()) ;
+ } catch (QueryExceptionHTTP ex)
+ {
+ throw new CmdException("HTTP Exeception", ex) ;
+ }
+ catch (Exception ex)
+ {
+ System.out.flush() ;
+ ex.printStackTrace(System.err) ;
+ }
+ }
+
+
+ @Override
+ protected String getSummary()
+ {
+ return null ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/rupdate.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/rupdate.java b/jena-cmds/src/main/java/arq/rupdate.java
new file mode 100644
index 0000000..8ef988c
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/rupdate.java
@@ -0,0 +1,98 @@
+/**
+ * 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 arq;
+
+import java.util.List ;
+
+import jena.cmd.ArgDecl;
+import jena.cmd.CmdException;
+
+import org.apache.jena.update.UpdateExecutionFactory ;
+import org.apache.jena.update.UpdateFactory ;
+import org.apache.jena.update.UpdateProcessor ;
+import org.apache.jena.update.UpdateRequest ;
+
+import arq.cmdline.CmdARQ ;
+import arq.cmdline.ModRemote ;
+
+public class rupdate extends CmdARQ
+{
+ static final ArgDecl updateArg = new ArgDecl(ArgDecl.HasValue, "update", "file") ;
+
+ protected ModRemote modRemote = new ModRemote() ;
+
+ List<String> requestFiles = null ;
+
+ public static void main(String[] argv)
+ {
+ new rupdate(argv).mainRun() ;
+ }
+
+ protected rupdate(String[] argv)
+ {
+ super(argv) ;
+ super.add(updateArg, "--update=FILE", "Update commands to execute") ;
+ super.addModule(modRemote) ;
+ }
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ requestFiles = getValues(updateArg) ; // ????
+ super.processModulesAndArgs() ;
+ }
+
+
+ @Override
+ protected String getSummary()
+ {
+ return getCommandName()+" --service=URL --update=<request file>" ;
+ }
+
+ @Override
+ protected void exec()
+ {
+ if ( modRemote.getServiceURL() == null )
+ {
+ throw new CmdException("No endpoint given") ;
+ }
+ String endpoint = modRemote.getServiceURL() ;
+
+ for ( String filename : requestFiles )
+ {
+ UpdateRequest req = UpdateFactory.read( filename );
+ exec( endpoint, req );
+ }
+
+ for ( String requestString : super.getPositional() )
+ {
+ requestString = indirect( requestString );
+ UpdateRequest req = UpdateFactory.create( requestString );
+ exec( endpoint, req );
+ }
+ }
+
+ private void exec(String endpoint, UpdateRequest req)
+ {
+ UpdateProcessor proc = UpdateExecutionFactory.createRemote(req, endpoint) ;
+ proc.execute() ;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/sparql.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/sparql.java b/jena-cmds/src/main/java/arq/sparql.java
new file mode 100644
index 0000000..d42ba7f
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/sparql.java
@@ -0,0 +1,37 @@
+/*
+ * 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 arq;
+
+import org.apache.jena.query.Syntax ;
+
+/** A program to execute queries from the command line in SPARQL mode. */
+
+public class sparql extends query
+{
+ public static void main (String... argv) {
+ new sparql(argv).mainRun() ;
+ }
+
+ public sparql(String[] argv) {
+ super(argv) ;
+ }
+
+ @Override
+ protected Syntax getDefaultSyntax() { return Syntax.syntaxSPARQL_11 ; }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/sse.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/sse.java b/jena-cmds/src/main/java/arq/sse.java
new file mode 100644
index 0000000..95a769e
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/sse.java
@@ -0,0 +1,108 @@
+/*
+ * 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 arq;
+
+import jena.cmd.ArgDecl;
+import jena.cmd.TerminationException;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.sparql.serializer.SerializationContext ;
+import org.apache.jena.sparql.sse.Item ;
+import org.apache.jena.sparql.sse.ItemWriter ;
+import org.apache.jena.sparql.sse.SSE ;
+
+import arq.cmdline.CmdARQ_SSE ;
+
+public class sse extends CmdARQ_SSE
+{
+ protected final ArgDecl numberDecl = new ArgDecl(ArgDecl.HasValue, "num", "number") ;
+ protected final ArgDecl noPrintDecl = new ArgDecl(ArgDecl.NoValue, "n") ;
+ protected final ArgDecl noResolveDecl = new ArgDecl(ArgDecl.NoValue, "raw") ;
+
+ private boolean print = true ;
+ private boolean structural = true ;
+ private boolean lineNumbers = false ;
+
+ public static void main (String... argv)
+ {
+ new sse(argv).mainRun() ;
+ }
+
+ public sse(String[] argv)
+ {
+ super(argv) ;
+ super.add(noPrintDecl, "-n", "Don't print the expression") ;
+ super.add(numberDecl, "--num [on|off]", "Numbers") ;
+ super.add(noResolveDecl, "--raw", "Don't handle base or prefix names specially") ;
+ }
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ super.processModulesAndArgs() ;
+ print = !contains(noPrintDecl) ;
+ if ( contains(numberDecl) )
+ lineNumbers = getValue(numberDecl).equalsIgnoreCase("on") ;
+
+ if ( contains(noResolveDecl) )
+ SSE.setUseResolver(false) ;
+ }
+
+ @Override
+ protected String getCommandName() { return Lib.className(this) ; }
+
+ @Override
+ protected String getSummary() { return getCommandName() ; }
+
+ static final String divider = "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" ;
+ //static final String divider = "" ;
+
+ boolean needDivider = false ;
+ private void divider()
+ {
+ if ( needDivider ) System.out.println(divider) ;
+ needDivider = true ;
+ }
+
+ @Override
+ protected void exec(Item item)
+ {
+ if ( ! print )
+ return ;
+
+ if ( item == null )
+ {
+ System.err.println("No expression") ;
+ throw new TerminationException(9) ;
+ }
+ divider() ;
+ IndentedWriter out = new IndentedWriter(System.out, lineNumbers) ;
+
+ // Need to check if used.
+ //PrefixMapping pmap = SSE.getDefaultPrefixMapWrite() ;
+ PrefixMapping pmap = null ;
+ SerializationContext sCxt = new SerializationContext(pmap) ;
+ ItemWriter.write(out, item, sCxt) ;
+ //item.output(out) ;
+ out.ensureStartOfLine() ;
+ out.flush();
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/sse_exec.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/sse_exec.java b/jena-cmds/src/main/java/arq/sse_exec.java
new file mode 100644
index 0000000..3b5f49c
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/sse_exec.java
@@ -0,0 +1,50 @@
+/*
+ * 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 arq;
+
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.sparql.sse.Item ;
+import org.apache.jena.sparql.sse.builders.BuilderExec ;
+import arq.cmdline.CmdARQ_SSE ;
+
+public class sse_exec extends CmdARQ_SSE
+{
+
+ public static void main (String... argv)
+ {
+ new sse_exec(argv).mainRun() ;
+ }
+
+ public sse_exec(String[] argv)
+ {
+ super(argv) ;
+ }
+
+ @Override
+ protected String getCommandName() { return Lib.className(this) ; }
+
+ @Override
+ protected String getSummary() { return getCommandName()+" [--file<file> | string]" ; }
+
+ @Override
+ protected void exec(Item item)
+ {
+ BuilderExec.exec(item) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/sse_expr.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/sse_expr.java b/jena-cmds/src/main/java/arq/sse_expr.java
new file mode 100644
index 0000000..9339d53
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/sse_expr.java
@@ -0,0 +1,24 @@
+/*
+ * 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 arq;
+
+public class sse_expr
+{
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/sse_query.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/sse_query.java b/jena-cmds/src/main/java/arq/sse_query.java
new file mode 100644
index 0000000..c5d8c7f
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/sse_query.java
@@ -0,0 +1,162 @@
+/*
+ * 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 arq;
+
+
+import jena.cmd.ArgDecl;
+import jena.cmd.CmdException;
+import jena.cmd.TerminationException;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.query.Dataset ;
+import org.apache.jena.query.DatasetFactory ;
+import org.apache.jena.sparql.algebra.Algebra ;
+import org.apache.jena.sparql.algebra.Op ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.engine.Plan ;
+import org.apache.jena.sparql.engine.PlanOp ;
+import org.apache.jena.sparql.engine.QueryIterator ;
+import org.apache.jena.sparql.util.QueryExecUtils ;
+
+import arq.cmdline.CmdARQ ;
+import arq.cmdline.ModAlgebra ;
+import arq.cmdline.ModDataset ;
+import arq.cmdline.ModDatasetGeneralAssembler ;
+import arq.cmdline.ModEngine ;
+import arq.cmdline.ModResultsOut ;
+import arq.cmdline.ModTime ;
+
+public class sse_query extends CmdARQ
+{
+ // Merging with qparse/sparql
+ // 1 - split those two into Query and QueryExecution parts
+ // 2 - This is then calls on the QueryExecution parts
+ // 3 - Printing plan - uses a verbose prefix setting. Scan to see what's in use.
+ // WriterOp.reducePrologue(prologue, op) => prologue.
+
+ protected final ArgDecl printDecl = new ArgDecl(ArgDecl.HasValue, "print") ;
+
+ ModAlgebra modAlgebra = new ModAlgebra() ;
+ ModDataset modDataset = new ModDatasetGeneralAssembler() ;
+ ModResultsOut modResults = new ModResultsOut() ;
+ ModTime modTime = new ModTime() ;
+ ModEngine modEngine = new ModEngine() ;
+
+ boolean printOp = false ;
+ boolean printPlan = false ;
+
+ public static void main (String... argv)
+ {
+ new sse_query(argv).mainRun() ;
+ }
+
+ public sse_query(String[] argv)
+ {
+ super(argv) ;
+ super.add(printDecl, "--print=op/plan", "Print details") ;
+ super.addModule(modAlgebra) ;
+ super.addModule(modResults) ;
+ super.addModule(modDataset) ;
+ super.addModule(modTime) ;
+ super.addModule(modEngine) ;
+ }
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ super.processModulesAndArgs() ;
+
+ for (String arg : getValues(printDecl))
+ {
+ if ( arg.equalsIgnoreCase("op") ||
+ arg.equalsIgnoreCase("alg") ||
+ arg.equalsIgnoreCase("algebra") ) { printOp = true ; }
+ else if ( arg.equalsIgnoreCase("plan")) { printPlan = true ; }
+ else
+ throw new CmdException("Not a recognized print form: "+arg+" : Choices are: query, op, quad") ;
+ }
+
+ }
+
+ @Override
+ protected String getCommandName() { return Lib.className(this) ; }
+
+ @Override
+ protected String getSummary() { return getCommandName()+" --data=<file> --query=<query>" ; }
+
+ static final String divider = "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" ;
+ //static final String divider = "" ;
+ boolean needDivider = false ;
+ private void divider()
+ {
+ if ( needDivider ) System.out.println(divider) ;
+ needDivider = true ;
+ }
+
+ @Override
+ protected void exec()
+ {
+ Op op = modAlgebra.getOp() ;
+
+ if ( op == null )
+ {
+ System.err.println("No query expression to execute") ;
+ throw new TerminationException(9) ;
+ }
+
+ Dataset dataset = modDataset.getDataset() ;
+ // Check there is a dataset.
+ if ( dataset == null )
+ dataset = DatasetFactory.createGeneral() ;
+
+ modTime.startTimer() ;
+ DatasetGraph dsg = dataset.asDatasetGraph() ;
+
+ if ( printOp || printPlan )
+ {
+ if ( printOp )
+ {
+ divider() ;
+ IndentedWriter out = new IndentedWriter(System.out, true) ;
+ op.output(out) ;
+ out.flush();
+ }
+
+ if ( printPlan )
+ {
+ QueryIterator qIter = Algebra.exec(op, dsg) ;
+ Plan plan = new PlanOp(op, null, qIter) ;
+ divider() ;
+ IndentedWriter out = new IndentedWriter(System.out, false) ;
+ plan.output(out) ;
+ out.flush();
+ }
+ //return ;
+ }
+
+ // Do not optimize. Execute as-is.
+ QueryExecUtils.execute(op, dsg, modResults.getResultsFormat()) ;
+
+ long time = modTime.endTimer() ;
+ if ( modTime.timingEnabled() )
+ System.out.println("Time: "+modTime.timeStr(time)) ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/tokens.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/tokens.java b/jena-cmds/src/main/java/arq/tokens.java
new file mode 100644
index 0000000..a7cbbd2
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/tokens.java
@@ -0,0 +1,24 @@
+/*
+ * 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 arq;
+
+public class tokens
+{
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/uparse.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/uparse.java b/jena-cmds/src/main/java/arq/uparse.java
new file mode 100644
index 0000000..83d44cb
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/uparse.java
@@ -0,0 +1,187 @@
+/*
+ * 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 arq;
+
+import java.io.IOException ;
+import java.util.List ;
+
+import jena.cmd.ArgDecl;
+import jena.cmd.CmdException;
+
+import org.apache.jena.atlas.io.IndentedLineBuffer ;
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.query.QueryParseException ;
+import org.apache.jena.query.Syntax ;
+import org.apache.jena.sparql.modify.request.UpdateWriter ;
+import org.apache.jena.update.UpdateFactory ;
+import org.apache.jena.update.UpdateRequest ;
+import org.apache.jena.util.FileUtils ;
+
+import arq.cmdline.CmdARQ ;
+
+public class uparse extends CmdARQ
+{
+ protected static final ArgDecl fileArg = new ArgDecl(ArgDecl.HasValue, "file", "update") ;
+ protected static final ArgDecl syntaxArg = new ArgDecl(ArgDecl.HasValue, "syntax", "syn") ;
+ protected static final ArgDecl argDeclPrint = new ArgDecl(ArgDecl.HasValue, "print") ;
+ List<String> requestFiles = null ;
+ protected Syntax updateSyntax = null ;
+ private boolean printUpdate = false ;
+ private boolean printNone = false ;
+
+ public static void main (String... argv)
+ { new uparse(argv).mainRun() ; }
+
+ protected uparse(String[] argv)
+ {
+ super(argv) ;
+ super.add(fileArg, "--file=FILE", "Update commands to parse") ;
+ super.add(syntaxArg, "--syntax=name", "Update syntax") ;
+ super.add(argDeclPrint, "--print", "Print in various forms [update, none]") ;
+ }
+
+ @Override
+ protected void processModulesAndArgs()
+ {
+ requestFiles = getValues(fileArg) ;
+ super.processModulesAndArgs() ;
+ if ( super.cmdStrictMode )
+ updateSyntax = Syntax.syntaxSPARQL_11 ;
+
+ // Set syntax
+ if ( super.contains(syntaxArg) ) {
+ // short name
+ String s = super.getValue(syntaxArg) ;
+ Syntax syn = Syntax.lookup(s) ;
+ if ( syn == null )
+ super.cmdError("Unrecognized syntax: " + s) ;
+ updateSyntax = syn ;
+ }
+
+ for ( String arg : getValues( argDeclPrint ) )
+ {
+ if ( arg.equalsIgnoreCase( "query" ) )
+ printUpdate = true;
+ else if ( arg.equalsIgnoreCase( "none" ) )
+ printNone = true;
+ else
+ throw new CmdException("Not a recognized print form: " + arg + " : Choices are: update, none" );
+ }
+
+ if ( !printUpdate && ! printNone )
+ printUpdate = true ;
+
+ }
+
+ @Override
+ protected String getCommandName() { return Lib.className(this) ; }
+
+ @Override
+ protected String getSummary() { return getCommandName()+" --file=<request file> | <update string>" ; }
+
+ @Override
+ protected void exec()
+ {
+ for ( String filename : requestFiles )
+ {
+ Syntax syntax = updateSyntax ;
+ if ( syntax == null )
+ syntax = Syntax.guessUpdateFileSyntax(filename) ;
+ String x = oneFile( filename );
+ if ( x != null )
+ execOne( x, syntax );
+ }
+
+
+
+
+ for ( String x : super.positionals ) {
+ Syntax syntax = updateSyntax ;
+ if ( matchesIndirect(x) ) {
+ if ( syntax == null )
+ syntax = Syntax.guessUpdateFileSyntax(x) ;
+ x = indirect( x );
+ }
+ if ( syntax == null )
+ syntax = Syntax.defaultUpdateSyntax ;
+ execOne( x, syntax );
+ }
+
+ }
+
+ private String oneFile(String filename)
+ {
+ divider() ;
+ try
+ {
+ return FileUtils.readWholeFileAsUTF8(filename) ;
+ } catch (IOException ex)
+ {
+ System.err.println("No such file: "+filename) ;
+ return null ;
+ }
+ }
+
+ private void execOne(String updateString, Syntax syntax)
+ {
+ UpdateRequest req ;
+ try {
+ req = UpdateFactory.create(updateString, syntax) ;
+ } catch (QueryParseException ex)
+ {
+ System.err.print("Parse error: ") ;
+ System.err.println(ex.getMessage()) ;
+ return ;
+ }
+ //req.output(IndentedWriter.stderr) ;
+ if ( printUpdate )
+ System.out.print(req) ;
+
+ if ( printNone )
+ return ;
+
+ // And some checking.
+ IndentedLineBuffer w = new IndentedLineBuffer() ;
+ UpdateWriter.output(req, w) ;
+ String updateString2 = w.asString() ;
+ UpdateRequest req2 = null ;
+ try {
+ req2 = UpdateFactory.create(updateString2, syntax) ;
+ } catch (QueryParseException ex)
+ {
+ System.err.println("Can not reparse update after serialization") ;
+ System.err.println(updateString2) ;
+ }
+
+ if ( ! req.equalTo(req2) )
+ System.err.println("Reparsed update does not .equalTo original parsed request") ;
+
+
+ }
+
+ static final String divider = "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" ;
+ //static final String divider = "" ;
+ static boolean needDivider = false ;
+ private static void divider()
+ {
+ if ( needDivider ) System.out.println(divider) ;
+ needDivider = true ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/update.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/update.java b/jena-cmds/src/main/java/arq/update.java
new file mode 100644
index 0000000..333d41a
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/update.java
@@ -0,0 +1,128 @@
+/*
+ * 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 arq;
+
+import java.util.List ;
+
+import jena.cmd.ArgDecl;
+import jena.cmd.CmdException;
+
+import org.apache.jena.atlas.lib.Lib ;
+import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFDataMgr ;
+import org.apache.jena.sparql.SystemARQ ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.DatasetGraphFactory ;
+import org.apache.jena.sparql.core.Transactional ;
+import org.apache.jena.sparql.core.TransactionalNull ;
+import org.apache.jena.update.UpdateExecutionFactory ;
+import org.apache.jena.update.UpdateFactory ;
+import org.apache.jena.update.UpdateRequest ;
+
+import arq.cmdline.CmdUpdate ;
+
+public class update extends CmdUpdate
+{
+ static final ArgDecl updateArg = new ArgDecl(ArgDecl.HasValue, "update", "file") ;
+ static final ArgDecl dumpArg = new ArgDecl(ArgDecl.NoValue, "dump") ; // Write the result to stdout.
+
+ List<String> requestFiles = null ;
+ boolean dump = false ;
+
+ public static void main (String... argv)
+ { new update(argv).mainRun() ; }
+
+ protected update(String[] argv) {
+ super(argv) ;
+ super.add(updateArg, "--update=FILE", "Update commands to execute") ;
+ super.add(dumpArg, "--dump", "Dump the resulting graph store") ;
+ }
+
+ @Override
+ protected void processModulesAndArgs() {
+ requestFiles = getValues(updateArg) ; // ????
+ dump = contains(dumpArg) ;
+ super.processModulesAndArgs() ;
+ }
+
+ @Override
+ protected String getCommandName() { return Lib.className(this) ; }
+
+ @Override
+ protected String getSummary() { return getCommandName()+" --desc=assembler [--dump] --update=<request file>" ; }
+
+ // Subclass for specialised commands making common updates more convenient
+ @Override
+ protected void execUpdate(DatasetGraph graphStore) {
+ if ( requestFiles.size() == 0 && getPositional().size() == 0 )
+ throw new CmdException("Nothing to do") ;
+
+ Transactional transactional = (graphStore instanceof Transactional) ? (Transactional)graphStore : new TransactionalNull() ;
+
+ for ( String filename : requestFiles ) {
+ try {
+ transactional.begin(ReadWrite.WRITE) ;
+ execOneFile(filename, graphStore) ;
+ transactional.commit() ;
+ }
+ catch (Throwable ex) {
+ try { transactional.abort() ; } catch (Exception ex2) {}
+ throw ex ;
+ }
+ finally { transactional.end() ; }
+ }
+
+ for ( String requestString : super.getPositional() ) {
+ requestString = indirect(requestString) ;
+
+ try {
+ transactional.begin(ReadWrite.WRITE) ;
+ execOne(requestString, graphStore) ;
+ transactional.commit() ;
+ }
+ catch (Throwable ex) {
+ try { transactional.abort() ; } catch (Exception ex2) {}
+ throw ex ;
+ }
+ finally { transactional.end() ; }
+ }
+
+ if ( ! (graphStore instanceof Transactional) )
+ SystemARQ.sync(graphStore) ;
+
+ if ( dump )
+ RDFDataMgr.write(System.out, graphStore, Lang.NQUADS) ;
+ }
+
+ private void execOneFile(String filename, DatasetGraph store) {
+ UpdateRequest req = UpdateFactory.read(filename, updateSyntax) ;
+ UpdateExecutionFactory.create(req, store).execute() ;
+ }
+
+ private void execOne(String requestString, DatasetGraph store) {
+ UpdateRequest req = UpdateFactory.create(requestString, updateSyntax) ;
+ UpdateExecutionFactory.create(req, store).execute() ;
+ }
+
+ @Override
+ protected DatasetGraph dealWithNoDataset() {
+ return DatasetGraphFactory.create() ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/utf8.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/utf8.java b/jena-cmds/src/main/java/arq/utf8.java
new file mode 100644
index 0000000..bc47569
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/utf8.java
@@ -0,0 +1,29 @@
+/*
+ * 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 arq;
+
+
+public class utf8
+{
+ /** Simple program to help hunt down bad UTF-8 encoded characters */
+ public static void main(String[] args)
+ {
+ riotcmd.utf8.main(args) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/version.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/version.java b/jena-cmds/src/main/java/arq/version.java
new file mode 100644
index 0000000..e55434c
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/version.java
@@ -0,0 +1,29 @@
+/*
+ * 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 arq;
+
+import jena.cmd.ModVersion;
+
+public class version
+{
+ public static void main (String... argv)
+ {
+ new ModVersion(false).printVersionAndExit() ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/wwwdec.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/wwwdec.java b/jena-cmds/src/main/java/arq/wwwdec.java
new file mode 100644
index 0000000..60a07c5
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/wwwdec.java
@@ -0,0 +1,36 @@
+/*
+ * 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 arq;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+
+public class wwwdec
+{
+ public static void main(String...args)
+ {
+ for ( String x : args)
+ {
+ String y = StrUtils.decodeHex(x, '%') ;
+ System.out.println(y) ;
+
+// String s2 = URLDecoder.decode(x, "utf-8") ;
+// System.out.println(s2) ;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/arq/wwwenc.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/arq/wwwenc.java b/jena-cmds/src/main/java/arq/wwwenc.java
new file mode 100644
index 0000000..4ee19af
--- /dev/null
+++ b/jena-cmds/src/main/java/arq/wwwenc.java
@@ -0,0 +1,61 @@
+/*
+ * 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 arq;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+
+public class wwwenc
+{
+ /* http://en.wikipedia.org/wiki/Percent-encoding
+ * Reserved characters after percent-encoding
+ * ! * " ' ( ) ; : @ & = + $ , / ? % # [ ]
+ * %21 %2A %22 %27 %28 %29 %3B %3A %40 %26 %3D %2B %24 %2C %2F %3F %25 %23 %5B %5D
+ * These loose any reserved meaning if encoded.
+ *
+ * Other common, but unreserved, characters after percent-encoding
+ * < > ~ . { } | \ - ` _ ^
+ * %3C %3E %7E %2E %7B %7D %7C %5C %2D %60 %5F %5E
+ *
+ * Unreserved characters treated equivalent to their unencoded form.
+ *
+ *
+ */
+ public static void main(String...args)
+ {
+ // Reserved characters + space
+ char reserved[] =
+ {' ',
+ '\n','\t',
+ '!', '*', '"', '\'', '(', ')', ';', ':', '@', '&',
+ '=', '+', '$', ',', '/', '?', '%', '#', '[', ']'} ;
+
+ char[] other = {'<', '>', '~', '.', '{', '}', '|', '\\', '-', '`', '_', '^'} ;
+
+ for ( String x : args)
+ {
+ // Not URLEncoder which does www-form-encoding.
+ String y = StrUtils.encodeHex(x, '%', reserved) ;
+ System.out.println(y) ;
+
+// String s2 = URLEncoder.encode(s, "utf-8") ;
+// System.out.println(s2) ;
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/RuleMap.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/RuleMap.java b/jena-cmds/src/main/java/jena/RuleMap.java
new file mode 100644
index 0000000..111f44b
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/RuleMap.java
@@ -0,0 +1,196 @@
+/*
+ * 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 jena;
+
+
+import static org.apache.jena.atlas.logging.LogCtl.setCmdLogging;
+
+import java.util.*;
+import java.io.*;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Options;
+import org.apache.jena.graph.* ;
+import org.apache.jena.rdf.model.* ;
+import org.apache.jena.reasoner.Reasoner ;
+import org.apache.jena.reasoner.rulesys.* ;
+import org.apache.jena.reasoner.rulesys.builtins.BaseBuiltin ;
+import org.apache.jena.util.FileManager ;
+import org.apache.jena.util.FileUtils ;
+
+/**
+ * General command line utility to process one RDF file into another
+ * by application of a set of forward chaining rules.
+ * <pre>
+ * Usage: RuleMap [-il inlang] [-ol outlang] [-d] rulefile infile
+ * </pre>
+ * The resulting RDF data is written to stdout in format <code>outlang</code>
+ * (default N3). If <code>-d</code> is given then only the deductions
+ * generated by the rules are output. Otherwise all data including any input
+ * data (other than any removed triples) is output.
+ * <p>
+ * Rules are permitted an additional action "deduce" which forces triples
+ * to be added to the deductions graph even if they are already known (for use
+ * in deductions only mode).
+ * </p>
+ */
+public class RuleMap {
+ static { setCmdLogging() ; }
+
+ /**
+ * Load a set of rule definitions including processing of
+ * comment lines and any initial prefix definition lines.
+ * Also notes the prefix definitions for adding to a later inf model.
+ */
+ public static List<Rule> loadRules(String filename, Map<String, String> prefixes) {
+ String fname = filename;
+ if (fname.startsWith("file:///")) {
+ fname = File.separator + fname.substring(8);
+ } else if (fname.startsWith("file:/")) {
+ fname = File.separator + fname.substring(6);
+ } else if (fname.startsWith("file:")) {
+ fname = fname.substring(5);
+ }
+
+ BufferedReader src = FileUtils.openResourceFile(fname);
+ return loadRules(src, prefixes);
+ }
+
+ /**
+ * Load a set of rule definitions including processing of
+ * comment lines and any initial prefix definition lines.
+ * Also notes the prefix definitions for adding to a later inf model.
+ */
+ public static List<Rule> loadRules(BufferedReader src, Map<String, String> prefixes) {
+ Rule.Parser parser = Rule.rulesParserFromReader(src);
+ List<Rule> rules = Rule.parseRules(parser);
+ prefixes.putAll(parser.getPrefixMap());
+ return rules;
+ }
+
+ /**
+ * Internal implementation of the "deduce" primitve.
+ * This takes the form <code> ... -> deduce(s, p, o)</code>
+ */
+ static class Deduce extends BaseBuiltin {
+
+ /**
+ * Return a name for this builtin, normally this will be the name of the
+ * functor that will be used to invoke it.
+ */
+ @Override
+ public String getName() {
+ return "deduce";
+ }
+
+ /**
+ * Return the expected number of arguments for this functor or 0 if the number is flexible.
+ */
+ @Override
+ public int getArgLength() {
+ return 3;
+ }
+
+ /**
+ * This method is invoked when the builtin is called in a rule head.
+ * Such a use is only valid in a forward rule.
+ * @param args the array of argument values for the builtin, this is an array
+ * of Nodes.
+ * @param length the length of the argument list, may be less than the length of the args array
+ * for some rule engines
+ * @param context an execution context giving access to other relevant data
+ */
+ @Override
+ public void headAction(Node[] args, int length, RuleContext context) {
+ if (context.getGraph() instanceof FBRuleInfGraph) {
+ Triple t = new Triple(args[0], args[1], args[2]);
+ ((FBRuleInfGraph)context.getGraph()).addDeduction(t);
+ } else {
+ throw new BuiltinException(this, context, "Only usable in FBrule graphs");
+ }
+ }
+ }
+
+ /**
+ * General command line utility to process one RDF file into another
+ * by application of a set of forward chaining rules.
+ * <pre>
+ * Usage: RuleMap [-il inlang] [-ol outlang] -d infile rulefile
+ * </pre>
+ */
+ public static void main(String[] args) {
+ try {
+
+ // Parse the command line
+ String usage = "Usage: RuleMap [-il inlang] [-ol outlang] [-d] rulefile infile (- for stdin)";
+ final CommandLineParser parser = new DefaultParser();
+ Options options = new Options().addOption("il", "inputLang", true, "input language")
+ .addOption("ol", "outputLang", true, "output language").addOption("d", "Deductions only?");
+ CommandLine cl = parser.parse(options, args);
+ final List<String> filenameArgs = cl.getArgList();
+ if (filenameArgs.size() != 2) {
+ System.err.println(usage);
+ System.exit(1);
+ }
+
+ String inLang = cl.getOptionValue("inputLang");
+ String fname = filenameArgs.get(1);
+ Model inModel = null;
+ if (fname.equals("-")) {
+ inModel = ModelFactory.createDefaultModel();
+ inModel.read(System.in, null, inLang);
+ } else {
+ inModel = FileManager.get().loadModel(fname, inLang);
+ }
+
+ String outLang = cl.hasOption("outputLang") ? cl.getOptionValue("outputLang") : "N3";
+
+ boolean deductionsOnly = cl.hasOption('d');
+
+ // Fetch the rule set and create the reasoner
+ BuiltinRegistry.theRegistry.register(new Deduce());
+ Map<String, String> prefixes = new HashMap<>();
+ List<Rule> rules = loadRules(filenameArgs.get(0), prefixes);
+ Reasoner reasoner = new GenericRuleReasoner(rules);
+
+ // Process
+ InfModel infModel = ModelFactory.createInfModel(reasoner, inModel);
+ infModel.prepare();
+ infModel.setNsPrefixes(prefixes);
+
+ // Output
+ try ( PrintWriter writer = new PrintWriter(System.out) ) {
+ if (deductionsOnly) {
+ Model deductions = infModel.getDeductionsModel();
+ deductions.setNsPrefixes(prefixes);
+ deductions.setNsPrefixes(inModel);
+ deductions.write(writer, outLang);
+ } else {
+ infModel.write(writer, outLang);
+ }
+ }
+ } catch (Throwable t) {
+ System.err.println("An error occured: \n" + t);
+ t.printStackTrace();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/Arg.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/Arg.java b/jena-cmds/src/main/java/jena/cmd/Arg.java
new file mode 100644
index 0000000..d7fb8c9
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/Arg.java
@@ -0,0 +1,69 @@
+/*
+ * 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 jena.cmd;
+
+import java.util.ArrayList ;
+import java.util.List ;
+
+public class Arg
+{
+ String name ;
+ String value ; // Last seen
+ List<String> values = new ArrayList<>() ; // All seen
+
+ Arg() { name = null ; value = null ; }
+
+ public Arg(String _name) { this() ; setName(_name) ; }
+
+ Arg(String _name, String _value) { this() ; setName(_name) ; setValue(_value) ; }
+
+ void setName(String n) { name = n ; }
+
+ public void setValue(String v) { value = v ; }
+ public void addValue(String v) { values.add(v) ; }
+
+ public String getName() { return name ; }
+ public String getValue() { return value; }
+ public List<String> getValues() { return values; }
+
+ public boolean hasValue() { return value != null ; }
+
+ public boolean matches(ArgDecl decl)
+ {
+ return decl.getNames().contains(name) ;
+ }
+
+ @Override
+ public String toString()
+ {
+ String base = (( name.length() == 1 )?"-":"--") + name ;
+ if ( getValues().size() == 0 )
+ return base ;
+
+ String str = "" ;
+ String sep = "" ;
+
+ for ( String v : getValues() )
+ {
+ str = str + sep + base + "=" + v;
+ sep = " ";
+ }
+ return str ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/ArgDecl.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/ArgDecl.java b/jena-cmds/src/main/java/jena/cmd/ArgDecl.java
new file mode 100644
index 0000000..c3781e2
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/ArgDecl.java
@@ -0,0 +1,93 @@
+/*
+ * 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 jena.cmd;
+
+import static java.util.Arrays.asList;
+
+import java.util.ArrayList ;
+import java.util.Iterator ;
+import java.util.List ;
+
+/** A command line argument specification. */
+public class ArgDecl
+{
+ boolean takesValue ;
+
+ List<String> names = new ArrayList<>() ;
+
+ public static final boolean HasValue = true ;
+ public static final boolean NoValue = false ;
+
+ /** Create a declaration for a command argument.
+ *
+ * @param hasValue Does it take a value or not?
+ */
+ public ArgDecl(boolean hasValue)
+ {
+ takesValue = hasValue ;
+ }
+
+ /** Create a declaration for a command argument.
+ *
+ * @param hasValue Does it take a value or not?
+ * @param names Names of arguments
+ */
+ public ArgDecl(boolean hasValue, String... names)
+ {
+ this(hasValue) ;
+ asList(names).forEach(this::addName);
+ }
+
+ public void addName(String name)
+ {
+ name = canonicalForm(name) ;
+ if ( ! names.contains(name))
+ names.add(name) ;
+ }
+
+ public String getKeyName() { return names.get(0) ; }
+
+ public List<String> getNames() { return names ; }
+ public Iterator<String> names() { return names.iterator() ; }
+
+ public boolean takesValue() { return takesValue ; }
+
+ public boolean matches(Arg a)
+ {
+ String name = a.getName();
+ return names.stream().anyMatch(name::equals);
+ }
+
+ public boolean matches(String arg)
+ {
+ arg = canonicalForm(arg) ;
+ return names.contains(arg) ;
+ }
+
+ public static String canonicalForm(String str)
+ {
+ if ( str.startsWith("--") )
+ return str.substring(2) ;
+
+ if ( str.startsWith("-") )
+ return str.substring(1) ;
+
+ return str ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/ArgModule.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/ArgModule.java b/jena-cmds/src/main/java/jena/cmd/ArgModule.java
new file mode 100644
index 0000000..82194de
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/ArgModule.java
@@ -0,0 +1,26 @@
+/**
+ * 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 jena.cmd;
+
+public interface ArgModule
+{
+ // Argument processing phase
+ public void processArgs(CmdArgModule cmdLine) ;
+}
+
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/ArgModuleGeneral.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/ArgModuleGeneral.java b/jena-cmds/src/main/java/jena/cmd/ArgModuleGeneral.java
new file mode 100644
index 0000000..d6f09fa
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/ArgModuleGeneral.java
@@ -0,0 +1,25 @@
+/*
+ * 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 jena.cmd;
+
+public interface ArgModuleGeneral extends ArgModule
+{
+ // Registration phase for usage messages
+ public abstract void registerWith(CmdGeneral cmdLine) ;
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/ArgProc.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/ArgProc.java b/jena-cmds/src/main/java/jena/cmd/ArgProc.java
new file mode 100644
index 0000000..51989e7
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/ArgProc.java
@@ -0,0 +1,27 @@
+/*
+ * 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 jena.cmd;
+
+
+public interface ArgProc {
+
+ void startArgs() ;
+ void finishArgs() ;
+ void arg(String arg, int i) ;
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/CmdArgModule.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/CmdArgModule.java b/jena-cmds/src/main/java/jena/cmd/CmdArgModule.java
new file mode 100644
index 0000000..c3279dc
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/CmdArgModule.java
@@ -0,0 +1,70 @@
+/*
+ * 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 jena.cmd;
+
+import java.util.ArrayList ;
+import java.util.List ;
+
+import jena.cmd.ArgModuleGeneral;
+
+public abstract class CmdArgModule extends CmdMain
+{
+ List<ArgModuleGeneral> modules = new ArrayList<>() ;
+
+ protected CmdArgModule(String[] argv)
+ {
+ super(argv) ;
+ }
+
+ protected void addModule(ArgModuleGeneral argModule)
+ {
+ modules.add(argModule) ;
+ }
+
+ @Override
+ final
+ public void process()
+ {
+ super.process() ;
+ forEach(new Action(){
+ @Override
+ public void action(CmdArgModule controller, ArgModuleGeneral module)
+ {
+ module.processArgs(controller) ;
+ }
+ } ) ;
+ processModulesAndArgs() ;
+ }
+
+ abstract
+ protected void processModulesAndArgs() ;
+
+ private void forEach(Action action)
+ {
+ for ( ArgModuleGeneral am : modules )
+ {
+ action.action( this, am );
+ }
+ }
+
+ interface Action
+ {
+ public void action(CmdArgModule controller, ArgModuleGeneral module) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/498b2264/jena-cmds/src/main/java/jena/cmd/CmdException.java
----------------------------------------------------------------------
diff --git a/jena-cmds/src/main/java/jena/cmd/CmdException.java b/jena-cmds/src/main/java/jena/cmd/CmdException.java
new file mode 100644
index 0000000..df952af
--- /dev/null
+++ b/jena-cmds/src/main/java/jena/cmd/CmdException.java
@@ -0,0 +1,30 @@
+/*
+ * 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 jena.cmd;
+
+/**
+ * Indicate that something went wrong - while executing the command or processing the request.
+ */
+
+public class CmdException extends RuntimeException
+{
+ public CmdException() { super() ; }
+ public CmdException(String msg) { super(msg) ; }
+ public CmdException(String msg, Throwable cause) { super(msg, cause) ; }
+}