[GitHub] jena pull request #449: JENA-1578

2018-08-05 Thread asfgit
Github user asfgit closed the pull request at:

https://github.com/apache/jena/pull/449


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread GregAlbiston
Github user GregAlbiston commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207253365
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
--- End diff --

'setGroupedValues' now renamed to 'setRowValues'. Replaced 'group' with 
'row' and 'varName' with 'valueName'.


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread GregAlbiston
Github user GregAlbiston commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207253012
  
--- Diff: 
jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java 
---
@@ -1925,4 +1926,190 @@ public void test_param_string_bug_04() {
 
 pss.toString();
 }
+
+@Test
+public void test_set_values_item() {
+// Tests a single value being added.
+String str = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+pss.setValues("objs", ResourceFactory.createPlainLiteral("test"));
+
+String exp = "SELECT * WHERE { VALUES ?o {\"test\"} ?s ?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_items() {
+// Tests two values for same variable.
+String str = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+pss.setValues("objs", objs);
+
+String exp = "SELECT * WHERE { VALUES ?o {\"obj_A\" \"obj_B\"} ?s 
?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_items_parenthesis() {
+// Tests two values for same variable.
+String str = "SELECT * WHERE { VALUES (?o) {?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+pss.setValues("objs", objs);
+
+String exp = "SELECT * WHERE { VALUES (?o) {(\"obj_A\") 
(\"obj_B\")} ?s ?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_multiple_variables_parenthesis() {
+// Tests two values for same variable.
+String str = "SELECT * WHERE { VALUES (?p ?o) {?vars} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List vars = new ArrayList<>();
+
vars.add(ResourceFactory.createProperty("http://example.org/prop_A";));
+vars.add(ResourceFactory.createPlainLiteral("obj_A"));
+pss.setValues("vars", vars);
+
+String exp = "SELECT * WHERE { VALUES (?p ?o) 
{( \"obj_A\")} ?s ?p ?o }";
+String res = pss.toString();
+System.out.println("Exp: " + exp);
+System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_multi_var() {
+// Tests two variables.
+String str = "SELECT * WHERE { VALUES ?p {?props} VALUES ?o 
{?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+pss.setValues("objs", objs);
+
+List props = new ArrayList<>();
+
props.add(ResourceFactory.createProperty("http://example.org/prop_A";));
+
props.add(ResourceFactory.createProperty("http://example.org/prop_B";));
+pss.setValues("props", props);
+
+String exp = "SELECT * WHERE { VALUES ?p 
{ } VALUES ?o {\"obj_A\" 
\"obj_B\"} ?s ?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_multi_var_parenthesis() {
+// Tests two variables with parenthesis for one.
+String str = "SELECT * WHERE { VALUES (?p) {?props} VALUES ?o 
{?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.crea

[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread GregAlbiston
Github user GregAlbiston commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207249056
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
+groupedItems.forEach(collection -> collection.forEach(item -> 
validateParameterValue(item.asNode(;
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
groupedItems, true));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+private static final String VALUES_KEYWORD = "values";
+
+protected static String[] extractTargetVars(String command, String 
varName) {
+String[] targetVars;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int bracesIndex = subCmd.lastIndexOf("{");
+String vars = command.substring(valuesIndex + 
VALUES_KEYWORD.length(), bracesIndex);
--- End diff --

Additional checking has been added to catch missing `VALUES` or braces. The 
query will be unchanged if these or the valueName are missing. The existing 
design is that syntax errors are caught by the `Query` or `UpdateRequest` stage.


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread GregAlbiston
Github user GregAlbiston commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207248259
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
+groupedItems.forEach(collection -> collection.forEach(item -> 
validateParameterValue(item.asNode(;
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
groupedItems, true));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+private static final String VALUES_KEYWORD = "values";
+
+protected static String[] extractTargetVars(String command, String 
varName) {
+String[] targetVars;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int bracesIndex = subCmd.lastIndexOf("{");
+String vars = command.substring(valuesIndex + 
VALUES_KEYWORD.length(), bracesIndex);
+targetVars = vars.replaceAll("[(?)]", "").trim().split(" ");
+} else {
+targetVars = new String[]{};
+}
+return targetVars;
+}
+
+protected static boolean checkParenthesis(String command, String 
varName) {
--- End diff --

Parenthesis are now always applied.


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread GregAlbiston
Github user GregAlbiston commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207248104
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
+groupedItems.forEach(collection -> collection.forEach(item -> 
validateParameterValue(item.asNode(;
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
groupedItems, true));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+private static final String VALUES_KEYWORD = "values";
+
+protected static String[] extractTargetVars(String command, String 
varName) {
+String[] targetVars;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int bracesIndex = subCmd.lastIndexOf("{");
+String vars = command.substring(valuesIndex + 
VALUES_KEYWORD.length(), bracesIndex);
+targetVars = vars.replaceAll("[(?)]", "").trim().split(" ");
+} else {
+targetVars = new String[]{};
+}
+return targetVars;
+}
+
+protected static boolean checkParenthesis(String command, String 
varName) {
+boolean isNeeded;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int parenthesisIndex = subCmd.indexOf("(", valuesIndex + 
VALUES_KEYWORD.length());
+isNeeded = parenthesisIndex > -1;
+} else {
+isNeeded = false;
+}
+return isNeeded;
+}
+
+/**
+ * Performs replacement of VALUES in query string.
+ *
+ */
+private class ValueReplacement {
+
+private final String varName;
+private final Collection items;
+private final Collection> groupedItems;
+private final Boolean isGrouped;
+
+public ValueReplacement(String varName, Collection items) 

[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread GregAlbiston
Github user GregAlbiston commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207245515
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
--- End diff --

The `items` are now placed into a `List` if not already.


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207151396
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
+groupedItems.forEach(collection -> collection.forEach(item -> 
validateParameterValue(item.asNode(;
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
groupedItems, true));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+private static final String VALUES_KEYWORD = "values";
+
+protected static String[] extractTargetVars(String command, String 
varName) {
+String[] targetVars;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int bracesIndex = subCmd.lastIndexOf("{");
+String vars = command.substring(valuesIndex + 
VALUES_KEYWORD.length(), bracesIndex);
+targetVars = vars.replaceAll("[(?)]", "").trim().split(" ");
+} else {
+targetVars = new String[]{};
+}
+return targetVars;
+}
+
+protected static boolean checkParenthesis(String command, String 
varName) {
+boolean isNeeded;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int parenthesisIndex = subCmd.indexOf("(", valuesIndex + 
VALUES_KEYWORD.length());
+isNeeded = parenthesisIndex > -1;
+} else {
+isNeeded = false;
+}
+return isNeeded;
+}
+
+/**
+ * Performs replacement of VALUES in query string.
+ *
+ */
+private class ValueReplacement {
+
+private final String varName;
+private final Collection items;
+private final Collection> groupedItems;
+private final Boolean isGrouped;
+
+public ValueReplacement(String varName, Collection items) {

[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207152306
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
--- End diff --

Later code requires that `items` be a `List` so this code should either 
enforce it here or otherwise sanitise `items` into a `List` at this point


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207148170
  
--- Diff: 
jena-arq/src/test/java/org/apache/jena/query/TestParameterizedSparqlString.java 
---
@@ -1925,4 +1926,190 @@ public void test_param_string_bug_04() {
 
 pss.toString();
 }
+
+@Test
+public void test_set_values_item() {
+// Tests a single value being added.
+String str = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+pss.setValues("objs", ResourceFactory.createPlainLiteral("test"));
+
+String exp = "SELECT * WHERE { VALUES ?o {\"test\"} ?s ?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_items() {
+// Tests two values for same variable.
+String str = "SELECT * WHERE { VALUES ?o {?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+pss.setValues("objs", objs);
+
+String exp = "SELECT * WHERE { VALUES ?o {\"obj_A\" \"obj_B\"} ?s 
?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_items_parenthesis() {
+// Tests two values for same variable.
+String str = "SELECT * WHERE { VALUES (?o) {?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+pss.setValues("objs", objs);
+
+String exp = "SELECT * WHERE { VALUES (?o) {(\"obj_A\") 
(\"obj_B\")} ?s ?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_multiple_variables_parenthesis() {
+// Tests two values for same variable.
+String str = "SELECT * WHERE { VALUES (?p ?o) {?vars} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List vars = new ArrayList<>();
+
vars.add(ResourceFactory.createProperty("http://example.org/prop_A";));
+vars.add(ResourceFactory.createPlainLiteral("obj_A"));
+pss.setValues("vars", vars);
+
+String exp = "SELECT * WHERE { VALUES (?p ?o) 
{( \"obj_A\")} ?s ?p ?o }";
+String res = pss.toString();
+System.out.println("Exp: " + exp);
+System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_multi_var() {
+// Tests two variables.
+String str = "SELECT * WHERE { VALUES ?p {?props} VALUES ?o 
{?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlainLiteral("obj_A"));
+objs.add(ResourceFactory.createPlainLiteral("obj_B"));
+pss.setValues("objs", objs);
+
+List props = new ArrayList<>();
+
props.add(ResourceFactory.createProperty("http://example.org/prop_A";));
+
props.add(ResourceFactory.createProperty("http://example.org/prop_B";));
+pss.setValues("props", props);
+
+String exp = "SELECT * WHERE { VALUES ?p 
{ } VALUES ?o {\"obj_A\" 
\"obj_B\"} ?s ?p ?o }";
+String res = pss.toString();
+//System.out.println("Exp: " + exp);
+//System.out.println("Res: " + res);
+Assert.assertEquals(exp, res);
+}
+
+@Test
+public void test_set_values_multi_var_parenthesis() {
+// Tests two variables with parenthesis for one.
+String str = "SELECT * WHERE { VALUES (?p) {?props} VALUES ?o 
{?objs} ?s ?p ?o }";
+ParameterizedSparqlString pss = new ParameterizedSparqlString(str);
+List objs = new ArrayList<>();
+objs.add(ResourceFactory.createPlai

[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207150857
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
+groupedItems.forEach(collection -> collection.forEach(item -> 
validateParameterValue(item.asNode(;
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
groupedItems, true));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+private static final String VALUES_KEYWORD = "values";
+
+protected static String[] extractTargetVars(String command, String 
varName) {
+String[] targetVars;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int bracesIndex = subCmd.lastIndexOf("{");
+String vars = command.substring(valuesIndex + 
VALUES_KEYWORD.length(), bracesIndex);
+targetVars = vars.replaceAll("[(?)]", "").trim().split(" ");
+} else {
+targetVars = new String[]{};
+}
+return targetVars;
+}
+
+protected static boolean checkParenthesis(String command, String 
varName) {
--- End diff --

Per @afs's comments it might be simpler to just always include the 
parenthesis since the un-paranthesised form is simply a shortcut for the single 
variable case


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207147377
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
--- End diff --

I wonder if these should be named `setRowValues()` since you are 
effectively substituting several rows of data and that terminology more closely 
matches how the SPARQL spec and Jena algebra treats VALUES


---


[GitHub] jena pull request #449: JENA-1578

2018-08-02 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r207150287
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,250 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a VALUES varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ * Using "var" with list(prop_A, obj_A) on query "VALUES (?p ?o) 
{?var}"
+ * would produce "VALUES (?p ?o) {(prop_A obj_A)}".
+ *
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+items.forEach(item -> validateParameterValue(item.asNode()));
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+/**
+ * Assign a VALUES varName with a single item.
+ * Using "var" with Literal obj_A on query "VALUES ?o {?var}" would 
produce
+ * "VALUES ?o {obj_A}".
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item));
+}
+
+/**
+ * **
+ * Sets a map of VALUES varNames and their items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param itemsMap
+ */
+public void setValues(Map> 
itemsMap) {
+itemsMap.forEach(this::setValues);
+}
+
+/**
+ * Allocate multiple lists of variables to a single VALUES varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param groupedItems
+ */
+public void setGroupedValues(String varName, Collection> groupedItems) {
+groupedItems.forEach(collection -> collection.forEach(item -> 
validateParameterValue(item.asNode(;
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
groupedItems, true));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+private static final String VALUES_KEYWORD = "values";
+
+protected static String[] extractTargetVars(String command, String 
varName) {
+String[] targetVars;
+
+int varIndex = command.indexOf(varName);
+if (varIndex > -1) {
+String subCmd = command.substring(0, varIndex).toLowerCase(); 
//Truncate the command at the varName. Lowercase to search both types of values.
+int valuesIndex = subCmd.lastIndexOf(VALUES_KEYWORD);
+int bracesIndex = subCmd.lastIndexOf("{");
+String vars = command.substring(valuesIndex + 
VALUES_KEYWORD.length(), bracesIndex);
--- End diff --

Per my comments on test cases, does this potentially find too much if the 
query string never contains `VALUES` or the query is otherwise syntactically 
malformed e.g. missing braces?


---


[GitHub] jena pull request #449: JENA-1578

2018-07-30 Thread rvesse
Github user rvesse commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r206083636
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,237 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a varName with a multiple items and whether to include
+ * parenthesis.
+ *
+ * @param varName
+ * @param items
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, Collection 
items, boolean isParenthesisNeeded) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items, isParenthesisNeeded));
+}
+
+/**
+ * Assign a varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+setValues(varName, items, false);
+}
+
+/**
+ * Assign a varName with a single item and whether to include 
parenthesis.
+ *
+ * @param varName
+ * @param item
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, RDFNode item, boolean 
isParenthesisNeeded) {
--- End diff --

I will take a proper look at this tomorrow.

My first reaction though is that I am a little worried that we would expose 
to the user (even if they are a developer in this scenario) the decision as to 
whether parenthesis are needed both from a security (SPARQL injection) and a 
validity perspective.  The code should be able to determine this based upon how 
many variables are being inserted and do the right thing.


---


[GitHub] jena pull request #449: JENA-1578

2018-07-28 Thread afs
Github user afs commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r205953487
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,237 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a varName with a multiple items and whether to include
+ * parenthesis.
+ *
+ * @param varName
+ * @param items
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, Collection 
items, boolean isParenthesisNeeded) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items, isParenthesisNeeded));
+}
+
+/**
+ * Assign a varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+setValues(varName, items, false);
+}
+
+/**
+ * Assign a varName with a single item and whether to include 
parenthesis.
+ *
+ * @param varName
+ * @param item
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, RDFNode item, boolean 
isParenthesisNeeded) {
+setValues(varName, Arrays.asList(item), isParenthesisNeeded);
+}
+
+/**
+ * Assign a varName with a single item.
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item), false);
+}
+
+/**
+ * Sets a map of varNames and their items.
+ *
+ * @param valuesItems
+ */
+public void setValues(Map> 
valuesItems) {
+valuesItems.forEach(this::setValues);
+}
+
+/**
+ * All varNames in the map will use the same approach to parenthesis.
+ *
+ * @param valuesItems
+ * @param isParenthesisNeeded
+ */
+public void setValues(Map> 
valuesItems, Boolean isParenthesisNeeded) {
+valuesItems.forEach((varName, items) -> setValues(varName, items, 
isParenthesisNeeded));
+}
+
+/**
+ * Combine a map of varNames and items with whether to include 
parenthesis.
+ * Missing varNames in the parenthesis map will default to false.
+ *
+ * @param valuesItems
+ * @param valuesParenthesis
+ */
+public void setValues(Map> 
valuesItems, Map valuesParenthesis) {
+
+for (String varName : valuesItems.keySet()) {
+Collection items = valuesItems.get(varName);
+Boolean isParenthesisNeeded;
+if (valuesParenthesis.containsKey(varName)) {
+isParenthesisNeeded = valuesParenthesis.get(varName);
+} else {
+isParenthesisNeeded = false;
+}
+
+setValues(varName, items, isParenthesisNeeded);
+}
+}
+
+/**
+ * Allocate multiple lists of variables to a single varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param items
+ */
+public void setGroupedValues(String varName, Collection> items) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+/**
+ * Performs replacement of VALUES in query string.
+ *
+ */
+private class ValueReplacement {
+
+private final String varName;
+private final Collection items;
+private final Collection> groupedItems;
+private final Boolean isParenthesisNeeded;
+private final Boolean isGrouped;
+
+public ValueReplacement(String varName, Collection items, Boolean isParenthesisNeeded) {
+this.varName = varName;
+this.items = items;
+this.groupedItems = new ArrayList<>();
+this.isParenthesisNeeded = isParenthesisNeeded;
+this.isGrouped = false;
+

[GitHub] jena pull request #449: JENA-1578

2018-07-28 Thread afs
Github user afs commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r205953412
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1739,237 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a varName with a multiple items and whether to include
+ * parenthesis.
+ *
+ * @param varName
+ * @param items
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, Collection 
items, boolean isParenthesisNeeded) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items, isParenthesisNeeded));
+}
+
+/**
+ * Assign a varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+setValues(varName, items, false);
+}
+
+/**
+ * Assign a varName with a single item and whether to include 
parenthesis.
+ *
+ * @param varName
+ * @param item
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, RDFNode item, boolean 
isParenthesisNeeded) {
+setValues(varName, Arrays.asList(item), isParenthesisNeeded);
+}
+
+/**
+ * Assign a varName with a single item.
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item), false);
+}
+
+/**
+ * Sets a map of varNames and their items.
+ *
+ * @param valuesItems
+ */
+public void setValues(Map> 
valuesItems) {
+valuesItems.forEach(this::setValues);
+}
+
+/**
+ * All varNames in the map will use the same approach to parenthesis.
+ *
+ * @param valuesItems
+ * @param isParenthesisNeeded
+ */
+public void setValues(Map> 
valuesItems, Boolean isParenthesisNeeded) {
+valuesItems.forEach((varName, items) -> setValues(varName, items, 
isParenthesisNeeded));
+}
+
+/**
+ * Combine a map of varNames and items with whether to include 
parenthesis.
+ * Missing varNames in the parenthesis map will default to false.
+ *
+ * @param valuesItems
+ * @param valuesParenthesis
+ */
+public void setValues(Map> 
valuesItems, Map valuesParenthesis) {
+
+for (String varName : valuesItems.keySet()) {
+Collection items = valuesItems.get(varName);
+Boolean isParenthesisNeeded;
+if (valuesParenthesis.containsKey(varName)) {
+isParenthesisNeeded = valuesParenthesis.get(varName);
+} else {
+isParenthesisNeeded = false;
+}
+
+setValues(varName, items, isParenthesisNeeded);
+}
+}
+
+/**
+ * Allocate multiple lists of variables to a single varName.
+ * Using "vars" with list(list(prop_A, obj_A), list(prop_B, obj_B)) on 
query
+ * "VALUES (?p ?o) {?vars}" would produce "VALUES (?p ?o) {(prop_A 
obj_A)
+ * (prop_B obj_B)}".
+ *
+ * @param varName
+ * @param items
+ */
+public void setGroupedValues(String varName, Collection> items) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items));
+}
+
+private String applyValues(String command) {
+
+for (ValueReplacement valueReplacement : 
valuesReplacements.values()) {
+command = valueReplacement.apply(command);
+}
+return command;
+}
+
+/**
+ * Performs replacement of VALUES in query string.
+ *
+ */
+private class ValueReplacement {
+
+private final String varName;
+private final Collection items;
+private final Collection> groupedItems;
+private final Boolean isParenthesisNeeded;
+private final Boolean isGrouped;
+
+public ValueReplacement(String varName, Collection items, Boolean isParenthesisNeeded) {
+this.varName = varName;
+this.items = items;
+this.groupedItems = new ArrayList<>();
+this.isParenthesisNeeded = isParenthesisNeeded;
+this.isGrouped = false;
+

[GitHub] jena pull request #449: JENA-1578

2018-07-27 Thread ajs6f
Github user ajs6f commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r205813086
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1740,243 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a varName with a multiple items and whether to include
+ * parenthesis.
+ *
+ * @param varName
+ * @param items
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, Collection 
items, boolean isParenthesisNeeded) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items, isParenthesisNeeded));
+}
+
+/**
+ * Assign a varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+setValues(varName, items, false);
+}
+
+/**
+ * Assign a varName with a single item and whether to include 
parenthesis.
+ *
+ * @param varName
+ * @param item
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, RDFNode item, boolean 
isParenthesisNeeded) {
+setValues(varName, Arrays.asList(item), isParenthesisNeeded);
+}
+
+/**
+ * Assign a varName with a single item.
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item), false);
+}
+
+/**
+ * Sets a map of varNames and their items.
+ *
+ * @param valuesItems
+ */
+public void setValues(Map> 
valuesItems) {
+for (String varName : valuesItems.keySet()) {
--- End diff --

Just a style thing, really, but I believe this method could be just 
`valuesItems.forEach(this::setValues)`.


---


[GitHub] jena pull request #449: JENA-1578

2018-07-27 Thread ajs6f
Github user ajs6f commented on a diff in the pull request:

https://github.com/apache/jena/pull/449#discussion_r205813451
  
--- Diff: 
jena-arq/src/main/java/org/apache/jena/query/ParameterizedSparqlString.java ---
@@ -1734,4 +1740,243 @@ public String toString() {
 }
 
 }
+
+/**
+ * Assign a varName with a multiple items and whether to include
+ * parenthesis.
+ *
+ * @param varName
+ * @param items
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, Collection 
items, boolean isParenthesisNeeded) {
+this.valuesReplacements.put(varName, new ValueReplacement(varName, 
items, isParenthesisNeeded));
+}
+
+/**
+ * Assign a varName with a multiple items.
+ * Can be used to assign multiple values to a single variable or single
+ * value to multiple variables (if using a List) in the SPARQL 
query.
+ * See setGroupedValues to assign multiple values to multiple 
variables.
+ *
+ * @param varName
+ * @param items
+ */
+public void setValues(String varName, Collection 
items) {
+setValues(varName, items, false);
+}
+
+/**
+ * Assign a varName with a single item and whether to include 
parenthesis.
+ *
+ * @param varName
+ * @param item
+ * @param isParenthesisNeeded
+ */
+public void setValues(String varName, RDFNode item, boolean 
isParenthesisNeeded) {
+setValues(varName, Arrays.asList(item), isParenthesisNeeded);
+}
+
+/**
+ * Assign a varName with a single item.
+ *
+ * @param varName
+ * @param item
+ */
+public void setValues(String varName, RDFNode item) {
+setValues(varName, Arrays.asList(item), false);
+}
+
+/**
+ * Sets a map of varNames and their items.
+ *
+ * @param valuesItems
+ */
+public void setValues(Map> 
valuesItems) {
+for (String varName : valuesItems.keySet()) {
+Collection items = valuesItems.get(varName);
+setValues(varName, items);
+}
+}
+
+/**
+ * All varNames in the map will use the same approach to parenthesis.
+ *
+ * @param valuesItems
+ * @param isParenthesisNeeded
+ */
+public void setValues(Map> 
valuesItems, Boolean isParenthesisNeeded) {
+for (String varName : valuesItems.keySet()) {
+Collection items = valuesItems.get(varName);
+setValues(varName, items, isParenthesisNeeded);
--- End diff --

Similarly, `valuesItems.forEach((varName, item)->setValues(varName, items, 
isParenthesisNeeded))`, and the same below.


---


[GitHub] jena pull request #449: JENA-1578

2018-07-27 Thread GregAlbiston
GitHub user GregAlbiston opened a pull request:

https://github.com/apache/jena/pull/449

JENA-1578

- Subclass ValueReplacement and methods added to allow substitution of 
varNames with collections of RDFNodes. This is used in SPARQL queries to 
provide inline data with the VALUES keyword.
- Supports multiple values for a single variable, sets of values for 
multiple variables and multiple sets of values for multiple values.
- Optional inclusion of parenthesis for the first two cases.
- Tests included for use cases.

You can merge this pull request into a Git repository by running:

$ git pull https://github.com/GregAlbiston/jena query-value-replacement

Alternatively you can review and apply these changes as the patch at:

https://github.com/apache/jena/pull/449.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

This closes #449


commit 27695b93b7454b3948cc623cff788a18942a66e2
Author: Greg Albiston 
Date:   2018-07-27T14:05:52Z

ARQ:Query:ParameterizedSparqlString
- Subclass ValueReplacement and methods added to allow substitution of 
varNames with collections of RDFNodes. This is used in SPARQL queries to 
provide inline data with the VALUES keyword.
- Tests included for use cases.




---