1418 * @param literal the literal to append, not null
1419 * @return this, for chaining, not null
1420 */
1421 public DateTimeFormatterBuilder appendLiteral(char literal) {
1422 appendInternal(new CharLiteralPrinterParser(literal));
1423 return this;
1424 }
1425
1426 /**
1427 * Appends a string literal to the formatter.
1428 * <p>
1429 * This string will be output during a format.
1430 * <p>
1431 * If the literal is empty, nothing is added to the formatter.
1432 *
1433 * @param literal the literal to append, not null
1434 * @return this, for chaining, not null
1435 */
1436 public DateTimeFormatterBuilder appendLiteral(String literal) {
1437 Objects.requireNonNull(literal, "literal");
1438 if (literal.length() > 0) {
1439 if (literal.length() == 1) {
1440 appendInternal(new CharLiteralPrinterParser(literal.charAt(0)));
1441 } else {
1442 appendInternal(new StringLiteralPrinterParser(literal));
1443 }
1444 }
1445 return this;
1446 }
1447
1448 //-----------------------------------------------------------------------
1449 /**
1450 * Appends all the elements of a formatter to the builder.
1451 * <p>
1452 * This method has the same effect as appending each of the constituent
1453 * parts of the formatter directly to this builder.
1454 *
1455 * @param formatter the formatter to add, not null
1456 * @return this, for chaining, not null
1457 */
1458 public DateTimeFormatterBuilder append(DateTimeFormatter formatter) {
1811 throw new IllegalArgumentException("Unknown pattern letter: " + cur);
1812 }
1813 pos--;
1814
1815 } else if (cur == '\'') {
1816 // parse literals
1817 int start = pos++;
1818 for ( ; pos < pattern.length(); pos++) {
1819 if (pattern.charAt(pos) == '\'') {
1820 if (pos + 1 < pattern.length() && pattern.charAt(pos + 1) == '\'') {
1821 pos++;
1822 } else {
1823 break; // end of literal
1824 }
1825 }
1826 }
1827 if (pos >= pattern.length()) {
1828 throw new IllegalArgumentException("Pattern ends with an incomplete string literal: " + pattern);
1829 }
1830 String str = pattern.substring(start + 1, pos);
1831 if (str.length() == 0) {
1832 appendLiteral('\'');
1833 } else {
1834 appendLiteral(str.replace("''", "'"));
1835 }
1836
1837 } else if (cur == '[') {
1838 optionalStart();
1839
1840 } else if (cur == ']') {
1841 if (active.parent == null) {
1842 throw new IllegalArgumentException("Pattern invalid as it contains ] without previous [");
1843 }
1844 optionalEnd();
1845
1846 } else if (cur == '{' || cur == '}' || cur == '#') {
1847 throw new IllegalArgumentException("Pattern includes reserved character: '" + cur + "'");
1848 } else {
1849 appendLiteral(cur);
1850 }
1851 }
4310 return description;
4311 }
4312 }
4313
4314 //-----------------------------------------------------------------------
4315 /**
4316 * A String based prefix tree for parsing time-zone names.
4317 */
4318 static class PrefixTree {
4319 protected String key;
4320 protected String value;
4321 protected char c0; // performance optimization to avoid the
4322 // boundary check cost of key.charat(0)
4323 protected PrefixTree child;
4324 protected PrefixTree sibling;
4325
4326 private PrefixTree(String k, String v, PrefixTree child) {
4327 this.key = k;
4328 this.value = v;
4329 this.child = child;
4330 if (k.length() == 0){
4331 c0 = 0xffff;
4332 } else {
4333 c0 = key.charAt(0);
4334 }
4335 }
4336
4337 /**
4338 * Creates a new prefix parsing tree based on parse context.
4339 *
4340 * @param context the parse context
4341 * @return the tree, not null
4342 */
4343 public static PrefixTree newTree(DateTimeParseContext context) {
4344 //if (!context.isStrict()) {
4345 // return new LENIENT("", null, null);
4346 //}
4347 if (context.isCaseSensitive()) {
4348 return new PrefixTree("", null, null);
4349 }
4350 return new CI("", null, null);
|
1418 * @param literal the literal to append, not null
1419 * @return this, for chaining, not null
1420 */
1421 public DateTimeFormatterBuilder appendLiteral(char literal) {
1422 appendInternal(new CharLiteralPrinterParser(literal));
1423 return this;
1424 }
1425
1426 /**
1427 * Appends a string literal to the formatter.
1428 * <p>
1429 * This string will be output during a format.
1430 * <p>
1431 * If the literal is empty, nothing is added to the formatter.
1432 *
1433 * @param literal the literal to append, not null
1434 * @return this, for chaining, not null
1435 */
1436 public DateTimeFormatterBuilder appendLiteral(String literal) {
1437 Objects.requireNonNull(literal, "literal");
1438 if (!literal.isEmpty()) {
1439 if (literal.length() == 1) {
1440 appendInternal(new CharLiteralPrinterParser(literal.charAt(0)));
1441 } else {
1442 appendInternal(new StringLiteralPrinterParser(literal));
1443 }
1444 }
1445 return this;
1446 }
1447
1448 //-----------------------------------------------------------------------
1449 /**
1450 * Appends all the elements of a formatter to the builder.
1451 * <p>
1452 * This method has the same effect as appending each of the constituent
1453 * parts of the formatter directly to this builder.
1454 *
1455 * @param formatter the formatter to add, not null
1456 * @return this, for chaining, not null
1457 */
1458 public DateTimeFormatterBuilder append(DateTimeFormatter formatter) {
1811 throw new IllegalArgumentException("Unknown pattern letter: " + cur);
1812 }
1813 pos--;
1814
1815 } else if (cur == '\'') {
1816 // parse literals
1817 int start = pos++;
1818 for ( ; pos < pattern.length(); pos++) {
1819 if (pattern.charAt(pos) == '\'') {
1820 if (pos + 1 < pattern.length() && pattern.charAt(pos + 1) == '\'') {
1821 pos++;
1822 } else {
1823 break; // end of literal
1824 }
1825 }
1826 }
1827 if (pos >= pattern.length()) {
1828 throw new IllegalArgumentException("Pattern ends with an incomplete string literal: " + pattern);
1829 }
1830 String str = pattern.substring(start + 1, pos);
1831 if (str.isEmpty()) {
1832 appendLiteral('\'');
1833 } else {
1834 appendLiteral(str.replace("''", "'"));
1835 }
1836
1837 } else if (cur == '[') {
1838 optionalStart();
1839
1840 } else if (cur == ']') {
1841 if (active.parent == null) {
1842 throw new IllegalArgumentException("Pattern invalid as it contains ] without previous [");
1843 }
1844 optionalEnd();
1845
1846 } else if (cur == '{' || cur == '}' || cur == '#') {
1847 throw new IllegalArgumentException("Pattern includes reserved character: '" + cur + "'");
1848 } else {
1849 appendLiteral(cur);
1850 }
1851 }
4310 return description;
4311 }
4312 }
4313
4314 //-----------------------------------------------------------------------
4315 /**
4316 * A String based prefix tree for parsing time-zone names.
4317 */
4318 static class PrefixTree {
4319 protected String key;
4320 protected String value;
4321 protected char c0; // performance optimization to avoid the
4322 // boundary check cost of key.charat(0)
4323 protected PrefixTree child;
4324 protected PrefixTree sibling;
4325
4326 private PrefixTree(String k, String v, PrefixTree child) {
4327 this.key = k;
4328 this.value = v;
4329 this.child = child;
4330 if (k.isEmpty()) {
4331 c0 = 0xffff;
4332 } else {
4333 c0 = key.charAt(0);
4334 }
4335 }
4336
4337 /**
4338 * Creates a new prefix parsing tree based on parse context.
4339 *
4340 * @param context the parse context
4341 * @return the tree, not null
4342 */
4343 public static PrefixTree newTree(DateTimeParseContext context) {
4344 //if (!context.isStrict()) {
4345 // return new LENIENT("", null, null);
4346 //}
4347 if (context.isCaseSensitive()) {
4348 return new PrefixTree("", null, null);
4349 }
4350 return new CI("", null, null);
|