2929import org .elasticsearch .ElasticsearchIllegalArgumentException ;
3030import org .elasticsearch .Version ;
3131import org .elasticsearch .common .Nullable ;
32+ import org .elasticsearch .common .Strings ;
3233import org .elasticsearch .common .lucene .Lucene ;
3334import org .elasticsearch .common .settings .Settings ;
3435import org .elasticsearch .common .xcontent .XContentBuilder ;
35- import org .elasticsearch .common .xcontent .XContentFactory ;
3636import org .elasticsearch .index .codec .docvaluesformat .DocValuesFormatProvider ;
3737import org .elasticsearch .index .codec .postingsformat .PostingsFormatProvider ;
3838import org .elasticsearch .index .fielddata .FieldDataType ;
39- import org .elasticsearch .index .mapper .*;
39+ import org .elasticsearch .index .mapper .InternalMapper ;
40+ import org .elasticsearch .index .mapper .Mapper ;
41+ import org .elasticsearch .index .mapper .MapperParsingException ;
42+ import org .elasticsearch .index .mapper .MergeContext ;
43+ import org .elasticsearch .index .mapper .MergeMappingException ;
44+ import org .elasticsearch .index .mapper .ParseContext ;
45+ import org .elasticsearch .index .mapper .RootMapper ;
46+
4047import org .elasticsearch .index .mapper .core .AbstractFieldMapper ;
4148
4249import java .io .IOException ;
4552import java .util .List ;
4653import java .util .Map ;
4754
55+ import static org .elasticsearch .common .xcontent .support .XContentMapValues .nodeBooleanValue ;
4856import static org .elasticsearch .index .mapper .MapperBuilders .fieldNames ;
4957import static org .elasticsearch .index .mapper .core .TypeParsers .parseField ;
5058
@@ -62,10 +70,9 @@ public class FieldNamesFieldMapper extends AbstractFieldMapper<String> implement
6270
6371 public static class Defaults extends AbstractFieldMapper .Defaults {
6472 public static final String NAME = FieldNamesFieldMapper .NAME ;
65- public static final String INDEX_NAME = FieldNamesFieldMapper . NAME ;
66-
73+
74+ public static final EnabledAttributeMapper ENABLED_STATE = EnabledAttributeMapper . UNSET_ENABLED ;
6775 public static final FieldType FIELD_TYPE = new FieldType (AbstractFieldMapper .Defaults .FIELD_TYPE );
68- public static final FieldType FIELD_TYPE_PRE_1_3_0 ;
6976
7077 static {
7178 FIELD_TYPE .setIndexed (true );
@@ -74,68 +81,74 @@ public static class Defaults extends AbstractFieldMapper.Defaults {
7481 FIELD_TYPE .setOmitNorms (true );
7582 FIELD_TYPE .setIndexOptions (IndexOptions .DOCS_ONLY );
7683 FIELD_TYPE .freeze ();
77- FIELD_TYPE_PRE_1_3_0 = new FieldType (FIELD_TYPE );
78- FIELD_TYPE_PRE_1_3_0 .setIndexed (false );
79- FIELD_TYPE_PRE_1_3_0 .freeze ();
8084 }
8185 }
8286
8387 public static class Builder extends AbstractFieldMapper .Builder <Builder , FieldNamesFieldMapper > {
84-
85- private boolean indexIsExplicit ;
88+ private EnabledAttributeMapper enabledState = Defaults .ENABLED_STATE ;
8689
8790 public Builder () {
8891 super (Defaults .NAME , new FieldType (Defaults .FIELD_TYPE ));
89- indexName = Defaults .INDEX_NAME ;
92+ indexName = Defaults .NAME ;
9093 }
9194
9295 @ Override
9396 public Builder index (boolean index ) {
94- indexIsExplicit = true ;
97+ enabled ( index ) ;
9598 return super .index (index );
9699 }
100+
101+ public Builder enabled (boolean enabled ) {
102+ this .enabledState = enabled ? EnabledAttributeMapper .ENABLED : EnabledAttributeMapper .DISABLED ;
103+ return this ;
104+ }
97105
98106 @ Override
99107 public FieldNamesFieldMapper build (BuilderContext context ) {
100- if ((context .indexCreatedVersion () == null || context .indexCreatedVersion ().before (Version .V_1_3_0 )) && !indexIsExplicit ) {
101- fieldType .setIndexed (false );
102- }
103- return new FieldNamesFieldMapper (name , indexName , boost , fieldType , postingsProvider , docValuesProvider , fieldDataSettings , context .indexSettings ());
108+ return new FieldNamesFieldMapper (name , indexName , boost , fieldType , postingsProvider , docValuesProvider , enabledState , fieldDataSettings , context .indexSettings ());
104109 }
105110 }
106111
107112 public static class TypeParser implements Mapper .TypeParser {
108113 @ Override
109114 public Mapper .Builder parse (String name , Map <String , Object > node , ParserContext parserContext ) throws MapperParsingException {
110- if (parserContext .indexVersionCreated ().onOrAfter (Version .V_1_3_0 )) {
111- FieldNamesFieldMapper .Builder builder = fieldNames ();
112- parseField (builder , builder .name , node , parserContext );
113- return builder ;
114- } else {
115- throw new ElasticsearchIllegalArgumentException ("type=" +CONTENT_TYPE +" is not supported on indices created before version 1.3.0 is your cluster running multiple datanode versions?" );
115+ if (parserContext .indexVersionCreated ().before (Version .V_1_3_0 )) {
116+ throw new ElasticsearchIllegalArgumentException ("type=" +CONTENT_TYPE +" is not supported on indices created before version 1.3.0. Is your cluster running multiple datanode versions?" );
116117 }
118+
119+ FieldNamesFieldMapper .Builder builder = fieldNames ();
120+ parseField (builder , builder .name , node , parserContext );
121+
122+ for (Iterator <Map .Entry <String , Object >> iterator = node .entrySet ().iterator (); iterator .hasNext ();) {
123+ Map .Entry <String , Object > entry = iterator .next ();
124+ String fieldName = Strings .toUnderscoreCase (entry .getKey ());
125+ Object fieldNode = entry .getValue ();
126+ if (fieldName .equals ("enabled" )) {
127+ builder .enabled (nodeBooleanValue (fieldNode ));
128+ iterator .remove ();
129+ }
130+ }
131+ return builder ;
117132 }
118133 }
119134
120135 private final FieldType defaultFieldType ;
121-
122- private static FieldType defaultFieldType (Settings indexSettings ) {
123- return indexSettings != null && Version .indexCreated (indexSettings ).onOrAfter (Version .V_1_3_0 ) ? Defaults .FIELD_TYPE : Defaults .FIELD_TYPE_PRE_1_3_0 ;
124- }
136+ private EnabledAttributeMapper enabledState ;
125137
126138 public FieldNamesFieldMapper (Settings indexSettings ) {
127- this (Defaults .NAME , Defaults .INDEX_NAME , indexSettings );
128- }
129-
130- protected FieldNamesFieldMapper (String name , String indexName , Settings indexSettings ) {
131- this (name , indexName , Defaults .BOOST , new FieldType (defaultFieldType (indexSettings )), null , null , null , indexSettings );
139+ this (Defaults .NAME , Defaults .NAME , Defaults .BOOST , new FieldType (Defaults .FIELD_TYPE ), null , null , Defaults .ENABLED_STATE , null , indexSettings );
132140 }
133141
134142 public FieldNamesFieldMapper (String name , String indexName , float boost , FieldType fieldType , PostingsFormatProvider postingsProvider ,
135- DocValuesFormatProvider docValuesProvider , @ Nullable Settings fieldDataSettings , Settings indexSettings ) {
143+ DocValuesFormatProvider docValuesProvider , EnabledAttributeMapper enabledState , @ Nullable Settings fieldDataSettings , Settings indexSettings ) {
136144 super (new Names (name , indexName , indexName , name ), boost , fieldType , null , Lucene .KEYWORD_ANALYZER ,
137145 Lucene .KEYWORD_ANALYZER , postingsProvider , docValuesProvider , null , null , fieldDataSettings , indexSettings );
138- this .defaultFieldType = defaultFieldType (indexSettings );
146+ this .defaultFieldType = Defaults .FIELD_TYPE ;
147+ this .enabledState = enabledState ;
148+ }
149+
150+ public boolean enabled () {
151+ return enabledState .enabled ;
139152 }
140153
141154 @ Override
@@ -214,7 +227,7 @@ public String next() {
214227
215228 @ Override
216229 protected void parseCreateField (ParseContext context , List <Field > fields ) throws IOException {
217- if (! fieldType . indexed () && ! fieldType . stored () && ! hasDocValues () ) {
230+ if (enabledState . enabled == false ) {
218231 return ;
219232 }
220233 for (ParseContext .Document document : context .docs ()) {
@@ -242,12 +255,32 @@ protected String contentType() {
242255
243256 @ Override
244257 public XContentBuilder toXContent (XContentBuilder builder , Params params ) throws IOException {
245- XContentBuilder json = XContentFactory . jsonBuilder ( );
246- super . toXContent ( json , params );
247- if (json . string ().equals (" \" " + NAME + " \" { \" type \" : \" " + CONTENT_TYPE + " \" }" ) ) {
258+ boolean includeDefaults = params . paramAsBoolean ( "include_defaults" , false );
259+
260+ if (includeDefaults == false && fieldType ().equals (Defaults . FIELD_TYPE ) && enabledState == Defaults . ENABLED_STATE ) {
248261 return builder ;
249262 }
250- return super .toXContent (builder , params );
263+
264+ builder .startObject (NAME );
265+ if (includeDefaults || enabledState != Defaults .ENABLED_STATE ) {
266+ builder .field ("enabled" , enabledState .enabled );
267+ }
268+ if (includeDefaults || fieldType ().equals (Defaults .FIELD_TYPE ) == false ) {
269+ super .doXContentBody (builder , includeDefaults , params );
270+ }
271+
272+ builder .endObject ();
273+ return builder ;
274+ }
275+
276+ @ Override
277+ public void merge (Mapper mergeWith , MergeContext mergeContext ) throws MergeMappingException {
278+ FieldNamesFieldMapper fieldNamesMapperMergeWith = (FieldNamesFieldMapper )mergeWith ;
279+ if (!mergeContext .mergeFlags ().simulate ()) {
280+ if (fieldNamesMapperMergeWith .enabledState != enabledState && !fieldNamesMapperMergeWith .enabledState .unset ()) {
281+ this .enabledState = fieldNamesMapperMergeWith .enabledState ;
282+ }
283+ }
251284 }
252285
253286 @ Override
0 commit comments