or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

build-integration.mdcli.mdcode-generation.mderror-handling.mdindex.mdplugin-system.mdprogrammatic-api.md

code-generation.mddocs/

0

# Code Generation and Customization

1

2

The JAXB XJC code generation system provides comprehensive control over how Java classes are generated from XML schemas, with customizable field rendering, type mapping, and code structure.

3

4

## Capabilities

5

6

### Generation Outline System

7

8

The outline system provides a structured view of the generated code, allowing plugins and customization to modify the generation process.

9

10

```java { .api }

11

/**

12

* Root interface providing access to all generated code elements

13

*/

14

public interface Outline {

15

/**

16

* Get the underlying schema model

17

* @return Model containing parsed schema information

18

*/

19

Model getModel();

20

21

/**

22

* Get the CodeModel containing generated classes

23

* @return JCodeModel with all generated code

24

*/

25

JCodeModel getCodeModel();

26

27

/**

28

* Get all generated class outlines

29

* @return Collection of ClassOutline objects

30

*/

31

Collection<? extends ClassOutline> getClasses();

32

33

/**

34

* Get specific class outline for a model class

35

* @param clazz CClassInfo from the model

36

* @return ClassOutline for the specified class, or null if not found

37

*/

38

ClassOutline getClazz(CClassInfo clazz);

39

40

/**

41

* Get field outline for a specific property

42

* @param fu CPropertyInfo from the model

43

* @return FieldOutline for the specified property, or null if not found

44

*/

45

FieldOutline getField(CPropertyInfo fu);

46

47

/**

48

* Get package context for a specific package

49

* @param _Package JPackage to get context for

50

* @return PackageOutline containing package-level information

51

*/

52

PackageOutline getPackageContext(JPackage _Package);

53

}

54

```

55

56

### Class-Level Code Generation

57

58

Per-class code generation information and customization points.

59

60

```java { .api }

61

/**

62

* Represents generated code for a single XML Schema complex type

63

*/

64

public abstract class ClassOutline {

65

/**

66

* Target class information from the model

67

*/

68

public final CClassInfo target;

69

70

/**

71

* Generated class reference in the code model

72

*/

73

public final JDefinedClass ref;

74

75

/**

76

* Get parent outline

77

* @return Parent Outline object

78

*/

79

public abstract Outline parent();

80

81

/**

82

* Get all declared fields for this class

83

* @return Array of FieldOutline objects

84

*/

85

public abstract FieldOutline[] getDeclaredFields();

86

87

/**

88

* Get superclass outline if this class extends another generated class

89

* @return ClassOutline of superclass, or null if no generated superclass

90

*/

91

public abstract ClassOutline getSuperClass();

92

}

93

```

94

95

### Field-Level Code Generation

96

97

Fine-grained control over individual field generation and access patterns.

98

99

```java { .api }

100

/**

101

* Represents generated code for a single XML Schema element or attribute

102

*/

103

public abstract class FieldOutline {

104

/**

105

* Get the property information from the model

106

* @return CPropertyInfo containing schema binding information

107

*/

108

public abstract CPropertyInfo getPropertyInfo();

109

110

/**

111

* Get the parent class outline

112

* @return ClassOutline containing this field

113

*/

114

public abstract ClassOutline parent();

115

116

/**

117

* Get the raw Java type for this field

118

* @return JType representing the Java type

119

*/

120

public abstract JType getRawType();

121

122

/**

123

* Generate getter method expression

124

* @return JExpression for accessing the field value

125

*/

126

public abstract JExpression createGetter();

127

128

/**

129

* Generate setter method expression

130

* @param value JExpression representing the value to set

131

* @return JExpression for setting the field value

132

*/

133

public abstract JExpression createSetter(JExpression value);

134

}

135

```

136

137

### Field Rendering System

138

139

Customizable field rendering strategies for different collection and property types.

140

141

