• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google LLC nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package com.google.api.gax.httpjson;
31 
32 import com.google.protobuf.Message;
33 import com.google.protobuf.TypeRegistry;
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.io.InputStreamReader;
37 import java.io.Reader;
38 import java.nio.charset.StandardCharsets;
39 
40 /** The implementation of {@link HttpResponseParser} which works with protobuf messages. */
41 public class ProtoMessageResponseParser<ResponseT extends Message>
42     implements HttpResponseParser<ResponseT> {
43 
44   private final ResponseT defaultInstance;
45   private final TypeRegistry defaultRegistry;
46 
ProtoMessageResponseParser(ResponseT defaultInstance, TypeRegistry defaultRegistry)47   private ProtoMessageResponseParser(ResponseT defaultInstance, TypeRegistry defaultRegistry) {
48     this.defaultInstance = defaultInstance;
49     this.defaultRegistry = defaultRegistry;
50   }
51 
52   public static <ResponseT extends Message>
newBuilder()53       ProtoMessageResponseParser.Builder<ResponseT> newBuilder() {
54     return new ProtoMessageResponseParser.Builder<ResponseT>()
55         .setDefaultTypeRegistry(TypeRegistry.getEmptyTypeRegistry());
56   }
57 
58   /* {@inheritDoc} */
59   @Override
parse(InputStream httpContent)60   public ResponseT parse(InputStream httpContent) {
61     return parse(httpContent, defaultRegistry);
62   }
63 
64   @Override
parse(InputStream httpContent, TypeRegistry registry)65   public ResponseT parse(InputStream httpContent, TypeRegistry registry) {
66     try (Reader json = new InputStreamReader(httpContent, StandardCharsets.UTF_8)) {
67       return parse(json, registry);
68     } catch (IOException e) {
69       throw new RestSerializationException("Failed to parse response message", e);
70     }
71   }
72 
73   @Override
parse(Reader httpContent, TypeRegistry registry)74   public ResponseT parse(Reader httpContent, TypeRegistry registry) {
75     return ProtoRestSerializer.<ResponseT>create(registry)
76         .fromJson(httpContent, defaultInstance.newBuilderForType());
77   }
78 
79   /* {@inheritDoc} */
80   @Override
serialize(ResponseT response)81   public String serialize(ResponseT response) {
82     return ProtoRestSerializer.create(defaultRegistry).toJson(response, false);
83   }
84 
85   // Convert to @AutoValue if this class gets more complicated
86   public static class Builder<ResponseT extends Message> {
87     private ResponseT defaultInstance;
88     private TypeRegistry defaultRegistry;
89 
setDefaultInstance(ResponseT defaultInstance)90     public Builder<ResponseT> setDefaultInstance(ResponseT defaultInstance) {
91       this.defaultInstance = defaultInstance;
92       return this;
93     }
94 
setDefaultTypeRegistry(TypeRegistry defaultRegistry)95     public Builder<ResponseT> setDefaultTypeRegistry(TypeRegistry defaultRegistry) {
96       this.defaultRegistry = defaultRegistry;
97       return this;
98     }
99 
build()100     public ProtoMessageResponseParser<ResponseT> build() {
101       return new ProtoMessageResponseParser<>(defaultInstance, defaultRegistry);
102     }
103   }
104 }
105