/** Actual implementation of value reading+binding operation. */ protected Object _bind(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { /* First: may need to read the next token, to initialize state (either * before first read from parser, or after previous token has been cleared) */ Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { if (_valueToUpdate == null) { result = _findRootDeserializer(_config, _valueType).getNullValue(); } else { result = _valueToUpdate; } } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = _valueToUpdate; } else { // pointing to event other than null DeserializationContext ctxt = _createDeserializationContext(jp, _config); JsonDeserializer<Object> deser = _findRootDeserializer(_config, _valueType); if (_unwrapRoot) { result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser); } else { if (_valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, _valueToUpdate); result = _valueToUpdate; } } } // Need to consume the token too jp.clearCurrentToken(); return result; }
protected Object _unwrapAndDeserialize( JsonParser jp, DeserializationContext ctxt, JavaType rootType, JsonDeserializer<Object> deser) throws IOException, JsonParseException, JsonMappingException { SerializedString rootName = _provider.findExpectedRootName(ctxt.getConfig(), rootType); if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw JsonMappingException.from( jp, "Current token not START_OBJECT (needed to unwrap root name '" + rootName + "'), but " + jp.getCurrentToken()); } if (jp.nextToken() != JsonToken.FIELD_NAME) { throw JsonMappingException.from( jp, "Current token not FIELD_NAME (to contain expected root name '" + rootName + "'), but " + jp.getCurrentToken()); } String actualName = jp.getCurrentName(); if (!rootName.getValue().equals(actualName)) { throw JsonMappingException.from( jp, "Root name '" + actualName + "' does not match expected ('" + rootName + "') for type " + rootType); } // ok, then move to value itself.... jp.nextToken(); Object result; if (_valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, _valueToUpdate); result = _valueToUpdate; } // and last, verify that we now get matching END_OBJECT if (jp.nextToken() != JsonToken.END_OBJECT) { throw JsonMappingException.from( jp, "Current token not END_OBJECT (to match wrapper object with root name '" + rootName + "'), but " + jp.getCurrentToken()); } return result; }
/** 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() + ")"); }
protected JsonNode _bindAsTree(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { JsonNode result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL || t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = NullNode.instance; } else { DeserializationContext ctxt = _createDeserializationContext(jp, _config); JsonDeserializer<Object> deser = _findRootDeserializer(_config, JSON_NODE_TYPE); if (_unwrapRoot) { result = (JsonNode) _unwrapAndDeserialize(jp, ctxt, JSON_NODE_TYPE, deser); } else { result = (JsonNode) deser.deserialize(jp, ctxt); } } // Need to consume the token too jp.clearCurrentToken(); return result; }
protected Object _bindAndClose(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { if (_schema != null) { jp.setSchema(_schema); } try { Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { if (_valueToUpdate == null) { result = _findRootDeserializer(_config, _valueType).getNullValue(); } else { result = _valueToUpdate; } } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = _valueToUpdate; } else { DeserializationContext ctxt = _createDeserializationContext(jp, _config); JsonDeserializer<Object> deser = _findRootDeserializer(_config, _valueType); if (_unwrapRoot) { result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser); } else { if (_valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, _valueToUpdate); result = _valueToUpdate; } } } return result; } finally { try { jp.close(); } catch (IOException ioe) { } } }