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.google.common.base.Optional;
33  import com.jcabi.aspects.Immutable;
34  import com.jcabi.aspects.Loggable;
35  import java.io.IOException;
36  import java.net.URL;
37  import java.text.ParseException;
38  import java.util.Date;
39  import javax.json.JsonObject;
40  import lombok.EqualsAndHashCode;
41  import lombok.ToString;
42  
43  /**
44   * Github event.
45   *
46   * @author Yegor Bugayenko (yegor256@gmail.com)
47   * @version $Id: f031f9ed5089bcb39e3999c75ae9db2301f6e10f $
48   * @since 0.4
49   * @see <a href="https://developer.github.com/v3/issues/events/">Issue Events API</a>
50   * @checkstyle MultipleStringLiterals (500 lines)
51   */
52  @Immutable
53  @SuppressWarnings("PMD.TooManyMethods")
54  public interface Event extends Comparable<Event>, JsonReadable {
55  
56      /**
57       * Event type.
58       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
59       */
60      String CLOSED = "closed";
61  
62      /**
63       * Event type.
64       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
65       */
66      String REOPENED = "reopened";
67  
68      /**
69       * Event type.
70       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
71       */
72      String SUBSCRIBED = "subscribed";
73  
74      /**
75       * Event type.
76       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
77       */
78      String MERGED = "merged";
79  
80      /**
81       * Event type.
82       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
83       */
84      String REFERENCED = "referenced";
85  
86      /**
87       * Event type.
88       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
89       */
90      String MENTIONED = "mentioned";
91  
92      /**
93       * Event type.
94       * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
95       */
96      String ASSIGNED = "assigned";
97  
98      /**
99       * Event type.
100      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
101      */
102     String UNASSIGNED = "unassigned";
103 
104     /**
105      * Event type.
106      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
107      */
108     String LABELED = "labeled";
109 
110     /**
111      * Event type.
112      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
113      */
114     String UNLABELED = "unlabeled";
115 
116     /**
117      * Event type.
118      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
119      */
120     String MILESTONED = "milestoned";
121 
122     /**
123      * Event type.
124      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
125      */
126     String DEMILESTONED = "demilestoned";
127 
128     /**
129      * Event type.
130      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
131      */
132     String RENAMED = "renamed";
133 
134     /**
135      * Event type.
136      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
137      */
138     String LOCKED = "locked";
139 
140     /**
141      * Event type.
142      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
143      */
144     String UNLOCKED = "unlocked";
145 
146     /**
147      * Event type.
148      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
149      */
150     String HEAD_REF_DELETED = "head_ref_deleted";
151 
152     /**
153      * Event type.
154      * @see <a href="https://developer.github.com/v3/issues/events/">Event Types</a>
155      */
156     String HEAD_REF_RESTORED = "head_ref_restored";
157 
158     /**
159      * Repository we're in.
160      * @return Repo
161      */
162     Repo repo();
163 
164     /**
165      * Get its number.
166      * @return Issue number
167      */
168     int number();
169 
170     /**
171      * Smart event with extra features.
172      */
173     @Immutable
174     @ToString
175     @Loggable(Loggable.DEBUG)
176     @EqualsAndHashCode(of = { "event", "jsn" })
177     final class Smart implements Event {
178         /**
179          * Encapsulated event.
180          */
181         private final transient Event event;
182         /**
183          * SmartJson object for convenient JSON parsing.
184          */
185         private final transient SmartJson jsn;
186         /**
187          * Public ctor.
188          * @param evt Event
189          */
190         public Smart(final Event evt) {
191             this.event = evt;
192             this.jsn = new SmartJson(evt);
193         }
194         /**
195          * Does it have an author?
196          * @return TRUE if the author exists
197          * @throws IOException If there is any I/O problem
198          */
199         public boolean hasAuthor() throws IOException {
200             return !this.event.json().isNull("actor");
201         }
202         /**
203          * Get its author.
204          * @return Author of comment
205          * @throws IOException If there is any I/O problem
206          */
207         public User author() throws IOException {
208             return this.event.repo().github().users().get(
209                 this.event.json().getJsonObject("actor").getString("login")
210             );
211         }
212         /**
213          * Get its type.
214          * @return State of issue
215          * @throws IOException If there is any I/O problem
216          */
217         public String type() throws IOException {
218             return this.jsn.text("event");
219         }
220         /**
221          * Get its URL.
222          * @return URL of issue
223          * @throws IOException If there is any I/O problem
224          */
225         public URL url() throws IOException {
226             return new URL(this.jsn.text("url"));
227         }
228         /**
229          * When this issue was created.
230          * @return Date of creation
231          * @throws IOException If there is any I/O problem
232          */
233         public Date createdAt() throws IOException {
234             try {
235                 return new Github.Time(
236                     this.jsn.text("created_at")
237                 ).date();
238             } catch (final ParseException ex) {
239                 throw new IllegalStateException(ex);
240             }
241         }
242         /**
243          * Label that was added or removed in this event (if any).
244          * @return Label that was added or removed
245          * @throws IOException If there is any I/O problem
246          * @since 0.24
247          */
248         public Optional<Label> label() throws IOException {
249             Optional<Label> lab = Optional.absent();
250             final JsonObject lbl = this.jsn.json().getJsonObject("label");
251             if (lbl != null) {
252                 lab = Optional.of(
253                     this.event.repo()
254                         .labels()
255                         .get(lbl.getString("name"))
256                 );
257             }
258             return lab;
259         }
260         @Override
261         public Repo repo() {
262             return this.event.repo();
263         }
264         @Override
265         public int number() {
266             return this.event.number();
267         }
268         @Override
269         public JsonObject json() throws IOException {
270             return this.event.json();
271         }
272         @Override
273         public int compareTo(final Event obj) {
274             return this.event.compareTo(obj);
275         }
276     }
277 
278 }