mirror of https://github.com/apache/lucene.git
SOLR-9787, SOLR-9442: Replace json.nl=arrnvp with json.nl=arrntv (array of Name Type Value) style in JSONResponseWriter
This commit is contained in:
parent
bc55d8bc42
commit
73e50ceceb
|
@ -74,8 +74,8 @@ New Features
|
||||||
Example: { type:terms, field:category, filter:"user:yonik" }
|
Example: { type:terms, field:category, filter:"user:yonik" }
|
||||||
(yonik)
|
(yonik)
|
||||||
|
|
||||||
* SOLR-9442: Adds Array of NamedValuePair (json.nl=arrnvp) style to JSONResponseWriter.
|
* SOLR-9442, SOLR-9787: Adds Array of Name Type Value (json.nl=arrntv) style to JSONResponseWriter.
|
||||||
(Jonny Marks, Christine Poerschke)
|
(Jonny Marks, Christine Poerschke, hossman)
|
||||||
|
|
||||||
* SOLR-9055: Make collection backup/restore extensible. (Hrishikesh Gadre, Varun Thacker, Mark Miller)
|
* SOLR-9055: Make collection backup/restore extensible. (Hrishikesh Gadre, Varun Thacker, Mark Miller)
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,9 @@ public class JSONResponseWriter implements QueryResponseWriter {
|
||||||
final String namedListStyle = params.get(JSONWriter.JSON_NL_STYLE, JSONWriter.JSON_NL_FLAT).intern();
|
final String namedListStyle = params.get(JSONWriter.JSON_NL_STYLE, JSONWriter.JSON_NL_FLAT).intern();
|
||||||
|
|
||||||
final JSONWriter w;
|
final JSONWriter w;
|
||||||
if (namedListStyle.equals(JSONWriter.JSON_NL_ARROFNVP)) {
|
if (namedListStyle.equals(JSONWriter.JSON_NL_ARROFNTV)) {
|
||||||
w = new ArrayOfNamedValuePairJSONWriter(
|
w = new ArrayOfNameTypeValueJSONWriter(
|
||||||
writer, req, rsp, wrapperFunction, namedListStyle);
|
writer, req, rsp, wrapperFunction, namedListStyle, true);
|
||||||
} else {
|
} else {
|
||||||
w = new JSONWriter(
|
w = new JSONWriter(
|
||||||
writer, req, rsp, wrapperFunction, namedListStyle);
|
writer, req, rsp, wrapperFunction, namedListStyle);
|
||||||
|
@ -96,7 +96,7 @@ class JSONWriter extends TextResponseWriter {
|
||||||
static final String JSON_NL_FLAT="flat";
|
static final String JSON_NL_FLAT="flat";
|
||||||
static final String JSON_NL_ARROFARR="arrarr";
|
static final String JSON_NL_ARROFARR="arrarr";
|
||||||
static final String JSON_NL_ARROFMAP="arrmap";
|
static final String JSON_NL_ARROFMAP="arrmap";
|
||||||
static final String JSON_NL_ARROFNVP="arrnvp";
|
static final String JSON_NL_ARROFNTV="arrntv";
|
||||||
|
|
||||||
static final String JSON_WRAPPER_FUNCTION="json.wrf";
|
static final String JSON_WRAPPER_FUNCTION="json.wrf";
|
||||||
|
|
||||||
|
@ -331,9 +331,9 @@ class JSONWriter extends TextResponseWriter {
|
||||||
writeNamedListAsArrArr(name,val);
|
writeNamedListAsArrArr(name,val);
|
||||||
} else if (namedListStyle==JSON_NL_ARROFMAP) {
|
} else if (namedListStyle==JSON_NL_ARROFMAP) {
|
||||||
writeNamedListAsArrMap(name,val);
|
writeNamedListAsArrMap(name,val);
|
||||||
} else if (namedListStyle==JSON_NL_ARROFNVP) {
|
} else if (namedListStyle==JSON_NL_ARROFNTV) {
|
||||||
throw new UnsupportedOperationException(namedListStyle
|
throw new UnsupportedOperationException(namedListStyle
|
||||||
+ " namedListStyle must only be used with "+ArrayOfNamedValuePairJSONWriter.class.getSimpleName());
|
+ " namedListStyle must only be used with "+ArrayOfNameTypeValueJSONWriter.class.getSimpleName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,20 +675,25 @@ class JSONWriter extends TextResponseWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes NamedLists directly as an array of NamedValuePair JSON objects...
|
* Writes NamedLists directly as an array of NameTypeValue JSON objects...
|
||||||
* NamedList("a"=1,"b"=2,null=3,null=null) => [{"name":"a","int":1},{"name":"b","int":2},{"int":3},{"null":null}]
|
* NamedList("a"=1,"b"=null,null=3,null=null) =>
|
||||||
* NamedList("a"=1,"bar"="foo",null=3.4f) => [{"name":"a","int":1},{"name":"bar","str":"foo"},{"float":3.4}]
|
* [{"name":"a","type":"int","value":1},
|
||||||
|
* {"name":"b","type":"null","value":null},
|
||||||
|
* {"name":null,"type":"int","value":3},
|
||||||
|
* {"name":null,"type":"null","value":null}]
|
||||||
|
* NamedList("a"=1,"bar"="foo",null=3.4f) =>
|
||||||
|
* [{"name":"a","type":"int","value":1},
|
||||||
|
* {"name":"bar","type":"str","value":"foo"},
|
||||||
|
* {"name":null,"type":"float","value":3.4}]
|
||||||
*/
|
*/
|
||||||
class ArrayOfNamedValuePairJSONWriter extends JSONWriter {
|
class ArrayOfNameTypeValueJSONWriter extends JSONWriter {
|
||||||
private boolean writeTypeAsKey = false;
|
protected boolean writeTypeAndValueKey = false;
|
||||||
|
private final boolean writeNullName;
|
||||||
|
|
||||||
public ArrayOfNamedValuePairJSONWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp,
|
public ArrayOfNameTypeValueJSONWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp,
|
||||||
String wrapperFunction, String namedListStyle) {
|
String wrapperFunction, String namedListStyle, boolean writeNullName) {
|
||||||
super(writer, req, rsp, wrapperFunction, namedListStyle);
|
super(writer, req, rsp, wrapperFunction, namedListStyle);
|
||||||
if (namedListStyle != JSON_NL_ARROFNVP) {
|
this.writeNullName = writeNullName;
|
||||||
throw new UnsupportedOperationException(ArrayOfNamedValuePairJSONWriter.class.getSimpleName()+" must only be used with "
|
|
||||||
+ JSON_NL_ARROFNVP + " style");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -720,24 +725,24 @@ class ArrayOfNamedValuePairJSONWriter extends JSONWriter {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* JSONWriter's writeNamedListAsArrMap turns NamedList("bar"="foo") into [{"foo":"bar"}]
|
* JSONWriter's writeNamedListAsArrMap turns NamedList("bar"="foo") into [{"foo":"bar"}]
|
||||||
* but we here wish to turn it into [ {"name":"bar","str":"foo"} ] instead.
|
* but we here wish to turn it into [ {"name":"bar","type":"str","value":"foo"} ] instead.
|
||||||
*
|
*
|
||||||
* So first we write the <code>{"name":"bar",</code> portion ...
|
* So first we write the <code>{"name":"bar",</code> portion ...
|
||||||
*/
|
*/
|
||||||
writeMapOpener(-1);
|
writeMapOpener(-1);
|
||||||
if (elementName != null) {
|
if (elementName != null || writeNullName) {
|
||||||
writeKey("name", false);
|
writeKey("name", false);
|
||||||
writeVal("name", elementName);
|
writeVal("name", elementName);
|
||||||
writeMapSeparator();
|
writeMapSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ... and then we write the <code>"str":"foo"}</code> portion.
|
* ... and then we write the <code>"type":"str","value":"foo"}</code> portion.
|
||||||
*/
|
*/
|
||||||
writeTypeAsKey = true;
|
writeTypeAndValueKey = true;
|
||||||
writeVal(null, elementVal); // passing null since writeVal doesn't actually use name (and we already wrote elementName above)
|
writeVal(null, elementVal); // passing null since writeVal doesn't actually use name (and we already wrote elementName above)
|
||||||
if (writeTypeAsKey) {
|
if (writeTypeAndValueKey) {
|
||||||
throw new RuntimeException("writeTypeAsKey should have been reset to false by writeVal('"+elementName+"','"+elementVal+"')");
|
throw new RuntimeException("writeTypeAndValueKey should have been reset to false by writeVal('"+elementName+"','"+elementVal+"')");
|
||||||
}
|
}
|
||||||
writeMapCloser();
|
writeMapCloser();
|
||||||
}
|
}
|
||||||
|
@ -746,82 +751,85 @@ class ArrayOfNamedValuePairJSONWriter extends JSONWriter {
|
||||||
writeArrayCloser();
|
writeArrayCloser();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ifNeededWriteTypeAsKey(String type) throws IOException {
|
protected void ifNeededWriteTypeAndValueKey(String type) throws IOException {
|
||||||
if (writeTypeAsKey) {
|
if (writeTypeAndValueKey) {
|
||||||
writeTypeAsKey = false;
|
writeTypeAndValueKey = false;
|
||||||
writeKey(type, false);
|
writeKey("type", false);
|
||||||
|
writeVal("type", type);
|
||||||
|
writeMapSeparator();
|
||||||
|
writeKey("value", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeInt(String name, String val) throws IOException {
|
public void writeInt(String name, String val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("int");
|
ifNeededWriteTypeAndValueKey("int");
|
||||||
super.writeInt(name, val);
|
super.writeInt(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeLong(String name, String val) throws IOException {
|
public void writeLong(String name, String val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("long");
|
ifNeededWriteTypeAndValueKey("long");
|
||||||
super.writeLong(name, val);
|
super.writeLong(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeFloat(String name, String val) throws IOException {
|
public void writeFloat(String name, String val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("float");
|
ifNeededWriteTypeAndValueKey("float");
|
||||||
super.writeFloat(name, val);
|
super.writeFloat(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeDouble(String name, String val) throws IOException {
|
public void writeDouble(String name, String val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("double");
|
ifNeededWriteTypeAndValueKey("double");
|
||||||
super.writeDouble(name, val);
|
super.writeDouble(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBool(String name, String val) throws IOException {
|
public void writeBool(String name, String val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("bool");
|
ifNeededWriteTypeAndValueKey("bool");
|
||||||
super.writeBool(name, val);
|
super.writeBool(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeDate(String name, String val) throws IOException {
|
public void writeDate(String name, String val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("date");
|
ifNeededWriteTypeAndValueKey("date");
|
||||||
super.writeDate(name, val);
|
super.writeDate(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeStr(String name, String val, boolean needsEscaping) throws IOException {
|
public void writeStr(String name, String val, boolean needsEscaping) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("str");
|
ifNeededWriteTypeAndValueKey("str");
|
||||||
super.writeStr(name, val, needsEscaping);
|
super.writeStr(name, val, needsEscaping);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException {
|
public void writeSolrDocument(String name, SolrDocument doc, ReturnFields returnFields, int idx) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("doc");
|
ifNeededWriteTypeAndValueKey("doc");
|
||||||
super.writeSolrDocument(name, doc, returnFields, idx);
|
super.writeSolrDocument(name, doc, returnFields, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeStartDocumentList(String name, long start, int size, long numFound, Float maxScore) throws IOException {
|
public void writeStartDocumentList(String name, long start, int size, long numFound, Float maxScore) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("doclist");
|
ifNeededWriteTypeAndValueKey("doclist");
|
||||||
super.writeStartDocumentList(name, start, size, numFound, maxScore);
|
super.writeStartDocumentList(name, start, size, numFound, maxScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeMap(String name, Map val, boolean excludeOuter, boolean isFirstVal) throws IOException {
|
public void writeMap(String name, Map val, boolean excludeOuter, boolean isFirstVal) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("map");
|
ifNeededWriteTypeAndValueKey("map");
|
||||||
super.writeMap(name, val, excludeOuter, isFirstVal);
|
super.writeMap(name, val, excludeOuter, isFirstVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeArray(String name, Iterator val) throws IOException {
|
public void writeArray(String name, Iterator val) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("array");
|
ifNeededWriteTypeAndValueKey("array");
|
||||||
super.writeArray(name, val);
|
super.writeArray(name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeNull(String name) throws IOException {
|
public void writeNull(String name) throws IOException {
|
||||||
ifNeededWriteTypeAsKey("null");
|
ifNeededWriteTypeAndValueKey("null");
|
||||||
super.writeNull(name);
|
super.writeNull(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
||||||
JSONWriter.JSON_NL_MAP,
|
JSONWriter.JSON_NL_MAP,
|
||||||
JSONWriter.JSON_NL_ARROFARR,
|
JSONWriter.JSON_NL_ARROFARR,
|
||||||
JSONWriter.JSON_NL_ARROFMAP,
|
JSONWriter.JSON_NL_ARROFMAP,
|
||||||
JSONWriter.JSON_NL_ARROFNVP,
|
JSONWriter.JSON_NL_ARROFNTV,
|
||||||
};
|
};
|
||||||
for (final String namedListStyle : namedListStyles) {
|
for (final String namedListStyle : namedListStyles) {
|
||||||
implTestJSON(namedListStyle);
|
implTestJSON(namedListStyle);
|
||||||
|
@ -116,8 +116,10 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
||||||
expectedNLjson = "\"nl\":[[\"data1\",\"he\\u2028llo\\u2029!\"],[null,42],[null,null]]";
|
expectedNLjson = "\"nl\":[[\"data1\",\"he\\u2028llo\\u2029!\"],[null,42],[null,null]]";
|
||||||
} else if (namedListStyle == JSONWriter.JSON_NL_ARROFMAP) {
|
} else if (namedListStyle == JSONWriter.JSON_NL_ARROFMAP) {
|
||||||
expectedNLjson = "\"nl\":[{\"data1\":\"he\\u2028llo\\u2029!\"},42,null]";
|
expectedNLjson = "\"nl\":[{\"data1\":\"he\\u2028llo\\u2029!\"},42,null]";
|
||||||
} else if (namedListStyle == JSONWriter.JSON_NL_ARROFNVP) {
|
} else if (namedListStyle == JSONWriter.JSON_NL_ARROFNTV) {
|
||||||
expectedNLjson = "\"nl\":[{\"name\":\"data1\",\"str\":\"he\\u2028llo\\u2029!\"},{\"int\":42},{\"null\":null}]";
|
expectedNLjson = "\"nl\":[{\"name\":\"data1\",\"type\":\"str\",\"value\":\"he\\u2028llo\\u2029!\"}," +
|
||||||
|
"{\"name\":null,\"type\":\"int\",\"value\":42}," +
|
||||||
|
"{\"name\":null,\"type\":\"null\",\"value\":null}]";
|
||||||
} else {
|
} else {
|
||||||
expectedNLjson = null;
|
expectedNLjson = null;
|
||||||
fail("unexpected namedListStyle="+namedListStyle);
|
fail("unexpected namedListStyle="+namedListStyle);
|
||||||
|
@ -168,7 +170,7 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArrnvpWriterOverridesAllWrites() {
|
public void testArrntvWriterOverridesAllWrites() {
|
||||||
// List rather than Set because two not-overridden methods could share name but not signature
|
// List rather than Set because two not-overridden methods could share name but not signature
|
||||||
final List<String> methodsExpectedNotOverriden = new ArrayList<>(14);
|
final List<String> methodsExpectedNotOverriden = new ArrayList<>(14);
|
||||||
methodsExpectedNotOverriden.add("writeResponse");
|
methodsExpectedNotOverriden.add("writeResponse");
|
||||||
|
@ -189,7 +191,7 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
||||||
methodsExpectedNotOverriden.add("public void org.apache.solr.response.JSONWriter.writeMap(org.apache.solr.common.MapWriter) throws java.io.IOException");
|
methodsExpectedNotOverriden.add("public void org.apache.solr.response.JSONWriter.writeMap(org.apache.solr.common.MapWriter) throws java.io.IOException");
|
||||||
methodsExpectedNotOverriden.add("public void org.apache.solr.response.JSONWriter.writeIterator(org.apache.solr.common.IteratorWriter) throws java.io.IOException");
|
methodsExpectedNotOverriden.add("public void org.apache.solr.response.JSONWriter.writeIterator(org.apache.solr.common.IteratorWriter) throws java.io.IOException");
|
||||||
|
|
||||||
final Class<?> subClass = ArrayOfNamedValuePairJSONWriter.class;
|
final Class<?> subClass = ArrayOfNameTypeValueJSONWriter.class;
|
||||||
final Class<?> superClass = subClass.getSuperclass();
|
final Class<?> superClass = subClass.getSuperclass();
|
||||||
|
|
||||||
for (final Method superClassMethod : superClass.getDeclaredMethods()) {
|
for (final Method superClassMethod : superClass.getDeclaredMethods()) {
|
||||||
|
@ -231,14 +233,14 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArrnvpWriterLacksMethodsOfItsOwn() {
|
public void testArrntvWriterLacksMethodsOfItsOwn() {
|
||||||
final Class<?> subClass = ArrayOfNamedValuePairJSONWriter.class;
|
final Class<?> subClass = ArrayOfNameTypeValueJSONWriter.class;
|
||||||
final Class<?> superClass = subClass.getSuperclass();
|
final Class<?> superClass = subClass.getSuperclass();
|
||||||
// ArrayOfNamedValuePairJSONWriter is a simple sub-class
|
// ArrayOfNamedValuePairJSONWriter is a simple sub-class
|
||||||
// which should have (almost) no methods of its own
|
// which should have (almost) no methods of its own
|
||||||
for (final Method subClassMethod : subClass.getDeclaredMethods()) {
|
for (final Method subClassMethod : subClass.getDeclaredMethods()) {
|
||||||
// only own private method of its own
|
// only own private method of its own
|
||||||
if (subClassMethod.getName().equals("ifNeededWriteTypeAsKey")) continue;
|
if (subClassMethod.getName().equals("ifNeededWriteTypeAndValueKey")) continue;
|
||||||
try {
|
try {
|
||||||
final Method superClassMethod = superClass.getDeclaredMethod(
|
final Method superClassMethod = superClass.getDeclaredMethod(
|
||||||
subClassMethod.getName(),
|
subClassMethod.getName(),
|
||||||
|
@ -260,7 +262,7 @@ public class JSONWriterTest extends SolrTestCaseJ4 {
|
||||||
assertEquals("flat", JSONWriter.JSON_NL_FLAT);
|
assertEquals("flat", JSONWriter.JSON_NL_FLAT);
|
||||||
assertEquals("arrarr", JSONWriter.JSON_NL_ARROFARR);
|
assertEquals("arrarr", JSONWriter.JSON_NL_ARROFARR);
|
||||||
assertEquals("arrmap", JSONWriter.JSON_NL_ARROFMAP);
|
assertEquals("arrmap", JSONWriter.JSON_NL_ARROFMAP);
|
||||||
assertEquals("arrnvp", JSONWriter.JSON_NL_ARROFNVP);
|
assertEquals("arrntv", JSONWriter.JSON_NL_ARROFNTV);
|
||||||
assertEquals("json.wrf", JSONWriter.JSON_WRAPPER_FUNCTION);
|
assertEquals("json.wrf", JSONWriter.JSON_WRAPPER_FUNCTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue