1 /**
2 * Copyright (c) 2013-2023, jcabi.com
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met: 1) Redistributions of source code must retain the above
8 * copyright notice, this list of conditions and the following
9 * disclaimer. 2) Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution. 3) Neither the name of the jcabi.com nor
13 * the names of its contributors may be used to endorse or promote
14 * products derived from this software without specific prior written
15 * permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package com.jcabi.github;
31
32 import com.jcabi.aspects.Immutable;
33 import com.jcabi.aspects.Loggable;
34 import java.io.IOException;
35 import java.util.Collection;
36 import javax.json.Json;
37 import javax.json.JsonObject;
38 import lombok.EqualsAndHashCode;
39 import lombok.ToString;
40
41 /**
42 * Github pull comment.
43 *
44 * <p>PullComment implements {@link JsonReadable},
45 * that's how you can get its full details in JSON format.
46 * For example, to get its id, you get the entire JSON and
47 * then gets its element:
48 *
49 * <pre>String id = comment.jsn().getString("id");</pre>
50 *
51 * <p>However, it's better to use a supplementary "smart" decorator, which
52 * automates most of these operations:
53 *
54 * <pre>String id = new PullComment.Smart(comment).identifier();</pre>
55 *
56 * @author Carlos Miranda (miranda.cma@gmail.com)
57 * @version $Id: 3a512fdda8d32f0c5f095683997f2bc6fb7a813f $
58 * @since 0.8
59 * @see <a href="https://developer.github.com/v3/pulls/comments/">Pull Comments API</a>
60 */
61 @Immutable
62 @SuppressWarnings("PMD.TooManyMethods")
63 public interface PullComment extends JsonReadable, JsonPatchable,
64 Comparable<PullComment> {
65
66 /**
67 * Pull we're in.
68 * @return Pull
69 */
70 Pull pull();
71
72 /**
73 * Get its number.
74 * @return Pull comment number
75 */
76 int number();
77
78 /**
79 * Adds the reaction to the pull comment.
80 * @param reaction Reaction to be added.
81 */
82 void react(Reaction reaction);
83
84 /**
85 * List the reactions of the pull comment.
86 * @return Comment reactions.
87 */
88 Collection<Reaction> reactions();
89
90 /**
91 * Smart PullComment with extra features.
92 */
93 @Immutable
94 @ToString
95 @Loggable(Loggable.DEBUG)
96 @EqualsAndHashCode(of = { "cmnt", "jsn" })
97 final class Smart implements PullComment {
98
99 /**
100 * Id field's name in JSON.
101 */
102 private static final String ID = "id";
103
104 /**
105 * Commit id field's name in JSON.
106 */
107 private static final String COMMIT_ID = "commit_id";
108
109 /**
110 * Url field's name in JSON.
111 */
112 private static final String URL = "url";
113
114 /**
115 * Body field's name in JSON.
116 */
117 private static final String BODY = "body";
118
119 /**
120 * Encapsulated pull comment.
121 */
122 private final transient PullComment cmnt;
123
124 /**
125 * SmartJson object for convenient JSON parsing.
126 */
127 private final transient SmartJson jsn;
128
129 /**
130 * Public ctor.
131 * @param pcomment Pull comment
132 */
133 public Smart(
134 final PullComment pcomment
135 ) {
136 this.cmnt = pcomment;
137 this.jsn = new SmartJson(pcomment);
138 }
139
140 /**
141 * Get its id value.
142 * @return Id of pull comment
143 * @throws IOException If there is any I/O problem
144 */
145 public String identifier() throws IOException {
146 return this.jsn.text(ID);
147 }
148
149 /**
150 * Change its id value.
151 * @param value Id of pull comment
152 * @throws IOException If there is any I/O problem
153 */
154 public void identifier(
155 final String value
156 ) throws IOException {
157 this.cmnt.patch(
158 Json.createObjectBuilder().add(ID, value).build()
159 );
160 }
161
162 /**
163 * Get its commit id value.
164 * @return Commit id of pull comment
165 * @throws IOException If there is any I/O problem
166 */
167 public String commitId() throws IOException {
168 return this.jsn.text(COMMIT_ID);
169 }
170
171 /**
172 * Change its commit id value.
173 * @param value Commit id of pull comment
174 * @throws IOException If there is any I/O problem
175 */
176 public void commitId(
177 final String value
178 ) throws IOException {
179 this.cmnt.patch(
180 Json.createObjectBuilder().add(COMMIT_ID, value).build()
181 );
182 }
183
184 /**
185 * Get its url value.
186 * @return Url of pull comment
187 * @throws IOException If there is any I/O problem
188 */
189 public String url() throws IOException {
190 return this.jsn.text(URL);
191 }
192
193 /**
194 * Get its reply id value.
195 * @return Reply id of pull comment
196 * @throws IOException If there is any I/O problem
197 */
198 public int reply() throws IOException {
199 return this.jsn.number("in_reply_to");
200 }
201
202 /**
203 * Change its url value.
204 * @param value Url of pull comment
205 * @throws IOException If there is any I/O problem
206 */
207 public void url(
208 final String value
209 ) throws IOException {
210 this.cmnt.patch(
211 Json.createObjectBuilder().add(URL, value).build()
212 );
213 }
214
215 /**
216 * Get its body value.
217 * @return Url of pull comment
218 * @throws IOException If there is any I/O problem
219 */
220 public String body() throws IOException {
221 return this.jsn.text(BODY);
222 }
223
224 /**
225 * Change its body value.
226 * @param value Url of pull comment
227 * @throws IOException If there is any I/O problem
228 */
229 public void body(
230 final String value
231 ) throws IOException {
232 this.cmnt.patch(
233 Json.createObjectBuilder().add(BODY, value).build()
234 );
235 }
236
237 @Override
238 public Pull pull() {
239 return this.cmnt.pull();
240 }
241
242 @Override
243 public int number() {
244 return this.cmnt.number();
245 }
246
247 @Override
248 public void react(final Reaction reaction) {
249 throw new UnsupportedOperationException("React not implemented");
250 }
251
252 @Override
253 public Collection<Reaction> reactions() {
254 throw new UnsupportedOperationException(
255 "reactions() not implemented"
256 );
257 }
258
259 @Override
260 public int compareTo(
261 final PullComment comment
262 ) {
263 return this.cmnt.compareTo(comment);
264 }
265
266 @Override
267 public void patch(
268 final JsonObject json
269 ) throws IOException {
270 this.cmnt.patch(json);
271 }
272
273 @Override
274 public JsonObject json() throws IOException {
275 return this.cmnt.json();
276 }
277
278 /**
279 * Get its author.
280 * @return Pull comment author
281 * @throws IOException If there is any I/O problem
282 */
283 public String author() throws IOException {
284 return this.json().getJsonObject("user")
285 .getString("login");
286 }
287 }
288 }