001/*
002 * Copyright (c) 2011-2018 Nexmo Inc
003 *
004 * Permission is hereby granted, free of charge, to any person obtaining a copy
005 * of this software and associated documentation files (the "Software"), to deal
006 * in the Software without restriction, including without limitation the rights
007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008 * copies of the Software, and to permit persons to whom the Software is
009 * furnished to do so, subject to the following conditions:
010 *
011 * The above copyright notice and this permission notice shall be included in
012 * all copies or substantial portions of the Software.
013 *
014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
020 * THE SOFTWARE.
021 */
022package com.nexmo.client.verify;
023
024import com.fasterxml.jackson.core.JsonParser;
025import com.fasterxml.jackson.databind.DeserializationContext;
026import com.fasterxml.jackson.databind.JsonDeserializer;
027import com.fasterxml.jackson.databind.JsonNode;
028import com.fasterxml.jackson.databind.ObjectMapper;
029
030import java.io.IOException;
031import java.text.SimpleDateFormat;
032import java.util.Collections;
033
034public class SearchVerifyResponseDeserializer extends JsonDeserializer<SearchVerifyResponse> {
035    @Override
036    public SearchVerifyResponse deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
037        JsonNode node = p.getCodec().readTree(p);
038        // TODO: Restructure objects to handle this better.
039        // Deserialization is a little complicated here.  There are a few things to consider:
040        // (1) A search request with a single result comes back with that single result as json.
041        // (2) A search request with multiple results comes back with those results as an array in the
042        //     verification_requests property.
043        // (3) A search request which comes back in error has different Status values than search requests
044        //     that come back without error. (See VerifyStatus vs VerifyDetails.Status)
045
046        // If the results has a verification_requests node then we can successfully map our object as normal.
047        if (node.has("verification_requests")) {
048            // Have to create a second object mapper to handle this as we want to bypass custom deserialization.
049            ObjectMapper mapper = new ObjectMapper();
050            mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
051            return mapper.readValue(node.toString(), SearchVerifyResponse.class);
052        }
053
054        // If the result has error_text, we can assume that the only fields that matter are status and the error.
055        if (node.has("error_text")) {
056            return new SearchVerifyResponse(VerifyStatus.fromInt(node.get("status").asInt()),
057                                            node.get("error_text").asText());
058        }
059        // Otherwise we need to map the single result and then put it on the list as is.
060        VerifyDetails details = p.getCodec().treeToValue(node, VerifyDetails.class);
061        return new SearchVerifyResponse(Collections.singletonList(details));
062    }
063}