001/* 002 * Copyright 2020 Vonage 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.vonage.client.verify; 017 018import com.fasterxml.jackson.core.JsonParser; 019import com.fasterxml.jackson.databind.DeserializationContext; 020import com.fasterxml.jackson.databind.JsonDeserializer; 021import com.fasterxml.jackson.databind.JsonNode; 022import com.fasterxml.jackson.databind.ObjectMapper; 023 024import java.io.IOException; 025import java.text.SimpleDateFormat; 026import java.util.Collections; 027 028public class SearchVerifyResponseDeserializer extends JsonDeserializer<SearchVerifyResponse> { 029 @Override 030 public SearchVerifyResponse deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { 031 JsonNode node = p.getCodec().readTree(p); 032 // TODO: Restructure objects to handle this better. 033 // Deserialization is a little complicated here. There are a few things to consider: 034 // (1) A search request with a single result comes back with that single result as json. 035 // (2) A search request with multiple results comes back with those results as an array in the 036 // verification_requests property. 037 // (3) A search request which comes back in error has different Status values than search requests 038 // that come back without error. (See VerifyStatus vs VerifyDetails.Status) 039 040 // If the results has a verification_requests node then we can successfully map our object as normal. 041 if (node.has("verification_requests")) { 042 // Have to create a second object mapper to handle this as we want to bypass custom deserialization. 043 ObjectMapper mapper = new ObjectMapper(); 044 mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); 045 return mapper.readValue(node.toString(), SearchVerifyResponse.class); 046 } 047 048 // If the result has error_text, we can assume that the only fields that matter are status and the error. 049 if (node.has("error_text")) { 050 return new SearchVerifyResponse(VerifyStatus.fromInt(node.get("status").asInt()), 051 node.get("error_text").asText()); 052 } 053 // Otherwise we need to map the single result and then put it on the list as is. 054 VerifyDetails details = p.getCodec().treeToValue(node, VerifyDetails.class); 055 return new SearchVerifyResponse(Collections.singletonList(details)); 056 } 057}