or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcollection-mapping.mdconfiguration-inheritance.mdcore-mapping.mdenum-mapping.mdindex.mdlifecycle-customization.md

advanced-features.mddocs/

0

# Advanced Features

1

2

Advanced mapping control mechanisms, conditional mapping, subclass mapping, and fine-grained control over the mapping process.

3

4

## Capabilities

5

6

### Subclass Mapping

7

8

Support for polymorphic mapping with automatic subclass detection and specialized mappings.

9

10

```java { .api }

11

/**

12

* Configures the mapping to handle inheritance hierarchies.

13

*/

14

@Repeatable(SubclassMappings.class)

15

@Target(ElementType.METHOD)

16

@Retention(RetentionPolicy.CLASS)

17

@interface SubclassMapping {

18

/** Source subclass */

19

Class<?> source();

20

21

/** Target subclass */

22

Class<?> target();

23

24

/** Qualifiers for subclass mapping method selection */

25

Class<? extends Annotation>[] qualifiedBy() default {};

26

27

/** String-based qualifiers for subclass mapping method selection */

28

String[] qualifiedByName() default {};

29

}

30

31

/**

32

* Container for multiple @SubclassMapping annotations.

33

*/

34

@Target(ElementType.METHOD)

35

@Retention(RetentionPolicy.CLASS)

36

@interface SubclassMappings {

37

SubclassMapping[] value();

38

}

39

```

40

41

**Usage Examples:**

42

43

```java

44

// Inheritance hierarchy

45

public abstract class Vehicle {

46

private String brand;

47

private String model;

48

// getters, setters...

49

}

50

51

public class Car extends Vehicle {

52

private int doors;

53

private boolean convertible;

54

// getters, setters...

55

}

56

57

public class Motorcycle extends Vehicle {

58

private boolean hasSidecar;

59

private int engineSize;

60

// getters, setters...

61

}

62

63

// DTO hierarchy

64

public abstract class VehicleDto {

65

private String brand;

66

private String model;

67

// getters, setters...

68

}

69

70

public class CarDto extends VehicleDto {

71

private int doorCount;

72

private boolean isConvertible;

73

// getters, setters...

74

}

75

76

public class MotorcycleDto extends VehicleDto {

77

private boolean hasSidecar;

78

private String engineCapacity;

79

// getters, setters...

80

}

81

82

@Mapper

83

public interface VehicleMapper {

84

// Polymorphic mapping with subclass mappings

85

@SubclassMapping(source = Car.class, target = CarDto.class)

86

@SubclassMapping(source = Motorcycle.class, target = MotorcycleDto.class)

87

VehicleDto toVehicleDto(Vehicle vehicle);

88

89

// Specific subclass mappings

90

@Mapping(source = "doors", target = "doorCount")

91

@Mapping(source = "convertible", target = "isConvertible")

92

CarDto toCarDto(Car car);

93

94

@Mapping(source = "engineSize", target = "engineCapacity", numberFormat = "#,### cc")

95

MotorcycleDto toMotorcycleDto(Motorcycle motorcycle);

96

97

// Collection with subclass mapping

98

@SubclassMapping(source = Car.class, target = CarDto.class)

99

@SubclassMapping(source = Motorcycle.class, target = MotorcycleDto.class)

100

List<VehicleDto> toVehicleDtos(List<Vehicle> vehicles);

101

}

102

```

103

104

### Subclass Exhaustive Strategy

105

106

Strategy for handling missing subclass mappings.

107

108

```java { .api }

109

/**

110

* Strategy for handling missing implementation for super classes when using SubclassMapping.

111

*/

112

enum SubclassExhaustiveStrategy {

113

/** Generate compile error for missing subclass mappings */

114

COMPILE_ERROR,

115

116

/** Throw runtime exception for unmapped subclasses */

117

RUNTIME_EXCEPTION

118

}

119

```

120

121

**Usage Examples:**

122

123

```java

124

@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.COMPILE_ERROR)

125

public interface StrictVehicleMapper {

126

// Compiler will enforce all subclasses are mapped

127

@SubclassMapping(source = Car.class, target = CarDto.class)

128

@SubclassMapping(source = Motorcycle.class, target = MotorcycleDto.class)

129

// Missing Truck.class mapping will cause compile error

130

VehicleDto toVehicleDto(Vehicle vehicle);

131

132

CarDto toCarDto(Car car);

133

MotorcycleDto toMotorcycleDto(Motorcycle motorcycle);

134

// TruckDto toTruckDto(Truck truck); // Must be implemented

135

}

136

137

@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION)

138

public interface RuntimeVehicleMapper {

139

// Missing subclass mappings will throw runtime exception

140

@SubclassMapping(source = Car.class, target = CarDto.class)

141

VehicleDto toVehicleDto(Vehicle vehicle);

142

143

CarDto toCarDto(Car car);

144

// Mapping Motorcycle without SubclassMapping will throw exception at runtime

145

}

146

```

