Skip to content

Commit 87aa9bd

Browse files
authored
Merge branch 'master' into feature/delete_branch_automatically
2 parents 816c83c + b5c7f83 commit 87aa9bd

15 files changed

Lines changed: 105 additions & 70 deletions

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
<modelVersion>4.0.0</modelVersion>
33
<groupId>org.kohsuke</groupId>
44
<artifactId>github-api</artifactId>
5-
<version>1.107-SNAPSHOT</version>
5+
<version>1.108-SNAPSHOT</version>
66
<name>GitHub API for Java</name>
77
<url>https://github-api.kohsuke.org/</url>
88
<description>GitHub API for Java</description>
99

1010
<scm>
1111
<connection>scm:git:git@github.com/github-api/${project.artifactId}.git</connection>
1212
<developerConnection>scm:git:ssh://git@github.com/github-api/${project.artifactId}.git</developerConnection>
13-
<url>https://${project.artifactId}.kohsuke.org/</url>
13+
<url>https://github.com/github-api/github-api/</url>
1414
<tag>HEAD</tag>
1515
</scm>
1616

@@ -495,7 +495,7 @@
495495
<dependency>
496496
<groupId>org.mockito</groupId>
497497
<artifactId>mockito-core</artifactId>
498-
<version>3.2.4</version>
498+
<version>3.3.0</version>
499499
<scope>test</scope>
500500
</dependency>
501501
<dependency>

src/main/java/org/kohsuke/github/GHEventInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public GHOrganization getOrganization() throws IOException {
142142
* if payload cannot be parsed
143143
*/
144144
public <T extends GHEventPayload> T getPayload(Class<T> type) throws IOException {
145-
T v = GitHubClient.MAPPER.readValue(payload.traverse(), type);
145+
T v = GitHubClient.getMappingObjectReader().readValue(payload.traverse(), type);
146146
v.wrapUp(root);
147147
return v;
148148
}

src/main/java/org/kohsuke/github/GHNotificationStream.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,6 @@ private long calcNextCheckTime(GitHubResponse<GHThread[]> response) {
207207
long seconds = Integer.parseInt(v);
208208
return System.currentTimeMillis() + seconds * 1000;
209209
}
210-
211-
public void remove() {
212-
throw new UnsupportedOperationException();
213-
}
214210
};
215211
}
216212

src/main/java/org/kohsuke/github/GHObject.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.kohsuke.github;
22

