View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2013-2025 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.jcabi.github;
6   
7   import com.jcabi.aspects.Immutable;
8   import com.jcabi.aspects.Loggable;
9   import jakarta.json.JsonNumber;
10  import jakarta.json.JsonObject;
11  import jakarta.json.JsonString;
12  import jakarta.json.JsonValue;
13  import java.io.IOException;
14  import lombok.EqualsAndHashCode;
15  import lombok.ToString;
16  
17  /**
18   * Smart JSON (supplementary help class).
19   * @since 0.5
20   */
21  @Immutable
22  @ToString
23  @Loggable(Loggable.DEBUG)
24  @EqualsAndHashCode(of = "object")
25  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
26  final class SmartJson {
27  
28      /**
29       * Encapsulated JSON object.
30       */
31      private final transient JsonReadable object;
32  
33      /**
34       * Public ctor.
35       * @param obj Readable object
36       */
37      SmartJson(final JsonReadable obj) {
38          this.object = obj;
39      }
40  
41      /**
42       * Get its property as string.
43       * @param name Name of the property
44       * @return Value
45       * @throws IOException If there is any I/O problem
46       */
47      public String text(
48          final String name
49      ) throws IOException {
50          return this.value(name, JsonString.class).getString();
51      }
52  
53      /**
54       * Get its property as number.
55       * @param name Name of the property
56       * @return Value
57       * @throws IOException If there is any I/O problem
58       */
59      public int number(
60          final String name
61      ) throws IOException {
62          return this.value(name, JsonNumber.class).intValue();
63      }
64  
65      /**
66       * Get JSON.
67       * @return JSON
68       * @throws IOException If there is any I/O problem
69       * @since 0.14
70       */
71      public JsonObject json() throws IOException {
72          return this.object.json();
73      }
74  
75      /**
76       * Get its property as custom type.
77       * @param name Name of the property
78       * @param type Type of result expected
79       * @param <T> Type expected
80       * @return Value
81       * @throws IOException If there is any I/O problem
82       */
83      public <T> T value(
84          final String name,
85          final Class<T> type
86      ) throws IOException {
87          final JsonObject json = this.json();
88          if (!json.containsKey(name)) {
89              throw new IllegalStateException(
90                  String.format(
91                      "'%s' is absent in JSON: %s", name, json
92                  )
93              );
94          }
95          final JsonValue value = json.get(name);
96          if (value == null) {
97              throw new IllegalStateException(
98                  String.format(
99                      "'%s' is NULL in %s", name, json
100                 )
101             );
102         }
103         if (value.getClass().isAssignableFrom(type)) {
104             throw new IllegalStateException(
105                 String.format(
106                     "'%s' is not of type %s", name, type
107                 )
108             );
109         }
110         return type.cast(value);
111     }
112 
113     /**
114      * Checks if a certain key is present
115      *  AND its ValueType isn't ValueType.NULL.
116      * @param name Name of the key which ValueType should be checked.
117      * @return Returns <code>true</code> if key <code>name</code> is present
118      *  and its ValueType isn't ValueType.NULL, <code>false</code> otherwise.
119      * @throws IOException If there is any I/O problem
120      */
121     public boolean hasNotNull(
122         final String name
123     ) throws IOException {
124         final JsonValue value = this.object.json().get(name);
125         return value != null
126             && !JsonValue.ValueType.NULL.equals(value.getValueType());
127     }
128 }