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.http.Request; 34 import java.io.IOException; 35 import java.text.DateFormat; 36 import java.text.ParseException; 37 import java.text.SimpleDateFormat; 38 import java.util.Date; 39 import java.util.Locale; 40 import java.util.TimeZone; 41 import javax.json.JsonObject; 42 import lombok.EqualsAndHashCode; 43 44 /** 45 * Github client, starting point to the entire library. 46 * 47 * <p>This is how you start communicating with Github API: 48 * 49 * <pre> Github github = new RtGithub(oauthKey); 50 * Repo repo = github.repos().get( 51 * new Coordinates.Simple("jcabi/jcabi-github") 52 * ); 53 * Issues issues = repo.issues(); 54 * Issue issue = issues.post("issue title", "issue body");</pre> 55 * 56 * <p>It is strongly recommended to use 57 * {@link com.jcabi.http.wire.RetryWire} to avoid 58 * accidental I/O exceptions: 59 * 60 * <pre> Github github = new RtGithub( 61 * new RtGithub(oauthKey) 62 * .entry() 63 * .through(RetryWire.class) 64 * );</pre> 65 * 66 * <p>The interfaces in this packages are trying to cover as much 67 * as possible of Github API. However, there are parts of API that are 68 * rarely used and making Java classes for them is not an effective 69 * idea. That's why {@code Github} class has {@link #entry()} method, 70 * which returns an entry point to the RESTful API. For example, you 71 * want to use 72 * <a href="https://developer.github.com/v3/search/#search-repositories">"Search 73 * Repositories"</a> feature of Github: 74 * 75 * <pre> Github github = new RtGithub(oauthKey); 76 * int found = github.entry() 77 * .uri().path("/search/repositories").back() 78 * .method(Request.GET) 79 * .fetch() 80 * .as(JsonResponse.class) 81 * .getJsonObject() 82 * .getNumber("total_count") 83 * .intValue();</pre> 84 * @author Yegor Bugayenko (yegor256@gmail.com) 85 * @version $Id: a5925448bec69199ce04cb612c44c135cf22e00f $ 86 * @since 0.1 87 */ 88 @Immutable 89 @SuppressWarnings("PMD.TooManyMethods") 90 public interface Github { 91 92 /** 93 * RESTful request, an entry point to the Github API. 94 * @return Request 95 */ 96 Request entry(); 97 98 /** 99 * Get repositories. 100 * @return Repositories 101 */ 102 Repos repos(); 103 104 /** 105 * Get Gists API entry point. 106 * @return Gists API entry point 107 */ 108 Gists gists(); 109 110 /** 111 * Get Users API entry point. 112 * @return Users API entry point 113 * @since 0.4 114 */ 115 Users users(); 116 117 /** 118 * Get Organizations API entry point. 119 * @return Organizations API entry point 120 * @since 0.24 121 */ 122 Organizations organizations(); 123 124 /** 125 * Get Markdown API entry point. 126 * @return Markdown API entry point 127 * @since 0.6 128 */ 129 Markdown markdown(); 130 131 /** 132 * Rate limit API entry point. 133 * @return Rate limit API 134 * @since 0.6 135 */ 136 Limits limits(); 137 138 /** 139 * Search API entry point. 140 * @return Search API 141 * @since 0.8 142 */ 143 Search search(); 144 145 /** 146 * Get gitignores. 147 * @return Gitignotes API 148 * @see <a href="https://developer.github.com/v3/gitignore/">Gitignore API</a> 149 * @since 0.8 150 */ 151 Gitignores gitignores(); 152 153 /** 154 * Get meta information. 155 * @return JSON with meta 156 * @throws IOException If there is any I/O problem 157 * @see <a href="https://developer.github.com/v3/meta/">Meta API</a> 158 * @since 0.6 159 */ 160 JsonObject meta() throws IOException; 161 162 /** 163 * Get emojis. 164 * @return JSON with emojis 165 * @throws IOException If there is any I/O problem 166 * @see <a href="https://developer.github.com/v3/emojis/">Emojis API</a> 167 * @since 0.6 168 */ 169 JsonObject emojis() throws IOException; 170 171 /** 172 * Time in Github JSON. 173 * @see <a href="https://developer.github.com/v3/#schema">Schema</a> 174 * @since 0.2 175 */ 176 @Immutable 177 @EqualsAndHashCode(of = { "msec" }) 178 final class Time { 179 /** 180 * Pattern to present day in ISO-8601. 181 */ 182 public static final String FORMAT_ISO = "yyyy-MM-dd'T'HH:mm:ss'Z'"; 183 /** 184 * The time zone we're in. 185 */ 186 public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC"); 187 /** 188 * Encapsulated time in milliseconds. 189 */ 190 private final transient long msec; 191 192 /** 193 * Ctor. 194 */ 195 public Time() { 196 this(new Date()); 197 } 198 199 /** 200 * Ctor. 201 * @param text ISO date/time 202 * @throws ParseException If fails 203 */ 204 public Time(final String text) throws ParseException { 205 this(Github.Time.format().parse(text)); 206 } 207 208 /** 209 * Ctor. 210 * @param date Date to encapsulate 211 */ 212 public Time(final Date date) { 213 this(date.getTime()); 214 } 215 216 /** 217 * Ctor. 218 * @param millis Milliseconds 219 */ 220 public Time(final long millis) { 221 this.msec = millis; 222 } 223 224 @Override 225 public String toString() { 226 return Github.Time.format().format(this.date()); 227 } 228 229 /** 230 * Get date. 231 * @return Date 232 */ 233 public Date date() { 234 return new Date(this.msec); 235 } 236 237 /** 238 * Make format. 239 * @return Date format 240 */ 241 private static DateFormat format() { 242 final DateFormat fmt = new SimpleDateFormat( 243 Github.Time.FORMAT_ISO, Locale.ENGLISH 244 ); 245 fmt.setTimeZone(Github.Time.TIMEZONE); 246 return fmt; 247 } 248 } 249 250 }