or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcontent-generation.mdcontent-parsing.mdcontent-types.mdindex.mdobject-mapping.md

object-mapping.mddocs/

0

# Object Mapping Framework

1

2

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

3

4

## Capabilities

5

6

### ObjectParser

7

8

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

9

10

```java { .api }

11

/**

12

* Declarative parser for objects with setter-based construction

13

* @param <Value> the type of object to parse

14

* @param <Context> the type of parsing context

15

*/

16

public final class ObjectParser<Value, Context> extends AbstractObjectParser<Value, Context> {

17

18

/**

19

* Create an object parser with automatic value creation

20

* @param name parser name for error messages

21

*/

22

public ObjectParser(String name);

23

24

/**

25

* Create an object parser with custom value supplier

26

* @param name parser name for error messages

27

* @param valueSupplier supplier to create new instances

28

*/

29

public ObjectParser(String name, Supplier<Value> valueSupplier);

30

31

/**

32

* Create an object parser with unknown field handling

33

* @param name parser name for error messages

34

* @param ignoreUnknownFields whether to ignore unknown fields

35

* @param valueSupplier supplier to create new instances

36

*/

37

public ObjectParser(String name, boolean ignoreUnknownFields, Supplier<Value> valueSupplier);

38

39

/**

40

* Parse content into a new object instance

41

* @param parser content parser

42

* @param context parsing context

43

* @return parsed object

44

*/

45

public Value parse(XContentParser parser, Context context) throws IOException;

46

47

/**

48

* Parse content into an existing object instance

49

* @param parser content parser

50

* @param value existing object to populate

51

* @param context parsing context

52

* @return the populated object

53

*/

54

public Value parse(XContentParser parser, Value value, Context context) throws IOException;

55

}

56

```

57

58

### Field Declaration Methods

59

60

Methods for declaring how to parse different field types.

61

62

```java { .api }

63

/**

64

* Declare a string field

65

* @param consumer setter method reference

66

* @param field parse field definition

67

*/

68

public void declareString(BiConsumer<Value, String> consumer, ParseField field);

69

70

/**

71

* Declare an integer field

72

* @param consumer setter method reference

73

* @param field parse field definition

74

*/

75

public void declareInt(BiConsumer<Value, Integer> consumer, ParseField field);

76

77

/**

78

* Declare a long field

79

* @param consumer setter method reference

80

* @param field parse field definition

81

*/

82

public void declareLong(BiConsumer<Value, Long> consumer, ParseField field);

83

84

/**

85

* Declare a float field

86

* @param consumer setter method reference

87

* @param field parse field definition

88

*/

89

public void declareFloat(BiConsumer<Value, Float> consumer, ParseField field);

90

91

/**

92

* Declare a double field

93

* @param consumer setter method reference

94

* @param field parse field definition

95

*/

96

public void declareDouble(BiConsumer<Value, Double> consumer, ParseField field);

97

98

/**

99

* Declare a boolean field

100

* @param consumer setter method reference

101

* @param field parse field definition

102

*/

103

public void declareBoolean(BiConsumer<Value, Boolean> consumer, ParseField field);

104

105

/**

106

* Declare an object field

107

* @param consumer setter method reference

108

* @param parser parser for the object type

109

* @param field parse field definition

110

*/

111

public <T> void declareObject(BiConsumer<Value, T> consumer, ContextParser<Context, T> parser, ParseField field);

112

113

/**

114

* Declare an array of objects field

115

* @param consumer setter method reference

116

* @param parser parser for individual array elements

117

* @param field parse field definition

118

*/

119

public <T> void declareObjectArray(BiConsumer<Value, List<T>> consumer, ContextParser<Context, T> parser, ParseField field);

120

121

/**

122

* Declare a named object field (using registry)

123

* @param consumer setter method reference

124

* @param namedObjectParser parser for named objects

125

* @param field parse field definition

126

*/

127

public <T> void declareNamedObject(BiConsumer<Value, T> consumer,

128

NamedObjectParser<T, Context> namedObjectParser, ParseField field);

129

130

/**

131

* Declare an array of named objects field

132

* @param consumer setter method reference

133

* @param namedObjectParser parser for individual named objects

134

* @param field parse field definition

135

*/

136

public <T> void declareNamedObjects(BiConsumer<Value, List<T>> consumer,

137

NamedObjectParser<T, Context> namedObjectParser, ParseField field);

138

139

/**

140

* Declare a field that can contain any type of value

141

* @param consumer setter method reference

142

* @param field parse field definition

143

*/

144

public void declareField(BiConsumer<Value, Object> consumer, ContextParser<Context, Object> parser,

145

ParseField field, ValueType expectedValueType);

146

```

147

148

**Usage Example:**

149

150