```java { .api }

142

/**

143

* Factory for creating field renderers based on property characteristics

144

*/

145

public interface FieldRendererFactory {

146

/**

147

* Get default field renderer for single-valued properties

148

* @return FieldRenderer for default single value fields

149

*/

150

FieldRenderer getDefault();

151

152

/**

153

* Get array field renderer for array properties

154

* @return FieldRenderer for array fields

155

*/

156

FieldRenderer getArray();

157

158

/**

159

* Get list field renderer for collection properties

160

* @param coreList JClass representing the list implementation type

161

* @return FieldRenderer for list fields

162

*/

163

FieldRenderer getList(JClass coreList);

164

165

/**

166

* Get single field renderer for required single-valued properties

167

* @return FieldRenderer for required single value fields

168

*/

169

FieldRenderer getSingle();

170

171

/**

172

* Get constant field renderer with fallback for read-only properties

173

* @param fallback FieldRenderer to use as fallback for non-constant cases

174

* @return FieldRenderer for constant fields

175

*/

176

FieldRenderer getConst(FieldRenderer fallback);

177

}

178

179

/**

180

* Strategy interface for rendering individual fields with different access patterns

181

*/

182

public interface FieldRenderer {

183

// Implementation details vary by renderer type

184

// Generates appropriate getter/setter methods and field declarations

185

}

186

```

187

188

**Custom Field Renderer Example:**

189

190

```java

191

import com.sun.tools.xjc.generator.bean.field.*;

192

import com.sun.tools.xjc.outline.*;

193

import com.sun.codemodel.*;

194

195

public class FluentFieldRenderer implements FieldRenderer {

196

private final FieldRenderer core;

197

198

public FluentFieldRenderer(FieldRenderer core) {

199

this.core = core;

200

}

201

202

// Generate fluent setter methods that return 'this'

203

public JMethod generateSetter(ClassOutline classOutline, FieldOutline fieldOutline) {

204

JMethod setter = core.generateSetter(classOutline, fieldOutline);

205

206

// Modify return type to be fluent

207

setter.type(classOutline.ref);

208

setter.body()._return(JExpr._this());

209

210

return setter;

211

}

212

}

213

```

214

215

### Bean Generation System

216

217

Main bean generator implementing the generation process from model to code.

218

219

```java { .api }

220

/**

221

* Primary bean generator that implements the Outline interface

222

*/

223

public class BeanGenerator implements Outline {

224

/**

225

* Generate Java beans from the provided model

226

* @param model Schema model containing all type information

227

* @param errorReceiver Error handler for generation issues

228

* @return Outline containing all generated code

229

*/

230

public static Outline generate(Model model, ErrorReceiver errorReceiver);

231

232

// Outline interface implementation

233

public Model getModel();

234

public JCodeModel getCodeModel();

235

public Collection<? extends ClassOutline> getClasses();

236

public ClassOutline getClazz(CClassInfo clazz);

237

public FieldOutline getField(CPropertyInfo fu);

238

public PackageOutline getPackageContext(JPackage _Package);

239

}

240

241

/**

242

* Interface for generating ObjectFactory classes

243

*/

244

public interface ObjectFactoryGenerator {

245

/**

246

* Generate factory methods for the specified element

247

* @param cc ClassOutline for the containing class

248

* @param element CElementInfo for the element

249

* @param eo ElementOutline containing element generation info

250

*/

251

void populate(ClassOutline cc, CElementInfo element, ElementOutline eo);

252

}

253

```

254

255

### Package-Level Generation

256

257

Package-level code generation and organization.

258

259

```java { .api }

260

/**

261

* Package-level information and generated content

262

*/

263

public interface PackageOutline {

264

/**

265

* Get the JPackage representing this package

266

* @return JPackage in the code model

267

*/

268

JPackage _package();

269

270

/**

271

* Get ObjectFactory class for this package

272

* @return JDefinedClass representing the ObjectFactory

273

*/

274

JDefinedClass objectFactory();

275

276

/**

277

* Get package-info class if generated

278

* @return JDefinedClass for package-info, or null if not generated

279

*/

280

JDefinedClass packageInfo();

281

}

282

```

283

284

### Code Generation Customization

285

286

Advanced customization options and patterns for specialized generation needs.

287

288

**Custom Code Writer:**

289

```java

290

import com.sun.codemodel.*;

291

import com.sun.codemodel.writer.FileCodeWriter;

292

import java.io.File;

293

import java.io.IOException;

294

295

public class CustomCodeWriter extends FileCodeWriter {

296

297

public CustomCodeWriter(File target) throws IOException {

298

super(target);

299

}

300

301

@Override

302

public Writer openSource(JPackage pkg, String fileName) throws IOException {

303

// Add custom header to all generated files

304

Writer writer = super.openSource(pkg, fileName);

305

writer.write("// This file was generated by Custom XJC Plugin\n");

306

writer.write("// Generation time: " + new Date() + "\n\n");

307

return writer;

308

}

309

}

310

```

