5
5
import io .swagger .models .ModelImpl ;
6
6
import io .swagger .models .Operation ;
7
7
import io .swagger .models .Swagger ;
8
- import io .swagger .models .properties .ArrayProperty ;
9
- import io .swagger .models .properties .MapProperty ;
10
- import io .swagger .models .properties .Property ;
8
+ import io .swagger .models .properties .*;
11
9
12
10
import java .util .*;
13
11
import java .util .regex .Pattern ;
14
12
15
13
import org .apache .commons .io .FileUtils ;
16
14
15
+ import io .swagger .models .auth .SecuritySchemeDefinition ;
17
16
import io .swagger .codegen .CliOption ;
18
17
import io .swagger .codegen .CodegenConstants ;
19
18
import io .swagger .codegen .CodegenModel ;
26
25
import java .io .File ;
27
26
28
27
import org .apache .commons .lang3 .StringUtils ;
28
+ import org .apache .commons .lang3 .StringEscapeUtils ;
29
29
import org .apache .commons .lang3 .text .WordUtils ;
30
30
31
31
import java .util .regex .Matcher ;
@@ -65,8 +65,8 @@ public class HaskellHttpClientCodegen extends DefaultCodegen implements CodegenC
65
65
static final String MEDIA_IS_JSON = "x-mediaIsJson" ;
66
66
67
67
68
- protected Map <String , CodegenParameter > uniqueOptionalParamsByName = new HashMap <String , CodegenParameter >();
69
- protected Map <String , CodegenModel > modelNames = new HashMap <String , CodegenModel >();
68
+ protected Map <String , CodegenParameter > uniqueParamsByName = new HashMap <String , CodegenParameter >();
69
+ protected Set <String > typeNames = new HashSet <String >();
70
70
protected Map <String , Map <String ,String >> allMimeTypes = new HashMap <String , Map <String ,String >>();
71
71
protected Map <String , String > knownMimeDataTypes = new HashMap <String , String >();
72
72
protected Map <String , Set <String >> modelMimeTypes = new HashMap <String , Set <String >>();
@@ -466,42 +466,49 @@ public String toInstantiationType(Property p) {
466
466
public CodegenOperation fromOperation (String resourcePath , String httpMethod , Operation operation , Map <String , Model > definitions , Swagger swagger ) {
467
467
CodegenOperation op = super .fromOperation (resourcePath , httpMethod , operation , definitions , swagger );
468
468
469
- op .vendorExtensions .put ("x-baseOperationId" , op .operationId );
469
+ // prevent aliasing/sharing of operation.vendorExtensions reference
470
+ op .vendorExtensions = new LinkedHashMap ();
471
+
472
+ String operationType = toTypeName ("Op" , op .operationId );
473
+ op .vendorExtensions .put ("x-operationType" , operationType );
474
+ typeNames .add (operationType );
475
+
470
476
op .vendorExtensions .put ("x-haddockPath" , String .format ("%s %s" , op .httpMethod , op .path .replace ("/" , "\\ /" )));
471
- op .operationId = toVarName (op .operationId );
472
- op .vendorExtensions .put ("x-operationType" , toTypeName ("Op" , op .operationId ));
473
477
op .vendorExtensions .put ("x-hasBodyOrFormParam" , op .getHasBodyParam () || op .getHasFormParams ());
474
478
475
479
for (CodegenParameter param : op .allParams ) {
476
- param .vendorExtensions .put ("x-operationType" , WordUtils .capitalize (op .operationId ));
480
+ param .vendorExtensions = new LinkedHashMap (); // prevent aliasing/sharing
481
+ param .vendorExtensions .put ("x-operationType" , operationType );
477
482
param .vendorExtensions .put ("x-isBodyOrFormParam" , param .isBodyParam || param .isFormParam );
478
483
if (!StringUtils .isBlank (param .collectionFormat )) {
479
484
param .vendorExtensions .put ("x-collectionFormat" , mapCollectionFormat (param .collectionFormat ));
480
485
}
481
- if (!param .required ) {
486
+ if (!param .required ) {
482
487
op .vendorExtensions .put ("x-hasOptionalParams" , true );
483
-
488
+ }
489
+ if (typeMapping .containsKey (param .dataType ) || param .isPrimitiveType || param .isListContainer || param .isMapContainer || param .isFile ) {
484
490
String paramNameType = toTypeName ("Param" , param .paramName );
485
491
486
- if (uniqueOptionalParamsByName .containsKey (paramNameType )) {
487
- CodegenParameter lastParam = this .uniqueOptionalParamsByName .get (paramNameType );
492
+ if (uniqueParamsByName .containsKey (paramNameType )) {
493
+ CodegenParameter lastParam = this .uniqueParamsByName .get (paramNameType );
488
494
if (lastParam .dataType != null && lastParam .dataType .equals (param .dataType )) {
489
495
param .vendorExtensions .put ("x-duplicate" , true );
490
496
} else {
491
497
paramNameType = paramNameType + param .dataType ;
492
- while (modelNames . containsKey (paramNameType )) {
498
+ while (typeNames . contains (paramNameType )) {
493
499
paramNameType = generateNextName (paramNameType );
494
500
}
501
+ uniqueParamsByName .put (paramNameType , param );
495
502
}
496
503
} else {
497
- while (modelNames . containsKey (paramNameType )) {
504
+ while (typeNames . contains (paramNameType )) {
498
505
paramNameType = generateNextName (paramNameType );
499
506
}
500
- uniqueOptionalParamsByName .put (paramNameType , param );
507
+ uniqueParamsByName .put (paramNameType , param );
501
508
}
502
509
503
510
param .vendorExtensions .put ("x-paramNameType" , paramNameType );
504
- op . vendorExtensions . put ( "x-hasBodyOrFormParam" , op . getHasBodyParam () || op . getHasFormParams () );
511
+ typeNames . add ( paramNameType );
505
512
}
506
513
}
507
514
if (op .getHasPathParams ()) {
@@ -572,7 +579,18 @@ public CodegenOperation fromOperation(String resourcePath, String httpMethod, Op
572
579
573
580
return op ;
574
581
}
575
-
582
+
583
+ public List <CodegenSecurity > fromSecurity (Map <String , SecuritySchemeDefinition > schemes ) {
584
+ List <CodegenSecurity > secs = super .fromSecurity (schemes );
585
+ for (CodegenSecurity sec : secs ) {
586
+ String prefix = "" ;
587
+ if (sec .isBasic ) prefix = "AuthBasic" ;
588
+ if (sec .isApiKey ) prefix = "AuthApiKey" ;
589
+ if (sec .isOAuth ) prefix = "AuthOAuth" ;
590
+ sec .name = prefix + toTypeName ("" ,sec .name );
591
+ }
592
+ return secs ;
593
+ }
576
594
577
595
@ Override
578
596
public Map <String , Object > postProcessOperations (Map <String , Object > objs ) {
@@ -586,6 +604,7 @@ public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
586
604
587
605
additionalProperties .put ("x-hasUnknownMimeTypes" , !unknownMimeTypes .isEmpty ());
588
606
additionalProperties .put ("x-unknownMimeTypes" , unknownMimeTypes );
607
+ additionalProperties .put ("x-allUniqueParams" , uniqueParamsByName .values ());
589
608
590
609
return ret ;
591
610
}
@@ -619,12 +638,13 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
619
638
public CodegenModel fromModel (String name , Model mod , Map <String , Model > allDefinitions ) {
620
639
CodegenModel model = super .fromModel (name , mod , allDefinitions );
621
640
622
- while (uniqueOptionalParamsByName . containsKey (model .classname )) {
641
+ while (typeNames . contains (model .classname )) {
623
642
model .classname = generateNextName (model .classname );
624
643
}
644
+ typeNames .add (model .classname );
625
645
626
646
// From the model name, compute the prefix for the fields.
627
- String prefix = WordUtils .uncapitalize (model .classname );
647
+ String prefix = StringUtils .uncapitalize (model .classname );
628
648
for (CodegenProperty prop : model .vars ) {
629
649
prop .name = toVarName (prefix , prop .name );
630
650
}
@@ -635,7 +655,6 @@ public CodegenModel fromModel(String name, Model mod, Map<String, Model> allDefi
635
655
return model ;
636
656
}
637
657
638
- modelNames .put (model .classname , model );
639
658
return model ;
640
659
}
641
660
@@ -674,6 +693,7 @@ private void processMediaType(CodegenOperation op, Map<String, String> m) {
674
693
if (StringUtils .isBlank (mediaType )) return ;
675
694
676
695
String mimeType = getMimeDataType (mediaType );
696
+ typeNames .add (mimeType );
677
697
m .put (MEDIA_DATA_TYPE , mimeType );
678
698
if (isJsonMimeType (mediaType )) {
679
699
m .put (MEDIA_IS_JSON , "true" );
@@ -761,6 +781,7 @@ private static boolean isMultipartOperation(List<Map<String, String>> consumes)
761
781
}
762
782
return false ;
763
783
}
784
+
764
785
@ Override
765
786
public String toVarName (String name ) {
766
787
return toVarName ("" , name );
@@ -794,8 +815,28 @@ public String toModelFilename(String name) {
794
815
return toTypeName ("Model" , name );
795
816
}
796
817
public String toTypeName (String prefix , String name ) {
797
- name = camelize (underscore (sanitizeName (name )));
798
-
818
+ name = escapeIdentifier (prefix , camelize (sanitizeName (name )));
819
+ return name ;
820
+ }
821
+ @ Override
822
+ public String toOperationId (String operationId ) {
823
+ if (StringUtils .isEmpty (operationId )) {
824
+ throw new RuntimeException ("Empty method/operation name (operationId) not allowed" );
825
+ }
826
+ operationId = escapeIdentifier ("op" ,camelize (sanitizeName (operationId ), true ));
827
+ String uniqueName = operationId ;
828
+ String uniqueNameType = toTypeName ("Op" , operationId );
829
+ while (typeNames .contains (uniqueNameType )) {
830
+ uniqueName = generateNextName (uniqueName );
831
+ uniqueNameType = toTypeName ("Op" , uniqueName );
832
+ }
833
+ typeNames .add (uniqueNameType );
834
+ if (!operationId .equals (uniqueName )) {
835
+ LOGGER .warn ("generated unique operationId `" + uniqueName + "`" );
836
+ }
837
+ return uniqueName ;
838
+ }
839
+ public String escapeIdentifier (String prefix , String name ) {
799
840
if (StringUtils .isBlank (prefix )) return name ;
800
841
801
842
if (isReservedWord (name )) {
@@ -815,4 +856,65 @@ public String toTypeName(String prefix, String name) {
815
856
static boolean isJsonMimeType (String mime ) {
816
857
return mime != null && JSON_MIME_PATTERN .matcher (mime ).matches ();
817
858
}
859
+
860
+ @ Override
861
+ public String toDefaultValue (Property p ) {
862
+ if (p instanceof StringProperty ) {
863
+ StringProperty dp = (StringProperty ) p ;
864
+ if (dp .getDefault () != null ) {
865
+ return "\" " + escapeText (dp .getDefault ()) + "\" " ;
866
+ }
867
+ } else if (p instanceof BooleanProperty ) {
868
+ BooleanProperty dp = (BooleanProperty ) p ;
869
+ if (dp .getDefault () != null ) {
870
+ if (dp .getDefault ().toString ().equalsIgnoreCase ("false" ))
871
+ return "False" ;
872
+ else
873
+ return "True" ;
874
+ }
875
+ } else if (p instanceof DoubleProperty ) {
876
+ DoubleProperty dp = (DoubleProperty ) p ;
877
+ if (dp .getDefault () != null ) {
878
+ return dp .getDefault ().toString ();
879
+ }
880
+ } else if (p instanceof FloatProperty ) {
881
+ FloatProperty dp = (FloatProperty ) p ;
882
+ if (dp .getDefault () != null ) {
883
+ return dp .getDefault ().toString ();
884
+ }
885
+ } else if (p instanceof IntegerProperty ) {
886
+ IntegerProperty dp = (IntegerProperty ) p ;
887
+ if (dp .getDefault () != null ) {
888
+ return dp .getDefault ().toString ();
889
+ }
890
+ } else if (p instanceof LongProperty ) {
891
+ LongProperty dp = (LongProperty ) p ;
892
+ if (dp .getDefault () != null ) {
893
+ return dp .getDefault ().toString ();
894
+ }
895
+ }
896
+
897
+ return null ;
898
+ }
899
+
900
+ // override with any special text escaping logic
901
+ @ SuppressWarnings ("static-method" )
902
+ public String escapeText (String input ) {
903
+ if (input == null ) {
904
+ return input ;
905
+ }
906
+
907
+ // remove \t, \n, \r
908
+ // replace \ with \\
909
+ // replace " with \"
910
+ // outter unescape to retain the original multi-byte characters
911
+ // finally escalate characters avoiding code injection
912
+ return escapeUnsafeCharacters (
913
+ StringEscapeUtils .unescapeJava (
914
+ StringEscapeUtils .escapeJava (input )
915
+ .replace ("\\ /" , "/" ))
916
+ .replaceAll ("[\\ t\\ n\\ r]" ," " )
917
+ .replace ("\\ " , "\\ \\ " )
918
+ .replace ("\" " , "\\ \" " ));
919
+ }
818
920
}
0 commit comments