@autorest/java 4.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,720 @@
1
+ # Overview
2
+
3
+ The `azure-autorest-customization` package provides APIs for customizing Autorest code generation safely and
4
+ programmatically to support special cases not supported by Autorest code generation directly using Eclipse language
5
+ server to ensure valid Java code.
6
+
7
+ To set up customizations, create a Maven project with dependency:
8
+
9
+ ```xml
10
+ <dependency>
11
+ <groupId>com.azure.tools</groupId>
12
+ <artifactId>azure-autorest-customization</artifactId>
13
+ <version>1.0.0-beta.7</version>
14
+ </dependency>
15
+ ```
16
+
17
+ Create a customization class extending from `com.azure.autorest.customization.Customization` and override the
18
+ `void customize(LibraryCustomization, Logger)` method. You will have access to a `LibraryCustomization` class where you
19
+ will be able to customize the generated Java code before it's written to the disk. Currently, the following
20
+ customizations are supported:
21
+
22
+ - [Change class modifier](#change-class-modifier)
23
+ - [Change method modifier](#change-method-modifier)
24
+ - [Change method return type](#change-method-return-type)
25
+ - [Add an annotation to a class](#add-an-annotation-to-a-class)
26
+ - [Add an annotation to a method](#add-an-annotation-to-a-method)
27
+ - [Remove an annotation from a class](#remove-an-annotation-from-a-class)
28
+ - [Refactor: Rename a class](#refactor-rename-a-class)
29
+ - [Refactor: Rename a method](#refactor-rename-a-method)
30
+ - [Refactor: Generate the getter and setter methods for a property](#refactor-generate-the-getter-and-setter-methods-for-a-property)
31
+ - [Refactor: Rename a property and its corresponding getter and setter methods](#refactor-rename-a-property-and-its-corresponding-getter-and-setter-methods)
32
+ - [Refactor: Rename an enum member name](#refactor-rename-an-enum-member-name)
33
+ - [Javadoc: Set the description for a class / method](#javadoc-set-the-description-for-a-class--method)
34
+ - [Javadoc: Set / remove a parameter's javadoc on a method](#javadoc-set--remove-a-parameters-javadoc-on-a-method)
35
+ - [Javadoc: Set the return javadoc on a method](#javadoc-set-the-return-javadoc-on-a-method)
36
+ - [Javadoc: Set / remove an exception's javadoc on a method ](#javadoc-add--remove-an-exceptions-javadoc-on-a-method)
37
+
38
+ ## Navigate through the packages and classes
39
+
40
+ There are five primary customization classes currently available, `LibraryCustomization`, `PackageCustomization`,
41
+ `ClassCustomization`, `MethodCustomization` and `JavadocCustomization`. From a given `LibraryCustomization`, you can
42
+ navigate through the packages, classes, and methods intuitively with the following methods:
43
+
44
+ ```java readme-sample-implementation-customization
45
+ @Override
46
+ public void customize(LibraryCustomization customization, Logger logger) {
47
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
48
+ /* code to customize on the package level */
49
+ ClassCustomization foo = models.getClass("Foo");
50
+ /* code to customize the Foo class */
51
+ MethodCustomization getBar = foo.getMethod("getBar");
52
+ /* code to customize the getBar method */
53
+ JavadocCustomization getBarJavadoc = getBar.getJavadoc();
54
+ /* code to customize javadoc for getBar() method */
55
+ }
56
+ ```
57
+
58
+ ## Change class modifier
59
+
60
+ A class `Foo`
61
+
62
+ ```java readme-sample-change-class-modifier-initial
63
+ public class Foo {
64
+ }
65
+ ```
66
+
67
+ with customization
68
+
69
+ ```java readme-sample-change-class-modifier-customization
70
+ @Override
71
+ public void customize(LibraryCustomization customization, Logger logger) {
72
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
73
+ ClassCustomization foo = models.getClass("Foo");
74
+ foo.setModifier(0); // 0 is a special modifier that sets package private
75
+ }
76
+ ```
77
+
78
+ will generate
79
+
80
+ ```java readme-sample-change-class-modifier-result
81
+ class Foo {
82
+ }
83
+ ```
84
+
85
+ ## Change method modifier
86
+
87
+ A method `getBar` in the `Foo` class
88
+
89
+ ```java readme-sample-change-method-modifier-initial
90
+ public class Foo {
91
+ private Bar bar;
92
+
93
+ public Bar getBar() {
94
+ return this.bar;
95
+ }
96
+ }
97
+ ```
98
+
99
+ with customization
100
+
101
+ ```java readme-sample-change-method-modifier-customization
102
+ @Override
103
+ public void customize(LibraryCustomization customization, Logger logger) {
104
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
105
+ ClassCustomization foo = models.getClass("Foo");
106
+ MethodCustomization getBar = foo.getMethod("getBar");
107
+ getBar.setModifier(Modifier.PRIVATE); // change to private
108
+ }
109
+ ```
110
+
111
+ will generate
112
+
113
+ ```java readme-sample-change-method-modifier-result
114
+ public class Foo {
115
+ private Bar bar;
116
+
117
+ private Bar getBar() {
118
+ return this.bar;
119
+ }
120
+ }
121
+ ```
122
+
123
+ ## Change method return type
124
+
125
+ You can change a method's return type, and pass a String formatter to transform the original return value statement.
126
+ If the original return type is `void`, simply pass the full return value String expression in place of the String
127
+ formatter; if the new return type is `void`, simply pass `null`.
128
+
129
+ A method `getId` in the `Foo` class
130
+
131
+ ```java readme-sample-change-method-return-type-initial
132
+ public class Foo {
133
+ private Bar bar;
134
+
135
+ public Bar getBar() {
136
+ return this.bar;
137
+ }
138
+ }
139
+ ```
140
+
141
+ with customization
142
+
143
+ ```java readme-sample-change-method-return-type-customization
144
+ @Override
145
+ public void customize(LibraryCustomization customization, Logger logger) {
146
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
147
+ ClassCustomization foo = models.getClass("Foo");
148
+ MethodCustomization getId = foo.getMethod("getId");
149
+ getId.setReturnType("UUID", "UUID.fromString(%s)"); // change return type to UUID
150
+ }
151
+ ```
152
+
153
+ will generate
154
+
155
+ ```java readme-sample-change-method-return-type-result
156
+ public class Foo {
157
+ private String id;
158
+
159
+ public UUID getId() {
160
+ String returnValue = this.id;
161
+ return UUID.fromString(returnValue);
162
+ }
163
+ }
164
+ ```
165
+
166
+ The `UUID` class will be automatically imported.
167
+
168
+ ## Add an annotation to a class
169
+
170
+ A class `Foo`
171
+
172
+ ```java readme-sample-add-class-annotation-initial
173
+ public class Foo {
174
+ }
175
+ ```
176
+
177
+ with customization
178
+
179
+ ```java readme-sample-add-class-annotation-customization
180
+ @Override
181
+ public void customize(LibraryCustomization customization, Logger logger) {
182
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
183
+ ClassCustomization foo = models.getClass("Foo");
184
+ foo.addAnnotation("JsonClassDescription(\"Foo class\")");
185
+ }
186
+ ```
187
+
188
+ will generate
189
+
190
+ ```java readme-sample-add-class-annotation-result
191
+ @JsonClassDescription("Foo class")
192
+ public class Foo {
193
+ }
194
+ ```
195
+
196
+ The `JsonClassDescription` class will be automatically imported.
197
+
198
+ ## Add an annotation to a method
199
+
200
+ A method `getBar` in the `Foo` class
201
+
202
+ ```java readme-sample-add-method-annotation-initial
203
+ public class Foo {
204
+ private Bar bar;
205
+
206
+ public Bar getBar() {
207
+ return this.bar;
208
+ }
209
+ }
210
+ ```
211
+
212
+ with customization
213
+
214
+ ```java readme-sample-add-method-annotation-customization
215
+ @Override
216
+ public void customize(LibraryCustomization customization, Logger logger) {
217
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
218
+ ClassCustomization foo = models.getClass("Foo");
219
+ MethodCustomization getBar = foo.getMethod("getBar");
220
+ getBar.addAnnotation("Deprecated");
221
+ }
222
+ ```
223
+
224
+ will generate
225
+
226
+ ```java readme-sample-add-method-annotation-result
227
+ public class Foo {
228
+ private Bar bar;
229
+
230
+ @Deprecated
231
+ public Bar getBar() {
232
+ return this.bar;
233
+ }
234
+ }
235
+ ```
236
+
237
+ The `Deprecated` class will be automatically imported.
238
+
239
+ ## Remove an annotation from a class
240
+
241
+ A class `Foo`
242
+
243
+ ```java readme-sample-remove-class-annotation-initial
244
+ @JsonClassDescription("Foo class")
245
+ public class Foo {
246
+ }
247
+ ```
248
+
249
+ with customization
250
+
251
+ ```java readme-sample-remove-class-annotation-customization
252
+ @Override
253
+ public void customize(LibraryCustomization customization, Logger logger) {
254
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
255
+ ClassCustomization foo = models.getClass("Foo");
256
+ foo.removeAnnotation("JsonClassDescription");
257
+ }
258
+ ```
259
+
260
+ will generate
261
+
262
+ ```java readme-sample-remove-class-annotation-result
263
+ public class Foo {
264
+ }
265
+ ```
266
+
267
+ ## Refactor: Rename a class
268
+
269
+ A class `Foo`
270
+
271
+ ```java readme-sample-rename-class-initial
272
+ public class Foo {
273
+ }
274
+ ```
275
+
276
+ with customization
277
+
278
+ ```java readme-sample-rename-class-customization
279
+ @Override
280
+ public void customize(LibraryCustomization customization, Logger logger) {
281
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
282
+ ClassCustomization foo = models.getClass("Foo");
283
+ foo.rename("FooInfo");
284
+ }
285
+ ```
286
+
287
+ will generate
288
+
289
+ ```java readme-sample-rename-class-result
290
+ public class FooInfo {
291
+ }
292
+ ```
293
+
294
+ All references of `Foo` will be modified to `FooInfo`. When a valid value is provided, this customization is guaranteed
295
+ to not break the build.
296
+
297
+ ## Refactor: Rename a method
298
+
299
+ A method `isSupportsUnicode` in the `Foo` class
300
+
301
+ ```java readme-sample-rename-method-initial
302
+ public class Foo {
303
+ private boolean supportsUnicode;
304
+
305
+ public boolean isSupportsUnicode() {
306
+ return this.supportsUnicode;
307
+ }
308
+ }
309
+ ```
310
+
311
+ with customization
312
+
313
+ ```java readme-sample-rename-method-customization
314
+ @Override
315
+ public void customize(LibraryCustomization customization, Logger logger) {
316
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
317
+ ClassCustomization foo = models.getClass("Foo");
318
+ MethodCustomization isSupportsUnicode = foo.getMethod("isSupportsUnicode");
319
+ isSupportsUnicode.rename("isUnicodeSupported");
320
+ }
321
+ ```
322
+
323
+ will generate
324
+
325
+ ```java readme-sample-rename-method-result
326
+ public class Foo {
327
+ private boolean supportsUnicode;
328
+
329
+ public boolean isUnicodeSupported() {
330
+ return this.supportsUnicode;
331
+ }
332
+ }
333
+ ```
334
+
335
+ All references of `isSupportsUnicode()` will be modified to `isUnicodeSupported()`. When a valid value is provided, this
336
+ customization is guaranteed to not break the build.
337
+
338
+ ## Refactor: Generate the getter and setter methods for a property
339
+
340
+ A property `active` in the `Foo` class
341
+
342
+ ```java readme-sample-generate-getter-and-setter-initial
343
+ public class Foo {
344
+ private boolean active;
345
+ }
346
+ ```
347
+
348
+ with customization
349
+
350
+ ```java readme-sample-generate-getter-and-setter-customization
351
+ @Override
352
+ public void customize(LibraryCustomization customization, Logger logger) {
353
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
354
+ ClassCustomization foo = models.getClass("Foo");
355
+ PropertyCustomization active = foo.getProperty("active");
356
+ active.generateGetterAndSetter();
357
+ }
358
+ ```
359
+
360
+ will generate
361
+
362
+ ```java readme-sample-generate-getter-and-setter-result
363
+ public class Foo {
364
+ private boolean active;
365
+
366
+ public boolean isActive() {
367
+ return this.active;
368
+ }
369
+
370
+ public Foo setActive(boolean active) {
371
+ this.active = active;
372
+ return this;
373
+ }
374
+ }
375
+ ```
376
+
377
+ If the class already contains a getter or a setter method, the current method will be kept. This customization is
378
+ guaranteed to not break the build.
379
+
380
+ ## Refactor: Rename a property and its corresponding getter and setter methods
381
+
382
+ A property `whitelist` in the `Foo` class
383
+
384
+ ```java readme-sample-rename-property-initial
385
+ public class Foo {
386
+ private List<String> whiteList;
387
+
388
+ public List<String> getWhiteList() {
389
+ return this.whiteList;
390
+ }
391
+
392
+ public Foo setWhiteList(List<String> whiteList) {
393
+ this.whiteList = whiteList;
394
+ return this;
395
+ }
396
+ }
397
+ ```
398
+
399
+ with customization
400
+
401
+ ```java readme-sample-rename-property-customization
402
+ @Override
403
+ public void customize(LibraryCustomization customization, Logger logger) {
404
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
405
+ ClassCustomization foo = models.getClass("Foo");
406
+ PropertyCustomization active = foo.getProperty("active");
407
+ active.rename("allowList");
408
+ }
409
+ ```
410
+
411
+ will generate
412
+
413
+ ```java readme-sample-rename-property-result
414
+ public class Foo {
415
+ private List<String> allowList;
416
+
417
+ public List<String> getAllowList() {
418
+ return this.allowList;
419
+ }
420
+
421
+ public Foo setAllowList(List<String> allowList) {
422
+ this.allowList = allowList;
423
+ return this;
424
+ }
425
+ }
426
+ ```
427
+
428
+ This customization is guaranteed to not break the build.
429
+
430
+ ## Refactor: Rename an enum member name
431
+
432
+ An enum member `JPG` in an enum class `ImageFileType`:
433
+
434
+ ```java readme-sample-rename-enum-member-initial
435
+ public enum ImageFileType {
436
+ GIF("gif"),
437
+ JPG("jpg"),
438
+ TIFF("tiff"),
439
+ PNG("png");
440
+
441
+ private final String value;
442
+
443
+ ImageFileType(String value) {
444
+ this.value = value;
445
+ }
446
+ }
447
+ ```
448
+
449
+ with customization
450
+
451
+ ```java readme-sample-rename-enum-member-customization
452
+ @Override
453
+ public void customize(LibraryCustomization customization, Logger logger) {
454
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
455
+ ClassCustomization foo = models.getClass("Foo");
456
+ foo.renameEnumMember("JPG", "JPEG");
457
+ }
458
+ ```
459
+
460
+ will generate
461
+
462
+ ```java readme-sample-rename-enum-member-result
463
+ public enum ImageFileType {
464
+ GIF("gif"),
465
+ JPEG("jpg"),
466
+ TIFF("tiff"),
467
+ PNG("png");
468
+
469
+ private final String value;
470
+
471
+ ImageFileType(String value) {
472
+ this.value = value;
473
+ }
474
+ }
475
+ ```
476
+
477
+ This customization is guaranteed to not break the build.
478
+
479
+ ## Javadoc: Set the description for a class / method
480
+
481
+ A class `Foo`
482
+
483
+ ```java readme-sample-change-javadoc-description-initial
484
+ /** Class Foo. */
485
+ public class Foo {
486
+ private boolean active;
487
+
488
+ public boolean isActive() {
489
+ return this.active;
490
+ }
491
+
492
+ public Foo setActive(boolean active) {
493
+ this.active = active;
494
+ return this;
495
+ }
496
+ }
497
+ ```
498
+
499
+ with customization
500
+
501
+ ```java readme-sample-change-javadoc-description-customization
502
+ @Override
503
+ public void customize(LibraryCustomization customization, Logger logger) {
504
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
505
+ ClassCustomization foo = models.getClass("Foo");
506
+ JavadocCustomization fooJavadoc = foo.getJavadoc();
507
+ fooJavadoc.setDescription("A Foo object stored in Azure.");
508
+ JavadocCustomization setActiveJavadoc = foo.getMethod("setActive").getJavadoc();
509
+ setActiveJavadoc.setDescription("Set the active value.");
510
+ }
511
+ ```
512
+
513
+ will generate
514
+
515
+ ```java readme-sample-change-javadoc-description-result
516
+ /**
517
+ * A Foo object stored in Azure.
518
+ */
519
+ public class Foo {
520
+ private boolean active;
521
+
522
+ public boolean isActive() {
523
+ return this.active;
524
+ }
525
+
526
+ /**
527
+ * Set the active value.
528
+ */
529
+ public Foo setActive(boolean active) {
530
+ this.active = active;
531
+ return this;
532
+ }
533
+ }
534
+ ```
535
+
536
+ ## Javadoc: Set / remove a parameter's javadoc on a method
537
+
538
+ A class `Foo`
539
+
540
+ ```java readme-sample-change-javadoc-param-initial
541
+ public class Foo {
542
+ private boolean active;
543
+
544
+ public boolean isActive() {
545
+ return this.active;
546
+ }
547
+
548
+ /**
549
+ * Set the active value.
550
+ */
551
+ public Foo setActive(boolean active) {
552
+ this.active = active;
553
+ return this;
554
+ }
555
+ }
556
+ ```
557
+
558
+ with customization
559
+
560
+ ```java readme-sample-change-javadoc-param-customization
561
+ @Override
562
+ public void customize(LibraryCustomization customization, Logger logger) {
563
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
564
+ ClassCustomization foo = models.getClass("Foo");
565
+ JavadocCustomization setActiveJavadoc = foo.getMethod("setActive").getJavadoc();
566
+ setActiveJavadoc.setParam("active", "if the foo object is in active state");
567
+ }
568
+ ```
569
+
570
+ will generate
571
+
572
+ ```java readme-sample-change-javadoc-param-result
573
+ public class Foo {
574
+ private boolean active;
575
+
576
+ public boolean isActive() {
577
+ return this.active;
578
+ }
579
+
580
+ /**
581
+ * Set the active value.
582
+ *
583
+ * @param active if the foo object is in active state
584
+ */
585
+ public Foo setActive(boolean active) {
586
+ this.active = active;
587
+ return this;
588
+ }
589
+ }
590
+ ```
591
+
592
+ ## Javadoc: Set the return javadoc on a method
593
+
594
+ A `Foo` class
595
+
596
+ ```java readme-sample-change-javadoc-return-initial
597
+ public class Foo {
598
+ private boolean active;
599
+
600
+ public boolean isActive() {
601
+ return this.active;
602
+ }
603
+
604
+ /**
605
+ * Set the active value.
606
+ *
607
+ * @param active if the foo object is in active state
608
+ */
609
+ public Foo setActive(boolean active) {
610
+ this.active = active;
611
+ return this;
612
+ }
613
+ }
614
+ ```
615
+
616
+ with customization
617
+
618
+ ```java readme-sample-change-javadoc-return-customization
619
+ @Override
620
+ public void customize(LibraryCustomization customization, Logger logger) {
621
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
622
+ ClassCustomization foo = models.getClass("Foo");
623
+ JavadocCustomization setActiveJavadoc = foo.getMethod("setActive").getJavadoc();
624
+ setActiveJavadoc.setReturn("the current foo object");
625
+ }
626
+ ```
627
+
628
+ will generate
629
+
630
+ ```java readme-sample-change-javadoc-return-result
631
+ public class Foo {
632
+ private boolean active;
633
+
634
+ public boolean isActive() {
635
+ return this.active;
636
+ }
637
+
638
+ /**
639
+ * Set the active value.
640
+ *
641
+ * @param active if the foo object is in active state
642
+ * @return the current foo object
643
+ */
644
+ public Foo setActive(boolean active) {
645
+ this.active = active;
646
+ return this;
647
+ }
648
+ }
649
+ ```
650
+
651
+ ## Javadoc: Add / remove an exception's javadoc on a method
652
+
653
+ A `FooClient` class
654
+
655
+ ```java readme-sample-change-javadoc-throws-initial
656
+ public class FooClient {
657
+ /**
658
+ * Create a Foo object.
659
+ *
660
+ * @param foo the foo object to create in Azure
661
+ * @return the response for creating the foo object
662
+ */
663
+ public CreateFooResponse createFoo(Foo foo) {
664
+ /* REST call to create foo */
665
+ return null;
666
+ }
667
+ }
668
+ ```
669
+
670
+ with customization
671
+
672
+ ```java readme-sample-change-javadoc-throws-customization
673
+ @Override
674
+ public void customize(LibraryCustomization customization, Logger logger) {
675
+ PackageCustomization models = customization.getPackage("com.azure.myservice.models");
676
+ ClassCustomization foo = models.getClass("Foo");
677
+ JavadocCustomization setActiveJavadoc = foo.getMethod("setActive").getJavadoc();
678
+ setActiveJavadoc.addThrows("RuntimeException", "An unsuccessful response is received");
679
+ }
680
+ ```
681
+
682
+ will generate
683
+
684
+ ```java readme-sample-change-javadoc-throws-result
685
+ /**
686
+ * Create a Foo object.
687
+ *
688
+ * @param foo the foo object to create in Azure
689
+ * @return the response for creating the foo object
690
+ * @throws RuntimeException An unsuccessful response is received
691
+ */
692
+ public CreateFooResponse createFoo(Foo foo) {
693
+ /* REST call to create foo */
694
+ return null;
695
+ }
696
+ ```
697
+
698
+ # Troubleshooting
699
+
700
+ ## AutoRest fails with "Unable to format output file"
701
+
702
+ The cause is that the customized Java code has syntax error.
703
+
704
+ Possible root cause:
705
+ * Bug in customization code.
706
+ * Bug in the `customization-base` package.
707
+
708
+ Steps to diagnose and fix:
709
+ 1. Add `skip-formatting` flag to skip Java code formatting, and hence not checking the syntax error.
710
+ 2. Compile or inspect the generated code, find the error.
711
+ 3. Determine the root cause. If it is caused by bug in customization code, fix it. If it is caused by bug in `customization-base` package, report it in GitHub issues.
712
+ 4. Remove `skip-formatting` flag.
713
+
714
+ # Developer note
715
+
716
+ `azure-autorest-customization` passes all generated code files to an Eclipse language server process to enable richer,
717
+ IDE-like functionality. For this to work correctly all required dependencies must be passed to the language server using
718
+ a dummy `pom.xml`, which can be found in `src/main/resources`. If you make changes to code generation and begin seeing
719
+ code customizations failing it may be that the `pom.xml` is missing required dependencies and is causing the language
720
+ server to change processing from IDE-like to a regex, or find and replace, style.