```java

151

import org.elasticsearch.xcontent.*;

152

153

// Define a simple data class

154

public class User {

155

private String name;

156

private int age;

157

private boolean active;

158

private List<String> skills;

159

private Address address;

160

161

// Constructor, getters, and setters...

162

public User() {}

163

public void setName(String name) { this.name = name; }

164

public void setAge(int age) { this.age = age; }

165

public void setActive(boolean active) { this.active = active; }

166

public void setSkills(List<String> skills) { this.skills = skills; }

167

public void setAddress(Address address) { this.address = address; }

168

}

169

170

public class Address {

171

private String street;

172

private String city;

173

174

public Address() {}

175

public void setStreet(String street) { this.street = street; }

176

public void setCity(String city) { this.city = city; }

177

}

178

179

// Create parsers

180

ObjectParser<Address, Void> addressParser = new ObjectParser<>("address", Address::new);

181

addressParser.declareString(Address::setStreet, new ParseField("street"));

182

addressParser.declareString(Address::setCity, new ParseField("city"));

183

184

ObjectParser<User, Void> userParser = new ObjectParser<>("user", User::new);

185

userParser.declareString(User::setName, new ParseField("name"));

186

userParser.declareInt(User::setAge, new ParseField("age"));

187

userParser.declareBoolean(User::setActive, new ParseField("active"));

188

userParser.declareStringArray(User::setSkills, new ParseField("skills"));

189

userParser.declareObject(User::setAddress, addressParser, new ParseField("address"));

190

191

// Parse JSON content

192

String json = """

193

{

194

"name": "John Doe",

195

"age": 30,

196

"active": true,

197

"skills": ["Java", "Elasticsearch"],

198

"address": {

199

"street": "123 Main St",

200

"city": "New York"

201

}

202

}

203

""";

204

205

XContentParser parser = XContentType.JSON.xContent()

206

.createParser(XContentParserConfiguration.EMPTY, json);

207

User user = userParser.parse(parser, null);

208

parser.close();

209

```

210

211

### ConstructingObjectParser

212

213

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

214

215

```java { .api }

216

/**

217

* Parser for objects requiring constructor arguments

218

* @param <Value> the type of object to construct

219

* @param <Context> the type of parsing context

220

*/

221

public final class ConstructingObjectParser<Value, Context> extends AbstractObjectParser<Value, Context> {

222

223

/**

224

* Create a constructing parser with simple builder function

225

* @param name parser name for error messages

226

* @param builder function that constructs objects from argument array

227

*/

228

public ConstructingObjectParser(String name, Function<Object[], Value> builder);

229

230

/**

231

* Create a constructing parser with context-aware builder function

232

* @param name parser name for error messages

233

* @param ignoreUnknownFields whether to ignore unknown fields

234

* @param builder function that constructs objects from arguments and context

235

*/

236

public ConstructingObjectParser(String name, boolean ignoreUnknownFields,

237

BiFunction<Object[], Context, Value> builder);

238

239

/**

240

* Mark a field as a required constructor argument

241

* @return BiConsumer that marks the field as a constructor argument

242

*/

243

public static <Value, FieldT> BiConsumer<Value, FieldT> constructorArg();

244

245

/**

246

* Mark a field as an optional constructor argument

247

* @return BiConsumer that marks the field as an optional constructor argument

248

*/

249

public static <Value, FieldT> BiConsumer<Value, FieldT> optionalConstructorArg();

250

251

/**

252

* Parse content into a new object instance

253

* @param parser content parser

254

* @param context parsing context

255

* @return constructed object

256

*/

257

public Value parse(XContentParser parser, Context context) throws IOException;

258

}

259

```

260

261

**Usage Example:**

262

263

```java

264

// Immutable data class with constructor

265

public class ImmutableUser {

266

private final String name;

267

private final int age;

268

private final boolean active;

269

private final List<String> skills;

270

271

public ImmutableUser(String name, int age, boolean active, List<String> skills) {

272

this.name = name;

273

this.age = age;

274

this.active = active;

275

this.skills = skills;

276

}

277

278

// Getters only...

279

}

280

281

// Create constructing parser

282

ConstructingObjectParser<ImmutableUser, Void> parser = new ConstructingObjectParser<>(

283

"immutable_user",

284

args -> new ImmutableUser(

285

(String) args[0], // name

286

(Integer) args[1], // age

287

(Boolean) args[2], // active

288

(List<String>) args[3] // skills

289

)

290

);

291

292

// Declare fields as constructor arguments

293

parser.declareString(constructorArg(), new ParseField("name"));

294

parser.declareInt(constructorArg(), new ParseField("age"));

295

parser.declareBoolean(constructorArg(), new ParseField("active"));

296

parser.declareStringArray(constructorArg(), new ParseField("skills"));

297

298

// Parse content

299

XContentParser contentParser = XContentType.JSON.xContent()

300

.createParser(XContentParserConfiguration.EMPTY, jsonContent);

301

ImmutableUser user = parser.parse(contentParser, null);

302

contentParser.close();

303

```

304

305

### InstantiatingObjectParser

306

307

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

308

309

