|
1 | 1 | package org.kohsuke.github; |
2 | 2 |
|
3 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature; |
| 4 | +import com.fasterxml.jackson.databind.InjectableValues; |
4 | 5 | import com.fasterxml.jackson.databind.MapperFeature; |
5 | 6 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 7 | +import com.fasterxml.jackson.databind.ObjectReader; |
| 8 | +import com.fasterxml.jackson.databind.ObjectWriter; |
6 | 9 | import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
7 | 10 | import com.fasterxml.jackson.databind.introspect.VisibilityChecker; |
8 | 11 | import org.apache.commons.lang3.StringUtils; |
@@ -73,7 +76,7 @@ abstract class GitHubClient { |
73 | 76 |
|
74 | 77 | private static final Logger LOGGER = Logger.getLogger(GitHubClient.class.getName()); |
75 | 78 |
|
76 | | - static final ObjectMapper MAPPER = new ObjectMapper(); |
| 79 | + private static final ObjectMapper MAPPER = new ObjectMapper(); |
77 | 80 | static final String GITHUB_URL = "https://api.github.com"; |
78 | 81 |
|
79 | 82 | 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 |
399 | 402 | // Maybe throw an exception instead? |
400 | 403 | } else if (handler != null) { |
401 | 404 | body = handler.apply(responseInfo); |
402 | | - setResponseHeaders(responseInfo, body); |
403 | 405 | } |
404 | 406 | return new GitHubResponse<>(responseInfo, body); |
405 | 407 | } |
@@ -443,30 +445,6 @@ private static IOException interpretApiError(IOException e, |
443 | 445 | return e; |
444 | 446 | } |
445 | 447 |
|
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 | | - |
470 | 448 | protected static boolean isRateLimitResponse(@Nonnull GitHubResponse.ResponseInfo responseInfo) { |
471 | 449 | return responseInfo.statusCode() == HttpURLConnection.HTTP_FORBIDDEN |
472 | 450 | && "0".equals(responseInfo.headerField("X-RateLimit-Remaining")); |
@@ -567,7 +545,7 @@ private void noteRateLimit(@Nonnull GitHubResponse.ResponseInfo responseInfo) { |
567 | 545 | return; |
568 | 546 | } |
569 | 547 |
|
570 | | - GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo.headerField("Date")); |
| 548 | + GHRateLimit.Record observed = new GHRateLimit.Record(limit, remaining, reset, responseInfo); |
571 | 549 |
|
572 | 550 | updateCoreRateLimit(observed); |
573 | 551 | } |
@@ -714,4 +692,45 @@ static String printDate(Date dt) { |
714 | 692 | df.setTimeZone(TimeZone.getTimeZone("GMT")); |
715 | 693 | return df.format(dt); |
716 | 694 | } |
| 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 | + } |
717 | 736 | } |
0 commit comments