or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdcustom-serialization.mdfield-access.mdindex.mdpolymorphic-schemas.mdruntime-environment.mdschema-generation.mdtype-strategy.md

polymorphic-schemas.mddocs/

0

# Polymorphic Schema Factories

1

2

Factory system for creating polymorphic schemas that handle inheritance, collections, and complex object hierarchies. Polymorphic schemas enable protostuff-runtime to serialize and deserialize objects when the exact type is not known at compile time, supporting inheritance, collections, maps, and other complex object graphs.

3

4

## Capabilities

5

6

### PolymorphicSchemaFactories Enum

7

8

Central enum providing predefined factory implementations for different types of polymorphic scenarios.

9

10

```java { .api }

11

/**

12

* Enum providing polymorphic schema factories for different object types

13

*/

14

public enum PolymorphicSchemaFactories implements PolymorphicSchema.Factory {

15

16

/**

17

* Factory for array types

18

*/

19

ARRAY,

20

21

/**

22

* Factory for numeric wrapper types (Integer, Long, etc.)

23

*/

24

NUMBER,

25

26

/**

27

* Factory for Class objects

28

*/

29

CLASS,

30

31

/**

32

* Factory for enum types

33

*/

34

ENUM,

35

36

/**

37

* Factory for collection types (List, Set, etc.)

38

*/

39

COLLECTION,

40

41

/**

42

* Factory for map types

43

*/

44

MAP,

45

46

/**

47

* Factory for Throwable and exception types

48

*/

49

THROWABLE,

50

51

/**

52

* Factory for Plain Old Java Objects (POJOs)

53

*/

54

POJO,

55

56

/**

57

* Factory for POJO map implementations

58

*/

59

POJO_MAP,

60

61

/**

62

* Factory for POJO collection implementations

63

*/

64

POJO_COLLECTION,

65

66

/**

67

* Factory for generic Object types

68

*/

69

OBJECT;

70

}

71

```

72

73

### Factory Selection Methods

74

75

Static methods for automatically selecting appropriate factory based on field or type information.

76

77

```java { .api }

78

/**

79

* Get appropriate factory based on field reflection information

80

* @param f Java reflection field to analyze

81

* @param strategy ID strategy for polymorphic handling

82

* @return Appropriate polymorphic schema factory

83

*/

84

public static PolymorphicSchema.Factory getFactoryFromField(java.lang.reflect.Field f, IdStrategy strategy);

85

86

/**

87

* Get factory for repeated value generic types

88

* @param clazz Class with generic type information

89

* @return Appropriate factory for the repeated value type

90

*/

91

public static PolymorphicSchema.Factory getFactoryFromRepeatedValueGenericType(Class<?> clazz);

92

93

/**

94

* Get schema for collection or map with generic type information

95

* @param clazz Collection or map class

96

* @param strategy ID strategy for polymorphic handling

97

* @return Polymorphic schema instance

98

*/

99

public static PolymorphicSchema getSchemaFromCollectionOrMapGenericType(Class<?> clazz, IdStrategy strategy);

100

```

101

102

## Polymorphic Schema Classes

103

104

### PolymorphicSchema Base Class

105

106

Base class for all polymorphic schema implementations providing common functionality for type identification and serialization.

107

108

```java { .api }

109

/**

110

* Base class for polymorphic schema implementations

111

*/

112

public abstract class PolymorphicSchema implements Schema<Object> {

113

114

/**

115

* Factory interface for creating polymorphic schemas

116

*/

117

public interface Factory {

118

/**

119

* Create polymorphic schema for the specified class

120

* @param typeClass Class to create schema for

121

* @param strategy ID strategy for type handling

122

* @return Polymorphic schema instance

123

*/

124

PolymorphicSchema create(Class<?> typeClass, IdStrategy strategy);

125

}

126

127

/**

128

* Get the ID strategy used by this schema

129

* @return ID strategy instance

130

*/

131

public IdStrategy getStrategy();

132

133

/**

134

* Create new message instance

135

* @return New Object instance

136

*/

137

public Object newMessage();

138

139

/**

140

* Get message name for this schema

141

* @return Message name string

142

*/

143

public String messageName();

144

145

/**

146

* Get full message name for this schema

147

* @return Full message name string

148

*/

149

public String messageFullName();

150

151

/**

152

* Get type class for this schema

153

* @return Class type

154

*/

155

public Class<Object> typeClass();

156

}

157

```

