Merge pull request #720 from bitwiseman/task/inject-root

Enable injection of GitHub and other values into mapping
This commit is contained in:
Liam Newman
2020-02-28 14:38:09 -08:00
committed by GitHub
8 changed files with 104 additions and 55 deletions

View File

@@ -142,7 +142,7 @@ public class GHEventInfo {
* if payload cannot be parsed
*/
public <T extends GHEventPayload> T getPayload(Class<T> type) throws IOException {
T v = GitHubClient.getMappingObjectReader().readValue(payload.traverse(), type);
T v = GitHubClient.getMappingObjectReader(root).readValue(payload.traverse(), type);
v.wrapUp(root);
return v;
}

View File

@@ -1,12 +1,13 @@
package org.kohsuke.github;
import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -19,8 +20,9 @@ import java.util.Map.Entry;
* @see <a href="https://developer.github.com/v3/gists/">documentation</a>
*/
public class GHGist extends GHObject {
/* package almost final */ GHUser owner;
/* package almost final */ GitHub root;
final GHUser owner;
final GitHub root;
private String forks_url, commits_url, id, git_pull_url, git_push_url, html_url;
@@ -33,7 +35,19 @@ public class GHGist extends GHObject {
private String comments_url;
private Map<String, GHGistFile> files = new HashMap<String, GHGistFile>();
private final Map<String, GHGistFile> files;
@JsonCreator
private GHGist(@JacksonInject GitHub root,
@JsonProperty("owner") GHUser owner,
@JsonProperty("files") Map<String, GHGistFile> files) {
this.root = root;
for (Entry<String, GHGistFile> e : files.entrySet()) {
e.getValue().fileName = e.getKey();
}
this.files = Collections.unmodifiableMap(files);
this.owner = root.getUser(owner);
}
/**
* Gets owner.
@@ -43,7 +57,7 @@ public class GHGist extends GHObject {
* the io exception
*/
public GHUser getOwner() throws IOException {
return root.intern(owner);
return owner;
}
/**
@@ -139,31 +153,7 @@ public class GHGist extends GHObject {
* @return the files
*/
public Map<String, GHGistFile> getFiles() {
return Collections.unmodifiableMap(files);
}
GHGist wrapUp(GHUser owner) {
this.owner = owner;
this.root = owner.root;
wrapUp();
return this;
}
/**
* Used when caller obtains {@link GHGist} without knowing its owner. A partially constructed owner object is
* interned.
*/
GHGist wrapUp(GitHub root) {
this.owner = root.getUser(owner);
this.root = root;
wrapUp();
return this;
}
private void wrapUp() {
for (Entry<String, GHGistFile> e : files.entrySet()) {
e.getValue().fileName = e.getKey();
}
return files;
}
String getApiTailUrl(String tail) {
@@ -213,7 +203,7 @@ public class GHGist extends GHObject {
* the io exception
*/
public GHGist fork() throws IOException {
return root.createRequest().method("POST").withUrlPath(getApiTailUrl("forks")).fetch(GHGist.class).wrapUp(root);
return root.createRequest().method("POST").withUrlPath(getApiTailUrl("forks")).fetch(GHGist.class);
}
/**
@@ -222,9 +212,7 @@ public class GHGist extends GHObject {
* @return the paged iterable
*/
public PagedIterable<GHGist> listForks() {
return root.createRequest()
.withUrlPath(getApiTailUrl("forks"))
.toIterable(GHGist[].class, item -> item.wrapUp(root));
return root.createRequest().withUrlPath(getApiTailUrl("forks")).toIterable(GHGist[].class, null);
}
/**
@@ -263,10 +251,4 @@ public class GHGist extends GHObject {
public int hashCode() {
return id.hashCode();
}
GHGist wrap(GHUser owner) {
this.owner = owner;
this.root = owner.root;
return this;
}
}

View File

@@ -72,6 +72,6 @@ public class GHGistBuilder {
*/
public GHGist create() throws IOException {
req.with("files", files);
return req.withUrlPath("/gists").fetch(GHGist.class).wrapUp(root);
return req.withUrlPath("/gists").fetch(GHGist.class);
}
}

View File

@@ -94,6 +94,6 @@ public class GHGistUpdater {
*/
public GHGist update() throws IOException {
builder.with("files", files);
return builder.method("PATCH").withUrlPath(base.getApiTailUrl("")).fetch(GHGist.class).wrap(base.owner);
return builder.method("PATCH").withUrlPath(base.getApiTailUrl("")).fetch(GHGist.class);
}
}

View File

@@ -217,7 +217,7 @@ public class GHUser extends GHPerson {
public PagedIterable<GHGist> listGists() throws IOException {
return root.createRequest()
.withUrlPath(String.format("/users/%s/gists", login))
.toIterable(GHGist[].class, item -> item.wrapUp(this));
.toIterable(GHGist[].class, null);
}
@Override

View File

@@ -743,7 +743,7 @@ public class GitHub {
* the io exception
*/
public GHGist getGist(String id) throws IOException {
return createRequest().withUrlPath("/gists/" + id).fetch(GHGist.class).wrapUp(this);
return createRequest().withUrlPath("/gists/" + id).fetch(GHGist.class);
}
/**
@@ -772,7 +772,7 @@ public class GitHub {
* the io exception
*/
public <T extends GHEventPayload> T parseEventPayload(Reader r, Class<T> type) throws IOException {
T t = GitHubClient.getMappingObjectReader().forType(type).readValue(r);
T t = GitHubClient.getMappingObjectReader(this).forType(type).readValue(r);
t.wrapUp(this);
return t;
}
@@ -1184,7 +1184,7 @@ public class GitHub {
@Nonnull
Requester createRequest() {
return new Requester(client);
return new Requester(client).injectMappingValue(this);
}
GHUser intern(GHUser user) throws IOException {

View File

@@ -706,11 +706,16 @@ abstract class GitHubClient {
/**
* Helper for {@link #getMappingObjectReader(GitHubResponse.ResponseInfo)}
*
* @param root
* the root GitHub object for this reader
*
* @return an {@link ObjectReader} instance that can be further configured.
*/
@Nonnull
static ObjectReader getMappingObjectReader() {
return getMappingObjectReader(null);
static ObjectReader getMappingObjectReader(@Nonnull GitHub root) {
ObjectReader reader = getMappingObjectReader((GitHubResponse.ResponseInfo) null);
((InjectableValues.Std) reader.getInjectableValues()).addValue(GitHub.class, root);
return reader;
}
/**
@@ -724,13 +729,21 @@ abstract class GitHubClient {
*
* @param responseInfo
* the {@link GitHubResponse.ResponseInfo} to inject for this reader.
*
* @return an {@link ObjectReader} instance that can be further configured.
*/
@Nonnull
static ObjectReader getMappingObjectReader(@CheckForNull GitHubResponse.ResponseInfo responseInfo) {
InjectableValues.Std inject = new InjectableValues.Std();
inject.addValue(GitHubResponse.ResponseInfo.class, responseInfo);
Map<String, Object> injected = new HashMap<>();
return MAPPER.reader(inject);
// Required or many things break
injected.put(GitHubResponse.ResponseInfo.class.getName(), null);
injected.put(GitHub.class.getName(), null);
if (responseInfo != null) {
injected.put(GitHubResponse.ResponseInfo.class.getName(), responseInfo);
injected.putAll(responseInfo.request().injectedMappingValues());
}
return MAPPER.reader(new InjectableValues.Std(injected));
}
}

View File

@@ -1,5 +1,6 @@
package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.NonNull;
import org.apache.commons.lang3.StringUtils;
import java.io.InputStream;
@@ -40,6 +41,7 @@ class GitHubRequest {
private static final List<String> METHODS_WITHOUT_BODY = asList("GET", "DELETE");
private final List<Entry> args;
private final Map<String, String> headers;
private final Map<String, Object> injectedMappingValues;
private final String apiUrl;
private final String urlPath;
private final String method;
@@ -50,6 +52,7 @@ class GitHubRequest {
private GitHubRequest(@Nonnull List<Entry> args,
@Nonnull Map<String, String> headers,
@Nonnull Map<String, Object> injectedMappingValues,
@Nonnull String apiUrl,
@Nonnull String urlPath,
@Nonnull String method,
@@ -57,6 +60,7 @@ class GitHubRequest {
boolean forceBody) throws MalformedURLException {
this.args = Collections.unmodifiableList(new ArrayList<>(args));
this.headers = Collections.unmodifiableMap(new LinkedHashMap<>(headers));
this.injectedMappingValues = Collections.unmodifiableMap(new LinkedHashMap<>(injectedMappingValues));
this.apiUrl = apiUrl;
this.urlPath = urlPath;
this.method = method;
@@ -136,6 +140,16 @@ class GitHubRequest {
return headers;
}
/**
* The headers for this request.
*
* @return the {@link Map} of headers
*/
@Nonnull
public Map<String, Object> injectedMappingValues() {
return injectedMappingValues;
}
/**
* The base GitHub API URL for this request represented as a {@link String}
*
@@ -203,7 +217,7 @@ class GitHubRequest {
* @return a {@link Builder} based on this request.
*/
public Builder<?> toBuilder() {
return new Builder<>(args, headers, apiUrl, urlPath, method, body, forceBody);
return new Builder<>(args, headers, injectedMappingValues, apiUrl, urlPath, method, body, forceBody);
}
private String buildTailApiUrl() {
@@ -248,6 +262,12 @@ class GitHubRequest {
@Nonnull
private final Map<String, String> headers;
/**
* Injected local data map
*/
@Nonnull
private final Map<String, Object> injectedMappingValues;
/**
* The base GitHub API for this request.
*/
@@ -268,11 +288,19 @@ class GitHubRequest {
* Create a new {@link GitHubRequest.Builder}
*/
protected Builder() {
this(new ArrayList<>(), new LinkedHashMap<>(), GitHubClient.GITHUB_URL, "/", "GET", null, false);
this(new ArrayList<>(),
new LinkedHashMap<>(),
new LinkedHashMap<>(),
GitHubClient.GITHUB_URL,
"/",
"GET",
null,
false);
}
private Builder(@Nonnull List<Entry> args,
@Nonnull Map<String, String> headers,
@Nonnull Map<String, Object> injectedMappingValues,
@Nonnull String apiUrl,
@Nonnull String urlPath,
@Nonnull String method,
@@ -280,6 +308,7 @@ class GitHubRequest {
boolean forceBody) {
this.args = new ArrayList<>(args);
this.headers = new LinkedHashMap<>(headers);
this.injectedMappingValues = new LinkedHashMap<>(injectedMappingValues);
this.apiUrl = apiUrl;
this.urlPath = urlPath;
this.method = method;
@@ -295,7 +324,7 @@ class GitHubRequest {
* if the GitHub API URL cannot be constructed
*/
public GitHubRequest build() throws MalformedURLException {
return new GitHubRequest(args, headers, apiUrl, urlPath, method, body, forceBody);
return new GitHubRequest(args, headers, injectedMappingValues, apiUrl, urlPath, method, body, forceBody);
}
/**
@@ -338,6 +367,31 @@ class GitHubRequest {
return (B) this;
}
/**
* Object to inject into binding.
*
* @param value
* the value
* @return the request builder
*/
public B injectMappingValue(@NonNull Object value) {
return injectMappingValue(value.getClass().getName(), value);
}
/**
* Object to inject into binding.
*
* @param name
* the name
* @param value
* the value
* @return the request builder
*/
public B injectMappingValue(@NonNull String name, Object value) {
this.injectedMappingValues.put(name, value);
return (B) this;
}
public B withPreview(String name) {
return withHeader("Accept", name);
}