Line data Source code
1 : // Copyright (C) 2022 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.json; 16 : 17 : import com.google.gson.JsonDeserializationContext; 18 : import com.google.gson.JsonDeserializer; 19 : import com.google.gson.JsonElement; 20 : import com.google.gson.JsonNull; 21 : import com.google.gson.JsonObject; 22 : import com.google.gson.JsonParseException; 23 : import com.google.gson.JsonSerializationContext; 24 : import com.google.gson.JsonSerializer; 25 : import com.google.inject.TypeLiteral; 26 : import java.lang.reflect.ParameterizedType; 27 : import java.lang.reflect.Type; 28 : import java.util.Optional; 29 : 30 153 : public class OptionalTypeAdapter 31 : implements JsonSerializer<Optional<?>>, JsonDeserializer<Optional<?>> { 32 : 33 : private static final String VALUE = "value"; 34 : 35 : @Override 36 : public JsonElement serialize(Optional<?> src, Type typeOfSrc, JsonSerializationContext context) { 37 4 : Optional<?> optional = src == null ? Optional.empty() : src; 38 4 : JsonObject json = new JsonObject(); 39 4 : json.add(VALUE, optional.map(context::serialize).orElse(JsonNull.INSTANCE)); 40 4 : return json; 41 : } 42 : 43 : @Override 44 : public Optional<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 45 : throws JsonParseException { 46 4 : if (!json.getAsJsonObject().has(VALUE)) { 47 3 : return Optional.empty(); 48 : } 49 : 50 4 : JsonElement value = json.getAsJsonObject().get(VALUE); 51 4 : if (value == null || value.isJsonNull()) { 52 3 : return Optional.empty(); 53 : } 54 : 55 : // handle the situation when one uses Optional without type parameter which is an equivalent of 56 : // <?> type 57 2 : ParameterizedType parameterizedType = 58 2 : (ParameterizedType) new TypeLiteral<Optional<?>>() {}.getType(); 59 2 : if (typeOfT instanceof ParameterizedType) { 60 2 : parameterizedType = (ParameterizedType) typeOfT; 61 2 : if (parameterizedType.getActualTypeArguments().length != 1) { 62 0 : throw new JsonParseException("Expected one parameter type in Optional."); 63 : } 64 : } 65 : 66 2 : Type optionalOf = parameterizedType.getActualTypeArguments()[0]; 67 2 : return Optional.of(context.deserialize(value, optionalOf)); 68 : } 69 : }