start abstaction of xconten over json

This commit is contained in:
kimchy 2010-04-28 21:29:30 +03:00
parent c48851f49c
commit cdc33e18f3
81 changed files with 3118 additions and 1383 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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'

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
}
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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());

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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 + "]");
}

View File

@ -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
}
}

View File

@ -0,0 +1,4 @@
{
"_default_" : {
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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));
}
}

View File

@ -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();
}
}

View File

@ -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 + "]");
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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));

View File

@ -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");

View File

@ -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());

View File

@ -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));

View File

@ -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 {

View File

@ -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();
}
}

View File

@ -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());
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();

View File

@ -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();