```java { .api }

310

/**

311

* Parser that uses reflection for object construction

312

* @param <Value> the type of object to instantiate

313

* @param <Context> the type of parsing context

314

*/

315

public class InstantiatingObjectParser<Value, Context>

316

implements BiFunction<XContentParser, Context, Value>, ContextParser<Context, Value> {

317

318

/**

319

* Builder for creating instantiating parsers

320

*/

321

public static class Builder<Value, Context> {

322

323

/**

324

* Create a builder for the specified class

325

* @param name parser name for error messages

326

* @param valueClass class to instantiate

327

* @return builder instance

328

*/

329

public static <Value, Context> Builder<Value, Context> builder(String name, Class<Value> valueClass);

330

331

/**

332

* Create a builder with unknown field handling

333

* @param name parser name for error messages

334

* @param ignoreUnknownFields whether to ignore unknown fields

335

* @param valueClass class to instantiate

336

* @return builder instance

337

*/

338

public static <Value, Context> Builder<Value, Context> builder(String name, boolean ignoreUnknownFields,

339

Class<Value> valueClass);

340

341

/**

342

* Build the parser

343

* @return InstantiatingObjectParser instance

344

*/

345

public InstantiatingObjectParser<Value, Context> build();

346

}

347

348

/**

349

* Parse content and instantiate object

350

* @param parser content parser

351

* @param context parsing context

352

* @return instantiated object

353

*/

354

public Value apply(XContentParser parser, Context context);

355

}

356

357

/**

358

* Annotation to mark constructors for automatic parsing

359

*/

360

@Target(ElementType.CONSTRUCTOR)

361

@Retention(RetentionPolicy.RUNTIME)

362

public @interface ParserConstructor {

363

}

364

```

365

366

**Usage Example:**

367

368

```java

369

// Data class with annotated constructor

370

public class AnnotatedUser {

371

private final String name;

372

private final int age;

373

private final boolean active;

374

375

@ParserConstructor

376

public AnnotatedUser(String name, int age, boolean active) {

377

this.name = name;

378

this.age = age;

379

this.active = active;

380

}

381

382

// Getters...

383

}

384

385

// Create instantiating parser

386

InstantiatingObjectParser<AnnotatedUser, Void> parser =

387

InstantiatingObjectParser.builder("annotated_user", AnnotatedUser.class).build();

388

389

// Parse content (field names must match constructor parameter names)

390

XContentParser contentParser = XContentType.JSON.xContent()

391

.createParser(XContentParserConfiguration.EMPTY, jsonContent);

392

AnnotatedUser user = parser.apply(contentParser, null);

393

contentParser.close();

394

```

395

396

### ValueType Enumeration

397

398

Enumeration defining supported value types for field declarations.

399

400

```java { .api }

401

/**

402

* Enumeration of supported value types for object parsing

403

*/

404

public enum ValueType {

405

STRING,

406

STRING_OR_NULL,

407

FLOAT,

408

FLOAT_OR_NULL,

409

DOUBLE,

410

DOUBLE_OR_NULL,

411

INT,

412

INT_OR_NULL,

413

LONG,

414

LONG_OR_NULL,

415

BOOLEAN,

416

BOOLEAN_OR_NULL,

417

STRING_ARRAY,

418

FLOAT_ARRAY,

419

DOUBLE_ARRAY,

420

INT_ARRAY,

421

LONG_ARRAY,

422

BOOLEAN_ARRAY,

423

OBJECT,

424

OBJECT_OR_NULL,

425

OBJECT_ARRAY,

426

OBJECT_ARRAY_OR_NULL,

427

VALUE,

428

VALUE_OR_NULL,

429

VALUE_ARRAY

430

}

431

```

432

433

### Parser Interfaces

434

435

```java { .api }

436

/**

437

* Interface for parsing objects with context

438

*/

439

@FunctionalInterface

440

public interface ContextParser<Context, T> {

441

/**

442

* Parse an object with the given context

443

* @param parser content parser

444

* @param context parsing context

445

* @return parsed object

446

*/

447

T parse(XContentParser parser, Context context) throws IOException;

448

}

449

450

/**

451

* Interface for parsing named objects

452

*/

453

public interface NamedObjectParser<T, Context> {

454

/**

455

* Parse a named object

456

* @param parser content parser

457

* @param context parsing context

458

* @param name object name

459

* @return parsed object

460

*/

461

T parse(XContentParser parser, Context context, String name) throws IOException;

462

}

463

464

/**

465

* Interface for consuming unknown fields during parsing

466

*/

467

@FunctionalInterface

468

public interface UnknownFieldConsumer<Value> {

469

/**

470

* Accept an unknown field

471

* @param objectParser the parser that encountered the unknown field

472

* @param value the object being parsed

473

* @param fieldName the unknown field name

474

* @param parser content parser positioned at the field value

475

*/

476

void accept(ObjectParser<Value, ?> objectParser, Value value, String fieldName, XContentParser parser);

477

}

478

```