20
20
import com .samskivert .mustache .Mustache ;
21
21
import io .swagger .v3 .oas .models .OpenAPI ;
22
22
import io .swagger .v3 .oas .models .media .Schema ;
23
+ import io .swagger .v3 .parser .util .SchemaTypeUtil ;
23
24
import org .openapitools .codegen .*;
24
25
import org .openapitools .codegen .utils .URLPathUtils ;
25
26
import org .slf4j .Logger ;
@@ -39,13 +40,17 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
39
40
public static final String ASPNET_CORE_VERSION = "aspnetCoreVersion" ;
40
41
public static final String CLASS_MODIFIER = "classModifier" ;
41
42
public static final String OPERATION_MODIFIER = "operationModifier" ;
43
+ public static final String OPERATION_IS_ASYNC = "operationIsAsync" ;
44
+ public static final String OPERATION_RESULT_TASK = "operationResultTask" ;
42
45
public static final String GENERATE_BODY = "generateBody" ;
43
46
public static final String BUILD_TARGET = "buildTarget" ;
47
+ public static final String MODEL_CLASS_MODIFIER = "modelClassModifier" ;
44
48
45
49
public static final String PROJECT_SDK = "projectSdk" ;
46
50
public static final String SDK_WEB = "Microsoft.NET.Sdk.Web" ;
47
51
public static final String SDK_LIB = "Microsoft.NET.Sdk" ;
48
52
public static final String COMPATIBILITY_VERSION = "compatibilityVersion" ;
53
+ public static final String IS_LIBRARY = "isLibrary" ;
49
54
50
55
private String packageGuid = "{" + randomUUID ().toString ().toUpperCase (Locale .ROOT ) + "}" ;
51
56
@@ -55,13 +60,18 @@ public class AspNetCoreServerCodegen extends AbstractCSharpCodegen {
55
60
private boolean useSwashbuckle = true ;
56
61
protected int serverPort = 8080 ;
57
62
protected String serverHost = "0.0.0.0" ;
58
- private CliOption aspnetCoreVersion = new CliOption (ASPNET_CORE_VERSION , "ASP.NET Core version: 2.2 (default), 2.1, 2.0 (deprecated)" );
63
+ protected CliOption aspnetCoreVersion = new CliOption (ASPNET_CORE_VERSION , "ASP.NET Core version: 2.2 (default), 2.1, 2.0 (deprecated)" );
64
+ ; // default to 2.1
59
65
private CliOption classModifier = new CliOption (CLASS_MODIFIER , "Class Modifier can be empty, abstract" );
60
66
private CliOption operationModifier = new CliOption (OPERATION_MODIFIER , "Operation Modifier can be virtual, abstract or partial" );
67
+ private CliOption modelClassModifier = new CliOption (MODEL_CLASS_MODIFIER , "Model Class Modifier can be nothing or partial" );
61
68
private boolean generateBody = true ;
62
69
private CliOption buildTarget = new CliOption ("buildTarget" , "Target to build an application or library" );
63
70
private String projectSdk = SDK_WEB ;
64
71
private String compatibilityVersion = "Version_2_1" ;
72
+ private boolean operationIsAsync = false ;
73
+ private boolean operationResultTask = false ;
74
+ private boolean isLibrary = false ;
65
75
66
76
public AspNetCoreServerCodegen () {
67
77
super ();
@@ -160,6 +170,10 @@ public AspNetCoreServerCodegen() {
160
170
"Uses the Swashbuckle.AspNetCore NuGet package for documentation." ,
161
171
useSwashbuckle );
162
172
173
+ addSwitch (IS_LIBRARY ,
174
+ "Is the build a library" ,
175
+ isLibrary );
176
+
163
177
classModifier .addEnum ("" , "Keep class default with no modifier" );
164
178
classModifier .addEnum ("abstract" , "Make class abstract" );
165
179
classModifier .setDefault ("" );
@@ -182,6 +196,21 @@ public AspNetCoreServerCodegen() {
182
196
"Generates method body." ,
183
197
generateBody );
184
198
199
+ addSwitch (OPERATION_IS_ASYNC ,
200
+ "Set methods to async or sync." ,
201
+ operationIsAsync );
202
+
203
+ addSwitch (OPERATION_RESULT_TASK ,
204
+ "Set methods result to Task<>." ,
205
+ operationResultTask );
206
+
207
+ modelClassModifier .setType ("String" );
208
+ modelClassModifier .addEnum ("" , "Keep model class default with no modifier" );
209
+ modelClassModifier .addEnum ("partial" , "Make model class partial" );
210
+ modelClassModifier .setDefault ("partial" );
211
+ modelClassModifier .setOptValue (modelClassModifier .getDefault ());
212
+ addOption (modelClassModifier .getOpt (), modelClassModifier .getDescription (), modelClassModifier .getOptValue ());
213
+
185
214
}
186
215
187
216
@ Override
@@ -210,34 +239,36 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
210
239
@ Override
211
240
public void processOpts () {
212
241
super .processOpts ();
213
- boolean isLibrary = false ;
214
242
215
243
if (additionalProperties .containsKey (CodegenConstants .OPTIONAL_PROJECT_GUID )) {
216
244
setPackageGuid ((String ) additionalProperties .get (CodegenConstants .OPTIONAL_PROJECT_GUID ));
217
245
}
218
246
additionalProperties .put ("packageGuid" , packageGuid );
219
247
220
- if (additionalProperties .containsKey (USE_SWASHBUCKLE )) {
221
- useSwashbuckle = convertPropertyToBooleanAndWriteBack (USE_SWASHBUCKLE );
222
- } else {
223
- additionalProperties .put (USE_SWASHBUCKLE , useSwashbuckle );
224
- }
225
-
226
248
227
249
// CHeck for the modifiers etc.
228
250
// The order of the checks is important.
229
- isLibrary = setBuildTarget ();
251
+ setBuildTarget ();
230
252
setClassModifier ();
231
253
setOperationModifier ();
232
-
254
+ setModelClassModifier ();
255
+ setUseSwashbuckle ();
256
+ setOperationIsAsync ();
233
257
234
258
// CHeck for class modifier if not present set the default value.
235
259
additionalProperties .put (PROJECT_SDK , projectSdk );
236
260
237
261
additionalProperties .put ("dockerTag" , packageName .toLowerCase (Locale .ROOT ));
238
262
239
- apiPackage = packageName + ".Controllers" ;
240
- modelPackage = packageName + ".Models" ;
263
+ if (!additionalProperties .containsKey (CodegenConstants .API_PACKAGE )) {
264
+ apiPackage = packageName + ".Controllers" ;
265
+ additionalProperties .put (CodegenConstants .API_PACKAGE , apiPackage );
266
+ }
267
+
268
+ if (!additionalProperties .containsKey (CodegenConstants .MODEL_PACKAGE )) {
269
+ modelPackage = packageName + ".Models" ;
270
+ additionalProperties .put (CodegenConstants .MODEL_PACKAGE , modelPackage );
271
+ }
241
272
242
273
String packageFolder = sourceFolder + File .separator + packageName ;
243
274
@@ -259,15 +290,15 @@ public void processOpts() {
259
290
supportingFiles .add (new SupportingFile ("Program.mustache" , packageFolder , "Program.cs" ));
260
291
supportingFiles .add (new SupportingFile ("Properties" + File .separator + "launchSettings.json" ,
261
292
packageFolder + File .separator + "Properties" , "launchSettings.json" ));
262
- } else {
263
- supportingFiles .add (new SupportingFile ("Project.nuspec.mustache" , packageFolder , packageName + ".nuspec" ));
264
293
// wwwroot files.
265
294
supportingFiles .add (new SupportingFile ("wwwroot" + File .separator + "README.md" , packageFolder + File .separator + "wwwroot" , "README.md" ));
266
295
supportingFiles .add (new SupportingFile ("wwwroot" + File .separator + "index.html" , packageFolder + File .separator + "wwwroot" , "index.html" ));
267
296
supportingFiles .add (new SupportingFile ("wwwroot" + File .separator + "web.config" , packageFolder + File .separator + "wwwroot" , "web.config" ));
268
297
269
298
supportingFiles .add (new SupportingFile ("wwwroot" + File .separator + "openapi-original.mustache" ,
270
299
packageFolder + File .separator + "wwwroot" , "openapi-original.json" ));
300
+ } else {
301
+ supportingFiles .add (new SupportingFile ("Project.nuspec.mustache" , packageFolder , packageName + ".nuspec" ));
271
302
}
272
303
273
304
@@ -342,15 +373,23 @@ public String getNullableType(Schema p, String type) {
342
373
343
374
private void setCliOption (CliOption cliOption ) throws IllegalArgumentException {
344
375
if (additionalProperties .containsKey (cliOption .getOpt ())) {
345
- cliOption .setOptValue (additionalProperties .get (cliOption .getOpt ()).toString ());
346
- if (cliOption .getOptValue () == null ) {
347
- cliOption .setOptValue (cliOption .getDefault ());
348
- throw new IllegalArgumentException (cliOption .getOpt () + ": Invalid value '" + additionalProperties .get (cliOption .getOpt ()).toString () + "'" +
349
- ". " + cliOption .getDescription ());
376
+ // TODO Hack - not sure why the empty strings become boolean.
377
+ Object obj = additionalProperties .get (cliOption .getOpt ());
378
+ if (!SchemaTypeUtil .BOOLEAN_TYPE .equals (cliOption .getType ())) {
379
+ if (obj instanceof Boolean ) {
380
+ obj = "" ;
381
+ additionalProperties .put (cliOption .getOpt (), obj );
382
+ }
350
383
}
384
+ cliOption .setOptValue (obj .toString ());
351
385
} else {
352
386
additionalProperties .put (cliOption .getOpt (), cliOption .getOptValue ());
353
387
}
388
+ if (cliOption .getOptValue () == null ) {
389
+ cliOption .setOptValue (cliOption .getDefault ());
390
+ throw new IllegalArgumentException (cliOption .getOpt () + ": Invalid value '" + additionalProperties .get (cliOption .getOpt ()).toString () + "'" +
391
+ ". " + cliOption .getDescription ());
392
+ }
354
393
}
355
394
356
395
private void setClassModifier () {
@@ -362,8 +401,6 @@ private void setClassModifier() {
362
401
operationModifier .setOptValue (classModifier .getOptValue ());
363
402
additionalProperties .put (OPERATION_MODIFIER , operationModifier .getOptValue ());
364
403
LOGGER .warn ("classModifier is " + classModifier .getOptValue () + " so forcing operatonModifier to " + operationModifier .getOptValue ());
365
- } else {
366
- setCliOption (operationModifier );
367
404
}
368
405
}
369
406
@@ -382,15 +419,28 @@ private void setOperationModifier() {
382
419
}
383
420
}
384
421
385
- private boolean setBuildTarget () {
386
- boolean isLibrary = false ;
422
+ private void setModelClassModifier () {
423
+ setCliOption (modelClassModifier );
424
+
425
+ // If operation modifier is abstract then dont generate any body
426
+ if (isLibrary ) {
427
+ modelClassModifier .setOptValue ("" );
428
+ additionalProperties .put (MODEL_CLASS_MODIFIER , modelClassModifier .getOptValue ());
429
+ LOGGER .warn ("buildTarget is " + buildTarget .getOptValue () + " so removing any modelClassModifier " );
430
+ }
431
+ }
432
+
433
+ private void setBuildTarget () {
387
434
setCliOption (buildTarget );
388
435
if ("library" .equals (buildTarget .getOptValue ())) {
389
436
isLibrary = true ;
390
437
projectSdk = SDK_LIB ;
391
438
additionalProperties .put (CLASS_MODIFIER , "abstract" );
439
+ } else {
440
+ isLibrary = false ;
441
+ projectSdk = SDK_WEB ;
392
442
}
393
- return isLibrary ;
443
+ additionalProperties . put ( IS_LIBRARY , isLibrary ) ;
394
444
}
395
445
396
446
private void setAspnetCoreVersion (String packageFolder ) {
@@ -407,4 +457,29 @@ private void setAspnetCoreVersion(String packageFolder) {
407
457
}
408
458
additionalProperties .put (COMPATIBILITY_VERSION , compatibilityVersion );
409
459
}
460
+
461
+ private void setUseSwashbuckle () {
462
+ if (isLibrary ) {
463
+ LOGGER .warn ("buildTarget is " + buildTarget .getOptValue () + " so changing default isLibrary to false " );
464
+ useSwashbuckle = false ;
465
+ } else {
466
+ useSwashbuckle = true ;
467
+ }
468
+ if (additionalProperties .containsKey (USE_SWASHBUCKLE )) {
469
+ useSwashbuckle = convertPropertyToBooleanAndWriteBack (USE_SWASHBUCKLE );
470
+ } else {
471
+ additionalProperties .put (USE_SWASHBUCKLE , useSwashbuckle );
472
+ }
473
+ }
474
+
475
+ private void setOperationIsAsync () {
476
+ if (isLibrary ) {
477
+ operationIsAsync = false ;
478
+ additionalProperties .put (OPERATION_IS_ASYNC , operationIsAsync );
479
+ } else if (additionalProperties .containsKey (OPERATION_IS_ASYNC )) {
480
+ operationIsAsync = convertPropertyToBooleanAndWriteBack (OPERATION_IS_ASYNC );
481
+ } else {
482
+ additionalProperties .put (OPERATION_IS_ASYNC , operationIsAsync );
483
+ }
484
+ }
410
485
}
0 commit comments