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.