158

159

### Specialized Polymorphic Schema Classes

160

161

Concrete implementations for specific polymorphic scenarios.

162

163

```java { .api }

164

/**

165

* Polymorphic schema for array types

166

*/

167

public abstract class ArraySchema extends PolymorphicSchema {

168

// Handles arrays of various types with type information

169

}

170

171

/**

172

* Polymorphic schema for numeric wrapper types

173

*/

174

public abstract class NumberSchema extends PolymorphicSchema {

175

// Handles Integer, Long, Double, Float, etc.

176

}

177

178

/**

179

* Polymorphic schema for Class objects

180

*/

181

public abstract class ClassSchema extends PolymorphicSchema {

182

// Handles Class<?> instances with type safety

183

}

184

185

/**

186

* Polymorphic schema for enum types

187

*/

188

public abstract class PolymorphicEnumSchema extends PolymorphicSchema {

189

// Handles enum values with type identification

190

}

191

192

/**

193

* Polymorphic schema for collection types

194

*/

195

public abstract class PolymorphicCollectionSchema extends PolymorphicSchema {

196

// Handles List, Set, Queue, and other collection interfaces

197

}

198

199

/**

200

* Polymorphic schema for map types

201

*/

202

public abstract class PolymorphicMapSchema extends PolymorphicSchema {

203

// Handles Map interfaces and implementations

204

}

205

206

/**

207

* Polymorphic schema for POJO types

208

*/

209

public abstract class PolymorphicPojoSchema extends PolymorphicSchema {

210

// Handles Plain Old Java Objects with inheritance

211

}

212

213

/**

214

* Polymorphic schema for POJO collections

215

*/

216

public abstract class PolymorphicPojoCollectionSchema extends PolymorphicSchema {

217

// Handles collections containing POJOs

218

}

219

220

/**

221

* Polymorphic schema for POJO maps

222

*/

223

public abstract class PolymorphicPojoMapSchema extends PolymorphicSchema {

224

// Handles maps containing POJOs

225

}

226

227

/**

228

* Polymorphic schema for Throwable types

229

*/

230

public abstract class PolymorphicThrowableSchema extends PolymorphicSchema {

231

// Handles exceptions and errors with inheritance

232

}

233

234

/**

235

* Polymorphic schema for generic Object types

236

*/

237

public abstract class ObjectSchema extends PolymorphicSchema {

238

// Handles generic Object references

239

}

240

```

241

242

### DerivativeSchema

243

244

Special schema implementation for handling derived or wrapped types.

245

246

```java { .api }

247

/**

248

* Schema for derivative types that wrap or extend other types

249

*/

250

public abstract class DerivativeSchema implements Schema<Object> {

251

252

/**

253

* Get the base schema this derivative extends

254

* @return Base schema instance

255

*/

256

public abstract Schema<?> getBaseSchema();

257

258

/**

259

* Check if this schema can handle the specified type

260

* @param typeClass Class to check

261

* @return true if this schema can handle the type

262

*/

263

public abstract boolean canHandle(Class<?> typeClass);

264

}

265

```

266

267

## Usage Examples

268

269

### Automatic Factory Selection

270

271

```java

272

import io.protostuff.runtime.PolymorphicSchemaFactories;

273

import io.protostuff.runtime.DefaultIdStrategy;

274

import java.lang.reflect.Field;

275

276

// Automatic factory selection based on field

277

public class User {

278

public List<String> tags; // Collection field

279

public Map<String, Object> data; // Map field

280

public Animal pet; // POJO field with inheritance

281

public Status status; // Enum field

282

}

283

284

DefaultIdStrategy strategy = new DefaultIdStrategy();

285

286

// Get factories for different field types

287

Field tagsField = User.class.getField("tags");

288

PolymorphicSchema.Factory collectionFactory =

289

PolymorphicSchemaFactories.getFactoryFromField(tagsField, strategy);

290

291

Field dataField = User.class.getField("data");

292

PolymorphicSchema.Factory mapFactory =

293

PolymorphicSchemaFactories.getFactoryFromField(dataField, strategy);

294

295

Field petField = User.class.getField("pet");

296

PolymorphicSchema.Factory pojoFactory =

297

PolymorphicSchemaFactories.getFactoryFromField(petField, strategy);

298

299

Field statusField = User.class.getField("status");

300

PolymorphicSchema.Factory enumFactory =

301

PolymorphicSchemaFactories.getFactoryFromField(statusField, strategy);

302

```

303

304

### Manual Factory Usage

305

306

```java

307

// Direct factory usage for specific scenarios

308

DefaultIdStrategy strategy = new DefaultIdStrategy();

309

310

// Create schemas using specific factories

311

PolymorphicSchema arraySchema = PolymorphicSchemaFactories.ARRAY.create(String[].class, strategy);

312

PolymorphicSchema collectionSchema = PolymorphicSchemaFactories.COLLECTION.create(List.class, strategy);

313

PolymorphicSchema mapSchema = PolymorphicSchemaFactories.MAP.create(Map.class, strategy);

314

PolymorphicSchema pojoSchema = PolymorphicSchemaFactories.POJO.create(User.class, strategy);

315

316

// Use schemas for polymorphic serialization

317

// (requires protostuff-core for actual serialization)

318

```

319

320

### Collection and Map Generic Type Handling

321

322

```java

323

import java.util.*;

324

325

// Handle complex generic types

326

Class<List<User>> userListClass = (Class<List<User>>) (Class<?>) List.class;

327

PolymorphicSchema userListSchema =

328

PolymorphicSchemaFactories.getSchemaFromCollectionOrMapGenericType(userListClass, strategy);

329

330

Class<Map<String, List<User>>> complexMapClass =

331

(Class<Map<String, List<User>>>) (Class<?>) Map.class;

332

PolymorphicSchema complexMapSchema =

333

PolymorphicSchemaFactories.getSchemaFromCollectionOrMapGenericType(complexMapClass, strategy);

334

335

// Factory for repeated value types in collections

336

PolymorphicSchema.Factory repeatedFactory =

337

PolymorphicSchemaFactories.getFactoryFromRepeatedValueGenericType(User.class);

338

```

339

340

### Inheritance Hierarchy Handling

341

342

```java

343

// Define inheritance hierarchy

344

public abstract class Animal {

345

public String name;

346

}

347

348

public class Dog extends Animal {

349

public String breed;

350

}

351

352

public class Cat extends Animal {

353

public boolean indoor;

354

}

355

356

// Register polymorphic types

357

DefaultIdStrategy strategy = new DefaultIdStrategy();

358

strategy.registerPojo(Animal.class);

359

strategy.registerPojo(Dog.class);

360

strategy.registerPojo(Cat.class);

361

362

// Map inheritance relationships

363

strategy.map(Animal.class, Dog.class);

364

strategy.map(Animal.class, Cat.class);

365

366

// Create polymorphic schema for the base class

367

PolymorphicSchema animalSchema = PolymorphicSchemaFactories.POJO.create(Animal.class, strategy);

368

369

// The schema can now handle Dog, Cat, or any other Animal subtype

370

```

371

372

### Custom Polymorphic Schema Creation

373

374

