CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-elasticsearch--elasticsearch-x-content

A content processing library for Elasticsearch that provides abstractions for parsing and generating various content formats including JSON, YAML, CBOR, and Smile.

Pending
Overview
Eval results
Files

object-mapping.mddocs/

Object Mapping Framework

The X-Content library provides a comprehensive declarative framework for converting structured content directly into Java objects with type safety and flexible construction patterns.

Capabilities

ObjectParser

Declarative, stateless parser for objects that use setter methods or field assignment.

/**
 * Declarative parser for objects with setter-based construction
 * @param <Value> the type of object to parse
 * @param <Context> the type of parsing context
 */
public final class ObjectParser<Value, Context> extends AbstractObjectParser<Value, Context> {
    
    /**
     * Create an object parser with automatic value creation
     * @param name parser name for error messages
     */
    public ObjectParser(String name);
    
    /**
     * Create an object parser with custom value supplier
     * @param name parser name for error messages
     * @param valueSupplier supplier to create new instances
     */
    public ObjectParser(String name, Supplier<Value> valueSupplier);
    
    /**
     * Create an object parser with unknown field handling
     * @param name parser name for error messages
     * @param ignoreUnknownFields whether to ignore unknown fields
     * @param valueSupplier supplier to create new instances
     */
    public ObjectParser(String name, boolean ignoreUnknownFields, Supplier<Value> valueSupplier);
    
    /**
     * Parse content into a new object instance
     * @param parser content parser
     * @param context parsing context
     * @return parsed object
     */
    public Value parse(XContentParser parser, Context context) throws IOException;
    
    /**
     * Parse content into an existing object instance
     * @param parser content parser
     * @param value existing object to populate
     * @param context parsing context
     * @return the populated object
     */
    public Value parse(XContentParser parser, Value value, Context context) throws IOException;
}

Field Declaration Methods

Methods for declaring how to parse different field types.

/**
 * Declare a string field
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareString(BiConsumer<Value, String> consumer, ParseField field);

/**
 * Declare an integer field
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareInt(BiConsumer<Value, Integer> consumer, ParseField field);

/**
 * Declare a long field
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareLong(BiConsumer<Value, Long> consumer, ParseField field);

/**
 * Declare a float field
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareFloat(BiConsumer<Value, Float> consumer, ParseField field);

/**
 * Declare a double field
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareDouble(BiConsumer<Value, Double> consumer, ParseField field);

/**
 * Declare a boolean field
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareBoolean(BiConsumer<Value, Boolean> consumer, ParseField field);

/**
 * Declare an object field
 * @param consumer setter method reference
 * @param parser parser for the object type
 * @param field parse field definition
 */
public <T> void declareObject(BiConsumer<Value, T> consumer, ContextParser<Context, T> parser, ParseField field);

/**
 * Declare an array of objects field
 * @param consumer setter method reference
 * @param parser parser for individual array elements
 * @param field parse field definition
 */
public <T> void declareObjectArray(BiConsumer<Value, List<T>> consumer, ContextParser<Context, T> parser, ParseField field);

/**
 * Declare a named object field (using registry)
 * @param consumer setter method reference
 * @param namedObjectParser parser for named objects
 * @param field parse field definition
 */
public <T> void declareNamedObject(BiConsumer<Value, T> consumer, 
                                   NamedObjectParser<T, Context> namedObjectParser, ParseField field);

/**
 * Declare an array of named objects field
 * @param consumer setter method reference
 * @param namedObjectParser parser for individual named objects
 * @param field parse field definition
 */
public <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer,
                                    NamedObjectParser<T, Context> namedObjectParser, ParseField field);

/**
 * Declare a field that can contain any type of value
 * @param consumer setter method reference
 * @param field parse field definition
 */
public void declareField(BiConsumer<Value, Object> consumer, ContextParser<Context, Object> parser, 
                        ParseField field, ValueType expectedValueType);

Usage Example:

import org.elasticsearch.xcontent.*;

// Define a simple data class
public class User {
    private String name;
    private int age;
    private boolean active;
    private List<String> skills;
    private Address address;
    
    // Constructor, getters, and setters...
    public User() {}
    public void setName(String name) { this.name = name; }
    public void setAge(int age) { this.age = age; }
    public void setActive(boolean active) { this.active = active; }
    public void setSkills(List<String> skills) { this.skills = skills; }
    public void setAddress(Address address) { this.address = address; }
}

