diff --git a/.idea/dictionaries/kimchy.xml b/.idea/dictionaries/kimchy.xml
index c28b83d2963..3b42a495ff4 100644
--- a/.idea/dictionaries/kimchy.xml
+++ b/.idea/dictionaries/kimchy.xml
@@ -82,6 +82,7 @@
versioned
wildcards
xcontent
+ xson
yaml
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/count/CountRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/count/CountRequest.java
index 17834d437b7..7780016df52 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/count/CountRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/count/CountRequest.java
@@ -19,18 +19,27 @@
package org.elasticsearch.action.count;
+import org.elasticsearch.ElasticSearchGenerationException;
+import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.action.Actions;
import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
import org.elasticsearch.action.support.broadcast.BroadcastOperationThreading;
+import org.elasticsearch.client.Requests;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.util.Required;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.Unicode;
+import org.elasticsearch.util.io.FastByteArrayOutputStream;
import org.elasticsearch.util.io.stream.StreamInput;
import org.elasticsearch.util.io.stream.StreamOutput;
+import org.elasticsearch.util.xcontent.XContentFactory;
+import org.elasticsearch.util.xcontent.XContentType;
+import org.elasticsearch.util.xcontent.builder.BinaryXContentBuilder;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Map;
/**
* A request to count the number of documents matching a specific query. Best created with
@@ -46,6 +55,8 @@ import java.util.Arrays;
*/
public class CountRequest extends BroadcastOperationRequest {
+ private static final XContentType contentType = Requests.CONTENT_TYPE;
+
public static final float DEFAULT_MIN_SCORE = -1f;
private float minScore = DEFAULT_MIN_SCORE;
@@ -53,6 +64,8 @@ public class CountRequest extends BroadcastOperationRequest {
private String[] types = Strings.EMPTY_ARRAY;
@Nullable private String queryParserName;
+ private transient QueryBuilder queryBuilder = null;
+
CountRequest() {
}
@@ -64,6 +77,14 @@ public class CountRequest extends BroadcastOperationRequest {
super(indices, null);
}
+ @Override public ActionRequestValidationException validate() {
+ ActionRequestValidationException validationException = super.validate();
+ if (querySource == null && queryBuilder == null) {
+ validationException = Actions.addValidationError("query is missing", validationException);
+ }
+ return validationException;
+ }
+
/**
* Controls the operation threading model.
*/
@@ -113,6 +134,10 @@ public class CountRequest extends BroadcastOperationRequest {
* The query source to execute.
*/
byte[] querySource() {
+ if (querySource == null && queryBuilder != null) {
+ // did not get serialized...
+ querySource = queryBuilder.buildAsBytes(contentType);
+ }
return querySource;
}
@@ -122,7 +147,22 @@ public class CountRequest extends BroadcastOperationRequest {
* @see org.elasticsearch.index.query.xcontent.QueryBuilders
*/
@Required public CountRequest query(QueryBuilder queryBuilder) {
- return query(queryBuilder.buildAsBytes());
+ this.queryBuilder = queryBuilder;
+ return this;
+ }
+
+ /**
+ * The query source to execute in the form of a map.
+ */
+ @Required public CountRequest query(Map querySource) {
+ try {
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
+ builder.map(querySource);
+ this.querySource = builder.copiedBytes();
+ } catch (IOException e) {
+ throw new ElasticSearchGenerationException("Failed to generate [" + querySource + "]", e);
+ }
+ return this;
}
/**
@@ -191,8 +231,14 @@ public class CountRequest extends BroadcastOperationRequest {
@Override public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeFloat(minScore);
- out.writeVInt(querySource.length);
- out.writeBytes(querySource);
+ if (querySource != null) {
+ out.writeVInt(querySource.length);
+ out.writeBytes(querySource);
+ } else {
+ FastByteArrayOutputStream os = queryBuilder.buildAsUnsafeBytes(contentType);
+ out.writeVInt(os.size());
+ out.writeBytes(os.unsafeByteArray(), 0, os.size());
+ }
if (queryParserName == null) {
out.writeBoolean(false);
} else {
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java
index 381f2ffce24..89de0e2d9d0 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/deletebyquery/DeleteByQueryRequest.java
@@ -22,11 +22,13 @@ package org.elasticsearch.action.deletebyquery;
import org.elasticsearch.ElasticSearchGenerationException;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.replication.IndicesReplicationOperationRequest;
+import org.elasticsearch.client.Requests;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.util.Required;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.TimeValue;
import org.elasticsearch.util.Unicode;
+import org.elasticsearch.util.io.FastByteArrayOutputStream;
import org.elasticsearch.util.io.stream.StreamInput;
import org.elasticsearch.util.io.stream.StreamOutput;
import org.elasticsearch.util.xcontent.XContentFactory;
@@ -53,10 +55,14 @@ import static org.elasticsearch.action.Actions.*;
*/
public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
+ private static final XContentType contentType = Requests.CONTENT_TYPE;
+
private byte[] querySource;
private String queryParserName;
private String[] types = Strings.EMPTY_ARRAY;
+ private transient QueryBuilder queryBuilder;
+
/**
* Constructs a new delete by query request to run against the provided indices. No indices means
* it will run against all indices.
@@ -78,7 +84,7 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
@Override public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = super.validate();
- if (querySource == null) {
+ if (querySource == null && queryBuilder == null) {
validationException = addValidationError("query is missing", validationException);
}
return validationException;
@@ -93,6 +99,9 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
* The query source to execute.
*/
byte[] querySource() {
+ if (querySource == null && queryBuilder != null) {
+ querySource = queryBuilder.buildAsBytes();
+ }
return querySource;
}
@@ -102,7 +111,8 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
* @see org.elasticsearch.index.query.xcontent.QueryBuilders
*/
@Required public DeleteByQueryRequest query(QueryBuilder queryBuilder) {
- return query(queryBuilder.buildAsBytes());
+ this.queryBuilder = queryBuilder;
+ return this;
}
/**
@@ -118,7 +128,7 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
*/
@Required public DeleteByQueryRequest query(Map querySource) {
try {
- BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(XContentType.JSON);
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
builder.map(querySource);
this.querySource = builder.copiedBytes();
} catch (IOException e) {
@@ -184,8 +194,14 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
- out.writeVInt(querySource.length);
- out.writeBytes(querySource);
+ if (querySource != null) {
+ out.writeVInt(querySource.length);
+ out.writeBytes(querySource);
+ } else {
+ FastByteArrayOutputStream os = queryBuilder.buildAsUnsafeBytes(contentType);
+ out.writeVInt(os.size());
+ out.writeBytes(os.unsafeByteArray(), 0, os.size());
+ }
if (queryParserName == null) {
out.writeBoolean(false);
} else {
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/index/IndexRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/index/IndexRequest.java
index 8f96d0c0d46..92f4cfd33b8 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/index/IndexRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/index/IndexRequest.java
@@ -105,6 +105,8 @@ public class IndexRequest extends ShardReplicationOperationRequest {
private byte[] source;
private OpType opType = OpType.INDEX;
+ private transient XContentBuilder sourceBuilder;
+
public IndexRequest() {
}
@@ -136,7 +138,7 @@ public class IndexRequest extends ShardReplicationOperationRequest {
if (type == null) {
validationException = addValidationError("type is missing", validationException);
}
- if (source == null) {
+ if (source == null && sourceBuilder == null) {
validationException = addValidationError("source is missing", validationException);
}
return validationException;
@@ -201,6 +203,13 @@ public class IndexRequest extends ShardReplicationOperationRequest {
* The source of the JSON document to index.
*/
byte[] source() {
+ if (source == null && sourceBuilder != null) {
+ try {
+ source = sourceBuilder.copiedBytes();
+ } catch (IOException e) {
+ throw new ElasticSearchGenerationException("Failed to build source", e);
+ }
+ }
return source;
}
@@ -234,12 +243,9 @@ public class IndexRequest extends ShardReplicationOperationRequest {
/**
* Sets the content source to index.
*/
- @Required public IndexRequest source(XContentBuilder jsonBuilder) {
- try {
- return source(jsonBuilder.copiedBytes());
- } catch (IOException e) {
- throw new ElasticSearchIllegalArgumentException("Failed to build json for index request", e);
- }
+ @Required public IndexRequest source(XContentBuilder sourceBuilder) {
+ this.sourceBuilder = sourceBuilder;
+ return this;
}
/**
@@ -318,8 +324,13 @@ public class IndexRequest extends ShardReplicationOperationRequest {
out.writeBoolean(true);
out.writeUTF(id);
}
- out.writeVInt(source.length);
- out.writeBytes(source);
+ if (source != null) {
+ out.writeVInt(source.length);
+ out.writeBytes(source);
+ } else {
+ out.writeVInt(sourceBuilder.unsafeBytesLength());
+ out.writeBytes(sourceBuilder.unsafeBytes(), 0, sourceBuilder.unsafeBytesLength());
+ }
out.writeByte(opType.id());
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/mlt/MoreLikeThisRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/mlt/MoreLikeThisRequest.java
index d7c4f691941..7040dec8feb 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/mlt/MoreLikeThisRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/mlt/MoreLikeThisRequest.java
@@ -25,12 +25,14 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.Actions;
import org.elasticsearch.action.search.SearchType;
+import org.elasticsearch.client.Requests;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.util.Bytes;
import org.elasticsearch.util.Required;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.Unicode;
+import org.elasticsearch.util.io.FastByteArrayOutputStream;
import org.elasticsearch.util.io.stream.StreamInput;
import org.elasticsearch.util.io.stream.StreamOutput;
import org.elasticsearch.util.xcontent.XContentFactory;
@@ -55,6 +57,8 @@ import static org.elasticsearch.search.Scroll.*;
*/
public class MoreLikeThisRequest implements ActionRequest {
+ private static final XContentType contentType = Requests.CONTENT_TYPE;
+
private String index;
private String type;
@@ -80,6 +84,7 @@ public class MoreLikeThisRequest implements ActionRequest {
private Scroll searchScroll;
private byte[] searchSource;
+ private transient SearchSourceBuilder searchSourceBuiler;
private boolean threadedListener = false;
@@ -306,7 +311,8 @@ public class MoreLikeThisRequest implements ActionRequest {
* more like this documents.
*/
public MoreLikeThisRequest searchSource(SearchSourceBuilder sourceBuilder) {
- return searchSource(sourceBuilder.build());
+ this.searchSourceBuiler = sourceBuilder;
+ return this;
}
/**
@@ -342,6 +348,9 @@ public class MoreLikeThisRequest implements ActionRequest {
* more like this documents.
*/
public byte[] searchSource() {
+ if (searchSource == null && searchSourceBuiler != null) {
+ searchSource = searchSourceBuiler.buildAsBytes(contentType);
+ }
return this.searchSource;
}
@@ -589,11 +598,17 @@ public class MoreLikeThisRequest implements ActionRequest {
out.writeBoolean(true);
searchScroll.writeTo(out);
}
- if (searchSource == null) {
+ if (searchSource == null && searchSourceBuiler == null) {
out.writeVInt(0);
} else {
- out.writeVInt(searchSource.length);
- out.writeBytes(searchSource);
+ if (searchSource != null) {
+ out.writeVInt(searchSource.length);
+ out.writeBytes(searchSource);
+ } else {
+ FastByteArrayOutputStream os = searchSourceBuiler.buildAsUnsafeBytes(contentType);
+ out.writeVInt(os.size());
+ out.writeBytes(os.unsafeByteArray(), 0, os.size());
+ }
}
}
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchRequest.java
index 289bd4ad77f..15aed2010b9 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchRequest.java
@@ -23,12 +23,14 @@ import org.elasticsearch.ElasticSearchGenerationException;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
+import org.elasticsearch.client.Requests;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.util.Bytes;
import org.elasticsearch.util.Strings;
import org.elasticsearch.util.TimeValue;
import org.elasticsearch.util.Unicode;
+import org.elasticsearch.util.io.FastByteArrayOutputStream;
import org.elasticsearch.util.io.stream.StreamInput;
import org.elasticsearch.util.io.stream.StreamOutput;
import org.elasticsearch.util.xcontent.XContentFactory;
@@ -58,6 +60,8 @@ import static org.elasticsearch.util.TimeValue.*;
*/
public class SearchRequest implements ActionRequest {
+ private static final XContentType contentType = Requests.CONTENT_TYPE;
+
private SearchType searchType = SearchType.DEFAULT;
private String[] indices;
@@ -77,6 +81,9 @@ public class SearchRequest implements ActionRequest {
private boolean listenerThreaded = false;
private SearchOperationThreading operationThreading = SearchOperationThreading.SINGLE_THREAD;
+ private transient SearchSourceBuilder sourceBuilder;
+ private transient SearchSourceBuilder extraSourceBuilder;
+
SearchRequest() {
}
@@ -98,7 +105,7 @@ public class SearchRequest implements ActionRequest {
@Override public ActionRequestValidationException validate() {
ActionRequestValidationException validationException = null;
- if (source == null && extraSource == null) {
+ if (source == null && sourceBuilder == null && extraSource == null && extraSourceBuilder == null) {
validationException = addValidationError("search source is missing", validationException);
}
return validationException;
@@ -188,7 +195,8 @@ public class SearchRequest implements ActionRequest {
* The source of the search request.
*/
public SearchRequest source(SearchSourceBuilder sourceBuilder) {
- return source(sourceBuilder.build());
+ this.sourceBuilder = sourceBuilder;
+ return this;
}
/**
@@ -204,7 +212,7 @@ public class SearchRequest implements ActionRequest {
*/
public SearchRequest source(Map source) {
try {
- BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(XContentType.JSON);
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
builder.map(source);
this.source = builder.copiedBytes();
} catch (IOException e) {
@@ -225,6 +233,9 @@ public class SearchRequest implements ActionRequest {
* The search source to execute.
*/
public byte[] source() {
+ if (source == null && sourceBuilder != null) {
+ source = sourceBuilder.buildAsBytes(contentType);
+ }
return source;
}
@@ -232,12 +243,13 @@ public class SearchRequest implements ActionRequest {
* Allows to provide additional source that will be used as well.
*/
public SearchRequest extraSource(SearchSourceBuilder sourceBuilder) {
- return extraSource(sourceBuilder.build());
+ this.extraSourceBuilder = sourceBuilder;
+ return this;
}
public SearchRequest extraSource(Map extraSource) {
try {
- BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(XContentType.JSON);
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
builder.map(extraSource);
this.extraSource = builder.copiedBytes();
} catch (IOException e) {
@@ -265,6 +277,9 @@ public class SearchRequest implements ActionRequest {
* Additional search source to execute.
*/
public byte[] extraSource() {
+ if (extraSource == null && extraSourceBuilder != null) {
+ extraSource = extraSourceBuilder.buildAsBytes(contentType);
+ }
return this.extraSource;
}
@@ -405,17 +420,29 @@ public class SearchRequest implements ActionRequest {
out.writeBoolean(true);
timeout.writeTo(out);
}
- if (source == null) {
+ if (source == null && sourceBuilder == null) {
out.writeVInt(0);
} else {
- out.writeVInt(source.length);
- out.writeBytes(source);
+ if (source != null) {
+ out.writeVInt(source.length);
+ out.writeBytes(source);
+ } else {
+ FastByteArrayOutputStream os = sourceBuilder.buildAsUnsafeBytes(contentType);
+ out.writeVInt(os.size());
+ out.writeBytes(os.unsafeByteArray(), 0, os.size());
+ }
}
- if (extraSource == null) {
+ if (extraSource == null && extraSourceBuilder == null) {
out.writeVInt(0);
} else {
- out.writeVInt(extraSource.length);
- out.writeBytes(extraSource);
+ if (extraSource != null) {
+ out.writeVInt(extraSource.length);
+ out.writeBytes(extraSource);
+ } else {
+ FastByteArrayOutputStream os = extraSourceBuilder.buildAsUnsafeBytes(contentType);
+ out.writeVInt(os.size());
+ out.writeBytes(os.unsafeByteArray(), 0, os.size());
+ }
}
out.writeVInt(types.length);
for (String type : types) {
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/client/Requests.java b/modules/elasticsearch/src/main/java/org/elasticsearch/client/Requests.java
index 7cc09a3d0f5..c427b6ac00c 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/client/Requests.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/client/Requests.java
@@ -45,14 +45,20 @@ import org.elasticsearch.action.mlt.MoreLikeThisRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.terms.TermsRequest;
+import org.elasticsearch.util.xcontent.XContentType;
/**
* A handy one stop shop for creating requests (make sure to import static this class).
*
- * @author kimchy (Shay Banon)
+ * @author kimchy (shay.banon)
*/
public class Requests {
+ /**
+ * The content type used to generate request builders (query / search).
+ */
+ public static XContentType CONTENT_TYPE = XContentType.XSON;
+
public static IndexRequest indexRequest() {
return new IndexRequest();
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/http/netty/NettyHttpRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/http/netty/NettyHttpRequest.java
index bac47528e53..2d8c25896d8 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/http/netty/NettyHttpRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/http/netty/NettyHttpRequest.java
@@ -22,11 +22,9 @@ package org.elasticsearch.http.netty;
import org.elasticsearch.http.HttpRequest;
import org.elasticsearch.rest.support.AbstractRestRequest;
import org.elasticsearch.rest.support.RestUtils;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpMethod;
-import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -90,10 +88,6 @@ public class NettyHttpRequest extends AbstractRestRequest implements HttpRequest
return request.getContent().readableBytes() > 0;
}
- @Override public InputStream contentAsStream() {
- return new ChannelBufferInputStream(request.getContent());
- }
-
@Override public byte[] contentAsBytes() {
byte[] data = new byte[request.getContent().readableBytes()];
request.getContent().getBytes(request.getContent().readerIndex(), data);
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/XContentObjectMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/XContentObjectMapper.java
index 5ccbb536f6a..f5fe3805aeb 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/XContentObjectMapper.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/XContentObjectMapper.java
@@ -428,11 +428,19 @@ public class XContentObjectMapper implements XContentMapper, XContentIncludeInAl
} else if (token == XContentParser.Token.VALUE_NUMBER) {
XContentParser.NumberType numberType = context.parser().numberType();
if (numberType == XContentParser.NumberType.INT) {
- mapper = integerField(currentFieldName).build(builderContext);
+ if (context.parser().estimatedNumberType()) {
+ mapper = longField(currentFieldName).build(builderContext);
+ } else {
+ mapper = integerField(currentFieldName).build(builderContext);
+ }
} else if (numberType == XContentParser.NumberType.LONG) {
mapper = longField(currentFieldName).build(builderContext);
} else if (numberType == XContentParser.NumberType.FLOAT) {
- mapper = floatField(currentFieldName).build(builderContext);
+ if (context.parser().estimatedNumberType()) {
+ mapper = doubleField(currentFieldName).build(builderContext);
+ } else {
+ mapper = floatField(currentFieldName).build(builderContext);
+ }
} else if (numberType == XContentParser.NumberType.DOUBLE) {
mapper = doubleField(currentFieldName).build(builderContext);
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/RestRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/RestRequest.java
index 02df2482a70..7460649c4fa 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/RestRequest.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/RestRequest.java
@@ -23,7 +23,6 @@ import org.elasticsearch.util.SizeValue;
import org.elasticsearch.util.TimeValue;
import org.elasticsearch.util.xcontent.ToXContent;
-import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -51,8 +50,6 @@ public interface RestRequest extends ToXContent.Params {
boolean hasContent();
- InputStream contentAsStream();
-
byte[] contentAsBytes();
String contentAsString();
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java
index b2e40e7f094..da70e935861 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java
@@ -145,7 +145,7 @@ public class RestSearchAction extends BaseRestHandler {
return searchRequest;
}
- private byte[] parseSearchSource(RestRequest request) {
+ private SearchSourceBuilder parseSearchSource(RestRequest request) {
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
String queryString = request.param("q");
if (queryString != null) {
@@ -227,7 +227,6 @@ public class RestSearchAction extends BaseRestHandler {
}
}
- // TODO add different parameters to the source
- return searchSourceBuilder.build();
+ return searchSourceBuilder;
}
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/support/RestXContentBuilder.java b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/support/RestXContentBuilder.java
index 289bc995e13..494dd06b5f4 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/support/RestXContentBuilder.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/rest/action/support/RestXContentBuilder.java
@@ -32,7 +32,18 @@ import java.io.IOException;
public class RestXContentBuilder {
public static BinaryXContentBuilder restContentBuilder(RestRequest request) throws IOException {
- BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(XContentType.JSON);
+ XContentType contentType = XContentType.fromRestContentType(request.header("Content-Type"));
+ if (contentType == null) {
+ // try and guess it from the body, if exists
+ if (request.hasContent()) {
+ contentType = XContentFactory.xContentType(request.contentAsBytes());
+ }
+ }
+ if (contentType == null) {
+ // default to JSON
+ contentType = XContentType.JSON;
+ }
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
if (request.paramAsBoolean("pretty", false)) {
builder.prettyPrint();
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
index 0835f969142..bbd98384acf 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java
@@ -20,14 +20,16 @@
package org.elasticsearch.search.builder;
import org.elasticsearch.index.query.xcontent.XContentQueryBuilder;
-import org.elasticsearch.search.SearchException;
import org.elasticsearch.util.gnu.trove.TObjectFloatHashMap;
import org.elasticsearch.util.gnu.trove.TObjectFloatIterator;
+import org.elasticsearch.util.io.FastByteArrayOutputStream;
import org.elasticsearch.util.xcontent.ToXContent;
import org.elasticsearch.util.xcontent.XContentFactory;
import org.elasticsearch.util.xcontent.XContentType;
+import org.elasticsearch.util.xcontent.builder.BinaryXContentBuilder;
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -40,7 +42,7 @@ import static org.elasticsearch.util.gcommon.collect.Lists.*;
* @author kimchy (shay.banon)
* @see org.elasticsearch.action.search.SearchRequest#source(SearchSourceBuilder)
*/
-public class SearchSourceBuilder {
+public class SearchSourceBuilder implements ToXContent {
public static enum Order {
ASC,
@@ -253,87 +255,106 @@ public class SearchSourceBuilder {
return this;
}
+ public FastByteArrayOutputStream buildAsUnsafeBytes() throws SearchSourceBuilderException {
+ return buildAsUnsafeBytes(XContentType.JSON);
+ }
- public byte[] build() throws SearchException {
+ public FastByteArrayOutputStream buildAsUnsafeBytes(XContentType contentType) throws SearchSourceBuilderException {
try {
- XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
- builder.startObject();
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
+ toXContent(builder, ToXContent.EMPTY_PARAMS);
+ return builder.unsafeStream();
+ } catch (Exception e) {
+ throw new SearchSourceBuilderException("Failed to build search source", e);
+ }
+ }
- ToXContent.Params params = ToXContent.EMPTY_PARAMS;
-
- if (from != -1) {
- builder.field("from", from);
- }
- if (size != -1) {
- builder.field("size", size);
- }
- if (queryParserName != null) {
- builder.field("query_parser_name", queryParserName);
- }
-
- if (queryBuilder != null) {
- builder.field("query");
- queryBuilder.toXContent(builder, params);
- }
-
- if (explain != null) {
- builder.field("explain", explain);
- }
-
- if (fieldNames != null) {
- if (fieldNames.size() == 1) {
- builder.field("fields", fieldNames.get(0));
- } else {
- builder.startArray("fields");
- for (String fieldName : fieldNames) {
- builder.value(fieldName);
- }
- builder.endArray();
- }
- }
-
- if (sortFields != null) {
- builder.field("sort");
- builder.startObject();
- for (SortTuple sortTuple : sortFields) {
- builder.field(sortTuple.fieldName());
- builder.startObject();
- if (sortTuple.reverse) {
- builder.field("reverse", true);
- }
- if (sortTuple.type != null) {
- builder.field("type", sortTuple.type());
- }
- builder.endObject();
- }
- builder.endObject();
- }
-
- if (indexBoost != null) {
- builder.startObject("indices_boost");
- for (TObjectFloatIterator it = indexBoost.iterator(); it.hasNext();) {
- it.advance();
- builder.field(it.key(), it.value());
- }
- builder.endObject();
- }
-
- if (facetsBuilder != null) {
- facetsBuilder.toXContent(builder, params);
- }
-
- if (highlightBuilder != null) {
- highlightBuilder.toXContent(builder, params);
- }
-
- builder.endObject();
+ public byte[] buildAsBytes() throws SearchSourceBuilderException {
+ return buildAsBytes(XContentType.JSON);
+ }
+ public byte[] buildAsBytes(XContentType contentType) throws SearchSourceBuilderException {
+ try {
+ XContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
+ toXContent(builder, EMPTY_PARAMS);
return builder.copiedBytes();
} catch (Exception e) {
throw new SearchSourceBuilderException("Failed to build search source", e);
}
}
+
+ @Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
+ builder.startObject();
+
+ if (from != -1) {
+ builder.field("from", from);
+ }
+ if (size != -1) {
+ builder.field("size", size);
+ }
+ if (queryParserName != null) {
+ builder.field("query_parser_name", queryParserName);
+ }
+
+ if (queryBuilder != null) {
+ builder.field("query");
+ queryBuilder.toXContent(builder, params);
+ }
+
+ if (explain != null) {
+ builder.field("explain", explain);
+ }
+
+ if (fieldNames != null) {
+ if (fieldNames.size() == 1) {
+ builder.field("fields", fieldNames.get(0));
+ } else {
+ builder.startArray("fields");
+ for (String fieldName : fieldNames) {
+ builder.value(fieldName);
+ }
+ builder.endArray();
+ }
+ }
+
+ if (sortFields != null) {
+ builder.field("sort");
+ builder.startObject();
+ for (SortTuple sortTuple : sortFields) {
+ builder.field(sortTuple.fieldName());
+ builder.startObject();
+ if (sortTuple.reverse) {
+ builder.field("reverse", true);
+ }
+ if (sortTuple.type != null) {
+ builder.field("type", sortTuple.type());
+ }
+ builder.endObject();
+ }
+ builder.endObject();
+ }
+
+ if (indexBoost != null) {
+ builder.startObject("indices_boost");
+ for (TObjectFloatIterator it = indexBoost.iterator(); it.hasNext();) {
+ it.advance();
+ builder.field(it.key(), it.value());
+ }
+ builder.endObject();
+ }
+
+ if (facetsBuilder != null) {
+ facetsBuilder.toXContent(builder, params);
+ }
+
+ if (highlightBuilder != null) {
+ highlightBuilder.toXContent(builder, params);
+ }
+
+ builder.endObject();
+ }
+
private static class SortTuple {
private final String fieldName;
private final boolean reverse;
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/ToXContent.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/ToXContent.java
index b70264878b1..89d26d1131c 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/ToXContent.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/ToXContent.java
@@ -25,6 +25,8 @@ import java.io.IOException;
import java.util.Map;
/**
+ * An interface allowing to transfer an object to "XContent" using an {@link org.elasticsearch.util.xcontent.builder.XContentBuilder}.
+ *
* @author kimchy (shay.banon)
*/
public interface ToXContent {
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContent.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContent.java
index 10a35840efe..c8ffc1e614c 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContent.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContent.java
@@ -22,23 +22,49 @@ package org.elasticsearch.util.xcontent;
import java.io.*;
/**
+ * A generic abstraction on top of handling content, inspired by JSON and pull parsing.
+ *
* @author kimchy (shay.banon)
*/
public interface XContent {
+ /**
+ * The type this content handles and produces.
+ */
XContentType type();
+ /**
+ * Creates a new generator using the provided output stream.
+ */
XContentGenerator createGenerator(OutputStream os) throws IOException;
+ /**
+ * Creates a new generator using the provided writer.
+ */
XContentGenerator createGenerator(Writer writer) throws IOException;
+ /**
+ * Creates a parser over the provided string content.
+ */
XContentParser createParser(String content) throws IOException;
+ /**
+ * Creates a parser over the provided input stream.
+ */
XContentParser createParser(InputStream is) throws IOException;
+ /**
+ * Creates a parser over the provided bytes.
+ */
XContentParser createParser(byte[] data) throws IOException;
+ /**
+ * Creates a parser over the provided bytes.
+ */
XContentParser createParser(byte[] data, int offset, int length) throws IOException;
+ /**
+ * Creates a parser over the provided reader.
+ */
XContentParser createParser(Reader reader) throws IOException;
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentFactory.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentFactory.java
index 0618a0b4601..a2fdbaca8b8 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentFactory.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentFactory.java
@@ -20,14 +20,17 @@
package org.elasticsearch.util.xcontent;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
-import org.elasticsearch.ElasticSearchIllegalStateException;
import org.elasticsearch.util.xcontent.builder.BinaryXContentBuilder;
import org.elasticsearch.util.xcontent.builder.TextXContentBuilder;
import org.elasticsearch.util.xcontent.json.JsonXContent;
+import org.elasticsearch.util.xcontent.xson.XsonType;
+import org.elasticsearch.util.xcontent.xson.XsonXContent;
import java.io.IOException;
/**
+ * A one stop to use {@link org.elasticsearch.util.xcontent.XContent} and {@link org.elasticsearch.util.xcontent.builder.XContentBuilder}.
+ *
* @author kimchy (shay.banon)
*/
public class XContentFactory {
@@ -37,28 +40,52 @@ public class XContentFactory {
private static final XContent[] contents;
static {
- contents = new XContent[1];
+ contents = new XContent[2];
contents[0] = new JsonXContent();
+ contents[1] = new XsonXContent();
}
+ /**
+ * Returns a binary content builder using JSON format ({@link org.elasticsearch.util.xcontent.XContentType#JSON}.
+ */
public static BinaryXContentBuilder jsonBuilder() throws IOException {
return contentBinaryBuilder(XContentType.JSON);
}
+ /**
+ * Returns a binary content builder using XSON format ({@link org.elasticsearch.util.xcontent.XContentType#XSON}.
+ */
+ public static BinaryXContentBuilder xsonBuilder() throws IOException {
+ return contentBinaryBuilder(XContentType.XSON);
+ }
+
+ /**
+ * Returns a binary content builder for the provided content type.
+ */
public static BinaryXContentBuilder contentBuilder(XContentType type) throws IOException {
if (type == XContentType.JSON) {
return JsonXContent.contentBinaryBuilder();
+ } else if (type == XContentType.XSON) {
+ return XsonXContent.contentBinaryBuilder();
}
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
}
+ /**
+ * Returns a binary content builder for the provided content type.
+ */
public static BinaryXContentBuilder contentBinaryBuilder(XContentType type) throws IOException {
if (type == XContentType.JSON) {
return JsonXContent.contentBinaryBuilder();
+ } else if (type == XContentType.XSON) {
+ return XsonXContent.contentBinaryBuilder();
}
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
}
+ /**
+ * Returns a textual content builder for the provided content type. Note, XSON does not support this... .
+ */
public static TextXContentBuilder contentTextBuilder(XContentType type) throws IOException {
if (type == XContentType.JSON) {
return JsonXContent.contentTextBuilder();
@@ -66,10 +93,16 @@ public class XContentFactory {
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
}
+ /**
+ * Returns the {@link org.elasticsearch.util.xcontent.XContent} for the provided content type.
+ */
public static XContent xContent(XContentType type) {
return contents[type.index()];
}
+ /**
+ * Guesses the content type based on the provided char sequence.
+ */
public static XContentType xContentType(CharSequence content) {
int length = content.length() < GUESS_HEADER_LENGTH ? content.length() : GUESS_HEADER_LENGTH;
for (int i = 0; i < length; i++) {
@@ -78,32 +111,50 @@ public class XContentFactory {
return XContentType.JSON;
}
}
- throw new ElasticSearchIllegalStateException("Failed to derive xContent from byte stream");
+ return null;
}
+ /**
+ * Guesses the content (type) based on the provided char sequence.
+ */
public static XContent xContent(CharSequence content) {
return xContent(xContentType(content));
}
+ /**
+ * Guesses the content type based on the provided bytes.
+ */
public static XContent xContent(byte[] data) {
return xContent(data, 0, data.length);
}
+ /**
+ * Guesses the content type based on the provided bytes.
+ */
public static XContent xContent(byte[] data, int offset, int length) {
return xContent(xContentType(data, offset, length));
}
+ /**
+ * Guesses the content type based on the provided bytes.
+ */
public static XContentType xContentType(byte[] data) {
return xContentType(data, 0, data.length);
}
+ /**
+ * Guesses the content type based on the provided bytes.
+ */
public static XContentType xContentType(byte[] data, int offset, int length) {
length = length < GUESS_HEADER_LENGTH ? length : GUESS_HEADER_LENGTH;
+ if (length > 1 && data[0] == XsonType.HEADER) {
+ return XContentType.XSON;
+ }
for (int i = offset; i < length; i++) {
if (data[i] == '{') {
return XContentType.JSON;
}
}
- throw new ElasticSearchIllegalStateException("Failed to derive xContent from byte stream");
+ return null;
}
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentGenerator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentGenerator.java
index ca3be3e5df6..a0a847b550a 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentGenerator.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentGenerator.java
@@ -20,8 +20,6 @@
package org.elasticsearch.util.xcontent;
import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
/**
* @author kimchy (shay.banon)
@@ -54,14 +52,10 @@ public interface XContentGenerator {
void writeNumber(long v) throws IOException;
- void writeNumber(BigInteger v) throws IOException;
-
void writeNumber(double d) throws IOException;
void writeNumber(float f) throws IOException;
- void writeNumber(BigDecimal dec) throws IOException;
-
void writeBoolean(boolean state) throws IOException;
void writeNull() throws IOException;
@@ -81,8 +75,6 @@ public interface XContentGenerator {
void writeNumberField(String fieldName, float value) throws IOException;
- void writeNumberField(String fieldName, BigDecimal value) throws IOException;
-
void writeBinaryField(String fieldName, byte[] data) throws IOException;
void writeArrayFieldStart(String fieldName) throws IOException;
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentParser.java
index 4473e10bdaf..1d71be351d9 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentParser.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentParser.java
@@ -20,7 +20,6 @@
package org.elasticsearch.util.xcontent;
import java.io.IOException;
-import java.math.BigInteger;
import java.util.Map;
/**
@@ -78,7 +77,7 @@ public interface XContentParser {
}
enum NumberType {
- INT, LONG, BIG_INTEGER, FLOAT, DOUBLE, BIG_DECIMAL
+ INT, LONG, FLOAT, DOUBLE
}
XContentType contentType();
@@ -107,7 +106,11 @@ public interface XContentParser {
NumberType numberType() throws IOException;
- byte byteValue() throws IOException;
+ /**
+ * Is the number type estimated or not (i.e. an int might actually be a long, its just low enough
+ * to be an int).
+ */
+ boolean estimatedNumberType();
short shortValue() throws IOException;
@@ -115,14 +118,10 @@ public interface XContentParser {
long longValue() throws IOException;
- BigInteger bigIntegerValue() throws IOException;
-
float floatValue() throws IOException;
double doubleValue() throws IOException;
- java.math.BigDecimal decimalValue() throws IOException;
-
boolean booleanValue() throws IOException;
byte[] binaryValue() throws IOException;
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentType.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentType.java
index 64e387f5da9..634d24511cd 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentType.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/XContentType.java
@@ -24,7 +24,23 @@ package org.elasticsearch.util.xcontent;
*/
public enum XContentType {
- JSON(0);
+ JSON(0),
+ XSON(1);
+
+ public static XContentType fromRestContentType(String contentType) {
+ if (contentType == null) {
+ return null;
+ }
+ if ("application/json".equals(contentType)) {
+ return JSON;
+ }
+
+ if ("application/xson".equals(contentType)) {
+ return XSON;
+ }
+
+ return null;
+ }
private int index;
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContent.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContent.java
index 955840dd4ac..84facf62b4c 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContent.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContent.java
@@ -36,6 +36,8 @@ import org.elasticsearch.util.xcontent.builder.TextXContentBuilder;
import java.io.*;
/**
+ * A JSON based content implementation using Jackson.
+ *
* @author kimchy (shay.banon)
*/
public class JsonXContent implements XContent {
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentGenerator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentGenerator.java
index 9c2e653f13d..7187466a9f1 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentGenerator.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentGenerator.java
@@ -24,8 +24,6 @@ import org.elasticsearch.util.xcontent.XContentGenerator;
import org.elasticsearch.util.xcontent.XContentType;
import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
/**
* @author kimchy (shay.banon)
@@ -90,10 +88,6 @@ public class JsonXContentGenerator implements XContentGenerator {
generator.writeNumber(v);
}
- @Override public void writeNumber(BigInteger v) throws IOException {
- generator.writeNumber(v);
- }
-
@Override public void writeNumber(double d) throws IOException {
generator.writeNumber(d);
}
@@ -102,10 +96,6 @@ public class JsonXContentGenerator implements XContentGenerator {
generator.writeNumber(f);
}
- @Override public void writeNumber(BigDecimal dec) throws IOException {
- generator.writeNumber(dec);
- }
-
@Override public void writeBoolean(boolean state) throws IOException {
generator.writeBoolean(state);
}
@@ -142,10 +132,6 @@ public class JsonXContentGenerator implements XContentGenerator {
generator.writeNumberField(fieldName, value);
}
- @Override public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
- generator.writeNumberField(fieldName, value);
- }
-
@Override public void writeBinaryField(String fieldName, byte[] data) throws IOException {
generator.writeBinaryField(fieldName, data);
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentParser.java
index 9337428557a..4c545fa1327 100644
--- a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentParser.java
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/json/JsonXContentParser.java
@@ -22,14 +22,10 @@ package org.elasticsearch.util.xcontent.json;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.elasticsearch.ElasticSearchIllegalStateException;
-import org.elasticsearch.util.xcontent.XContentParser;
import org.elasticsearch.util.xcontent.XContentType;
import org.elasticsearch.util.xcontent.support.AbstractXContentParser;
import java.io.IOException;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Map;
/**
* @author kimchy (shay.banon)
@@ -62,6 +58,10 @@ public class JsonXContentParser extends AbstractXContentParser {
return convertNumberType(parser.getNumberType());
}
+ @Override public boolean estimatedNumberType() {
+ return true;
+ }
+
@Override public String currentName() throws IOException {
return parser.getCurrentName();
}
@@ -90,10 +90,6 @@ public class JsonXContentParser extends AbstractXContentParser {
return parser.getNumberValue();
}
- @Override public byte byteValue() throws IOException {
- return parser.getByteValue();
- }
-
@Override public short doShortValue() throws IOException {
return parser.getShortValue();
}
@@ -106,10 +102,6 @@ public class JsonXContentParser extends AbstractXContentParser {
return parser.getLongValue();
}
- @Override public BigInteger bigIntegerValue() throws IOException {
- return parser.getBigIntegerValue();
- }
-
@Override public float doFloatValue() throws IOException {
return parser.getFloatValue();
}
@@ -118,10 +110,6 @@ public class JsonXContentParser extends AbstractXContentParser {
return parser.getDoubleValue();
}
- @Override public BigDecimal decimalValue() throws IOException {
- return parser.getDecimalValue();
- }
-
@Override public byte[] binaryValue() throws IOException {
return parser.getBinaryValue();
}
@@ -144,10 +132,6 @@ public class JsonXContentParser extends AbstractXContentParser {
return NumberType.FLOAT;
case DOUBLE:
return NumberType.DOUBLE;
- case BIG_DECIMAL:
- return NumberType.BIG_DECIMAL;
- case BIG_INTEGER:
- return NumberType.BIG_INTEGER;
}
throw new ElasticSearchIllegalStateException("No matching token for number_type [" + numberType + "]");
}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/support/AbstractXContentGenerator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/support/AbstractXContentGenerator.java
new file mode 100644
index 00000000000..31c01c239eb
--- /dev/null
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/support/AbstractXContentGenerator.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.util.xcontent.support;
+
+import org.elasticsearch.util.xcontent.XContentGenerator;
+
+import java.io.IOException;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public abstract class AbstractXContentGenerator implements XContentGenerator {
+
+ @Override public void writeStringField(String fieldName, String value) throws IOException {
+ writeFieldName(fieldName);
+ writeString(value);
+ }
+
+ @Override public void writeBooleanField(String fieldName, boolean value) throws IOException {
+ writeFieldName(fieldName);
+ writeBoolean(value);
+ }
+
+ @Override public void writeNullField(String fieldName) throws IOException {
+ writeFieldName(fieldName);
+ writeNull();
+ }
+
+ @Override public void writeNumberField(String fieldName, int value) throws IOException {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ @Override public void writeNumberField(String fieldName, long value) throws IOException {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ @Override public void writeNumberField(String fieldName, double value) throws IOException {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ @Override public void writeNumberField(String fieldName, float value) throws IOException {
+ writeFieldName(fieldName);
+ writeNumber(value);
+ }
+
+ @Override public void writeBinaryField(String fieldName, byte[] data) throws IOException {
+ writeFieldName(fieldName);
+ writeBinary(data);
+ }
+
+ @Override public void writeArrayFieldStart(String fieldName) throws IOException {
+ writeFieldName(fieldName);
+ writeStartArray();
+ }
+
+ @Override public void writeObjectFieldStart(String fieldName) throws IOException {
+ writeFieldName(fieldName);
+ writeStartObject();
+ }
+}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonType.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonType.java
new file mode 100644
index 00000000000..a8207ac2f46
--- /dev/null
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonType.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.util.xcontent.xson;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public enum XsonType {
+
+ START_ARRAY((byte) 0x01),
+ END_ARRAY((byte) 0x02),
+ START_OBJECT((byte) 0x03),
+ END_OBJECT((byte) 0x04),
+ FIELD_NAME((byte) 0x05),
+ VALUE_STRING((byte) 0x06),
+ VALUE_BINARY((byte) 0x07),
+ VALUE_INTEGER((byte) 0x08),
+ VALUE_LONG((byte) 0x09),
+ VALUE_FLOAT((byte) 0x0A),
+ VALUE_DOUBLE((byte) 0x0B),
+ VALUE_BOOLEAN((byte) 0x0C),
+ VALUE_NULL((byte) 0x0D),;
+
+ public static final int HEADER = 0x00;
+
+ private final byte code;
+
+ XsonType(byte code) {
+ this.code = code;
+ }
+
+ public byte code() {
+ return code;
+ }
+}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContent.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContent.java
new file mode 100644
index 00000000000..8826d918be4
--- /dev/null
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContent.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.util.xcontent.xson;
+
+import org.elasticsearch.ElasticSearchException;
+import org.elasticsearch.ElasticSearchIllegalStateException;
+import org.elasticsearch.util.ThreadLocals;
+import org.elasticsearch.util.io.FastByteArrayInputStream;
+import org.elasticsearch.util.xcontent.XContent;
+import org.elasticsearch.util.xcontent.XContentGenerator;
+import org.elasticsearch.util.xcontent.XContentParser;
+import org.elasticsearch.util.xcontent.XContentType;
+import org.elasticsearch.util.xcontent.builder.BinaryXContentBuilder;
+
+import java.io.*;
+
+/**
+ * A binary representation of content (basically, JSON encoded in optimized binary format).
+ *
+ * @author kimchy (shay.banon)
+ */
+public class XsonXContent implements XContent {
+
+ public static class CachedBinaryBuilder {
+
+ private static final ThreadLocal> cache = new ThreadLocal>() {
+ @Override protected ThreadLocals.CleanableValue initialValue() {
+ try {
+ BinaryXContentBuilder builder = new BinaryXContentBuilder(new XsonXContent());
+ return new ThreadLocals.CleanableValue(builder);
+ } catch (IOException e) {
+ throw new ElasticSearchException("Failed to create xson generator", e);
+ }
+ }
+ };
+
+ /**
+ * Returns the cached thread local generator, with its internal {@link StringBuilder} cleared.
+ */
+ static BinaryXContentBuilder cached() throws IOException {
+ ThreadLocals.CleanableValue cached = cache.get();
+ cached.get().reset();
+ return cached.get();
+ }
+ }
+
+ public static BinaryXContentBuilder contentBinaryBuilder() throws IOException {
+ return CachedBinaryBuilder.cached();
+ }
+
+ @Override public XContentType type() {
+ return XContentType.XSON;
+ }
+
+ @Override public XContentGenerator createGenerator(OutputStream os) throws IOException {
+ return new XsonXContentGenerator(os);
+ }
+
+ @Override public XContentGenerator createGenerator(Writer writer) throws IOException {
+ throw new ElasticSearchIllegalStateException("Can't create generator over xson with textual data");
+ }
+
+ @Override public XContentParser createParser(String content) throws IOException {
+ throw new ElasticSearchIllegalStateException("Can't create parser over xson for textual data");
+ }
+
+ @Override public XContentParser createParser(InputStream is) throws IOException {
+ return new XsonXContentParser(is);
+ }
+
+ @Override public XContentParser createParser(byte[] data) throws IOException {
+ return new XsonXContentParser(new FastByteArrayInputStream(data));
+ }
+
+ @Override public XContentParser createParser(byte[] data, int offset, int length) throws IOException {
+ return new XsonXContentParser(new FastByteArrayInputStream(data, offset, length));
+ }
+
+ @Override public XContentParser createParser(Reader reader) throws IOException {
+ throw new ElasticSearchIllegalStateException("Can't create parser over xson for textual data");
+ }
+}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContentGenerator.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContentGenerator.java
new file mode 100644
index 00000000000..b9da606bb49
--- /dev/null
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContentGenerator.java
@@ -0,0 +1,211 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.util.xcontent.xson;
+
+import org.apache.lucene.util.UnicodeUtil;
+import org.elasticsearch.util.Unicode;
+import org.elasticsearch.util.xcontent.XContentGenerator;
+import org.elasticsearch.util.xcontent.XContentType;
+import org.elasticsearch.util.xcontent.support.AbstractXContentGenerator;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class XsonXContentGenerator extends AbstractXContentGenerator implements XContentGenerator {
+
+ private final OutputStream out;
+
+ public XsonXContentGenerator(OutputStream out) throws IOException {
+ this.out = out;
+ outInt(XsonType.HEADER);
+ }
+
+ @Override public XContentType contentType() {
+ return XContentType.XSON;
+ }
+
+ @Override public void usePrettyPrint() {
+ // irrelevant
+ }
+
+ @Override public void writeStartArray() throws IOException {
+ out.write(XsonType.START_ARRAY.code());
+ }
+
+ @Override public void writeEndArray() throws IOException {
+ out.write(XsonType.END_ARRAY.code());
+ }
+
+ @Override public void writeStartObject() throws IOException {
+ out.write(XsonType.START_OBJECT.code());
+ }
+
+ @Override public void writeEndObject() throws IOException {
+ out.write(XsonType.END_OBJECT.code());
+ }
+
+ @Override public void writeFieldName(String name) throws IOException {
+ out.write(XsonType.FIELD_NAME.code());
+ outUTF(name);
+ }
+
+ @Override public void writeString(String text) throws IOException {
+ out.write(XsonType.VALUE_STRING.code());
+ outUTF(text);
+ }
+
+ @Override public void writeString(char[] text, int offset, int len) throws IOException {
+ writeString(new String(text, offset, len));
+ }
+
+ @Override public void writeBinary(byte[] data, int offset, int len) throws IOException {
+ out.write(XsonType.VALUE_BINARY.code());
+ outVInt(len);
+ out.write(data, offset, len);
+ }
+
+ @Override public void writeBinary(byte[] data) throws IOException {
+ out.write(XsonType.VALUE_BINARY.code());
+ outVInt(data.length);
+ out.write(data);
+ }
+
+ @Override public void writeNumber(int v) throws IOException {
+ out.write(XsonType.VALUE_INTEGER.code());
+ outInt(v);
+ }
+
+ @Override public void writeNumber(long v) throws IOException {
+ out.write(XsonType.VALUE_LONG.code());
+ outLong(v);
+ }
+
+ @Override public void writeNumber(double d) throws IOException {
+ out.write(XsonType.VALUE_DOUBLE.code());
+ outDouble(d);
+ }
+
+ @Override public void writeNumber(float f) throws IOException {
+ out.write(XsonType.VALUE_FLOAT.code());
+ outFloat(f);
+ }
+
+ @Override public void writeBoolean(boolean state) throws IOException {
+ out.write(XsonType.VALUE_BOOLEAN.code());
+ outBoolean(state);
+ }
+
+ @Override public void writeNull() throws IOException {
+ out.write(XsonType.VALUE_NULL.code());
+ }
+
+ @Override public void writeRawFieldStart(String fieldName) throws IOException {
+ writeFieldName(fieldName);
+ }
+
+ @Override public void flush() throws IOException {
+ out.flush();
+ }
+
+ @Override public void close() throws IOException {
+ out.close();
+ }
+
+
+ private void outShort(short v) throws IOException {
+ out.write((byte) (v >> 8));
+ out.write((byte) v);
+ }
+
+ /**
+ * Writes an int as four bytes.
+ */
+ private void outInt(int i) throws IOException {
+ out.write((byte) (i >> 24));
+ out.write((byte) (i >> 16));
+ out.write((byte) (i >> 8));
+ out.write((byte) i);
+ }
+
+ /**
+ * Writes an int in a variable-length format. Writes between one and
+ * five bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ */
+ private void outVInt(int i) throws IOException {
+ while ((i & ~0x7F) != 0) {
+ out.write((byte) ((i & 0x7f) | 0x80));
+ i >>>= 7;
+ }
+ out.write((byte) i);
+ }
+
+ /**
+ * Writes a long as eight bytes.
+ */
+ private void outLong(long i) throws IOException {
+ outInt((int) (i >> 32));
+ outInt((int) i);
+ }
+
+ /**
+ * Writes an long in a variable-length format. Writes between one and five
+ * bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ */
+ private void outVLong(long i) throws IOException {
+ while ((i & ~0x7F) != 0) {
+ out.write((byte) ((i & 0x7f) | 0x80));
+ i >>>= 7;
+ }
+ out.write((byte) i);
+ }
+
+ /**
+ * Writes a string.
+ */
+ private void outUTF(String s) throws IOException {
+ UnicodeUtil.UTF8Result utf8Result = Unicode.unsafeFromStringAsUtf8(s);
+ outVInt(utf8Result.length);
+ out.write(utf8Result.result, 0, utf8Result.length);
+ }
+
+ private void outFloat(float v) throws IOException {
+ outInt(Float.floatToIntBits(v));
+ }
+
+ private void outDouble(double v) throws IOException {
+ outLong(Double.doubleToLongBits(v));
+ }
+
+
+ private static byte ZERO = 0;
+ private static byte ONE = 1;
+
+ /**
+ * Writes a boolean.
+ */
+ private void outBoolean(boolean b) throws IOException {
+ out.write(b ? ONE : ZERO);
+ }
+}
diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContentParser.java b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContentParser.java
new file mode 100644
index 00000000000..b33d8cb2030
--- /dev/null
+++ b/modules/elasticsearch/src/main/java/org/elasticsearch/util/xcontent/xson/XsonXContentParser.java
@@ -0,0 +1,390 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.util.xcontent.xson;
+
+import org.apache.lucene.util.StringHelper;
+import org.elasticsearch.util.ThreadLocals;
+import org.elasticsearch.util.Unicode;
+import org.elasticsearch.util.xcontent.XContentType;
+import org.elasticsearch.util.xcontent.support.AbstractXContentParser;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class XsonXContentParser extends AbstractXContentParser {
+
+ private static ThreadLocal> cachedBytes = new ThreadLocal>() {
+ @Override protected ThreadLocals.CleanableValue initialValue() {
+ return new ThreadLocals.CleanableValue(new byte[256]);
+ }
+ };
+
+ private final InputStream is;
+
+ private Token currentToken;
+
+ private XsonType xsonType;
+
+ private NumberType currentNumberType;
+
+ private String currentName;
+
+ private Unicode.UTF16Result utf16Result;
+
+ private int valueInt;
+ private long valueLong;
+ private float valueFloat;
+ private double valueDouble;
+ private boolean valueBoolean;
+ private byte[] valueBytes;
+
+ public XsonXContentParser(InputStream is) throws IOException {
+ this.is = is;
+ int header = inInt();
+ if (header != XsonType.HEADER) {
+ throw new IOException("Not xson type header");
+ }
+ }
+
+ @Override public XContentType contentType() {
+ return XContentType.XSON;
+ }
+
+ @Override public Token nextToken() throws IOException {
+ byte tokenType = (byte) is.read();
+ if (tokenType == -1) {
+ xsonType = null;
+ currentToken = null;
+ currentNumberType = null;
+ return null;
+ } else if (tokenType == XsonType.START_ARRAY.code()) {
+ xsonType = XsonType.START_ARRAY;
+ currentToken = Token.START_ARRAY;
+ } else if (tokenType == XsonType.END_ARRAY.code()) {
+ xsonType = XsonType.END_ARRAY;
+ currentToken = Token.END_ARRAY;
+ } else if (tokenType == XsonType.START_OBJECT.code()) {
+ xsonType = XsonType.START_OBJECT;
+ currentToken = Token.START_OBJECT;
+ } else if (tokenType == XsonType.END_OBJECT.code()) {
+ xsonType = XsonType.END_OBJECT;
+ currentToken = Token.END_OBJECT;
+ } else if (tokenType == XsonType.FIELD_NAME.code()) {
+ xsonType = XsonType.FIELD_NAME;
+ currentToken = Token.FIELD_NAME;
+ // read the field name (interned)
+ currentName = StringHelper.intern(inUTF());
+ } else if (tokenType == XsonType.VALUE_STRING.code()) {
+ xsonType = XsonType.VALUE_STRING;
+ currentToken = Token.VALUE_STRING;
+ inUtf16();
+ } else if (tokenType == XsonType.VALUE_BINARY.code()) {
+ xsonType = XsonType.VALUE_BINARY;
+ currentToken = Token.VALUE_STRING;
+ int length = inVInt();
+ valueBytes = new byte[length];
+ inBytes(valueBytes, 0, length);
+ } else if (tokenType == XsonType.VALUE_INTEGER.code()) {
+ xsonType = XsonType.VALUE_INTEGER;
+ currentToken = Token.VALUE_NUMBER;
+ currentNumberType = NumberType.INT;
+ valueInt = inInt();
+ } else if (tokenType == XsonType.VALUE_LONG.code()) {
+ xsonType = XsonType.VALUE_LONG;
+ currentToken = Token.VALUE_NUMBER;
+ currentNumberType = NumberType.LONG;
+ valueLong = inLong();
+ } else if (tokenType == XsonType.VALUE_FLOAT.code()) {
+ xsonType = XsonType.VALUE_FLOAT;
+ currentToken = Token.VALUE_NUMBER;
+ currentNumberType = NumberType.FLOAT;
+ valueFloat = inFloat();
+ } else if (tokenType == XsonType.VALUE_DOUBLE.code()) {
+ xsonType = XsonType.VALUE_DOUBLE;
+ currentToken = Token.VALUE_NUMBER;
+ currentNumberType = NumberType.DOUBLE;
+ valueDouble = inDouble();
+ } else if (tokenType == XsonType.VALUE_BOOLEAN.code()) {
+ xsonType = XsonType.VALUE_BOOLEAN;
+ currentToken = Token.VALUE_BOOLEAN;
+ valueBoolean = inBoolean();
+ } else if (tokenType == XsonType.VALUE_NULL.code()) {
+ xsonType = XsonType.VALUE_NULL;
+ currentToken = Token.VALUE_NULL;
+ }
+ return currentToken;
+ }
+
+ @Override public void skipChildren() throws IOException {
+ if (xsonType != XsonType.START_OBJECT && xsonType != XsonType.START_ARRAY) {
+ return;
+ }
+ int open = 1;
+
+ /* Since proper matching of start/end markers is handled
+ * by nextToken(), we'll just count nesting levels here
+ */
+ while (true) {
+ nextToken();
+ if (xsonType == null) {
+ return;
+ }
+ switch (xsonType) {
+ case START_OBJECT:
+ case START_ARRAY:
+ ++open;
+ break;
+ case END_OBJECT:
+ case END_ARRAY:
+ if (--open == 0) {
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ @Override public Token currentToken() {
+ return currentToken;
+ }
+
+ @Override public String currentName() throws IOException {
+ return currentName;
+ }
+
+ @Override public String text() throws IOException {
+ return new String(utf16Result.result, 0, utf16Result.length);
+ }
+
+ @Override public char[] textCharacters() throws IOException {
+ return utf16Result.result;
+ }
+
+ @Override public int textLength() throws IOException {
+ return utf16Result.length;
+ }
+
+ @Override public int textOffset() throws IOException {
+ return 0;
+ }
+
+ @Override public Number numberValue() throws IOException {
+ if (currentNumberType == NumberType.INT) {
+ return valueInt;
+ } else if (currentNumberType == NumberType.LONG) {
+ return valueLong;
+ } else if (currentNumberType == NumberType.FLOAT) {
+ return valueFloat;
+ } else if (currentNumberType == NumberType.DOUBLE) {
+ return valueDouble;
+ }
+ throw new IOException("No number type");
+ }
+
+ @Override public NumberType numberType() throws IOException {
+ return currentNumberType;
+ }
+
+ @Override public boolean estimatedNumberType() {
+ return false;
+ }
+
+ @Override public byte[] binaryValue() throws IOException {
+ return valueBytes;
+ }
+
+ @Override protected boolean doBooleanValue() throws IOException {
+ return valueBoolean;
+ }
+
+ @Override protected short doShortValue() throws IOException {
+ if (currentNumberType == NumberType.INT) {
+ return (short) valueInt;
+ } else if (currentNumberType == NumberType.LONG) {
+ return (short) valueLong;
+ } else if (currentNumberType == NumberType.FLOAT) {
+ return (short) valueFloat;
+ } else if (currentNumberType == NumberType.DOUBLE) {
+ return (short) valueDouble;
+ }
+ throw new IOException("No number type");
+ }
+
+ @Override protected int doIntValue() throws IOException {
+ if (currentNumberType == NumberType.INT) {
+ return valueInt;
+ } else if (currentNumberType == NumberType.LONG) {
+ return (int) valueLong;
+ } else if (currentNumberType == NumberType.FLOAT) {
+ return (int) valueFloat;
+ } else if (currentNumberType == NumberType.DOUBLE) {
+ return (int) valueDouble;
+ }
+ throw new IOException("No number type");
+ }
+
+ @Override protected long doLongValue() throws IOException {
+ if (currentNumberType == NumberType.LONG) {
+ return valueLong;
+ } else if (currentNumberType == NumberType.INT) {
+ return (long) valueInt;
+ } else if (currentNumberType == NumberType.FLOAT) {
+ return (long) valueFloat;
+ } else if (currentNumberType == NumberType.DOUBLE) {
+ return (long) valueDouble;
+ }
+ throw new IOException("No number type");
+ }
+
+ @Override protected float doFloatValue() throws IOException {
+ if (currentNumberType == NumberType.FLOAT) {
+ return valueFloat;
+ } else if (currentNumberType == NumberType.INT) {
+ return (float) valueInt;
+ } else if (currentNumberType == NumberType.LONG) {
+ return (float) valueLong;
+ } else if (currentNumberType == NumberType.DOUBLE) {
+ return (float) valueDouble;
+ }
+ throw new IOException("No number type");
+ }
+
+ @Override protected double doDoubleValue() throws IOException {
+ if (currentNumberType == NumberType.DOUBLE) {
+ return valueDouble;
+ } else if (currentNumberType == NumberType.INT) {
+ return (double) valueInt;
+ } else if (currentNumberType == NumberType.FLOAT) {
+ return (double) valueFloat;
+ } else if (currentNumberType == NumberType.LONG) {
+ return (double) valueLong;
+ }
+ throw new IOException("No number type");
+ }
+
+ @Override public void close() {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ private short inShort() throws IOException {
+ return (short) (((is.read() & 0xFF) << 8) | (is.read() & 0xFF));
+ }
+
+ /**
+ * Reads four bytes and returns an int.
+ */
+ private int inInt() throws IOException {
+ return ((is.read() & 0xFF) << 24) | ((is.read() & 0xFF) << 16)
+ | ((is.read() & 0xFF) << 8) | (is.read() & 0xFF);
+ }
+
+ /**
+ * Reads an int stored in variable-length format. Reads between one and
+ * five bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ */
+ private int inVInt() throws IOException {
+ int b = is.read();
+ int i = b & 0x7F;
+ for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = is.read();
+ i |= (b & 0x7F) << shift;
+ }
+ return i;
+ }
+
+ /**
+ * Reads eight bytes and returns a long.
+ */
+ private long inLong() throws IOException {
+ return (((long) inInt()) << 32) | (inInt() & 0xFFFFFFFFL);
+ }
+
+ /**
+ * Reads a long stored in variable-length format. Reads between one and
+ * nine bytes. Smaller values take fewer bytes. Negative numbers are not
+ * supported.
+ */
+ private long readVLong() throws IOException {
+ int b = is.read();
+ long i = b & 0x7F;
+ for (int shift = 7; (b & 0x80) != 0; shift += 7) {
+ b = is.read();
+ i |= (b & 0x7FL) << shift;
+ }
+ return i;
+ }
+
+ private String inUTF() throws IOException {
+ inUtf16();
+ return new String(utf16Result.result, 0, utf16Result.length);
+ }
+
+ /**
+ * Reads a string.
+ */
+ private void inUtf16() throws IOException {
+ int length = inVInt();
+ byte[] bytes = cachedBytes.get().get();
+ if (bytes == null || length > bytes.length) {
+ bytes = new byte[(int) (length * 1.25)];
+ cachedBytes.get().set(bytes);
+ }
+ inBytes(bytes, 0, length);
+ utf16Result = Unicode.fromBytesAsUtf16(bytes, 0, length);
+ }
+
+ private float inFloat() throws IOException {
+ return Float.intBitsToFloat(inInt());
+ }
+
+ private double inDouble() throws IOException {
+ return Double.longBitsToDouble(inLong());
+ }
+
+ /**
+ * Reads a boolean.
+ */
+ private boolean inBoolean() throws IOException {
+ byte ch = (byte) is.read();
+ if (ch < 0)
+ throw new EOFException();
+ return (ch != 0);
+ }
+
+ private void inBytes(byte[] b, int offset, int len) throws IOException {
+ int n = 0;
+ while (n < len) {
+ int count = is.read(b, offset + n, len - n);
+ if (count < 0)
+ throw new EOFException();
+ n += count;
+ }
+ }
+
+}
diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java
index 95d2a5e5839..19085f5575c 100644
--- a/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java
+++ b/modules/elasticsearch/src/test/java/org/elasticsearch/index/query/xcontent/SimpleIndexQueryParserTests.java
@@ -606,7 +606,7 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanTermQuery.class));
SpanTermQuery termQuery = (SpanTermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
- assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
+ assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
}
@Test public void testSpanTermQuery() throws IOException {
@@ -616,7 +616,7 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanTermQuery.class));
SpanTermQuery termQuery = (SpanTermQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
- assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
+ assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
}
@Test public void testSpanNotQueryBuilder() throws IOException {
@@ -625,8 +625,8 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanNotQuery.class));
SpanNotQuery spanNotQuery = (SpanNotQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
- assertThat(((SpanTermQuery) spanNotQuery.getInclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
- assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
+ assertThat(((SpanTermQuery) spanNotQuery.getInclude()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
}
@Test public void testSpanNotQuery() throws IOException {
@@ -636,8 +636,8 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanNotQuery.class));
SpanNotQuery spanNotQuery = (SpanNotQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
- assertThat(((SpanTermQuery) spanNotQuery.getInclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
- assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
+ assertThat(((SpanTermQuery) spanNotQuery.getInclude()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
}
@Test public void testSpanFirstQueryBuilder() throws IOException {
@@ -646,7 +646,7 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanFirstQuery.class));
SpanFirstQuery spanFirstQuery = (SpanFirstQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
- assertThat(((SpanTermQuery) spanFirstQuery.getMatch()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanFirstQuery.getMatch()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(spanFirstQuery.getEnd(), equalTo(12));
}
@@ -657,7 +657,7 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanFirstQuery.class));
SpanFirstQuery spanFirstQuery = (SpanFirstQuery) parsedQuery;
// since age is automatically registered in data, we encode it as numeric
- assertThat(((SpanTermQuery) spanFirstQuery.getMatch()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanFirstQuery.getMatch()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
assertThat(spanFirstQuery.getEnd(), equalTo(12));
}
@@ -667,9 +667,9 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanNearQuery.class));
SpanNearQuery spanNearQuery = (SpanNearQuery) parsedQuery;
assertThat(spanNearQuery.getClauses().length, equalTo(3));
- assertThat(((SpanTermQuery) spanNearQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
- assertThat(((SpanTermQuery) spanNearQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
- assertThat(((SpanTermQuery) spanNearQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(36))));
+ assertThat(((SpanTermQuery) spanNearQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanNearQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
+ assertThat(((SpanTermQuery) spanNearQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(36))));
assertThat(spanNearQuery.isInOrder(), equalTo(false));
}
@@ -680,9 +680,9 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanNearQuery.class));
SpanNearQuery spanNearQuery = (SpanNearQuery) parsedQuery;
assertThat(spanNearQuery.getClauses().length, equalTo(3));
- assertThat(((SpanTermQuery) spanNearQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
- assertThat(((SpanTermQuery) spanNearQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
- assertThat(((SpanTermQuery) spanNearQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(36))));
+ assertThat(((SpanTermQuery) spanNearQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanNearQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
+ assertThat(((SpanTermQuery) spanNearQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(36))));
assertThat(spanNearQuery.isInOrder(), equalTo(false));
}
@@ -692,9 +692,9 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanOrQuery.class));
SpanOrQuery spanOrQuery = (SpanOrQuery) parsedQuery;
assertThat(spanOrQuery.getClauses().length, equalTo(3));
- assertThat(((SpanTermQuery) spanOrQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
- assertThat(((SpanTermQuery) spanOrQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
- assertThat(((SpanTermQuery) spanOrQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(36))));
+ assertThat(((SpanTermQuery) spanOrQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanOrQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
+ assertThat(((SpanTermQuery) spanOrQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(36))));
}
@Test public void testSpanOrQuery() throws IOException {
@@ -704,9 +704,9 @@ public class SimpleIndexQueryParserTests {
assertThat(parsedQuery, instanceOf(SpanOrQuery.class));
SpanOrQuery spanOrQuery = (SpanOrQuery) parsedQuery;
assertThat(spanOrQuery.getClauses().length, equalTo(3));
- assertThat(((SpanTermQuery) spanOrQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
- assertThat(((SpanTermQuery) spanOrQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
- assertThat(((SpanTermQuery) spanOrQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(36))));
+ assertThat(((SpanTermQuery) spanOrQuery.getClauses()[0]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(34))));
+ assertThat(((SpanTermQuery) spanOrQuery.getClauses()[1]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
+ assertThat(((SpanTermQuery) spanOrQuery.getClauses()[2]).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(36))));
}
@Test public void testQueryFilterBuilder() throws Exception {
diff --git a/modules/elasticsearch/src/test/java/org/elasticsearch/util/xcontent/xson/JsonVsXsonTests.java b/modules/elasticsearch/src/test/java/org/elasticsearch/util/xcontent/xson/JsonVsXsonTests.java
new file mode 100644
index 00000000000..81f518cb6d8
--- /dev/null
+++ b/modules/elasticsearch/src/test/java/org/elasticsearch/util/xcontent/xson/JsonVsXsonTests.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.util.xcontent.xson;
+
+import org.elasticsearch.util.io.FastByteArrayOutputStream;
+import org.elasticsearch.util.xcontent.XContentFactory;
+import org.elasticsearch.util.xcontent.XContentGenerator;
+import org.elasticsearch.util.xcontent.XContentParser;
+import org.elasticsearch.util.xcontent.XContentType;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+
+import static org.hamcrest.MatcherAssert.*;
+import static org.hamcrest.Matchers.*;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class JsonVsXsonTests {
+
+ @Test public void compareParsingTokens() throws IOException {
+ FastByteArrayOutputStream xsonOs = new FastByteArrayOutputStream();
+ XContentGenerator xsonGen = XContentFactory.xContent(XContentType.XSON).createGenerator(xsonOs);
+
+ FastByteArrayOutputStream jsonOs = new FastByteArrayOutputStream();
+ XContentGenerator jsonGen = XContentFactory.xContent(XContentType.JSON).createGenerator(jsonOs);
+
+ xsonGen.writeStartObject();
+ jsonGen.writeStartObject();
+
+ xsonGen.writeStringField("test", "value");
+ jsonGen.writeStringField("test", "value");
+
+ xsonGen.writeArrayFieldStart("arr");
+ jsonGen.writeArrayFieldStart("arr");
+ xsonGen.writeNumber(1);
+ jsonGen.writeNumber(1);
+ xsonGen.writeNull();
+ jsonGen.writeNull();
+ xsonGen.writeEndArray();
+ jsonGen.writeEndArray();
+
+ xsonGen.writeEndObject();
+ jsonGen.writeEndObject();
+
+ xsonGen.close();
+ jsonGen.close();
+
+ verifySameTokens(XContentFactory.xContent(XContentType.JSON).createParser(jsonOs.copiedByteArray()), XContentFactory.xContent(XContentType.XSON).createParser(xsonOs.copiedByteArray()));
+ }
+
+ private void verifySameTokens(XContentParser parser1, XContentParser parser2) throws IOException {
+ while (true) {
+ XContentParser.Token token1 = parser1.nextToken();
+ XContentParser.Token token2 = parser2.nextToken();
+ if (token1 == null) {
+ assertThat(token2, nullValue());
+ return;
+ }
+ assertThat(token1, equalTo(token2));
+ switch (token1) {
+ case FIELD_NAME:
+ assertThat(parser1.currentName(), equalTo(parser2.currentName()));
+ break;
+ case VALUE_STRING:
+ assertThat(parser1.text(), equalTo(parser2.text()));
+ break;
+ case VALUE_NUMBER:
+ assertThat(parser1.numberType(), equalTo(parser2.numberType()));
+ assertThat(parser1.numberValue(), equalTo(parser2.numberValue()));
+ break;
+ }
+ }
+ }
+}
diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/SingleInstanceEmbeddedSearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/SingleInstanceEmbeddedSearchTests.java
index 05bb855f47b..3f95a9cda1f 100644
--- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/SingleInstanceEmbeddedSearchTests.java
+++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/SingleInstanceEmbeddedSearchTests.java
@@ -45,10 +45,10 @@ import org.testng.annotations.Test;
import java.util.Map;
-import static org.elasticsearch.util.gcommon.collect.Lists.*;
import static org.elasticsearch.client.Requests.*;
import static org.elasticsearch.index.query.xcontent.QueryBuilders.*;
import static org.elasticsearch.search.builder.SearchSourceBuilder.*;
+import static org.elasticsearch.util.gcommon.collect.Lists.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
@@ -194,7 +194,7 @@ public class SingleInstanceEmbeddedSearchTests extends AbstractNodesTests {
private InternalSearchRequest searchRequest(SearchSourceBuilder builder) {
- return new InternalSearchRequest("test", 0, builder.build());
+ return new InternalSearchRequest("test", 0, builder.buildAsBytes());
}
private void index(Client client, String id, String nameValue, int age) {
diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceEmbeddedSearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceEmbeddedSearchTests.java
index 19bff08d0b2..8eae3f2a95d 100644
--- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceEmbeddedSearchTests.java
+++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceEmbeddedSearchTests.java
@@ -19,8 +19,6 @@
package org.elasticsearch.test.integration.search;
-import org.elasticsearch.util.gcommon.collect.ImmutableMap;
-import org.elasticsearch.util.gcommon.collect.Sets;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.ClusterService;
@@ -45,6 +43,8 @@ import org.elasticsearch.search.query.QuerySearchResult;
import org.elasticsearch.search.query.QuerySearchResultProvider;
import org.elasticsearch.test.integration.AbstractNodesTests;
import org.elasticsearch.util.TimeValue;
+import org.elasticsearch.util.gcommon.collect.ImmutableMap;
+import org.elasticsearch.util.gcommon.collect.Sets;
import org.elasticsearch.util.trove.ExtTIntArrayList;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@@ -55,12 +55,12 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
-import static org.elasticsearch.util.gcommon.collect.Lists.*;
-import static org.elasticsearch.util.gcommon.collect.Maps.*;
import static org.elasticsearch.client.Requests.*;
import static org.elasticsearch.index.query.xcontent.QueryBuilders.*;
import static org.elasticsearch.search.builder.SearchSourceBuilder.*;
import static org.elasticsearch.util.TimeValue.*;
+import static org.elasticsearch.util.gcommon.collect.Lists.*;
+import static org.elasticsearch.util.gcommon.collect.Maps.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
@@ -354,7 +354,7 @@ public class TwoInstanceEmbeddedSearchTests extends AbstractNodesTests {
}
private InternalSearchRequest searchRequest(ShardRouting shardRouting, SearchSourceBuilder builder) {
- return new InternalSearchRequest(shardRouting, builder.build());
+ return new InternalSearchRequest(shardRouting, builder.buildAsBytes());
}
private void index(Client client, String id, String nameValue, int age) {
diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceUnbalancedShardsEmbeddedSearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceUnbalancedShardsEmbeddedSearchTests.java
index 2be0de93b08..13e53d31ae4 100644
--- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceUnbalancedShardsEmbeddedSearchTests.java
+++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/TwoInstanceUnbalancedShardsEmbeddedSearchTests.java
@@ -19,9 +19,6 @@
package org.elasticsearch.test.integration.search;
-import org.elasticsearch.util.gcommon.collect.ImmutableMap;
-import org.elasticsearch.util.guice.inject.AbstractModule;
-import org.elasticsearch.util.guice.inject.Inject;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.Requests;
import org.elasticsearch.cluster.ClusterService;
@@ -50,6 +47,9 @@ import org.elasticsearch.search.query.QuerySearchResult;
import org.elasticsearch.search.query.QuerySearchResultProvider;
import org.elasticsearch.test.integration.AbstractNodesTests;
import org.elasticsearch.util.TimeValue;
+import org.elasticsearch.util.gcommon.collect.ImmutableMap;
+import org.elasticsearch.util.guice.inject.AbstractModule;
+import org.elasticsearch.util.guice.inject.Inject;
import org.elasticsearch.util.settings.Settings;
import org.elasticsearch.util.trove.ExtTIntArrayList;
import org.testng.annotations.AfterClass;
@@ -60,12 +60,12 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
-import static org.elasticsearch.util.gcommon.collect.Lists.*;
-import static org.elasticsearch.util.gcommon.collect.Maps.*;
import static org.elasticsearch.client.Requests.*;
import static org.elasticsearch.index.query.xcontent.QueryBuilders.*;
import static org.elasticsearch.search.builder.SearchSourceBuilder.*;
import static org.elasticsearch.util.TimeValue.*;
+import static org.elasticsearch.util.gcommon.collect.Lists.*;
+import static org.elasticsearch.util.gcommon.collect.Maps.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
@@ -360,7 +360,7 @@ public class TwoInstanceUnbalancedShardsEmbeddedSearchTests extends AbstractNode
}
private static InternalSearchRequest searchRequest(ShardRouting shardRouting, SearchSourceBuilder builder) {
- return new InternalSearchRequest(shardRouting, builder.build());
+ return new InternalSearchRequest(shardRouting, builder.buildAsBytes());
}
private void index(Client client, String id, String nameValue, int age) {
diff --git a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GClient.groovy b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GClient.groovy
index 961c8ad240e..b17623dad0b 100644
--- a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GClient.groovy
+++ b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GClient.groovy
@@ -38,7 +38,8 @@ import org.elasticsearch.action.terms.TermsResponse
import org.elasticsearch.client.Client
import org.elasticsearch.client.internal.InternalClient
import org.elasticsearch.groovy.client.action.GActionFuture
-import org.elasticsearch.groovy.util.json.JsonBuilder
+import org.elasticsearch.groovy.util.xcontent.GXContentBuilder
+import org.elasticsearch.util.xcontent.XContentType
/**
* @author kimchy (shay.banon)
@@ -47,47 +48,51 @@ class GClient {
static {
IndexRequest.metaClass.setSource = {Closure c ->
- delegate.source(new JsonBuilder().buildAsBytes(c))
+ delegate.source(new GXContentBuilder().buildAsBytes(c, indexContentType))
}
IndexRequest.metaClass.source = {Closure c ->
- delegate.source(new JsonBuilder().buildAsBytes(c))
+ delegate.source(new GXContentBuilder().buildAsBytes(c, indexContentType))
}
DeleteByQueryRequest.metaClass.setQuery = {Closure c ->
- delegate.query(new JsonBuilder().buildAsBytes(c))
+ delegate.query(new GXContentBuilder().buildAsBytes(c, contentType))
}
DeleteByQueryRequest.metaClass.query = {Closure c ->
- delegate.query(new JsonBuilder().buildAsBytes(c))
+ delegate.query(new GXContentBuilder().buildAsBytes(c, contentType))
}
CountRequest.metaClass.setQuery = {Closure c ->
- delegate.query(new JsonBuilder().buildAsBytes(c))
+ delegate.query(new GXContentBuilder().buildAsBytes(c, contentType))
}
CountRequest.metaClass.query = {Closure c ->
- delegate.query(new JsonBuilder().buildAsBytes(c))
+ delegate.query(new GXContentBuilder().buildAsBytes(c, contentType))
}
SearchRequest.metaClass.setSource = {Closure c ->
- delegate.source(new JsonBuilder().buildAsBytes(c))
+ delegate.source(new GXContentBuilder().buildAsBytes(c, contentType))
}
SearchRequest.metaClass.source = {Closure c ->
- delegate.source(new JsonBuilder().buildAsBytes(c))
+ delegate.source(new GXContentBuilder().buildAsBytes(c, contentType))
}
SearchRequest.metaClass.setExtraSource = {Closure c ->
- delegate.extraSource(new JsonBuilder().buildAsBytes(c))
+ delegate.extraSource(new GXContentBuilder().buildAsBytes(c, contentType))
}
SearchRequest.metaClass.extraSource = {Closure c ->
- delegate.extraSource(new JsonBuilder().buildAsBytes(c))
+ delegate.extraSource(new GXContentBuilder().buildAsBytes(c, contentType))
}
MoreLikeThisRequest.metaClass.setSearchSource = {Closure c ->
- delegate.searchSource(new JsonBuilder().buildAsBytes(c))
+ delegate.searchSource(new GXContentBuilder().buildAsBytes(c, contentType))
}
MoreLikeThisRequest.metaClass.searchSource = {Closure c ->
- delegate.searchSource(new JsonBuilder().buildAsBytes(c))
+ delegate.searchSource(new GXContentBuilder().buildAsBytes(c, contentType))
}
}
+ static XContentType contentType = XContentType.XSON;
+
+ static XContentType indexContentType = XContentType.JSON;
+
final Client client;
int resolveStrategy = Closure.DELEGATE_FIRST
diff --git a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GIndicesAdminClient.groovy b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GIndicesAdminClient.groovy
index 8f258751b13..2bc147580e5 100644
--- a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GIndicesAdminClient.groovy
+++ b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/client/GIndicesAdminClient.groovy
@@ -43,7 +43,7 @@ import org.elasticsearch.action.admin.indices.status.IndicesStatusResponse
import org.elasticsearch.client.IndicesAdminClient
import org.elasticsearch.client.internal.InternalClient
import org.elasticsearch.groovy.client.action.GActionFuture
-import org.elasticsearch.groovy.util.json.JsonBuilder
+import org.elasticsearch.groovy.util.xcontent.GXContentBuilder
/**
* @author kimchy (shay.banon)
@@ -52,23 +52,23 @@ class GIndicesAdminClient {
static {
CreateIndexRequest.metaClass.setSettings = {Closure c ->
- delegate.settings(new JsonBuilder().buildAsString(c))
+ delegate.settings(new GXContentBuilder().buildAsString(c))
}
CreateIndexRequest.metaClass.settings = {Closure c ->
- delegate.settings(new JsonBuilder().buildAsString(c))
+ delegate.settings(new GXContentBuilder().buildAsString(c))
}
CreateIndexRequest.metaClass.mapping = {String type, Closure c ->
- delegate.mapping(type, new JsonBuilder().buildAsString(c))
+ delegate.mapping(type, new GXContentBuilder().buildAsString(c))
}
CreateIndexRequest.metaClass.setMapping = {String type, Closure c ->
- delegate.mapping(type, new JsonBuilder().buildAsString(c))
+ delegate.mapping(type, new GXContentBuilder().buildAsString(c))
}
PutMappingRequest.metaClass.setSource = {Closure c ->
- delegate.source(new JsonBuilder().buildAsString(c))
+ delegate.source(new GXContentBuilder().buildAsString(c))
}
PutMappingRequest.metaClass.source = {Closure c ->
- delegate.source(new JsonBuilder().buildAsString(c))
+ delegate.source(new GXContentBuilder().buildAsString(c))
}
}
diff --git a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/node/GNodeBuilder.groovy b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/node/GNodeBuilder.groovy
index 1bd68c426c3..cfa54fdfc87 100644
--- a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/node/GNodeBuilder.groovy
+++ b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/node/GNodeBuilder.groovy
@@ -19,14 +19,14 @@
package org.elasticsearch.groovy.node
-import org.elasticsearch.groovy.util.json.JsonBuilder
+import org.elasticsearch.groovy.util.xcontent.GXContentBuilder
import org.elasticsearch.node.Node
import org.elasticsearch.node.internal.InternalNode
import org.elasticsearch.util.settings.ImmutableSettings
import org.elasticsearch.util.settings.loader.JsonSettingsLoader
/**
- * The node builder allow to build a {@link GNode} instance.
+ * The node builder allow to build a {@link GNode} instance.
*
* @author kimchy (shay.banon)
*/
@@ -41,7 +41,7 @@ public class GNodeBuilder {
}
def settings(Closure settings) {
- byte[] settingsBytes = new JsonBuilder().buildAsBytes(settings);
+ byte[] settingsBytes = new GXContentBuilder().buildAsBytes(settings);
settingsBuilder.put(new JsonSettingsLoader().load(settingsBytes))
}
diff --git a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/util/json/JsonBuilder.groovy b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/util/xcontent/GXContentBuilder.groovy
similarity index 95%
rename from plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/util/json/JsonBuilder.groovy
rename to plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/util/xcontent/GXContentBuilder.groovy
index 00115b352ec..91de9af8f33 100644
--- a/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/util/json/JsonBuilder.groovy
+++ b/plugins/client/groovy/src/main/groovy/org/elasticsearch/groovy/util/xcontent/GXContentBuilder.groovy
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.elasticsearch.groovy.util.json
+package org.elasticsearch.groovy.util.xcontent
import org.elasticsearch.util.xcontent.XContentFactory
import org.elasticsearch.util.xcontent.XContentType
@@ -32,7 +32,7 @@ import org.elasticsearch.util.xcontent.builder.TextXContentBuilder
*
* @since 1.2
*/
-class JsonBuilder {
+class GXContentBuilder {
static NODE_ELEMENT = "element"
@@ -56,7 +56,11 @@ class JsonBuilder {
}
byte[] buildAsBytes(Closure c) {
- BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(XContentType.JSON);
+ return buildAsBytes(c, XContentType.JSON);
+ }
+
+ byte[] buildAsBytes(Closure c, XContentType contentType) {
+ BinaryXContentBuilder builder = XContentFactory.contentBinaryBuilder(contentType);
def json = build(c)
builder.map(json);
return builder.copiedBytes();
@@ -164,7 +168,7 @@ class JsonBuilder {
value = value.collect {
if (it instanceof Closure) {
def callable = it
- final JsonBuilder localBuilder = new JsonBuilder()
+ final GXContentBuilder localBuilder = new GXContentBuilder()
callable.delegate = localBuilder
callable.resolveStrategy = Closure.DELEGATE_FIRST
final Map nestedObject = localBuilder.buildRoot(callable)
diff --git a/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/test/client/SimpleActionsTests.groovy b/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/test/client/SimpleActionsTests.groovy
index 4699a5806e4..89e6ec7ef41 100644
--- a/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/test/client/SimpleActionsTests.groovy
+++ b/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/test/client/SimpleActionsTests.groovy
@@ -54,7 +54,7 @@ class SimpleActionsTests {
@Test
void testSimpleOperations() {
- def value1 = new org.elasticsearch.groovy.util.json.JsonBuilder().buildAsString {
+ def value1 = new org.elasticsearch.groovy.util.xcontent.GXContentBuilder().buildAsString {
something = "test"
}
println value1
diff --git a/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/util/json/JsonBuilderTests.groovy b/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/util/xcontent/GXContentBuilderTests.groovy
similarity index 89%
rename from plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/util/json/JsonBuilderTests.groovy
rename to plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/util/xcontent/GXContentBuilderTests.groovy
index 5a51b0db818..0a5999bf3a7 100644
--- a/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/util/json/JsonBuilderTests.groovy
+++ b/plugins/client/groovy/src/test/groovy/org/elasticsearch/groovy/util/xcontent/GXContentBuilderTests.groovy
@@ -17,15 +17,15 @@
* under the License.
*/
-package org.elasticsearch.groovy.util.json
+package org.elasticsearch.groovy.util.xcontent
/**
* @author kimchy (shay.banon)
*/
-class JsonBuilderTests extends GroovyTestCase {
+class GXContentBuilderTests extends GroovyTestCase {
void testSimple() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def result = builder.buildAsString {
rootprop = "something"
@@ -35,7 +35,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testArrays() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def result = builder.buildAsString {
categories = ['a', 'b', 'c']
@@ -46,7 +46,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testSubObjects() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def result = builder.buildAsString {
categories = ['a', 'b', 'c']
@@ -60,7 +60,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testAssignedObjects() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def result = builder.buildAsString {
categories = ['a', 'b', 'c']
@@ -74,7 +74,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testNamedArgumentHandling() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def result = builder.buildAsString {
categories = ['a', 'b', 'c']
rootprop = "something"
@@ -87,7 +87,7 @@ class JsonBuilderTests extends GroovyTestCase {
void testArrayOfClosures() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def result = builder.buildAsString {
foo = [{ bar = "hello" }]
}
@@ -96,7 +96,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testRootElementList() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def results = ['one', 'two', 'three']
@@ -117,7 +117,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testExampleFromReferenceGuide() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def results = ['one', 'two', 'three']
@@ -150,7 +150,7 @@ class JsonBuilderTests extends GroovyTestCase {
}
void testAppendToArray() {
- def builder = new JsonBuilder()
+ def builder = new GXContentBuilder()
def results = ['one', 'two', 'three']
diff --git a/plugins/transport/memcached/src/main/java/org/elasticsearch/memcached/MemcachedRestRequest.java b/plugins/transport/memcached/src/main/java/org/elasticsearch/memcached/MemcachedRestRequest.java
index 054de540886..f57692a44fb 100644
--- a/plugins/transport/memcached/src/main/java/org/elasticsearch/memcached/MemcachedRestRequest.java
+++ b/plugins/transport/memcached/src/main/java/org/elasticsearch/memcached/MemcachedRestRequest.java
@@ -19,14 +19,12 @@
package org.elasticsearch.memcached;
-import org.elasticsearch.util.gcommon.collect.ImmutableList;
-import org.elasticsearch.util.gcommon.collect.ImmutableSet;
import org.elasticsearch.rest.support.AbstractRestRequest;
import org.elasticsearch.rest.support.RestUtils;
import org.elasticsearch.util.Unicode;
-import org.elasticsearch.util.io.FastByteArrayInputStream;
+import org.elasticsearch.util.gcommon.collect.ImmutableList;
+import org.elasticsearch.util.gcommon.collect.ImmutableSet;
-import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -111,10 +109,6 @@ public class MemcachedRestRequest extends AbstractRestRequest {
return data != null;
}
- @Override public InputStream contentAsStream() {
- return new FastByteArrayInputStream(data);
- }
-
@Override public byte[] contentAsBytes() {
return data;
}