```java

375

/**

376

* Custom polymorphic schema factory for special handling

377

*/

378

public class CustomPolymorphicFactory implements PolymorphicSchema.Factory {

379

380

@Override

381

public PolymorphicSchema create(Class<?> typeClass, IdStrategy strategy) {

382

if (isSpecialType(typeClass)) {

383

return new CustomPolymorphicSchema(typeClass, strategy);

384

}

385

// Delegate to appropriate default factory

386

return PolymorphicSchemaFactories.POJO.create(typeClass, strategy);

387

}

388

389

private boolean isSpecialType(Class<?> typeClass) {

390

// Custom logic to identify special types

391

return typeClass.isAnnotationPresent(CustomSerialization.class);

392

}

393

}

394

395

// Custom schema implementation

396

public class CustomPolymorphicSchema extends PolymorphicSchema {

397

398

private final Class<?> typeClass;

399

private final IdStrategy strategy;

400

401

public CustomPolymorphicSchema(Class<?> typeClass, IdStrategy strategy) {

402

this.typeClass = typeClass;

403

this.strategy = strategy;

404

}

405

406

@Override

407

public Object newMessage() {

408

// Custom object creation logic

409

return createCustomInstance(typeClass);

410

}

411

412

// Implement other required methods...

413

}

414

```

415

416

## Factory Selection Logic

417

418

The `getFactoryFromField` method uses the following logic to select appropriate factories:

419

420

1. **Array Types**: Returns `ARRAY` factory for array fields

421

2. **Collection Types**: Returns `COLLECTION` for List, Set, Queue interfaces

422

3. **Map Types**: Returns `MAP` for Map interfaces

423

4. **Enum Types**: Returns `ENUM` for enum fields

424

5. **Number Types**: Returns `NUMBER` for numeric wrapper types

425

6. **Class Types**: Returns `CLASS` for Class<?> fields

426

7. **Throwable Types**: Returns `THROWABLE` for exception fields

427

8. **POJO Types**: Returns `POJO` for custom object types

428

9. **Object Types**: Returns `OBJECT` for generic Object fields

429

430

## Configuration with IdStrategy

431

432

Polymorphic schemas work closely with `IdStrategy` configuration:

433

434

```java

435

// Configure strategy with polymorphic flags

436

int flags = IdStrategy.MORPH_COLLECTION_INTERFACES

437

| IdStrategy.MORPH_MAP_INTERFACES

438

| IdStrategy.MORPH_NON_FINAL_POJOS

439

| IdStrategy.COLLECTION_SCHEMA_ON_REPEATED_FIELDS;

440

441

DefaultIdStrategy strategy = new DefaultIdStrategy(flags);

442

443

// Register types for polymorphic handling

444

strategy.registerPojo(BaseClass.class);

445

strategy.registerPojo(DerivedClass1.class);

446

strategy.registerPojo(DerivedClass2.class);

447

448

// Create polymorphic schemas with configured strategy

449

PolymorphicSchema schema = PolymorphicSchemaFactories.POJO.create(BaseClass.class, strategy);

450

```

451

452

## Performance Considerations

453

454

1. **Factory Caching**: Factories cache created schemas for performance

455

2. **Type Registration**: Pre-register polymorphic types for better performance

456

3. **Strategy Configuration**: Configure IdStrategy flags appropriately for your use case

457

4. **Generic Type Resolution**: Complex generic types may have resolution overhead

458

5. **Inheritance Depth**: Deep inheritance hierarchies may impact performance

459

460

## Best Practices

461

462

1. **Type Registration**: Register all polymorphic types upfront with IdStrategy

463

2. **Factory Selection**: Use automatic factory selection when possible

464

3. **Generic Types**: Be explicit about generic type parameters for better schema generation

465

4. **Strategy Configuration**: Configure IdStrategy flags based on your polymorphic requirements

466

5. **Error Handling**: Handle UnknownTypeException for unregistered polymorphic types

467

6. **Testing**: Test polymorphic serialization with all expected type combinations