Skip to content

Commit 0a3d187

Browse files
committed
Mapper: Allow to configure date_formats only on the root object mapper, closes elastic#437.
1 parent 69ecf8b commit 0a3d187

File tree

2 files changed

+87
-85
lines changed

2 files changed

+87
-85
lines changed

modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/ObjectMapper.java

Lines changed: 8 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.elasticsearch.common.Strings;
2424
import org.elasticsearch.common.collect.ImmutableMap;
2525
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
26-
import org.elasticsearch.common.joda.Joda;
2726
import org.elasticsearch.common.util.concurrent.ThreadSafe;
2827
import org.elasticsearch.common.xcontent.XContentBuilder;
2928
import org.elasticsearch.common.xcontent.XContentParser;
@@ -53,11 +52,6 @@ public static class Defaults {
5352
public static final boolean ENABLED = true;
5453
public static final boolean DYNAMIC = true;
5554
public static final ContentPath.Type PATH_TYPE = ContentPath.Type.FULL;
56-
public static final FormatDateTimeFormatter[] DATE_TIME_FORMATTERS =
57-
new FormatDateTimeFormatter[]{
58-
DateFieldMapper.Defaults.DATE_TIME_FORMATTER,
59-
Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd")
60-
};
6155
}
6256

6357
public static class Builder<T extends Builder, Y extends ObjectMapper> extends XContentMapper.Builder<T, Y> {
@@ -68,8 +62,6 @@ public static class Builder<T extends Builder, Y extends ObjectMapper> extends X
6862

6963
protected ContentPath.Type pathType = Defaults.PATH_TYPE;
7064

71-
protected List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
72-
7365
protected Boolean includeInAll;
7466

7567
protected final List<XContentMapper.Builder> mappersBuilders = newArrayList();
@@ -94,45 +86,17 @@ public T pathType(ContentPath.Type pathType) {
9486
return builder;
9587
}
9688

97-
public T noDateTimeFormatter() {
98-
this.dateTimeFormatters = null;
99-
return builder;
100-
}
101-
10289
public T includeInAll(boolean includeInAll) {
10390
this.includeInAll = includeInAll;
10491
return builder;
10592
}
10693

107-
public T dateTimeFormatter(Iterable<FormatDateTimeFormatter> dateTimeFormatters) {
108-
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
109-
this.dateTimeFormatters.add(dateTimeFormatter);
110-
}
111-
return builder;
112-
}
113-
114-
public T dateTimeFormatter(FormatDateTimeFormatter[] dateTimeFormatters) {
115-
this.dateTimeFormatters.addAll(newArrayList(dateTimeFormatters));
116-
return builder;
117-
}
118-
119-
public T dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
120-
this.dateTimeFormatters.add(dateTimeFormatter);
121-
return builder;
122-
}
123-
12494
public T add(XContentMapper.Builder builder) {
12595
mappersBuilders.add(builder);
12696
return this.builder;
12797
}
12898

12999
@Override public Y build(BuilderContext context) {
130-
if (dateTimeFormatters == null) {
131-
dateTimeFormatters = newArrayList();
132-
} else if (dateTimeFormatters.isEmpty()) {
133-
// add the default one
134-
dateTimeFormatters.addAll(newArrayList(Defaults.DATE_TIME_FORMATTERS));
135-
}
136100
ContentPath.Type origPathType = context.path().pathType();
137101
context.path().pathType(pathType);
138102
context.path().add(name);
@@ -142,8 +106,7 @@ public T add(XContentMapper.Builder builder) {
142106
XContentMapper mapper = builder.build(context);
143107
mappers.put(mapper.name(), mapper);
144108
}
145-
ObjectMapper objectMapper = createMapper(name, enabled, dynamic, pathType,
146-
dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]), mappers);
109+
ObjectMapper objectMapper = createMapper(name, enabled, dynamic, pathType, mappers);
147110

148111
context.path().pathType(origPathType);
149112
context.path().remove();
@@ -153,9 +116,8 @@ public T add(XContentMapper.Builder builder) {
153116
return (Y) objectMapper;
154117
}
155118

156-
protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
157-
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
158-
return new ObjectMapper(name, enabled, dynamic, pathType, dateTimeFormatters, mappers);
119+
protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map<String, XContentMapper> mappers) {
120+
return new ObjectMapper(name, enabled, dynamic, pathType, mappers);
159121
}
160122
}
161123