public class Address {
    private String street;
    private String city;
    
    public Address() {}
    public void setStreet(String street) { this.street = street; }
    public void setCity(String city) { this.city = city; }
}

// Create parsers
ObjectParser<Address, Void> addressParser = new ObjectParser<>("address", Address::new);
addressParser.declareString(Address::setStreet, new ParseField("street"));
addressParser.declareString(Address::setCity, new ParseField("city"));

ObjectParser<User, Void> userParser = new ObjectParser<>("user", User::new);
userParser.declareString(User::setName, new ParseField("name"));
userParser.declareInt(User::setAge, new ParseField("age"));
userParser.declareBoolean(User::setActive, new ParseField("active"));
userParser.declareStringArray(User::setSkills, new ParseField("skills"));
userParser.declareObject(User::setAddress, addressParser, new ParseField("address"));

// Parse JSON content
String json = """
{
    "name": "John Doe",
    "age": 30,
    "active": true,
    "skills": ["Java", "Elasticsearch"],
    "address": {
        "street": "123 Main St",
        "city": "New York"
    }
}
""";

XContentParser parser = XContentType.JSON.xContent()
    .createParser(XContentParserConfiguration.EMPTY, json);
User user = userParser.parse(parser, null);
parser.close();

ConstructingObjectParser

Parser for objects that require constructor arguments rather than setter methods.

/**
 * Parser for objects requiring constructor arguments
 * @param <Value> the type of object to construct
 * @param <Context> the type of parsing context
 */
public final class ConstructingObjectParser<Value, Context> extends AbstractObjectParser<Value, Context> {
    
    /**
     * Create a constructing parser with simple builder function
     * @param name parser name for error messages
     * @param builder function that constructs objects from argument array
     */
    public ConstructingObjectParser(String name, Function<Object[], Value> builder);
    
    /**
     * Create a constructing parser with context-aware builder function
     * @param name parser name for error messages
     * @param ignoreUnknownFields whether to ignore unknown fields
     * @param builder function that constructs objects from arguments and context
     */
    public ConstructingObjectParser(String name, boolean ignoreUnknownFields, 
                                   BiFunction<Object[], Context, Value> builder);
    
    /**
     * Mark a field as a required constructor argument
     * @return BiConsumer that marks the field as a constructor argument
     */
    public static <Value, FieldT> BiConsumer<Value, FieldT> constructorArg();
    
    /**
     * Mark a field as an optional constructor argument
     * @return BiConsumer that marks the field as an optional constructor argument
     */
    public static <Value, FieldT> BiConsumer<Value, FieldT> optionalConstructorArg();
    
    /**
     * Parse content into a new object instance
     * @param parser content parser
     * @param context parsing context
     * @return constructed object
     */
    public Value parse(XContentParser parser, Context context) throws IOException;
}

Usage Example:

// Immutable data class with constructor
public class ImmutableUser {
    private final String name;
    private final int age;
    private final boolean active;
    private final List<String> skills;
    
    public ImmutableUser(String name, int age, boolean active, List<String> skills) {
        this.name = name;
        this.age = age;
        this.active = active;
        this.skills = skills;
    }
    
    // Getters only...
}

// Create constructing parser
ConstructingObjectParser<ImmutableUser, Void> parser = new ConstructingObjectParser<>(
    "immutable_user",
    args -> new ImmutableUser(
        (String) args[0],    // name
        (Integer) args[1],   // age
        (Boolean) args[2],   // active
        (List<String>) args[3]  // skills
    )
);

// Declare fields as constructor arguments
parser.declareString(constructorArg(), new ParseField("name"));
parser.declareInt(constructorArg(), new ParseField("age"));
parser.declareBoolean(constructorArg(), new ParseField("active"));
parser.declareStringArray(constructorArg(), new ParseField("skills"));

// Parse content
XContentParser contentParser = XContentType.JSON.xContent()
    .createParser(XContentParserConfiguration.EMPTY, jsonContent);
ImmutableUser user = parser.parse(contentParser, null);
contentParser.close();

InstantiatingObjectParser

Parser that uses reflection to call constructors with @ParserConstructor annotation.

/**
 * Parser that uses reflection for object construction
 * @param <Value> the type of object to instantiate
 * @param <Context> the type of parsing context
 */
public class InstantiatingObjectParser<Value, Context> 
    implements BiFunction<XContentParser, Context, Value>, ContextParser<Context, Value> {
    
    /**
     * Builder for creating instantiating parsers
     */
    public static class Builder<Value, Context> {
        
        /**
         * Create a builder for the specified class
         * @param name parser name for error messages
         * @param valueClass class to instantiate
         * @return builder instance
         */
        public static <Value, Context> Builder<Value, Context> builder(String name, Class<Value> valueClass);
        
        /**
         * Create a builder with unknown field handling
         * @param name parser name for error messages
         * @param ignoreUnknownFields whether to ignore unknown fields
         * @param valueClass class to instantiate
         * @return builder instance
         */
        public static <Value, Context> Builder<Value, Context> builder(String name, boolean ignoreUnknownFields, 
                                                                       Class<Value> valueClass);
        
        /**
         * Build the parser
         * @return InstantiatingObjectParser instance
         */
        public InstantiatingObjectParser<Value, Context> build();
    }
    
    /**
     * Parse content and instantiate object
     * @param parser content parser
     * @param context parsing context
     * @return instantiated object
     */
    public Value apply(XContentParser parser, Context context);
}

/**
 * Annotation to mark constructors for automatic parsing
 */
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParserConstructor {
}

Usage Example:

// Data class with annotated constructor
public class AnnotatedUser {
    private final String name;
    private final int age;
    private final boolean active;
    
    @ParserConstructor
    public AnnotatedUser(String name, int age, boolean active) {
        this.name = name;
        this.age = age;
        this.active = active;
    }
    
    // Getters...
}

// Create instantiating parser
InstantiatingObjectParser<AnnotatedUser, Void> parser = 
    InstantiatingObjectParser.builder("annotated_user", AnnotatedUser.class).build();

// Parse content (field names must match constructor parameter names)
XContentParser contentParser = XContentType.JSON.xContent()
    .createParser(XContentParserConfiguration.EMPTY, jsonContent);
AnnotatedUser user = parser.apply(contentParser, null);
contentParser.close();

ValueType Enumeration

Enumeration defining supported value types for field declarations.

/**
 * Enumeration of supported value types for object parsing
 */
public enum ValueType {
    STRING,
    STRING_OR_NULL,
    FLOAT,
    FLOAT_OR_NULL,
    DOUBLE,
    DOUBLE_OR_NULL,
    INT,
    INT_OR_NULL,
    LONG,
    LONG_OR_NULL,
    BOOLEAN,
    BOOLEAN_OR_NULL,
    STRING_ARRAY,
    FLOAT_ARRAY,
    DOUBLE_ARRAY,
    INT_ARRAY,
    LONG_ARRAY,
    BOOLEAN_ARRAY,
    OBJECT,
    OBJECT_OR_NULL,
    OBJECT_ARRAY,
    OBJECT_ARRAY_OR_NULL,
    VALUE,
    VALUE_OR_NULL,
    VALUE_ARRAY
}

Parser Interfaces

/**
 * Interface for parsing objects with context
 */
@FunctionalInterface
public interface ContextParser<Context, T> {
    /**
     * Parse an object with the given context
     * @param parser content parser
     * @param context parsing context
     * @return parsed object
     */
    T parse(XContentParser parser, Context context) throws IOException;
}

/**
 * Interface for parsing named objects
 */
public interface NamedObjectParser<T, Context> {
    /**
     * Parse a named object
     * @param parser content parser
     * @param context parsing context
     * @param name object name
     * @return parsed object
     */
    T parse(XContentParser parser, Context context, String name) throws IOException;
}

/**
 * Interface for consuming unknown fields during parsing
 */
@FunctionalInterface
public interface UnknownFieldConsumer<Value> {
    /**
     * Accept an unknown field
     * @param objectParser the parser that encountered the unknown field
     * @param value the object being parsed
     * @param fieldName the unknown field name
     * @param parser content parser positioned at the field value
     */
    void accept(ObjectParser<Value, ?> objectParser, Value value, String fieldName, XContentParser parser);
}

Install with Tessl CLI

npx tessl i tessl/maven-org-elasticsearch--elasticsearch-x-content

docs

configuration.md

content-generation.md

content-parsing.md

content-types.md

index.md

object-mapping.md

tile.json