/** * Parses the text to a builder. * * <p>This parses to a {@code DateTimeBuilder} ensuring that the text is fully parsed. This method * throws {@link DateTimeParseException} if unable to parse, or some other {@code * DateTimeException} if another date/time problem occurs. * * @param text the text to parse, not null * @return the engine representing the result of the parse, not null * @throws DateTimeParseException if the parse fails * @throws DateTimeException if there is a date/time problem */ public DateTimeBuilder parseToBuilder(CharSequence text) { Objects.requireNonNull(text, "text"); String str = text.toString(); // parsing whole String, so this makes sense ParsePosition pos = new ParsePosition(0); DateTimeBuilder result = parseToBuilder(str, pos); if (result == null || pos.getErrorIndex() >= 0 || pos.getIndex() < str.length()) { String abbr = str.toString(); if (abbr.length() > 64) { abbr = abbr.substring(0, 64) + "..."; } if (pos.getErrorIndex() >= 0) { throw new DateTimeParseException( "Text '" + abbr + "' could not be parsed at index " + pos.getErrorIndex(), str, pos.getErrorIndex()); } else { throw new DateTimeParseException( "Text '" + abbr + "' could not be parsed, unparsed text found at index " + pos.getIndex(), str, pos.getIndex()); } } return result; }
@Override public Object parseObject(String text, ParsePosition pos) { Objects.requireNonNull(text, "text"); DateTimeBuilder builder; try { builder = formatter.parseToBuilder(text, pos); } catch (IndexOutOfBoundsException ex) { if (pos.getErrorIndex() < 0) { pos.setErrorIndex(0); } return null; } if (builder == null) { if (pos.getErrorIndex() < 0) { pos.setErrorIndex(0); } return null; } if (parseType == null) { return builder; } try { return builder.resolve().build(parseType); } catch (RuntimeException ex) { pos.setErrorIndex(0); return null; } }
@Override public Object parseObject(String s, ParsePosition pos) { if (pos.getErrorIndex() >= 0) throw new IllegalArgumentException(pos + " has en error at " + pos.getErrorIndex()); boolean success = false; Object tmpRes = null; final ParsePosition tmpPos = new ParsePosition(pos.getIndex()); final Iterator<? extends Format> iter = this.formats.iterator(); while (iter.hasNext() && !success) { final Format f = iter.next(); mutateTo(tmpPos, pos); tmpRes = f.parseObject(s, tmpPos); success = tmpPos.getIndex() != pos.getIndex() && tmpPos.getErrorIndex() < 0; } final Object res; if (!success) { // fail with the same as format() res = this.formats.get(this.formatIndex).parseObject(s, pos); } else { res = tmpRes; mutateTo(pos, tmpPos); } return res; }
public void test(TestHarness harness) { ParsePosition pp = new ParsePosition(69); harness.check(pp.getIndex(), 69, "getIndex() post-create"); pp.setIndex(666); harness.check(pp.getIndex(), 666, "set/getIndex()"); harness.check(pp.getErrorIndex(), -1, "getErrorIndex() no error"); pp.setErrorIndex(65536); harness.check(pp.getErrorIndex(), 65536, "set/getErrorIndex()"); harness.debug(pp.toString()); }
/** * Checks if the value can safely be converted to a byte primitive. * * @param value The value validation is being performed on. * @param locale The locale to use to parse the number (system default if null) * @return the converted Byte value. */ public static Byte formatByte(String value, Locale locale) { Byte result = null; if (value != null) { NumberFormat formatter = null; if (locale != null) { formatter = NumberFormat.getNumberInstance(locale); } else { formatter = NumberFormat.getNumberInstance(Locale.getDefault()); } formatter.setParseIntegerOnly(true); ParsePosition pos = new ParsePosition(0); Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && num.doubleValue() >= Byte.MIN_VALUE && num.doubleValue() <= Byte.MAX_VALUE) { result = new Byte(num.byteValue()); } } return result; }
/** * @generated */ public IParserEditStatus isValidEditString(IAdaptable adapter, String editString) { ParsePosition pos = new ParsePosition(0); Object[] values = getEditProcessor().parse(editString, pos); if (values == null) { return new ParserEditStatus(ScribbleDiagramEditorPlugin.ID, IParserEditStatus.UNEDITABLE, NLS.bind( Messages.MessageFormatParser_InvalidInputError, new Integer(pos.getErrorIndex()))); } return validateNewValues(values); }
@Override public Date parse(String i, ParsePosition p) { /* delegate to SimpleDateFormat for easy stuff */ Date d = super.parse(i, p); int milliIndex = p.getIndex(); /* worry about the milliseconds ourselves */ if (null != d && -1 == p.getErrorIndex() && milliIndex + 1 < i.length() && '.' == i.charAt(milliIndex)) { p.setIndex(++milliIndex); // NOTE: ++ to chomp '.' Number millis = millisParser.parse(i, p); if (-1 == p.getErrorIndex()) { int endIndex = p.getIndex(); d = new Date( d.getTime() + (long) (millis.doubleValue() * Math.pow(10, (3 - endIndex + milliIndex)))); } } return d; }
protected String isCorrectString(String value) { String text = value.trim(); if (sMinValue.equalsIgnoreCase(text) || sMaxValue.equalsIgnoreCase(text)) return null; Number result = null; if ((fNumberType == DOUBLE || fNumberType == FLOAT) && (text.indexOf('e') != -1 || text.indexOf('E') != -1)) { // We have a double/float with an exponent. This is scientific notation. Formatter handles // them badly, so use parse instead. try { if (fNumberType == DOUBLE) { result = new Double(Double.parseDouble(text)); } else { result = new Float(Float.parseFloat(text)); } } catch (NumberFormatException e) { } } else { // integral or not scientific notation. Let formatter handle it. ParsePosition parsePosition = new ParsePosition(0); result = fFormatter.parse(text, parsePosition); if (parsePosition.getErrorIndex() != -1 || parsePosition.getIndex() != text.length()) result = null; // Some error // Check for out of bounds with long type if (fNumberType == LONG && result instanceof Double) { result = (result.doubleValue() < 0) ? MinmaxValidator.LONG_UNDERFLOW : MinmaxValidator.LONG_OVERFLOW; } } if (result != null) { // Now see if it is valid for the requested type. MinmaxValidator v = sMinMaxValidators[fNumberType]; // Double/Float are special because the min/MIN are on the absolute value, not signed value. if (fNumberType == DOUBLE || fNumberType == FLOAT) { double d = result.doubleValue(); if (d == 0.0 || d == -0.0) return null; // +/- zero are valid values. result = new Double(Math.abs(d)); } if (v != null) { String e = v.isValid(result); if (e == null || e.length() == 0) return null; return e; // It didn't fit in a the number type. } } return (fFormatter.isParseIntegerOnly() ? sNotIntegerError : sNotNumberError); }
/** * @tests java.text.MessageFormat#parseObject(java.lang.String, java.text.ParsePosition) Test of * method java.text.MessageFormat#parseObject(java.lang.String, java.text.ParsePosition). Case * 1: Parsing of correct data string. Case 2: Parsing of partial correct data string. Case 3: * Try to use argument ParsePosition as null. */ @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "parseObject", args = {java.lang.String.class, java.text.ParsePosition.class}) public void test_parseObjectLjava_lang_StringLjavajava_text_ParsePosition() { MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}"); try { // case 1: Try to parse correct data string. Object[] objs = {new Double(3.1415)}; String result = mf.format(objs); // result now equals "3.14, 3.1" Object[] res = null; ParsePosition pp = new ParsePosition(0); int parseIndex = pp.getIndex(); res = (Object[]) mf.parseObject(result, pp); assertTrue("Parse operation return null", res != null); assertTrue("parse operation return array with incorrect length", 1 == res.length); assertTrue("ParseIndex is incorrect", pp.getIndex() != parseIndex); assertTrue("Result object is incorrect", new Double(3.1).equals(res[0])); // case 2: Try to parse partially correct data string. pp.setIndex(0); char[] cur = result.toCharArray(); cur[cur.length / 2] = 'Z'; String partialCorrect = new String(cur); res = (Object[]) mf.parseObject(partialCorrect, pp); assertTrue("Parse operation return null", res == null); assertTrue("ParseIndex is incorrect", pp.getIndex() == 0); assertTrue("ParseErrorIndex is incorrect", pp.getErrorIndex() == cur.length / 2); // case 3: Try to use argument ParsePosition as null. try { mf.parseObject(result, null); fail("Expected NullPointerException was not thrown"); } catch (NullPointerException e) { // expected } } catch (Exception e) { fail("Unexpected exception " + e.toString()); } }
/** * Parse a String into a <code>Calendar</code> object using the specified <code>DateFormat</code>. * * @param sourceType The type of the value being converted * @param targetType The type to convert the value to * @param value The String date value. * @param format The DateFormat to parse the String value. * @return The converted Calendar object. * @throws ConversionException if the String cannot be converted. */ private Calendar parse( final Class sourceType, final Class targetType, final String value, final DateFormat format) { format.setLenient(false); ParsePosition pos = new ParsePosition(0); Date parsedDate = format.parse(value, pos); // ignore the result (use the Calendar) if (pos.getErrorIndex() >= 0 || pos.getIndex() != value.length() || parsedDate == null) { String msg = "Error converting '" + this.toString(sourceType) + "' to '" + this.toString(targetType) + "'"; if (format instanceof SimpleDateFormat) { msg += " using pattern '" + ((SimpleDateFormat) format).toPattern() + "'"; } throw new ConversionException(msg); } Calendar calendar = format.getCalendar(); return calendar; }
/** * Checks if the value can safely be converted to a double primitive. * * @param value The value validation is being performed on. * @param locale The locale to use to parse the number (system default if null) * @return the converted Double value. */ public static Double formatDouble(String value, Locale locale) { Double result = null; if (value != null) { NumberFormat formatter = null; if (locale != null) { formatter = NumberFormat.getInstance(locale); } else { formatter = NumberFormat.getInstance(Locale.getDefault()); } ParsePosition pos = new ParsePosition(0); Number num = formatter.parse(value, pos); // If there was no error and we used the whole string if (pos.getErrorIndex() == -1 && pos.getIndex() == value.length() && num.doubleValue() >= (Double.MAX_VALUE * -1) && num.doubleValue() <= Double.MAX_VALUE) { result = new Double(num.doubleValue()); } } return result; }
/** * Parse a TimeUnitAmount. * * @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition) * @stable ICU 4.0 */ public Object parseObject(String source, ParsePosition pos) { if (!isReady) { setup(); } Number resultNumber = null; TimeUnit resultTimeUnit = null; int oldPos = pos.getIndex(); int newPos = -1; int longestParseDistance = 0; String countOfLongestMatch = null; // we don't worry too much about speed on parsing, but this can be optimized later if needed. // Parse by iterating through all available patterns // and looking for the longest match. for (TimeUnit timeUnit : timeUnitToCountToPatterns.keySet()) { Map<String, Object[]> countToPattern = timeUnitToCountToPatterns.get(timeUnit); for (Entry<String, Object[]> patternEntry : countToPattern.entrySet()) { String count = patternEntry.getKey(); for (int styl = FULL_NAME; styl < TOTAL_STYLES; ++styl) { MessageFormat pattern = (MessageFormat) (patternEntry.getValue())[styl]; pos.setErrorIndex(-1); pos.setIndex(oldPos); // see if we can parse Object parsed = pattern.parseObject(source, pos); if (pos.getErrorIndex() != -1 || pos.getIndex() == oldPos) { // nothing parsed continue; } Number temp = null; if (((Object[]) parsed).length != 0) { // pattern with Number as beginning, // such as "{0} d". // check to make sure that the timeUnit is consistent temp = (Number) ((Object[]) parsed)[0]; String select = pluralRules.select(temp.doubleValue()); if (!count.equals(select)) { continue; } } int parseDistance = pos.getIndex() - oldPos; if (parseDistance > longestParseDistance) { resultNumber = temp; resultTimeUnit = timeUnit; newPos = pos.getIndex(); longestParseDistance = parseDistance; countOfLongestMatch = count; } } } } /* After find the longest match, parse the number. * Result number could be null for the pattern without number pattern. * such as unit pattern in Arabic. * When result number is null, use plural rule to set the number. */ if (resultNumber == null && longestParseDistance != 0) { // set the number using plurrual count if (countOfLongestMatch.equals("zero")) { resultNumber = Integer.valueOf(0); } else if (countOfLongestMatch.equals("one")) { resultNumber = Integer.valueOf(1); } else if (countOfLongestMatch.equals("two")) { resultNumber = Integer.valueOf(2); } else { // should not happen. // TODO: how to handle? resultNumber = Integer.valueOf(3); } } if (longestParseDistance == 0) { pos.setIndex(oldPos); pos.setErrorIndex(0); return null; } else { pos.setIndex(newPos); pos.setErrorIndex(-1); return new TimeUnitAmount(resultNumber, resultTimeUnit); } }
private void mutateTo(ParsePosition tmpPos, ParsePosition pos) { tmpPos.setIndex(pos.getIndex()); tmpPos.setErrorIndex(pos.getErrorIndex()); }