1   /*
2    * Copyright 2018 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package com.linecorp.centraldogma.common;
18  
19  import com.fasterxml.jackson.core.JsonParseException;
20  import com.fasterxml.jackson.core.JsonProcessingException;
21  import com.fasterxml.jackson.core.TreeNode;
22  import com.fasterxml.jackson.databind.JsonMappingException;
23  import com.fasterxml.jackson.databind.JsonNode;
24  
25  import com.linecorp.centraldogma.internal.Jackson;
26  
27  /**
28   * A holder which has the content and its {@link EntryType}.
29   *
30   * @param <T> the type of the content
31   */
32  public interface ContentHolder<T> {
33  
34      /**
35       * Returns the {@link EntryType} of the content.
36       */
37      EntryType type();
38  
39      /**
40       * Returns the content.
41       *
42       * @throws IllegalStateException if the content is {@code null}
43       */
44      T content();
45  
46      /**
47       * Returns the textual representation of the specified content.
48       *
49       * @throws IllegalStateException if the content is {@code null}
50       */
51      default String contentAsText() {
52          final T content = content();
53          if (content instanceof JsonNode) {
54              try {
55                  return Jackson.writeValueAsString(content);
56              } catch (JsonProcessingException e) {
57                  // Should never happen because it's a JSON tree already.
58                  throw new Error(e);
59              }
60          } else {
61              return content.toString();
62          }
63      }
64  
65      /**
66       * Returns the prettified textual representation of the specified content. Only a {@link TreeNode} is
67       * prettified currently.
68       *
69       * @throws IllegalStateException if the content is {@code null}
70       */
71      default String contentAsPrettyText() {
72          final T content = content();
73          if (content instanceof TreeNode) {
74              try {
75                  return Jackson.writeValueAsPrettyString(content);
76              } catch (JsonProcessingException e) {
77                  // Should never happen because it's a JSON tree already.
78                  throw new Error(e);
79              }
80          } else {
81              return content.toString();
82          }
83      }
84  
85      /**
86       * Returns the JSON representation of the specified content.
87       *
88       * @return the {@link JsonNode} parsed from the content
89       *
90       * @throws IllegalStateException if the content is {@code null}
91       * @throws JsonParseException if failed to parse the content as JSON
92       */
93      default JsonNode contentAsJson() throws JsonParseException {
94          final T content = content();
95          if (content instanceof JsonNode) {
96              return (JsonNode) content;
97          }
98  
99          return Jackson.readTree(contentAsText());
100     }
101 
102     /**
103      * Returns the value converted from the JSON representation of the specified content.
104      *
105      * @return the value converted from the content
106      *
107      * @throws IllegalStateException if the content is {@code null}
108      * @throws JsonParseException if failed to parse the content as JSON
109      * @throws JsonMappingException if failed to convert the parsed JSON into {@code valueType}
110      */
111     default <U> U contentAsJson(Class<U> valueType) throws JsonParseException, JsonMappingException {
112         final T content = content();
113         if (content instanceof TreeNode) {
114             return Jackson.treeToValue((TreeNode) content, valueType);
115         }
116 
117         return Jackson.readValue(contentAsText(), valueType);
118     }
119 }