@@ -1041,7 +1041,9 @@ public CodegenProperty fromProperty(String name, Schema p, boolean required, boo
10411041 cp .isNullable = false ;
10421042 cp .setHasMultipleTypes (true );
10431043 }
1044- postProcessPattern (cp .pattern , cp .vendorExtensions );
1044+ if (p .getPattern () != null ) {
1045+ postProcessPattern (p .getPattern (), cp .vendorExtensions );
1046+ }
10451047 // if we have a property that has a difficult name, either:
10461048 // 1. name is reserved, like class int float
10471049 // 2. name is invalid in python like '3rd' or 'Content-Type'
@@ -1485,7 +1487,11 @@ protected Object processTestExampleData(Object value) {
14851487 @ Override
14861488 public CodegenModel fromModel (String name , Schema sc ) {
14871489 CodegenModel cm = super .fromModel (name , sc );
1488-
1490+ if (sc .getPattern () != null ) {
1491+ postProcessPattern (sc .getPattern (), cm .vendorExtensions );
1492+ String pattern = (String ) cm .vendorExtensions .get ("x-regex" );
1493+ cm .setPattern (pattern );
1494+ }
14891495 if (cm .isNullable ) {
14901496 cm .setIsNull (true );
14911497 cm .isNullable = false ;
@@ -1891,34 +1897,21 @@ private String toExampleValueRecursive(String modelName, Schema schema, Object o
18911897 example = "2" ;
18921898 } else if (StringUtils .isNotBlank (schema .getPattern ())) {
18931899 String pattern = schema .getPattern ();
1900+ List <Object > results = getPatternAndModifiers (pattern );
1901+ String extractedPattern = (String ) results .get (0 );
1902+ List <String > regexFlags = (List <String >) results .get (1 );
18941903 /*
18951904 RxGen does not support our ECMA dialect https://github.com/curious-odd-man/RgxGen/issues/56
18961905 So strip off the leading / and trailing / and turn on ignore case if we have it
18971906 */
1898- Pattern valueExtractor = Pattern .compile ("^/?(.+?)/?(.?)$" );
1899- Matcher m = valueExtractor .matcher (pattern );
19001907 RgxGen rgxGen = null ;
1901- if (m .find ()) {
1902- int groupCount = m .groupCount ();
1903- if (groupCount == 1 ) {
1904- // only pattern found
1905- String isolatedPattern = m .group (1 );
1906- rgxGen = new RgxGen (isolatedPattern );
1907- } else if (groupCount == 2 ) {
1908- // patterns and flag found
1909- String isolatedPattern = m .group (1 );
1910- String flags = m .group (2 );
1911- if (flags .contains ("i" )) {
1912- rgxGen = new RgxGen (isolatedPattern );
1913- RgxGenProperties properties = new RgxGenProperties ();
1914- RgxGenOption .CASE_INSENSITIVE .setInProperties (properties , true );
1915- rgxGen .setProperties (properties );
1916- } else {
1917- rgxGen = new RgxGen (isolatedPattern );
1918- }
1919- }
1908+ if (regexFlags .size () > 0 && regexFlags .contains ("i" )) {
1909+ rgxGen = new RgxGen (extractedPattern );
1910+ RgxGenProperties properties = new RgxGenProperties ();
1911+ RgxGenOption .CASE_INSENSITIVE .setInProperties (properties , true );
1912+ rgxGen .setProperties (properties );
19201913 } else {
1921- rgxGen = new RgxGen (pattern );
1914+ rgxGen = new RgxGen (extractedPattern );
19221915 }
19231916
19241917 // this seed makes it so if we have [a-z] we pick a
@@ -2358,6 +2351,16 @@ protected void updatePropertyForString(CodegenProperty property, Schema p) {
23582351 property .pattern = toRegularExpression (p .getPattern ());
23592352 }
23602353
2354+ @ Override
2355+ public String toRegularExpression (String pattern ) {
2356+ if (pattern == null ) {
2357+ return null ;
2358+ }
2359+ List <Object > results = getPatternAndModifiers (pattern );
2360+ String extractedPattern = (String ) results .get (0 );
2361+ return extractedPattern ;
2362+ }
2363+
23612364 protected void updatePropertyForNumber (CodegenProperty property , Schema p ) {
23622365 property .setIsNumber (true );
23632366 // float and double differentiation is determined with format info
@@ -2482,35 +2485,61 @@ public ModelsMap postProcessModels(ModelsMap objs) {
24822485 return postProcessModelsEnum (objs );
24832486 }
24842487
2488+ /**
2489+ * @param pattern the regex pattern
2490+ * @return List<String pattern, List<String modifer>>
2491+ */
2492+ private List <Object > getPatternAndModifiers (String pattern ) {
2493+ /*
2494+ Notes:
2495+ RxGen does not support our ECMA dialect https://github.com/curious-odd-man/RgxGen/issues/56
2496+ So strip off the leading / and trailing / and turn on ignore case if we have it
2497+
2498+ json schema test cases omit the leading and trailing /s, so make sure that the regex allows that
2499+ */
2500+ Pattern valueExtractor = Pattern .compile ("^/?(.+?)/?([simu]{0,4})$" );
2501+ Matcher m = valueExtractor .matcher (pattern );
2502+ if (m .find ()) {
2503+ int groupCount = m .groupCount ();
2504+ if (groupCount == 1 ) {
2505+ // only pattern found
2506+ String isolatedPattern = m .group (1 );
2507+ return Arrays .asList (isolatedPattern , null );
2508+ } else if (groupCount == 2 ) {
2509+ List <String > modifiers = new ArrayList <String >();
2510+ // patterns and flag found
2511+ String isolatedPattern = m .group (1 );
2512+ String flags = m .group (2 );
2513+ if (flags .contains ("s" )) {
2514+ modifiers .add ("DOTALL" );
2515+ }
2516+ if (flags .contains ("i" )) {
2517+ modifiers .add ("IGNORECASE" );
2518+ }
2519+ if (flags .contains ("m" )) {
2520+ modifiers .add ("MULTILINE" );
2521+ }
2522+ return Arrays .asList (isolatedPattern , modifiers );
2523+ }
2524+ }
2525+ return Arrays .asList (pattern , new ArrayList <String >());
2526+ }
2527+
24852528 /*
24862529 * The OpenAPI pattern spec follows the Perl convention and style of modifiers. Python
24872530 * does not support this in as natural a way so it needs to convert it. See
24882531 * https://docs.python.org/2/howto/regex.html#compilation-flags for details.
24892532 */
24902533 public void postProcessPattern (String pattern , Map <String , Object > vendorExtensions ) {
24912534 if (pattern != null ) {
2492- int regexLength = pattern .length ();
2493- String regex = pattern ;
2494- int i = pattern .lastIndexOf ('/' );
2495- if (regexLength >= 2 && pattern .charAt (0 ) == '/' && i != -1 ) {
2496- // json schema tests do not include the leading and trailing slashes
2497- // so I do not think that they are required
2498- regex = pattern .substring (1 , i );
2499- }
2500- regex = regex .replace ("'" , "\\ '" );
2501- List <String > modifiers = new ArrayList <String >();
2502-
2503- if (i != -1 ) {
2504- for (char c : pattern .substring (i ).toCharArray ()) {
2505- if (regexModifiers .containsKey (c )) {
2506- String modifier = regexModifiers .get (c );
2507- modifiers .add (modifier );
2508- }
2509- }
2510- }
2535+ List <Object > results = getPatternAndModifiers (pattern );
2536+ String extractedPattern = (String ) results .get (0 );
2537+ List <String > modifiers = (List <String >) results .get (1 );
25112538
2512- vendorExtensions .put ("x-regex" , regex );
2513- vendorExtensions .put ("x-modifiers" , modifiers );
2539+ vendorExtensions .put ("x-regex" , extractedPattern );
2540+ if (modifiers .size () > 0 ) {
2541+ vendorExtensions .put ("x-modifiers" , modifiers );
2542+ }
25142543 }
25152544 }
25162545
0 commit comments