@@ -175,22 +137,6 @@ public static class TypeParser implements XContentMapper.TypeParser {
175137
if (!type.equals("object")) {
176138
throw new MapperParsingException("Trying to parse an object but has a different type [" + type + "] for [" + name + "]");
177139
}
178-
} else if (fieldName.equals("date_formats")) {
179-
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
180-
if (fieldNode instanceof List) {
181-
for (Object node1 : (List) fieldNode) {
182-
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, node1));
183-
}
184-
} else if ("none".equals(fieldNode.toString())) {
185-
dateTimeFormatters = null;
186-
} else {
187-
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, fieldNode));
188-
}
189-
if (dateTimeFormatters == null) {
190-
builder.noDateTimeFormatter();
191-
} else {
192-
builder.dateTimeFormatter(dateTimeFormatters);
193-
}
194140
} else if (fieldName.equals("enabled")) {
195141
builder.enabled(nodeBooleanValue(fieldNode));
196142
} else if (fieldName.equals("path")) {
@@ -251,8 +197,6 @@ protected void processField(Builder builder, String fieldName, Object fieldNode)
251197

252198
private final ContentPath.Type pathType;
253199

254-
private final FormatDateTimeFormatter[] dateTimeFormatters;
255-
256200
private Boolean includeInAll;
257201

258202
private volatile ImmutableMap<String, XContentMapper> mappers = ImmutableMap.of();
@@ -263,22 +207,16 @@ protected ObjectMapper(String name) {
263207
this(name, Defaults.ENABLED, Defaults.DYNAMIC, Defaults.PATH_TYPE);
264208
}
265209

266-
protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType) {
267-
this(name, enabled, dynamic, pathType, Defaults.DATE_TIME_FORMATTERS);
268-
}
269210

270-
protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
271-
FormatDateTimeFormatter[] dateTimeFormatters) {
272-
this(name, enabled, dynamic, pathType, dateTimeFormatters, null);
211+
protected ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType) {
212+
this(name, enabled, dynamic, pathType, null);
273213
}
274214

275-
ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
276-
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
215+
ObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map<String, XContentMapper> mappers) {
277216
this.name = name;
278217
this.enabled = enabled;
279218
this.dynamic = dynamic;
280219
this.pathType = pathType;
281-
this.dateTimeFormatters = dateTimeFormatters;
282220
if (mappers != null) {
283221
this.mappers = copyOf(mappers);
284222
}
@@ -385,8 +323,7 @@ private void serializeObject(ParseContext context, String currentFieldName) thro
385323
BuilderContext builderContext = new BuilderContext(context.path());
386324
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "object");
387325
if (builder == null) {
388-
builder = XContentMapperBuilders.object(currentFieldName).enabled(true)
389-
.dynamic(dynamic).pathType(pathType).dateTimeFormatter(dateTimeFormatters);
326+
builder = XContentMapperBuilders.object(currentFieldName).enabled(true).dynamic(dynamic).pathType(pathType);
390327
}
391328
objectMapper = builder.build(builderContext);
392329
putMapper(objectMapper);
@@ -452,7 +389,7 @@ private void serializeValue(final ParseContext context, String currentFieldName,
452389
boolean isDate = false;
453390
// a safe check since "1" gets parsed as well
454391
if (text.contains(":") || text.contains("-") || text.contains("/")) {
455-
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
392+
for (FormatDateTimeFormatter dateTimeFormatter : context.root().dateTimeFormatters()) {
456393
try {
457394
dateTimeFormatter.parser().parseMillis(text);
458395
XContentMapper.Builder builder = context.root().findTemplateBuilder(context, currentFieldName, "date");
@@ -605,14 +542,6 @@ public void toXContent(XContentBuilder builder, Params params, XContentMapper...
605542

606543
doXContent(builder, params);
607544

608-
if (dateTimeFormatters.length > 0) {
609-
builder.startArray("date_formats");
610-
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
611-
builder.value(dateTimeFormatter.format());
612-
}
613-
builder.endArray();
614-
}
615-
616545
// check internal mappers first (this is only relevant for root object)
617546
for (XContentMapper mapper : mappers.values()) {
618547
if (mapper instanceof InternalMapper) {

modules/elasticsearch/src/main/java/org/elasticsearch/index/mapper/xcontent/RootObjectMapper.java

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.elasticsearch.common.collect.Lists;
2323
import org.elasticsearch.common.joda.FormatDateTimeFormatter;
24+
import org.elasticsearch.common.joda.Joda;
2425
import org.elasticsearch.common.xcontent.XContentBuilder;
2526
import org.elasticsearch.index.mapper.MapperParsingException;
2627

@@ -30,21 +31,54 @@
3031
import java.util.Map;
3132

3233
import static org.elasticsearch.common.collect.Lists.*;
34+
import static org.elasticsearch.index.mapper.xcontent.XContentTypeParsers.*;
3335

3436
/**
3537
* @author kimchy (shay.banon)
3638
*/
3739
public class RootObjectMapper extends ObjectMapper {
3840

41+
public static class Defaults {
42+
public static final FormatDateTimeFormatter[] DATE_TIME_FORMATTERS =
43+
new FormatDateTimeFormatter[]{
44+
DateFieldMapper.Defaults.DATE_TIME_FORMATTER,
45+
Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd")
46+
};
47+
}
48+
3949
public static class Builder extends ObjectMapper.Builder<Builder, RootObjectMapper> {
4050

4151
protected final List<DynamicTemplate> dynamicTemplates = newArrayList();
4252

53+
protected List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
54+
4355
public Builder(String name) {
4456
super(name);
4557
this.builder = this;
4658
}
4759

60+
public Builder noDateTimeFormatter() {
61+
this.dateTimeFormatters = null;
62+
return builder;
63+
}
64+
65+
public Builder dateTimeFormatter(Iterable<FormatDateTimeFormatter> dateTimeFormatters) {
66+
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
67+
this.dateTimeFormatters.add(dateTimeFormatter);
68+
}
69+
return builder;
70+
}
71+
72+
public Builder dateTimeFormatter(FormatDateTimeFormatter[] dateTimeFormatters) {
73+
this.dateTimeFormatters.addAll(newArrayList(dateTimeFormatters));
74+
return builder;
75+
}
76+
77+
public Builder dateTimeFormatter(FormatDateTimeFormatter dateTimeFormatter) {
78+
this.dateTimeFormatters.add(dateTimeFormatter);
79+
return builder;
80+
}
81+
4882
public Builder add(DynamicTemplate dynamicTemplate) {
4983
this.dynamicTemplates.add(dynamicTemplate);
5084
return this;
@@ -58,8 +92,16 @@ public Builder add(DynamicTemplate... dynamicTemplate) {
5892
}
5993

6094

61-
@Override protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers) {
62-
return new RootObjectMapper(name, enabled, dynamic, pathType, dateTimeFormatters, mappers, dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]));
95+
@Override protected ObjectMapper createMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map<String, XContentMapper> mappers) {
96+
if (dateTimeFormatters == null) {
97+
dateTimeFormatters = newArrayList();
98+
} else if (dateTimeFormatters.isEmpty()) {
99+
// add the default one
100+
dateTimeFormatters.addAll(newArrayList(Defaults.DATE_TIME_FORMATTERS));
101+
}
102+
return new RootObjectMapper(name, enabled, dynamic, pathType, mappers,
103+
dateTimeFormatters.toArray(new FormatDateTimeFormatter[dateTimeFormatters.size()]),
104+
dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]));
63105
}
64106
}
65107

@@ -70,7 +112,23 @@ public static class TypeParser extends ObjectMapper.TypeParser {
70112
}
71113

72114
@Override protected void processField(ObjectMapper.Builder builder, String fieldName, Object fieldNode) {
73-
if (fieldName.equals("dynamic_templates")) {
115+
if (fieldName.equals("date_formats")) {
116+
List<FormatDateTimeFormatter> dateTimeFormatters = newArrayList();
117+
if (fieldNode instanceof List) {
118+
for (Object node1 : (List) fieldNode) {
119+
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, node1));
120+
}
121+
} else if ("none".equals(fieldNode.toString())) {
122+
dateTimeFormatters = null;
123+
} else {
124+
dateTimeFormatters.add(parseDateTimeFormatter(fieldName, fieldNode));
125+
}
126+
if (dateTimeFormatters == null) {
127+
((Builder) builder).noDateTimeFormatter();
128+
} else {
129+
((Builder) builder).dateTimeFormatter(dateTimeFormatters);
130+
}
131+
} else if (fieldName.equals("dynamic_templates")) {
74132
// "dynamic_templates" : [
75133
// {
76134
// "template_1" : {
@@ -93,12 +151,19 @@ public static class TypeParser extends ObjectMapper.TypeParser {
93151
}
94152
}
95153

154+
private final FormatDateTimeFormatter[] dateTimeFormatters;
155+
96156
private volatile DynamicTemplate dynamicTemplates[];
97157

98-
RootObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType,
99-
FormatDateTimeFormatter[] dateTimeFormatters, Map<String, XContentMapper> mappers, DynamicTemplate dynamicTemplates[]) {
100-
super(name, enabled, dynamic, pathType, dateTimeFormatters, mappers);
158+
RootObjectMapper(String name, boolean enabled, boolean dynamic, ContentPath.Type pathType, Map<String, XContentMapper> mappers,
159+
FormatDateTimeFormatter[] dateTimeFormatters, DynamicTemplate dynamicTemplates[]) {
160+
super(name, enabled, dynamic, pathType, mappers);
101161
this.dynamicTemplates = dynamicTemplates;
162+
this.dateTimeFormatters = dateTimeFormatters;
163+
}
164+
165+
public FormatDateTimeFormatter[] dateTimeFormatters() {
166+
return dateTimeFormatters;
102167
}
103168

104169
public XContentMapper.Builder findTemplateBuilder(ParseContext context, String name, String dynamicType) {
@@ -141,6 +206,14 @@ public DynamicTemplate findTemplate(String name, String dynamicType) {
141206
}
142207

143208
@Override protected void doXContent(XContentBuilder builder, Params params) throws IOException {
209+
if (dateTimeFormatters.length > 0) {
210+
builder.startArray("date_formats");
211+
for (FormatDateTimeFormatter dateTimeFormatter : dateTimeFormatters) {
212+
builder.value(dateTimeFormatter.format());
213+
}
214+
builder.endArray();
215+
}
216+
144217
if (dynamicTemplates != null && dynamicTemplates.length > 0) {
145218
builder.startArray("dynamic_templates");
146219
for (DynamicTemplate dynamicTemplate : dynamicTemplates) {

0 commit comments

Comments
 (0)