From 0a3d187e6a37af8e74ae54d9263d4659d5a8aab5 Mon Sep 17 00:00:00 2001 From: kimchy Date: Sun, 17 Oct 2010 19:56:58 +0200 Subject: [PATCH] Mapper: Allow to configure `date_formats` only on the root object mapper, closes #437. --- .../index/mapper/xcontent/ObjectMapper.java | 87 ++----------------- .../mapper/xcontent/RootObjectMapper.java | 85 ++++++++++++++++-- 2 files changed, 87 insertions(+), 85 deletions(-) diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/ObjectMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/ObjectMapper.java index 0765abb04e6..5e2c115bc0f 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/ObjectMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/ObjectMapper.java @@ -23,7 +23,6 @@ import org.elasticsearch.ElasticSearchIllegalStateException; import org.elasticsearch.common.Strings; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.joda.FormatDateTimeFormatter; -import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.util.concurrent.ThreadSafe; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; @@ -53,11 +52,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { public static final boolean ENABLED = true; public static final boolean DYNAMIC = true; public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL; - public static final FormatDateTimeFormatter[] DATE_TIME_FORMATTERS = - new FormatDateTimeFormatter[]{ - DateFieldMapper.Defaults.DATE_TIME_FORMATTER, - Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd") - }; } public static class Builder extends XContentMapper.Builder { @@ -68,8 +62,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { protected ContentPath.Type pathType = Defaults.PATH_TYPE; - protected List dateTimeFormatters = newArrayList(); - protected Boolean includeInAll; protected final List mappersBuilders = newArrayList(); @@ -94,45 +86,17 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { return builder; } - public T noDateTimeFormatter() { - this.dateTimeFormatters = null; - return builder; - } - public T includeInAll(boolean includeInAll) { this.includeInAll = includeInAll; return builder; } - public T dateTimeFormatter(Iterable dateTimeFormatters) { - for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) { - this.dateTimeFormatters.add(dateTimeFormatter); - } - return builder; - } - - public T dateTimeFormatter(FormatDateTimeFormatter[] dateTimeFormatters) { - this.dateTimeFormatters.addAll(newArrayList(dateTimeFormatters)); - return builder; - } - - public T dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) { - this.dateTimeFormatters.add(dateTimeFormatter); - return builder; - } - public T add(XContentMapper.Builder builder) { mappersBuilders.add(builder); return this.builder; } @Override public Y build(BuilderContext context) { - if (dateTimeFormatters == null) { - dateTimeFormatters = newArrayList(); - } else if (dateTimeFormatters.isEmpty()) { - // add the default one - dateTimeFormatters.addAll(newArrayList(Defaults.DATE_TIME_FORMATTERS)); - } ContentPath.Type origPathType = context.path().pathType(); context.path().pathType(pathType); context.path().add(name); @@ -142,8 +106,7 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { XContentMapper mapper = builder.build(context); mappers.put(mapper.name(), mapper); } - ObjectMapper objectMapper = createMapper(name, enabled, dynamic, pathType, - dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]), mappers); + ObjectMapper objectMapper = createMapper(name, enabled, dynamic, pathType, mappers); context.path().pathType(origPathType); context.path().remove(); @@ -153,9 +116,8 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { return (Y) objectMapper; } - protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, - FormatDateTimeFormatter[] dateTimeFormatters, Map mappers) { - return new ObjectMapper(name, enabled, dynamic, pathType, dateTimeFormatters, mappers); + protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map mappers) { + return new ObjectMapper(name, enabled, dynamic, pathType, mappers); } } @@ -175,22 +137,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { if (!type.equals("object")) { throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]"); } - } else if (fieldName.equals("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.noDateTimeFormatter(); - } else { - builder.dateTimeFormatter(dateTimeFormatters); - } } else if (fieldName.equals("enabled")) { builder.enabled(nodeBooleanValue(fieldNode)); } else if (fieldName.equals("path")) { @@ -251,8 +197,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { private final ContentPath.Type pathType; - private final FormatDateTimeFormatter[] dateTimeFormatters; - private Boolean includeInAll; private volatile ImmutableMap mappers = ImmutableMap.of(); @@ -263,22 +207,16 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { this(name, Defaults.ENABLED, Defaults.DYNAMIC, Defaults.PATH_TYPE); } + protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType) { - this(name, enabled, dynamic, pathType, Defaults.DATE_TIME_FORMATTERS); + this(name, enabled, dynamic, pathType, null); } - protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, - FormatDateTimeFormatter[] dateTimeFormatters) { - this(name, enabled, dynamic, pathType, dateTimeFormatters, null); - } - - ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, - FormatDateTimeFormatter[] dateTimeFormatters, Map mappers) { + ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map mappers) { this.name = name; this.enabled = enabled; this.dynamic = dynamic; this.pathType = pathType; - this.dateTimeFormatters = dateTimeFormatters; if (mappers != null) { this.mappers = copyOf(mappers); } @@ -385,8 +323,7 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { BuilderContext builderContext = new BuilderContext(context.path()); XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object"); if (builder == null) { - builder = XContentMapperBuilders.object(currentFieldName).enabled(true) - .dynamic(dynamic).pathType(pathType).dateTimeFormatter(dateTimeFormatters); + builder = XContentMapperBuilders.object(currentFieldName).enabled(true).dynamic(dynamic).pathType(pathType); } objectMapper = builder.build(builderContext); putMapper(objectMapper); @@ -452,7 +389,7 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { boolean isDate = false; // a safe check since "1" gets parsed as well if (text.contains(":") || text.contains("-") || text.contains("/")) { - for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) { + for (FormatDateTimeFormatter dateTimeFormatter : context.root().dateTimeFormatters()) { try { dateTimeFormatter.parser().parseMillis(text); XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "date"); @@ -605,14 +542,6 @@ public class ObjectMapper implements XContentMapper, IncludeInAllMapper { doXContent(builder, params); - if (dateTimeFormatters.length > 0) { - builder.startArray("date_formats"); - for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) { - builder.value(dateTimeFormatter.format()); - } - builder.endArray(); - } - // check internal mappers first (this is only relevant for root object) for (XContentMapper mapper : mappers.values()) { if (mapper instanceof InternalMapper) { diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/RootObjectMapper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/RootObjectMapper.java index 3c8103da740..e319f44b208 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/RootObjectMapper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/RootObjectMapper.java @@ -21,6 +21,7 @@ package org.elasticsearch.index.mapper.xcontent; import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.joda.FormatDateTimeFormatter; +import org.elasticsearch.common.joda.Joda; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.index.mapper.MapperParsingException; @@ -30,21 +31,54 @@ import java.util.List; import java.util.Map; import static org.elasticsearch.common.collect.Lists.*; +import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*; /** * @author kimchy (shay.banon) */ public class RootObjectMapper extends ObjectMapper { + public static class Defaults { + public static final FormatDateTimeFormatter[] DATE_TIME_FORMATTERS = + new FormatDateTimeFormatter[]{ + DateFieldMapper.Defaults.DATE_TIME_FORMATTER, + Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd") + }; + } + public static class Builder extends ObjectMapper.Builder { protected final List dynamicTemplates = newArrayList(); + protected List dateTimeFormatters = newArrayList(); + public Builder(String name) { super(name); this.builder = this; } + public Builder noDateTimeFormatter() { + this.dateTimeFormatters = null; + return builder; + } + + public Builder dateTimeFormatter(Iterable dateTimeFormatters) { + for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) { + this.dateTimeFormatters.add(dateTimeFormatter); + } + return builder; + } + + public Builder dateTimeFormatter(FormatDateTimeFormatter[] dateTimeFormatters) { + this.dateTimeFormatters.addAll(newArrayList(dateTimeFormatters)); + return builder; + } + + public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) { + this.dateTimeFormatters.add(dateTimeFormatter); + return builder; + } + public Builder add(DynamicTemplate dynamicTemplate) { this.dynamicTemplates.add(dynamicTemplate); return this; @@ -58,8 +92,16 @@ public class RootObjectMapper extends ObjectMapper { } - @Override protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, FormatDateTimeFormatter[] dateTimeFormatters, Map mappers) { - return new RootObjectMapper(name, enabled, dynamic, pathType, dateTimeFormatters, mappers, dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()])); + @Override protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map mappers) { + if (dateTimeFormatters == null) { + dateTimeFormatters = newArrayList(); + } else if (dateTimeFormatters.isEmpty()) { + // add the default one + dateTimeFormatters.addAll(newArrayList(Defaults.DATE_TIME_FORMATTERS)); + } + return new RootObjectMapper(name, enabled, dynamic, pathType, mappers, + dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]), + dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()])); } } @@ -70,7 +112,23 @@ public class RootObjectMapper extends ObjectMapper { } @Override protected void processField(ObjectMapper.Builder builder, String fieldName, Object fieldNode) { - if (fieldName.equals("dynamic_templates")) { + if (fieldName.equals("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).noDateTimeFormatter(); + } else { + ((Builder) builder).dateTimeFormatter(dateTimeFormatters); + } + } else if (fieldName.equals("dynamic_templates")) { // "dynamic_templates" : [ // { // "template_1" : { @@ -93,12 +151,19 @@ public class RootObjectMapper extends ObjectMapper { } } + private final FormatDateTimeFormatter[] dateTimeFormatters; + private volatile DynamicTemplate dynamicTemplates[]; - RootObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, - FormatDateTimeFormatter[] dateTimeFormatters, Map mappers, DynamicTemplate dynamicTemplates[]) { - super(name, enabled, dynamic, pathType, dateTimeFormatters, mappers); + RootObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map mappers, + FormatDateTimeFormatter[] dateTimeFormatters, DynamicTemplate dynamicTemplates[]) { + super(name, enabled, dynamic, pathType, mappers); this.dynamicTemplates = dynamicTemplates; + this.dateTimeFormatters = dateTimeFormatters; + } + + public FormatDateTimeFormatter[] dateTimeFormatters() { + return dateTimeFormatters; } public XContentMapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType) { @@ -141,6 +206,14 @@ public class RootObjectMapper extends ObjectMapper { } @Override protected void doXContent(XContentBuilder builder, Params params) throws IOException { + if (dateTimeFormatters.length > 0) { + builder.startArray("date_formats"); + for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) { + builder.value(dateTimeFormatter.format()); + } + builder.endArray(); + } + if (dynamicTemplates != null && dynamicTemplates.length > 0) { builder.startArray("dynamic_templates"); for (DynamicTemplate dynamicTemplate : dynamicTemplates) {