Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
User |
|
| 1.1666666666666667;1.167 | ||||
User$Smart |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure1 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure11 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure13 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure15 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure17 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure19 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure21 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure23 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure25 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure27 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure29 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure3 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure31 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure33 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure35 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure37 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure39 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure41 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure43 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure45 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure47 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure49 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure5 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure51 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure53 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure55 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure57 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure59 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure61 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure63 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure65 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure67 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure69 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure7 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure71 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure73 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure75 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure77 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure79 |
|
| 1.1666666666666667;1.167 | ||||
User$Smart$AjcClosure9 |
|
| 1.1666666666666667;1.167 |
1 | 0 | /** |
2 | * Copyright (c) 2013-2017, 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.Date; | |
38 | import javax.json.JsonObject; | |
39 | import lombok.EqualsAndHashCode; | |
40 | import lombok.ToString; | |
41 | ||
42 | /** | |
43 | * Github user. | |
44 | * @author Yegor Bugayenko (yegor@tpc2.com) | |
45 | * @version $Id: 73655046e068b217d1443bc61c4a1c1f0ac52c3c $ | |
46 | * @checkstyle MultipleStringLiterals (500 lines) | |
47 | * @see <a href="http://developer.github.com/v3/users/">User API</a> | |
48 | * @since 0.1 | |
49 | */ | |
50 | @Immutable | |
51 | @SuppressWarnings({"PMD.TooManyMethods", "PMD.ExcessivePublicCount", | |
52 | "PMD.GodClass" }) | |
53 | public interface User extends JsonReadable, JsonPatchable { | |
54 | ||
55 | /** | |
56 | * Github we're in. | |
57 | * @return Github | |
58 | * @since 0.4 | |
59 | */ | |
60 | Github github(); | |
61 | ||
62 | /** | |
63 | * Get his login. | |
64 | * @return Login name | |
65 | * @throws IOException If it fails | |
66 | */ | |
67 | String login() throws IOException; | |
68 | ||
69 | /** | |
70 | * Get his organizations. | |
71 | * @return UserOrganizations organizations | |
72 | */ | |
73 | UserOrganizations organizations(); | |
74 | ||
75 | /** | |
76 | * Get his keys. | |
77 | * @return PublicKeys keys | |
78 | */ | |
79 | PublicKeys keys(); | |
80 | ||
81 | /** | |
82 | * Get user's emails. | |
83 | * @return User's emails | |
84 | * @since 0.8 | |
85 | */ | |
86 | UserEmails emails(); | |
87 | ||
88 | /** | |
89 | * Notifications for this user. | |
90 | * Wraps the call "List your notifications". See "List your notifications" | |
91 | * at https://developer.github.com/v3/activity/notifications/ | |
92 | * @see <a href="https://developer.github.com/v3/activity/notifications/#list-your-notifications">List your notifications</a> | |
93 | * @return Notifications for this user. | |
94 | * @throws IOException Thrown, if an error during sending request and/or | |
95 | * receiving response occurs. | |
96 | */ | |
97 | Notifications notifications() throws IOException; | |
98 | ||
99 | /** | |
100 | * Marks notifications as read. | |
101 | * @param lastread Describes the last point that notifications were | |
102 | * checked. | |
103 | * @see <a href="https://developer.github.com/v3/activity/notifications/#mark-as-read">Mark as read</a> | |
104 | * @throws IOException Thrown, if an error during sending request and/or | |
105 | * receiving response occurs. | |
106 | */ | |
107 | void markAsRead(final Date lastread) throws IOException; | |
108 | ||
109 | /** | |
110 | * Smart user with extra features. | |
111 | * @see <a href="http://developer.github.com/v3/users/#get-a-single-user">Get a Single User</a> | |
112 | */ | |
113 | @Immutable | |
114 | 0 | @ToString |
115 | @Loggable(Loggable.DEBUG) | |
116 | 0 | @EqualsAndHashCode(of = { "user", "jsn" }) |
117 | final class Smart implements User { | |
118 | /** | |
119 | * Encapsulated user. | |
120 | */ | |
121 | private final transient User user; | |
122 | /** | |
123 | * SmartJson object for convenient JSON parsing. | |
124 | */ | |
125 | private final transient SmartJson jsn; | |
126 | ||
127 | /** | |
128 | * Public ctor. | |
129 | * @param usr User | |
130 | */ | |
131 | 29 | public Smart(final User usr) { |
132 | 29 | this.user = usr; |
133 | 29 | this.jsn = new SmartJson(usr); |
134 | 29 | } |
135 | ||
136 | /** | |
137 | * Does it exist in GitHub? | |
138 | * @return TRUE if this user truly exists | |
139 | * @throws IOException If it fails | |
140 | * @since 0.34 | |
141 | */ | |
142 | public boolean exists() throws IOException { | |
143 | 0 | return new Existence(this.user).check(); |
144 | } | |
145 | ||
146 | /** | |
147 | * Get his ID. | |
148 | * @return Unique user ID | |
149 | * @throws IOException If it fails | |
150 | * @checkstyle MethodName (3 lines) | |
151 | */ | |
152 | @SuppressWarnings("PMD.ShortMethodName") | |
153 | public int id() throws IOException { | |
154 | 0 | return this.user.json().getJsonNumber("id").intValue(); |
155 | } | |
156 | ||
157 | /** | |
158 | * Get his avatar URL. | |
159 | * @return URL of the avatar | |
160 | * @throws IOException If it fails | |
161 | */ | |
162 | public URL avatarUrl() throws IOException { | |
163 | 0 | return new URL(this.jsn.text("avatar_url")); |
164 | } | |
165 | ||
166 | /** | |
167 | * Get his URL. | |
168 | * @return URL of the user | |
169 | * @throws IOException If it fails | |
170 | */ | |
171 | public URL url() throws IOException { | |
172 | 0 | return new URL(this.jsn.text("url")); |
173 | } | |
174 | ||
175 | /** | |
176 | * Get his name. | |
177 | * @return User name | |
178 | * @throws IOException If it fails | |
179 | */ | |
180 | public String name() throws IOException { | |
181 | 0 | final JsonObject json = this.json(); |
182 | 0 | if (!json.containsKey("name")) { |
183 | 0 | throw new IllegalStateException( |
184 | 0 | String.format( |
185 | // @checkstyle LineLength (1 line) | |
186 | "User %s doesn't have a name specified in his/her Github account; use #hasName() first.", | |
187 | 0 | this.login() |
188 | ) | |
189 | ); | |
190 | } | |
191 | 0 | return json.getString("name"); |
192 | } | |
193 | ||
194 | /** | |
195 | * Check if user has name. | |
196 | * @return True if user has name | |
197 | * @throws IOException If it fails | |
198 | */ | |
199 | public boolean hasName() throws IOException { | |
200 | 4 | return this.json().containsKey("name"); |
201 | } | |
202 | ||
203 | /** | |
204 | * Get his company. | |
205 | * @return Company name | |
206 | * @throws IOException If it fails | |
207 | */ | |
208 | public String company() throws IOException { | |
209 | 0 | return this.jsn.text("company"); |
210 | } | |
211 | ||
212 | /** | |
213 | * Get his location. | |
214 | * @return Location name | |
215 | * @throws IOException If it fails | |
216 | */ | |
217 | public String location() throws IOException { | |
218 | 0 | return this.jsn.text("location"); |
219 | } | |
220 | ||
221 | /** | |
222 | * Get his email. | |
223 | * @return Email | |
224 | * @throws IOException If it fails | |
225 | */ | |
226 | public String email() throws IOException { | |
227 | 0 | return this.jsn.text("email"); |
228 | } | |
229 | ||
230 | @Override | |
231 | public Github github() { | |
232 | 0 | return this.user.github(); |
233 | } | |
234 | ||
235 | @Override | |
236 | public String login() throws IOException { | |
237 | 10 | return this.user.login(); |
238 | } | |
239 | ||
240 | @Override | |
241 | public UserOrganizations organizations() { | |
242 | 0 | return this.user.organizations(); |
243 | } | |
244 | ||
245 | @Override | |
246 | public PublicKeys keys() { | |
247 | 0 | return this.user.keys(); |
248 | } | |
249 | ||
250 | @Override | |
251 | public UserEmails emails() { | |
252 | 0 | return this.user.emails(); |
253 | } | |
254 | ||
255 | @Override | |
256 | public Notifications notifications() throws IOException { | |
257 | 0 | return this.user.notifications(); |
258 | } | |
259 | ||
260 | @Override | |
261 | public void markAsRead(final Date lastread) throws IOException { | |
262 | 0 | this.user.markAsRead(lastread); |
263 | 0 | } |
264 | ||
265 | @Override | |
266 | public JsonObject json() throws IOException { | |
267 | 4 | return this.user.json(); |
268 | } | |
269 | ||
270 | @Override | |
271 | public void patch( | |
272 | final JsonObject json | |
273 | ) throws IOException { | |
274 | 0 | this.user.patch(json); |
275 | 0 | } |
276 | ||
277 | /** | |
278 | * Returns the value of gravatar_id property of User's JSON. | |
279 | * @return The 'gravatar_id' property value. | |
280 | * @throws IOException If any I/O error occurs. | |
281 | */ | |
282 | public String gravatar() throws IOException { | |
283 | 2 | return this.jsn.text("gravatar_id"); |
284 | } | |
285 | ||
286 | /** | |
287 | * Returns the value of html_url property of User's JSON. | |
288 | * @return The 'html_url' property value. | |
289 | * @throws IOException If any I/O error occurs. | |
290 | */ | |
291 | public String htmlUrl() throws IOException { | |
292 | 2 | return this.jsn.text("html_url"); |
293 | } | |
294 | ||
295 | /** | |
296 | * Returns the value of followers_url property of User's JSON. | |
297 | * @return The 'followers_url' property value. | |
298 | * @throws IOException If any I/O error occurs. | |
299 | */ | |
300 | public String followersUrl() throws IOException { | |
301 | 2 | return this.jsn.text("followers_url"); |
302 | } | |
303 | ||
304 | /** | |
305 | * Returns the value of following_url property of User's JSON. | |
306 | * @return The 'following_url' property value. | |
307 | * @throws IOException If any I/O error occurs. | |
308 | */ | |
309 | public String followingUrl() throws IOException { | |
310 | 2 | return this.jsn.text("following_url"); |
311 | } | |
312 | ||
313 | /** | |
314 | * Returns the value of gists_url property of User's JSON. | |
315 | * @return The 'gists_url' property value. | |
316 | * @throws IOException If any I/O error occurs. | |
317 | */ | |
318 | public String gistsUrl() throws IOException { | |
319 | 2 | return this.jsn.text("gists_url"); |
320 | } | |
321 | ||
322 | /** | |
323 | * Returns the value of starred_url property of User's JSON. | |
324 | * @return The 'starred_url' property value. | |
325 | * @throws IOException If any I/O error occurs. | |
326 | */ | |
327 | public String starredUrl() throws IOException { | |
328 | 2 | return this.jsn.text("starred_url"); |
329 | } | |
330 | ||
331 | /** | |
332 | * Returns the value of subscriptions_url property of User's JSON. | |
333 | * @return The 'subscriptions_url' property value. | |
334 | * @throws IOException If any I/O error occurs. | |
335 | */ | |
336 | public String subscriptionsUrl() throws IOException { | |
337 | 2 | return this.jsn.text("subscriptions_url"); |
338 | } | |
339 | ||
340 | /** | |
341 | * Returns the value of organizations_url property of User's JSON. | |
342 | * @return The 'organizations_url' property value. | |
343 | * @throws IOException If any I/O error occurs. | |
344 | */ | |
345 | public String organizationsUrl() throws IOException { | |
346 | 2 | return this.jsn.text("organizations_url"); |
347 | } | |
348 | ||
349 | /** | |
350 | * Returns the value of repos_url property of User's JSON. | |
351 | * @return The 'repos_url' property value. | |
352 | * @throws IOException If any I/O error occurs. | |
353 | */ | |
354 | public String reposUrl() throws IOException { | |
355 | 2 | return this.jsn.text("repos_url"); |
356 | } | |
357 | ||
358 | /** | |
359 | * Returns the value of events_url property of User's JSON. | |
360 | * @return The 'events_url' property value. | |
361 | * @throws IOException If any I/O error occurs. | |
362 | */ | |
363 | public String eventsUrl() throws IOException { | |
364 | 2 | return this.jsn.text("events_url"); |
365 | } | |
366 | ||
367 | /** | |
368 | * Returns the value of received_events_url property of User's JSON. | |
369 | * @return The 'received_events_url' property value. | |
370 | * @throws IOException If any I/O error occurs. | |
371 | */ | |
372 | public String receivedEventsUrl() throws IOException { | |
373 | 2 | return this.jsn.text("received_events_url"); |
374 | } | |
375 | ||
376 | /** | |
377 | * Returns the value of type property of User's JSON. | |
378 | * @return The 'type' property value. | |
379 | * @throws IOException If any I/O error occurs. | |
380 | */ | |
381 | public String type() throws IOException { | |
382 | 2 | return this.jsn.text("type"); |
383 | } | |
384 | ||
385 | /** | |
386 | * Returns the value of site_admin property of User's JSON. | |
387 | * @return The 'site_admin' property value. | |
388 | * @throws IOException If any I/O error occurs. | |
389 | */ | |
390 | public boolean siteAdmin() throws IOException { | |
391 | 2 | return "true".equals(this.jsn.text("site_admin")); |
392 | } | |
393 | ||
394 | /** | |
395 | * Returns the value of blog property of User's JSON. | |
396 | * @return The 'blog' property value. | |
397 | * @throws IOException If any I/O error occurs. | |
398 | */ | |
399 | public String blog() throws IOException { | |
400 | 2 | return this.jsn.text("blog"); |
401 | } | |
402 | ||
403 | /** | |
404 | * Returns the value of hireable property of User's JSON. | |
405 | * @return The 'hireable' property value. | |
406 | * @throws IOException If any I/O error occurs. | |
407 | */ | |
408 | public boolean hireable() throws IOException { | |
409 | 2 | return "true".equals(this.jsn.text("hireable")); |
410 | } | |
411 | ||
412 | /** | |
413 | * Returns the value of bio property of User's JSON. | |
414 | * @return The 'bio' property value. | |
415 | * @throws IOException If any I/O error occurs. | |
416 | */ | |
417 | public String bio() throws IOException { | |
418 | 2 | return this.jsn.text("bio"); |
419 | } | |
420 | ||
421 | /** | |
422 | * Returns the value of public_repos property of User's JSON. | |
423 | * @return The 'public_repos' property value. | |
424 | * @throws IOException If any I/O error occurs. | |
425 | */ | |
426 | public int publicRepos() throws IOException { | |
427 | 2 | return Integer.parseInt(this.jsn.text("public_repos")); |
428 | } | |
429 | ||
430 | /** | |
431 | * Returns the value of public_gists property of User's JSON. | |
432 | * @return The 'public_gists' property value. | |
433 | * @throws IOException If any I/O error occurs. | |
434 | */ | |
435 | public int publicGists() throws IOException { | |
436 | 2 | return Integer.parseInt(this.jsn.text("public_gists")); |
437 | } | |
438 | ||
439 | /** | |
440 | * Returns the value of followers property of User's JSON. | |
441 | * @return The 'followers' property value. | |
442 | * @throws IOException If any I/O error occurs. | |
443 | */ | |
444 | public int followersCount() throws IOException { | |
445 | 2 | return Integer.parseInt(this.jsn.text("followers")); |
446 | } | |
447 | ||
448 | /** | |
449 | * Returns the value of following property of User's JSON. | |
450 | * @return The 'following' property value. | |
451 | * @throws IOException If any I/O error occurs. | |
452 | */ | |
453 | public int followingCount() throws IOException { | |
454 | 2 | return Integer.parseInt(this.jsn.text("following")); |
455 | } | |
456 | ||
457 | /** | |
458 | * Returns the value of created_at property of User's JSON. | |
459 | * @return The 'created_at' property value. | |
460 | * @throws IOException If any I/O error occurs. | |
461 | */ | |
462 | public Github.Time created() throws IOException { | |
463 | try { | |
464 | 2 | return new Github.Time(this.jsn.text("created_at")); |
465 | 0 | } catch (final ParseException ex) { |
466 | 0 | throw new IllegalArgumentException( |
467 | "Cannot parse value of 'created_at' property", | |
468 | ex | |
469 | ); | |
470 | } | |
471 | } | |
472 | ||
473 | /** | |
474 | * Returns the value of updated_at property of User's JSON. | |
475 | * @return The 'updated_at' property value. | |
476 | * @throws IOException If any I/O error occurs. | |
477 | */ | |
478 | public Github.Time updated() throws IOException { | |
479 | try { | |
480 | 2 | return new Github.Time(this.jsn.text("updated_at")); |
481 | 0 | } catch (final ParseException ex) { |
482 | 0 | throw new IllegalArgumentException( |
483 | "Cannot parse value of 'updated_at' property", | |
484 | ex | |
485 | ); | |
486 | } | |
487 | } | |
488 | } | |
489 | } |