21
21
import io .swagger .v3 .oas .models .OpenAPI ;
22
22
import io .swagger .v3 .oas .models .Operation ;
23
23
import io .swagger .v3 .oas .models .PathItem ;
24
+ import io .swagger .v3 .oas .models .media .ComposedSchema ;
25
+ import io .swagger .v3 .oas .models .media .Schema ;
26
+ import io .swagger .v3 .oas .models .parameters .RequestBody ;
27
+ import org .apache .commons .lang3 .StringUtils ;
24
28
import org .apache .commons .lang3 .tuple .Pair ;
25
29
import org .openapitools .codegen .*;
26
30
import org .openapitools .codegen .languages .features .BeanValidationFeatures ;
29
33
import org .openapitools .codegen .meta .features .*;
30
34
import org .openapitools .codegen .templating .mustache .SplitStringLambda ;
31
35
import org .openapitools .codegen .templating .mustache .TrimWhitespaceLambda ;
36
+ import org .openapitools .codegen .utils .ModelUtils ;
37
+ import org .openapitools .codegen .utils .OneOfImplementorAdditionalData ;
32
38
import org .openapitools .codegen .utils .URLPathUtils ;
33
39
import org .slf4j .Logger ;
34
40
import org .slf4j .LoggerFactory ;
@@ -233,7 +239,7 @@ public void processOpts() {
233
239
}
234
240
235
241
super .processOpts ();
236
-
242
+ useOneOfInterfaces = true ;
237
243
// clear model and api doc template as this codegen
238
244
// does not support auto-generated markdown doc at the moment
239
245
//TODO: add doc templates
@@ -523,6 +529,58 @@ public void addOperationToGroup(String tag, String resourcePath, Operation opera
523
529
}
524
530
}
525
531
532
+ @ Override
533
+ public void addOneOfInterfaceModel (ComposedSchema cs , String name ) {
534
+ CodegenModel codegenModel = new CodegenModel ();
535
+
536
+ for (Schema o : cs .getOneOf ()) {
537
+ codegenModel .oneOf .add (toModelName (ModelUtils .getSimpleRef (o .get$ref ())));
538
+ }
539
+ codegenModel .name = name ;
540
+ codegenModel .classname = name ;
541
+ codegenModel .vendorExtensions .put ("isOneOfInterface" , true );
542
+ codegenModel .discriminator = createDiscriminator ("" , (Schema ) cs );
543
+ codegenModel .interfaceModels = new ArrayList <CodegenModel >();
544
+
545
+ for (Schema schema : cs .getOneOf ()){
546
+ String [] split = schema .get$ref ().split ("/" );
547
+ String singleSchemaType = split [split .length -1 ];
548
+ CodegenProperty codegenProperty = fromProperty (singleSchemaType , schema );
549
+ codegenProperty .setBaseName (singleSchemaType .toLowerCase (Locale .getDefault ()));
550
+ codegenModel .vars .add (codegenProperty );
551
+ }
552
+ addOneOfInterfaces .add (codegenModel );
553
+ }
554
+
555
+ @ Override
556
+ public CodegenParameter fromRequestBody (RequestBody body , Set <String > imports , String bodyParameterName ) {
557
+ CodegenParameter codegenParameter = super .fromRequestBody (body , imports , bodyParameterName );
558
+ Schema schema = ModelUtils .getSchemaFromRequestBody (body );
559
+ CodegenProperty codegenProperty = fromProperty ("property" , schema );
560
+
561
+ List <String > oneOfClassNames = new ArrayList <>();
562
+ if (codegenProperty != null && codegenProperty .getComplexType () != null && schema instanceof ComposedSchema ) {
563
+ // will be set with imports.add(codegenParameter.baseType); in defaultcodegen
564
+ imports .clear ();
565
+ ComposedSchema composedSchema = (ComposedSchema ) schema ;
566
+ for (Schema oneOfSchema : composedSchema .getOneOf ()){
567
+ String [] split = oneOfSchema .get$ref ().split ("/" );
568
+ oneOfClassNames .add (split [split .length - 1 ]);
569
+ }
570
+ String codegenModelName = createOneOfClassName (oneOfClassNames );
571
+ imports .add (codegenModelName );
572
+ codegenParameter .baseName = codegenModelName ;
573
+ codegenParameter .paramName = toParamName (codegenParameter .baseName );
574
+ codegenParameter .baseType = codegenParameter .baseName ;
575
+ codegenParameter .dataType = getTypeDeclaration (codegenModelName );
576
+ codegenParameter .description = codegenProperty .getDescription ();
577
+ codegenProperty .setComplexType (codegenModelName );
578
+ codegenProperty .setBaseName (codegenModelName );
579
+ codegenProperty .setDatatype (codegenModelName );
580
+ }
581
+ return codegenParameter ;
582
+ }
583
+
526
584
@ Override
527
585
public void preprocessOpenAPI (OpenAPI openAPI ) {
528
586
super .preprocessOpenAPI (openAPI );
@@ -629,6 +687,57 @@ public void setReturnContainer(final String returnContainer) {
629
687
return objs ;
630
688
}
631
689
690
+ @ Override
691
+ public Map <String , Object > postProcessAllModels (Map <String , Object > objs ) {
692
+ super .postProcessAllModels (objs );
693
+ Map <String , OneOfImplementorAdditionalData > additionalDataMap = new HashMap <>();
694
+ for (Map .Entry modelsEntry : objs .entrySet ()) {
695
+ Map <String , Object > modelsAttrs = (Map <String , Object >) modelsEntry .getValue ();
696
+ List <Object > models = (List <Object >) modelsAttrs .get ("models" );
697
+ List <Map <String , String >> modelsImports = (List <Map <String , String >>) modelsAttrs
698
+ .getOrDefault ("imports" , new ArrayList <Map <String , String >>());
699
+ for (Object _mo : models ) {
700
+ Map <String , Object > mo = (Map <String , Object >) _mo ;
701
+ CodegenModel cm = (CodegenModel ) mo .get ("model" );
702
+ if (cm .oneOf .size () > 0 ) {
703
+ cm .vendorExtensions .put ("isOneOfInterface" , true );
704
+ // if this is oneOf interface, make sure we include the necessary jackson imports for it
705
+ for (String classToImport : Arrays
706
+ .asList ("JsonTypeInfo" , "JsonSubTypes" , "JsonProperty" ,
707
+ "ApiModelProperty" )) {
708
+ Map <String , String > i = new HashMap <String , String >() {{
709
+ put ("import" , importMapping .get (classToImport ));
710
+ }};
711
+ if (!modelsImports .contains (i )) {
712
+ modelsImports .add (i );
713
+ }
714
+ }
715
+ List <String > oneOfClassNames = new ArrayList <>();
716
+
717
+ for (String one : cm .oneOf ) {
718
+ if (!additionalDataMap .containsKey (one )) {
719
+ additionalDataMap .put (one , new OneOfImplementorAdditionalData (one ));
720
+ additionalDataMap .get (one ).addFromInterfaceModel (cm , modelsImports );
721
+ }
722
+ oneOfClassNames .add (one );
723
+ }
724
+ String codegenModelName = createOneOfClassName (oneOfClassNames );
725
+ cm .name = codegenModelName ;
726
+ cm .classname = codegenModelName ;
727
+ Object value = modelsEntry .getValue ();
728
+ objs .remove (modelsEntry .getKey ());
729
+ objs .put (codegenModelName , value );
730
+ }
731
+ }
732
+ }
733
+ return objs ;
734
+ }
735
+
736
+ private String createOneOfClassName (List <String > oneOfClassNames ) {
737
+ oneOfClassNames .sort (String ::compareToIgnoreCase );
738
+ return "OneOf" + StringUtils .join (oneOfClassNames , "" );
739
+ }
740
+
632
741
private interface DataTypeAssigner {
633
742
void setReturnType (String returnType );
634
743
@@ -898,4 +1007,16 @@ public void postProcessParameter(CodegenParameter p) {
898
1007
}
899
1008
}
900
1009
901
- }
1010
+ @ Override
1011
+ public void addImportsToOneOfInterface (List <Map <String , String >> imports ) {
1012
+ for (String i : Arrays .asList ("JsonSubTypes" , "JsonTypeInfo" )) {
1013
+ Map <String , String > oneImport = new HashMap <String , String >() {{
1014
+ put ("import" , importMapping .get (i ));
1015
+ }};
1016
+ if (!imports .contains (oneImport )) {
1017
+ imports .add (oneImport );
1018
+ }
1019
+ }
1020
+ }
1021
+
1022
+ }
0 commit comments