mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-23 05:15:04 +00:00
start abstaction of xconten over json
This commit is contained in:
parent
c48851f49c
commit
cdc33e18f3
2
.idea/dictionaries/kimchy.xml
generated
2
.idea/dictionaries/kimchy.xml
generated
@ -32,6 +32,7 @@
|
||||
<w>infos</w>
|
||||
<w>intf</w>
|
||||
<w>iter</w>
|
||||
<w>iterable</w>
|
||||
<w>jgroups</w>
|
||||
<w>joda</w>
|
||||
<w>jsonp</w>
|
||||
@ -79,6 +80,7 @@
|
||||
<w>uuid</w>
|
||||
<w>versioned</w>
|
||||
<w>wildcards</w>
|
||||
<w>xcontent</w>
|
||||
<w>yaml</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
|
9
.idea/libraries/jackson.xml
generated
9
.idea/libraries/jackson.xml
generated
@ -1,10 +1,13 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jackson">
|
||||
<CLASSES>
|
||||
<root url="jar://$GRADLE_REPOSITORY$/org.codehaus.jackson/jackson-mapper-asl/jars/jackson-mapper-asl-1.5.1.jar!/" />
|
||||
<root url="jar://$GRADLE_REPOSITORY$/org.codehaus.jackson/jackson-core-asl/jars/jackson-core-asl-1.5.1.jar!/" />
|
||||
<root url="jar://$GRADLE_REPOSITORY$/org.codehaus.jackson/jackson-core-asl/jars/jackson-core-asl-1.5.2.jar!/" />
|
||||
<root url="jar://$GRADLE_REPOSITORY$/org.codehaus.jackson/jackson-mapper-asl/jars/jackson-mapper-asl-1.5.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/../../../opt/jackson/1.5.2/src/mapper/java" />
|
||||
<root url="file://$PROJECT_DIR$/../../../opt/jackson/1.5.2/src/java" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
@ -38,8 +38,8 @@ dependencies {
|
||||
|
||||
compile 'joda-time:joda-time:1.6'
|
||||
|
||||
compile 'org.codehaus.jackson:jackson-core-asl:1.5.1'
|
||||
compile 'org.codehaus.jackson:jackson-mapper-asl:1.5.1'
|
||||
compile 'org.codehaus.jackson:jackson-core-asl:1.5.2'
|
||||
compile 'org.codehaus.jackson:jackson-mapper-asl:1.5.2'
|
||||
|
||||
compile 'org.apache.lucene:lucene-core:3.0.1'
|
||||
compile 'org.apache.lucene:lucene-analyzers:3.0.1'
|
||||
|
@ -29,7 +29,7 @@ import org.elasticsearch.env.FailedToResolveConfigException;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapperParser;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
import org.elasticsearch.util.concurrent.ThreadSafe;
|
||||
import org.elasticsearch.util.io.Streams;
|
||||
@ -85,7 +85,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||
|
||||
@Inject public MapperService(Index index, @IndexSettings Settings indexSettings, Environment environment, AnalysisService analysisService) {
|
||||
super(index, indexSettings);
|
||||
this.documentParser = new JsonDocumentMapperParser(analysisService);
|
||||
this.documentParser = new XContentDocumentMapperParser(analysisService);
|
||||
this.searchAnalyzer = new SmartIndexNameSearchAnalyzer(analysisService.defaultSearchAnalyzer());
|
||||
this.indexClassLoader = indexSettings.getClassLoader();
|
||||
|
||||
@ -97,7 +97,7 @@ public class MapperService extends AbstractIndexComponent implements Iterable<Do
|
||||
dynamicMappingUrl = environment.resolveConfig("dynamic-mapping.json");
|
||||
} catch (FailedToResolveConfigException e) {
|
||||
// not there, default to the built in one
|
||||
dynamicMappingUrl = indexClassLoader.getResource("org/elasticsearch/index/mapper/json/dynamic-mapping.json");
|
||||
dynamicMappingUrl = indexClassLoader.getResource("org/elasticsearch/index/mapper/xcontent/dynamic-mapping.json");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* 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.index.mapper.json;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
public final class JsonMapperBuilders {
|
||||
|
||||
private JsonMapperBuilders() {
|
||||
|
||||
}
|
||||
|
||||
public static JsonDocumentMapper.Builder doc(JsonObjectMapper.Builder objectBuilder) {
|
||||
return new JsonDocumentMapper.Builder(objectBuilder);
|
||||
}
|
||||
|
||||
public static JsonSourceFieldMapper.Builder source() {
|
||||
return new JsonSourceFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static JsonIdFieldMapper.Builder id() {
|
||||
return new JsonIdFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static JsonUidFieldMapper.Builder uid() {
|
||||
return new JsonUidFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static JsonTypeFieldMapper.Builder type() {
|
||||
return new JsonTypeFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static JsonBoostFieldMapper.Builder boost(String name) {
|
||||
return new JsonBoostFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonAllFieldMapper.Builder all() {
|
||||
return new JsonAllFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static JsonMultiFieldMapper.Builder multiField(String name) {
|
||||
return new JsonMultiFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonObjectMapper.Builder object(String name) {
|
||||
return new JsonObjectMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonBooleanFieldMapper.Builder booleanField(String name) {
|
||||
return new JsonBooleanFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonStringFieldMapper.Builder stringField(String name) {
|
||||
return new JsonStringFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonBinaryFieldMapper.Builder binaryField(String name) {
|
||||
return new JsonBinaryFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonDateFieldMapper.Builder dateField(String name) {
|
||||
return new JsonDateFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonShortFieldMapper.Builder shortField(String name) {
|
||||
return new JsonShortFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonIntegerFieldMapper.Builder integerField(String name) {
|
||||
return new JsonIntegerFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonLongFieldMapper.Builder longField(String name) {
|
||||
return new JsonLongFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonFloatFieldMapper.Builder floatField(String name) {
|
||||
return new JsonFloatFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static JsonDoubleFieldMapper.Builder doubleField(String name) {
|
||||
return new JsonDoubleFieldMapper.Builder(name);
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
{
|
||||
_default_ : {
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.elasticsearch.util.concurrent.NotThreadSafe;
|
||||
|
||||
@ -25,7 +25,7 @@ import org.elasticsearch.util.concurrent.NotThreadSafe;
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class JsonPath {
|
||||
public class ContentPath {
|
||||
|
||||
public static enum Type {
|
||||
JUST_NAME,
|
||||
@ -44,7 +44,7 @@ public class JsonPath {
|
||||
|
||||
private String[] path = new String[10];
|
||||
|
||||
public JsonPath() {
|
||||
public ContentPath() {
|
||||
this(0);
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ public class JsonPath {
|
||||
* Constructs a json path with an offset. The offset will result an <tt>offset</tt>
|
||||
* number of path elements to not be included in {@link #pathAsText(String)}.
|
||||
*/
|
||||
public JsonPath(int offset) {
|
||||
public ContentPath(int offset) {
|
||||
this.delimiter = '.';
|
||||
this.sb = new StringBuilder();
|
||||
this.offset = offset;
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.elasticsearch.util.gcommon.collect.Lists;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
@ -27,20 +27,20 @@ import java.util.List;
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonMergeContext {
|
||||
public class MergeContext {
|
||||
|
||||
private final JsonDocumentMapper documentMapper;
|
||||
private final XContentDocumentMapper documentMapper;
|
||||
|
||||
private final DocumentMapper.MergeFlags mergeFlags;
|
||||
|
||||
private final List<String> mergeConflicts = Lists.newArrayList();
|
||||
|
||||
public JsonMergeContext(JsonDocumentMapper documentMapper, DocumentMapper.MergeFlags mergeFlags) {
|
||||
public MergeContext(XContentDocumentMapper documentMapper, DocumentMapper.MergeFlags mergeFlags) {
|
||||
this.documentMapper = documentMapper;
|
||||
this.mergeFlags = mergeFlags;
|
||||
}
|
||||
|
||||
public JsonDocumentMapper docMapper() {
|
||||
public XContentDocumentMapper docMapper() {
|
||||
return documentMapper;
|
||||
}
|
||||
|
@ -17,25 +17,25 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.util.concurrent.NotThreadSafe;
|
||||
import org.elasticsearch.util.lucene.all.AllEntries;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
*/
|
||||
@NotThreadSafe
|
||||
public class JsonParseContext {
|
||||
public class ParseContext {
|
||||
|
||||
private final JsonDocumentMapper docMapper;
|
||||
private final XContentDocumentMapper docMapper;
|
||||
|
||||
private final JsonPath path;
|
||||
private final ContentPath path;
|
||||
|
||||
private JsonParser jsonParser;
|
||||
private XContentParser parser;
|
||||
|
||||
private Document document;
|
||||
|
||||
@ -61,13 +61,13 @@ public class JsonParseContext {
|
||||
|
||||
private AllEntries allEntries = new AllEntries();
|
||||
|
||||
public JsonParseContext(JsonDocumentMapper docMapper, JsonPath path) {
|
||||
public ParseContext(XContentDocumentMapper docMapper, ContentPath path) {
|
||||
this.docMapper = docMapper;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public void reset(JsonParser jsonParser, Document document, String type, byte[] source, DocumentMapper.ParseListener listener) {
|
||||
this.jsonParser = jsonParser;
|
||||
public void reset(XContentParser parser, Document document, String type, byte[] source, DocumentMapper.ParseListener listener) {
|
||||
this.parser = parser;
|
||||
this.document = document;
|
||||
this.type = type;
|
||||
this.source = source;
|
||||
@ -94,12 +94,12 @@ public class JsonParseContext {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public JsonPath path() {
|
||||
public ContentPath path() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public JsonParser jp() {
|
||||
return this.jsonParser;
|
||||
public XContentParser parser() {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
public DocumentMapper.ParseListener listener() {
|
||||
@ -110,7 +110,7 @@ public class JsonParseContext {
|
||||
return this.document;
|
||||
}
|
||||
|
||||
public JsonDocumentMapper docMapper() {
|
||||
public XContentDocumentMapper docMapper() {
|
||||
return this.docMapper;
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
@ -29,9 +29,9 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.mapper.AllFieldMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.Lucene;
|
||||
import org.elasticsearch.util.lucene.all.AllTermQuery;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -40,18 +40,18 @@ import static org.elasticsearch.util.lucene.all.AllTokenFilter.*;
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFieldMapper {
|
||||
public class XContentAllFieldMapper extends XContentFieldMapper<Void> implements AllFieldMapper {
|
||||
|
||||
public static final String JSON_TYPE = "_all";
|
||||
public static final String CONTENT_TYPE = "_all";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final String NAME = AllFieldMapper.NAME;
|
||||
public static final String INDEX_NAME = AllFieldMapper.NAME;
|
||||
public static final boolean ENABLED = true;
|
||||
}
|
||||
|
||||
|
||||
public static class Builder extends JsonFieldMapper.Builder<Builder, JsonAllFieldMapper> {
|
||||
public static class Builder extends XContentFieldMapper.Builder<Builder, XContentAllFieldMapper> {
|
||||
|
||||
private boolean enabled = Defaults.ENABLED;
|
||||
|
||||
@ -82,8 +82,8 @@ public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFiel
|
||||
return super.searchAnalyzer(searchAnalyzer);
|
||||
}
|
||||
|
||||
@Override public JsonAllFieldMapper build(BuilderContext context) {
|
||||
return new JsonAllFieldMapper(name, store, termVector, omitNorms, omitTermFreqAndPositions,
|
||||
@Override public XContentAllFieldMapper build(BuilderContext context) {
|
||||
return new XContentAllFieldMapper(name, store, termVector, omitNorms, omitTermFreqAndPositions,
|
||||
indexAnalyzer, searchAnalyzer, enabled);
|
||||
}
|
||||
}
|
||||
@ -91,12 +91,12 @@ public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFiel
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
public JsonAllFieldMapper() {
|
||||
public XContentAllFieldMapper() {
|
||||
this(Defaults.NAME, Defaults.STORE, Defaults.TERM_VECTOR, Defaults.OMIT_NORMS, Defaults.OMIT_TERM_FREQ_AND_POSITIONS, null, null, Defaults.ENABLED);
|
||||
}
|
||||
|
||||
protected JsonAllFieldMapper(String name, Field.Store store, Field.TermVector termVector, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer, boolean enabled) {
|
||||
protected XContentAllFieldMapper(String name, Field.Store store, Field.TermVector termVector, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer, boolean enabled) {
|
||||
super(new Names(name, name, name, name), Field.Index.ANALYZED, store, termVector, 1.0f, omitNorms, omitTermFreqAndPositions,
|
||||
indexAnalyzer, searchAnalyzer);
|
||||
this.enabled = enabled;
|
||||
@ -114,18 +114,18 @@ public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFiel
|
||||
return new AllTermQuery(new Term(names.indexName(), value));
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
// reset the entries
|
||||
jsonContext.allEntries().reset();
|
||||
context.allEntries().reset();
|
||||
|
||||
Analyzer analyzer = findAnalyzer(jsonContext.docMapper());
|
||||
TokenStream tokenStream = allTokenStream(names.indexName(), jsonContext.allEntries(), analyzer);
|
||||
Analyzer analyzer = findAnalyzer(context.docMapper());
|
||||
TokenStream tokenStream = allTokenStream(names.indexName(), context.allEntries(), analyzer);
|
||||
if (stored()) {
|
||||
// TODO when its possible to pass char[] to field, we can optimize
|
||||
Field field = new Field(names.indexName(), jsonContext.allEntries().buildText(), store, index, termVector);
|
||||
Field field = new Field(names.indexName(), context.allEntries().buildText(), store, index, termVector);
|
||||
field.setTokenStream(tokenStream);
|
||||
return field;
|
||||
} else {
|
||||
@ -160,12 +160,12 @@ public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFiel
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(JSON_TYPE);
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
builder.field("enabled", enabled);
|
||||
builder.field("store", store.name().toLowerCase());
|
||||
builder.field("term_vector", termVector.name().toLowerCase());
|
||||
@ -178,7 +178,7 @@ public class JsonAllFieldMapper extends JsonFieldMapper<Void> implements AllFiel
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// do nothing here, no merging, but also no exception
|
||||
}
|
||||
}
|
@ -17,28 +17,28 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonBinaryFieldMapper extends JsonFieldMapper<byte[]> {
|
||||
public class XContentBinaryFieldMapper extends XContentFieldMapper<byte[]> {
|
||||
|
||||
public static final String JSON_TYPE = "binary";
|
||||
public static final String CONTENT_TYPE = "binary";
|
||||
|
||||
public static class Builder extends JsonFieldMapper.Builder<Builder, JsonBinaryFieldMapper> {
|
||||
public static class Builder extends XContentFieldMapper.Builder<Builder, XContentBinaryFieldMapper> {
|
||||
|
||||
public Builder(String name) {
|
||||
super(name);
|
||||
@ -49,20 +49,20 @@ public class JsonBinaryFieldMapper extends JsonFieldMapper<byte[]> {
|
||||
return super.indexName(indexName);
|
||||
}
|
||||
|
||||
@Override public JsonBinaryFieldMapper build(BuilderContext context) {
|
||||
return new JsonBinaryFieldMapper(buildNames(context));
|
||||
@Override public XContentBinaryFieldMapper build(BuilderContext context) {
|
||||
return new XContentBinaryFieldMapper(buildNames(context));
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonBinaryFieldMapper.Builder builder = binaryField(name);
|
||||
parseJsonField(builder, name, node, parserContext);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentBinaryFieldMapper.Builder builder = binaryField(name);
|
||||
parseField(builder, name, node, parserContext);
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
protected JsonBinaryFieldMapper(Names names) {
|
||||
protected XContentBinaryFieldMapper(Names names) {
|
||||
super(names, Field.Index.NO, Field.Store.YES, Field.TermVector.NO, 1.0f, true, true, null, null);
|
||||
}
|
||||
|
||||
@ -78,12 +78,12 @@ public class JsonBinaryFieldMapper extends JsonFieldMapper<byte[]> {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
byte[] value;
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
return null;
|
||||
} else {
|
||||
value = jsonContext.jp().getBinaryValue();
|
||||
value = context.parser().binaryValue();
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
@ -91,13 +91,13 @@ public class JsonBinaryFieldMapper extends JsonFieldMapper<byte[]> {
|
||||
return new Field(names.indexName(), value, Field.Store.YES);
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(names.name());
|
||||
builder.field("type", jsonType());
|
||||
builder.field("type", contentType());
|
||||
builder.field("index_name", names.indexNameClean());
|
||||
builder.endObject();
|
||||
}
|
@ -17,38 +17,38 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Booleans;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.Lucene;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
// TODO this can be made better, maybe storing a byte for it?
|
||||
public class JsonBooleanFieldMapper extends JsonFieldMapper<Boolean> {
|
||||
public class XContentBooleanFieldMapper extends XContentFieldMapper<Boolean> {
|
||||
|
||||
public static final String JSON_TYPE = "boolean";
|
||||
public static final String CONTENT_TYPE = "boolean";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final boolean OMIT_NORMS = true;
|
||||
public static final Boolean NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonFieldMapper.Builder<Builder, JsonBooleanFieldMapper> {
|
||||
public static class Builder extends XContentFieldMapper.Builder<Builder, XContentBooleanFieldMapper> {
|
||||
|
||||
private Boolean nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -87,16 +87,16 @@ public class JsonBooleanFieldMapper extends JsonFieldMapper<Boolean> {
|
||||
return super.omitTermFreqAndPositions(omitTermFreqAndPositions);
|
||||
}
|
||||
|
||||
@Override public JsonBooleanFieldMapper build(BuilderContext context) {
|
||||
return new JsonBooleanFieldMapper(buildNames(context), index, store,
|
||||
@Override public XContentBooleanFieldMapper build(BuilderContext context) {
|
||||
return new XContentBooleanFieldMapper(buildNames(context), index, store,
|
||||
termVector, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonBooleanFieldMapper.Builder builder = booleanField(name);
|
||||
parseJsonField(builder, name, node, parserContext);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentBooleanFieldMapper.Builder builder = booleanField(name);
|
||||
parseField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
Object propNode = entry.getValue();
|
||||
@ -110,8 +110,8 @@ public class JsonBooleanFieldMapper extends JsonFieldMapper<Boolean> {
|
||||
|
||||
private Boolean nullValue;
|
||||
|
||||
protected JsonBooleanFieldMapper(Names names, Field.Index index, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions, Boolean nullValue) {
|
||||
protected XContentBooleanFieldMapper(Names names, Field.Index index, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions, Boolean nullValue) {
|
||||
super(names, index, store, termVector, boost, omitNorms, omitTermFreqAndPositions, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER);
|
||||
this.nullValue = nullValue;
|
||||
}
|
||||
@ -141,34 +141,18 @@ public class JsonBooleanFieldMapper extends JsonFieldMapper<Boolean> {
|
||||
return value ? "T" : "F";
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
if (!indexed() && !stored()) {
|
||||
return null;
|
||||
}
|
||||
JsonToken token = jsonContext.jp().getCurrentToken();
|
||||
XContentParser.Token token = context.parser().currentToken();
|
||||
String value = null;
|
||||
if (token == JsonToken.VALUE_FALSE) {
|
||||
value = "F";
|
||||
} else if (token == JsonToken.VALUE_TRUE) {
|
||||
value = "T";
|
||||
} else if (token == JsonToken.VALUE_NULL) {
|
||||
if (token == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue != null) {
|
||||
value = nullValue ? "T" : "F";
|
||||
}
|
||||
} else if (token == JsonToken.VALUE_NUMBER_INT) {
|
||||
if (jsonContext.jp().getIntValue() == 0) {
|
||||
value = "F";
|
||||
} else {
|
||||
value = "T";
|
||||
}
|
||||
} else if (token == JsonToken.VALUE_STRING) {
|
||||
if (Booleans.parseBoolean(jsonContext.jp().getText(), false)) {
|
||||
value = "T";
|
||||
} else {
|
||||
value = "F";
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
value = context.parser().booleanValue() ? "T" : "F";
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
@ -176,12 +160,12 @@ public class JsonBooleanFieldMapper extends JsonFieldMapper<Boolean> {
|
||||
return new Field(names.indexName(), value, store, index, termVector);
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,37 +17,37 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
|
||||
import org.elasticsearch.index.mapper.BoostFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implements BoostFieldMapper {
|
||||
public class XContentBoostFieldMapper extends XContentNumberFieldMapper<Float> implements BoostFieldMapper {
|
||||
|
||||
public static final String JSON_TYPE = "_boost";
|
||||
public static final String CONTENT_TYPE = "_boost";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final String NAME = "_boost";
|
||||
public static final Float NULL_VALUE = null;
|
||||
public static final Field.Index INDEX = Field.Index.NO;
|
||||
public static final Field.Store STORE = Field.Store.NO;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonBoostFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentBoostFieldMapper> {
|
||||
|
||||
protected Float nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -63,8 +63,8 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonBoostFieldMapper build(BuilderContext context) {
|
||||
return new JsonBoostFieldMapper(name, buildIndexName(context),
|
||||
@Override public XContentBoostFieldMapper build(BuilderContext context) {
|
||||
return new XContentBoostFieldMapper(name, buildIndexName(context),
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
}
|
||||
}
|
||||
@ -72,18 +72,18 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
|
||||
|
||||
private final Float nullValue;
|
||||
|
||||
protected JsonBoostFieldMapper() {
|
||||
protected XContentBoostFieldMapper() {
|
||||
this(Defaults.NAME, Defaults.NAME);
|
||||
}
|
||||
|
||||
protected JsonBoostFieldMapper(String name, String indexName) {
|
||||
protected XContentBoostFieldMapper(String name, String indexName) {
|
||||
this(name, indexName, Defaults.PRECISION_STEP, Defaults.INDEX, Defaults.STORE,
|
||||
Defaults.BOOST, Defaults.OMIT_NORMS, Defaults.OMIT_TERM_FREQ_AND_POSITIONS, Defaults.NULL_VALUE);
|
||||
}
|
||||
|
||||
protected JsonBoostFieldMapper(String name, String indexName, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Float nullValue) {
|
||||
protected XContentBoostFieldMapper(String name, String indexName, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Float nullValue) {
|
||||
super(new Names(name, indexName, indexName, name), precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
new NamedAnalyzer("_float/" + precisionStep, new NumericFloatAnalyzer(precisionStep)),
|
||||
new NamedAnalyzer("_float/max", new NumericFloatAnalyzer(Integer.MAX_VALUE)));
|
||||
@ -136,21 +136,21 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override public void parse(JsonParseContext jsonContext) throws IOException {
|
||||
@Override public void parse(ParseContext context) throws IOException {
|
||||
// we override parse since we want to handle cases where it is not indexed and not stored (the default)
|
||||
float value = parseFloatValue(jsonContext);
|
||||
float value = parseFloatValue(context);
|
||||
if (!Float.isNaN(value)) {
|
||||
jsonContext.doc().setBoost(value);
|
||||
context.doc().setBoost(value);
|
||||
}
|
||||
super.parse(jsonContext);
|
||||
super.parse(context);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
float value = parseFloatValue(jsonContext);
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
float value = parseFloatValue(context);
|
||||
if (Float.isNaN(value)) {
|
||||
return null;
|
||||
}
|
||||
jsonContext.doc().setBoost(value);
|
||||
context.doc().setBoost(value);
|
||||
Field field = null;
|
||||
if (stored()) {
|
||||
field = new Field(names.indexName(), Numbers.floatToBytes(value), store);
|
||||
@ -163,19 +163,15 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
|
||||
return field;
|
||||
}
|
||||
|
||||
private float parseFloatValue(JsonParseContext jsonContext) throws IOException {
|
||||
private float parseFloatValue(ParseContext context) throws IOException {
|
||||
float value;
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue == null) {
|
||||
return Float.NaN;
|
||||
}
|
||||
value = nullValue;
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
|
||||
value = Float.parseFloat(jsonContext.jp().getText());
|
||||
} else {
|
||||
value = jsonContext.jp().getFloatValue();
|
||||
}
|
||||
value = context.parser().floatValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -184,12 +180,12 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
|
||||
return SortField.FLOAT;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(jsonType());
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(contentType());
|
||||
builder.field("name", name());
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
@ -197,7 +193,7 @@ public class JsonBoostFieldMapper extends JsonNumberFieldMapper<Float> implement
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// do nothing here, no merging, but also no exception
|
||||
}
|
||||
}
|
@ -17,13 +17,12 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericDateAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
@ -31,28 +30,29 @@ import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.joda.FormatDateTimeFormatter;
|
||||
import org.elasticsearch.util.joda.Joda;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
public class XContentDateFieldMapper extends XContentNumberFieldMapper<Long> {
|
||||
|
||||
public static final String JSON_TYPE = "date";
|
||||
public static final String CONTENT_TYPE = "date";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final FormatDateTimeFormatter DATE_TIME_FORMATTER = Joda.forPattern("dateOptionalTime");
|
||||
|
||||
public static final String NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonDateFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentDateFieldMapper> {
|
||||
|
||||
protected String nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -73,17 +73,17 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonDateFieldMapper build(BuilderContext context) {
|
||||
JsonDateFieldMapper fieldMapper = new JsonDateFieldMapper(buildNames(context), dateTimeFormatter,
|
||||
@Override public XContentDateFieldMapper build(BuilderContext context) {
|
||||
XContentDateFieldMapper fieldMapper = new XContentDateFieldMapper(buildNames(context), dateTimeFormatter,
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonDateFieldMapper.Builder builder = dateField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentDateFieldMapper.Builder builder = dateField(name);
|
||||
parseNumberField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -102,10 +102,10 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
|
||||
private final String nullValue;
|
||||
|
||||
protected JsonDateFieldMapper(Names names, FormatDateTimeFormatter dateTimeFormatter, int precisionStep,
|
||||
Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
String nullValue) {
|
||||
protected XContentDateFieldMapper(Names names, FormatDateTimeFormatter dateTimeFormatter, int precisionStep,
|
||||
Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
String nullValue) {
|
||||
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
new NamedAnalyzer("_date/" + precisionStep, new NumericDateAnalyzer(precisionStep, dateTimeFormatter.parser())),
|
||||
new NamedAnalyzer("_date/max", new NumericDateAnalyzer(Integer.MAX_VALUE, dateTimeFormatter.parser())));
|
||||
@ -178,18 +178,18 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
String dateAsString;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
dateAsString = (String) jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
dateAsString = (String) context.externalValue();
|
||||
if (dateAsString == null) {
|
||||
dateAsString = nullValue;
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
dateAsString = nullValue;
|
||||
} else {
|
||||
dateAsString = jsonContext.jp().getText();
|
||||
dateAsString = context.parser().text();
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
return null;
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), dateAsString, boost);
|
||||
context.allEntries().addText(names.fullName(), dateAsString, boost);
|
||||
}
|
||||
|
||||
long value = dateTimeFormatter.parser().parseMillis(dateAsString);
|
||||
@ -217,12 +217,12 @@ public class JsonDateFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
return SortField.LONG;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
builder.field("format", dateTimeFormatter.format());
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
@ -17,89 +17,85 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.codehaus.jackson.JsonFactory;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.util.Preconditions;
|
||||
import org.elasticsearch.util.ThreadLocals;
|
||||
import org.elasticsearch.util.json.Jackson;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.json.StringJsonBuilder;
|
||||
import org.elasticsearch.util.json.ToJson;
|
||||
import org.elasticsearch.util.xcontent.ToXContent;
|
||||
import org.elasticsearch.util.xcontent.XContentFactory;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.XContentType;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.util.gcommon.collect.Lists.*;
|
||||
import static org.elasticsearch.util.json.JsonBuilder.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class
|
||||
JsonDocumentMapper implements DocumentMapper, ToJson {
|
||||
public class XContentDocumentMapper implements DocumentMapper, ToXContent {
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private JsonUidFieldMapper uidFieldMapper = new JsonUidFieldMapper();
|
||||
private XContentUidFieldMapper uidFieldMapper = new XContentUidFieldMapper();
|
||||
|
||||
private JsonIdFieldMapper idFieldMapper = new JsonIdFieldMapper();
|
||||
private XContentIdFieldMapper idFieldMapper = new XContentIdFieldMapper();
|
||||
|
||||
private JsonTypeFieldMapper typeFieldMapper = new JsonTypeFieldMapper();
|
||||
private XContentTypeFieldMapper typeFieldMapper = new XContentTypeFieldMapper();
|
||||
|
||||
private JsonSourceFieldMapper sourceFieldMapper = new JsonSourceFieldMapper();
|
||||
private XContentSourceFieldMapper sourceFieldMapper = new XContentSourceFieldMapper();
|
||||
|
||||
private JsonBoostFieldMapper boostFieldMapper = new JsonBoostFieldMapper();
|
||||
private XContentBoostFieldMapper boostFieldMapper = new XContentBoostFieldMapper();
|
||||
|
||||
private JsonAllFieldMapper allFieldMapper = new JsonAllFieldMapper();
|
||||
private XContentAllFieldMapper allFieldMapper = new XContentAllFieldMapper();
|
||||
|
||||
private NamedAnalyzer indexAnalyzer;
|
||||
|
||||
private NamedAnalyzer searchAnalyzer;
|
||||
|
||||
private final JsonObjectMapper rootObjectMapper;
|
||||
private final XContentObjectMapper rootObjectMapper;
|
||||
|
||||
private String mappingSource;
|
||||
|
||||
private JsonMapper.BuilderContext builderContext = new JsonMapper.BuilderContext(new JsonPath(1));
|
||||
private XContentMapper.BuilderContext builderContext = new XContentMapper.BuilderContext(new ContentPath(1));
|
||||
|
||||
public Builder(JsonObjectMapper.Builder builder) {
|
||||
public Builder(XContentObjectMapper.Builder builder) {
|
||||
this.rootObjectMapper = builder.build(builderContext);
|
||||
}
|
||||
|
||||
public Builder sourceField(JsonSourceFieldMapper.Builder builder) {
|
||||
public Builder sourceField(XContentSourceFieldMapper.Builder builder) {
|
||||
this.sourceFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder idField(JsonIdFieldMapper.Builder builder) {
|
||||
public Builder idField(XContentIdFieldMapper.Builder builder) {
|
||||
this.idFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder uidField(JsonUidFieldMapper.Builder builder) {
|
||||
public Builder uidField(XContentUidFieldMapper.Builder builder) {
|
||||
this.uidFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder typeField(JsonTypeFieldMapper.Builder builder) {
|
||||
public Builder typeField(XContentTypeFieldMapper.Builder builder) {
|
||||
this.typeFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder boostField(JsonBoostFieldMapper.Builder builder) {
|
||||
public Builder boostField(XContentBoostFieldMapper.Builder builder) {
|
||||
this.boostFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder allField(JsonAllFieldMapper.Builder builder) {
|
||||
public Builder allField(XContentAllFieldMapper.Builder builder) {
|
||||
this.allFieldMapper = builder.build(builderContext);
|
||||
return this;
|
||||
}
|
||||
@ -127,39 +123,37 @@ public class
|
||||
return searchAnalyzer != null;
|
||||
}
|
||||
|
||||
public JsonDocumentMapper build() {
|
||||
Preconditions.checkNotNull(rootObjectMapper, "Json mapper builder must have the root object mapper set");
|
||||
return new JsonDocumentMapper(rootObjectMapper, uidFieldMapper, idFieldMapper, typeFieldMapper,
|
||||
public XContentDocumentMapper build() {
|
||||
Preconditions.checkNotNull(rootObjectMapper, "Mapper builder must have the root object mapper set");
|
||||
return new XContentDocumentMapper(rootObjectMapper, uidFieldMapper, idFieldMapper, typeFieldMapper,
|
||||
sourceFieldMapper, allFieldMapper, indexAnalyzer, searchAnalyzer, boostFieldMapper, mappingSource);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private ThreadLocal<ThreadLocals.CleanableValue<JsonParseContext>> cache = new ThreadLocal<ThreadLocals.CleanableValue<JsonParseContext>>() {
|
||||
@Override protected ThreadLocals.CleanableValue<JsonParseContext> initialValue() {
|
||||
return new ThreadLocals.CleanableValue<JsonParseContext>(new JsonParseContext(JsonDocumentMapper.this, new JsonPath(0)));
|
||||
private ThreadLocal<ThreadLocals.CleanableValue<ParseContext>> cache = new ThreadLocal<ThreadLocals.CleanableValue<ParseContext>>() {
|
||||
@Override protected ThreadLocals.CleanableValue<ParseContext> initialValue() {
|
||||
return new ThreadLocals.CleanableValue<ParseContext>(new ParseContext(XContentDocumentMapper.this, new ContentPath(0)));
|
||||
}
|
||||
};
|
||||
|
||||
private final JsonFactory jsonFactory = Jackson.defaultJsonFactory();
|
||||
|
||||
private final String type;
|
||||
|
||||
private volatile String mappingSource;
|
||||
|
||||
private final JsonUidFieldMapper uidFieldMapper;
|
||||
private final XContentUidFieldMapper uidFieldMapper;
|
||||
|
||||
private final JsonIdFieldMapper idFieldMapper;
|
||||
private final XContentIdFieldMapper idFieldMapper;
|
||||
|
||||
private final JsonTypeFieldMapper typeFieldMapper;
|
||||
private final XContentTypeFieldMapper typeFieldMapper;
|
||||
|
||||
private final JsonSourceFieldMapper sourceFieldMapper;
|
||||
private final XContentSourceFieldMapper sourceFieldMapper;
|
||||
|
||||
private final JsonBoostFieldMapper boostFieldMapper;
|
||||
private final XContentBoostFieldMapper boostFieldMapper;
|
||||
|
||||
private final JsonAllFieldMapper allFieldMapper;
|
||||
private final XContentAllFieldMapper allFieldMapper;
|
||||
|
||||
private final JsonObjectMapper rootObjectMapper;
|
||||
private final XContentObjectMapper rootObjectMapper;
|
||||
|
||||
private final Analyzer indexAnalyzer;
|
||||
|
||||
@ -171,14 +165,14 @@ public class
|
||||
|
||||
private final Object mutex = new Object();
|
||||
|
||||
public JsonDocumentMapper(JsonObjectMapper rootObjectMapper,
|
||||
JsonUidFieldMapper uidFieldMapper,
|
||||
JsonIdFieldMapper idFieldMapper,
|
||||
JsonTypeFieldMapper typeFieldMapper,
|
||||
JsonSourceFieldMapper sourceFieldMapper,
|
||||
JsonAllFieldMapper allFieldMapper,
|
||||
public XContentDocumentMapper(XContentObjectMapper rootObjectMapper,
|
||||
XContentUidFieldMapper uidFieldMapper,
|
||||
XContentIdFieldMapper idFieldMapper,
|
||||
XContentTypeFieldMapper typeFieldMapper,
|
||||
XContentSourceFieldMapper sourceFieldMapper,
|
||||
XContentAllFieldMapper allFieldMapper,
|
||||
Analyzer indexAnalyzer, Analyzer searchAnalyzer,
|
||||
@Nullable JsonBoostFieldMapper boostFieldMapper,
|
||||
@Nullable XContentBoostFieldMapper boostFieldMapper,
|
||||
@Nullable String mappingSource) {
|
||||
this.type = rootObjectMapper.name();
|
||||
this.mappingSource = mappingSource;
|
||||
@ -279,74 +273,70 @@ public class
|
||||
}
|
||||
|
||||
@Override public ParsedDocument parse(String type, String id, byte[] source, ParseListener listener) {
|
||||
JsonParseContext jsonContext = cache.get().get();
|
||||
ParseContext context = cache.get().get();
|
||||
|
||||
if (type != null && !type.equals(this.type)) {
|
||||
throw new MapperParsingException("Type mismatch, provide type [" + type + "] but mapper is of type [" + this.type + "]");
|
||||
}
|
||||
type = this.type;
|
||||
|
||||
JsonParser jp = null;
|
||||
XContentParser parser = null;
|
||||
try {
|
||||
jp = jsonFactory.createJsonParser(source);
|
||||
jsonContext.reset(jp, new Document(), type, source, listener);
|
||||
parser = XContentFactory.xContent(source).createParser(source);
|
||||
context.reset(parser, new Document(), type, source, listener);
|
||||
|
||||
// will result in JsonToken.START_OBJECT
|
||||
JsonToken token = jp.nextToken();
|
||||
if (token != JsonToken.START_OBJECT) {
|
||||
throw new MapperException("Malformed json, must start with an object");
|
||||
// will result in START_OBJECT
|
||||
XContentParser.Token token = parser.nextToken();
|
||||
if (token != XContentParser.Token.START_OBJECT) {
|
||||
throw new MapperException("Malformed content, must start with an object");
|
||||
}
|
||||
token = jp.nextToken();
|
||||
if (token != JsonToken.FIELD_NAME) {
|
||||
throw new MapperException("Malformed json, after first object, the type name must exists");
|
||||
token = parser.nextToken();
|
||||
if (token != XContentParser.Token.FIELD_NAME) {
|
||||
throw new MapperException("Malformed content, after first object, the type name must exists");
|
||||
}
|
||||
if (!jp.getCurrentName().equals(type)) {
|
||||
if (!parser.currentName().equals(type)) {
|
||||
if (type == null) {
|
||||
throw new MapperException("Json content type [" + jp.getCurrentName() + "] does not match the type of the mapper [" + type + "]");
|
||||
throw new MapperException("Content _type [" + parser.currentName() + "] does not match the type of the mapper [" + type + "]");
|
||||
}
|
||||
// continue
|
||||
} else {
|
||||
// now move to the actual content, which is the start object
|
||||
token = jp.nextToken();
|
||||
if (token != JsonToken.START_OBJECT) {
|
||||
throw new MapperException("Malformed json, a field with the same name as the type much be an object json with the properties/fields within it");
|
||||
token = parser.nextToken();
|
||||
if (token != XContentParser.Token.START_OBJECT) {
|
||||
throw new MapperException("Malformed content, a field with the same name as the type much be an object with the properties/fields within it");
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceFieldMapper.enabled()) {
|
||||
sourceFieldMapper.parse(jsonContext);
|
||||
sourceFieldMapper.parse(context);
|
||||
}
|
||||
// set the id if we have it so we can validate it later on, also, add the uid if we can
|
||||
if (id != null) {
|
||||
jsonContext.id(id);
|
||||
uidFieldMapper.parse(jsonContext);
|
||||
context.id(id);
|
||||
uidFieldMapper.parse(context);
|
||||
}
|
||||
typeFieldMapper.parse(jsonContext);
|
||||
typeFieldMapper.parse(context);
|
||||
|
||||
rootObjectMapper.parse(jsonContext);
|
||||
rootObjectMapper.parse(context);
|
||||
|
||||
// if we did not get the id, we need to parse the uid into the document now, after it was added
|
||||
if (id == null) {
|
||||
uidFieldMapper.parse(jsonContext);
|
||||
uidFieldMapper.parse(context);
|
||||
}
|
||||
if (jsonContext.parsedIdState() != JsonParseContext.ParsedIdState.PARSED) {
|
||||
if (context.parsedIdState() != ParseContext.ParsedIdState.PARSED) {
|
||||
// mark it as external, so we can parse it
|
||||
jsonContext.parsedId(JsonParseContext.ParsedIdState.EXTERNAL);
|
||||
idFieldMapper.parse(jsonContext);
|
||||
context.parsedId(ParseContext.ParsedIdState.EXTERNAL);
|
||||
idFieldMapper.parse(context);
|
||||
}
|
||||
allFieldMapper.parse(jsonContext);
|
||||
allFieldMapper.parse(context);
|
||||
} catch (IOException e) {
|
||||
throw new MapperParsingException("Failed to parse", e);
|
||||
} finally {
|
||||
if (jp != null) {
|
||||
try {
|
||||
jp.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
if (parser != null) {
|
||||
parser.close();
|
||||
}
|
||||
}
|
||||
return new ParsedDocument(jsonContext.uid(), jsonContext.id(), jsonContext.type(), jsonContext.doc(), source, jsonContext.mappersAdded());
|
||||
return new ParsedDocument(context.uid(), context.id(), context.type(), context.doc(), source, context.mappersAdded());
|
||||
}
|
||||
|
||||
void addFieldMapper(FieldMapper fieldMapper) {
|
||||
@ -373,9 +363,9 @@ public class
|
||||
}
|
||||
|
||||
@Override public synchronized MergeResult merge(DocumentMapper mergeWith, MergeFlags mergeFlags) {
|
||||
JsonDocumentMapper jsonMergeWith = (JsonDocumentMapper) mergeWith;
|
||||
JsonMergeContext mergeContext = new JsonMergeContext(this, mergeFlags);
|
||||
rootObjectMapper.merge(jsonMergeWith.rootObjectMapper, mergeContext);
|
||||
XContentDocumentMapper xContentMergeWith = (XContentDocumentMapper) mergeWith;
|
||||
MergeContext mergeContext = new MergeContext(this, mergeFlags);
|
||||
rootObjectMapper.merge(xContentMergeWith.rootObjectMapper, mergeContext);
|
||||
if (!mergeFlags.simulate()) {
|
||||
// update the source to the merged one
|
||||
mappingSource = buildSource();
|
||||
@ -385,9 +375,9 @@ public class
|
||||
|
||||
@Override public String buildSource() throws FailedToGenerateSourceMapperException {
|
||||
try {
|
||||
StringJsonBuilder builder = stringJsonBuilder().prettyPrint();
|
||||
XContentBuilder builder = XContentFactory.contentTextBuilder(XContentType.JSON);
|
||||
builder.startObject();
|
||||
toJson(builder, ToJson.EMPTY_PARAMS);
|
||||
toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
return builder.string();
|
||||
} catch (Exception e) {
|
||||
@ -395,7 +385,7 @@ public class
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
rootObjectMapper.toJson(builder, params, allFieldMapper, sourceFieldMapper);
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
rootObjectMapper.toXContent(builder, params, allFieldMapper, sourceFieldMapper);
|
||||
}
|
||||
}
|
@ -17,9 +17,8 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.DocumentMapperParser;
|
||||
@ -27,51 +26,49 @@ import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.MapBuilder;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
|
||||
import org.elasticsearch.util.io.FastStringReader;
|
||||
import org.elasticsearch.util.json.Jackson;
|
||||
import org.elasticsearch.util.xcontent.XContentFactory;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonDocumentMapperParser implements DocumentMapperParser {
|
||||
|
||||
private final ObjectMapper objectMapper = Jackson.newObjectMapper();
|
||||
public class XContentDocumentMapperParser implements DocumentMapperParser {
|
||||
|
||||
private final AnalysisService analysisService;
|
||||
|
||||
private final JsonObjectMapper.TypeParser rootObjectTypeParser = new JsonObjectMapper.TypeParser();
|
||||
private final XContentObjectMapper.TypeParser rootObjectTypeParser = new XContentObjectMapper.TypeParser();
|
||||
|
||||
private final Object typeParsersMutex = new Object();
|
||||
|
||||
private volatile ImmutableMap<String, JsonTypeParser> typeParsers;
|
||||
private volatile ImmutableMap<String, XContentTypeParser> typeParsers;
|
||||
|
||||
public JsonDocumentMapperParser(AnalysisService analysisService) {
|
||||
public XContentDocumentMapperParser(AnalysisService analysisService) {
|
||||
this.analysisService = analysisService;
|
||||
typeParsers = new MapBuilder<String, JsonTypeParser>()
|
||||
.put(JsonShortFieldMapper.JSON_TYPE, new JsonShortFieldMapper.TypeParser())
|
||||
.put(JsonIntegerFieldMapper.JSON_TYPE, new JsonIntegerFieldMapper.TypeParser())
|
||||
.put(JsonLongFieldMapper.JSON_TYPE, new JsonLongFieldMapper.TypeParser())
|
||||
.put(JsonFloatFieldMapper.JSON_TYPE, new JsonFloatFieldMapper.TypeParser())
|
||||
.put(JsonDoubleFieldMapper.JSON_TYPE, new JsonDoubleFieldMapper.TypeParser())
|
||||
.put(JsonBooleanFieldMapper.JSON_TYPE, new JsonBooleanFieldMapper.TypeParser())
|
||||
.put(JsonBinaryFieldMapper.JSON_TYPE, new JsonBinaryFieldMapper.TypeParser())
|
||||
.put(JsonDateFieldMapper.JSON_TYPE, new JsonDateFieldMapper.TypeParser())
|
||||
.put(JsonStringFieldMapper.JSON_TYPE, new JsonStringFieldMapper.TypeParser())
|
||||
.put(JsonObjectMapper.JSON_TYPE, new JsonObjectMapper.TypeParser())
|
||||
.put(JsonMultiFieldMapper.JSON_TYPE, new JsonMultiFieldMapper.TypeParser())
|
||||
typeParsers = new MapBuilder<String, XContentTypeParser>()
|
||||
.put(XContentShortFieldMapper.CONTENT_TYPE, new XContentShortFieldMapper.TypeParser())
|
||||
.put(XContentIntegerFieldMapper.CONTENT_TYPE, new XContentIntegerFieldMapper.TypeParser())
|
||||
.put(XContentLongFieldMapper.CONTENT_TYPE, new XContentLongFieldMapper.TypeParser())
|
||||
.put(XContentFloatFieldMapper.CONTENT_TYPE, new XContentFloatFieldMapper.TypeParser())
|
||||
.put(XContentDoubleFieldMapper.CONTENT_TYPE, new XContentDoubleFieldMapper.TypeParser())
|
||||
.put(XContentBooleanFieldMapper.CONTENT_TYPE, new XContentBooleanFieldMapper.TypeParser())
|
||||
.put(XContentBinaryFieldMapper.CONTENT_TYPE, new XContentBinaryFieldMapper.TypeParser())
|
||||
.put(XContentDateFieldMapper.CONTENT_TYPE, new XContentDateFieldMapper.TypeParser())
|
||||
.put(XContentStringFieldMapper.CONTENT_TYPE, new XContentStringFieldMapper.TypeParser())
|
||||
.put(XContentObjectMapper.CONTENT_TYPE, new XContentObjectMapper.TypeParser())
|
||||
.put(XContentMultiFieldMapper.CONTENT_TYPE, new XContentMultiFieldMapper.TypeParser())
|
||||
.immutableMap();
|
||||
}
|
||||
|
||||
public void putTypeParser(String type, JsonTypeParser typeParser) {
|
||||
public void putTypeParser(String type, XContentTypeParser typeParser) {
|
||||
synchronized (typeParsersMutex) {
|
||||
typeParsers = new MapBuilder<String, JsonTypeParser>()
|
||||
typeParsers = new MapBuilder<String, XContentTypeParser>()
|
||||
.putAll(typeParsers)
|
||||
.put(type, typeParser)
|
||||
.immutableMap();
|
||||
@ -84,10 +81,16 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
||||
|
||||
@Override public DocumentMapper parse(String type, String source) throws MapperParsingException {
|
||||
Map<String, Object> root;
|
||||
XContentParser xContentParser = null;
|
||||
try {
|
||||
root = objectMapper.readValue(new FastStringReader(source), Map.class);
|
||||
xContentParser = XContentFactory.xContent(source).createParser(source);
|
||||
root = xContentParser.map();
|
||||
} catch (IOException e) {
|
||||
throw new MapperParsingException("Failed to parse json mapping definition", e);
|
||||
throw new MapperParsingException("Failed to parse mapping definition", e);
|
||||
} finally {
|
||||
if (xContentParser != null) {
|
||||
xContentParser.close();
|
||||
}
|
||||
}
|
||||
String rootName = root.keySet().iterator().next();
|
||||
Map<String, Object> rootObj;
|
||||
@ -109,25 +112,25 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
||||
}
|
||||
}
|
||||
|
||||
JsonTypeParser.ParserContext parserContext = new JsonTypeParser.ParserContext(rootObj, analysisService, typeParsers);
|
||||
XContentTypeParser.ParserContext parserContext = new XContentTypeParser.ParserContext(rootObj, analysisService, typeParsers);
|
||||
|
||||
JsonDocumentMapper.Builder docBuilder = doc((JsonObjectMapper.Builder) rootObjectTypeParser.parse(type, rootObj, parserContext));
|
||||
XContentDocumentMapper.Builder docBuilder = doc((XContentObjectMapper.Builder) rootObjectTypeParser.parse(type, rootObj, parserContext));
|
||||
|
||||
for (Map.Entry<String, Object> entry : rootObj.entrySet()) {
|
||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||
Object fieldNode = entry.getValue();
|
||||
|
||||
if (JsonSourceFieldMapper.JSON_TYPE.equals(fieldName) || "sourceField".equals(fieldName)) {
|
||||
if (XContentSourceFieldMapper.CONTENT_TYPE.equals(fieldName) || "sourceField".equals(fieldName)) {
|
||||
docBuilder.sourceField(parseSourceField((Map<String, Object>) fieldNode, parserContext));
|
||||
} else if (JsonIdFieldMapper.JSON_TYPE.equals(fieldName) || "idField".equals(fieldName)) {
|
||||
} else if (XContentIdFieldMapper.CONTENT_TYPE.equals(fieldName) || "idField".equals(fieldName)) {
|
||||
docBuilder.idField(parseIdField((Map<String, Object>) fieldNode, parserContext));
|
||||
} else if (JsonTypeFieldMapper.JSON_TYPE.equals(fieldName) || "typeField".equals(fieldName)) {
|
||||
} else if (XContentTypeFieldMapper.CONTENT_TYPE.equals(fieldName) || "typeField".equals(fieldName)) {
|
||||
docBuilder.typeField(parseTypeField((Map<String, Object>) fieldNode, parserContext));
|
||||
} else if (JsonUidFieldMapper.JSON_TYPE.equals(fieldName) || "uidField".equals(fieldName)) {
|
||||
} else if (XContentUidFieldMapper.CONTENT_TYPE.equals(fieldName) || "uidField".equals(fieldName)) {
|
||||
docBuilder.uidField(parseUidField((Map<String, Object>) fieldNode, parserContext));
|
||||
} else if (JsonBoostFieldMapper.JSON_TYPE.equals(fieldName) || "boostField".equals(fieldName)) {
|
||||
} else if (XContentBoostFieldMapper.CONTENT_TYPE.equals(fieldName) || "boostField".equals(fieldName)) {
|
||||
docBuilder.boostField(parseBoostField((Map<String, Object>) fieldNode, parserContext));
|
||||
} else if (JsonAllFieldMapper.JSON_TYPE.equals(fieldName) || "allField".equals(fieldName)) {
|
||||
} else if (XContentAllFieldMapper.CONTENT_TYPE.equals(fieldName) || "allField".equals(fieldName)) {
|
||||
docBuilder.allField(parseAllField((Map<String, Object>) fieldNode, parserContext));
|
||||
} else if ("index_analyzer".equals(fieldName)) {
|
||||
docBuilder.indexAnalyzer(analysisService.analyzer(fieldNode.toString()));
|
||||
@ -148,20 +151,20 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
||||
|
||||
docBuilder.mappingSource(source);
|
||||
|
||||
JsonDocumentMapper documentMapper = docBuilder.build();
|
||||
XContentDocumentMapper documentMapper = docBuilder.build();
|
||||
// update the source with the generated one
|
||||
documentMapper.mappingSource(documentMapper.buildSource());
|
||||
return documentMapper;
|
||||
}
|
||||
|
||||
private JsonUidFieldMapper.Builder parseUidField(Map<String, Object> uidNode, JsonTypeParser.ParserContext parserContext) {
|
||||
JsonUidFieldMapper.Builder builder = uid();
|
||||
private XContentUidFieldMapper.Builder parseUidField(Map<String, Object> uidNode, XContentTypeParser.ParserContext parserContext) {
|
||||
XContentUidFieldMapper.Builder builder = uid();
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonBoostFieldMapper.Builder parseBoostField(Map<String, Object> boostNode, JsonTypeParser.ParserContext parserContext) {
|
||||
String name = boostNode.get("name") == null ? JsonBoostFieldMapper.Defaults.NAME : boostNode.get("name").toString();
|
||||
JsonBoostFieldMapper.Builder builder = boost(name);
|
||||
private XContentBoostFieldMapper.Builder parseBoostField(Map<String, Object> boostNode, XContentTypeParser.ParserContext parserContext) {
|
||||
String name = boostNode.get("name") == null ? XContentBoostFieldMapper.Defaults.NAME : boostNode.get("name").toString();
|
||||
XContentBoostFieldMapper.Builder builder = boost(name);
|
||||
parseNumberField(builder, name, boostNode, parserContext);
|
||||
for (Map.Entry<String, Object> entry : boostNode.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -173,22 +176,22 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonTypeFieldMapper.Builder parseTypeField(Map<String, Object> typeNode, JsonTypeParser.ParserContext parserContext) {
|
||||
JsonTypeFieldMapper.Builder builder = type();
|
||||
parseJsonField(builder, builder.name, typeNode, parserContext);
|
||||
private XContentTypeFieldMapper.Builder parseTypeField(Map<String, Object> typeNode, XContentTypeParser.ParserContext parserContext) {
|
||||
XContentTypeFieldMapper.Builder builder = type();
|
||||
parseField(builder, builder.name, typeNode, parserContext);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private JsonIdFieldMapper.Builder parseIdField(Map<String, Object> idNode, JsonTypeParser.ParserContext parserContext) {
|
||||
JsonIdFieldMapper.Builder builder = id();
|
||||
parseJsonField(builder, builder.name, idNode, parserContext);
|
||||
private XContentIdFieldMapper.Builder parseIdField(Map<String, Object> idNode, XContentTypeParser.ParserContext parserContext) {
|
||||
XContentIdFieldMapper.Builder builder = id();
|
||||
parseField(builder, builder.name, idNode, parserContext);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonAllFieldMapper.Builder parseAllField(Map<String, Object> allNode, JsonTypeParser.ParserContext parserContext) {
|
||||
JsonAllFieldMapper.Builder builder = all();
|
||||
parseJsonField(builder, builder.name, allNode, parserContext);
|
||||
private XContentAllFieldMapper.Builder parseAllField(Map<String, Object> allNode, XContentTypeParser.ParserContext parserContext) {
|
||||
XContentAllFieldMapper.Builder builder = all();
|
||||
parseField(builder, builder.name, allNode, parserContext);
|
||||
for (Map.Entry<String, Object> entry : allNode.entrySet()) {
|
||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||
Object fieldNode = entry.getValue();
|
||||
@ -199,8 +202,8 @@ public class JsonDocumentMapperParser implements DocumentMapperParser {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private JsonSourceFieldMapper.Builder parseSourceField(Map<String, Object> sourceNode, JsonTypeParser.ParserContext parserContext) {
|
||||
JsonSourceFieldMapper.Builder builder = source();
|
||||
private XContentSourceFieldMapper.Builder parseSourceField(Map<String, Object> sourceNode, XContentTypeParser.ParserContext parserContext) {
|
||||
XContentSourceFieldMapper.Builder builder = source();
|
||||
|
||||
for (Map.Entry<String, Object> entry : sourceNode.entrySet()) {
|
||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
@ -17,38 +17,38 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericDoubleAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
|
||||
public class XContentDoubleFieldMapper extends XContentNumberFieldMapper<Double> {
|
||||
|
||||
public static final String JSON_TYPE = "double";
|
||||
public static final String CONTENT_TYPE = "double";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final Double NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonDoubleFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentDoubleFieldMapper> {
|
||||
|
||||
protected Double nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -62,17 +62,17 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonDoubleFieldMapper build(BuilderContext context) {
|
||||
JsonDoubleFieldMapper fieldMapper = new JsonDoubleFieldMapper(buildNames(context),
|
||||
@Override public XContentDoubleFieldMapper build(BuilderContext context) {
|
||||
XContentDoubleFieldMapper fieldMapper = new XContentDoubleFieldMapper(buildNames(context),
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonDoubleFieldMapper.Builder builder = doubleField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentDoubleFieldMapper.Builder builder = doubleField(name);
|
||||
parseNumberField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = entry.getKey();
|
||||
@ -90,10 +90,10 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
|
||||
|
||||
private final String nullValueAsString;
|
||||
|
||||
protected JsonDoubleFieldMapper(Names names, int precisionStep,
|
||||
Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Double nullValue) {
|
||||
protected XContentDoubleFieldMapper(Names names, int precisionStep,
|
||||
Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Double nullValue) {
|
||||
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
new NamedAnalyzer("_double/" + precisionStep, new NumericDoubleAnalyzer(precisionStep)),
|
||||
new NamedAnalyzer("_double/max", new NumericDoubleAnalyzer(Integer.MAX_VALUE)));
|
||||
@ -147,10 +147,10 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
double value;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
Object externalValue = jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
Object externalValue = context.externalValue();
|
||||
if (externalValue == null) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
@ -160,25 +160,21 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
|
||||
value = ((Number) externalValue).doubleValue();
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), Double.toString(value), boost);
|
||||
context.allEntries().addText(names.fullName(), Double.toString(value), boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
}
|
||||
value = nullValue;
|
||||
if (nullValueAsString != null && (includeInAll == null || includeInAll)) {
|
||||
jsonContext.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
|
||||
value = Double.parseDouble(jsonContext.jp().getText());
|
||||
} else {
|
||||
value = jsonContext.jp().getDoubleValue();
|
||||
}
|
||||
value = context.parser().doubleValue();
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), jsonContext.jp().getText(), boost);
|
||||
context.allEntries().addText(names.fullName(), context.parser().text(), boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -199,12 +195,12 @@ public class JsonDoubleFieldMapper extends JsonNumberFieldMapper<Double> {
|
||||
return SortField.DOUBLE;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
import org.apache.lucene.document.Field;
|
||||
@ -28,15 +28,15 @@ import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMapperListener;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.search.TermFilter;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
public abstract class XContentFieldMapper<T> implements FieldMapper<T>, XContentMapper {
|
||||
|
||||
public static class Defaults {
|
||||
public static final Field.Index INDEX = Field.Index.ANALYZED;
|
||||
@ -47,7 +47,7 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
public static final boolean OMIT_TERM_FREQ_AND_POSITIONS = false;
|
||||
}
|
||||
|
||||
public abstract static class OpenBuilder<T extends Builder, Y extends JsonFieldMapper> extends JsonFieldMapper.Builder<T, Y> {
|
||||
public abstract static class OpenBuilder<T extends Builder, Y extends XContentFieldMapper> extends XContentFieldMapper.Builder<T, Y> {
|
||||
|
||||
protected OpenBuilder(String name) {
|
||||
super(name);
|
||||
@ -90,7 +90,7 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class Builder<T extends Builder, Y extends JsonFieldMapper> extends JsonMapper.Builder<T, Y> {
|
||||
public abstract static class Builder<T extends Builder, Y extends XContentFieldMapper> extends XContentMapper.Builder<T, Y> {
|
||||
|
||||
protected Field.Index index = Defaults.INDEX;
|
||||
|
||||
@ -201,8 +201,8 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
|
||||
protected final NamedAnalyzer searchAnalyzer;
|
||||
|
||||
protected JsonFieldMapper(Names names, Field.Index index, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer) {
|
||||
protected XContentFieldMapper(Names names, Field.Index index, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer) {
|
||||
this.names = names;
|
||||
this.index = index;
|
||||
this.store = store;
|
||||
@ -266,20 +266,20 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
return this.searchAnalyzer;
|
||||
}
|
||||
|
||||
@Override public void parse(JsonParseContext jsonContext) throws IOException {
|
||||
Field field = parseCreateField(jsonContext);
|
||||
@Override public void parse(ParseContext context) throws IOException {
|
||||
Field field = parseCreateField(context);
|
||||
if (field == null) {
|
||||
return;
|
||||
}
|
||||
field.setOmitNorms(omitNorms);
|
||||
field.setOmitTermFreqAndPositions(omitTermFreqAndPositions);
|
||||
field.setBoost(boost);
|
||||
if (jsonContext.listener().beforeFieldAdded(this, field, jsonContext)) {
|
||||
jsonContext.doc().add(field);
|
||||
if (context.listener().beforeFieldAdded(this, field, context)) {
|
||||
context.doc().add(field);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Field parseCreateField(JsonParseContext jsonContext) throws IOException;
|
||||
protected abstract Field parseCreateField(ParseContext context) throws IOException;
|
||||
|
||||
@Override public void traverse(FieldMapperListener fieldMapperListener) {
|
||||
fieldMapperListener.fieldMapper(this);
|
||||
@ -330,7 +330,7 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
@Override public Query fieldQuery(String value) {
|
||||
return new TermQuery(new Term(names.indexName(), indexedValue(value)));
|
||||
}
|
||||
|
||||
|
||||
@Override public Filter fieldFilter(String value) {
|
||||
return new TermFilter(new Term(names.indexName(), indexedValue(value)));
|
||||
}
|
||||
@ -349,7 +349,7 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
mergeContext.addConflict("Mapper [" + names.fullName() + "] exists, can't merge");
|
||||
}
|
||||
|
||||
@ -357,14 +357,14 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
return SortField.STRING;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(names.name());
|
||||
doJsonBody(builder);
|
||||
doXContentBody(builder);
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
builder.field("type", jsonType());
|
||||
protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
builder.field("type", contentType());
|
||||
builder.field("index_name", names.indexNameClean());
|
||||
builder.field("index", index.name().toLowerCase());
|
||||
builder.field("store", store.name().toLowerCase());
|
||||
@ -380,5 +380,5 @@ public abstract class JsonFieldMapper<T> implements FieldMapper<T>, JsonMapper {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract String jsonType();
|
||||
protected abstract String contentType();
|
||||
}
|
@ -17,39 +17,39 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericFloatAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
|
||||
public class XContentFloatFieldMapper extends XContentNumberFieldMapper<Float> {
|
||||
|
||||
public static final String JSON_TYPE = "float";
|
||||
public static final String CONTENT_TYPE = "float";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final Float NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonFloatFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentFloatFieldMapper> {
|
||||
|
||||
protected Float nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -63,17 +63,17 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonFloatFieldMapper build(BuilderContext context) {
|
||||
JsonFloatFieldMapper fieldMapper = new JsonFloatFieldMapper(buildNames(context),
|
||||
@Override public XContentFloatFieldMapper build(BuilderContext context) {
|
||||
XContentFloatFieldMapper fieldMapper = new XContentFloatFieldMapper(buildNames(context),
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonFloatFieldMapper.Builder builder = floatField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentFloatFieldMapper.Builder builder = floatField(name);
|
||||
parseNumberField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -90,7 +90,7 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
|
||||
|
||||
private final String nullValueAsString;
|
||||
|
||||
protected JsonFloatFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
protected XContentFloatFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Float nullValue) {
|
||||
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
@ -146,10 +146,10 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
float value;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
Object externalValue = jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
Object externalValue = context.externalValue();
|
||||
if (externalValue == null) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
@ -159,25 +159,21 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
|
||||
value = ((Number) externalValue).floatValue();
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), Float.toString(value), boost);
|
||||
context.allEntries().addText(names.fullName(), Float.toString(value), boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
}
|
||||
value = nullValue;
|
||||
if (nullValueAsString != null && (includeInAll == null || includeInAll)) {
|
||||
jsonContext.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
|
||||
value = Float.parseFloat(jsonContext.jp().getText());
|
||||
} else {
|
||||
value = jsonContext.jp().getFloatValue();
|
||||
}
|
||||
value = context.parser().floatValue();
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), jsonContext.jp().getText(), boost);
|
||||
context.allEntries().addText(names.fullName(), context.parser().text(), boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,12 +194,12 @@ public class JsonFloatFieldMapper extends JsonNumberFieldMapper<Float> {
|
||||
return SortField.FLOAT;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
@ -25,19 +25,19 @@ import org.apache.lucene.document.Fieldable;
|
||||
import org.elasticsearch.index.mapper.IdFieldMapper;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.Lucene;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonIdFieldMapper extends JsonFieldMapper<String> implements IdFieldMapper {
|
||||
public class XContentIdFieldMapper extends XContentFieldMapper<String> implements IdFieldMapper {
|
||||
|
||||
public static final String JSON_TYPE = "_id";
|
||||
public static final String CONTENT_TYPE = "_id";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final String NAME = "_id";
|
||||
public static final String INDEX_NAME = "_id";
|
||||
public static final Field.Index INDEX = Field.Index.NOT_ANALYZED;
|
||||
@ -46,7 +46,7 @@ public class JsonIdFieldMapper extends JsonFieldMapper<String> implements IdFiel
|
||||
public static final boolean OMIT_TERM_FREQ_AND_POSITIONS = true;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonFieldMapper.Builder<Builder, JsonIdFieldMapper> {
|
||||
public static class Builder extends XContentFieldMapper.Builder<Builder, XContentIdFieldMapper> {
|
||||
|
||||
public Builder() {
|
||||
super(Defaults.NAME);
|
||||
@ -57,22 +57,22 @@ public class JsonIdFieldMapper extends JsonFieldMapper<String> implements IdFiel
|
||||
omitTermFreqAndPositions = Defaults.OMIT_TERM_FREQ_AND_POSITIONS;
|
||||
}
|
||||
|
||||
@Override public JsonIdFieldMapper build(BuilderContext context) {
|
||||
return new JsonIdFieldMapper(name, indexName, store, termVector, boost, omitNorms, omitTermFreqAndPositions);
|
||||
@Override public XContentIdFieldMapper build(BuilderContext context) {
|
||||
return new XContentIdFieldMapper(name, indexName, store, termVector, boost, omitNorms, omitTermFreqAndPositions);
|
||||
}
|
||||
}
|
||||
|
||||
protected JsonIdFieldMapper() {
|
||||
protected XContentIdFieldMapper() {
|
||||
this(Defaults.NAME, Defaults.INDEX_NAME);
|
||||
}
|
||||
|
||||
protected JsonIdFieldMapper(String name, String indexName) {
|
||||
protected XContentIdFieldMapper(String name, String indexName) {
|
||||
this(name, indexName, Defaults.STORE, Defaults.TERM_VECTOR, Defaults.BOOST,
|
||||
Defaults.OMIT_NORMS, Defaults.OMIT_TERM_FREQ_AND_POSITIONS);
|
||||
}
|
||||
|
||||
protected JsonIdFieldMapper(String name, String indexName, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions) {
|
||||
protected XContentIdFieldMapper(String name, String indexName, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions) {
|
||||
super(new Names(name, indexName, indexName, name), Defaults.INDEX, store, termVector, boost, omitNorms, omitTermFreqAndPositions,
|
||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER);
|
||||
}
|
||||
@ -94,36 +94,36 @@ public class JsonIdFieldMapper extends JsonFieldMapper<String> implements IdFiel
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
if (jsonContext.parsedIdState() == JsonParseContext.ParsedIdState.NO) {
|
||||
String id = jsonContext.jp().getText();
|
||||
if (jsonContext.id() != null && !jsonContext.id().equals(id)) {
|
||||
throw new MapperParsingException("Provided id [" + jsonContext.id() + "] does not match the json one [" + id + "]");
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
if (context.parsedIdState() == ParseContext.ParsedIdState.NO) {
|
||||
String id = context.parser().text();
|
||||
if (context.id() != null && !context.id().equals(id)) {
|
||||
throw new MapperParsingException("Provided id [" + context.id() + "] does not match the content one [" + id + "]");
|
||||
}
|
||||
jsonContext.id(id);
|
||||
jsonContext.parsedId(JsonParseContext.ParsedIdState.PARSED);
|
||||
return new Field(names.indexName(), jsonContext.id(), store, index);
|
||||
} else if (jsonContext.parsedIdState() == JsonParseContext.ParsedIdState.EXTERNAL) {
|
||||
if (jsonContext.id() == null) {
|
||||
throw new MapperParsingException("No id mapping with [" + names.name() + "] found in the json, and not explicitly set");
|
||||
context.id(id);
|
||||
context.parsedId(ParseContext.ParsedIdState.PARSED);
|
||||
return new Field(names.indexName(), context.id(), store, index);
|
||||
} else if (context.parsedIdState() == ParseContext.ParsedIdState.EXTERNAL) {
|
||||
if (context.id() == null) {
|
||||
throw new MapperParsingException("No id mapping with [" + names.name() + "] found in the content, and not explicitly set");
|
||||
}
|
||||
return new Field(names.indexName(), jsonContext.id(), store, index);
|
||||
return new Field(names.indexName(), context.id(), store, index);
|
||||
} else {
|
||||
throw new MapperParsingException("Illegal parsed id state");
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(JSON_TYPE);
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
builder.field("store", store.name().toLowerCase());
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// do nothing here, no merging, but also no exception
|
||||
}
|
||||
}
|
@ -17,12 +17,12 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface JsonIncludeInAllMapper extends JsonMapper {
|
||||
public interface XContentIncludeInAllMapper extends XContentMapper {
|
||||
|
||||
void includeInAll(Boolean includeInAll);
|
||||
}
|
@ -17,42 +17,39 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.codehaus.jackson.node.ObjectNode;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
|
||||
public class XContentIntegerFieldMapper extends XContentNumberFieldMapper<Integer> {
|
||||
|
||||
public static final String JSON_TYPE = "integer";
|
||||
public static final String CONTENT_TYPE = "integer";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final Integer NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonIntegerFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentIntegerFieldMapper> {
|
||||
|
||||
protected Integer nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -66,17 +63,17 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonIntegerFieldMapper build(BuilderContext context) {
|
||||
JsonIntegerFieldMapper fieldMapper = new JsonIntegerFieldMapper(buildNames(context),
|
||||
@Override public XContentIntegerFieldMapper build(BuilderContext context) {
|
||||
XContentIntegerFieldMapper fieldMapper = new XContentIntegerFieldMapper(buildNames(context),
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonIntegerFieldMapper.Builder builder = integerField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentIntegerFieldMapper.Builder builder = integerField(name);
|
||||
parseNumberField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -93,7 +90,7 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
|
||||
|
||||
private final String nullValueAsString;
|
||||
|
||||
protected JsonIntegerFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
protected XContentIntegerFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Integer nullValue) {
|
||||
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
@ -149,10 +146,10 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
int value;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
Object externalValue = jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
Object externalValue = context.externalValue();
|
||||
if (externalValue == null) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
@ -162,25 +159,21 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
|
||||
value = ((Number) externalValue).intValue();
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), Integer.toString(value), boost);
|
||||
context.allEntries().addText(names.fullName(), Integer.toString(value), boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
}
|
||||
value = nullValue;
|
||||
if (nullValueAsString != null && (includeInAll == null || includeInAll)) {
|
||||
jsonContext.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
|
||||
value = Integer.parseInt(jsonContext.jp().getText());
|
||||
} else {
|
||||
value = jsonContext.jp().getIntValue();
|
||||
}
|
||||
value = context.parser().intValue();
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), jsonContext.jp().getText(), boost);
|
||||
context.allEntries().addText(names.fullName(), context.parser().text(), boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -201,12 +194,12 @@ public class JsonIntegerFieldMapper extends JsonNumberFieldMapper<Integer> {
|
||||
return SortField.INT;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,39 +17,39 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericLongAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
public class XContentLongFieldMapper extends XContentNumberFieldMapper<Long> {
|
||||
|
||||
public static final String JSON_TYPE = "long";
|
||||
public static final String CONTENT_TYPE = "long";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final Long NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonLongFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentLongFieldMapper> {
|
||||
|
||||
protected Long nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -63,17 +63,17 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonLongFieldMapper build(BuilderContext context) {
|
||||
JsonLongFieldMapper fieldMapper = new JsonLongFieldMapper(buildNames(context),
|
||||
@Override public XContentLongFieldMapper build(BuilderContext context) {
|
||||
XContentLongFieldMapper fieldMapper = new XContentLongFieldMapper(buildNames(context),
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonLongFieldMapper.Builder builder = longField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentLongFieldMapper.Builder builder = longField(name);
|
||||
parseNumberField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -90,9 +90,9 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
|
||||
private final String nullValueAsString;
|
||||
|
||||
protected JsonLongFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Long nullValue) {
|
||||
protected XContentLongFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Long nullValue) {
|
||||
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
new NamedAnalyzer("_long/" + precisionStep, new NumericLongAnalyzer(precisionStep)),
|
||||
new NamedAnalyzer("_long/max", new NumericLongAnalyzer(Integer.MAX_VALUE)));
|
||||
@ -146,10 +146,10 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
long value;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
Object externalValue = jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
Object externalValue = context.externalValue();
|
||||
if (externalValue == null) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
@ -159,25 +159,21 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
value = ((Number) externalValue).longValue();
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), Long.toString(value), boost);
|
||||
context.allEntries().addText(names.fullName(), Long.toString(value), boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
}
|
||||
value = nullValue;
|
||||
if (nullValueAsString != null && (includeInAll == null || includeInAll)) {
|
||||
jsonContext.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
|
||||
value = Long.parseLong(jsonContext.jp().getText());
|
||||
} else {
|
||||
value = jsonContext.jp().getLongValue();
|
||||
}
|
||||
value = context.parser().longValue();
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), jsonContext.jp().getText(), boost);
|
||||
context.allEntries().addText(names.fullName(), context.parser().text(), boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,12 +194,12 @@ public class JsonLongFieldMapper extends JsonNumberFieldMapper<Long> {
|
||||
return SortField.LONG;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,39 +17,39 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.elasticsearch.index.mapper.FieldMapperListener;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.concurrent.NotThreadSafe;
|
||||
import org.elasticsearch.util.concurrent.ThreadSafe;
|
||||
import org.elasticsearch.util.json.ToJson;
|
||||
import org.elasticsearch.util.xcontent.ToXContent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
@ThreadSafe
|
||||
public interface JsonMapper extends ToJson {
|
||||
public interface XContentMapper extends ToXContent {
|
||||
|
||||
public static final JsonMapper[] EMPTY_ARRAY = new JsonMapper[0];
|
||||
public static final XContentMapper[] EMPTY_ARRAY = new XContentMapper[0];
|
||||
|
||||
@NotThreadSafe
|
||||
public static class BuilderContext {
|
||||
private final JsonPath jsonPath;
|
||||
private final ContentPath contentPath;
|
||||
|
||||
public BuilderContext(JsonPath jsonPath) {
|
||||
this.jsonPath = jsonPath;
|
||||
public BuilderContext(ContentPath contentPath) {
|
||||
this.contentPath = contentPath;
|
||||
}
|
||||
|
||||
public JsonPath path() {
|
||||
return this.jsonPath;
|
||||
public ContentPath path() {
|
||||
return this.contentPath;
|
||||
}
|
||||
}
|
||||
|
||||
@NotThreadSafe
|
||||
public static abstract class Builder<T extends Builder, Y extends JsonMapper> {
|
||||
public static abstract class Builder<T extends Builder, Y extends XContentMapper> {
|
||||
|
||||
protected String name;
|
||||
|
||||
@ -64,9 +64,9 @@ public interface JsonMapper extends ToJson {
|
||||
|
||||
String name();
|
||||
|
||||
void parse(JsonParseContext jsonContext) throws IOException;
|
||||
void parse(ParseContext context) throws IOException;
|
||||
|
||||
void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException;
|
||||
void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException;
|
||||
|
||||
void traverse(FieldMapperListener fieldMapperListener);
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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.index.mapper.xcontent;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public final class XContentMapperBuilders {
|
||||
|
||||
private XContentMapperBuilders() {
|
||||
|
||||
}
|
||||
|
||||
public static XContentDocumentMapper.Builder doc(XContentObjectMapper.Builder objectBuilder) {
|
||||
return new XContentDocumentMapper.Builder(objectBuilder);
|
||||
}
|
||||
|
||||
public static XContentSourceFieldMapper.Builder source() {
|
||||
return new XContentSourceFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static XContentIdFieldMapper.Builder id() {
|
||||
return new XContentIdFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static XContentUidFieldMapper.Builder uid() {
|
||||
return new XContentUidFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static XContentTypeFieldMapper.Builder type() {
|
||||
return new XContentTypeFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static XContentBoostFieldMapper.Builder boost(String name) {
|
||||
return new XContentBoostFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentAllFieldMapper.Builder all() {
|
||||
return new XContentAllFieldMapper.Builder();
|
||||
}
|
||||
|
||||
public static XContentMultiFieldMapper.Builder multiField(String name) {
|
||||
return new XContentMultiFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentObjectMapper.Builder object(String name) {
|
||||
return new XContentObjectMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentBooleanFieldMapper.Builder booleanField(String name) {
|
||||
return new XContentBooleanFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentStringFieldMapper.Builder stringField(String name) {
|
||||
return new XContentStringFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentBinaryFieldMapper.Builder binaryField(String name) {
|
||||
return new XContentBinaryFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentDateFieldMapper.Builder dateField(String name) {
|
||||
return new XContentDateFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentShortFieldMapper.Builder shortField(String name) {
|
||||
return new XContentShortFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentIntegerFieldMapper.Builder integerField(String name) {
|
||||
return new XContentIntegerFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentLongFieldMapper.Builder longField(String name) {
|
||||
return new XContentLongFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentFloatFieldMapper.Builder floatField(String name) {
|
||||
return new XContentFloatFieldMapper.Builder(name);
|
||||
}
|
||||
|
||||
public static XContentDoubleFieldMapper.Builder doubleField(String name) {
|
||||
return new XContentDoubleFieldMapper.Builder(name);
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.elasticsearch.index.mapper.FieldMapper;
|
||||
import org.elasticsearch.index.mapper.FieldMapperListener;
|
||||
@ -25,48 +25,48 @@ import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.MapBuilder.*;
|
||||
import static org.elasticsearch.util.gcommon.collect.Lists.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
public class XContentMultiFieldMapper implements XContentMapper, XContentIncludeInAllMapper {
|
||||
|
||||
public static final String JSON_TYPE = "multi_field";
|
||||
public static final String CONTENT_TYPE = "multi_field";
|
||||
|
||||
public static class Defaults {
|
||||
public static final JsonPath.Type PATH_TYPE = JsonPath.Type.FULL;
|
||||
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonMapper.Builder<Builder, JsonMultiFieldMapper> {
|
||||
public static class Builder extends XContentMapper.Builder<Builder, XContentMultiFieldMapper> {
|
||||
|
||||
private JsonPath.Type pathType = Defaults.PATH_TYPE;
|
||||
private ContentPath.Type pathType = Defaults.PATH_TYPE;
|
||||
|
||||
private final List<JsonMapper.Builder> mappersBuilders = newArrayList();
|
||||
private final List<XContentMapper.Builder> mappersBuilders = newArrayList();
|
||||
|
||||
private JsonMapper.Builder defaultMapperBuilder;
|
||||
private XContentMapper.Builder defaultMapperBuilder;
|
||||
|
||||
public Builder(String name) {
|
||||
super(name);
|
||||
this.builder = this;
|
||||
}
|
||||
|
||||
public Builder pathType(JsonPath.Type pathType) {
|
||||
public Builder pathType(ContentPath.Type pathType) {
|
||||
this.pathType = pathType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder add(JsonMapper.Builder builder) {
|
||||
public Builder add(XContentMapper.Builder builder) {
|
||||
if (builder.name.equals(name)) {
|
||||
defaultMapperBuilder = builder;
|
||||
} else {
|
||||
@ -75,32 +75,32 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonMultiFieldMapper build(BuilderContext context) {
|
||||
JsonPath.Type origPathType = context.path().pathType();
|
||||
@Override public XContentMultiFieldMapper build(BuilderContext context) {
|
||||
ContentPath.Type origPathType = context.path().pathType();
|
||||
context.path().pathType(pathType);
|
||||
|
||||
JsonMapper defaultMapper = null;
|
||||
XContentMapper defaultMapper = null;
|
||||
if (defaultMapperBuilder != null) {
|
||||
defaultMapper = defaultMapperBuilder.build(context);
|
||||
}
|
||||
|
||||
context.path().add(name);
|
||||
Map<String, JsonMapper> mappers = new HashMap<String, JsonMapper>();
|
||||
for (JsonMapper.Builder builder : mappersBuilders) {
|
||||
JsonMapper mapper = builder.build(context);
|
||||
Map<String, XContentMapper> mappers = new HashMap<String, XContentMapper>();
|
||||
for (XContentMapper.Builder builder : mappersBuilders) {
|
||||
XContentMapper mapper = builder.build(context);
|
||||
mappers.put(mapper.name(), mapper);
|
||||
}
|
||||
context.path().remove();
|
||||
|
||||
context.path().pathType(origPathType);
|
||||
|
||||
return new JsonMultiFieldMapper(name, pathType, mappers, defaultMapper);
|
||||
return new XContentMultiFieldMapper(name, pathType, mappers, defaultMapper);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonMultiFieldMapper.Builder builder = multiField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentMultiFieldMapper.Builder builder = multiField(name);
|
||||
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -121,7 +121,7 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
|
||||
throw new MapperParsingException("No type specified for property [" + propName + "]");
|
||||
}
|
||||
|
||||
JsonTypeParser typeParser = parserContext.typeParser(type);
|
||||
XContentTypeParser typeParser = parserContext.typeParser(type);
|
||||
if (typeParser == null) {
|
||||
throw new MapperParsingException("No handler for type [" + type + "] declared on field [" + fieldName + "]");
|
||||
}
|
||||
@ -135,28 +135,28 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
|
||||
|
||||
private final String name;
|
||||
|
||||
private final JsonPath.Type pathType;
|
||||
private final ContentPath.Type pathType;
|
||||
|
||||
private final Object mutex = new Object();
|
||||
|
||||
private volatile ImmutableMap<String, JsonMapper> mappers = ImmutableMap.of();
|
||||
private volatile ImmutableMap<String, XContentMapper> mappers = ImmutableMap.of();
|
||||
|
||||
private volatile JsonMapper defaultMapper;
|
||||
private volatile XContentMapper defaultMapper;
|
||||
|
||||
public JsonMultiFieldMapper(String name, JsonPath.Type pathType, JsonMapper defaultMapper) {
|
||||
this(name, pathType, new HashMap<String, JsonMapper>(), defaultMapper);
|
||||
public XContentMultiFieldMapper(String name, ContentPath.Type pathType, XContentMapper defaultMapper) {
|
||||
this(name, pathType, new HashMap<String, XContentMapper>(), defaultMapper);
|
||||
}
|
||||
|
||||
public JsonMultiFieldMapper(String name, JsonPath.Type pathType, Map<String, JsonMapper> mappers, JsonMapper defaultMapper) {
|
||||
public XContentMultiFieldMapper(String name, ContentPath.Type pathType, Map<String, XContentMapper> mappers, XContentMapper defaultMapper) {
|
||||
this.name = name;
|
||||
this.pathType = pathType;
|
||||
this.mappers = ImmutableMap.copyOf(mappers);
|
||||
this.defaultMapper = defaultMapper;
|
||||
|
||||
// we disable the all in mappers, only the default one can be added
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
if (mapper instanceof JsonIncludeInAllMapper) {
|
||||
((JsonIncludeInAllMapper) mapper).includeInAll(false);
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
if (mapper instanceof XContentIncludeInAllMapper) {
|
||||
((XContentIncludeInAllMapper) mapper).includeInAll(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,47 +166,47 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
|
||||
}
|
||||
|
||||
@Override public void includeInAll(Boolean includeInAll) {
|
||||
if (includeInAll != null && defaultMapper != null && (defaultMapper instanceof JsonIncludeInAllMapper)) {
|
||||
((JsonIncludeInAllMapper) defaultMapper).includeInAll(includeInAll);
|
||||
if (includeInAll != null && defaultMapper != null && (defaultMapper instanceof XContentIncludeInAllMapper)) {
|
||||
((XContentIncludeInAllMapper) defaultMapper).includeInAll(includeInAll);
|
||||
}
|
||||
}
|
||||
|
||||
public JsonPath.Type pathType() {
|
||||
public ContentPath.Type pathType() {
|
||||
return pathType;
|
||||
}
|
||||
|
||||
public JsonMapper defaultMapper() {
|
||||
public XContentMapper defaultMapper() {
|
||||
return this.defaultMapper;
|
||||
}
|
||||
|
||||
public ImmutableMap<String, JsonMapper> mappers() {
|
||||
public ImmutableMap<String, XContentMapper> mappers() {
|
||||
return this.mappers;
|
||||
}
|
||||
|
||||
@Override public void parse(JsonParseContext jsonContext) throws IOException {
|
||||
JsonPath.Type origPathType = jsonContext.path().pathType();
|
||||
jsonContext.path().pathType(pathType);
|
||||
@Override public void parse(ParseContext context) throws IOException {
|
||||
ContentPath.Type origPathType = context.path().pathType();
|
||||
context.path().pathType(pathType);
|
||||
|
||||
// do the default mapper without adding the path
|
||||
if (defaultMapper != null) {
|
||||
defaultMapper.parse(jsonContext);
|
||||
defaultMapper.parse(context);
|
||||
}
|
||||
|
||||
jsonContext.path().add(name);
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
mapper.parse(jsonContext);
|
||||
context.path().add(name);
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
mapper.parse(context);
|
||||
}
|
||||
jsonContext.path().remove();
|
||||
context.path().remove();
|
||||
|
||||
jsonContext.path().pathType(origPathType);
|
||||
context.path().pathType(origPathType);
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
if (!(mergeWith instanceof JsonMultiFieldMapper)) {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
if (!(mergeWith instanceof XContentMultiFieldMapper)) {
|
||||
mergeContext.addConflict("Can't merge a non multi_field mapping [" + mergeWith.name() + "] with a multi_field mapping [" + name() + "]");
|
||||
return;
|
||||
}
|
||||
JsonMultiFieldMapper mergeWithMultiField = (JsonMultiFieldMapper) mergeWith;
|
||||
XContentMultiFieldMapper mergeWithMultiField = (XContentMultiFieldMapper) mergeWith;
|
||||
synchronized (mutex) {
|
||||
// merge the default mapper
|
||||
if (defaultMapper == null) {
|
||||
@ -223,17 +223,17 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
|
||||
}
|
||||
|
||||
// merge all the other mappers
|
||||
for (JsonMapper mergeWithMapper : mergeWithMultiField.mappers.values()) {
|
||||
JsonMapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
||||
for (XContentMapper mergeWithMapper : mergeWithMultiField.mappers.values()) {
|
||||
XContentMapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
||||
if (mergeIntoMapper == null) {
|
||||
// no mapping, simply add it if not simulating
|
||||
if (!mergeContext.mergeFlags().simulate()) {
|
||||
// disable the mapper from being in all, only the default mapper is in all
|
||||
if (mergeWithMapper instanceof JsonIncludeInAllMapper) {
|
||||
((JsonIncludeInAllMapper) mergeWithMapper).includeInAll(false);
|
||||
if (mergeWithMapper instanceof XContentIncludeInAllMapper) {
|
||||
((XContentIncludeInAllMapper) mergeWithMapper).includeInAll(false);
|
||||
}
|
||||
mappers = newMapBuilder(mappers).put(mergeWithMapper.name(), mergeWithMapper).immutableMap();
|
||||
if (mergeWithMapper instanceof JsonFieldMapper) {
|
||||
if (mergeWithMapper instanceof XContentFieldMapper) {
|
||||
mergeContext.docMapper().addFieldMapper((FieldMapper) mergeWithMapper);
|
||||
}
|
||||
}
|
||||
@ -248,22 +248,22 @@ public class JsonMultiFieldMapper implements JsonMapper, JsonIncludeInAllMapper
|
||||
if (defaultMapper != null) {
|
||||
defaultMapper.traverse(fieldMapperListener);
|
||||
}
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
mapper.traverse(fieldMapperListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(name);
|
||||
builder.field("type", JSON_TYPE);
|
||||
builder.field("type", CONTENT_TYPE);
|
||||
builder.field("path", pathType.name().toLowerCase());
|
||||
|
||||
builder.startObject("fields");
|
||||
if (defaultMapper != null) {
|
||||
defaultMapper.toJson(builder, params);
|
||||
defaultMapper.toXContent(builder, params);
|
||||
}
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
mapper.toJson(builder, params);
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
mapper.toXContent(builder, params);
|
||||
}
|
||||
builder.endObject();
|
||||
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.analysis.NumericTokenStream;
|
||||
import org.apache.lucene.analysis.TokenStream;
|
||||
@ -29,7 +29,7 @@ import org.apache.lucene.util.NumericUtils;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.util.ThreadLocals;
|
||||
import org.elasticsearch.util.gnu.trove.TIntObjectHashMap;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
@ -38,16 +38,16 @@ import java.util.Deque;
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public abstract class JsonNumberFieldMapper<T extends Number> extends JsonFieldMapper<T> implements JsonIncludeInAllMapper {
|
||||
public abstract class XContentNumberFieldMapper<T extends Number> extends XContentFieldMapper<T> implements XContentIncludeInAllMapper {
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final int PRECISION_STEP = NumericUtils.PRECISION_STEP_DEFAULT;
|
||||
public static final Field.Index INDEX = Field.Index.NOT_ANALYZED;
|
||||
public static final boolean OMIT_NORMS = true;
|
||||
public static final boolean OMIT_TERM_FREQ_AND_POSITIONS = true;
|
||||
}
|
||||
|
||||
public abstract static class Builder<T extends Builder, Y extends JsonNumberFieldMapper> extends JsonFieldMapper.Builder<T, Y> {
|
||||
public abstract static class Builder<T extends Builder, Y extends XContentNumberFieldMapper> extends XContentFieldMapper.Builder<T, Y> {
|
||||
|
||||
protected int precisionStep = Defaults.PRECISION_STEP;
|
||||
|
||||
@ -90,10 +90,10 @@ public abstract class JsonNumberFieldMapper<T extends Number> extends JsonFieldM
|
||||
|
||||
protected Boolean includeInAll;
|
||||
|
||||
protected JsonNumberFieldMapper(Names names, int precisionStep,
|
||||
Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer) {
|
||||
protected XContentNumberFieldMapper(Names names, int precisionStep,
|
||||
Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer) {
|
||||
super(names, index, store, Field.TermVector.NO, boost, omitNorms, omitTermFreqAndPositions, indexAnalyzer, searchAnalyzer);
|
||||
if (precisionStep <= 0 || precisionStep >= maxPrecisionStep()) {
|
||||
this.precisionStep = Integer.MAX_VALUE;
|
||||
@ -164,8 +164,8 @@ public abstract class JsonNumberFieldMapper<T extends Number> extends JsonFieldM
|
||||
return text == null;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
builder.field("precision_step", precisionStep);
|
||||
}
|
||||
|
@ -17,58 +17,57 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||
import org.elasticsearch.index.mapper.*;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.concurrent.ThreadSafe;
|
||||
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
|
||||
import org.elasticsearch.util.joda.FormatDateTimeFormatter;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.MapBuilder.*;
|
||||
import static org.elasticsearch.util.gcommon.collect.ImmutableMap.*;
|
||||
import static org.elasticsearch.util.gcommon.collect.Lists.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
public class XContentObjectMapper implements XContentMapper, XContentIncludeInAllMapper {
|
||||
|
||||
public static final String JSON_TYPE = "object";
|
||||
public static final String CONTENT_TYPE = "object";
|
||||
|
||||
public static class Defaults {
|
||||
public static final boolean ENABLED = true;
|
||||
public static final boolean DYNAMIC = true;
|
||||
public static final JsonPath.Type PATH_TYPE = JsonPath.Type.FULL;
|
||||
public static final FormatDateTimeFormatter[] DATE_TIME_FORMATTERS = new FormatDateTimeFormatter[]{JsonDateFieldMapper.Defaults.DATE_TIME_FORMATTER};
|
||||
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
|
||||
public static final FormatDateTimeFormatter[] DATE_TIME_FORMATTERS = new FormatDateTimeFormatter[]{XContentDateFieldMapper.Defaults.DATE_TIME_FORMATTER};
|
||||
}
|
||||
|
||||
public static class Builder extends JsonMapper.Builder<Builder, JsonObjectMapper> {
|
||||
public static class Builder extends XContentMapper.Builder<Builder, XContentObjectMapper> {
|
||||
|
||||
private boolean enabled = Defaults.ENABLED;
|
||||
|
||||
private boolean dynamic = Defaults.DYNAMIC;
|
||||
|
||||
private JsonPath.Type pathType = Defaults.PATH_TYPE;
|
||||
private ContentPath.Type pathType = Defaults.PATH_TYPE;
|
||||
|
||||
private List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
|
||||
|
||||
private Boolean includeInAll;
|
||||
|
||||
private final List<JsonMapper.Builder> mappersBuilders = newArrayList();
|
||||
private final List<XContentMapper.Builder> mappersBuilders = newArrayList();
|
||||
|
||||
public Builder(String name) {
|
||||
super(name);
|
||||
@ -85,7 +84,7 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder pathType(JsonPath.Type pathType) {
|
||||
public Builder pathType(ContentPath.Type pathType) {
|
||||
this.pathType = pathType;
|
||||
return this;
|
||||
}
|
||||
@ -117,28 +116,28 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder add(JsonMapper.Builder builder) {
|
||||
public Builder add(XContentMapper.Builder builder) {
|
||||
mappersBuilders.add(builder);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonObjectMapper build(BuilderContext context) {
|
||||
@Override public XContentObjectMapper build(BuilderContext context) {
|
||||
if (dateTimeFormatters == null) {
|
||||
dateTimeFormatters = newArrayList();
|
||||
} else if (dateTimeFormatters.isEmpty()) {
|
||||
// add the default one
|
||||
dateTimeFormatters.addAll(newArrayList(Defaults.DATE_TIME_FORMATTERS));
|
||||
}
|
||||
JsonPath.Type origPathType = context.path().pathType();
|
||||
ContentPath.Type origPathType = context.path().pathType();
|
||||
context.path().pathType(pathType);
|
||||
context.path().add(name);
|
||||
|
||||
Map<String, JsonMapper> mappers = new HashMap<String, JsonMapper>();
|
||||
for (JsonMapper.Builder builder : mappersBuilders) {
|
||||
JsonMapper mapper = builder.build(context);
|
||||
Map<String, XContentMapper> mappers = new HashMap<String, XContentMapper>();
|
||||
for (XContentMapper.Builder builder : mappersBuilders) {
|
||||
XContentMapper mapper = builder.build(context);
|
||||
mappers.put(mapper.name(), mapper);
|
||||
}
|
||||
JsonObjectMapper objectMapper = new JsonObjectMapper(name, enabled, dynamic, pathType,
|
||||
XContentObjectMapper objectMapper = new XContentObjectMapper(name, enabled, dynamic, pathType,
|
||||
dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]),
|
||||
mappers);
|
||||
|
||||
@ -151,10 +150,10 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
Map<String, Object> objectNode = node;
|
||||
JsonObjectMapper.Builder builder = object(name);
|
||||
XContentObjectMapper.Builder builder = object(name);
|
||||
|
||||
for (Map.Entry<String, Object> entry : objectNode.entrySet()) {
|
||||
String fieldName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -196,7 +195,7 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void parseProperties(JsonObjectMapper.Builder objBuilder, Map<String, Object> propsNode, JsonTypeParser.ParserContext parserContext) {
|
||||
private void parseProperties(XContentObjectMapper.Builder objBuilder, Map<String, Object> propsNode, XContentTypeParser.ParserContext parserContext) {
|
||||
for (Map.Entry<String, Object> entry : propsNode.entrySet()) {
|
||||
String propName = entry.getKey();
|
||||
Map<String, Object> propNode = (Map<String, Object>) entry.getValue();
|
||||
@ -208,15 +207,15 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
} else {
|
||||
// lets see if we can derive this...
|
||||
if (propNode.get("properties") != null) {
|
||||
type = JsonObjectMapper.JSON_TYPE;
|
||||
type = XContentObjectMapper.CONTENT_TYPE;
|
||||
} else if (propNode.get("fields") != null) {
|
||||
type = JsonMultiFieldMapper.JSON_TYPE;
|
||||
type = XContentMultiFieldMapper.CONTENT_TYPE;
|
||||
} else {
|
||||
throw new MapperParsingException("No type specified for property [" + propName + "]");
|
||||
}
|
||||
}
|
||||
|
||||
JsonTypeParser typeParser = parserContext.typeParser(type);
|
||||
XContentTypeParser typeParser = parserContext.typeParser(type);
|
||||
if (typeParser == null) {
|
||||
throw new MapperParsingException("No handler for type [" + type + "] declared on field [" + propName + "]");
|
||||
}
|
||||
@ -231,31 +230,31 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
|
||||
private final boolean dynamic;
|
||||
|
||||
private final JsonPath.Type pathType;
|
||||
private final ContentPath.Type pathType;
|
||||
|
||||
private final FormatDateTimeFormatter[] dateTimeFormatters;
|
||||
|
||||
private Boolean includeInAll;
|
||||
|
||||
private volatile ImmutableMap<String, JsonMapper> mappers = ImmutableMap.of();
|
||||
private volatile ImmutableMap<String, XContentMapper> mappers = ImmutableMap.of();
|
||||
|
||||
private final Object mutex = new Object();
|
||||
|
||||
protected JsonObjectMapper(String name) {
|
||||
protected XContentObjectMapper(String name) {
|
||||
this(name, Defaults.ENABLED, Defaults.DYNAMIC, Defaults.PATH_TYPE);
|
||||
}
|
||||
|
||||
protected JsonObjectMapper(String name, boolean enabled, boolean dynamic, JsonPath.Type pathType) {
|
||||
protected XContentObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType) {
|
||||
this(name, enabled, dynamic, pathType, Defaults.DATE_TIME_FORMATTERS);
|
||||
}
|
||||
|
||||
protected JsonObjectMapper(String name, boolean enabled, boolean dynamic, JsonPath.Type pathType,
|
||||
protected XContentObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
||||
FormatDateTimeFormatter[] dateTimeFormatters) {
|
||||
this(name, enabled, dynamic, pathType, dateTimeFormatters, null);
|
||||
}
|
||||
|
||||
JsonObjectMapper(String name, boolean enabled, boolean dynamic, JsonPath.Type pathType,
|
||||
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, JsonMapper> mappers) {
|
||||
XContentObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
|
||||
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
|
||||
this.name = name;
|
||||
this.enabled = enabled;
|
||||
this.dynamic = dynamic;
|
||||
@ -276,16 +275,16 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
}
|
||||
this.includeInAll = includeInAll;
|
||||
// when called from outside, apply this on all the inner mappers
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
if (mapper instanceof JsonIncludeInAllMapper) {
|
||||
((JsonIncludeInAllMapper) mapper).includeInAll(includeInAll);
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
if (mapper instanceof XContentIncludeInAllMapper) {
|
||||
((XContentIncludeInAllMapper) mapper).includeInAll(includeInAll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObjectMapper putMapper(JsonMapper mapper) {
|
||||
if (mapper instanceof JsonIncludeInAllMapper) {
|
||||
((JsonIncludeInAllMapper) mapper).includeInAll(includeInAll);
|
||||
public XContentObjectMapper putMapper(XContentMapper mapper) {
|
||||
if (mapper instanceof XContentIncludeInAllMapper) {
|
||||
((XContentIncludeInAllMapper) mapper).includeInAll(includeInAll);
|
||||
}
|
||||
synchronized (mutex) {
|
||||
mappers = newMapBuilder(mappers).put(mapper.name(), mapper).immutableMap();
|
||||
@ -294,54 +293,54 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
}
|
||||
|
||||
@Override public void traverse(FieldMapperListener fieldMapperListener) {
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
mapper.traverse(fieldMapperListener);
|
||||
}
|
||||
}
|
||||
|
||||
public void parse(JsonParseContext jsonContext) throws IOException {
|
||||
public void parse(ParseContext context) throws IOException {
|
||||
if (!enabled) {
|
||||
jsonContext.jp().skipChildren();
|
||||
context.parser().skipChildren();
|
||||
return;
|
||||
}
|
||||
JsonParser jp = jsonContext.jp();
|
||||
XContentParser parser = context.parser();
|
||||
|
||||
JsonPath.Type origPathType = jsonContext.path().pathType();
|
||||
jsonContext.path().pathType(pathType);
|
||||
ContentPath.Type origPathType = context.path().pathType();
|
||||
context.path().pathType(pathType);
|
||||
|
||||
String currentFieldName = jp.getCurrentName();
|
||||
JsonToken token;
|
||||
while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
|
||||
if (token == JsonToken.START_OBJECT) {
|
||||
serializeObject(jsonContext, currentFieldName);
|
||||
} else if (token == JsonToken.START_ARRAY) {
|
||||
serializeArray(jsonContext, currentFieldName);
|
||||
} else if (token == JsonToken.FIELD_NAME) {
|
||||
currentFieldName = jp.getCurrentName();
|
||||
} else if (token == JsonToken.VALUE_NULL) {
|
||||
serializeNullValue(jsonContext, currentFieldName);
|
||||
String currentFieldName = parser.currentName();
|
||||
XContentParser.Token token;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
serializeObject(context, currentFieldName);
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
serializeArray(context, currentFieldName);
|
||||
} else if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.VALUE_NULL) {
|
||||
serializeNullValue(context, currentFieldName);
|
||||
} else {
|
||||
serializeValue(jsonContext, currentFieldName, token);
|
||||
serializeValue(context, currentFieldName, token);
|
||||
}
|
||||
}
|
||||
// restore the enable path flag
|
||||
jsonContext.path().pathType(origPathType);
|
||||
context.path().pathType(origPathType);
|
||||
}
|
||||
|
||||
private void serializeNullValue(JsonParseContext jsonContext, String lastFieldName) throws IOException {
|
||||
private void serializeNullValue(ParseContext context, String lastFieldName) throws IOException {
|
||||
// we can only handle null values if we have mappings for them
|
||||
JsonMapper mapper = mappers.get(lastFieldName);
|
||||
XContentMapper mapper = mappers.get(lastFieldName);
|
||||
if (mapper != null) {
|
||||
mapper.parse(jsonContext);
|
||||
mapper.parse(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void serializeObject(JsonParseContext jsonContext, String currentFieldName) throws IOException {
|
||||
jsonContext.path().add(currentFieldName);
|
||||
private void serializeObject(ParseContext context, String currentFieldName) throws IOException {
|
||||
context.path().add(currentFieldName);
|
||||
|
||||
JsonMapper objectMapper = mappers.get(currentFieldName);
|
||||
XContentMapper objectMapper = mappers.get(currentFieldName);
|
||||
if (objectMapper != null) {
|
||||
objectMapper.parse(jsonContext);
|
||||
objectMapper.parse(context);
|
||||
} else {
|
||||
if (dynamic) {
|
||||
// we sync here just so we won't add it twice. Its not the end of the world
|
||||
@ -349,47 +348,47 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
synchronized (mutex) {
|
||||
objectMapper = mappers.get(currentFieldName);
|
||||
if (objectMapper != null) {
|
||||
objectMapper.parse(jsonContext);
|
||||
objectMapper.parse(context);
|
||||
}
|
||||
|
||||
BuilderContext builderContext = new BuilderContext(jsonContext.path());
|
||||
objectMapper = JsonMapperBuilders.object(currentFieldName).enabled(true)
|
||||
BuilderContext builderContext = new BuilderContext(context.path());
|
||||
objectMapper = XContentMapperBuilders.object(currentFieldName).enabled(true)
|
||||
.dynamic(dynamic).pathType(pathType).dateTimeFormatter(dateTimeFormatters).build(builderContext);
|
||||
putMapper(objectMapper);
|
||||
objectMapper.parse(jsonContext);
|
||||
jsonContext.addedMapper();
|
||||
objectMapper.parse(context);
|
||||
context.addedMapper();
|
||||
}
|
||||
} else {
|
||||
// not dynamic, read everything up to end object
|
||||
jsonContext.jp().skipChildren();
|
||||
context.parser().skipChildren();
|
||||
}
|
||||
}
|
||||
|
||||
jsonContext.path().remove();
|
||||
context.path().remove();
|
||||
}
|
||||
|
||||
private void serializeArray(JsonParseContext jsonContext, String lastFieldName) throws IOException {
|
||||
JsonParser jp = jsonContext.jp();
|
||||
JsonToken token;
|
||||
while ((token = jp.nextToken()) != JsonToken.END_ARRAY) {
|
||||
if (token == JsonToken.START_OBJECT) {
|
||||
serializeObject(jsonContext, lastFieldName);
|
||||
} else if (token == JsonToken.START_ARRAY) {
|
||||
serializeArray(jsonContext, lastFieldName);
|
||||
} else if (token == JsonToken.FIELD_NAME) {
|
||||
lastFieldName = jp.getCurrentName();
|
||||
} else if (token == JsonToken.VALUE_NULL) {
|
||||
serializeNullValue(jsonContext, lastFieldName);
|
||||
private void serializeArray(ParseContext context, String lastFieldName) throws IOException {
|
||||
XContentParser parser = context.parser();
|
||||
XContentParser.Token token;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
serializeObject(context, lastFieldName);
|
||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||
serializeArray(context, lastFieldName);
|
||||
} else if (token == XContentParser.Token.FIELD_NAME) {
|
||||
lastFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.VALUE_NULL) {
|
||||
serializeNullValue(context, lastFieldName);
|
||||
} else {
|
||||
serializeValue(jsonContext, lastFieldName, token);
|
||||
serializeValue(context, lastFieldName, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void serializeValue(JsonParseContext jsonContext, String currentFieldName, JsonToken token) throws IOException {
|
||||
JsonMapper mapper = mappers.get(currentFieldName);
|
||||
private void serializeValue(ParseContext context, String currentFieldName, XContentParser.Token token) throws IOException {
|
||||
XContentMapper mapper = mappers.get(currentFieldName);
|
||||
if (mapper != null) {
|
||||
mapper.parse(jsonContext);
|
||||
mapper.parse(context);
|
||||
return;
|
||||
}
|
||||
if (!dynamic) {
|
||||
@ -401,13 +400,13 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
synchronized (mutex) {
|
||||
mapper = mappers.get(currentFieldName);
|
||||
if (mapper != null) {
|
||||
mapper.parse(jsonContext);
|
||||
mapper.parse(context);
|
||||
return;
|
||||
}
|
||||
|
||||
BuilderContext builderContext = new BuilderContext(jsonContext.path());
|
||||
if (token == JsonToken.VALUE_STRING) {
|
||||
String text = jsonContext.jp().getText();
|
||||
BuilderContext builderContext = new BuilderContext(context.path());
|
||||
if (token == XContentParser.Token.VALUE_STRING) {
|
||||
String text = context.parser().text();
|
||||
// check if it fits one of the date formats
|
||||
boolean isDate = false;
|
||||
// a safe check since "1" gets parsed as well
|
||||
@ -426,52 +425,57 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
if (!isDate) {
|
||||
mapper = stringField(currentFieldName).build(builderContext);
|
||||
}
|
||||
} else if (token == JsonToken.VALUE_NUMBER_INT) {
|
||||
mapper = longField(currentFieldName).build(builderContext);
|
||||
} else if (token == JsonToken.VALUE_NUMBER_FLOAT) {
|
||||
mapper = doubleField(currentFieldName).build(builderContext);
|
||||
} else if (token == JsonToken.VALUE_TRUE) {
|
||||
mapper = booleanField(currentFieldName).build(builderContext);
|
||||
} else if (token == JsonToken.VALUE_FALSE) {
|
||||
} else if (token == XContentParser.Token.VALUE_NUMBER) {
|
||||
XContentParser.NumberType numberType = context.parser().numberType();
|
||||
if (numberType == XContentParser.NumberType.INT) {
|
||||
mapper = integerField(currentFieldName).build(builderContext);
|
||||
} else if (numberType == XContentParser.NumberType.LONG) {
|
||||
mapper = longField(currentFieldName).build(builderContext);
|
||||
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
||||
mapper = floatField(currentFieldName).build(builderContext);
|
||||
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
||||
mapper = doubleField(currentFieldName).build(builderContext);
|
||||
}
|
||||
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
|
||||
mapper = booleanField(currentFieldName).build(builderContext);
|
||||
} else {
|
||||
// TODO how do we identify dynamically that its a binary value?
|
||||
throw new ElasticSearchIllegalStateException("Can't handle serializing a dynamic type with json token [" + token + "] and field name [" + currentFieldName + "]");
|
||||
throw new ElasticSearchIllegalStateException("Can't handle serializing a dynamic type with content token [" + token + "] and field name [" + currentFieldName + "]");
|
||||
}
|
||||
putMapper(mapper);
|
||||
jsonContext.docMapper().addFieldMapper((FieldMapper) mapper);
|
||||
context.docMapper().addFieldMapper((FieldMapper) mapper);
|
||||
|
||||
mapper.parse(jsonContext);
|
||||
jsonContext.addedMapper();
|
||||
mapper.parse(context);
|
||||
context.addedMapper();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
if (!(mergeWith instanceof JsonObjectMapper)) {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
if (!(mergeWith instanceof XContentObjectMapper)) {
|
||||
mergeContext.addConflict("Can't merge a non object mapping [" + mergeWith.name() + "] with an object mapping [" + name() + "]");
|
||||
return;
|
||||
}
|
||||
JsonObjectMapper mergeWithObject = (JsonObjectMapper) mergeWith;
|
||||
XContentObjectMapper mergeWithObject = (XContentObjectMapper) mergeWith;
|
||||
synchronized (mutex) {
|
||||
for (JsonMapper mergeWithMapper : mergeWithObject.mappers.values()) {
|
||||
JsonMapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
||||
for (XContentMapper mergeWithMapper : mergeWithObject.mappers.values()) {
|
||||
XContentMapper mergeIntoMapper = mappers.get(mergeWithMapper.name());
|
||||
if (mergeIntoMapper == null) {
|
||||
// no mapping, simply add it if not simulating
|
||||
if (!mergeContext.mergeFlags().simulate()) {
|
||||
putMapper(mergeWithMapper);
|
||||
if (mergeWithMapper instanceof JsonFieldMapper) {
|
||||
if (mergeWithMapper instanceof XContentFieldMapper) {
|
||||
mergeContext.docMapper().addFieldMapper((FieldMapper) mergeWithMapper);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((mergeWithMapper instanceof JsonMultiFieldMapper) && !(mergeIntoMapper instanceof JsonMultiFieldMapper)) {
|
||||
JsonMultiFieldMapper mergeWithMultiField = (JsonMultiFieldMapper) mergeWithMapper;
|
||||
if ((mergeWithMapper instanceof XContentMultiFieldMapper) && !(mergeIntoMapper instanceof XContentMultiFieldMapper)) {
|
||||
XContentMultiFieldMapper mergeWithMultiField = (XContentMultiFieldMapper) mergeWithMapper;
|
||||
mergeWithMultiField.merge(mergeIntoMapper, mergeContext);
|
||||
if (!mergeContext.mergeFlags().simulate()) {
|
||||
putMapper(mergeWithMultiField);
|
||||
// now, raise events for all mappers
|
||||
for (JsonMapper mapper : mergeWithMultiField.mappers().values()) {
|
||||
if (mapper instanceof JsonFieldMapper) {
|
||||
for (XContentMapper mapper : mergeWithMultiField.mappers().values()) {
|
||||
if (mapper instanceof XContentFieldMapper) {
|
||||
mergeContext.docMapper().addFieldMapper((FieldMapper) mapper);
|
||||
}
|
||||
}
|
||||
@ -484,13 +488,13 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
toJson(builder, params, JsonMapper.EMPTY_ARRAY);
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
toXContent(builder, params, XContentMapper.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
public void toJson(JsonBuilder builder, Params params, JsonMapper... additionalMappers) throws IOException {
|
||||
public void toXContent(XContentBuilder builder, Params params, XContentMapper... additionalMappers) throws IOException {
|
||||
builder.startObject(name);
|
||||
builder.field("type", JSON_TYPE);
|
||||
builder.field("type", CONTENT_TYPE);
|
||||
builder.field("dynamic", dynamic);
|
||||
builder.field("enabled", enabled);
|
||||
builder.field("path", pathType.name().toLowerCase());
|
||||
@ -507,22 +511,22 @@ public class JsonObjectMapper implements JsonMapper, JsonIncludeInAllMapper {
|
||||
}
|
||||
|
||||
// check internal mappers first (this is only relevant for root object)
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
if (mapper instanceof InternalMapper) {
|
||||
mapper.toJson(builder, params);
|
||||
mapper.toXContent(builder, params);
|
||||
}
|
||||
}
|
||||
if (additionalMappers != null) {
|
||||
for (JsonMapper mapper : additionalMappers) {
|
||||
mapper.toJson(builder, params);
|
||||
for (XContentMapper mapper : additionalMappers) {
|
||||
mapper.toXContent(builder, params);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mappers.isEmpty()) {
|
||||
builder.startObject("properties");
|
||||
for (JsonMapper mapper : mappers.values()) {
|
||||
for (XContentMapper mapper : mappers.values()) {
|
||||
if (!(mapper instanceof InternalMapper)) {
|
||||
mapper.toJson(builder, params);
|
||||
mapper.toXContent(builder, params);
|
||||
}
|
||||
}
|
||||
builder.endObject();
|
@ -17,39 +17,39 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.util.NumericUtils;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.analysis.NumericIntegerAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Numbers;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
|
||||
public class XContentShortFieldMapper extends XContentNumberFieldMapper<Short> {
|
||||
|
||||
public static final String JSON_TYPE = "short";
|
||||
public static final String CONTENT_TYPE = "short";
|
||||
|
||||
public static class Defaults extends JsonNumberFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentNumberFieldMapper.Defaults {
|
||||
public static final Short NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonNumberFieldMapper.Builder<Builder, JsonShortFieldMapper> {
|
||||
public static class Builder extends XContentNumberFieldMapper.Builder<Builder, XContentShortFieldMapper> {
|
||||
|
||||
protected Short nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -63,17 +63,17 @@ public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonShortFieldMapper build(BuilderContext context) {
|
||||
JsonShortFieldMapper fieldMapper = new JsonShortFieldMapper(buildNames(context),
|
||||
@Override public XContentShortFieldMapper build(BuilderContext context) {
|
||||
XContentShortFieldMapper fieldMapper = new XContentShortFieldMapper(buildNames(context),
|
||||
precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions, nullValue);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
return fieldMapper;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonShortFieldMapper.Builder builder = shortField(name);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentShortFieldMapper.Builder builder = shortField(name);
|
||||
parseNumberField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
@ -90,7 +90,7 @@ public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
|
||||
|
||||
private final String nullValueAsString;
|
||||
|
||||
protected JsonShortFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
protected XContentShortFieldMapper(Names names, int precisionStep, Field.Index index, Field.Store store,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
Short nullValue) {
|
||||
super(names, precisionStep, index, store, boost, omitNorms, omitTermFreqAndPositions,
|
||||
@ -146,10 +146,10 @@ public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
|
||||
includeLower, includeUpper);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
short value;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
Object externalValue = jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
Object externalValue = context.externalValue();
|
||||
if (externalValue == null) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
@ -159,25 +159,21 @@ public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
|
||||
value = ((Number) externalValue).shortValue();
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), Short.toString(value), boost);
|
||||
context.allEntries().addText(names.fullName(), Short.toString(value), boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
if (nullValue == null) {
|
||||
return null;
|
||||
}
|
||||
value = nullValue;
|
||||
if (nullValueAsString != null && (includeInAll == null || includeInAll)) {
|
||||
jsonContext.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
context.allEntries().addText(names.fullName(), nullValueAsString, boost);
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_STRING) {
|
||||
value = Short.parseShort(jsonContext.jp().getText());
|
||||
} else {
|
||||
value = jsonContext.jp().getShortValue();
|
||||
}
|
||||
value = context.parser().shortValue();
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), jsonContext.jp().getText(), boost);
|
||||
context.allEntries().addText(names.fullName(), context.parser().text(), boost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,12 +194,12 @@ public class JsonShortFieldMapper extends JsonNumberFieldMapper<Short> {
|
||||
return SortField.SHORT;
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,24 +17,24 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.*;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.index.mapper.SourceFieldMapper;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.Lucene;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements SourceFieldMapper {
|
||||
public class XContentSourceFieldMapper extends XContentFieldMapper<byte[]> implements SourceFieldMapper {
|
||||
|
||||
public static final String JSON_TYPE = "_source";
|
||||
public static final String CONTENT_TYPE = "_source";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final String NAME = SourceFieldMapper.NAME;
|
||||
public static final boolean ENABLED = true;
|
||||
public static final Field.Index INDEX = Field.Index.NO;
|
||||
@ -43,7 +43,7 @@ public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements So
|
||||
public static final boolean OMIT_TERM_FREQ_AND_POSITIONS = true;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonMapper.Builder<Builder, JsonSourceFieldMapper> {
|
||||
public static class Builder extends XContentMapper.Builder<Builder, XContentSourceFieldMapper> {
|
||||
|
||||
private boolean enabled = Defaults.ENABLED;
|
||||
|
||||
@ -56,8 +56,8 @@ public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements So
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonSourceFieldMapper build(BuilderContext context) {
|
||||
return new JsonSourceFieldMapper(name, enabled);
|
||||
@Override public XContentSourceFieldMapper build(BuilderContext context) {
|
||||
return new XContentSourceFieldMapper(name, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,11 +65,11 @@ public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements So
|
||||
|
||||
private final SourceFieldSelector fieldSelector;
|
||||
|
||||
protected JsonSourceFieldMapper() {
|
||||
protected XContentSourceFieldMapper() {
|
||||
this(Defaults.NAME, Defaults.ENABLED);
|
||||
}
|
||||
|
||||
protected JsonSourceFieldMapper(String name, boolean enabled) {
|
||||
protected XContentSourceFieldMapper(String name, boolean enabled) {
|
||||
super(new Names(name, name, name, name), Defaults.INDEX, Defaults.STORE, Defaults.TERM_VECTOR, Defaults.BOOST,
|
||||
Defaults.OMIT_NORMS, Defaults.OMIT_TERM_FREQ_AND_POSITIONS, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER);
|
||||
this.enabled = enabled;
|
||||
@ -84,11 +84,11 @@ public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements So
|
||||
return this.fieldSelector;
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
return new Field(names.indexName(), jsonContext.source(), store);
|
||||
return new Field(names.indexName(), context.source(), store);
|
||||
}
|
||||
|
||||
@Override public byte[] value(Document document) {
|
||||
@ -124,18 +124,18 @@ public class JsonSourceFieldMapper extends JsonFieldMapper<byte[]> implements So
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(jsonType());
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(contentType());
|
||||
builder.field("name", name());
|
||||
builder.field("enabled", enabled);
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// do nothing here, no merging, but also no exception
|
||||
}
|
||||
}
|
@ -17,35 +17,35 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.elasticsearch.index.analysis.NamedAnalyzer;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonStringFieldMapper extends JsonFieldMapper<String> implements JsonIncludeInAllMapper {
|
||||
public class XContentStringFieldMapper extends XContentFieldMapper<String> implements XContentIncludeInAllMapper {
|
||||
|
||||
public static final String JSON_TYPE = "string";
|
||||
public static final String CONTENT_TYPE = "string";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
// NOTE, when adding defaults here, make sure you add them in the builder
|
||||
public static final String NULL_VALUE = null;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonFieldMapper.OpenBuilder<Builder, JsonStringFieldMapper> {
|
||||
public static class Builder extends XContentFieldMapper.OpenBuilder<Builder, XContentStringFieldMapper> {
|
||||
|
||||
protected String nullValue = Defaults.NULL_VALUE;
|
||||
|
||||
@ -64,8 +64,8 @@ public class JsonStringFieldMapper extends JsonFieldMapper<String> implements Js
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonStringFieldMapper build(BuilderContext context) {
|
||||
JsonStringFieldMapper fieldMapper = new JsonStringFieldMapper(buildNames(context),
|
||||
@Override public XContentStringFieldMapper build(BuilderContext context) {
|
||||
XContentStringFieldMapper fieldMapper = new XContentStringFieldMapper(buildNames(context),
|
||||
index, store, termVector, boost, omitNorms, omitTermFreqAndPositions, nullValue,
|
||||
indexAnalyzer, searchAnalyzer);
|
||||
fieldMapper.includeInAll(includeInAll);
|
||||
@ -73,10 +73,10 @@ public class JsonStringFieldMapper extends JsonFieldMapper<String> implements Js
|
||||
}
|
||||
}
|
||||
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonStringFieldMapper.Builder builder = stringField(name);
|
||||
parseJsonField(builder, name, node, parserContext);
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentStringFieldMapper.Builder builder = stringField(name);
|
||||
parseField(builder, name, node, parserContext);
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
Object propNode = entry.getValue();
|
||||
@ -93,9 +93,9 @@ public class JsonStringFieldMapper extends JsonFieldMapper<String> implements Js
|
||||
|
||||
private Boolean includeInAll;
|
||||
|
||||
protected JsonStringFieldMapper(Names names, Field.Index index, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
String nullValue, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer) {
|
||||
protected XContentStringFieldMapper(Names names, Field.Index index, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions,
|
||||
String nullValue, NamedAnalyzer indexAnalyzer, NamedAnalyzer searchAnalyzer) {
|
||||
super(names, index, store, termVector, boost, omitNorms, omitTermFreqAndPositions, indexAnalyzer, searchAnalyzer);
|
||||
this.nullValue = nullValue;
|
||||
}
|
||||
@ -118,25 +118,25 @@ public class JsonStringFieldMapper extends JsonFieldMapper<String> implements Js
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
String value;
|
||||
if (jsonContext.externalValueSet()) {
|
||||
value = (String) jsonContext.externalValue();
|
||||
if (context.externalValueSet()) {
|
||||
value = (String) context.externalValue();
|
||||
if (value == null) {
|
||||
value = nullValue;
|
||||
}
|
||||
} else {
|
||||
if (jsonContext.jp().getCurrentToken() == JsonToken.VALUE_NULL) {
|
||||
if (context.parser().currentToken() == XContentParser.Token.VALUE_NULL) {
|
||||
value = nullValue;
|
||||
} else {
|
||||
value = jsonContext.jp().getText();
|
||||
value = context.parser().text();
|
||||
}
|
||||
}
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (includeInAll == null || includeInAll) {
|
||||
jsonContext.allEntries().addText(names.fullName(), value, boost);
|
||||
context.allEntries().addText(names.fullName(), value, boost);
|
||||
}
|
||||
if (!indexed() && !stored()) {
|
||||
return null;
|
||||
@ -144,12 +144,12 @@ public class JsonStringFieldMapper extends JsonFieldMapper<String> implements Js
|
||||
return new Field(names.indexName(), value, store, index, termVector);
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override protected void doJsonBody(JsonBuilder builder) throws IOException {
|
||||
super.doJsonBody(builder);
|
||||
@Override protected void doXContentBody(XContentBuilder builder) throws IOException {
|
||||
super.doXContentBody(builder);
|
||||
if (nullValue != null) {
|
||||
builder.field("null_value", nullValue);
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
@ -25,19 +25,19 @@ import org.apache.lucene.document.Fieldable;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.index.mapper.TypeFieldMapper;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.Lucene;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonTypeFieldMapper extends JsonFieldMapper<String> implements TypeFieldMapper {
|
||||
public class XContentTypeFieldMapper extends XContentFieldMapper<String> implements TypeFieldMapper {
|
||||
|
||||
public static final String JSON_TYPE = "_type";
|
||||
public static final String CONTENT_TYPE = "_type";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final String NAME = TypeFieldMapper.NAME;
|
||||
public static final String INDEX_NAME = TypeFieldMapper.NAME;
|
||||
public static final Field.Index INDEX = Field.Index.NOT_ANALYZED;
|
||||
@ -46,7 +46,7 @@ public class JsonTypeFieldMapper extends JsonFieldMapper<String> implements Type
|
||||
public static final boolean OMIT_TERM_FREQ_AND_POSITIONS = true;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonFieldMapper.Builder<Builder, JsonTypeFieldMapper> {
|
||||
public static class Builder extends XContentFieldMapper.Builder<Builder, XContentTypeFieldMapper> {
|
||||
|
||||
public Builder() {
|
||||
super(Defaults.NAME);
|
||||
@ -57,21 +57,21 @@ public class JsonTypeFieldMapper extends JsonFieldMapper<String> implements Type
|
||||
omitTermFreqAndPositions = Defaults.OMIT_TERM_FREQ_AND_POSITIONS;
|
||||
}
|
||||
|
||||
@Override public JsonTypeFieldMapper build(BuilderContext context) {
|
||||
return new JsonTypeFieldMapper(name, indexName, store, termVector, boost, omitNorms, omitTermFreqAndPositions);
|
||||
@Override public XContentTypeFieldMapper build(BuilderContext context) {
|
||||
return new XContentTypeFieldMapper(name, indexName, store, termVector, boost, omitNorms, omitTermFreqAndPositions);
|
||||
}
|
||||
}
|
||||
|
||||
protected JsonTypeFieldMapper() {
|
||||
protected XContentTypeFieldMapper() {
|
||||
this(Defaults.NAME, Defaults.INDEX_NAME);
|
||||
}
|
||||
|
||||
protected JsonTypeFieldMapper(String name, String indexName) {
|
||||
protected XContentTypeFieldMapper(String name, String indexName) {
|
||||
this(name, indexName, Defaults.STORE, Defaults.TERM_VECTOR, Defaults.BOOST,
|
||||
Defaults.OMIT_NORMS, Defaults.OMIT_TERM_FREQ_AND_POSITIONS);
|
||||
}
|
||||
|
||||
public JsonTypeFieldMapper(String name, String indexName, Field.Store store, Field.TermVector termVector,
|
||||
public XContentTypeFieldMapper(String name, String indexName, Field.Store store, Field.TermVector termVector,
|
||||
float boost, boolean omitNorms, boolean omitTermFreqAndPositions) {
|
||||
super(new Names(name, indexName, indexName, name), Defaults.INDEX, store, termVector, boost, omitNorms, omitTermFreqAndPositions,
|
||||
Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER);
|
||||
@ -98,21 +98,21 @@ public class JsonTypeFieldMapper extends JsonFieldMapper<String> implements Type
|
||||
return new Term(names.indexName(), value);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
return new Field(names.indexName(), jsonContext.type(), store, index);
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
return new Field(names.indexName(), context.type(), store, index);
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(JSON_TYPE);
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(CONTENT_TYPE);
|
||||
builder.field("store", store.name().toLowerCase());
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// do nothing here, no merging, but also no exception
|
||||
}
|
||||
}
|
@ -17,11 +17,9 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.elasticsearch.util.gcommon.collect.ImmutableMap;
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
import org.codehaus.jackson.node.ObjectNode;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.util.Strings;
|
||||
@ -31,7 +29,7 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface JsonTypeParser {
|
||||
public interface XContentTypeParser {
|
||||
|
||||
public static class ParserContext {
|
||||
|
||||
@ -39,9 +37,9 @@ public interface JsonTypeParser {
|
||||
|
||||
private final Map<String, Object> rootNode;
|
||||
|
||||
private final ImmutableMap<String, JsonTypeParser> typeParsers;
|
||||
private final ImmutableMap<String, XContentTypeParser> typeParsers;
|
||||
|
||||
public ParserContext(Map<String, Object> rootNode, AnalysisService analysisService, ImmutableMap<String, JsonTypeParser> typeParsers) {
|
||||
public ParserContext(Map<String, Object> rootNode, AnalysisService analysisService, ImmutableMap<String, XContentTypeParser> typeParsers) {
|
||||
this.analysisService = analysisService;
|
||||
this.rootNode = rootNode;
|
||||
this.typeParsers = typeParsers;
|
||||
@ -55,10 +53,10 @@ public interface JsonTypeParser {
|
||||
return this.rootNode;
|
||||
}
|
||||
|
||||
public JsonTypeParser typeParser(String type) {
|
||||
public XContentTypeParser typeParser(String type) {
|
||||
return typeParsers.get(Strings.toUnderscoreCase(type));
|
||||
}
|
||||
}
|
||||
|
||||
JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException;
|
||||
XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException;
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
@ -27,15 +27,15 @@ import org.elasticsearch.util.joda.Joda;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.util.json.JacksonNodes.*;
|
||||
import static org.elasticsearch.util.xcontent.support.XContentMapValues.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonTypeParsers {
|
||||
public class XContentTypeParsers {
|
||||
|
||||
public static void parseNumberField(JsonNumberFieldMapper.Builder builder, String name, Map<String, Object> numberNode, JsonTypeParser.ParserContext parserContext) {
|
||||
parseJsonField(builder, name, numberNode, parserContext);
|
||||
public static void parseNumberField(XContentNumberFieldMapper.Builder builder, String name, Map<String, Object> numberNode, XContentTypeParser.ParserContext parserContext) {
|
||||
parseField(builder, name, numberNode, parserContext);
|
||||
for (Map.Entry<String, Object> entry : numberNode.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
Object propNode = entry.getValue();
|
||||
@ -45,7 +45,7 @@ public class JsonTypeParsers {
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseJsonField(JsonFieldMapper.Builder builder, String name, Map<String, Object> fieldNode, JsonTypeParser.ParserContext parserContext) {
|
||||
public static void parseField(XContentFieldMapper.Builder builder, String name, Map<String, Object> fieldNode, XContentTypeParser.ParserContext parserContext) {
|
||||
for (Map.Entry<String, Object> entry : fieldNode.entrySet()) {
|
||||
String propName = Strings.toUnderscoreCase(entry.getKey());
|
||||
Object propNode = entry.getValue();
|
||||
@ -120,12 +120,12 @@ public class JsonTypeParsers {
|
||||
}
|
||||
}
|
||||
|
||||
public static JsonPath.Type parsePathType(String name, String path) throws MapperParsingException {
|
||||
public static ContentPath.Type parsePathType(String name, String path) throws MapperParsingException {
|
||||
path = Strings.toUnderscoreCase(path);
|
||||
if ("just_name".equals(path)) {
|
||||
return JsonPath.Type.JUST_NAME;
|
||||
return ContentPath.Type.JUST_NAME;
|
||||
} else if ("full".equals(path)) {
|
||||
return JsonPath.Type.FULL;
|
||||
return ContentPath.Type.FULL;
|
||||
} else {
|
||||
throw new MapperParsingException("Wrong value for pathType [" + path + "] for objet [" + name + "]");
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.document.Fieldable;
|
||||
@ -26,26 +26,26 @@ import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.UidFieldMapper;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
import org.elasticsearch.util.lucene.Lucene;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (Shay Banon)
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonUidFieldMapper extends JsonFieldMapper<Uid> implements UidFieldMapper {
|
||||
public class XContentUidFieldMapper extends XContentFieldMapper<Uid> implements UidFieldMapper {
|
||||
|
||||
public static final String JSON_TYPE = "_uid";
|
||||
public static final String CONTENT_TYPE = "_uid";
|
||||
|
||||
public static class Defaults extends JsonFieldMapper.Defaults {
|
||||
public static class Defaults extends XContentFieldMapper.Defaults {
|
||||
public static final String NAME = UidFieldMapper.NAME;
|
||||
public static final Field.Index INDEX = Field.Index.NOT_ANALYZED;
|
||||
public static final boolean OMIT_NORMS = true;
|
||||
public static final boolean OMIT_TERM_FREQ_AND_POSITIONS = true;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonMapper.Builder<Builder, JsonUidFieldMapper> {
|
||||
public static class Builder extends XContentMapper.Builder<Builder, XContentUidFieldMapper> {
|
||||
|
||||
protected String indexName;
|
||||
|
||||
@ -54,30 +54,30 @@ public class JsonUidFieldMapper extends JsonFieldMapper<Uid> implements UidField
|
||||
this.indexName = name;
|
||||
}
|
||||
|
||||
@Override public JsonUidFieldMapper build(BuilderContext context) {
|
||||
return new JsonUidFieldMapper(name, indexName);
|
||||
@Override public XContentUidFieldMapper build(BuilderContext context) {
|
||||
return new XContentUidFieldMapper(name, indexName);
|
||||
}
|
||||
}
|
||||
|
||||
protected JsonUidFieldMapper() {
|
||||
protected XContentUidFieldMapper() {
|
||||
this(Defaults.NAME);
|
||||
}
|
||||
|
||||
protected JsonUidFieldMapper(String name) {
|
||||
protected XContentUidFieldMapper(String name) {
|
||||
this(name, name);
|
||||
}
|
||||
|
||||
protected JsonUidFieldMapper(String name, String indexName) {
|
||||
protected XContentUidFieldMapper(String name, String indexName) {
|
||||
super(new Names(name, indexName, indexName, name), Defaults.INDEX, Field.Store.YES, Defaults.TERM_VECTOR, Defaults.BOOST,
|
||||
Defaults.OMIT_NORMS, Defaults.OMIT_TERM_FREQ_AND_POSITIONS, Lucene.KEYWORD_ANALYZER, Lucene.KEYWORD_ANALYZER);
|
||||
}
|
||||
|
||||
@Override protected Field parseCreateField(JsonParseContext jsonContext) throws IOException {
|
||||
if (jsonContext.id() == null) {
|
||||
throw new MapperParsingException("No id found while parsing the json source");
|
||||
@Override protected Field parseCreateField(ParseContext context) throws IOException {
|
||||
if (context.id() == null) {
|
||||
throw new MapperParsingException("No id found while parsing the content source");
|
||||
}
|
||||
jsonContext.uid(Uid.createUid(jsonContext.stringBuilder(), jsonContext.type(), jsonContext.id()));
|
||||
return new Field(names.indexName(), jsonContext.uid(), store, index);
|
||||
context.uid(Uid.createUid(context.stringBuilder(), context.type(), context.id()));
|
||||
return new Field(names.indexName(), context.uid(), store, index);
|
||||
}
|
||||
|
||||
@Override public Uid value(Fieldable field) {
|
||||
@ -100,15 +100,15 @@ public class JsonUidFieldMapper extends JsonFieldMapper<Uid> implements UidField
|
||||
return new Term(names.indexName(), uid);
|
||||
}
|
||||
|
||||
@Override protected String jsonType() {
|
||||
return JSON_TYPE;
|
||||
@Override protected String contentType() {
|
||||
return CONTENT_TYPE;
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
// for now, don't output it at all
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// do nothing here, no merging, but also no exception
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"_default_" : {
|
||||
}
|
||||
}
|
@ -24,6 +24,22 @@ package org.elasticsearch.util;
|
||||
*/
|
||||
public class Booleans {
|
||||
|
||||
public static boolean parseBoolean(char[] text, int offset, int length, boolean defaultValue) {
|
||||
if (text == null || length == 0) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (length == 1) {
|
||||
return text[offset] != '0';
|
||||
}
|
||||
if (length == 3) {
|
||||
return !(text[offset] == 'o' && text[offset + 1] == 'f' && text[offset + 2] == 'f');
|
||||
}
|
||||
if (length == 5) {
|
||||
return !(text[offset] == 'f' && text[offset + 1] == 'a' && text[offset + 2] == 'l' && text[offset + 3] == 's' && text[offset + 4] == 'e');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean parseBoolean(String value, boolean defaultValue) {
|
||||
if (value == null) {
|
||||
return defaultValue;
|
||||
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface ToXContent {
|
||||
|
||||
public static interface Params {
|
||||
String param(String key);
|
||||
}
|
||||
|
||||
public static final Params EMPTY_PARAMS = new Params() {
|
||||
@Override public String param(String key) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public static class MapParams implements Params {
|
||||
|
||||
private final Map<String, String> params;
|
||||
|
||||
public MapParams(Map<String, String> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override public String param(String key) {
|
||||
return params.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
void toXContent(XContentBuilder builder, Params params) throws IOException;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface XContent {
|
||||
|
||||
XContentType type();
|
||||
|
||||
XContentGenerator createGenerator(OutputStream os) throws IOException;
|
||||
|
||||
XContentGenerator createGenerator(Writer writer) throws IOException;
|
||||
|
||||
XContentParser createParser(String content) throws IOException;
|
||||
|
||||
XContentParser createParser(InputStream is) throws IOException;
|
||||
|
||||
XContentParser createParser(byte[] data) throws IOException;
|
||||
|
||||
XContentParser createParser(byte[] data, int offset, int length) throws IOException;
|
||||
|
||||
XContentParser createParser(Reader reader) throws IOException;
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.elasticsearch.ElasticSearchIllegalArgumentException;
|
||||
import org.elasticsearch.ElasticSearchIllegalStateException;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
import org.elasticsearch.util.xcontent.json.JsonXContent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class XContentFactory {
|
||||
|
||||
private static int GUESS_HEADER_LENGTH = 20;
|
||||
|
||||
private static final XContent[] contents;
|
||||
|
||||
static {
|
||||
contents = new XContent[1];
|
||||
contents[0] = new JsonXContent();
|
||||
}
|
||||
|
||||
public static XContentBuilder contentBuilder(XContentType type) throws IOException {
|
||||
if (type == XContentType.JSON) {
|
||||
return JsonXContent.contentBinaryBuilder();
|
||||
}
|
||||
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
|
||||
}
|
||||
|
||||
public static XContentBuilder contentBinaryBuilder(XContentType type) throws IOException {
|
||||
if (type == XContentType.JSON) {
|
||||
return JsonXContent.contentBinaryBuilder();
|
||||
}
|
||||
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
|
||||
}
|
||||
|
||||
public static XContentBuilder contentTextBuilder(XContentType type) throws IOException {
|
||||
if (type == XContentType.JSON) {
|
||||
return JsonXContent.contentTextBuilder();
|
||||
}
|
||||
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
|
||||
}
|
||||
|
||||
public static XContent xContent(XContentType type) {
|
||||
return contents[type.index()];
|
||||
}
|
||||
|
||||
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++) {
|
||||
char c = content.charAt(i);
|
||||
if (c == '{') {
|
||||
return XContentType.JSON;
|
||||
}
|
||||
}
|
||||
throw new ElasticSearchIllegalStateException("Failed to derive xContent from byte stream");
|
||||
}
|
||||
|
||||
public static XContent xContent(CharSequence content) {
|
||||
return xContent(xContentType(content));
|
||||
}
|
||||
|
||||
public static XContent xContent(byte[] data) {
|
||||
return xContent(data, 0, data.length);
|
||||
}
|
||||
|
||||
public static XContent xContent(byte[] data, int offset, int length) {
|
||||
return xContent(xContentType(data, offset, length));
|
||||
}
|
||||
|
||||
public static XContentType xContentType(byte[] data) {
|
||||
return xContentType(data, 0, data.length);
|
||||
}
|
||||
|
||||
public static XContentType xContentType(byte[] data, int offset, int length) {
|
||||
length = length < GUESS_HEADER_LENGTH ? length : GUESS_HEADER_LENGTH;
|
||||
for (int i = offset; i < length; i++) {
|
||||
if (data[i] == '{') {
|
||||
return XContentType.JSON;
|
||||
}
|
||||
}
|
||||
throw new ElasticSearchIllegalStateException("Failed to derive xContent from byte stream");
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface XContentGenerator {
|
||||
|
||||
XContentType contentType();
|
||||
|
||||
void usePrettyPrint();
|
||||
|
||||
void writeStartArray() throws IOException;
|
||||
|
||||
void writeEndArray() throws IOException;
|
||||
|
||||
void writeStartObject() throws IOException;
|
||||
|
||||
void writeEndObject() throws IOException;
|
||||
|
||||
void writeFieldName(String name) throws IOException;
|
||||
|
||||
void writeString(String text) throws IOException;
|
||||
|
||||
void writeString(char[] text, int offset, int len) throws IOException;
|
||||
|
||||
void writeBinary(byte[] data, int offset, int len) throws IOException;
|
||||
|
||||
void writeBinary(byte[] data) throws IOException;
|
||||
|
||||
void writeNumber(int v) throws IOException;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
void writeStringField(String fieldName, String value) throws IOException;
|
||||
|
||||
void writeBooleanField(String fieldName, boolean value) throws IOException;
|
||||
|
||||
void writeNullField(String fieldName) throws IOException;
|
||||
|
||||
void writeNumberField(String fieldName, int value) throws IOException;
|
||||
|
||||
void writeNumberField(String fieldName, long value) throws IOException;
|
||||
|
||||
void writeNumberField(String fieldName, double value) throws IOException;
|
||||
|
||||
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;
|
||||
|
||||
void writeObjectFieldStart(String fieldName) throws IOException;
|
||||
|
||||
void flush() throws IOException;
|
||||
|
||||
void close() throws IOException;
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public interface XContentParser {
|
||||
|
||||
enum Token {
|
||||
START_OBJECT,
|
||||
END_OBJECT,
|
||||
START_ARRAY,
|
||||
END_ARRAY,
|
||||
FIELD_NAME,
|
||||
VALUE_STRING,
|
||||
VALUE_NUMBER,
|
||||
VALUE_BOOLEAN,
|
||||
VALUE_NULL
|
||||
}
|
||||
|
||||
enum NumberType {
|
||||
INT, LONG, BIG_INTEGER, FLOAT, DOUBLE, BIG_DECIMAL
|
||||
}
|
||||
|
||||
XContentType contentType();
|
||||
|
||||
Token nextToken() throws IOException;
|
||||
|
||||
void skipChildren() throws IOException;
|
||||
|
||||
Token currentToken();
|
||||
|
||||
String currentName() throws IOException;
|
||||
|
||||
Map<String, Object> map() throws IOException;
|
||||
|
||||
String text() throws IOException;
|
||||
|
||||
char[] textCharacters() throws IOException;
|
||||
|
||||
int textLength() throws IOException;
|
||||
|
||||
int textOffset() throws IOException;
|
||||
|
||||
Number numberValue() throws IOException;
|
||||
|
||||
NumberType numberType() throws IOException;
|
||||
|
||||
byte byteValue() throws IOException;
|
||||
|
||||
short shortValue() throws IOException;
|
||||
|
||||
int intValue() throws IOException;
|
||||
|
||||
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;
|
||||
|
||||
void close();
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public enum XContentType {
|
||||
|
||||
JSON(0);
|
||||
|
||||
private int index;
|
||||
|
||||
XContentType(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int index() {
|
||||
return index;
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.builder;
|
||||
|
||||
import org.elasticsearch.util.Unicode;
|
||||
import org.elasticsearch.util.io.FastByteArrayOutputStream;
|
||||
import org.elasticsearch.util.xcontent.XContent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class BinaryXContentBuilder extends XContentBuilder<BinaryXContentBuilder> {
|
||||
|
||||
private final FastByteArrayOutputStream bos;
|
||||
|
||||
private final XContent xContent;
|
||||
|
||||
public BinaryXContentBuilder(XContent xContent) throws IOException {
|
||||
this.bos = new FastByteArrayOutputStream();
|
||||
this.xContent = xContent;
|
||||
this.generator = xContent.createGenerator(bos);
|
||||
this.builder = this;
|
||||
}
|
||||
|
||||
@Override public BinaryXContentBuilder raw(byte[] json) throws IOException {
|
||||
flush();
|
||||
bos.write(json);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public BinaryXContentBuilder reset() throws IOException {
|
||||
fieldCaseConversion = globalFieldCaseConversion;
|
||||
bos.reset();
|
||||
this.generator = xContent.createGenerator(bos);
|
||||
return this;
|
||||
}
|
||||
|
||||
public FastByteArrayOutputStream unsafeStream() throws IOException {
|
||||
flush();
|
||||
return bos;
|
||||
}
|
||||
|
||||
@Override public byte[] unsafeBytes() throws IOException {
|
||||
flush();
|
||||
return bos.unsafeByteArray();
|
||||
}
|
||||
|
||||
@Override public int unsafeBytesLength() throws IOException {
|
||||
flush();
|
||||
return bos.size();
|
||||
}
|
||||
|
||||
@Override public byte[] copiedBytes() throws IOException {
|
||||
flush();
|
||||
return bos.copiedByteArray();
|
||||
}
|
||||
|
||||
@Override public String string() throws IOException {
|
||||
flush();
|
||||
return Unicode.fromBytes(bos.unsafeByteArray(), 0, bos.size());
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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.builder;
|
||||
|
||||
import org.apache.lucene.util.UnicodeUtil;
|
||||
import org.elasticsearch.util.Unicode;
|
||||
import org.elasticsearch.util.io.FastCharArrayWriter;
|
||||
import org.elasticsearch.util.xcontent.XContent;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class TextXContentBuilder extends XContentBuilder<TextXContentBuilder> {
|
||||
|
||||
private final FastCharArrayWriter writer;
|
||||
|
||||
private final XContent xContent;
|
||||
|
||||
final UnicodeUtil.UTF8Result utf8Result = new UnicodeUtil.UTF8Result();
|
||||
|
||||
public TextXContentBuilder(XContent xContent) throws IOException {
|
||||
this.writer = new FastCharArrayWriter();
|
||||
this.xContent = xContent;
|
||||
this.generator = xContent.createGenerator(writer);
|
||||
this.builder = this;
|
||||
}
|
||||
|
||||
@Override public TextXContentBuilder raw(byte[] json) throws IOException {
|
||||
flush();
|
||||
Unicode.UTF16Result result = Unicode.unsafeFromBytesAsUtf16(json);
|
||||
writer.write(result.result, 0, result.length);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextXContentBuilder reset() throws IOException {
|
||||
fieldCaseConversion = globalFieldCaseConversion;
|
||||
writer.reset();
|
||||
generator = xContent.createGenerator(writer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String string() throws IOException {
|
||||
flush();
|
||||
return writer.toStringTrim();
|
||||
}
|
||||
|
||||
public FastCharArrayWriter unsafeChars() throws IOException {
|
||||
flush();
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override public byte[] unsafeBytes() throws IOException {
|
||||
return utf8().result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this AFTER {@link #unsafeBytes()}.
|
||||
*/
|
||||
@Override public int unsafeBytesLength() {
|
||||
return utf8Result.length;
|
||||
}
|
||||
|
||||
@Override public byte[] copiedBytes() throws IOException {
|
||||
flush();
|
||||
byte[] ret = new byte[utf8Result.length];
|
||||
System.arraycopy(utf8Result.result, 0, ret, 0, ret.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the byte[] that represents the utf8 of the json written up until now.
|
||||
* Note, the result is shared within this instance, so copy the byte array if needed
|
||||
* or use {@link #utf8copied()}.
|
||||
*/
|
||||
public UnicodeUtil.UTF8Result utf8() throws IOException {
|
||||
flush();
|
||||
|
||||
// ignore whitepsaces
|
||||
int st = 0;
|
||||
int len = writer.size();
|
||||
char[] val = writer.unsafeCharArray();
|
||||
|
||||
while ((st < len) && (val[st] <= ' ')) {
|
||||
st++;
|
||||
len--;
|
||||
}
|
||||
while ((st < len) && (val[len - 1] <= ' ')) {
|
||||
len--;
|
||||
}
|
||||
|
||||
UnicodeUtil.UTF16toUTF8(val, st, len, utf8Result);
|
||||
|
||||
return utf8Result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copied byte[] that represnts the utf8 o fthe json written up until now.
|
||||
*/
|
||||
public byte[] utf8copied() throws IOException {
|
||||
utf8();
|
||||
byte[] result = new byte[utf8Result.length];
|
||||
System.arraycopy(utf8Result.result, 0, result, 0, utf8Result.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,404 @@
|
||||
/*
|
||||
* 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.builder;
|
||||
|
||||
import org.elasticsearch.util.Strings;
|
||||
import org.elasticsearch.util.xcontent.XContentGenerator;
|
||||
import org.elasticsearch.util.xcontent.XContentType;
|
||||
import org.elasticsearch.util.xcontent.support.XContentMapConverter;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.ReadableInstant;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
import org.joda.time.format.ISODateTimeFormat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public abstract class XContentBuilder<T extends XContentBuilder> {
|
||||
|
||||
public static enum FieldCaseConversion {
|
||||
/**
|
||||
* No came conversion will occur.
|
||||
*/
|
||||
NONE,
|
||||
/**
|
||||
* Camel Case will be converted to Underscore casing.
|
||||
*/
|
||||
UNDERSCORE,
|
||||
/**
|
||||
* Underscore will be converted to Camel case conversion.
|
||||
*/
|
||||
CAMELCASE
|
||||
}
|
||||
|
||||
private final static DateTimeFormatter defaultDatePrinter = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC);
|
||||
|
||||
protected static FieldCaseConversion globalFieldCaseConversion = FieldCaseConversion.NONE;
|
||||
|
||||
public static void globalFieldCaseConversion(FieldCaseConversion globalFieldCaseConversion) {
|
||||
XContentBuilder.globalFieldCaseConversion = globalFieldCaseConversion;
|
||||
}
|
||||
|
||||
protected XContentGenerator generator;
|
||||
|
||||
protected T builder;
|
||||
|
||||
protected FieldCaseConversion fieldCaseConversion = globalFieldCaseConversion;
|
||||
|
||||
protected StringBuilder cachedStringBuilder = new StringBuilder();
|
||||
|
||||
public T fieldCaseConversion(FieldCaseConversion fieldCaseConversion) {
|
||||
this.fieldCaseConversion = fieldCaseConversion;
|
||||
return builder;
|
||||
}
|
||||
|
||||
public XContentType contentType() {
|
||||
return generator.contentType();
|
||||
}
|
||||
|
||||
public T prettyPrint() {
|
||||
generator.usePrettyPrint();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T map(Map<String, Object> map) throws IOException {
|
||||
XContentMapConverter.writeMap(generator, map);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T startObject(String name) throws IOException {
|
||||
field(name);
|
||||
startObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T startObject() throws IOException {
|
||||
generator.writeStartObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T endObject() throws IOException {
|
||||
generator.writeEndObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T array(String name, String... values) throws IOException {
|
||||
startArray(name);
|
||||
for (String value : values) {
|
||||
value(value);
|
||||
}
|
||||
endArray();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T array(String name, Object... values) throws IOException {
|
||||
startArray(name);
|
||||
for (Object value : values) {
|
||||
value(value);
|
||||
}
|
||||
endArray();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T startArray(String name) throws IOException {
|
||||
field(name);
|
||||
startArray();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T startArray() throws IOException {
|
||||
generator.writeStartArray();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T endArray() throws IOException {
|
||||
generator.writeEndArray();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name) throws IOException {
|
||||
if (fieldCaseConversion == FieldCaseConversion.UNDERSCORE) {
|
||||
name = Strings.toUnderscoreCase(name, cachedStringBuilder);
|
||||
} else if (fieldCaseConversion == FieldCaseConversion.CAMELCASE) {
|
||||
name = Strings.toCamelCase(name, cachedStringBuilder);
|
||||
}
|
||||
generator.writeFieldName(name);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, char[] value, int offset, int length) throws IOException {
|
||||
field(name);
|
||||
if (value == null) {
|
||||
generator.writeNull();
|
||||
} else {
|
||||
generator.writeString(value, offset, length);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, String value) throws IOException {
|
||||
field(name);
|
||||
if (value == null) {
|
||||
generator.writeNull();
|
||||
} else {
|
||||
generator.writeString(value);
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, Integer value) throws IOException {
|
||||
return field(name, value.intValue());
|
||||
}
|
||||
|
||||
public T field(String name, int value) throws IOException {
|
||||
field(name);
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, Long value) throws IOException {
|
||||
return field(name, value.longValue());
|
||||
}
|
||||
|
||||
public T field(String name, long value) throws IOException {
|
||||
field(name);
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, Float value) throws IOException {
|
||||
return field(name, value.floatValue());
|
||||
}
|
||||
|
||||
public T field(String name, float value) throws IOException {
|
||||
field(name);
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
public T field(String name, Double value) throws IOException {
|
||||
return field(name, value.doubleValue());
|
||||
}
|
||||
|
||||
public T field(String name, double value) throws IOException {
|
||||
field(name);
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, Object value) throws IOException {
|
||||
if (value == null) {
|
||||
nullField(name);
|
||||
return builder;
|
||||
}
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
field(name, (String) value);
|
||||
} else if (type == Float.class) {
|
||||
field(name, ((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
field(name, ((Double) value).doubleValue());
|
||||
} else if (type == Integer.class) {
|
||||
field(name, ((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
field(name, ((Long) value).longValue());
|
||||
} else if (type == Boolean.class) {
|
||||
field(name, ((Boolean) value).booleanValue());
|
||||
} else if (type == Date.class) {
|
||||
field(name, (Date) value);
|
||||
} else if (type == byte[].class) {
|
||||
field(name, (byte[]) value);
|
||||
} else if (value instanceof ReadableInstant) {
|
||||
field(name, (ReadableInstant) value);
|
||||
} else {
|
||||
field(name, value.toString());
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, boolean value) throws IOException {
|
||||
field(name);
|
||||
generator.writeBoolean(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, byte[] value) throws IOException {
|
||||
field(name);
|
||||
generator.writeBinary(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T field(String name, ReadableInstant date) throws IOException {
|
||||
field(name);
|
||||
return value(date);
|
||||
}
|
||||
|
||||
public T field(String name, ReadableInstant date, DateTimeFormatter formatter) throws IOException {
|
||||
field(name);
|
||||
return value(date, formatter);
|
||||
}
|
||||
|
||||
public T field(String name, Date date) throws IOException {
|
||||
field(name);
|
||||
return value(date);
|
||||
}
|
||||
|
||||
public T field(String name, Date date, DateTimeFormatter formatter) throws IOException {
|
||||
field(name);
|
||||
return value(date, formatter);
|
||||
}
|
||||
|
||||
public T nullField(String name) throws IOException {
|
||||
generator.writeNullField(name);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T nullValue() throws IOException {
|
||||
generator.writeNull();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public abstract T raw(byte[] json) throws IOException;
|
||||
|
||||
public T value(Boolean value) throws IOException {
|
||||
return value(value.booleanValue());
|
||||
}
|
||||
|
||||
public T value(boolean value) throws IOException {
|
||||
generator.writeBoolean(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(ReadableInstant date) throws IOException {
|
||||
return value(date, defaultDatePrinter);
|
||||
}
|
||||
|
||||
public T value(ReadableInstant date, DateTimeFormatter dateTimeFormatter) throws IOException {
|
||||
return value(dateTimeFormatter.print(date));
|
||||
}
|
||||
|
||||
public T value(Date date) throws IOException {
|
||||
return value(date, defaultDatePrinter);
|
||||
}
|
||||
|
||||
public T value(Date date, DateTimeFormatter dateTimeFormatter) throws IOException {
|
||||
return value(dateTimeFormatter.print(date.getTime()));
|
||||
}
|
||||
|
||||
public T value(Integer value) throws IOException {
|
||||
return value(value.intValue());
|
||||
}
|
||||
|
||||
public T value(int value) throws IOException {
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(Long value) throws IOException {
|
||||
return value(value.longValue());
|
||||
}
|
||||
|
||||
public T value(long value) throws IOException {
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(Float value) throws IOException {
|
||||
return value(value.floatValue());
|
||||
}
|
||||
|
||||
public T value(float value) throws IOException {
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(Double value) throws IOException {
|
||||
return value(value.doubleValue());
|
||||
}
|
||||
|
||||
public T value(double value) throws IOException {
|
||||
generator.writeNumber(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(String value) throws IOException {
|
||||
generator.writeString(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(byte[] value) throws IOException {
|
||||
generator.writeBinary(value);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T value(Object value) throws IOException {
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
value((String) value);
|
||||
} else if (type == Float.class) {
|
||||
value(((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
value(((Double) value).doubleValue());
|
||||
} else if (type == Integer.class) {
|
||||
value(((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
value(((Long) value).longValue());
|
||||
} else if (type == Boolean.class) {
|
||||
value((Boolean) value);
|
||||
} else if (type == byte[].class) {
|
||||
value((byte[]) value);
|
||||
} else if (type == Date.class) {
|
||||
value((Date) value);
|
||||
} else if (value instanceof ReadableInstant) {
|
||||
value((ReadableInstant) value);
|
||||
} else {
|
||||
throw new IOException("Type not allowed [" + type + "]");
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
public T flush() throws IOException {
|
||||
generator.flush();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
generator.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public abstract T reset() throws IOException;
|
||||
|
||||
public abstract byte[] unsafeBytes() throws IOException;
|
||||
|
||||
public abstract int unsafeBytesLength() throws IOException;
|
||||
|
||||
public abstract byte[] copiedBytes() throws IOException;
|
||||
|
||||
public abstract String string() throws IOException;
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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.json;
|
||||
|
||||
import org.codehaus.jackson.JsonEncoding;
|
||||
import org.codehaus.jackson.JsonFactory;
|
||||
import org.elasticsearch.ElasticSearchException;
|
||||
import org.elasticsearch.util.ThreadLocals;
|
||||
import org.elasticsearch.util.json.Jackson;
|
||||
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 org.elasticsearch.util.xcontent.builder.TextXContentBuilder;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonXContent 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 JsonXContent());
|
||||
return new ThreadLocals.CleanableValue<BinaryXContentBuilder>(builder);
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchException("Failed to create json 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 class CachedTextBuilder {
|
||||
|
||||
private static final ThreadLocal<ThreadLocals.CleanableValue<TextXContentBuilder>> cache = new ThreadLocal<ThreadLocals.CleanableValue<TextXContentBuilder>>() {
|
||||
@Override protected ThreadLocals.CleanableValue<TextXContentBuilder> initialValue() {
|
||||
try {
|
||||
TextXContentBuilder builder = new TextXContentBuilder(new JsonXContent());
|
||||
return new ThreadLocals.CleanableValue<TextXContentBuilder>(builder);
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchException("Failed to create json generator", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the cached thread local generator, with its internal {@link StringBuilder} cleared.
|
||||
*/
|
||||
static TextXContentBuilder cached() throws IOException {
|
||||
ThreadLocals.CleanableValue<TextXContentBuilder> cached = cache.get();
|
||||
cached.get().reset();
|
||||
return cached.get();
|
||||
}
|
||||
}
|
||||
|
||||
public static XContentBuilder contentBuilder() throws IOException {
|
||||
return contentBinaryBuilder();
|
||||
}
|
||||
|
||||
public static XContentBuilder contentBinaryBuilder() throws IOException {
|
||||
return CachedBinaryBuilder.cached();
|
||||
}
|
||||
|
||||
public static XContentBuilder contentTextBuilder() throws IOException {
|
||||
return CachedTextBuilder.cached();
|
||||
}
|
||||
|
||||
|
||||
private final JsonFactory jsonFactory;
|
||||
|
||||
public JsonXContent() {
|
||||
jsonFactory = Jackson.defaultJsonFactory();
|
||||
}
|
||||
|
||||
@Override public XContentType type() {
|
||||
return XContentType.JSON;
|
||||
}
|
||||
|
||||
@Override public XContentGenerator createGenerator(OutputStream os) throws IOException {
|
||||
return new JsonXContentGenerator(jsonFactory.createJsonGenerator(os, JsonEncoding.UTF8));
|
||||
}
|
||||
|
||||
@Override public XContentGenerator createGenerator(Writer writer) throws IOException {
|
||||
return new JsonXContentGenerator(jsonFactory.createJsonGenerator(writer));
|
||||
}
|
||||
|
||||
@Override public XContentParser createParser(String content) throws IOException {
|
||||
return new JsonXContentParser(jsonFactory.createJsonParser(content));
|
||||
}
|
||||
|
||||
@Override public XContentParser createParser(InputStream is) throws IOException {
|
||||
return new JsonXContentParser(jsonFactory.createJsonParser(is));
|
||||
}
|
||||
|
||||
@Override public XContentParser createParser(byte[] data) throws IOException {
|
||||
return new JsonXContentParser(jsonFactory.createJsonParser(data));
|
||||
}
|
||||
|
||||
@Override public XContentParser createParser(byte[] data, int offset, int length) throws IOException {
|
||||
return new JsonXContentParser(jsonFactory.createJsonParser(data, offset, length));
|
||||
}
|
||||
|
||||
@Override public XContentParser createParser(Reader reader) throws IOException {
|
||||
return new JsonXContentParser(jsonFactory.createJsonParser(reader));
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.json;
|
||||
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
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)
|
||||
*/
|
||||
public class JsonXContentGenerator implements XContentGenerator {
|
||||
|
||||
private final JsonGenerator generator;
|
||||
|
||||
public JsonXContentGenerator(JsonGenerator generator) {
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override public XContentType contentType() {
|
||||
return XContentType.JSON;
|
||||
}
|
||||
|
||||
@Override public void usePrettyPrint() {
|
||||
generator.useDefaultPrettyPrinter();
|
||||
}
|
||||
|
||||
@Override public void writeStartArray() throws IOException {
|
||||
generator.writeStartArray();
|
||||
}
|
||||
|
||||
@Override public void writeEndArray() throws IOException {
|
||||
generator.writeEndArray();
|
||||
}
|
||||
|
||||
@Override public void writeStartObject() throws IOException {
|
||||
generator.writeStartObject();
|
||||
}
|
||||
|
||||
@Override public void writeEndObject() throws IOException {
|
||||
generator.writeEndObject();
|
||||
}
|
||||
|
||||
@Override public void writeFieldName(String name) throws IOException {
|
||||
generator.writeFieldName(name);
|
||||
}
|
||||
|
||||
@Override public void writeString(String text) throws IOException {
|
||||
generator.writeString(text);
|
||||
}
|
||||
|
||||
@Override public void writeString(char[] text, int offset, int len) throws IOException {
|
||||
generator.writeString(text, offset, len);
|
||||
}
|
||||
|
||||
@Override public void writeBinary(byte[] data, int offset, int len) throws IOException {
|
||||
generator.writeBinary(data, offset, len);
|
||||
}
|
||||
|
||||
@Override public void writeBinary(byte[] data) throws IOException {
|
||||
generator.writeBinary(data);
|
||||
}
|
||||
|
||||
@Override public void writeNumber(int v) throws IOException {
|
||||
generator.writeNumber(v);
|
||||
}
|
||||
|
||||
@Override public void writeNumber(long v) throws IOException {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override public void writeNumber(float f) throws IOException {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override public void writeNull() throws IOException {
|
||||
generator.writeNull();
|
||||
}
|
||||
|
||||
@Override public void writeStringField(String fieldName, String value) throws IOException {
|
||||
generator.writeStringField(fieldName, value);
|
||||
}
|
||||
|
||||
@Override public void writeBooleanField(String fieldName, boolean value) throws IOException {
|
||||
generator.writeBooleanField(fieldName, value);
|
||||
}
|
||||
|
||||
@Override public void writeNullField(String fieldName) throws IOException {
|
||||
generator.writeNullField(fieldName);
|
||||
}
|
||||
|
||||
@Override public void writeNumberField(String fieldName, int value) throws IOException {
|
||||
generator.writeNumberField(fieldName, value);
|
||||
}
|
||||
|
||||
@Override public void writeNumberField(String fieldName, long value) throws IOException {
|
||||
generator.writeNumberField(fieldName, value);
|
||||
}
|
||||
|
||||
@Override public void writeNumberField(String fieldName, double value) throws IOException {
|
||||
generator.writeNumberField(fieldName, value);
|
||||
}
|
||||
|
||||
@Override public void writeNumberField(String fieldName, float value) throws IOException {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override public void writeArrayFieldStart(String fieldName) throws IOException {
|
||||
generator.writeArrayFieldStart(fieldName);
|
||||
}
|
||||
|
||||
@Override public void writeObjectFieldStart(String fieldName) throws IOException {
|
||||
generator.writeObjectFieldStart(fieldName);
|
||||
}
|
||||
|
||||
@Override public void flush() throws IOException {
|
||||
generator.flush();
|
||||
}
|
||||
|
||||
@Override public void close() throws IOException {
|
||||
generator.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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.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)
|
||||
*/
|
||||
public class JsonXContentParser extends AbstractXContentParser {
|
||||
|
||||
private final JsonParser parser;
|
||||
|
||||
public JsonXContentParser(JsonParser parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
@Override public XContentType contentType() {
|
||||
return XContentType.JSON;
|
||||
}
|
||||
|
||||
@Override public Token nextToken() throws IOException {
|
||||
return convertToken(parser.nextToken());
|
||||
}
|
||||
|
||||
@Override public void skipChildren() throws IOException {
|
||||
parser.skipChildren();
|
||||
}
|
||||
|
||||
@Override public Token currentToken() {
|
||||
return convertToken(parser.getCurrentToken());
|
||||
}
|
||||
|
||||
@Override public NumberType numberType() throws IOException {
|
||||
return convertNumberType(parser.getNumberType());
|
||||
}
|
||||
|
||||
@Override public String currentName() throws IOException {
|
||||
return parser.getCurrentName();
|
||||
}
|
||||
|
||||
@Override protected boolean doBooleanValue() throws IOException {
|
||||
return parser.getBooleanValue();
|
||||
}
|
||||
|
||||
@Override public String text() throws IOException {
|
||||
return parser.getText();
|
||||
}
|
||||
|
||||
@Override public char[] textCharacters() throws IOException {
|
||||
return parser.getTextCharacters();
|
||||
}
|
||||
|
||||
@Override public int textLength() throws IOException {
|
||||
return parser.getTextLength();
|
||||
}
|
||||
|
||||
@Override public int textOffset() throws IOException {
|
||||
return parser.getTextOffset();
|
||||
}
|
||||
|
||||
@Override public Number numberValue() throws IOException {
|
||||
return parser.getNumberValue();
|
||||
}
|
||||
|
||||
@Override public byte byteValue() throws IOException {
|
||||
return parser.getByteValue();
|
||||
}
|
||||
|
||||
@Override public short doShortValue() throws IOException {
|
||||
return parser.getShortValue();
|
||||
}
|
||||
|
||||
@Override public int doIntValue() throws IOException {
|
||||
return parser.getIntValue();
|
||||
}
|
||||
|
||||
@Override public long doLongValue() throws IOException {
|
||||
return parser.getLongValue();
|
||||
}
|
||||
|
||||
@Override public BigInteger bigIntegerValue() throws IOException {
|
||||
return parser.getBigIntegerValue();
|
||||
}
|
||||
|
||||
@Override public float doFloatValue() throws IOException {
|
||||
return parser.getFloatValue();
|
||||
}
|
||||
|
||||
@Override public double doDoubleValue() throws IOException {
|
||||
return parser.getDoubleValue();
|
||||
}
|
||||
|
||||
@Override public BigDecimal decimalValue() throws IOException {
|
||||
return parser.getDecimalValue();
|
||||
}
|
||||
|
||||
@Override public byte[] binaryValue() throws IOException {
|
||||
return parser.getBinaryValue();
|
||||
}
|
||||
|
||||
@Override public void close() {
|
||||
try {
|
||||
parser.close();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private NumberType convertNumberType(JsonParser.NumberType numberType) {
|
||||
switch (numberType) {
|
||||
case INT:
|
||||
return NumberType.INT;
|
||||
case LONG:
|
||||
return NumberType.LONG;
|
||||
case FLOAT:
|
||||
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 + "]");
|
||||
}
|
||||
|
||||
private Token convertToken(JsonToken token) {
|
||||
if (token == null) {
|
||||
return null;
|
||||
}
|
||||
switch (token) {
|
||||
case FIELD_NAME:
|
||||
return Token.FIELD_NAME;
|
||||
case VALUE_FALSE:
|
||||
case VALUE_TRUE:
|
||||
return Token.VALUE_BOOLEAN;
|
||||
case VALUE_STRING:
|
||||
return Token.VALUE_STRING;
|
||||
case VALUE_NUMBER_INT:
|
||||
case VALUE_NUMBER_FLOAT:
|
||||
return Token.VALUE_NUMBER;
|
||||
case VALUE_NULL:
|
||||
return Token.VALUE_NULL;
|
||||
case START_OBJECT:
|
||||
return Token.START_OBJECT;
|
||||
case END_OBJECT:
|
||||
return Token.END_OBJECT;
|
||||
case START_ARRAY:
|
||||
return Token.START_ARRAY;
|
||||
case END_ARRAY:
|
||||
return Token.END_ARRAY;
|
||||
}
|
||||
throw new ElasticSearchIllegalStateException("No matching token for json_token [" + token + "]");
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.Booleans;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public abstract class AbstractXContentParser implements XContentParser {
|
||||
|
||||
@Override public boolean booleanValue() throws IOException {
|
||||
Token token = currentToken();
|
||||
if (token == Token.VALUE_NUMBER) {
|
||||
return intValue() != 0;
|
||||
} else if (token == Token.VALUE_STRING) {
|
||||
return Booleans.parseBoolean(textCharacters(), textOffset(), textLength(), false /* irrelevant */);
|
||||
}
|
||||
return doBooleanValue();
|
||||
}
|
||||
|
||||
protected abstract boolean doBooleanValue() throws IOException;
|
||||
|
||||
@Override public short shortValue() throws IOException {
|
||||
Token token = currentToken();
|
||||
if (token == Token.VALUE_STRING) {
|
||||
return Short.parseShort(text());
|
||||
}
|
||||
return doShortValue();
|
||||
}
|
||||
|
||||
protected abstract short doShortValue() throws IOException;
|
||||
|
||||
@Override public int intValue() throws IOException {
|
||||
Token token = currentToken();
|
||||
if (token == Token.VALUE_STRING) {
|
||||
return Integer.parseInt(text());
|
||||
}
|
||||
return doIntValue();
|
||||
}
|
||||
|
||||
protected abstract int doIntValue() throws IOException;
|
||||
|
||||
@Override public long longValue() throws IOException {
|
||||
Token token = currentToken();
|
||||
if (token == Token.VALUE_STRING) {
|
||||
return Long.parseLong(text());
|
||||
}
|
||||
return doLongValue();
|
||||
}
|
||||
|
||||
protected abstract long doLongValue() throws IOException;
|
||||
|
||||
@Override public float floatValue() throws IOException {
|
||||
Token token = currentToken();
|
||||
if (token == Token.VALUE_STRING) {
|
||||
return Float.parseFloat(text());
|
||||
}
|
||||
return doFloatValue();
|
||||
}
|
||||
|
||||
protected abstract float doFloatValue() throws IOException;
|
||||
|
||||
@Override public double doubleValue() throws IOException {
|
||||
Token token = currentToken();
|
||||
if (token == Token.VALUE_STRING) {
|
||||
return Double.parseDouble(text());
|
||||
}
|
||||
return doDoubleValue();
|
||||
}
|
||||
|
||||
protected abstract double doDoubleValue() throws IOException;
|
||||
|
||||
@Override public Map<String, Object> map() throws IOException {
|
||||
return XContentMapConverter.readMap(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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 org.elasticsearch.util.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class XContentMapConverter {
|
||||
|
||||
public static Map<String, Object> readMap(XContentParser parser) throws IOException {
|
||||
Map<String, Object> map = new HashMap<String, Object>();
|
||||
XContentParser.Token t = parser.currentToken();
|
||||
if (t == null) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
if (t == XContentParser.Token.START_OBJECT) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
for (; t == XContentParser.Token.FIELD_NAME; t = parser.nextToken()) {
|
||||
// Must point to field name
|
||||
String fieldName = parser.currentName();
|
||||
// And then the value...
|
||||
t = parser.nextToken();
|
||||
Object value = readValue(parser, t);
|
||||
map.put(fieldName, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static List<Object> readList(XContentParser parser, XContentParser.Token t) throws IOException {
|
||||
if (t == XContentParser.Token.START_ARRAY) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
list.add(readValue(parser, t));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static Object readValue(XContentParser parser, XContentParser.Token t) throws IOException {
|
||||
if (t == XContentParser.Token.VALUE_NULL) {
|
||||
return null;
|
||||
} else if (t == XContentParser.Token.VALUE_STRING) {
|
||||
return parser.text();
|
||||
} else if (t == XContentParser.Token.VALUE_NUMBER) {
|
||||
XContentParser.NumberType numberType = parser.numberType();
|
||||
if (numberType == XContentParser.NumberType.INT) {
|
||||
return parser.intValue();
|
||||
} else if (numberType == XContentParser.NumberType.LONG) {
|
||||
return parser.longValue();
|
||||
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
||||
return parser.floatValue();
|
||||
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
||||
return parser.doubleValue();
|
||||
}
|
||||
} else if (t == XContentParser.Token.VALUE_BOOLEAN) {
|
||||
return parser.booleanValue();
|
||||
} else if (t == XContentParser.Token.START_OBJECT) {
|
||||
return readMap(parser);
|
||||
} else if (t == XContentParser.Token.START_ARRAY) {
|
||||
return readList(parser, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void writeMap(XContentGenerator gen, Map<String, Object> map) throws IOException {
|
||||
gen.writeStartObject();
|
||||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
gen.writeFieldName(entry.getKey());
|
||||
Object value = entry.getValue();
|
||||
if (value == null) {
|
||||
gen.writeNull();
|
||||
} else {
|
||||
writeValue(gen, value);
|
||||
}
|
||||
}
|
||||
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
private static void writeIterable(XContentGenerator gen, Iterable iterable) throws IOException {
|
||||
gen.writeStartArray();
|
||||
for (Object value : iterable) {
|
||||
writeValue(gen, value);
|
||||
}
|
||||
gen.writeEndArray();
|
||||
}
|
||||
|
||||
private static void writeObjectArray(XContentGenerator gen, Object[] array) throws IOException {
|
||||
gen.writeStartArray();
|
||||
for (Object value : array) {
|
||||
writeValue(gen, value);
|
||||
}
|
||||
gen.writeEndArray();
|
||||
}
|
||||
|
||||
private static void writeValue(XContentGenerator gen, Object value) throws IOException {
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
gen.writeString((String) value);
|
||||
} else if (type == Integer.class) {
|
||||
gen.writeNumber(((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
gen.writeNumber(((Long) value).longValue());
|
||||
} else if (type == Float.class) {
|
||||
gen.writeNumber(((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
gen.writeNumber(((Double) value).doubleValue());
|
||||
} else if (type == Short.class) {
|
||||
gen.writeNumber(((Short) value).shortValue());
|
||||
} else if (type == Boolean.class) {
|
||||
gen.writeBoolean(((Boolean) value).booleanValue());
|
||||
} else if (value instanceof Map) {
|
||||
writeMap(gen, (Map) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
writeIterable(gen, (Iterable) value);
|
||||
} else if (value instanceof Object[]) {
|
||||
writeObjectArray(gen, (Object[]) value);
|
||||
} else if (type == byte[].class) {
|
||||
gen.writeBinary((byte[]) value);
|
||||
} else {
|
||||
gen.writeString(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -17,9 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.util.json;
|
||||
|
||||
import org.codehaus.jackson.JsonNode;
|
||||
package org.elasticsearch.util.xcontent.support;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -27,7 +25,7 @@ import java.util.Map;
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JacksonNodes {
|
||||
public class XContentMapValues {
|
||||
|
||||
public static boolean isObject(Object node) {
|
||||
return node instanceof Map;
|
@ -17,14 +17,14 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json.all;
|
||||
package org.elasticsearch.index.mapper.xcontent.all;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapperParser;
|
||||
import org.elasticsearch.util.lucene.all.AllEntries;
|
||||
import org.elasticsearch.util.lucene.all.AllTokenFilter;
|
||||
import org.testng.annotations.Test;
|
||||
@ -40,9 +40,9 @@ import static org.hamcrest.Matchers.*;
|
||||
public class SimpleAllMapperTests {
|
||||
|
||||
@Test public void testSimpleAllMappers() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/all/mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/all/test1.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/test1.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
Field field = doc.getField("_all");
|
||||
AllEntries allEntries = ((AllTokenFilter) field.tokenStreamValue()).allEntries();
|
||||
@ -52,13 +52,13 @@ public class SimpleAllMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleAllMappersWithReparse() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/all/mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String builtMapping = docMapper.buildSource();
|
||||
// System.out.println(builtMapping);
|
||||
// reparse it
|
||||
JsonDocumentMapper builtDocMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/all/test1.json");
|
||||
XContentDocumentMapper builtDocMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/test1.json");
|
||||
Document doc = builtDocMapper.parse(json).doc();
|
||||
|
||||
Field field = doc.getField("_all");
|
||||
@ -69,9 +69,9 @@ public class SimpleAllMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleAllMappersWithStore() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/all/store-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/all/test1.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/store-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/test1.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
Field field = doc.getField("_all");
|
||||
AllEntries allEntries = ((AllTokenFilter) field.tokenStreamValue()).allEntries();
|
||||
@ -84,13 +84,13 @@ public class SimpleAllMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleAllMappersWithReparseWithStore() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/all/store-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/store-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String builtMapping = docMapper.buildSource();
|
||||
System.out.println(builtMapping);
|
||||
// reparse it
|
||||
JsonDocumentMapper builtDocMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/all/test1.json");
|
||||
XContentDocumentMapper builtDocMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/all/test1.json");
|
||||
Document doc = builtDocMapper.parse(json).doc();
|
||||
|
||||
Field field = doc.getField("_all");
|
@ -17,13 +17,13 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json.merge.test1;
|
||||
package org.elasticsearch.index.mapper.xcontent.merge.test1;
|
||||
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.DocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapperParser;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.elasticsearch.index.mapper.DocumentMapper.MergeFlags.*;
|
||||
@ -38,10 +38,10 @@ import static org.hamcrest.Matchers.*;
|
||||
public class Test1MergeMapperTests {
|
||||
|
||||
@Test public void test1Merge() throws Exception {
|
||||
String stage1Mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/merge/test1/stage1.json");
|
||||
JsonDocumentMapper stage1 = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage1Mapping);
|
||||
String stage2Mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/merge/test1/stage2.json");
|
||||
JsonDocumentMapper stage2 = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage2Mapping);
|
||||
String stage1Mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/merge/test1/stage1.json");
|
||||
XContentDocumentMapper stage1 = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage1Mapping);
|
||||
String stage2Mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/merge/test1/stage2.json");
|
||||
XContentDocumentMapper stage2 = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(stage2Mapping);
|
||||
|
||||
DocumentMapper.MergeResult mergeResult = stage1.merge(stage2, mergeFlags().simulate(true));
|
||||
assertThat(mergeResult.hasConflicts(), equalTo(true));
|
@ -17,17 +17,17 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json.multifield;
|
||||
package org.elasticsearch.index.mapper.xcontent.multifield;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapperParser;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.util.io.Streams.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
@ -36,12 +36,12 @@ import static org.hamcrest.Matchers.*;
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
@Test
|
||||
public class JsonMultiFieldTests {
|
||||
public class XContentMultiFieldTests {
|
||||
|
||||
@Test public void testMultiField() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/multifield/test-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/multifield/test-data.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/test-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/test-data.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
|
||||
Field f = doc.getField("name");
|
||||
@ -71,7 +71,7 @@ public class JsonMultiFieldTests {
|
||||
}
|
||||
|
||||
@Test public void testBuildThenParse() throws Exception {
|
||||
JsonDocumentMapper builderDocMapper = doc(object("person").add(
|
||||
XContentDocumentMapper builderDocMapper = doc(object("person").add(
|
||||
multiField("name")
|
||||
.add(stringField("name").store(Field.Store.YES))
|
||||
.add(stringField("indexed").index(Field.Index.ANALYZED))
|
||||
@ -81,10 +81,10 @@ public class JsonMultiFieldTests {
|
||||
String builtMapping = builderDocMapper.buildSource();
|
||||
// System.out.println(builtMapping);
|
||||
// reparse it
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
|
||||
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/multifield/test-data.json");
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/test-data.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
|
||||
Field f = doc.getField("name");
|
@ -17,14 +17,14 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json.multifield.merge;
|
||||
package org.elasticsearch.index.mapper.xcontent.multifield.merge;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapperParser;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.elasticsearch.index.mapper.DocumentMapper.MergeFlags.*;
|
||||
@ -39,13 +39,13 @@ import static org.hamcrest.Matchers.*;
|
||||
public class JavaMultiFieldMergeTests {
|
||||
|
||||
@Test public void testMergeMultiField() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/multifield/merge/test-mapping1.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/merge/test-mapping1.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
|
||||
assertThat(docMapper.mappers().fullName("name").mapper().indexed(), equalTo(true));
|
||||
assertThat(docMapper.mappers().fullName("name.indexed"), nullValue());
|
||||
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/multifield/merge/test-data.json");
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/merge/test-data.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
Field f = doc.getField("name");
|
||||
assertThat(f, notNullValue());
|
||||
@ -53,8 +53,8 @@ public class JavaMultiFieldMergeTests {
|
||||
assertThat(f, nullValue());
|
||||
|
||||
|
||||
mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/multifield/merge/test-mapping2.json");
|
||||
JsonDocumentMapper docMapper2 = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/merge/test-mapping2.json");
|
||||
XContentDocumentMapper docMapper2 = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
|
||||
docMapper.merge(docMapper2, mergeFlags().simulate(true));
|
||||
|
||||
@ -65,7 +65,7 @@ public class JavaMultiFieldMergeTests {
|
||||
assertThat(docMapper.mappers().fullName("name").mapper().indexed(), equalTo(true));
|
||||
assertThat(docMapper.mappers().fullName("name.indexed").mapper(), notNullValue());
|
||||
|
||||
json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/multifield/merge/test-data.json");
|
||||
json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/multifield/merge/test-data.json");
|
||||
doc = docMapper.parse(json).doc();
|
||||
f = doc.getField("name");
|
||||
assertThat(f, notNullValue());
|
@ -17,19 +17,19 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.index.mapper.json.simple;
|
||||
package org.elasticsearch.index.mapper.xcontent.simple;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentDocumentMapperParser;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.apache.lucene.document.Field.Store.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.util.io.Streams.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
@ -37,15 +37,15 @@ import static org.hamcrest.Matchers.*;
|
||||
/**
|
||||
* @author kimchy
|
||||
*/
|
||||
public class SimpleJsonMapperTests {
|
||||
public class SimpleXContentMapperTests {
|
||||
|
||||
@Test public void testSimpleMapper() throws Exception {
|
||||
JsonDocumentMapper docMapper = doc(
|
||||
XContentDocumentMapper docMapper = doc(
|
||||
object("person")
|
||||
.add(object("name").add(stringField("first").store(YES).index(Field.Index.NO)))
|
||||
).sourceField(source()).build();
|
||||
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/simple/test1.json");
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test1.json");
|
||||
Document doc = docMapper.parse("person", "1", json).doc();
|
||||
|
||||
assertThat((double) doc.getBoost(), closeTo(3.7, 0.01));
|
||||
@ -59,13 +59,13 @@ public class SimpleJsonMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testParseToJsonAndParse() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/simple/test-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
String builtMapping = docMapper.buildSource();
|
||||
// System.out.println(builtMapping);
|
||||
// reparse it
|
||||
JsonDocumentMapper builtDocMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/simple/test1.json");
|
||||
XContentDocumentMapper builtDocMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(builtMapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test1.json");
|
||||
Document doc = builtDocMapper.parse(json).doc();
|
||||
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
|
||||
assertThat((double) doc.getBoost(), closeTo(3.7, 0.01));
|
||||
@ -76,9 +76,9 @@ public class SimpleJsonMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleParser() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/simple/test-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/simple/test1.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test1.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
|
||||
assertThat((double) doc.getBoost(), closeTo(3.7, 0.01));
|
||||
@ -89,9 +89,9 @@ public class SimpleJsonMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleParserMappingWithNoType() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/simple/test-mapping-notype.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse("person", mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/simple/test1.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test-mapping-notype.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse("person", mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test1.json");
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
|
||||
assertThat((double) doc.getBoost(), closeTo(3.7, 0.01));
|
||||
@ -102,9 +102,9 @@ public class SimpleJsonMapperTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleParserNoTypeNoId() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/json/simple/test-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) new JsonDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/json/simple/test1-notype-noid.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) new XContentDocumentMapperParser(new AnalysisService(new Index("test"))).parse(mapping);
|
||||
byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/simple/test1-notype-noid.json");
|
||||
Document doc = docMapper.parse("person", "1", json).doc();
|
||||
assertThat(doc.get(docMapper.uidMapper().names().indexName()), equalTo(Uid.createUid("person", "1")));
|
||||
assertThat((double) doc.getBoost(), closeTo(3.7, 0.01));
|
@ -606,7 +606,7 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.longToPrefixCoded(34))));
|
||||
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
|
||||
}
|
||||
|
||||
@Test public void testSpanTermQuery() throws IOException {
|
||||
@ -616,7 +616,7 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.longToPrefixCoded(34))));
|
||||
assertThat(termQuery.getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
|
||||
}
|
||||
|
||||
@Test public void testSpanNotQueryBuilder() throws IOException {
|
||||
@ -625,8 +625,8 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.longToPrefixCoded(34))));
|
||||
assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
|
||||
assertThat(((SpanTermQuery) spanNotQuery.getInclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
|
||||
assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
|
||||
}
|
||||
|
||||
@Test public void testSpanNotQuery() throws IOException {
|
||||
@ -636,8 +636,8 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.longToPrefixCoded(34))));
|
||||
assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.longToPrefixCoded(35))));
|
||||
assertThat(((SpanTermQuery) spanNotQuery.getInclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
|
||||
assertThat(((SpanTermQuery) spanNotQuery.getExclude()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(35))));
|
||||
}
|
||||
|
||||
@Test public void testSpanFirstQueryBuilder() throws IOException {
|
||||
@ -646,7 +646,7 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.longToPrefixCoded(34))));
|
||||
assertThat(((SpanTermQuery) spanFirstQuery.getMatch()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
|
||||
assertThat(spanFirstQuery.getEnd(), equalTo(12));
|
||||
}
|
||||
|
||||
@ -657,7 +657,7 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.longToPrefixCoded(34))));
|
||||
assertThat(((SpanTermQuery) spanFirstQuery.getMatch()).getTerm(), equalTo(new Term("age", NumericUtils.intToPrefixCoded(34))));
|
||||
assertThat(spanFirstQuery.getEnd(), equalTo(12));
|
||||
}
|
||||
|
||||
@ -667,9 +667,9 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.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(((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(spanNearQuery.isInOrder(), equalTo(false));
|
||||
}
|
||||
|
||||
@ -680,9 +680,9 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.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(((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(spanNearQuery.isInOrder(), equalTo(false));
|
||||
}
|
||||
|
||||
@ -692,9 +692,9 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.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))));
|
||||
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))));
|
||||
}
|
||||
|
||||
@Test public void testSpanOrQuery() throws IOException {
|
||||
@ -704,9 +704,9 @@ public class SimpleJsonIndexQueryParserTests {
|
||||
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.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))));
|
||||
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))));
|
||||
}
|
||||
|
||||
@Test public void testQueryFilterBuilder() throws Exception {
|
||||
|
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* 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.index.mapper.xcontent;
|
||||
|
||||
import org.apache.tika.exception.TikaException;
|
||||
import org.apache.tika.metadata.Metadata;
|
||||
import org.elasticsearch.index.mapper.FieldMapperListener;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.util.io.FastByteArrayInputStream;
|
||||
import org.elasticsearch.util.xcontent.XContentParser;
|
||||
import org.elasticsearch.util.xcontent.builder.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
|
||||
import static org.elasticsearch.plugin.attachments.tika.TikaInstance.*;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* field1 : "..."
|
||||
* </pre>
|
||||
* <p>Or:
|
||||
* <pre>
|
||||
* {
|
||||
* file1 : {
|
||||
* _content_type : "application/pdf",
|
||||
* _name : "..../something.pdf",
|
||||
* content : ""
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class XContentAttachmentMapper implements XContentMapper {
|
||||
|
||||
public static final String CONTENT_TYPE = "attachment";
|
||||
|
||||
public static class Defaults {
|
||||
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
|
||||
}
|
||||
|
||||
public static class Builder extends XContentMapper.Builder<Builder, XContentAttachmentMapper> {
|
||||
|
||||
private ContentPath.Type pathType = Defaults.PATH_TYPE;
|
||||
|
||||
private XContentStringFieldMapper.Builder contentBuilder;
|
||||
|
||||
private XContentStringFieldMapper.Builder titleBuilder = stringField("title");
|
||||
|
||||
private XContentStringFieldMapper.Builder authorBuilder = stringField("author");
|
||||
|
||||
private XContentStringFieldMapper.Builder keywordsBuilder = stringField("keywords");
|
||||
|
||||
private XContentDateFieldMapper.Builder dateBuilder = dateField("date");
|
||||
|
||||
public Builder(String name) {
|
||||
super(name);
|
||||
this.builder = this;
|
||||
this.contentBuilder = stringField(name);
|
||||
}
|
||||
|
||||
public Builder pathType(ContentPath.Type pathType) {
|
||||
this.pathType = pathType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder content(XContentStringFieldMapper.Builder content) {
|
||||
this.contentBuilder = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder date(XContentDateFieldMapper.Builder date) {
|
||||
this.dateBuilder = date;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder author(XContentStringFieldMapper.Builder author) {
|
||||
this.authorBuilder = author;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder title(XContentStringFieldMapper.Builder title) {
|
||||
this.titleBuilder = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keywords(XContentStringFieldMapper.Builder keywords) {
|
||||
this.keywordsBuilder = keywords;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public XContentAttachmentMapper build(BuilderContext context) {
|
||||
ContentPath.Type origPathType = context.path().pathType();
|
||||
context.path().pathType(pathType);
|
||||
|
||||
// create the content mapper under the actual name
|
||||
XContentStringFieldMapper contentMapper = contentBuilder.build(context);
|
||||
|
||||
// create the DC one under the name
|
||||
context.path().add(name);
|
||||
XContentDateFieldMapper dateMapper = dateBuilder.build(context);
|
||||
XContentStringFieldMapper authorMapper = authorBuilder.build(context);
|
||||
XContentStringFieldMapper titleMapper = titleBuilder.build(context);
|
||||
XContentStringFieldMapper keywordsMapper = keywordsBuilder.build(context);
|
||||
context.path().remove();
|
||||
|
||||
context.path().pathType(origPathType);
|
||||
|
||||
return new XContentAttachmentMapper(name, pathType, contentMapper, dateMapper, titleMapper, authorMapper, keywordsMapper);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* field1 : { type : "attachment" }
|
||||
* </pre>
|
||||
* Or:
|
||||
* <pre>
|
||||
* field1 : {
|
||||
* type : "attachment",
|
||||
* fields : {
|
||||
* field1 : {type : "binary"},
|
||||
* title : {store : "yes"},
|
||||
* date : {store : "yes"}
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public static class TypeParser implements XContentTypeParser {
|
||||
|
||||
@Override public XContentMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
XContentAttachmentMapper.Builder builder = new XContentAttachmentMapper.Builder(name);
|
||||
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
Object fieldNode = entry.getValue();
|
||||
if (fieldName.equals("path")) {
|
||||
builder.pathType(parsePathType(name, fieldNode.toString()));
|
||||
} else if (fieldName.equals("fields")) {
|
||||
Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
|
||||
for (Map.Entry<String, Object> entry1 : fieldsNode.entrySet()) {
|
||||
String propName = entry1.getKey();
|
||||
Object propNode = entry1.getValue();
|
||||
|
||||
if (name.equals(propName)) {
|
||||
// that is the content
|
||||
builder.content((XContentStringFieldMapper.Builder) parserContext.typeParser("string").parse(name, (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("date".equals(propName)) {
|
||||
builder.date((XContentDateFieldMapper.Builder) parserContext.typeParser("date").parse("date", (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("title".equals(propName)) {
|
||||
builder.title((XContentStringFieldMapper.Builder) parserContext.typeParser("string").parse("title", (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("author".equals(propName)) {
|
||||
builder.author((XContentStringFieldMapper.Builder) parserContext.typeParser("string").parse("author", (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("keywords".equals(propName)) {
|
||||
builder.keywords((XContentStringFieldMapper.Builder) parserContext.typeParser("string").parse("keywords", (Map<String, Object>) propNode, parserContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
private final ContentPath.Type pathType;
|
||||
|
||||
private final XContentStringFieldMapper contentMapper;
|
||||
|
||||
private final XContentDateFieldMapper dateMapper;
|
||||
|
||||
private final XContentStringFieldMapper authorMapper;
|
||||
|
||||
private final XContentStringFieldMapper titleMapper;
|
||||
|
||||
private final XContentStringFieldMapper keywordsMapper;
|
||||
|
||||
public XContentAttachmentMapper(String name, ContentPath.Type pathType, XContentStringFieldMapper contentMapper,
|
||||
XContentDateFieldMapper dateMapper, XContentStringFieldMapper titleMapper, XContentStringFieldMapper authorMapper,
|
||||
XContentStringFieldMapper keywordsMapper) {
|
||||
this.name = name;
|
||||
this.pathType = pathType;
|
||||
this.contentMapper = contentMapper;
|
||||
this.dateMapper = dateMapper;
|
||||
this.titleMapper = titleMapper;
|
||||
this.authorMapper = authorMapper;
|
||||
this.keywordsMapper = keywordsMapper;
|
||||
}
|
||||
|
||||
@Override public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override public void parse(ParseContext context) throws IOException {
|
||||
byte[] content = null;
|
||||
String contentType = null;
|
||||
String name = null;
|
||||
|
||||
XContentParser parser = context.parser();
|
||||
XContentParser.Token token = parser.currentToken();
|
||||
if (token == XContentParser.Token.VALUE_STRING) {
|
||||
content = parser.binaryValue();
|
||||
} else {
|
||||
String currentFieldName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token == XContentParser.Token.VALUE_STRING) {
|
||||
if ("content".equals(currentFieldName)) {
|
||||
content = parser.binaryValue();
|
||||
} else if ("_content_type".equals(currentFieldName)) {
|
||||
contentType = parser.text();
|
||||
} else if ("_name".equals(currentFieldName)) {
|
||||
name = parser.text();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Metadata metadata = new Metadata();
|
||||
if (contentType != null) {
|
||||
metadata.add(Metadata.CONTENT_TYPE, contentType);
|
||||
}
|
||||
if (name != null) {
|
||||
metadata.add(Metadata.RESOURCE_NAME_KEY, name);
|
||||
}
|
||||
|
||||
String parsedContent;
|
||||
try {
|
||||
parsedContent = tika().parseToString(new FastByteArrayInputStream(content), metadata);
|
||||
} catch (TikaException e) {
|
||||
throw new MapperParsingException("Failed to extract text for [" + name + "]", e);
|
||||
}
|
||||
|
||||
context.externalValue(parsedContent);
|
||||
contentMapper.parse(context);
|
||||
|
||||
context.externalValue(metadata.get(Metadata.DATE));
|
||||
dateMapper.parse(context);
|
||||
|
||||
context.externalValue(metadata.get(Metadata.TITLE));
|
||||
titleMapper.parse(context);
|
||||
|
||||
context.externalValue(metadata.get(Metadata.AUTHOR));
|
||||
authorMapper.parse(context);
|
||||
|
||||
context.externalValue(metadata.get(Metadata.KEYWORDS));
|
||||
keywordsMapper.parse(context);
|
||||
}
|
||||
|
||||
@Override public void merge(XContentMapper mergeWith, MergeContext mergeContext) throws MergeMappingException {
|
||||
// ignore this for now
|
||||
}
|
||||
|
||||
@Override public void traverse(FieldMapperListener fieldMapperListener) {
|
||||
contentMapper.traverse(fieldMapperListener);
|
||||
dateMapper.traverse(fieldMapperListener);
|
||||
titleMapper.traverse(fieldMapperListener);
|
||||
authorMapper.traverse(fieldMapperListener);
|
||||
keywordsMapper.traverse(fieldMapperListener);
|
||||
}
|
||||
|
||||
@Override public void toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(name);
|
||||
builder.field("type", CONTENT_TYPE);
|
||||
builder.field("path", pathType.name().toLowerCase());
|
||||
|
||||
builder.startObject("fields");
|
||||
contentMapper.toXContent(builder, params);
|
||||
authorMapper.toXContent(builder, params);
|
||||
titleMapper.toXContent(builder, params);
|
||||
dateMapper.toXContent(builder, params);
|
||||
keywordsMapper.toXContent(builder, params);
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
@ -17,24 +17,23 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.plugin.attachments.index.mapper;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.elasticsearch.util.guice.inject.Inject;
|
||||
import org.elasticsearch.index.AbstractIndexComponent;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.elasticsearch.index.settings.IndexSettings;
|
||||
import org.elasticsearch.util.guice.inject.Inject;
|
||||
import org.elasticsearch.util.settings.Settings;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonAttachmentMapperService extends AbstractIndexComponent {
|
||||
public class XContentAttachmentMapperService extends AbstractIndexComponent {
|
||||
|
||||
@Inject public JsonAttachmentMapperService(Index index, @IndexSettings Settings indexSettings, MapperService mapperService) {
|
||||
@Inject public XContentAttachmentMapperService(Index index, @IndexSettings Settings indexSettings, MapperService mapperService) {
|
||||
super(index, indexSettings);
|
||||
|
||||
((JsonDocumentMapperParser) mapperService.documentMapperParser()).putTypeParser("attachment", new JsonAttachmentMapper.TypeParser());
|
||||
((XContentDocumentMapperParser) mapperService.documentMapperParser()).putTypeParser("attachment", new XContentAttachmentMapper.TypeParser());
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
package org.elasticsearch.plugin.attachments;
|
||||
|
||||
import org.elasticsearch.util.guice.inject.AbstractModule;
|
||||
import org.elasticsearch.plugin.attachments.index.mapper.JsonAttachmentMapperService;
|
||||
import org.elasticsearch.index.mapper.xcontent.XContentAttachmentMapperService;
|
||||
|
||||
/**
|
||||
* @author kimchy (shay.banon)
|
||||
@ -28,6 +28,6 @@ import org.elasticsearch.plugin.attachments.index.mapper.JsonAttachmentMapperSer
|
||||
public class MapperAttachmentsIndexModule extends AbstractModule {
|
||||
|
||||
@Override protected void configure() {
|
||||
bind(JsonAttachmentMapperService.class).asEagerSingleton();
|
||||
bind(XContentAttachmentMapperService.class).asEagerSingleton();
|
||||
}
|
||||
}
|
||||
|
@ -1,315 +0,0 @@
|
||||
/*
|
||||
* 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.plugin.attachments.index.mapper;
|
||||
|
||||
import org.apache.tika.exception.TikaException;
|
||||
import org.apache.tika.metadata.Metadata;
|
||||
import org.codehaus.jackson.*;
|
||||
import org.codehaus.jackson.node.ObjectNode;
|
||||
import org.elasticsearch.index.mapper.FieldMapperListener;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.index.mapper.MergeMappingException;
|
||||
import org.elasticsearch.index.mapper.json.*;
|
||||
import org.elasticsearch.util.io.FastByteArrayInputStream;
|
||||
import org.elasticsearch.util.json.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.index.mapper.json.JsonMapperBuilders.*;
|
||||
import static org.elasticsearch.index.mapper.json.JsonTypeParsers.*;
|
||||
import static org.elasticsearch.plugin.attachments.tika.TikaInstance.*;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* field1 : "..."
|
||||
* </pre>
|
||||
* <p>Or:
|
||||
* <pre>
|
||||
* {
|
||||
* file1 : {
|
||||
* _content_type : "application/pdf",
|
||||
* _name : "..../something.pdf",
|
||||
* content : ""
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public class JsonAttachmentMapper implements JsonMapper {
|
||||
|
||||
public static final String JSON_TYPE = "attachment";
|
||||
|
||||
public static class Defaults {
|
||||
public static final JsonPath.Type PATH_TYPE = JsonPath.Type.FULL;
|
||||
}
|
||||
|
||||
public static class Builder extends JsonMapper.Builder<Builder, JsonAttachmentMapper> {
|
||||
|
||||
private JsonPath.Type pathType = Defaults.PATH_TYPE;
|
||||
|
||||
private JsonStringFieldMapper.Builder contentBuilder;
|
||||
|
||||
private JsonStringFieldMapper.Builder titleBuilder = stringField("title");
|
||||
|
||||
private JsonStringFieldMapper.Builder authorBuilder = stringField("author");
|
||||
|
||||
private JsonStringFieldMapper.Builder keywordsBuilder = stringField("keywords");
|
||||
|
||||
private JsonDateFieldMapper.Builder dateBuilder = dateField("date");
|
||||
|
||||
public Builder(String name) {
|
||||
super(name);
|
||||
this.builder = this;
|
||||
this.contentBuilder = stringField(name);
|
||||
}
|
||||
|
||||
public Builder pathType(JsonPath.Type pathType) {
|
||||
this.pathType = pathType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder content(JsonStringFieldMapper.Builder content) {
|
||||
this.contentBuilder = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder date(JsonDateFieldMapper.Builder date) {
|
||||
this.dateBuilder = date;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder author(JsonStringFieldMapper.Builder author) {
|
||||
this.authorBuilder = author;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder title(JsonStringFieldMapper.Builder title) {
|
||||
this.titleBuilder = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder keywords(JsonStringFieldMapper.Builder keywords) {
|
||||
this.keywordsBuilder = keywords;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public JsonAttachmentMapper build(BuilderContext context) {
|
||||
JsonPath.Type origPathType = context.path().pathType();
|
||||
context.path().pathType(pathType);
|
||||
|
||||
// create the content mapper under the actual name
|
||||
JsonStringFieldMapper contentMapper = contentBuilder.build(context);
|
||||
|
||||
// create the DC one under the name
|
||||
context.path().add(name);
|
||||
JsonDateFieldMapper dateMapper = dateBuilder.build(context);
|
||||
JsonStringFieldMapper authorMapper = authorBuilder.build(context);
|
||||
JsonStringFieldMapper titleMapper = titleBuilder.build(context);
|
||||
JsonStringFieldMapper keywordsMapper = keywordsBuilder.build(context);
|
||||
context.path().remove();
|
||||
|
||||
context.path().pathType(origPathType);
|
||||
|
||||
return new JsonAttachmentMapper(name, pathType, contentMapper, dateMapper, titleMapper, authorMapper, keywordsMapper);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* field1 : { type : "attachment" }
|
||||
* </pre>
|
||||
* Or:
|
||||
* <pre>
|
||||
* field1 : {
|
||||
* type : "attachment",
|
||||
* fields : {
|
||||
* field1 : {type : "binary"},
|
||||
* title : {store : "yes"},
|
||||
* date : {store : "yes"}
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author kimchy (shay.banon)
|
||||
*/
|
||||
public static class TypeParser implements JsonTypeParser {
|
||||
|
||||
@Override public JsonMapper.Builder parse(String name, Map<String, Object> node, ParserContext parserContext) throws MapperParsingException {
|
||||
JsonAttachmentMapper.Builder builder = new JsonAttachmentMapper.Builder(name);
|
||||
|
||||
for (Map.Entry<String, Object> entry : node.entrySet()) {
|
||||
String fieldName = entry.getKey();
|
||||
Object fieldNode = entry.getValue();
|
||||
if (fieldName.equals("path")) {
|
||||
builder.pathType(parsePathType(name, fieldNode.toString()));
|
||||
} else if (fieldName.equals("fields")) {
|
||||
Map<String, Object> fieldsNode = (Map<String, Object>) fieldNode;
|
||||
for (Map.Entry<String, Object> entry1 : fieldsNode.entrySet()) {
|
||||
String propName = entry1.getKey();
|
||||
Object propNode = entry1.getValue();
|
||||
|
||||
if (name.equals(propName)) {
|
||||
// that is the content
|
||||
builder.content((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse(name, (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("date".equals(propName)) {
|
||||
builder.date((JsonDateFieldMapper.Builder) parserContext.typeParser("date").parse("date", (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("title".equals(propName)) {
|
||||
builder.title((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("title", (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("author".equals(propName)) {
|
||||
builder.author((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("author", (Map<String, Object>) propNode, parserContext));
|
||||
} else if ("keywords".equals(propName)) {
|
||||
builder.keywords((JsonStringFieldMapper.Builder) parserContext.typeParser("string").parse("keywords", (Map<String, Object>) propNode, parserContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
private final JsonPath.Type pathType;
|
||||
|
||||
private final JsonStringFieldMapper contentMapper;
|
||||
|
||||
private final JsonDateFieldMapper dateMapper;
|
||||
|
||||
private final JsonStringFieldMapper authorMapper;
|
||||
|
||||
private final JsonStringFieldMapper titleMapper;
|
||||
|
||||
private final JsonStringFieldMapper keywordsMapper;
|
||||
|
||||
public JsonAttachmentMapper(String name, JsonPath.Type pathType, JsonStringFieldMapper contentMapper,
|
||||
JsonDateFieldMapper dateMapper, JsonStringFieldMapper titleMapper, JsonStringFieldMapper authorMapper,
|
||||
JsonStringFieldMapper keywordsMapper) {
|
||||
this.name = name;
|
||||
this.pathType = pathType;
|
||||
this.contentMapper = contentMapper;
|
||||
this.dateMapper = dateMapper;
|
||||
this.titleMapper = titleMapper;
|
||||
this.authorMapper = authorMapper;
|
||||
this.keywordsMapper = keywordsMapper;
|
||||
}
|
||||
|
||||
@Override public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override public void parse(JsonParseContext jsonContext) throws IOException {
|
||||
byte[] content = null;
|
||||
String contentType = null;
|
||||
String name = null;
|
||||
Base64Variant base64Variant = Base64Variants.getDefaultVariant();
|
||||
|
||||
JsonParser jp = jsonContext.jp();
|
||||
JsonToken token = jp.getCurrentToken();
|
||||
if (token == JsonToken.VALUE_STRING) {
|
||||
content = jp.getBinaryValue();
|
||||
} else {
|
||||
String currentFieldName = null;
|
||||
while ((token = jp.nextToken()) != JsonToken.END_OBJECT) {
|
||||
if (token == JsonToken.FIELD_NAME) {
|
||||
currentFieldName = jp.getCurrentName();
|
||||
} else if (token == JsonToken.VALUE_STRING) {
|
||||
if ("content".equals(currentFieldName)) {
|
||||
content = jp.getBinaryValue(base64Variant);
|
||||
} else if ("_content_type".equals(currentFieldName)) {
|
||||
contentType = jp.getText();
|
||||
} else if ("_name".equals(currentFieldName)) {
|
||||
name = jp.getText();
|
||||
} else if ("_base64".equals(currentFieldName)) {
|
||||
String variant = jp.getText();
|
||||
if ("mime".equals(variant)) {
|
||||
base64Variant = Base64Variants.MIME;
|
||||
} else if ("mime_no_linefeeds".equals(variant)) {
|
||||
base64Variant = Base64Variants.MIME_NO_LINEFEEDS;
|
||||
} else {
|
||||
throw new MapperParsingException("Can't handle base64 [" + variant + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Metadata metadata = new Metadata();
|
||||
if (contentType != null) {
|
||||
metadata.add(Metadata.CONTENT_TYPE, contentType);
|
||||
}
|
||||
if (name != null) {
|
||||
metadata.add(Metadata.RESOURCE_NAME_KEY, name);
|
||||
}
|
||||
|
||||
String parsedContent;
|
||||
try {
|
||||
parsedContent = tika().parseToString(new FastByteArrayInputStream(content), metadata);
|
||||
} catch (TikaException e) {
|
||||
throw new MapperParsingException("Failed to extract text for [" + name + "]", e);
|
||||
}
|
||||
|
||||
jsonContext.externalValue(parsedContent);
|
||||
contentMapper.parse(jsonContext);
|
||||
|
||||
jsonContext.externalValue(metadata.get(Metadata.DATE));
|
||||
dateMapper.parse(jsonContext);
|
||||
|
||||
jsonContext.externalValue(metadata.get(Metadata.TITLE));
|
||||
titleMapper.parse(jsonContext);
|
||||
|
||||
jsonContext.externalValue(metadata.get(Metadata.AUTHOR));
|
||||
authorMapper.parse(jsonContext);
|
||||
|
||||
jsonContext.externalValue(metadata.get(Metadata.KEYWORDS));
|
||||
keywordsMapper.parse(jsonContext);
|
||||
}
|
||||
|
||||
@Override public void merge(JsonMapper mergeWith, JsonMergeContext mergeContext) throws MergeMappingException {
|
||||
// ignore this for now
|
||||
}
|
||||
|
||||
@Override public void traverse(FieldMapperListener fieldMapperListener) {
|
||||
contentMapper.traverse(fieldMapperListener);
|
||||
dateMapper.traverse(fieldMapperListener);
|
||||
titleMapper.traverse(fieldMapperListener);
|
||||
authorMapper.traverse(fieldMapperListener);
|
||||
keywordsMapper.traverse(fieldMapperListener);
|
||||
}
|
||||
|
||||
@Override public void toJson(JsonBuilder builder, Params params) throws IOException {
|
||||
builder.startObject(name);
|
||||
builder.field("type", JSON_TYPE);
|
||||
builder.field("path", pathType.name().toLowerCase());
|
||||
|
||||
builder.startObject("fields");
|
||||
contentMapper.toJson(builder, params);
|
||||
authorMapper.toJson(builder, params);
|
||||
titleMapper.toJson(builder, params);
|
||||
dateMapper.toJson(builder, params);
|
||||
keywordsMapper.toJson(builder, params);
|
||||
builder.endObject();
|
||||
|
||||
builder.endObject();
|
||||
}
|
||||
}
|
@ -17,13 +17,11 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.plugin.attachments.index.mapper;
|
||||
package org.elasticsearch.index.mapper.xcontent;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.analysis.AnalysisService;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapper;
|
||||
import org.elasticsearch.index.mapper.json.JsonDocumentMapperParser;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@ -38,17 +36,17 @@ import static org.hamcrest.Matchers.*;
|
||||
@Test
|
||||
public class SimpleAttachmentMapperTests {
|
||||
|
||||
private JsonDocumentMapperParser mapperParser;
|
||||
private XContentDocumentMapperParser mapperParser;
|
||||
|
||||
@BeforeTest public void setupMapperParser() {
|
||||
mapperParser = new JsonDocumentMapperParser(new AnalysisService(new Index("test")));
|
||||
mapperParser.putTypeParser(JsonAttachmentMapper.JSON_TYPE, new JsonAttachmentMapper.TypeParser());
|
||||
mapperParser = new XContentDocumentMapperParser(new AnalysisService(new Index("test")));
|
||||
mapperParser.putTypeParser(XContentAttachmentMapper.CONTENT_TYPE, new XContentAttachmentMapper.TypeParser());
|
||||
}
|
||||
|
||||
@Test public void testSimpleMappings() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/plugin/attachments/index/mapper/test-mapping.json");
|
||||
JsonDocumentMapper docMapper = (JsonDocumentMapper) mapperParser.parse(mapping);
|
||||
byte[] json = jsonBuilder().startObject().field("_id", 1).field("file", copyToBytesFromClasspath("/org/elasticsearch/plugin/attachments/index/mapper/testXHTML.html")).endObject().copiedBytes();
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/test-mapping.json");
|
||||
XContentDocumentMapper docMapper = (XContentDocumentMapper) mapperParser.parse(mapping);
|
||||
byte[] json = jsonBuilder().startObject().field("_id", 1).field("file", copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/testXHTML.html")).endObject().copiedBytes();
|
||||
|
||||
Document doc = docMapper.parse(json).doc();
|
||||
|
||||
@ -57,9 +55,9 @@ public class SimpleAttachmentMapperTests {
|
||||
|
||||
// re-parse it
|
||||
String builtMapping = docMapper.buildSource();
|
||||
docMapper = (JsonDocumentMapper) mapperParser.parse(builtMapping);
|
||||
docMapper = (XContentDocumentMapper) mapperParser.parse(builtMapping);
|
||||
|
||||
json = jsonBuilder().startObject().field("_id", 1).field("file", copyToBytesFromClasspath("/org/elasticsearch/plugin/attachments/index/mapper/testXHTML.html")).endObject().copiedBytes();
|
||||
json = jsonBuilder().startObject().field("_id", 1).field("file", copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/testXHTML.html")).endObject().copiedBytes();
|
||||
|
||||
doc = docMapper.parse(json).doc();
|
||||
|
@ -70,12 +70,12 @@ public class SimpleAttachmentIntegrationTests {
|
||||
}
|
||||
|
||||
@Test public void testSimpleAttachment() throws Exception {
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/plugin/attachments/index/mapper/test-mapping.json");
|
||||
String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/xcontent/test-mapping.json");
|
||||
|
||||
node.client().admin().indices().putMapping(putMappingRequest("test").source(mapping)).actionGet();
|
||||
|
||||
node.client().index(indexRequest("test").type("person")
|
||||
.source(jsonBuilder().startObject().field("file", copyToBytesFromClasspath("/org/elasticsearch/plugin/attachments/index/mapper/testXHTML.html")).endObject())).actionGet();
|
||||
.source(jsonBuilder().startObject().field("file", copyToBytesFromClasspath("/org/elasticsearch/index/mapper/xcontent/testXHTML.html")).endObject())).actionGet();
|
||||
node.client().admin().indices().refresh(refreshRequest()).actionGet();
|
||||
|
||||
CountResponse countResponse = node.client().count(countRequest("test").query(fieldQuery("file.title", "test document"))).actionGet();
|
||||
|
Loading…
x
Reference in New Issue
Block a user