2020package org .elasticsearch .index .mapper .internal ;
2121
2222import com .google .common .collect .UnmodifiableIterator ;
23-
2423import org .apache .lucene .document .Field ;
2524import org .apache .lucene .document .FieldType ;
2625import org .apache .lucene .document .SortedSetDocValuesField ;
3029import org .elasticsearch .ElasticsearchIllegalArgumentException ;
3130import org .elasticsearch .Version ;
3231import org .elasticsearch .common .Nullable ;
32+ import org .elasticsearch .common .Strings ;
3333import org .elasticsearch .common .lucene .Lucene ;
3434import org .elasticsearch .common .settings .Settings ;
3535import org .elasticsearch .common .xcontent .XContentBuilder ;
36- import org .elasticsearch .common .xcontent .XContentFactory ;
3736import org .elasticsearch .index .fielddata .FieldDataType ;
3837import org .elasticsearch .index .mapper .InternalMapper ;
3938import org .elasticsearch .index .mapper .Mapper ;
4039import org .elasticsearch .index .mapper .MapperParsingException ;
40+ import org .elasticsearch .index .mapper .MergeContext ;
41+ import org .elasticsearch .index .mapper .MergeMappingException ;
4142import org .elasticsearch .index .mapper .ParseContext ;
4243import org .elasticsearch .index .mapper .RootMapper ;
4344import org .elasticsearch .index .mapper .core .AbstractFieldMapper ;
4849import java .util .List ;
4950import java .util .Map ;
5051
52+ import static org .elasticsearch .common .xcontent .support .XContentMapValues .nodeBooleanValue ;
5153import static org .elasticsearch .index .mapper .MapperBuilders .fieldNames ;
5254import static org .elasticsearch .index .mapper .core .TypeParsers .parseField ;
5355
@@ -65,79 +67,83 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper<String> implement
6567
6668 public static class Defaults extends AbstractFieldMapper .Defaults {
6769 public static final String NAME = FieldNamesFieldMapper .NAME ;
68- public static final String INDEX_NAME = FieldNamesFieldMapper . NAME ;
69-
70+
71+ public static final EnabledAttributeMapper ENABLED_STATE = EnabledAttributeMapper . UNSET_ENABLED ;
7072 public static final FieldType FIELD_TYPE = new FieldType (AbstractFieldMapper .Defaults .FIELD_TYPE );
71- // TODO: this field should be removed?
72- public static final FieldType FIELD_TYPE_PRE_1_3_0 ;
7373
7474 static {
7575 FIELD_TYPE .setIndexOptions (IndexOptions .DOCS );
7676 FIELD_TYPE .setTokenized (false );
7777 FIELD_TYPE .setStored (false );
7878 FIELD_TYPE .setOmitNorms (true );
7979 FIELD_TYPE .freeze ();
80- FIELD_TYPE_PRE_1_3_0 = new FieldType (FIELD_TYPE );
81- FIELD_TYPE_PRE_1_3_0 .setIndexOptions (IndexOptions .NONE );
82- FIELD_TYPE_PRE_1_3_0 .freeze ();
8380 }
8481 }
8582
8683 public static class Builder extends AbstractFieldMapper .Builder <Builder , FieldNamesFieldMapper > {
87-
88- private boolean indexIsExplicit ;
84+ private EnabledAttributeMapper enabledState = Defaults .ENABLED_STATE ;
8985
9086 public Builder () {
9187 super (Defaults .NAME , new FieldType (Defaults .FIELD_TYPE ));
92- indexName = Defaults .INDEX_NAME ;
88+ indexName = Defaults .NAME ;
9389 }
9490
9591 @ Override
9692 public Builder index (boolean index ) {
97- indexIsExplicit = true ;
93+ enabled ( index ) ;
9894 return super .index (index );
9995 }
96+
97+ public Builder enabled (boolean enabled ) {
98+ this .enabledState = enabled ? EnabledAttributeMapper .ENABLED : EnabledAttributeMapper .DISABLED ;
99+ return this ;
100+ }
100101
101102 @ Override
102103 public FieldNamesFieldMapper build (BuilderContext context ) {
103- if ((context .indexCreatedVersion () == null || context .indexCreatedVersion ().before (Version .V_1_3_0 )) && !indexIsExplicit ) {
104- fieldType .setIndexOptions (IndexOptions .NONE );
105- }
106- return new FieldNamesFieldMapper (name , indexName , boost , fieldType , fieldDataSettings , context .indexSettings ());
104+ return new FieldNamesFieldMapper (name , indexName , boost , fieldType , enabledState , fieldDataSettings , context .indexSettings ());
107105 }
108106 }
109107
110108 public static class TypeParser implements Mapper .TypeParser {
111109 @ Override
112110 public Mapper .Builder parse (String name , Map <String , Object > node , ParserContext parserContext ) throws MapperParsingException {
113- if (parserContext .indexVersionCreated ().onOrAfter (Version .V_1_3_0 )) {
114- FieldNamesFieldMapper .Builder builder = fieldNames ();
115- parseField (builder , builder .name , node , parserContext );
116- return builder ;
117- } else {
118- throw new ElasticsearchIllegalArgumentException ("type=" +CONTENT_TYPE +" is not supported on indices created before version 1.3.0 is your cluster running multiple datanode versions?" );
111+ if (parserContext .indexVersionCreated ().before (Version .V_1_3_0 )) {
112+ throw new ElasticsearchIllegalArgumentException ("type=" +CONTENT_TYPE +" is not supported on indices created before version 1.3.0. Is your cluster running multiple datanode versions?" );
119113 }
114+
115+ FieldNamesFieldMapper .Builder builder = fieldNames ();
116+ parseField (builder , builder .name , node , parserContext );
117+
118+ for (Iterator <Map .Entry <String , Object >> iterator = node .entrySet ().iterator (); iterator .hasNext ();) {
119+ Map .Entry <String , Object > entry = iterator .next ();
120+ String fieldName = Strings .toUnderscoreCase (entry .getKey ());
121+ Object fieldNode = entry .getValue ();
122+ if (fieldName .equals ("enabled" )) {
123+ builder .enabled (nodeBooleanValue (fieldNode ));
124+ iterator .remove ();
125+ }
126+ }
127+ return builder ;
120128 }
121129 }
122130
123131 private final FieldType defaultFieldType ;
124-
125- private static FieldType defaultFieldType (Settings indexSettings ) {
126- return indexSettings != null && Version .indexCreated (indexSettings ).onOrAfter (Version .V_1_3_0 ) ? Defaults .FIELD_TYPE : Defaults .FIELD_TYPE_PRE_1_3_0 ;
127- }
132+ private EnabledAttributeMapper enabledState ;
128133
129134 public FieldNamesFieldMapper (Settings indexSettings ) {
130- this (Defaults .NAME , Defaults .INDEX_NAME , indexSettings );
131- }
132-
133- protected FieldNamesFieldMapper (String name , String indexName , Settings indexSettings ) {
134- this (name , indexName , Defaults .BOOST , new FieldType (defaultFieldType (indexSettings )), null , indexSettings );
135+ this (Defaults .NAME , Defaults .NAME , Defaults .BOOST , new FieldType (Defaults .FIELD_TYPE ), Defaults .ENABLED_STATE , null , indexSettings );
135136 }
136137
137- public FieldNamesFieldMapper (String name , String indexName , float boost , FieldType fieldType , @ Nullable Settings fieldDataSettings , Settings indexSettings ) {
138+ public FieldNamesFieldMapper (String name , String indexName , float boost , FieldType fieldType , EnabledAttributeMapper enabledState , @ Nullable Settings fieldDataSettings , Settings indexSettings ) {
138139 super (new Names (name , indexName , indexName , name ), boost , fieldType , null , Lucene .KEYWORD_ANALYZER ,
139140 Lucene .KEYWORD_ANALYZER , null , null , fieldDataSettings , indexSettings );
140- this .defaultFieldType = defaultFieldType (indexSettings );
141+ this .defaultFieldType = Defaults .FIELD_TYPE ;
142+ this .enabledState = enabledState ;
143+ }
144+
145+ public boolean enabled () {
146+ return enabledState .enabled ;
141147 }
142148
143149 @ Override
@@ -216,7 +222,7 @@ public String next() {
216222
217223 @ Override
218224 protected void parseCreateField (ParseContext context , List <Field > fields ) throws IOException {
219- if (fieldType . indexOptions () == IndexOptions . NONE && ! fieldType . stored () && ! hasDocValues () ) {
225+ if (enabledState . enabled == false ) {
220226 return ;
221227 }
222228 for (ParseContext .Document document : context .docs ()) {
@@ -244,12 +250,32 @@ protected String contentType() {
244250
245251 @ Override
246252 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
247- XContentBuilder json = XContentFactory . jsonBuilder ( );
248- super . toXContent ( json , params );
249- if (json . string ().equals (" \" " + NAME + " \" { \" type \" : \" " + CONTENT_TYPE + " \" }" ) ) {
253+ boolean includeDefaults = params . paramAsBoolean ( "include_defaults" , false );
254+
255+ if (includeDefaults == false && fieldType ().equals (Defaults . FIELD_TYPE ) && enabledState == Defaults . ENABLED_STATE ) {
250256 return builder ;
251257 }
252- return super .toXContent (builder , params );
258+
259+ builder .startObject (NAME );
260+ if (includeDefaults || enabledState != Defaults .ENABLED_STATE ) {
261+ builder .field ("enabled" , enabledState .enabled );
262+ }
263+ if (includeDefaults || fieldType ().equals (Defaults .FIELD_TYPE ) == false ) {
264+ super .doXContentBody (builder , includeDefaults , params );
265+ }
266+
267+ builder .endObject ();
268+ return builder ;
269+ }
270+
271+ @ Override
272+ public void merge (Mapper mergeWith , MergeContext mergeContext ) throws MergeMappingException {
273+ FieldNamesFieldMapper fieldNamesMapperMergeWith = (FieldNamesFieldMapper )mergeWith ;
274+ if (!mergeContext .mergeFlags ().simulate ()) {
275+ if (fieldNamesMapperMergeWith .enabledState != enabledState && !fieldNamesMapperMergeWith .enabledState .unset ()) {
276+ this .enabledState = fieldNamesMapperMergeWith .enabledState ;
277+ }
278+ }
253279 }
254280
255281 @ Override
0 commit comments