/** Unit test to check for regression of [JACKSON-18]. */ public void testSmallNumbers() throws Exception { ObjectMapper mapper = new ObjectMapper(); ArrayNode root = mapper.createArrayNode(); for (int i = -20; i <= 20; ++i) { JsonNode n = root.numberNode(i); root.add(n); // Hmmh. Not sure why toString() won't be triggered otherwise... assertEquals(String.valueOf(i), n.toString()); } // Loop over 2 different serialization methods for (int type = 0; type < 2; ++type) { StringWriter sw = new StringWriter(); if (type == 0) { JsonGenerator gen = new JsonFactory().createGenerator(sw); root.serialize(gen, null); gen.close(); } else { mapper.writeValue(sw, root); } String doc = sw.toString(); JsonParser p = new JsonFactory().createParser(new StringReader(doc)); assertEquals(JsonToken.START_ARRAY, p.nextToken()); for (int i = -20; i <= 20; ++i) { assertEquals(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(i, p.getIntValue()); assertEquals("" + i, p.getText()); } assertEquals(JsonToken.END_ARRAY, p.nextToken()); p.close(); } }
private TwitterEntry read(JsonParser jp) throws IOException { // First: verify that we got "Json Object": if (jp.nextToken() != JsonToken.START_OBJECT) { throw new IOException("Expected data to start with an Object"); } TwitterEntry result = new TwitterEntry(); // Iterate over object fields: while (jp.nextToken() != JsonToken.END_OBJECT) { String fieldName = jp.getCurrentName(); // Let's move to value jp.nextToken(); if (fieldName.equals("id")) { result.setId(jp.getLongValue()); } else if (fieldName.equals("text")) { result.setText(jp.getText()); } else if (fieldName.equals("fromUserId")) { result.setFromUserId(jp.getIntValue()); } else if (fieldName.equals("toUserId")) { result.setToUserId(jp.getIntValue()); } else if (fieldName.equals("languageCode")) { result.setLanguageCode(jp.getText()); } else { // ignore, or signal error throw new IOException("Unrecognized field '" + fieldName + "'"); } } jp.close(); // important to close both parser and underlying File reader return result; }
private void _testSurrogates(JsonFactory f, boolean checkText) throws IOException { byte[] json = "{\"text\":\"\uD83D\uDE03\"}".getBytes("UTF-8"); // first JsonParser jp = f.createParser(json); assertToken(JsonToken.START_OBJECT, jp.nextToken()); assertToken(JsonToken.FIELD_NAME, jp.nextToken()); if (checkText) { assertEquals("text", jp.getText()); } assertToken(JsonToken.VALUE_STRING, jp.nextToken()); if (checkText) { assertEquals("\uD83D\uDE03", jp.getText()); } assertToken(JsonToken.END_OBJECT, jp.nextToken()); }
public void testUtf8Issue462() throws Exception { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); IOContext ioc = new IOContext(new BufferRecycler(), bytes, true); JsonGenerator gen = new UTF8JsonGenerator(ioc, 0, null, bytes); String str = "Natuurlijk is alles gelukt en weer een tevreden klant\uD83D\uDE04"; int length = 4000 - 38; for (int i = 1; i <= length; ++i) { gen.writeNumber(1); } gen.writeString(str); gen.flush(); gen.close(); // Also verify it's parsable? JsonFactory f = new JsonFactory(); JsonParser p = f.createParser(bytes.toByteArray()); for (int i = 1; i <= length; ++i) { assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); assertEquals(1, p.getIntValue()); } assertToken(JsonToken.VALUE_STRING, p.nextToken()); assertEquals(str, p.getText()); assertNull(p.nextToken()); p.close(); }
protected String _valueDesc() { try { return _desc(_parser.getText()); } catch (Exception e) { return "[N/A]"; } }
protected DateTime parseLocal(JsonParser jp) throws IOException, JsonProcessingException { String str = jp.getText().trim(); if (str.length() == 0) { // [JACKSON-360] return null; } return _localDateTimeFormat.parseDateTime(str); }
@Override public Collection<String> deserialize( JsonParser jp, DeserializationContext ctxt, Collection<String> result) throws IOException { // Ok: must point to START_ARRAY if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt, result); } if (_valueDeserializer != null) { return deserializeUsingCustom(jp, ctxt, result, _valueDeserializer); } JsonToken t; while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; } else { value = _parseString(jp, ctxt); } result.add(value); } return result; }
@Override public ReadablePeriod deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // TODO: perhaps support array of numbers... // if (jp.isExpectedStartArrayToken()) { ] switch (jp.getCurrentToken()) { case VALUE_NUMBER_INT: // assume it's millisecond count return new Period(jp.getLongValue()); case VALUE_STRING: return new Period(jp.getText()); } throw ctxt.wrongTokenException(jp, JsonToken.START_ARRAY, "expected JSON Number or String"); }
/** This is the trickiest thing to handle, since property we are looking for may be anywhere... */ @Override public Object deserializeTypedFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // but first, sanity check to ensure we have START_OBJECT or FIELD_NAME JsonToken t = jp.getCurrentToken(); if (t == JsonToken.START_OBJECT) { t = jp.nextToken(); } else if (t != JsonToken.FIELD_NAME) { throw ctxt.wrongTokenException( jp, JsonToken.START_OBJECT, "need JSON Object to contain As.PROPERTY type information (for class " + baseTypeName() + ")"); } // Ok, let's try to find the property. But first, need token buffer... TokenBuffer tb = null; for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String name = jp.getCurrentName(); jp.nextToken(); // to point to the value if (_propertyName.equals(name)) { // gotcha! JsonDeserializer<Object> deser = _findDeserializer(ctxt, jp.getText()); // deserializer should take care of closing END_OBJECT as well if (tb != null) { jp = JsonParserSequence.createFlattened(tb.asParser(jp), jp); } /* Must point to the next value; tb had no current, jp * pointed to VALUE_STRING: */ jp.nextToken(); // to skip past String value // deserializer should take care of closing END_OBJECT as well return deser.deserialize(jp, ctxt); } if (tb == null) { tb = new TokenBuffer(null); } tb.writeFieldName(name); tb.copyCurrentStructure(jp); } // Error if we get here... throw ctxt.wrongTokenException( jp, JsonToken.FIELD_NAME, "missing property '" + _propertyName + "' that is to contain type id (for class " + baseTypeName() + ")"); }
public ArtistImpl(JsonParser parser) throws JsonParseException, IOException { if (parser.getCurrentToken() != JsonToken.START_OBJECT) { if (parser.getCurrentToken() == JsonToken.VALUE_NULL) return; throw new IOException( "Expected data to start with an Object. Found " + parser.getCurrentToken()); } while (parser.nextToken() != JsonToken.END_OBJECT) { String fName = parser.getCurrentName(); parser.nextToken(); if (fName.equals("id")) id = parser.getLongValue(); else if (fName.equals("name")) name = parser.getText(); else if (fName.equals("eventDescription")) description = parser.getText(); else if (fName.equals("urlOfficialWebsite")) siteUrl = JFlyUtils.parseURL(parser.getText()); else if (fName.equals("urlMySpace")) myspaceUrl = JFlyUtils.parseURL(parser.getText()); else if (fName.equals("urlFacebook")) facebookUrl = JFlyUtils.parseURL(parser.getText()); else if (fName.equals("twitterScreenName")) twitterScreenName = parser.getText(); else if (fName.equals("urlAudio")) audioUrl = JFlyUtils.parseURL(parser.getText()); else if (fName.equals("urlPurchaseMusic")) purchaseUrl = JFlyUtils.parseURL(parser.getText()); else if (fName.equals("embedAudio")) audioHtml = parser.getText(); else if (fName.equals("embedVideo")) videoHtml = parser.getText(); else if (fName.equals("idMobileFriendly")) mobileFriendly = parser.getBooleanValue(); else if (fName.equals("images")) { if (parser.getCurrentToken().equals(JsonToken.START_ARRAY)) { while (parser.nextToken() != JsonToken.END_ARRAY) { images.add(new ImageMetaImpl(parser)); } } } else if (fName.equals("youtubeVideos")) { if (parser.getCurrentToken().equals(JsonToken.START_ARRAY)) { while (parser.nextToken() != JsonToken.END_ARRAY) { youTubeVideos.add(new YouTubeMetaImpl(parser)); } } } else if (parser.getCurrentToken() == JsonToken.START_OBJECT || parser.getCurrentToken() == JsonToken.START_ARRAY) { parser.skipChildren(); } } // end while }
@SuppressWarnings("unchecked") @Override public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); if (t == JsonToken.VALUE_NUMBER_INT) { return (T) new DateTime(jp.getLongValue(), DateTimeZone.UTC); } if (t == JsonToken.VALUE_STRING) { String str = jp.getText().trim(); if (str.length() == 0) { // [JACKSON-360] return null; } return (T) new DateTime(str, DateTimeZone.UTC); } throw ctxt.mappingException(getValueClass()); }
private final String[] handleNonArray(JsonParser p, DeserializationContext ctxt) throws IOException { // implicit arrays from single values? boolean canWrap = (_unwrapSingle == Boolean.TRUE) || ((_unwrapSingle == null) && ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)); if (canWrap) { return new String[] {p.hasToken(JsonToken.VALUE_NULL) ? null : _parseString(p, ctxt)}; } if (p.hasToken(JsonToken.VALUE_STRING) && ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) { String str = p.getText(); if (str.length() == 0) { return null; } } return (String[]) ctxt.handleUnexpectedToken(_valueClass, p); }
protected final double _testRawDeser(int reps, byte[] json, ObjectReader reader) throws IOException { long start = System.nanoTime(); final JsonFactory f = reader.getFactory(); while (--reps >= 0) { JsonParser p = f.createParser(new ByteArrayInputStream(json)); JsonToken t; while ((t = p.nextToken()) != null) { if (t == JsonToken.VALUE_STRING) { p.getText(); } else if (t.isNumeric()) { p.getNumberValue(); } ; } p.close(); } hash = f.hashCode(); return _msecsFromNanos(System.nanoTime() - start); }
public void testSimpleArrayWrite() throws Exception { StringWriter sw = new StringWriter(); JsonGenerator gen = new JsonFactory().createGenerator(sw); gen.writeStartArray(); gen.writeNumber(13); gen.writeBoolean(true); gen.writeString("foobar"); gen.writeEndArray(); gen.close(); String docStr = sw.toString(); JsonParser jp = createParserUsingReader(docStr); assertEquals(JsonToken.START_ARRAY, jp.nextToken()); assertEquals(JsonToken.VALUE_NUMBER_INT, jp.nextToken()); assertEquals(13, jp.getIntValue()); assertEquals(JsonToken.VALUE_TRUE, jp.nextToken()); assertEquals(JsonToken.VALUE_STRING, jp.nextToken()); assertEquals("foobar", jp.getText()); assertEquals(JsonToken.END_ARRAY, jp.nextToken()); assertEquals(null, jp.nextToken()); jp.close(); }
@Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // couple of accepted types... Object value; if (_inputType == null) { value = jp.getText(); } else if (_inputType == Integer.class) { value = Integer.valueOf(jp.getValueAsInt()); } else if (_inputType == Long.class) { value = Long.valueOf(jp.getValueAsLong()); } else { throw ctxt.mappingException(_enumClass); } try { return _factory.invoke(_enumClass, value); } catch (Exception e) { ClassUtil.unwrapAndThrowAsIAE(e); } return null; }
@Override public JSONArray deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JSONArray array = new JSONArray(); JsonToken t; while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { switch (t) { case START_ARRAY: array.put(deserialize(jp, ctxt)); continue; case START_OBJECT: array.put(JSONObjectDeserializer.instance.deserialize(jp, ctxt)); continue; case VALUE_STRING: array.put(jp.getText()); continue; case VALUE_NULL: array.put(JSONObject.NULL); continue; case VALUE_TRUE: array.put(Boolean.TRUE); continue; case VALUE_FALSE: array.put(Boolean.FALSE); continue; case VALUE_NUMBER_INT: array.put(jp.getNumberValue()); continue; case VALUE_NUMBER_FLOAT: array.put(jp.getNumberValue()); continue; case VALUE_EMBEDDED_OBJECT: array.put(jp.getEmbeddedObject()); continue; } throw ctxt.mappingException("Urecognized or unsupported JsonToken type: " + t); } return array; }
/** * Method that gets textual contents of the current token using available methods, and ensures * results are consistent, before returning them */ protected String getAndVerifyText(JsonParser jp) throws IOException, JsonParseException { // Ok, let's verify other accessors int actLen = jp.getTextLength(); char[] ch = jp.getTextCharacters(); String str2 = new String(ch, jp.getTextOffset(), actLen); String str = jp.getText(); if (str.length() != actLen) { fail( "Internal problem (jp.token == " + jp.getCurrentToken() + "): jp.getText().length() ['" + str + "'] == " + str.length() + "; jp.getTextLength() == " + actLen); } assertEquals("String access via getText(), getTextXxx() must be the same", str, str2); return str; }
@Override public Enum<?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonToken curr = jp.getCurrentToken(); // Usually should just get string value: if (curr == JsonToken.VALUE_STRING || curr == JsonToken.FIELD_NAME) { String name = jp.getText(); Enum<?> result = _resolver.findEnum(name); if (result == null && !ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { throw ctxt.weirdStringException( name, _resolver.getEnumClass(), "value not one of declared Enum instance names"); } return result; } // But let's consider int acceptable as well (if within ordinal range) if (curr == JsonToken.VALUE_NUMBER_INT) { /* ... unless told not to do that. :-) * (as per [JACKSON-412] */ if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) { throw ctxt.mappingException( "Not allowed to deserialize Enum value out of JSON number (disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow)"); } int index = jp.getIntValue(); Enum<?> result = _resolver.getEnum(index); if (result == null && !ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { throw ctxt.weirdNumberException( Integer.valueOf(index), _resolver.getEnumClass(), "index value outside legal index range [0.." + _resolver.lastValidIndex() + "]"); } return result; } throw ctxt.mappingException(_resolver.getEnumClass()); }
protected void verifyFieldName(JsonParser jp, String expName) throws IOException { assertEquals(expName, jp.getText()); assertEquals(expName, jp.getCurrentName()); }
public final void copyCurrentEvent(JsonParser jp) throws IOException, JsonProcessingException { switch (jp.getCurrentToken()) { case START_OBJECT: writeStartObject(); break; case END_OBJECT: writeEndObject(); break; case START_ARRAY: writeStartArray(); break; case END_ARRAY: writeEndArray(); break; case FIELD_NAME: writeFieldName(jp.getCurrentName()); break; case VALUE_STRING: if (jp.hasTextCharacters()) { writeString(jp.getTextCharacters(), jp.getTextOffset(), jp.getTextLength()); } else { writeString(jp.getText()); } break; case VALUE_NUMBER_INT: switch (jp.getNumberType()) { case INT: writeNumber(jp.getIntValue()); break; case BIG_INTEGER: writeNumber(jp.getBigIntegerValue()); break; default: writeNumber(jp.getLongValue()); } break; case VALUE_NUMBER_FLOAT: switch (jp.getNumberType()) { case BIG_DECIMAL: writeNumber(jp.getDecimalValue()); break; case FLOAT: writeNumber(jp.getFloatValue()); break; default: writeNumber(jp.getDoubleValue()); } break; case VALUE_TRUE: writeBoolean(true); break; case VALUE_FALSE: writeBoolean(false); break; case VALUE_NULL: writeNull(); break; case VALUE_EMBEDDED_OBJECT: writeObject(jp.getEmbeddedObject()); break; default: _cantHappen(); } }
@Override public CustomMap deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { CustomMap result = new CustomMap(); result.put("x", jp.getText()); return result; }
private Image readImage(JsonParser parser) throws IOException { boolean haveWidth = false; boolean haveHeight = false; Image image = new Image(); if (parser.nextFieldName(FIELD_URI)) { image.uri = parser.nextTextValue(); if (parser.nextFieldName(FIELD_TITLE)) { image.title = parser.nextTextValue(); if (parser.nextFieldName(FIELD_WIDTH)) { image.width = parser.nextIntValue(-1); haveWidth = true; if (parser.nextFieldName(FIELD_HEIGHT)) { image.height = parser.nextIntValue(-1); haveHeight = true; if (parser.nextFieldName(FIELD_SIZE)) { image.size = Image.Size.valueOf(parser.nextTextValue()); parser.nextToken(); verifyCurrent(parser, JsonToken.END_OBJECT); return image; } } } } } for (; parser.getCurrentToken() == JsonToken.FIELD_NAME; parser.nextToken()) { String field = parser.getCurrentName(); // read value token (or START_ARRAY) parser.nextToken(); Integer I = fullFieldToIndex.get(field); if (I != null) { switch (I) { case FIELD_IX_URI: image.uri = parser.getText(); continue; case FIELD_IX_TITLE: image.title = parser.getText(); continue; case FIELD_IX_WIDTH: image.width = parser.getIntValue(); haveWidth = true; continue; case FIELD_IX_HEIGHT: image.height = parser.getIntValue(); haveHeight = true; continue; case FIELD_IX_SIZE: image.size = Image.Size.valueOf(parser.getText()); continue; } } throw new IllegalStateException("Unexpected field '" + field + "'"); } if (image.uri == null) throw new IllegalStateException("Missing field: " + FIELD_URI); if (!haveWidth) throw new IllegalStateException("Missing field: " + FIELD_WIDTH); if (!haveHeight) throw new IllegalStateException("Missing field: " + FIELD_HEIGHT); if (image.size == null) throw new IllegalStateException("Missing field: " + FIELD_SIZE); verifyCurrent(parser, JsonToken.END_OBJECT); return image; }
@Override public OffsetTime deserialize(JsonParser parser, DeserializationContext context) throws IOException { if (parser.hasToken(JsonToken.VALUE_STRING)) { String string = parser.getText().trim(); if (string.length() == 0) { return null; } try { return OffsetTime.parse(string, _formatter); } catch (DateTimeException e) { _rethrowDateTimeException(parser, context, e, string); } } if (!parser.isExpectedStartArrayToken()) { if (parser.hasToken(JsonToken.VALUE_EMBEDDED_OBJECT)) { return (OffsetTime) parser.getEmbeddedObject(); } throw context.wrongTokenException(parser, JsonToken.START_ARRAY, "Expected array or string."); } int hour = parser.nextIntValue(-1); if (hour == -1) { JsonToken t = parser.getCurrentToken(); if (t == JsonToken.END_ARRAY) { return null; } if (t != JsonToken.VALUE_NUMBER_INT) { _reportWrongToken(parser, context, JsonToken.VALUE_NUMBER_INT, "hours"); } hour = parser.getIntValue(); } int minute = parser.nextIntValue(-1); if (minute == -1) { JsonToken t = parser.getCurrentToken(); if (t == JsonToken.END_ARRAY) { return null; } if (t != JsonToken.VALUE_NUMBER_INT) { _reportWrongToken(parser, context, JsonToken.VALUE_NUMBER_INT, "minutes"); } minute = parser.getIntValue(); } int partialSecond = 0; int second = 0; if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) { second = parser.getIntValue(); if (parser.nextToken() == JsonToken.VALUE_NUMBER_INT) { partialSecond = parser.getIntValue(); if (partialSecond < 1_000 && !context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) { partialSecond *= 1_000_000; // value is milliseconds, convert it to nanoseconds } parser.nextToken(); } } if (parser.getCurrentToken() == JsonToken.VALUE_STRING) { OffsetTime t = OffsetTime.of(hour, minute, second, partialSecond, ZoneOffset.of(parser.getText())); if (parser.nextToken() != JsonToken.END_ARRAY) { _reportWrongToken(parser, context, JsonToken.END_ARRAY, "timezone"); } return t; } throw context.wrongTokenException( parser, JsonToken.VALUE_STRING, "Expected string for TimeZone after numeric values"); }
protected void verifyIntValue(JsonParser jp, long expValue) throws IOException { // First, via textual assertEquals(String.valueOf(expValue), jp.getText()); }