Skip to content

Commit 49449c5

Browse files
author
Horia Chiorean
committed
Merge pull request #1548 from hchiorean/MODE-2594
MODE-2594 Adds better query handling by the REST service for multi-valued properties
2 parents 1ef0ab9 + e00ceaa commit 49449c5

File tree

4 files changed

+81
-7
lines changed

4 files changed

+81
-7
lines changed

web/modeshape-web-jcr-rest-war/src/test/java/org/modeshape/web/jcr/rest/ModeShapeRestServiceTest.java

+15
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,21 @@ public void shouldPerformRepositoryRestore() throws Exception {
874874
FileUtil.delete(new File(new URI(backupURL)));
875875
}
876876

877+
878+
@Test
879+
@FixFor( "MODE-2594" )
880+
public void shouldReturnAllValuesWhenQueryingMultiValuedProperty() throws Exception {
881+
doPost("post/node_multivalue_prop_request.json", itemsUrl(TEST_NODE)).isCreated();
882+
String query = "SELECT property FROM [nt:unstructured] WHERE [jcr:path] = '/" + TEST_NODE + "'";
883+
JSONObject result = jcrSQL2Query(query, queryUrl()).isOk().json();
884+
JSONArray rows = result.getJSONArray("rows");
885+
assertEquals(1, rows.length());
886+
JSONObject row = rows.getJSONObject(0);
887+
JSONArray values = row.getJSONArray("property");
888+
assertEquals("[\"value1\",\"value2\",\"value3\"]", values.toString());
889+
}
890+
891+
877892
private void assertUpload( String url,
878893
boolean expectCreated,
879894
boolean useMultiPart ) throws Exception {
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"jcr:primaryType":"nt:unstructured",
3-
"property":["value1"]
3+
"property":["value1", "value2", "value3"]
44
}

web/modeshape-web-jcr-rest/src/main/java/org/modeshape/web/jcr/rest/handler/RestQueryHandler.java

+51-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
import java.util.Iterator;
2222
import java.util.List;
2323
import java.util.Map;
24+
import java.util.function.Function;
25+
import java.util.stream.Collectors;
2426
import javax.jcr.Node;
27+
import javax.jcr.PathNotFoundException;
2528
import javax.jcr.Property;
2629
import javax.jcr.PropertyIterator;
2730
import javax.jcr.PropertyType;
@@ -194,8 +197,55 @@ private RestQueryResult.RestRow createRestRow( Session session,
194197
Row resultRow ) throws RepositoryException {
195198
RestQueryResult.RestRow restRow = restQueryResult.new RestRow();
196199
Map<Value, String> binaryPropertyPaths = null;
197-
200+
Map<String, Node> nodesBySelectorName = null;
201+
Node defaultNode = null;
202+
String defaultSelectorName = null;
203+
try {
204+
defaultNode = resultRow.getNode();
205+
defaultSelectorName = result.getSelectorNames()[0];
206+
} catch (RepositoryException e) {
207+
// there are multiple selectors....
208+
nodesBySelectorName = Arrays.stream(result.getSelectorNames())
209+
.collect(Collectors.toMap(Function.identity(), selectorName -> {
210+
try {
211+
return resultRow.getNode(selectorName);
212+
} catch (RepositoryException re) {
213+
throw new RuntimeException(re);
214+
}
215+
}));
216+
}
217+
198218
for (String columnName : columnNames) {
219+
Node activeNode = defaultNode;
220+
String activeSelectorName = defaultSelectorName;
221+
if (defaultNode == null) {
222+
// there are multiple selectors so we must see which one refers to the current column...
223+
assert nodesBySelectorName != null;
224+
for (Map.Entry<String, Node> nodeBySelector : nodesBySelectorName.entrySet()) {
225+
String selectorName = nodeBySelector.getKey();
226+
if (columnName.startsWith(selectorName)) {
227+
activeNode = nodeBySelector.getValue();
228+
activeSelectorName = selectorName;
229+
break;
230+
}
231+
}
232+
}
233+
234+
if (activeNode != null) {
235+
// the column name by default has the [selectorName].[propertyName] format...
236+
String propertyName = columnName.replaceFirst(activeSelectorName + "\\.", "");
237+
Property property = null;
238+
try {
239+
// try to locate the actual property based on the column name
240+
property = activeNode.getProperty(propertyName);
241+
List<String> values = restPropertyValues(property, baseUrl, session);
242+
restRow.addValue(columnName, values.size() == 1 ? values.get(0) : values);
243+
continue;
244+
} catch (PathNotFoundException e) {
245+
// we didn't locate the actual node property, so just read the value from the result row
246+
}
247+
}
248+
199249
Value value = resultRow.getValue(columnName);
200250
if (value == null) {
201251
continue;

web/modeshape-web-jcr-rest/src/main/java/org/modeshape/web/jcr/rest/model/RestQueryResult.java

+14-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.modeshape.web.jcr.rest.model;
1818

1919
import java.util.ArrayList;
20+
import java.util.Collection;
2021
import java.util.LinkedHashMap;
2122
import java.util.List;
2223
import java.util.Map;
@@ -85,16 +86,24 @@ public JSONObject toJSON() throws JSONException {
8586
}
8687

8788
public class RestRow implements JSONAble {
88-
private final Map<String, String> values;
89+
private final Map<String, Object> values;
8990

9091
public RestRow() {
91-
this.values = new LinkedHashMap<String, String>();
92+
this.values = new LinkedHashMap<>();
9293
}
9394

94-
public void addValue( String name,
95-
String value ) {
96-
if (!StringUtil.isBlank(name) && !StringUtil.isBlank(value)) {
95+
public void addValue(String name,
96+
Object value) {
97+
if (value == null || StringUtil.isBlank(name)) {
98+
return;
99+
}
100+
if (value instanceof Collection<?>) {
97101
values.put(name, value);
102+
} else {
103+
String valueString = value.toString();
104+
if (!StringUtil.isBlank(valueString)) {
105+
values.put(name, valueString);
106+
}
98107
}
99108
}
100109

0 commit comments

Comments
 (0)