147

148

### Mapping Control Annotations

149

150

Fine-grained control over which mapping mechanisms are allowed.

151

152

```java { .api }

153

/**

154

* Meta-annotation to mark an annotation as a mapping control annotation.

155

*/

156

@Target(ElementType.ANNOTATION_TYPE)

157

@Retention(RetentionPolicy.CLASS)

158

@interface MappingControl {

159

/** Allowed mapping mechanisms */

160

MappingControl[] value() default {};

161

}

162

163

/**

164

* Enum defining the types of mapping mechanisms.

165

*/

166

enum MappingControl {

167

/** Direct assignment (no conversion) */

168

DIRECT,

169

170

/** Built-in type conversions */

171

BUILT_IN_CONVERSION,

172

173

/** User-defined mapping methods */

174

MAPPING_METHOD,

175

176

/** Complex mappings (multi-step conversions) */

177

COMPLEX_MAPPING

178

}

179

```

180

181

**Predefined Control Annotations:**

182

183

```java { .api }

184

/**

185

* Forces deep cloning by only allowing mapping methods.

186

*/

187

@MappingControl(MappingControl.MAPPING_METHOD)

188

@Target({ElementType.TYPE, ElementType.METHOD})

189

@Retention(RetentionPolicy.CLASS)

190

@interface DeepClone {

191

}

192

193

/**

194

* Disables complex mappings (multi-step transformations).

195

*/

196

@MappingControl({MappingControl.DIRECT, MappingControl.BUILT_IN_CONVERSION, MappingControl.MAPPING_METHOD})

197

@Target({ElementType.TYPE, ElementType.METHOD})

198

@Retention(RetentionPolicy.CLASS)

199

@interface NoComplexMapping {

200

}

201

202

/**

203

* Container for multiple @MappingControl annotations.

204

*/

205

@Target({ElementType.TYPE, ElementType.METHOD})

206

@Retention(RetentionPolicy.CLASS)

207

@interface MappingControls {

208

Class<? extends Annotation>[] value();

209

}

210

```

211

212

**Usage Examples:**

213

214

```java

215

// Deep cloning mapper - forces all mappings through methods

216

@Mapper

217

@DeepClone

218

public interface DeepCloneMapper {

219

PersonDto toPersonDto(Person person);

220

221

// All nested objects will be deeply cloned through mapping methods

222

OrderDto toOrderDto(Order order);

223

224

// Custom deep cloning method

225

AddressDto cloneAddress(Address address);

226

}

227

228

// No complex mapping - prevents multi-step conversions

229

@Mapper

230

public interface SimpleMapper {

231

@NoComplexMapping

232

@Mapping(source = "name", target = "fullName")

233

UserDto toUserDto(User user);

234

235

// Only direct assignments and built-in conversions allowed

236

ProductDto toProductDto(Product product);

237

}

238

239

// Custom mapping control

240

@MappingControl({MappingControl.DIRECT, MappingControl.MAPPING_METHOD})

241

@Target(ElementType.METHOD)

242

@Retention(RetentionPolicy.CLASS)

243

public @interface DirectOrCustomOnly {

244

}

245

246

@Mapper

247

public interface ControlledMapper {

248

@DirectOrCustomOnly

249

@Mapping(source = "value", target = "result")

250

ResultDto toResultDto(Source source);

251

252

// Custom method for controlled mapping

253

String transformValue(String input);

254

}

255

```

256

257

### Builder Pattern Support

258

259

Configuration for builder pattern integration in target objects.

260

261

```java { .api }

262

/**

263

* Configuration for builder pattern support.

264

*/

265

@Target({ElementType.TYPE, ElementType.METHOD})

266

@Retention(RetentionPolicy.CLASS)

267

@interface Builder {

268

/** Name of the build method */

269

String buildMethod() default "build";

270

271

/** Disable builder pattern */

272

boolean disableBuilder() default false;

273

}

274

```

275

276

**Usage Examples:**

277

278

