diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/get/GetResponse.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/get/GetResponse.java index 966dc891802..d36f245093b 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/get/GetResponse.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/get/GetResponse.java @@ -24,11 +24,12 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.common.Unicode; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.compress.lzf.LZFDecoder; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.io.stream.Streamable; +import org.elasticsearch.common.io.stream.*; +import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.common.xcontent.builder.XContentBuilder; import java.io.IOException; import java.util.Iterator; @@ -45,7 +46,7 @@ import static org.elasticsearch.common.collect.Maps.*; * @see GetRequest * @see org.elasticsearch.client.Client#get(GetRequest) */ -public class GetResponse implements ActionResponse, Streamable, Iterable { +public class GetResponse implements ActionResponse, Streamable, Iterable, ToXContent { private String index; @@ -216,6 +217,63 @@ public class GetResponse implements ActionResponse, Streamable, Iterable { this.builder = this; } - @Override public TextXContentBuilder raw(byte[] json) throws IOException { + @Override public TextXContentBuilder raw(byte[] content) throws IOException { flush(); - Unicode.UTF16Result result = Unicode.unsafeFromBytesAsUtf16(json); + Unicode.UTF16Result result = Unicode.unsafeFromBytesAsUtf16(content); + writer.write(result.result, 0, result.length); + return this; + } + + @Override public TextXContentBuilder raw(InputStream content) throws IOException { + FastByteArrayOutputStream os = new FastByteArrayOutputStream(); + Streams.copy(content, os); + flush(); + Unicode.UTF16Result result = Unicode.unsafeFromBytesAsUtf16(os.unsafeByteArray(), 0, os.size()); writer.write(result.result, 0, result.length); return this; } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/builder/XContentBuilder.java b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/builder/XContentBuilder.java index 63e353aade6..c390ad2198e 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/builder/XContentBuilder.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/common/xcontent/builder/XContentBuilder.java @@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.support.XContentMapConverter; import java.io.IOException; +import java.io.InputStream; import java.util.Date; import java.util.Map; @@ -288,8 +289,15 @@ public abstract class XContentBuilder { return raw(content); } + public T rawField(String fieldName, InputStream content) throws IOException { + generator.writeRawFieldStart(fieldName); + return raw(content); + } + public abstract T raw(byte[] content) throws IOException; + public abstract T raw(InputStream content) throws IOException; + public T value(Boolean value) throws IOException { return value(value.booleanValue()); } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/get/RestGetAction.java b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/get/RestGetAction.java index e3a831298c3..1a86b398d33 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/get/RestGetAction.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/get/RestGetAction.java @@ -20,13 +20,11 @@ package org.elasticsearch.rest.action.get; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.get.GetField; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.client.Client; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.builder.XContentBuilder; import org.elasticsearch.rest.*; @@ -72,52 +70,13 @@ public class RestGetAction extends BaseRestHandler { client.get(getRequest, new ActionListener() { @Override public void onResponse(GetResponse response) { + try { + XContentBuilder builder = restContentBuilder(request); + response.toXContent(builder, request); if (!response.exists()) { - XContentBuilder builder = restContentBuilder(request); - builder.startObject(); - builder.field("_index", response.index()); - builder.field("_type", response.type()); - builder.field("_id", response.id()); - builder.endObject(); channel.sendResponse(new XContentRestResponse(request, NOT_FOUND, builder)); } else { - XContentBuilder builder = restContentBuilder(request); - builder.startObject(); - builder.field("_index", response.index()); - builder.field("_type", response.type()); - builder.field("_id", response.id()); - if (response.source() != null) { - if (builder.contentType() == XContentFactory.xContentType(response.source())) { - builder.rawField("_source", response.source()); - } else { - builder.field("_source"); - builder.value(response.source()); - } - } - - if (response.fields() != null && !response.fields().isEmpty()) { - builder.startObject("fields"); - for (GetField field : response.fields().values()) { - if (field.values().isEmpty()) { - continue; - } - if (field.values().size() == 1) { - builder.field(field.name(), field.values().get(0)); - } else { - builder.field(field.name()); - builder.startArray(); - for (Object value : field.values()) { - builder.value(value); - } - builder.endArray(); - } - } - builder.endObject(); - } - - - builder.endObject(); channel.sendResponse(new XContentRestResponse(request, OK, builder)); } } catch (Exception e) { diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java index be966cf1f9e..288f357b12f 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchHit.java @@ -24,11 +24,11 @@ import org.elasticsearch.ElasticSearchParseException; import org.elasticsearch.common.Unicode; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.compress.lzf.LZFDecoder; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.*; import org.elasticsearch.common.trove.TIntObjectHashMap; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.builder.XContentBuilder; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHitField; @@ -259,12 +259,23 @@ public class InternalSearchHit implements SearchHit { } else { builder.field("_score", score); } - if (source() != null) { - if (XContentFactory.xContentType(source()) == builder.contentType()) { - builder.rawField("_source", source()); + if (source != null) { + if (LZFDecoder.isCompressed(source)) { + BytesStreamInput siBytes = new BytesStreamInput(source); + LZFStreamInput siLzf = CachedStreamInput.cachedLzf(siBytes); + XContentType contentType = XContentFactory.xContentType(siLzf); + siLzf.resetToBufferStart(); + if (contentType == builder.contentType()) { + builder.rawField("_source", siLzf); + } else { + builder.field("_source", XContentFactory.xContent(builder.contentType()).createParser(siLzf).map()); + } } else { - builder.field("_source"); - builder.value(source()); + if (XContentFactory.xContentType(source) == builder.contentType()) { + builder.rawField("_source", source); + } else { + builder.field("_source", XContentFactory.xContent(builder.contentType()).createParser(source).map()); + } } } if (fields != null && !fields.isEmpty()) {