LCOV - code coverage report
Current view: top level - json - OptionalSubmitRequirementExpressionResultAdapterFactory.java (source / functions) Hit Total Coverage
Test: _coverage_report.dat Lines: 29 38 76.3 %
Date: 2022-11-19 15:00:39 Functions: 8 11 72.7 %

          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.gerrit.common.Nullable;
      18             : import com.google.gerrit.entities.SubmitRequirementExpressionResult;
      19             : import com.google.gerrit.entities.SubmitRequirementResult;
      20             : import com.google.gson.Gson;
      21             : import com.google.gson.JsonElement;
      22             : import com.google.gson.JsonParser;
      23             : import com.google.gson.TypeAdapter;
      24             : import com.google.gson.TypeAdapterFactory;
      25             : import com.google.gson.reflect.TypeToken;
      26             : import com.google.gson.stream.JsonReader;
      27             : import com.google.gson.stream.JsonWriter;
      28             : import com.google.inject.TypeLiteral;
      29             : import java.io.IOException;
      30             : import java.util.Optional;
      31             : 
      32             : /**
      33             :  * A {@code TypeAdapterFactory} for Optional {@code SubmitRequirementExpressionResult}.
      34             :  *
      35             :  * <p>{@link SubmitRequirementResult#submittabilityExpressionResult} was previously serialized as a
      36             :  * mandatory field, but was later on migrated to an optional field. The server needs to handle
      37             :  * deserializing of both formats.
      38             :  */
      39         153 : public class OptionalSubmitRequirementExpressionResultAdapterFactory implements TypeAdapterFactory {
      40             : 
      41         153 :   private static final TypeToken<?> OPTIONAL_SR_EXPRESSION_RESULT_TOKEN =
      42         153 :       TypeToken.get(new TypeLiteral<Optional<SubmitRequirementExpressionResult>>() {}.getType());
      43             : 
      44         153 :   private static final TypeToken<?> SR_EXPRESSION_RESULT_TOKEN =
      45         153 :       TypeToken.get(SubmitRequirementExpressionResult.class);
      46             : 
      47             :   @SuppressWarnings({"unchecked"})
      48             :   @Nullable
      49             :   @Override
      50             :   public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
      51          65 :     if (typeToken.equals(OPTIONAL_SR_EXPRESSION_RESULT_TOKEN)) {
      52           3 :       return (TypeAdapter<T>)
      53             :           new OptionalSubmitRequirementExpressionResultTypeAdapter(
      54           3 :               SubmitRequirementExpressionResult.typeAdapter(gson));
      55          65 :     } else if (typeToken.equals(SR_EXPRESSION_RESULT_TOKEN)) {
      56           0 :       return (TypeAdapter<T>)
      57             :           new SubmitRequirementExpressionResultTypeAdapter(
      58           0 :               SubmitRequirementExpressionResult.typeAdapter(gson));
      59             :     }
      60          65 :     return null;
      61             :   }
      62             : 
      63             :   /**
      64             :    * Reads json representation of either {@code Optional<SubmitRequirementExpressionResult>} or
      65             :    * {@code SubmitRequirementExpressionResult}, converting it to {@code Nullable} {@code
      66             :    * SubmitRequirementExpressionResult}.
      67             :    */
      68             :   @Nullable
      69             :   private static SubmitRequirementExpressionResult readOptionalOrMandatory(
      70             :       TypeAdapter<SubmitRequirementExpressionResult> submitRequirementExpressionResultAdapter,
      71             :       JsonReader in) {
      72           3 :     JsonElement parsed = JsonParser.parseReader(in);
      73           3 :     if (parsed == null) {
      74           0 :       return null;
      75             :     }
      76             :     // If it does not have 'value' field, then it was serialized as
      77             :     // SubmitRequirementExpressionResult directly
      78           3 :     if (parsed.getAsJsonObject().has("value")) {
      79           3 :       parsed = parsed.getAsJsonObject().get("value");
      80             :     }
      81           3 :     if (parsed == null || parsed.isJsonNull() || parsed.getAsJsonObject().entrySet().isEmpty()) {
      82           3 :       return null;
      83             :     }
      84           3 :     return submitRequirementExpressionResultAdapter.fromJsonTree(parsed);
      85             :   }
      86             : 
      87             :   /**
      88             :    * A {@code TypeAdapter} that provides backward compatibility for reading previously non-optional
      89             :    * {@code SubmitRequirementExpressionResult} field.
      90             :    */
      91             :   private static class OptionalSubmitRequirementExpressionResultTypeAdapter
      92             :       extends TypeAdapter<Optional<SubmitRequirementExpressionResult>> {
      93             : 
      94             :     private final TypeAdapter<SubmitRequirementExpressionResult>
      95             :         submitRequirementExpressionResultAdapter;
      96             : 
      97             :     public OptionalSubmitRequirementExpressionResultTypeAdapter(
      98           3 :         TypeAdapter<SubmitRequirementExpressionResult> submitRequirementResultAdapter) {
      99           3 :       this.submitRequirementExpressionResultAdapter = submitRequirementResultAdapter;
     100           3 :     }
     101             : 
     102             :     @Override
     103             :     public Optional<SubmitRequirementExpressionResult> read(JsonReader in) throws IOException {
     104           3 :       return Optional.ofNullable(
     105           3 :           readOptionalOrMandatory(submitRequirementExpressionResultAdapter, in));
     106             :     }
     107             : 
     108             :     @Override
     109             :     public void write(JsonWriter out, Optional<SubmitRequirementExpressionResult> value)
     110             :         throws IOException {
     111             :       // Serialize the field using the same format used by the AutoValue's default Gson serializer.
     112           3 :       out.beginObject();
     113           3 :       out.name("value");
     114           3 :       if (value.isPresent()) {
     115           3 :         out.jsonValue(submitRequirementExpressionResultAdapter.toJson(value.get()));
     116             :       } else {
     117           3 :         out.nullValue();
     118             :       }
     119           3 :       out.endObject();
     120           3 :     }
     121             :   }
     122             : 
     123             :   /**
     124             :    * A {@code TypeAdapter} that provides forward compatibility for reading the optional {@code
     125             :    * SubmitRequirementExpressionResult} field.
     126             :    *
     127             :    * <p>TODO(mariasavtchouk): Remove once updated to read the new format only.
     128             :    */
     129             :   private static class SubmitRequirementExpressionResultTypeAdapter
     130             :       extends TypeAdapter<SubmitRequirementExpressionResult> {
     131             : 
     132             :     private final TypeAdapter<SubmitRequirementExpressionResult>
     133             :         submitRequirementExpressionResultAdapter;
     134             : 
     135             :     public SubmitRequirementExpressionResultTypeAdapter(
     136           0 :         TypeAdapter<SubmitRequirementExpressionResult> submitRequirementResultAdapter) {
     137           0 :       this.submitRequirementExpressionResultAdapter = submitRequirementResultAdapter;
     138           0 :     }
     139             : 
     140             :     @Override
     141             :     public SubmitRequirementExpressionResult read(JsonReader in) throws IOException {
     142           0 :       return readOptionalOrMandatory(submitRequirementExpressionResultAdapter, in);
     143             :     }
     144             : 
     145             :     @Override
     146             :     public void write(JsonWriter out, SubmitRequirementExpressionResult value) throws IOException {
     147             :       // Serialize the field using the same format used by the AutoValue's default Gson serializer.
     148           0 :       out.jsonValue(submitRequirementExpressionResultAdapter.toJson(value));
     149           0 :     }
     150             :   }
     151             : }

Generated by: LCOV version 1.16+git.20220603.dfeb750