diff options
3 files changed, 131 insertions, 9 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java index 5c85c3641cf..cb115502468 100644 --- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java +++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/XMLField.java @@ -1,18 +1,14 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. /** - * Class representing a string field in the result set - * + * Class converting data (historically XML-encoded) from a document summary field. + * This has only been used to represent geographical positions. */ package com.yahoo.prelude.fastsearch; - -import java.nio.ByteBuffer; - -import com.yahoo.io.SlowInflate; -import com.yahoo.prelude.hitfield.XMLString; -import com.yahoo.text.Utf8; import com.yahoo.data.access.Inspector; - +import com.yahoo.data.access.Type; +import com.yahoo.prelude.hitfield.XMLString; +import com.yahoo.search.result.PositionsData; /** * @author Steinar Knutsen @@ -34,6 +30,13 @@ public class XMLField extends DocsumField { @Override public Object convert(Inspector value) { + /* In Vespa 6 the backend will send an XML-formatted string to represent + * positions data. This will change in next version to sending an array + * of objects instead, suitable for the PositionsData class. + */ + if (value.type() == Type.ARRAY) { + return new PositionsData(value); + } return convert(value.asString("")); } diff --git a/container-search/src/main/java/com/yahoo/search/result/PositionsData.java b/container-search/src/main/java/com/yahoo/search/result/PositionsData.java new file mode 100644 index 00000000000..a07eaa2438d --- /dev/null +++ b/container-search/src/main/java/com/yahoo/search/result/PositionsData.java @@ -0,0 +1,64 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.result; + +import com.yahoo.data.access.Inspector; +import com.yahoo.data.access.Inspectable; +import com.yahoo.data.access.Type; +import com.yahoo.data.JsonProducer; +import com.yahoo.data.XmlProducer; +import com.yahoo.data.access.simple.JsonRender; + +/** + * A wrapper for structured data representing an array of position values. + **/ +public class PositionsData implements Inspectable, JsonProducer, XmlProducer { + + private final Inspector value; + + public PositionsData(Inspector value) { + this.value = value; + if (value.type() != Type.ARRAY) { + throw new IllegalArgumentException("PositionsData expects an array of positions, got: "+value); + } + } + + @Override + public Inspector inspect() { + return value; + } + + public String toString() { + return toJson(); + } + + @Override + public StringBuilder writeJson(StringBuilder target) { + return JsonRender.render(value, target, true); + } + + @Override + public StringBuilder writeXML(StringBuilder target) { + for (int i = 0; i < value.entryCount(); i++) { + Inspector pos = value.entry(i); + target.append("<position "); + for (java.util.Map.Entry<String, Inspector> entry : pos.fields()) { + Inspector v = entry.getValue(); + if (v.type() == Type.STRING) { + target.append(entry.getKey()); + target.append("=\""); + target.append(entry.getValue().asString()); + target.append("\" "); + } + if (v.type() == Type.LONG) { + target.append(entry.getKey()); + target.append("=\""); + target.append(entry.getValue().asLong()); + target.append("\" "); + } + } + target.append("/>"); + } + return target; + } + +} diff --git a/container-search/src/test/java/com/yahoo/search/result/PositionsDataTestCase.java b/container-search/src/test/java/com/yahoo/search/result/PositionsDataTestCase.java new file mode 100644 index 00000000000..c77ff2eca3c --- /dev/null +++ b/container-search/src/test/java/com/yahoo/search/result/PositionsDataTestCase.java @@ -0,0 +1,55 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.search.result; + +import com.yahoo.data.access.simple.Value; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Arne Juul + */ +public class PositionsDataTestCase { + + @Test + public void testRendering() { + Value.ArrayValue arr = new Value.ArrayValue(); + Value.ObjectValue p1 = new Value.ObjectValue(); + p1.put("x", new Value.LongValue(-122057174)); + p1.put("y", new Value.LongValue(37374821)); + p1.put("latlong", new Value.StringValue("N37.374821;W122.057174")); + arr.add(p1); + + PositionsData pd = new PositionsData(arr.inspect()); + + String rendered = pd.toXML(); + String correct = "<position x=\"-122057174\" y=\"37374821\" latlong=\"N37.374821;W122.057174\" />"; + assertEquals(correct, rendered); + + rendered = pd.toJson(); + correct = "[{\"x\":-122057174,\"y\":37374821,\"latlong\":\"N37.374821;W122.057174\"}]"; + assertEquals(correct, rendered); + + Value.ObjectValue p2 = new Value.ObjectValue(); + p2.put("x", new Value.LongValue(3)); + p2.put("y", new Value.LongValue(-7)); + p2.put("latlong", new Value.StringValue("S0.000007;E0.000003")); + arr.add(p2); + + pd = new PositionsData(arr.inspect()); + + rendered = pd.toXML(); + correct = "<position x=\"-122057174\" y=\"37374821\" latlong=\"N37.374821;W122.057174\" />" + + "<position x=\"3\" y=\"-7\" latlong=\"S0.000007;E0.000003\" />"; + assertEquals(correct, rendered); + + rendered = pd.toJson(); + correct = "[{\"x\":-122057174,\"y\":37374821,\"latlong\":\"N37.374821;W122.057174\"}," + + "{\"x\":3,\"y\":-7,\"latlong\":\"S0.000007;E0.000003\"}]"; + assertEquals(correct, rendered); + } + +} |