mirror of
https://github.com/jlengrand/github-api.git
synced 2026-03-21 15:50:49 +00:00
320 lines
13 KiB
HTML
320 lines
13 KiB
HTML
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>GitHubResponse.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">GitHub API for Java</a> > <a href="index.source.html" class="el_package">org.kohsuke.github</a> > <span class="el_source">GitHubResponse.java</span></div><h1>GitHubResponse.java</h1><pre class="source lang-java linenums">package org.kohsuke.github;
|
|
|
|
import com.fasterxml.jackson.core.JsonParseException;
|
|
import com.fasterxml.jackson.databind.InjectableValues;
|
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
import org.apache.commons.io.IOUtils;
|
|
import org.kohsuke.github.function.FunctionThrows;
|
|
|
|
import java.io.Closeable;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.lang.reflect.Array;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.TreeMap;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import javax.annotation.CheckForNull;
|
|
import javax.annotation.Nonnull;
|
|
|
|
/**
|
|
* A GitHubResponse
|
|
* <p>
|
|
* A {@link GitHubResponse} generated by from sending a {@link GitHubRequest} to a {@link GitHubClient}.
|
|
* </p>
|
|
*
|
|
* @param <T>
|
|
* the type of the data parsed from the body of a {@link ResponseInfo}.
|
|
*/
|
|
class GitHubResponse<T> {
|
|
|
|
<span class="fc" id="L39"> private static final Logger LOGGER = Logger.getLogger(GitHubResponse.class.getName());</span>
|
|
|
|
private final int statusCode;
|
|
|
|
@Nonnull
|
|
private final GitHubRequest request;
|
|
|
|
@Nonnull
|
|
private final Map<String, List<String>> headers;
|
|
|
|
@CheckForNull
|
|
private final T body;
|
|
|
|
<span class="fc" id="L52"> GitHubResponse(GitHubResponse<T> response, @CheckForNull T body) {</span>
|
|
<span class="fc" id="L53"> this.statusCode = response.statusCode();</span>
|
|
<span class="fc" id="L54"> this.request = response.request();</span>
|
|
<span class="fc" id="L55"> this.headers = response.headers();</span>
|
|
<span class="fc" id="L56"> this.body = body;</span>
|
|
<span class="fc" id="L57"> }</span>
|
|
|
|
<span class="fc" id="L59"> GitHubResponse(ResponseInfo responseInfo, @CheckForNull T body) {</span>
|
|
<span class="fc" id="L60"> this.statusCode = responseInfo.statusCode();</span>
|
|
<span class="fc" id="L61"> this.request = responseInfo.request();</span>
|
|
<span class="fc" id="L62"> this.headers = responseInfo.headers();</span>
|
|
<span class="fc" id="L63"> this.body = body;</span>
|
|
<span class="fc" id="L64"> }</span>
|
|
|
|
/**
|
|
* Parses a {@link ResponseInfo} body into a new instance of {@link T}.
|
|
*
|
|
* @param responseInfo
|
|
* response info to parse.
|
|
* @param type
|
|
* the type to be constructed.
|
|
* @param <T>
|
|
* the type
|
|
* @return a new instance of {@link T}.
|
|
* @throws IOException
|
|
* if there is an I/O Exception.
|
|
*/
|
|
@CheckForNull
|
|
static <T> T parseBody(ResponseInfo responseInfo, Class<T> type) throws IOException {
|
|
|
|
<span class="fc bfc" id="L82" title="All 2 branches covered."> if (responseInfo.statusCode() == HttpURLConnection.HTTP_NO_CONTENT) {</span>
|
|
<span class="pc bpc" id="L83" title="1 of 4 branches missed."> if (type != null && type.isArray()) {</span>
|
|
// no content for array should be empty array
|
|
<span class="fc" id="L85"> return type.cast(Array.newInstance(type.getComponentType(), 0));</span>
|
|
} else {
|
|
// no content for object should be null
|
|
<span class="fc" id="L88"> return null;</span>
|
|
}
|
|
}
|
|
|
|
<span class="fc" id="L92"> String data = responseInfo.getBodyAsString();</span>
|
|
try {
|
|
<span class="fc" id="L94"> InjectableValues.Std inject = new InjectableValues.Std();</span>
|
|
<span class="fc" id="L95"> inject.addValue(ResponseInfo.class, responseInfo);</span>
|
|
|
|
<span class="fc" id="L97"> return GitHubClient.getMappingObjectReader(responseInfo).forType(type).readValue(data);</span>
|
|
<span class="fc" id="L98"> } catch (JsonMappingException | JsonParseException e) {</span>
|
|
<span class="fc" id="L99"> String message = "Failed to deserialize: " + data;</span>
|
|
<span class="fc" id="L100"> LOGGER.log(Level.FINE, message);</span>
|
|
<span class="fc" id="L101"> throw e;</span>
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parses a {@link ResponseInfo} body into a new instance of {@link T}.
|
|
*
|
|
* @param responseInfo
|
|
* response info to parse.
|
|
* @param instance
|
|
* the object to fill with data parsed from body
|
|
* @param <T>
|
|
* the type
|
|
* @return a new instance of {@link T}.
|
|
* @throws IOException
|
|
* if there is an I/O Exception.
|
|
*/
|
|
@CheckForNull
|
|
static <T> T parseBody(ResponseInfo responseInfo, T instance) throws IOException {
|
|
|
|
<span class="fc" id="L121"> String data = responseInfo.getBodyAsString();</span>
|
|
try {
|
|
<span class="fc" id="L123"> return GitHubClient.getMappingObjectReader(responseInfo).withValueToUpdate(instance).readValue(data);</span>
|
|
<span class="fc" id="L124"> } catch (JsonMappingException | JsonParseException e) {</span>
|
|
<span class="fc" id="L125"> String message = "Failed to deserialize: " + data;</span>
|
|
<span class="fc" id="L126"> LOGGER.log(Level.FINE, message);</span>
|
|
<span class="fc" id="L127"> throw e;</span>
|
|
}
|
|
}
|
|
|
|
/**
|
|
* The {@link URL} for this response.
|
|
*
|
|
* @return the {@link URL} for this response.
|
|
*/
|
|
@Nonnull
|
|
public URL url() {
|
|
<span class="nc" id="L138"> return request.url();</span>
|
|
}
|
|
|
|
/**
|
|
* The {@link GitHubRequest} for this response.
|
|
*
|
|
* @return the {@link GitHubRequest} for this response.
|
|
*/
|
|
@Nonnull
|
|
public GitHubRequest request() {
|
|
<span class="fc" id="L148"> return request;</span>
|
|
}
|
|
|
|
/**
|
|
* The status code for this response.
|
|
*
|
|
* @return the status code for this response.
|
|
*/
|
|
public int statusCode() {
|
|
<span class="fc" id="L157"> return statusCode;</span>
|
|
}
|
|
|
|
/**
|
|
* The headers for this response.
|
|
*
|
|
* @return the headers for this response.
|
|
*/
|
|
@Nonnull
|
|
public Map<String, List<String>> headers() {
|
|
<span class="fc" id="L167"> return headers;</span>
|
|
}
|
|
|
|
/**
|
|
* Gets the value of a header field for this response.
|
|
*
|
|
* @param name
|
|
* the name of the header field.
|
|
* @return the value of the header field, or {@code null} if the header isn't set.
|
|
*/
|
|
@CheckForNull
|
|
public String headerField(String name) {
|
|
<span class="fc" id="L179"> String result = null;</span>
|
|
<span class="fc bfc" id="L180" title="All 2 branches covered."> if (headers.containsKey(name)) {</span>
|
|
<span class="fc" id="L181"> result = headers.get(name).get(0);</span>
|
|
}
|
|
<span class="fc" id="L183"> return result;</span>
|
|
}
|
|
|
|
/**
|
|
* The body of the response parsed as a {@link T}
|
|
*
|
|
* @return body of the response
|
|
*/
|
|
public T body() {
|
|
<span class="fc" id="L192"> return body;</span>
|
|
}
|
|
|
|
/**
|
|
* Represents a supplier of results that can throw.
|
|
*
|
|
* @param <T>
|
|
* the type of results supplied by this supplier
|
|
*/
|
|
@FunctionalInterface
|
|
interface BodyHandler<T> extends FunctionThrows<ResponseInfo, T, IOException> {
|
|
}
|
|
|
|
/**
|
|
* Initial response information supplied to a {@link BodyHandler} when a response is initially received and before
|
|
* the body is processed.
|
|
*/
|
|
static abstract class ResponseInfo implements Closeable {
|
|
|
|
<span class="fc" id="L211"> private static final Comparator<String> nullableCaseInsensitiveComparator = Comparator</span>
|
|
<span class="fc" id="L212"> .nullsFirst(String.CASE_INSENSITIVE_ORDER);</span>
|
|
|
|
private final int statusCode;
|
|
@Nonnull
|
|
private final GitHubRequest request;
|
|
@Nonnull
|
|
private final Map<String, List<String>> headers;
|
|
|
|
protected ResponseInfo(@Nonnull GitHubRequest request,
|
|
int statusCode,
|
|
<span class="fc" id="L222"> @Nonnull Map<String, List<String>> headers) {</span>
|
|
<span class="fc" id="L223"> this.request = request;</span>
|
|
<span class="fc" id="L224"> this.statusCode = statusCode;</span>
|
|
|
|
// Response header field names must be case-insensitive.
|
|
<span class="fc" id="L227"> TreeMap<String, List<String>> caseInsensitiveMap = new TreeMap<>(nullableCaseInsensitiveComparator);</span>
|
|
<span class="fc" id="L228"> caseInsensitiveMap.putAll(headers);</span>
|
|
|
|
<span class="fc" id="L230"> this.headers = Collections.unmodifiableMap(caseInsensitiveMap);</span>
|
|
<span class="fc" id="L231"> }</span>
|
|
|
|
/**
|
|
* Gets the value of a header field for this response.
|
|
*
|
|
* @param name
|
|
* the name of the header field.
|
|
* @return the value of the header field, or {@code null} if the header isn't set.
|
|
*/
|
|
@CheckForNull
|
|
public String headerField(String name) {
|
|
<span class="fc" id="L242"> String result = null;</span>
|
|
<span class="fc bfc" id="L243" title="All 2 branches covered."> if (headers.containsKey(name)) {</span>
|
|
<span class="fc" id="L244"> result = headers.get(name).get(0);</span>
|
|
}
|
|
<span class="fc" id="L246"> return result;</span>
|
|
}
|
|
|
|
/**
|
|
* The response body as an {@link InputStream}.
|
|
*
|
|
* @return the response body
|
|
* @throws IOException
|
|
* if an I/O Exception occurs.
|
|
*/
|
|
abstract InputStream bodyStream() throws IOException;
|
|
|
|
/**
|
|
* The error message for this response.
|
|
*
|
|
* @return if there is an error with some error string, that is returned. If not, {@code null}.
|
|
*/
|
|
abstract String errorMessage();
|
|
|
|
/**
|
|
* The {@link URL} for this response.
|
|
*
|
|
* @return the {@link URL} for this response.
|
|
*/
|
|
@Nonnull
|
|
public URL url() {
|
|
<span class="fc" id="L272"> return request.url();</span>
|
|
}
|
|
|
|
/**
|
|
* Gets the {@link GitHubRequest} for this response.
|
|
*
|
|
* @return the {@link GitHubRequest} for this response.
|
|
*/
|
|
@Nonnull
|
|
public GitHubRequest request() {
|
|
<span class="fc" id="L282"> return request;</span>
|
|
}
|
|
|
|
/**
|
|
* The status code for this response.
|
|
*
|
|
* @return the status code for this response.
|
|
*/
|
|
public int statusCode() {
|
|
<span class="fc" id="L291"> return statusCode;</span>
|
|
}
|
|
|
|
/**
|
|
* The headers for this response.
|
|
*
|
|
* @return the headers for this response.
|
|
*/
|
|
@Nonnull
|
|
public Map<String, List<String>> headers() {
|
|
<span class="fc" id="L301"> return headers;</span>
|
|
}
|
|
|
|
/**
|
|
* Gets the body of the response as a {@link String}.
|
|
*
|
|
* @return the body of the response as a {@link String}.
|
|
* @throws IOException
|
|
* if an I/O Exception occurs.
|
|
*/
|
|
@Nonnull
|
|
String getBodyAsString() throws IOException {
|
|
<span class="fc" id="L313"> InputStreamReader r = null;</span>
|
|
<span class="fc" id="L314"> r = new InputStreamReader(this.bodyStream(), StandardCharsets.UTF_8);</span>
|
|
<span class="fc" id="L315"> return IOUtils.toString(r);</span>
|
|
}
|
|
}
|
|
|
|
}
|
|
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.7.202105040129</span></div></body></html> |