View Javadoc
1   package com.github.davidmoten.aws.lw.client;
2   
3   import java.net.HttpURLConnection;
4   import java.nio.charset.StandardCharsets;
5   import java.time.Instant;
6   import java.time.ZonedDateTime;
7   import java.util.List;
8   import java.util.Locale;
9   import java.util.Map;
10  import java.util.Optional;
11  import java.util.stream.Collectors;
12  
13  import com.github.davidmoten.aws.lw.client.internal.util.Preconditions;
14  
15  public final class Response {
16  
17      private final Map<String, List<String>> headers;
18      private final Map<String, List<String>> headersLowerCaseKey;
19      private final byte[] content;
20      private final int statusCode;
21  
22      public Response(Map<String, List<String>> headers, byte[] content, int statusCode) {
23          this.headers = headers;
24          this.headersLowerCaseKey = lowerCaseKey(headers);
25          this.content = content;
26          this.statusCode = statusCode;
27      }
28  
29      public Map<String, List<String>> headers() {
30          return headers;
31      }
32      
33      public Map<String, List<String>> headersLowerCaseKey() {
34          return headersLowerCaseKey;
35      }
36  
37      public Optional<String> firstHeader(String name) {
38          List<String> h = headersLowerCaseKey.get(lowerCase(name));
39          if (h == null || h.isEmpty()) {
40              return Optional.empty();
41          } else {
42              return Optional.of(h.get(0));
43          }
44      }
45  
46      public Optional<Instant> firstHeaderFullDate(String name) {
47          return firstHeader(name) //
48                  .map(x -> ZonedDateTime.parse(x, Formats.FULL_DATE).toInstant());
49      }
50  
51      /**
52       * Returns those headers that start with {@code x-amz-meta-} (and removes that
53       * prefix).
54       * 
55       * @return headers that start with {@code x-amz-meta-} (and removes that prefix)
56       */
57      public Metadata metadata() {
58          return new Metadata(headersLowerCaseKey //
59                  .entrySet() //
60                  .stream() //
61                  .filter(x -> x.getKey() != null) //
62                  .filter(x -> x.getKey().startsWith("x-amz-meta-")) //
63                  .collect(Collectors.toMap( //
64                          x -> x.getKey().substring(11), //
65                          x -> x.getValue().get(0))));
66      }
67  
68      public Optional<String> metadata(String name) {
69          Preconditions.checkNotNull(name);
70          // value() method does conversion of name to lower case
71          return metadata().value(name);
72      }
73  
74      public byte[] content() {
75          return content;
76      }
77  
78      public String contentUtf8() {
79          return new String(content, StandardCharsets.UTF_8);
80      }
81  
82      public int statusCode() {
83          return statusCode;
84      }
85  
86      public boolean isOk() {
87          return statusCode >= 200 && statusCode <= 299;
88      }
89  
90      /**
91       * Returns true if and only if status code is 2xx. Returns false if status code
92       * is 404 (NOT_FOUND) and throws a {@link ServiceException} otherwise.
93       * 
94       * @return true if status code 2xx, false if 404 otherwise throws
95       *         ServiceException
96       * @throws ServiceException if status code other than 2xx or 404
97       */
98      public boolean exists() {
99          if (statusCode >= 200 && statusCode <= 299) {
100             return true;
101         } else if (statusCode == HttpURLConnection.HTTP_NOT_FOUND) {
102             return false;
103         } else {
104             throw new ServiceException(statusCode, "call failed");
105         }
106     }
107 
108     private static Map<String, List<String>> lowerCaseKey(Map<String, List<String>> m) {
109         return m.entrySet().stream().collect( //
110                 Collectors.toMap( //
111                         entry -> lowerCase(entry.getKey()), //
112                         entry -> entry.getValue()));
113     }
114     
115     private static String lowerCase(String s) {
116         return s == null ? s : s.toLowerCase(Locale.ENGLISH);
117     }
118     
119     // TODO add toString method
120 }