Class ConstructingObjectParser<Value,Context> 
- All Implemented Interfaces:
- BiFunction<XContentParser,,- Context, - Value> - ContextParser<Context,- Value> 
ObjectParser but works with objects that have constructors whose arguments are mixed in with its other settings. Queries are
 like this, for example ids requires types but always parses the values field on the same level. If
 this doesn't sounds like what you want to parse have a look at
 ObjectParser.declareNamedObjects(BiConsumer, ObjectParser.NamedObjectParser, Consumer, ParseField) which solves a slightly
 different but similar sounding problem.
 Anyway, ConstructingObjectParser parses the fields in the order that they are in the XContent, collecting constructor arguments and parsing and queueing normal fields until all constructor arguments are parsed. Then it builds the target object and replays the queued fields. Any fields that come in after the last constructor arguments are parsed and immediately applied to the target object just like ObjectParser.
 Declaring a ConstructingObjectParser is intentionally quite similar to declaring an ObjectParser. The only
 differences being that constructor arguments are declared with the consumer returned by the static constructorArg() method and
 that ConstructingObjectParser's constructor takes a lambda that must build the target object from a list of constructor
 arguments:
 
   private static final ConstructingObjectParser<Thing, SomeContext> PARSER = new ConstructingObjectParser<>("thing",
           a -> new Thing((String) a[0], (String) a[1], (Integer) a[2]));
   static {
       PARSER.declareString(constructorArg(), new ParseField("animal"));
       PARSER.declareString(constructorArg(), new ParseField("vegetable"));
       PARSER.declareInt(optionalConstructorArg(), new ParseField("mineral"));
       PARSER.declareInt(Thing::setFruit, new ParseField("fruit"));
       PARSER.declareInt(Thing::setBug, new ParseField("bug"));
   }
 
 This does add some overhead compared to just using ObjectParser directly. On a 2.2 GHz Intel Core i7 MacBook Air running on
 battery power in a reasonably unscientific microbenchmark it is about 100 microseconds for a reasonably large object, less if the
 constructor arguments are first. On this platform with the same microbenchmarks just creating the XContentParser is around 900
 microseconds and using {#linkplain ObjectParser} directly adds another 300 or so microseconds. In the best case
 ConstructingObjectParser allocates two additional objects per parse compared to {#linkplain ObjectParser}. In the worst case
 it allocates 3 + 2 * param_count objects per parse. If this overhead is too much for you then feel free to have ObjectParser
 parse a secondary object and have that one call the target object's constructor. That ought to be rare though.
 
Note: if optional constructor arguments aren't specified then the number of allocations is always the worst case.
- 
Constructor SummaryConstructorsConstructorDescriptionConstructingObjectParser(String name, boolean ignoreUnknownFields, BiFunction<Object[], Context, Value> builder) Build the parser.ConstructingObjectParser(String name, boolean ignoreUnknownFields, Function<Object[], Value> builder) Build the parser.ConstructingObjectParser(String name, Function<Object[], Value> builder) Build the parser.
- 
Method SummaryModifier and TypeMethodDescriptionapply(XContentParser parser, Context context) Call this to do the actual parsing.static <Value,FieldT> 
 BiConsumer<Value, FieldT> Pass the BiConsumer this returns the declare methods to declare a required constructor argument.voiddeclareExclusiveFieldSet(String... exclusiveSet) Declares a set of fields of which at most one must appear for parsing to succeed E.g.<T> voiddeclareField(BiConsumer<Value, T> consumer, ContextParser<Context, T> parser, ParseField parseField, ObjectParser.ValueType type) Declare some field.<T> voiddeclareNamedObject(BiConsumer<Value, T> consumer, ObjectParser.NamedObjectParser<T, Context> namedObjectParser, ParseField parseField) Declares a single named object.<T> voiddeclareNamedObjects(BiConsumer<Value, List<T>> consumer, ObjectParser.NamedObjectParser<T, Context> namedObjectParser, Consumer<Value> orderedModeCallback, ParseField parseField) Declares named objects in the style of highlighting's field element.<T> voiddeclareNamedObjects(BiConsumer<Value, List<T>> consumer, ObjectParser.NamedObjectParser<T, Context> namedObjectParser, ParseField parseField) Declares named objects in the style of aggregations.voiddeclareRequiredFieldSet(String... requiredSet) Declares a set of fields that are required for parsing to succeed.getName()static <Value,FieldT> 
 BiConsumer<Value, FieldT> Pass the BiConsumer this returns the declare methods to declare an optional constructor argument.parse(XContentParser parser, Context context) Methods inherited from class org.elasticsearch.xcontent.AbstractObjectParserdeclareBoolean, declareDouble, declareDoubleArray, declareDoubleOrNull, declareField, declareFieldArray, declareFloat, declareFloatArray, declareFloatOrNull, declareInt, declareIntArray, declareIntOrNull, declareLong, declareLongArray, declareLongOrNull, declareObject, declareObjectArray, declareObjectArrayOrNull, declareObjectOrNull, declareString, declareString, declareStringArray, declareStringOrNull, parseArrayMethods inherited from class java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface java.util.function.BiFunctionandThen
- 
Constructor Details- 
ConstructingObjectParserBuild the parser.- Parameters:
- name- The name given to the delegate ObjectParser for error identification. Use what you'd use if the object worked with ObjectParser.
- builder- A function that builds the object from an array of Objects. Declare this inline with the parser, casting the elements of the array to the arguments so they work with your favorite constructor. The objects in the array will be in the same order that you declared the- constructorArg()s and none will be null. If any of the constructor arguments aren't defined in the XContent then parsing will throw an error. We use an array here rather than a- Map<String, Object>to save on allocations.
 
- 
ConstructingObjectParserpublic ConstructingObjectParser(String name, boolean ignoreUnknownFields, Function<Object[], Value> builder) Build the parser.- Parameters:
- name- The name given to the delegate ObjectParser for error identification. Use what you'd use if the object worked with ObjectParser.
- ignoreUnknownFields- Should this parser ignore unknown fields? This should generally be set to true only when parsing responses from external systems, never when parsing requests from users.
- builder- A function that builds the object from an array of Objects. Declare this inline with the parser, casting the elements of the array to the arguments so they work with your favorite constructor. The objects in the array will be in the same order that you declared the- constructorArg()s and none will be null. If any of the constructor arguments aren't defined in the XContent then parsing will throw an error. We use an array here rather than a- Map<String, Object>to save on allocations.
 
- 
ConstructingObjectParserpublic ConstructingObjectParser(String name, boolean ignoreUnknownFields, BiFunction<Object[], Context, Value> builder) Build the parser.- Parameters:
- name- The name given to the delegate ObjectParser for error identification. Use what you'd use if the object worked with ObjectParser.
- ignoreUnknownFields- Should this parser ignore unknown fields? This should generally be set to true only when parsing responses from external systems, never when parsing requests from users.
- builder- A binary function that builds the object from an array of Objects and the parser context. Declare this inline with the parser, casting the elements of the array to the arguments so they work with your favorite constructor. The objects in the array will be in the same order that you declared the- constructorArg()s and none will be null. The second argument is the value of the context provided to the- parse function. If any of the constructor arguments aren't defined in the XContent then parsing will throw an error. We use an array here rather than a- Map<String, Object>to save on allocations.
 
 
- 
- 
Method Details- 
applyCall this to do the actual parsing. This implementsBiFunctionfor conveniently integrating with ObjectParser.- Specified by:
- applyin interface- BiFunction<XContentParser,- Context, - Value> 
 
- 
parse- Specified by:
- parsein interface- ContextParser<Value,- Context> 
- Throws:
- IOException
 
- 
constructorArgPass the BiConsumer this returns the declare methods to declare a required constructor argument. See this class's javadoc for an example. The order in which these are declared matters: it is the order that they come in the array passed tobuilderand the order that missing arguments are reported to the user if any are missing. When all of these parameters are parsed from the XContentParser the target object is immediately built.
- 
optionalConstructorArgPass the BiConsumer this returns the declare methods to declare an optional constructor argument. See this class's javadoc for an example. The order in which these are declared matters: it is the order that they come in the array passed tobuilderand the order that missing arguments are reported to the user if any are missing. When all of these parameters are parsed from the XContentParser the target object is immediately built.
- 
declareFieldpublic <T> void declareField(BiConsumer<Value, T> consumer, ContextParser<Context, T> parser, ParseField parseField, ObjectParser.ValueType type) Description copied from class:AbstractObjectParserDeclare some field. Usually it is easier to useAbstractObjectParser.declareString(BiConsumer, ParseField)orAbstractObjectParser.declareObject(BiConsumer, ContextParser, ParseField)rather than call this directly.- Specified by:
- declareFieldin class- AbstractObjectParser<Value,- Context> 
 
- 
declareNamedObjectpublic <T> void declareNamedObject(BiConsumer<Value, T> consumer, ObjectParser.NamedObjectParser<T, Context> namedObjectParser, ParseField parseField) Description copied from class:AbstractObjectParserDeclares a single named object.{ "object_name": { "instance_name": { "field1": "value1", ... } } } }- Specified by:
- declareNamedObjectin class- AbstractObjectParser<Value,- Context> 
- Parameters:
- consumer- sets the value once it has been parsed
- namedObjectParser- parses the named object
- parseField- the field to parse
 
- 
declareNamedObjectspublic <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer, ObjectParser.NamedObjectParser<T, Context> namedObjectParser, ParseField parseField) Description copied from class:AbstractObjectParserDeclares named objects in the style of aggregations. These are named inside and object like this:
 Unlike the other version of this method, "ordered" mode (arrays of objects) is not supported. See NamedObjectHolder in ObjectParserTests for examples of how to invoke this.{ "aggregations": { "name_1": { "aggregation_type": {} }, "name_2": { "aggregation_type": {} }, "name_3": { "aggregation_type": {} } } } }- Specified by:
- declareNamedObjectsin class- AbstractObjectParser<Value,- Context> 
- Parameters:
- consumer- sets the values once they have been parsed
- namedObjectParser- parses each named object
- parseField- the field to parse
 
- 
declareNamedObjectspublic <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer, ObjectParser.NamedObjectParser<T, Context> namedObjectParser, Consumer<Value> orderedModeCallback, ParseField parseField) Description copied from class:AbstractObjectParserDeclares named objects in the style of highlighting's field element. These are usually named inside and object like this:
 but, when order is important, some may be written this way:{ "highlight": { "fields": { <------ this one "title": {}, "body": {}, "category": {} } } }
 This is because json doesn't enforce ordering. Elasticsearch reads it in the order sent but tools that generate json are free to put object members in an unordered Map, jumbling them. Thus, if you care about order you can send the object in the second way. See NamedObjectHolder in ObjectParserTests for examples of how to invoke this.{ "highlight": { "fields": [ <------ this one {"title": {}}, {"body": {}}, {"category": {}} ] } }- Specified by:
- declareNamedObjectsin class- AbstractObjectParser<Value,- Context> 
- Parameters:
- consumer- sets the values once they have been parsed
- namedObjectParser- parses each named object
- orderedModeCallback- called when the named object is parsed using the "ordered" mode (the array of objects)
- parseField- the field to parse
 