```java

279

// Target class with builder

280

public class PersonDto {

281

private String name;

282

private int age;

283

private String email;

284

285

// Private constructor

286

private PersonDto(Builder builder) {

287

this.name = builder.name;

288

this.age = builder.age;

289

this.email = builder.email;

290

}

291

292

public static Builder builder() {

293

return new Builder();

294

}

295

296

public static class Builder {

297

private String name;

298

private int age;

299

private String email;

300

301

public Builder name(String name) {

302

this.name = name;

303

return this;

304

}

305

306

public Builder age(int age) {

307

this.age = age;

308

return this;

309

}

310

311

public Builder email(String email) {

312

this.email = email;

313

return this;

314

}

315

316

public PersonDto build() {

317

return new PersonDto(this);

318

}

319

}

320

321

// getters...

322

}

323

324

@Mapper

325

public interface BuilderMapper {

326

// Automatically uses builder pattern

327

PersonDto toPersonDto(Person person);

328

329

// Custom builder configuration

330

@Builder(buildMethod = "create")

331

CustomDto toCustomDto(Entity entity);

332

333

// Disable builder for specific mapping

334

@Builder(disableBuilder = true)

335

SimpleDto toSimpleDto(SimpleEntity entity);

336

}

337

```

338

339

### Annotation Processing Control

340

341

Control over generated code annotations and metadata.

342

343

```java { .api }

344

// Mapper configuration affecting generated code

345

@Mapper(

346

suppressTimestampInGenerated = true, // Remove timestamp from @Generated

347

implementationName = "Custom<CLASS_NAME>Impl", // Custom implementation name

348

implementationPackage = "com.example.generated" // Custom package

349

)

350

public interface ProcessingControlMapper {

351

PersonDto toPersonDto(Person person);

352

}

353

```

354

355

### Experimental Features

356

357

Access to experimental features that may change in future versions.

358

359

```java { .api }

360

/**

361

* Marks features as experimental and subject to change.

362

*/

363

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})

364

@Retention(RetentionPolicy.CLASS)

365

@interface Experimental {

366

}

367

```

368

369

**Usage Examples:**

370

371

```java

372

@Mapper

373

public interface ExperimentalMapper {

374

@Experimental

375

@Mapping(target = "newField", expression = "java(experimentalTransform(source.getValue()))")

376

ExperimentalDto toExperimentalDto(Source source);

377

378

@Experimental

379

default String experimentalTransform(String input) {

380

// Experimental transformation logic

381

return input != null ? input.transform(String::toUpperCase) : null;

382

}

383

}

384

```

385

386

### Advanced Error Handling

387

388

Custom exception handling for mapping operations.

389

390

**Usage Examples:**

391

392

```java

393

@Mapper(unexpectedValueMappingException = MappingException.class)

394

public interface ErrorHandlingMapper {

395

// Custom exception for enum mapping errors

396

StatusDto mapStatus(Status status);

397

398

// Method-level exception override

399

@BeanMapping(unexpectedValueMappingException = ValidationException.class)

400

ValidatedDto toValidatedDto(Entity entity);

401

}

402

403

// Custom exceptions

404

public class MappingException extends RuntimeException {

405

public MappingException(String message) {

406

super(message);

407

}

408

}

409

410

public class ValidationException extends Exception {

411

public ValidationException(String message, Throwable cause) {

412

super(message, cause);

413

}

414

}

415

```

416

417

### Performance Optimizations

418

419

Advanced configuration for optimizing generated mapping code.

420

421

**Usage Examples:**

422

423

```java

424

@Mapper(

425

// Disable automatic sub-mapping generation for performance

426

disableSubMappingMethodsGeneration = true,

427

428

// Use constructor injection for better performance

429

injectionStrategy = InjectionStrategy.CONSTRUCTOR,

430

431

// Strict null checking strategy

432

nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS

433

)

434

public interface PerformanceMapper {

435

PersonDto toPersonDto(Person person);

436

437

// Explicit sub-mapping methods for control

438

AddressDto toAddressDto(Address address);

439

440

PhoneDto toPhoneDto(Phone phone);

441

}

442

```

443

444

### Integration with Validation Frameworks

445

446

Integration patterns with validation frameworks.

447

448

**Usage Examples:**

449

450

```java

451

@Mapper

452

public abstract class ValidatingMapper {

453

@Autowired

454

private Validator validator;

455

456

public PersonDto toPersonDto(Person person) {

457

PersonDto dto = mapPersonDto(person);

458

459

// Validate the result

460

Set<ConstraintViolation<PersonDto>> violations = validator.validate(dto);

461

if (!violations.isEmpty()) {

462

throw new ValidationException("Mapping validation failed: " + violations);

463

}

464

465

return dto;

466

}

467

468

@Mapping(source = "firstName", target = "name")

469

@Mapping(source = "birthDate", target = "dateOfBirth", dateFormat = "yyyy-MM-dd")

470

protected abstract PersonDto mapPersonDto(Person person);

471

472

@AfterMapping

473

protected void validateResult(@MappingTarget PersonDto dto) {

474

if (dto.getName() == null || dto.getName().trim().isEmpty()) {

475

throw new IllegalStateException("Name cannot be empty after mapping");

476

}

477

}

478

}

479

```