|
5 | 5 | import java.math.BigInteger;
|
6 | 6 | import java.util.Arrays;
|
7 | 7 | import java.util.Collections;
|
8 |
| -import java.util.HashSet; |
9 | 8 | import java.util.Map;
|
10 |
| -import java.util.Set; |
11 | 9 | import java.util.regex.Pattern;
|
12 | 10 |
|
13 | 11 | import org.yaml.snakeyaml.DumperOptions;
|
|
20 | 18 | import com.fasterxml.jackson.core.base.GeneratorBase;
|
21 | 19 | import com.fasterxml.jackson.core.json.JsonWriteContext;
|
22 | 20 | import com.fasterxml.jackson.core.util.JacksonFeatureSet;
|
| 21 | +import com.fasterxml.jackson.dataformat.yaml.util.StringQuotingChecker; |
23 | 22 | import com.fasterxml.jackson.core.io.IOContext;
|
24 | 23 |
|
25 | 24 | public class YAMLGenerator extends GeneratorBase
|
@@ -172,33 +171,6 @@ private Feature(boolean defaultState) {
|
172 | 171 | protected final static Pattern PLAIN_NUMBER_P = Pattern.compile("-?[0-9]*(\\.[0-9]*)?");
|
173 | 172 | protected final static String TAG_BINARY = Tag.BINARY.toString();
|
174 | 173 |
|
175 |
| - /* As per <a href="https://yaml.org/type/bool.html">YAML Spec</a> there are a few |
176 |
| - * aliases for booleans, and we better quote such values as keys; although Jackson |
177 |
| - * itself has no problems dealing with them, some other tools do have. |
178 |
| - */ |
179 |
| - // 02-Apr-2019, tatu: Some names will look funny if escaped: let's leave out |
180 |
| - // single letter case (esp so 'y' won't get escaped) |
181 |
| - // 17-Sep-2020, tatu: [dataformats-text#226] No, let's be consistent w/ values |
182 |
| - private final static Set<String> MUST_QUOTE_NAMES = new HashSet<>(Arrays.asList( |
183 |
| - "y", "Y", "n", "N", |
184 |
| - "yes", "Yes", "YES", "no", "No", "NO", |
185 |
| - "true", "True", "TRUE", "false", "False", "FALSE", |
186 |
| - "on", "On", "ON", "off", "Off", "OFF" |
187 |
| - )); |
188 |
| - |
189 |
| - /** |
190 |
| - * As per YAML <a href="https://yaml.org/type/null.html">null</a> |
191 |
| - * and <a href="https://yaml.org/type/bool.html">boolean</a> type specs, |
192 |
| - * better retain quoting for some values |
193 |
| - */ |
194 |
| - private final static Set<String> MUST_QUOTE_VALUES = new HashSet<>(Arrays.asList( |
195 |
| - "y", "Y", "n", "N", |
196 |
| - "yes", "Yes", "YES", "no", "No", "NO", |
197 |
| - "true", "True", "TRUE", "false", "False", "FALSE", |
198 |
| - "on", "On", "ON", "off", "Off", "OFF", |
199 |
| - "null", "Null", "NULL" |
200 |
| - )); |
201 |
| - |
202 | 174 | /*
|
203 | 175 | /**********************************************************
|
204 | 176 | /* Configuration
|
@@ -258,6 +230,7 @@ private Feature(boolean defaultState) {
|
258 | 230 |
|
259 | 231 | protected int _rootValueCount;
|
260 | 232 |
|
| 233 | + protected final StringQuotingChecker _quotingChecker = StringQuotingChecker.Default.instance(); |
261 | 234 | /*
|
262 | 235 | /**********************************************************
|
263 | 236 | /* Life-cycle
|
@@ -462,7 +435,7 @@ public void writeFieldId(long id) throws IOException {
|
462 | 435 | private final void _writeFieldName(String name) throws IOException
|
463 | 436 | {
|
464 | 437 | _writeScalar(name, "string",
|
465 |
| - _nameNeedsQuoting(name) ? STYLE_QUOTED : STYLE_UNQUOTED_NAME); |
| 438 | + _quotingChecker.needToQuoteName(name) ? STYLE_QUOTED : STYLE_UNQUOTED_NAME); |
466 | 439 | }
|
467 | 440 |
|
468 | 441 | /*
|
@@ -592,7 +565,7 @@ public void writeString(String text) throws IOException,JsonGenerationException
|
592 | 565 | DumperOptions.ScalarStyle style;
|
593 | 566 | if (Feature.MINIMIZE_QUOTES.enabledIn(_formatFeatures)) {
|
594 | 567 | // If one of reserved values ("true", "null"), or, number, preserve quoting:
|
595 |
| - if (_valueNeedsQuoting(text) |
| 568 | + if (_quotingChecker.needToQuoteValue(text) |
596 | 569 | || (Feature.ALWAYS_QUOTE_NUMBERS_AS_STRINGS.enabledIn(_formatFeatures)
|
597 | 570 | && PLAIN_NUMBER_P.matcher(text).matches())
|
598 | 571 | ) {
|
@@ -944,85 +917,6 @@ private String _base64encode(final Base64Variant b64v, final byte[] input, final
|
944 | 917 | return sb.toString();
|
945 | 918 | }
|
946 | 919 |
|
947 |
| - private boolean _nameNeedsQuoting(String name) { |
948 |
| - if (name.length() == 0) { // empty String does indeed require quoting |
949 |
| - return true; |
950 |
| - } |
951 |
| - switch (name.charAt(0)) { |
952 |
| - // First, reserved name starting chars: |
953 |
| - case 'f': // false |
954 |
| - case 'o': // on/off |
955 |
| - case 'n': // no |
956 |
| - case 't': // true |
957 |
| - case 'y': // yes |
958 |
| - case 'F': // False |
959 |
| - case 'O': // On/Off |
960 |
| - case 'N': // No |
961 |
| - case 'T': // True |
962 |
| - case 'Y': // Yes |
963 |
| - return MUST_QUOTE_NAMES.contains(name); |
964 |
| - |
965 |
| - // And then numbers |
966 |
| - case '0': case '1': case '2': case '3': case '4': |
967 |
| - case '5': case '6': case '7': case '8': case '9': |
968 |
| - case '-' : case '+': case '.': |
969 |
| - return true; |
970 |
| - } |
971 |
| - return false; |
972 |
| - } |
973 |
| - |
974 |
| - private boolean _valueNeedsQuoting(String name) { |
975 |
| - switch (name.charAt(0)) { // caller ensures no empty String |
976 |
| - // First, reserved name starting chars: |
977 |
| - case 'f': // false |
978 |
| - case 'o': // on/off |
979 |
| - case 'n': // null/n/no |
980 |
| - case 't': // true |
981 |
| - case 'y': // y/yes |
982 |
| - case 'F': // False/FALSE |
983 |
| - case 'O': // On/Off/ON/OFF |
984 |
| - case 'N': // Null/NULL/N/No/NO |
985 |
| - case 'T': // True/TRUE |
986 |
| - case 'Y': // Y/Yes/YES |
987 |
| - if (MUST_QUOTE_VALUES.contains(name)) { |
988 |
| - return true; |
989 |
| - } |
990 |
| - break; |
991 |
| - } |
992 |
| - return _valueHasQuotableChar(name); |
993 |
| - } |
994 |
| - |
995 |
| - /** |
996 |
| - * As per YAML <a href="https://yaml.org/spec/1.2/spec.html#id2788859">Plain Style</a>unquoted |
997 |
| - * strings are restricted to a reduced charset and must be quoted in case they contain |
998 |
| - * one of the following characters or character combinations. |
999 |
| - */ |
1000 |
| - private static boolean _valueHasQuotableChar(String inputStr) { |
1001 |
| - for (int i = 0, end = inputStr.length(); i < end; ++i) { |
1002 |
| - switch (inputStr.charAt(i)) { |
1003 |
| - case '[': |
1004 |
| - case ']': |
1005 |
| - case '{': |
1006 |
| - case '}': |
1007 |
| - case ',': |
1008 |
| - return true; |
1009 |
| - case '\t': |
1010 |
| - case ' ': |
1011 |
| - if (i < end - 1 && '#' == inputStr.charAt(i + 1)) { |
1012 |
| - return true; |
1013 |
| - } |
1014 |
| - break; |
1015 |
| - case ':': |
1016 |
| - if (i < end - 1 && (' ' == inputStr.charAt(i + 1) || '\t' == inputStr.charAt(i + 1))) { |
1017 |
| - return true; |
1018 |
| - } |
1019 |
| - break; |
1020 |
| - default: |
1021 |
| - } |
1022 |
| - } |
1023 |
| - return false; |
1024 |
| - } |
1025 |
| - |
1026 | 920 | protected String _lf() {
|
1027 | 921 | return _outputOptions.getLineBreak().getString();
|
1028 | 922 | }
|
|
0 commit comments