- 
getName- Specified by:
- getNamein class- AbstractObjectParser<Value,- Context> 
 
- 
declareRequiredFieldSetDescription copied from class:AbstractObjectParserDeclares a set of fields that are required for parsing to succeed. Only one of the values provided per String[] must be matched. E.g.declareRequiredFieldSet("foo", "bar");means at least one of "foo" or "bar" fields must be present. If neither of those fields are present, an exception will be thrown. Multiple required sets can be configured:
 requires that one of "foo" or "bar" fields are present, and also that one of "bizz" or "buzz" fields are present. In JSON, it means any of these combinations are acceptable:parser.declareRequiredFieldSet("foo", "bar"); parser.declareRequiredFieldSet("bizz", "buzz");- {"foo":"...", "bizz": "..."}
- {"bar":"...", "bizz": "..."}
- {"foo":"...", "buzz": "..."}
- {"bar":"...", "buzz": "..."}
- {"foo":"...", "bar":"...", "bizz": "..."}
- {"foo":"...", "bar":"...", "buzz": "..."}
- {"foo":"...", "bizz":"...", "buzz": "..."}
- {"bar":"...", "bizz":"...", "buzz": "..."}
- {"foo":"...", "bar":"...", "bizz": "...", "buzz": "..."}
 failure cases Provided JSON Reason for failure {"foo":"..."}Missing "bizz" or "buzz" field {"bar":"..."}Missing "bizz" or "buzz" field {"bizz": "..."}Missing "foo" or "bar" field {"buzz": "..."}Missing "foo" or "bar" field {"foo":"...", "bar": "..."}Missing "bizz" or "buzz" field {"bizz":"...", "buzz": "..."}Missing "foo" or "bar" field {"unrelated":"..."}Missing "foo" or "bar" field, and missing "bizz" or "buzz" field - Specified by:
- declareRequiredFieldSetin class- AbstractObjectParser<Value,- Context> 
- Parameters:
- requiredSet- A set of required fields, where at least one of the fields in the array _must_ be present
 
- 
declareExclusiveFieldSetDescription copied from class:AbstractObjectParserDeclares a set of fields of which at most one must appear for parsing to succeed E.g.declareExclusiveFieldSet("foo", "bar");means that only one of 'foo' or 'bar' must be present, and if both appear then an exception will be thrown. Note that this does not make 'foo' or 'bar' required - seeAbstractObjectParser.declareRequiredFieldSet(String...)for required fields. Multiple exclusive sets may be declared- Specified by:
- declareExclusiveFieldSetin class- AbstractObjectParser<Value,- Context> 
- Parameters:
- exclusiveSet- a set of field names, at most one of which must appear
 
 
-