Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package software.amazon.awssdk.protocols.json.internal.unmarshall;
import static software.amazon.awssdk.utils.FunctionalUtils.invokeSafely;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.SdkField;
import software.amazon.awssdk.core.SdkPojo;
import software.amazon.awssdk.core.document.Document;
import software.amazon.awssdk.core.protocol.MarshallLocation;
import software.amazon.awssdk.core.protocol.MarshallingKnownType;
import software.amazon.awssdk.core.protocol.MarshallingType;
import software.amazon.awssdk.core.traits.ListTrait;
import software.amazon.awssdk.core.traits.MapTrait;
import software.amazon.awssdk.core.traits.TimestampFormatTrait;
import software.amazon.awssdk.core.traits.TraitType;
import software.amazon.awssdk.protocols.jsoncore.JsonNodeParser;
import software.amazon.awssdk.protocols.jsoncore.JsonValueNodeFactory;
import software.amazon.awssdk.thirdparty.jackson.core.JsonFactory;
import software.amazon.awssdk.thirdparty.jackson.core.JsonParseException;
import software.amazon.awssdk.thirdparty.jackson.core.JsonParser;
import software.amazon.awssdk.thirdparty.jackson.core.JsonToken;
import software.amazon.awssdk.utils.BinaryUtils;
import software.amazon.awssdk.utils.builder.Buildable;
/**
* Parses and unmarshalls an JSON document.
*/
@SdkInternalApi
@ThreadSafe
@SuppressWarnings("unchecked")
final class JsonUnmarshallingParser {
private final JsonFactory jsonFactory;
private final JsonValueNodeFactory jsonValueNodeFactory;
private final JsonUnmarshallerRegistry unmarshallerRegistry;
private final TimestampFormatTrait.Format defaultFormat;
private JsonUnmarshallingParser(Builder builder) {
this.jsonFactory = builder.jsonFactory;
this.jsonValueNodeFactory = builder.jsonValueNodeFactory;
this.unmarshallerRegistry = builder.unmarshallerRegistry;
this.defaultFormat = builder.defaultFormat;
}
/**
* Create a parser using custom configuration.
*/
public static Builder builder() {
return new Builder();
}
/**
* Parse the provided {@link InputStream} and return the deserialized {@link SdkPojo}. Unlike
* {@link #parse(SdkPojo, InputStream)} this method returns null if the input stream is empty. This is used to unmarshall
* payload members that can be null unlike top-level response pojos.
*/
public SdkPojo parseMember(Supplier constructor, InputStream content) {
return invokeSafely(() -> {
try (JsonParser parser = jsonFactory.createParser(content)
.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false)) {
JsonUnmarshallerContext c = JsonUnmarshallerContext.builder().build();
JsonToken token = parser.nextToken();
if (token == null) {
return null;
}
if (token == JsonToken.VALUE_NULL) {
return null;
}
if (token != JsonToken.START_OBJECT) {
throw new JsonParseException("expecting start object, got instead: " + token);
}
SdkPojo pojo = constructor.get();
return parseSdkPojo(c, pojo, parser);
}
});
}
/**
* Parse the provided {@link InputStream} and return the deserialized {@link SdkPojo}.
*/
public SdkPojo parse(SdkPojo pojo, InputStream content) {
return invokeSafely(() -> {
try (JsonParser parser = jsonFactory.createParser(content)
.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false)) {
JsonUnmarshallerContext c = JsonUnmarshallerContext.builder().build();
JsonToken token = parser.nextToken();
if (token == null) {
return (SdkPojo) ((Buildable) pojo).build();
}
if (token == JsonToken.VALUE_NULL) {
return null;
}
if (token != JsonToken.START_OBJECT) {
throw new JsonParseException("expecting start object, got instead: " + token);
}
return parseSdkPojo(c, pojo, parser);
}
});
}
/**
* Parses an sdk pojo and fills its fields. The given SdkPojo instance is expected to be a {@link Buildable} instance. This
* method expects that the START_OBJECT token has been already consumed, so the next token should be either a field name or an
* END_OBJECT.
*/
private SdkPojo parseSdkPojo(JsonUnmarshallerContext c, SdkPojo pojo, JsonParser parser) throws IOException {
Map> pojoFields = pojo.sdkFieldNameToField();
JsonToken currentToken = parser.nextToken();
while (currentToken != JsonToken.END_OBJECT) {
String fieldName = parser.getText();
SdkField> pojoField = pojoFields.get(fieldName);
// if the name of the field is unknown or the field is expected in a non-payload location (e.g., header), we ignore
// its value here.
if (pojoField == null || !isPayloadUnmarshalling(pojoField.location())) {
skipValue(parser, null);
currentToken = parser.nextToken();
continue;
}
currentToken = parser.nextToken();
Object valueFor = valueFor(pojoField, c, pojoField.marshallingType(), parser, currentToken);
pojoField.set(pojo, valueFor);
currentToken = parser.nextToken();
}
return (SdkPojo) ((Buildable) pojo).build();
}
/**
* Returns true if the given location is considered as in the payload for unmarshalling. Those include
*
*
{@link MarshallLocation#PAYLOAD}
*
{@link MarshallLocation#PATH}
*
{@link MarshallLocation#QUERY_PARAM}
*
{@link MarshallLocation#GREEDY_PATH}
*
*/
private boolean isPayloadUnmarshalling(MarshallLocation location) {
switch (location) {
case PAYLOAD:
case PATH:
case QUERY_PARAM:
case GREEDY_PATH:
return true;
default:
return false;
}
}
/**
* Parses a list of the field member field info. This method expects that the BEGIN_ARRAY token has been already consumed.
*/
private List