3+
import com.fasterxml.jackson.annotation.JacksonInject;
34
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
45
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
56
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
@@ -33,6 +34,19 @@ public abstract class GHObject {
3334
GHObject() {
3435
}
3536

37+
/**
38+
* Called by Jackson
39+
*
40+
* @param responseInfo
41+
* the {@link GitHubResponse.ResponseInfo} to get headers from.
42+
*/
43+
@JacksonInject
44+
protected void setResponseHeaderFields(@CheckForNull GitHubResponse.ResponseInfo responseInfo) {
45+
if (responseInfo != null) {
46+
responseHeaderFields = responseInfo.headers();
47+
}
48+
}
49+
3650
/**
3751
* Returns the HTTP response headers given along with the state of this object.
3852
*

src/main/java/org/kohsuke/github/GHPerson.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,6 @@ public List<GHRepository> next() {
131131
r.root = root;
132132
return Arrays.asList(batch);
133133
}
134-
135-
public void remove() {
136-
throw new UnsupportedOperationException();
137-
}
138134
};
139135
}
140136
};

src/main/java/org/kohsuke/github/GHRateLimit.java

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.kohsuke.github;
22

3+
import com.fasterxml.jackson.annotation.JacksonInject;
34
import com.fasterxml.jackson.annotation.JsonCreator;
45
import com.fasterxml.jackson.annotation.JsonProperty;
56
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -289,14 +290,11 @@ public static class Record {
289290

290291
/**
291292
* The time at which the rate limit will reset. This value is calculated based on
292-
* {@link #getResetEpochSeconds()} by calling {@link #recalculateResetDate}. If the clock on the local machine
293-
* not synchronized with the server clock, this time value will be adjusted to match the local machine's clock.
294-
* <p>
295-
* Recalculated by calling {@link #recalculateResetDate}.
296-
* </p>
293+
* {@link #getResetEpochSeconds()} by calling {@link #calculateResetDate}. If the clock on the local machine not
294+
* synchronized with the server clock, this time value will be adjusted to match the local machine's clock.
297295
*/
298296
@Nonnull
299-
private Date resetDate;
297+
private final Date resetDate;
300298

301299
/**
302300
* Instantiates a new Record.
@@ -308,31 +306,37 @@ public static class Record {
308306
* @param resetEpochSeconds
309307
* the reset epoch seconds
310308
*/
311-
@JsonCreator
312309
public Record(@JsonProperty(value = "limit", required = true) int limit,
313310
@JsonProperty(value = "remaining", required = true) int remaining,
314311
@JsonProperty(value = "reset", required = true) long resetEpochSeconds) {
315312
this(limit, remaining, resetEpochSeconds, null);
316313
}
317314

318315
/**
319-
* Instantiates a new Record.
316+
* Instantiates a new Record. Called by Jackson data binding or during header parsing.
320317
*
321318
* @param limit
322319
* the limit
323320
* @param remaining
324321
* the remaining
325322
* @param resetEpochSeconds
326323
* the reset epoch seconds
327-
* @param updatedAt
328-
* the updated at
324+
* @param responseInfo
325+
* the response info
329326
*/
330-
@SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD", justification = "Deprecated")
331-
public Record(int limit, int remaining, long resetEpochSeconds, @CheckForNull String updatedAt) {
327+
@JsonCreator
328+
Record(@JsonProperty(value = "limit", required = true) int limit,
329+
@JsonProperty(value = "remaining", required = true) int remaining,
330+
@JsonProperty(value = "reset", required = true) long resetEpochSeconds,
331+
@JacksonInject @CheckForNull GitHubResponse.ResponseInfo responseInfo) {
332332
this.limit = limit;
333333
this.remaining = remaining;
334334
this.resetEpochSeconds = resetEpochSeconds;
335-
this.resetDate = recalculateResetDate(updatedAt);
335+
String updatedAt = null;
336+
if (responseInfo != null) {
337+
updatedAt = responseInfo.headerField("Date");
338+
}
339+
this.resetDate = calculateResetDate(updatedAt);
336340
}
337341

338342
/**
@@ -362,7 +366,8 @@ public Record(int limit, int remaining, long resetEpochSeconds, @CheckForNull St
362366
* a string date in RFC 1123
363367
* @return reset date based on the passed date
364368
*/
365-
Date recalculateResetDate(@CheckForNull String updatedAt) {
369+
@Nonnull
370+
private Date calculateResetDate(@CheckForNull String updatedAt) {
366371
long updatedAtEpochSeconds = createdAtEpochSeconds;
367372
if (!StringUtils.isBlank(updatedAt)) {
368373
try {
@@ -379,7 +384,7 @@ Date recalculateResetDate(@CheckForNull String updatedAt) {
379384
// This may seem odd but it results in an accurate or slightly pessimistic reset date
380385
// based on system time rather than assuming the system time synchronized with the server
381386
long calculatedSecondsUntilReset = resetEpochSeconds - updatedAtEpochSeconds;
382-
return resetDate = new Date((createdAtEpochSeconds + calculatedSecondsUntilReset) * 1000);
387+
return new Date((createdAtEpochSeconds + calculatedSecondsUntilReset) * 1000);
383388
}
384389

385390
/**

src/main/java/org/kohsuke/github/GitHub.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ public GHGistBuilder createGist() {
772772
* the io exception
773773
*/
774774
public <T extends GHEventPayload> T parseEventPayload(Reader r, Class<T> type) throws IOException {
775-
T t = GitHubClient.MAPPER.readValue(r, type);
775+
T t = GitHubClient.getMappingObjectReader().forType(type).readValue(r);
776776
t.wrapUp(this);
777777
return t;
778778
}

src/main/java/org/kohsuke/github/GitHubClient.java

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package org.kohsuke.github;
22

33
import com.fasterxml.jackson.databind.DeserializationFeature;
4+
import com.fasterxml.jackson.databind.InjectableValues;
45
import com.fasterxml.jackson.databind.MapperFeature;
56
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.ObjectReader;
8+
import com.fasterxml.jackson.databind.ObjectWriter;
69
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
710
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
811
import org.apache.commons.lang3.StringUtils;
@@ -73,7 +76,7 @@ abstract class GitHubClient {
7376

7477
private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName());
7578

76-
static final ObjectMapper MAPPER = new ObjectMapper();
79+
private static final ObjectMapper MAPPER = new ObjectMapper();
7780
static final String GITHUB_URL = "https://api.github.com";
7881

7982
private static final String[] TIME_FORMATS = { "yyyy/MM/dd HH:mm:ss ZZZZ", "yyyy-MM-dd'T'HH:mm:ss'Z'",
@@ -399,7 +402,6 @@ private static <T> GitHubResponse<T> createResponse(@Nonnull GitHubResponse.Resp
399402
// Maybe throw an exception instead?
400403
} else if (handler != null) {
401404
body = handler.apply(responseInfo);
402-
setResponseHeaders(responseInfo, body);
403405
}
404406
return new GitHubResponse<>(responseInfo, body);
405407
}
@@ -443,30 +445,6 @@ private static IOException interpretApiError(IOException e,
443445
return e;
444446
}
445447

446-
/**
447-
* Sets the response headers on objects that need it. Ideally this would be handled by the objects themselves, but
448-
* currently they do not have access to {@link GitHubResponse.ResponseInfo} after the
449-
*
450-
* @param responseInfo
451-
* the response info
452-
* @param readValue
453-
* the object to consider adding headers to.
454-
* @param <T>
455-
* type of the object
456-
*/
457-
private static <T> void setResponseHeaders(GitHubResponse.ResponseInfo responseInfo, T readValue) {
458-
if (readValue instanceof GHObject[]) {
459-
for (GHObject ghObject : (GHObject[]) readValue) {
460-
ghObject.responseHeaderFields = responseInfo.headers();
461-
}
462-
} else if (readValue instanceof GHObject) {
463-
((GHObject) readValue).responseHeaderFields = responseInfo.headers();
464-
} else if (readValue instanceof JsonRateLimit) {
465-
// if we're getting a GHRateLimit it needs the server date
466-
((JsonRateLimit) readValue).resources.getCore().recalculateResetDate(responseInfo.headerField("Date"));
467-
}
468-
}
469-
470448
protected static boolean isRateLimitResponse(@Nonnull GitHubResponse.ResponseInfo responseInfo) {
471449
return responseInfo.statusCode() == HttpURLConnection.HTTP_FORBIDDEN
472450
&& "0".equals(responseInfo.headerField("X-RateLimit-Remaining"));
@@ -567,7 +545,7 @@ private void noteRateLimit(@Nonnull GitHubResponse.ResponseInfo responseInfo) {
567545
return;
568546
}
569547

570-
GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo.headerField("Date"));
548+
GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo);
571549

572550
updateCoreRateLimit(observed);
573551
}
@@ -714,4 +692,45 @@ static String printDate(Date dt) {
714692
df.setTimeZone(TimeZone.getTimeZone("GMT"));
715693
return df.format(dt);
716694
}
695+
696+
/**
697+
* Gets an {@link ObjectWriter}.
698+
*
699+
* @return an {@link ObjectWriter} instance that can be further configured.
700+
*/
701+
@Nonnull
702+
static ObjectWriter getMappingObjectWriter() {
703+
return MAPPER.writer();
704+
}
705+
706+
/**
707+
* Helper for {@link #getMappingObjectReader(GitHubResponse.ResponseInfo)}
708+
*
709+
* @return an {@link ObjectReader} instance that can be further configured.
710+
*/
711+
@Nonnull
712+
static ObjectReader getMappingObjectReader() {
713+
return getMappingObjectReader(null);
714+
}
715+
716+
/**
717+
* Gets an {@link ObjectReader}.
718+
*
719+
* Members of {@link InjectableValues} must be present even if {@code null}, otherwise classes expecting those
720+
* values will fail to read. This differs from regular JSONProperties which provide defaults instead of failing.
721+
*
722+
* Having one spot to create readers and having it take all injectable values is not a great long term solution but
723+
* it is sufficient for this first cut.
724+
*
725+
* @param responseInfo
726+
* the {@link GitHubResponse.ResponseInfo} to inject for this reader.
727+
* @return an {@link ObjectReader} instance that can be further configured.
728+
*/
729+
@Nonnull
730+
static ObjectReader getMappingObjectReader(@CheckForNull GitHubResponse.ResponseInfo responseInfo) {
731+
InjectableValues.Std inject = new InjectableValues.Std();
732+
inject.addValue(GitHubResponse.ResponseInfo.class, responseInfo);
733+
734+
return MAPPER.reader(inject);
735+
}
717736
}

src/main/java/org/kohsuke/github/GitHubHttpUrlConnectionClient.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ private static void buildRequest(GitHubRequest request, HttpURLConnection connec
153153
for (GitHubRequest.Entry e : request.args()) {
154154
json.put(e.key, e.value);
155155
}
156-
MAPPER.writeValue(connection.getOutputStream(), json);
156+
getMappingObjectWriter().writeValue(connection.getOutputStream(), json);
157157
}
158158
}
159159
}
@@ -235,4 +235,5 @@ private InputStream wrapStream(InputStream stream) throws IOException {
235235
private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName());
236236

237237
}
238+
238239
}

src/main/java/org/kohsuke/github/GitHubPageIterator.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,6 @@ public GitHubResponse<T> finalResponse() {
114114
return finalResponse;
115115
}
116116

117-
public void remove() {
118-
throw new UnsupportedOperationException();
119-
}
120-
121117
/**
122118
* Fetch is called at the start of {@link #hasNext()} or {@link #next()} to fetch another page of data if it is
123119
* needed.

0 commit comments

Comments
 (0)