View Javadoc
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.net.URL;
36  import java.text.ParseException;
37  import java.util.Collection;
38  import java.util.Date;
39  import javax.json.Json;
40  import javax.json.JsonObject;
41  import lombok.EqualsAndHashCode;
42  import lombok.ToString;
43  
44  /**
45   * Github issue comment.
46   *
47   * <p>Comment implements {@link JsonReadable}, that's how you can get its full
48   * details in JSON format. For example, to get its author's Github login
49   * you get the entire JSON and then gets its element:
50   *
51   * <pre>String login = comment.json()
52   *   .getJsonObject("user")
53   *   .getString("login");</pre>
54   *
55   * <p>However, it's better to use a supplementary "smart" decorator, which
56   * automates most of these operations:
57   *
58   * <pre>String login = new Comment.Smart(comment).author().login();</pre>
59   *
60   * @author Yegor Bugayenko (yegor256@gmail.com)
61   * @author Paulo Lobo (pauloeduardolobo@gmail.com)
62   * @version $Id: 9e492078f5c26ef887ad0c8b07cfbc5e573f06e1 $
63   * @since 0.1
64   * @see <a href="https://developer.github.com/v3/issues/comments/">Issue Comments API</a>
65   * @checkstyle MultipleStringLiterals (500 lines)
66   */
67  @Immutable
68  @SuppressWarnings("PMD.TooManyMethods")
69  public interface Comment
70      extends Comparable<Comment>, JsonReadable, JsonPatchable {
71  
72      /**
73       * The issue it's in.
74       * @return Owner of the comment
75       */
76      Issue issue();
77  
78      /**
79       * Number.
80       * @return Comment number
81       */
82      int number();
83  
84      /**
85       * Delete the comment.
86       * @throws IOException If there is any I/O problem
87       * @see <a href="https://developer.github.com/v3/issues/comments/#delete-a-comment">Delete a Comment</a>
88       */
89      void remove() throws IOException;
90  
91      /**
92       * Adds the reaction to the comment.
93       * @param reaction Reaction to be added.
94       * @throws IOException In case something goes wrong.
95       */
96      void react(Reaction reaction) throws IOException;
97  
98      /**
99       * List the reactions of the comment.
100      * @return Comment reactions.
101      */
102     Iterable<Reaction> reactions();
103 
104     /**
105      * Smart comment with additional features.
106      */
107     @Immutable
108     @ToString
109     @Loggable(Loggable.DEBUG)
110     @EqualsAndHashCode(of = { "comment", "jsn" })
111     final class Smart implements Comment {
112         /**
113          * Encapsulated comment.
114          */
115         private final transient Comment comment;
116 
117         /**
118          * SmartJson object for convenient JSON parsing.
119          */
120         private final transient SmartJson jsn;
121 
122         /**
123          * Public ctor.
124          * @param cmt Comment
125          */
126         public Smart(final Comment cmt) {
127             this.comment = cmt;
128             this.jsn = new SmartJson(cmt);
129         }
130         /**
131          * Get its author.
132          * @return Author of comment
133          * @throws IOException If there is any I/O problem
134          */
135         public User author() throws IOException {
136             return this.comment.issue().repo().github().users().get(
137                 this.comment.json().getJsonObject("user").getString("login")
138             );
139         }
140         /**
141          * Get its body.
142          * @return Body of comment
143          * @throws IOException If there is any I/O problem
144          */
145         public String body() throws IOException {
146             return this.jsn.text("body");
147         }
148         /**
149          * Change comment body.
150          * @param text Body of comment
151          * @throws IOException If there is any I/O problem
152          */
153         public void body(final String text) throws IOException {
154             this.comment.patch(
155                 Json.createObjectBuilder().add("body", text).build()
156             );
157         }
158         /**
159          * Get its URL.
160          * @return URL of comment
161          * @throws IOException If there is any I/O problem
162          */
163         public URL url() throws IOException {
164             return new URL(this.jsn.text("url"));
165         }
166         /**
167          * When this comment was created.
168          * @return Date of creation
169          * @throws IOException If there is any I/O problem
170          */
171         public Date createdAt() throws IOException {
172             try {
173                 return new Github.Time(
174                     this.jsn.text("created_at")
175                 ).date();
176             } catch (final ParseException ex) {
177                 throw new IOException(ex);
178             }
179         }
180         /**
181          * When this comment was updated last time.
182          * @return Date of update
183          * @throws IOException If there is any I/O problem
184          */
185         public Date updatedAt() throws IOException {
186             try {
187                 return new Github.Time(
188                     this.jsn.text("updated_at")
189                 ).date();
190             } catch (final ParseException ex) {
191                 throw new IOException(ex);
192             }
193         }
194         @Override
195         public Issue issue() {
196             return this.comment.issue();
197         }
198         @Override
199         public int number() {
200             return this.comment.number();
201         }
202         @Override
203         public void remove() throws IOException {
204             this.comment.remove();
205         }
206 
207         @Override
208         public void react(final Reaction reaction) {
209             throw new UnsupportedOperationException("react() not implemented");
210         }
211 
212         @Override
213         public Collection<Reaction> reactions() {
214             throw new UnsupportedOperationException(
215                 "reactions() not implemented"
216             );
217         }
218 
219         @Override
220         public JsonObject json() throws IOException {
221             return this.comment.json();
222         }
223         @Override
224         public void patch(final JsonObject json) throws IOException {
225             this.comment.patch(json);
226         }
227         @Override
228         public int compareTo(final Comment obj) {
229             return this.comment.compareTo(obj);
230         }
231     }
232 
233 }