
org.elasticsearch.index.mapper.object.RootObjectMapper Maven / Gradle / Ivy
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch 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.object;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.mapper.*;
import org.elasticsearch.index.mapper.core.DateFieldMapper;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.collect.Lists.newArrayList;
import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue;
import static org.elasticsearch.index.mapper.core.TypeParsers.parseDateTimeFormatter;
/**
*
*/
public class RootObjectMapper extends ObjectMapper {
public static class Defaults {
public static final FormatDateTimeFormatter[] DYNAMIC_DATE_TIME_FORMATTERS =
new FormatDateTimeFormatter[]{
DateFieldMapper.Defaults.DATE_TIME_FORMATTER,
Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd")
};
public static final boolean DATE_DETECTION = true;
public static final boolean NUMERIC_DETECTION = false;
}
public static class Builder extends ObjectMapper.Builder {
protected final List dynamicTemplates = newArrayList();
// we use this to filter out seen date formats, because we might get duplicates during merging
protected Set seenDateFormats = Sets.newHashSet();
protected List dynamicDateTimeFormatters = newArrayList();
protected boolean dateDetection = Defaults.DATE_DETECTION;
protected boolean numericDetection = Defaults.NUMERIC_DETECTION;
public Builder(String name) {
super(name);
this.builder = this;
}
public Builder noDynamicDateTimeFormatter() {
this.dynamicDateTimeFormatters = null;
return builder;
}
public Builder dynamicDateTimeFormatter(Iterable dateTimeFormatters) {
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
if (!seenDateFormats.contains(dateTimeFormatter.format())) {
seenDateFormats.add(dateTimeFormatter.format());
this.dynamicDateTimeFormatters.add(dateTimeFormatter);
}
}
return builder;
}
public Builder add(DynamicTemplate dynamicTemplate) {
this.dynamicTemplates.add(dynamicTemplate);
return this;
}
public Builder add(DynamicTemplate... dynamicTemplate) {
for (DynamicTemplate template : dynamicTemplate) {
this.dynamicTemplates.add(template);
}
return this;
}
@Override
protected ObjectMapper createMapper(String name, String fullPath, boolean enabled, Nested nested, Dynamic dynamic, ContentPath.Type pathType, Map mappers) {
assert !nested.isNested();
FormatDateTimeFormatter[] dates = null;
if (dynamicDateTimeFormatters == null) {
dates = new FormatDateTimeFormatter[0];
} else if (dynamicDateTimeFormatters.isEmpty()) {
// add the default one
dates = Defaults.DYNAMIC_DATE_TIME_FORMATTERS;
} else {
dates = dynamicDateTimeFormatters.toArray(new FormatDateTimeFormatter[dynamicDateTimeFormatters.size()]);
}
return new RootObjectMapper(name, enabled, dynamic, pathType, mappers,
dates,
dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]),
dateDetection, numericDetection);
}
}
public static class TypeParser extends ObjectMapper.TypeParser {
@Override
protected ObjectMapper.Builder createBuilder(String name) {
return new Builder(name);
}
@Override
protected void processField(ObjectMapper.Builder builder, String fieldName, Object fieldNode) {
if (fieldName.equals("date_formats") || fieldName.equals("dynamic_date_formats")) {
List dateTimeFormatters = newArrayList();
if (fieldNode instanceof List) {
for (Object node1 : (List) fieldNode) {
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, node1));
}
} else if ("none".equals(fieldNode.toString())) {
dateTimeFormatters = null;
} else {
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, fieldNode));
}
if (dateTimeFormatters == null) {
((Builder) builder).noDynamicDateTimeFormatter();
} else {
((Builder) builder).dynamicDateTimeFormatter(dateTimeFormatters);
}
} else if (fieldName.equals("dynamic_templates")) {
// "dynamic_templates" : [
// {
// "template_1" : {
// "match" : "*_test",
// "match_mapping_type" : "string",
// "mapping" : { "type" : "string", "store" : "yes" }
// }
// }
// ]
List tmplNodes = (List) fieldNode;
for (Object tmplNode : tmplNodes) {
Map tmpl = (Map) tmplNode;
if (tmpl.size() != 1) {
throw new MapperParsingException("A dynamic template must be defined with a name");
}
Map.Entry entry = tmpl.entrySet().iterator().next();
((Builder) builder).add(DynamicTemplate.parse(entry.getKey(), (Map) entry.getValue()));
}
} else if (fieldName.equals("date_detection")) {
((Builder) builder).dateDetection = nodeBooleanValue(fieldNode);
} else if (fieldName.equals("numeric_detection")) {
((Builder) builder).numericDetection = nodeBooleanValue(fieldNode);
}
}
}
private final FormatDateTimeFormatter[] dynamicDateTimeFormatters;
private final boolean dateDetection;
private final boolean numericDetection;
private volatile DynamicTemplate dynamicTemplates[];
RootObjectMapper(String name, boolean enabled, Dynamic dynamic, ContentPath.Type pathType, Map mappers,
FormatDateTimeFormatter[] dynamicDateTimeFormatters, DynamicTemplate dynamicTemplates[], boolean dateDetection, boolean numericDetection) {
super(name, name, enabled, Nested.NO, dynamic, pathType, mappers);
this.dynamicTemplates = dynamicTemplates;
this.dynamicDateTimeFormatters = dynamicDateTimeFormatters;
this.dateDetection = dateDetection;
this.numericDetection = numericDetection;
}
public boolean dateDetection() {
return this.dateDetection;
}
public boolean numericDetection() {
return this.numericDetection;
}
public FormatDateTimeFormatter[] dynamicDateTimeFormatters() {
return dynamicDateTimeFormatters;
}
public Mapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType) {
return findTemplateBuilder(context, name, dynamicType, dynamicType);
}
public Mapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType, String matchType) {
DynamicTemplate dynamicTemplate = findTemplate(context.path(), name, matchType);
if (dynamicTemplate == null) {
return null;
}
Mapper.TypeParser.ParserContext parserContext = context.docMapperParser().parserContext();
String mappingType = dynamicTemplate.mappingType(dynamicType);
Mapper.TypeParser typeParser = parserContext.typeParser(mappingType);
if (typeParser == null) {
throw new MapperParsingException("failed to find type parsed [" + mappingType + "] for [" + name + "]");
}
return typeParser.parse(name, dynamicTemplate.mappingForName(name, dynamicType), parserContext);
}
public DynamicTemplate findTemplate(ContentPath path, String name, String matchType) {
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {
if (dynamicTemplate.match(path, name, matchType)) {
return dynamicTemplate;
}
}
return null;
}
@Override
protected boolean allowValue() {
return true;
}
@Override
protected void doMerge(ObjectMapper mergeWith, MergeContext mergeContext) {
RootObjectMapper mergeWithObject = (RootObjectMapper) mergeWith;
if (!mergeContext.mergeFlags().simulate()) {
// merge them
List mergedTemplates = Lists.newArrayList(Arrays.asList(this.dynamicTemplates));
for (DynamicTemplate template : mergeWithObject.dynamicTemplates) {
boolean replaced = false;
for (int i = 0; i < mergedTemplates.size(); i++) {
if (mergedTemplates.get(i).name().equals(template.name())) {
mergedTemplates.set(i, template);
replaced = true;
}
}
if (!replaced) {
mergedTemplates.add(template);
}
}
this.dynamicTemplates = mergedTemplates.toArray(new DynamicTemplate[mergedTemplates.size()]);
}
}
@Override
protected void doXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
if (dynamicDateTimeFormatters != Defaults.DYNAMIC_DATE_TIME_FORMATTERS) {
if (dynamicDateTimeFormatters.length > 0) {
builder.startArray("dynamic_date_formats");
for (FormatDateTimeFormatter dateTimeFormatter : dynamicDateTimeFormatters) {
builder.value(dateTimeFormatter.format());
}
builder.endArray();
}
}
if (dynamicTemplates != null && dynamicTemplates.length > 0) {
builder.startArray("dynamic_templates");
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {
builder.startObject();
builder.field(dynamicTemplate.name());
builder.map(dynamicTemplate.conf());
builder.endObject();
}
builder.endArray();
}
if (dateDetection != Defaults.DATE_DETECTION) {
builder.field("date_detection", dateDetection);
}
if (numericDetection != Defaults.NUMERIC_DETECTION) {
builder.field("numeric_detection", numericDetection);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy