mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-23 05:15:04 +00:00
XContent - An abstraction on top of content (JSON inspired), closes #152.
This commit is contained in:
parent
f8f65c991a
commit
34d99c39a5
1
.idea/dictionaries/kimchy.xml
generated
1
.idea/dictionaries/kimchy.xml
generated
@ -82,6 +82,7 @@
|
||||
<w>versioned</w>
|
||||
<w>wildcards</w>
|
||||
<w>xcontent</w>
|
||||
<w>xson</w>
|
||||
<w>yaml</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
@ -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);
|
||||
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 {
|
||||
|
@ -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);
|
||||
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 {
|
||||
|
@ -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);
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
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 {
|
||||
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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,13 +255,37 @@ 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;
|
||||
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);
|
||||
@ -327,11 +353,6 @@ public class SearchSourceBuilder {
|
||||
}
|
||||
|
||||
builder.endObject();
|
||||
|
||||
return builder.copiedBytes();
|
||||
} catch (Exception e) {
|
||||
throw new SearchSourceBuilderException("Failed to build search source", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SortTuple {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 + "]");
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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<ThreadLocals.CleanableValue<BinaryXContentBuilder>> cache = new ThreadLocal<ThreadLocals.CleanableValue<BinaryXContentBuilder>>() {
|
||||
@Override protected ThreadLocals.CleanableValue<BinaryXContentBuilder> initialValue() {
|
||||
try {
|
||||
BinaryXContentBuilder builder = new BinaryXContentBuilder(new XsonXContent());
|
||||
return new ThreadLocals.CleanableValue<BinaryXContentBuilder>(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<BinaryXContentBuilder> 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");
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<ThreadLocals.CleanableValue<byte[]>> cachedBytes = new ThreadLocal<ThreadLocals.CleanableValue<byte[]>>() {
|
||||
@Override protected ThreadLocals.CleanableValue<byte[]> initialValue() {
|
||||
return new ThreadLocals.CleanableValue<byte[]>(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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
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
|
||||
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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)
|
@ -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
|
||||
|
@ -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']
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user