311

312

**Type Mapping Customization:**

313

```java

314

import com.sun.tools.xjc.model.Model;

315

import com.sun.tools.xjc.model.CClassInfo;

316

import com.sun.codemodel.JType;

317

318

public class CustomTypeMapping {

319

320

public static void customizeModel(Model model) {

321

// Replace default date handling

322

for (CClassInfo classInfo : model.beans().values()) {

323

for (CPropertyInfo property : classInfo.getProperties()) {

324

if (property.getName(false).toLowerCase().contains("date")) {

325

// Customize date property generation

326

customizeDateProperty(property);

327

}

328

}

329

}

330

}

331

332

private static void customizeDateProperty(CPropertyInfo property) {

333

// Custom date handling logic

334

// Could change type mapping, add custom adapters, etc.

335

}

336

}

337

```

338

339

### Generation Examples

340

341

**Basic Code Generation:**

342

```java

343

import com.sun.tools.xjc.api.*;

344

import com.sun.tools.xjc.generator.bean.BeanGenerator;

345

import com.sun.tools.xjc.model.Model;

346

import com.sun.tools.xjc.outline.Outline;

347

import com.sun.codemodel.*;

348

349

// Parse schema and create model

350

SchemaCompiler compiler = XJC.createSchemaCompiler();

351

compiler.parseSchema(schemaSource);

352

S2JJAXBModel jaxbModel = compiler.bind();

353

354

// Generate outline

355

Model model = ((ModelImpl) jaxbModel).getModel();

356

Outline outline = BeanGenerator.generate(model, errorReceiver);

357

358

// Access generated classes

359

for (ClassOutline classOutline : outline.getClasses()) {

360

JDefinedClass generatedClass = classOutline.ref;

361

System.out.println("Generated class: " + generatedClass.fullName());

362

363

// Examine fields

364

for (FieldOutline fieldOutline : classOutline.getDeclaredFields()) {

365

String fieldName = fieldOutline.getPropertyInfo().getName(false);

366

JType fieldType = fieldOutline.getRawType();

367

System.out.printf(" Field: %s %s%n", fieldType.name(), fieldName);

368

}

369

}

370

```

371

372

**Custom Field Rendering:**

373

```java

374

import com.sun.tools.xjc.Options;

375

import com.sun.tools.xjc.generator.bean.field.*;

376

377

// Create custom field renderer factory

378

FieldRendererFactory customFactory = new FieldRendererFactory() {

379

@Override

380

public FieldRenderer getDefault() {

381

return new FluentFieldRenderer(new DefaultFieldRenderer());

382

}

383

384

@Override

385

public FieldRenderer getList(JClass coreList) {

386

return new ImmutableListFieldRenderer(coreList);

387

}

388

389

// ... other renderer methods

390

};

391

392

// Apply custom factory to options

393

Options options = new Options();

394

options.setFieldRendererFactory(customFactory, null);

395

```

396

397

**Post-Generation Customization:**

398

```java

399

public class PostGenerationCustomizer {

400

401

public static void customize(Outline outline) {

402

// Add custom methods to all generated classes

403

for (ClassOutline classOutline : outline.getClasses()) {

404

addValidationMethod(classOutline);

405

addBuilderPattern(classOutline);

406

addToStringMethod(classOutline);

407

}

408

}

409

410

private static void addValidationMethod(ClassOutline classOutline) {

411

JDefinedClass clazz = classOutline.ref;

412

JCodeModel codeModel = clazz.owner();

413

414

// Add validate() method

415

JMethod validate = clazz.method(JMod.PUBLIC, codeModel.VOID, "validate");

416

validate.annotate(Override.class);

417

418

JBlock body = validate.body();

419

420

// Add validation logic for each field

421

for (FieldOutline fieldOutline : classOutline.getDeclaredFields()) {

422

CPropertyInfo property = fieldOutline.getPropertyInfo();

423

if (property.isRequired()) {

424

JExpression getter = fieldOutline.createGetter();

425

JConditional nullCheck = body._if(getter.eq(JExpr._null()));

426

nullCheck._then()._throw(JExpr._new(codeModel.ref(IllegalStateException.class))

427

.arg("Required field " + property.getName(false) + " is null"));

428

}

429

}

430

}

431

}

432

```

433

434

This code generation system provides complete control over how XML schemas are transformed into Java code, enabling developers to create highly customized and optimized JAXB bindings for their specific use cases.