Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 144 additions & 49 deletions src/main/java/org/kohsuke/github/GHDiscussion.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package org.kohsuke.github;

import com.fasterxml.jackson.annotation.JacksonInject;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.net.URL;
import java.util.Objects;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/**
* A discussion in GitHub Team.
Expand All @@ -15,29 +21,31 @@ public class GHDiscussion extends GHObject {

@JacksonInject
private GitHub root;
private GHOrganization organization;
private GHTeam team;
private String number, body, title, htmlUrl;
private long number;
private String body, title, htmlUrl;

@JsonProperty(value = "private")
private boolean isPrivate;

@Override
public URL getHtmlUrl() throws IOException {
return GitHubClient.parseURL(htmlUrl);
}

public GHDiscussion wrapUp(GHTeam team) throws IOException {
this.organization = team.getOrganization();
GHDiscussion wrapUp(GHTeam team) {
this.team = team;
return this;
}

public GHDiscussion wrapUp(GitHub root) {
this.root = root;
return this;
}

public GHDiscussion wrapUp(GHOrganization owner) {
this.organization = owner;
return this;
/**
* Get the team to which this discussion belongs.
*
* @return the team for this discussion
*/
@Nonnull
public GHTeam getTeam() {
return team;
}

/**
Expand All @@ -63,68 +71,155 @@ public String getBody() {
*
* @return the number
*/
public String getNumber() {
public long getNumber() {
return number;
}

/**
* Sets body.
* The id number of this discussion. GitHub discussions have "number" instead of "id". This is provided for
* convenience.
*
* @param body
* the body
* @throws IOException
* the io exception
* @return the id number for this discussion
* @see #getNumber()
*/
public void setBody(String body) throws IOException {
edit("body", body);
@Override
public long getId() {
return getNumber();
}

/**
* Sets title.
* Whether the discussion is private to the team.
*
* @param title
* the title
* @throws IOException
* the io exception
* @return {@code true} if discussion is private.
*/
public void setTitle(String title) throws IOException {
edit("title", title);
public boolean isPrivate() {
return isPrivate;
}

/**
* Edit the discussion
* Begins the creation of a new instance.
*
* @param key
* the key
* @param value
* the value
* Consumer must call {@link GHDiscussion.Creator#done()} to commit changes.
*
* @param team
* the team in which the discussion will be created.
* @return a {@link GHLabel.Creator}
* @throws IOException
* the io exception
*/
private void edit(String key, Object value) throws IOException {
root.createRequest()
.method("PATCH")
// .withPreview(INERTIA)
.with(key, value)
.withUrlPath("/orgs/" + team.getOrganization().getLogin() + "/teams/" + team.getSlug() + "/discussions/"
+ number)
.send();
static GHDiscussion.Creator create(GHTeam team) throws IOException {
return new GHDiscussion.Creator(team);
}

static GHDiscussion read(GHTeam team, long discussionNumber) throws IOException {
return team.root.createRequest()
.setRawUrlPath(getRawUrlPath(team, discussionNumber))
.fetch(GHDiscussion.class)
.wrapUp(team);
}

static PagedIterable<GHDiscussion> readAll(GHTeam team) throws IOException {
return team.root.createRequest()
.setRawUrlPath(getRawUrlPath(team, null))
.toIterable(GHDiscussion[].class, item -> item.wrapUp(team));
}

/**
* Begins a batch update
*
* Consumer must call {@link GHDiscussion.Updater#done()} to commit changes.
*
* @return a {@link GHDiscussion.Updater}
*/
@Preview
@Deprecated
public GHDiscussion.Updater update() {
return new GHDiscussion.Updater(this);
}

/**
* Begins a single property update.
*
* @return a {@link GHDiscussion.Setter}
*/
@Preview
@Deprecated
public GHDiscussion.Setter set() {
return new GHDiscussion.Setter(this);
}

/**
* Delete the discussion
*
* @param number
* the number
* @throws IOException
* the io exception
*/
public void delete(String number) throws IOException {
root.createRequest()
// .withPreview(INERTIA)
.method("DELETE")
.withUrlPath("/orgs/" + team.getOrganization().getLogin() + "/teams/" + team.getSlug() + "/discussions/"
+ number)
.send();
public void delete() throws IOException {
team.root.createRequest().method("DELETE").setRawUrlPath(getRawUrlPath(team, number)).send();
}

@NotNull
private static String getRawUrlPath(@Nonnull GHTeam team, @CheckForNull Long discussionNumber) {
return team.getUrl().toString() + "/discussions" + (discussionNumber == null ? "" : "/" + discussionNumber);
}

/**
* A {@link GHLabelBuilder} that updates a single property per request
*
* {@link #done()} is called automatically after the property is set.
*/
public static class Setter extends GHDiscussionBuilder<GHDiscussion> {
private Setter(@Nonnull GHDiscussion base) {
super(GHDiscussion.class, base.team, base);
requester.method("PATCH").setRawUrlPath(base.getUrl().toString());
}
}

/**
* A {@link GHLabelBuilder} that allows multiple properties to be updated per request.
*
* Consumer must call {@link #done()} to commit changes.
*/
public static class Updater extends GHDiscussionBuilder<Updater> {
private Updater(@Nonnull GHDiscussion base) {
super(GHDiscussion.Updater.class, base.team, base);
requester.method("PATCH").setRawUrlPath(base.getUrl().toString());
}
}

/**
* A {@link GHLabelBuilder} that creates a new {@link GHLabel}
*
* Consumer must call {@link #done()} to create the new instance.
*/
public static class Creator extends GHDiscussionBuilder<Creator> {

private Creator(@Nonnull GHTeam team) {
super(GHDiscussion.Creator.class, team, null);
requester.method("POST").setRawUrlPath(getRawUrlPath(team, null));
}

@Nonnull
public Creator private_(boolean value) throws IOException {
return with("private", value);
}
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GHDiscussion that = (GHDiscussion) o;
return number == that.number && Objects.equals(getUrl(), that.getUrl()) && Objects.equals(team, that.team)
&& Objects.equals(body, that.body) && Objects.equals(title, that.title);
}

@Override
public int hashCode() {
return Objects.hash(team, number, body, title);
}
}
111 changes: 44 additions & 67 deletions src/main/java/org/kohsuke/github/GHDiscussionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,96 +2,73 @@

import java.io.IOException;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/**
* Creates a Discussion.
* Base class for creating or updating a discussion.
*
* https://developer.github.com/v3/teams/discussions/#create-a-discussion
* @param <S>
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If {@link S}
* the same as {@link GHLabel}, this builder will commit changes after each call to
* {@link #with(String, Object)}.
*/
public class GHDiscussionBuilder {
class GHDiscussionBuilder<S> extends AbstractBuilder<GHDiscussion, S> {

protected final Requester builder;
private final GHTeam team;

public GHDiscussionBuilder(GHTeam team, String title) {
this.team = team;
this.builder = team.root.createRequest();
builder.with("title", title);
}
/**
*
* @param intermediateReturnType
* Intermediate return type for this builder returned by calls to {@link #with(String, Object)}. If
* {@link S} the same as {@link GHDiscussion}, this builder will commit changes after each call to
* {@link #with(String, Object)}.
* @param team
* the GitHub team. Updates will be sent to the root of this team.
* @param baseInstance
* instance on which to base this builder. If {@code null} a new instance will be created.
*/
protected GHDiscussionBuilder(@Nonnull Class<S> intermediateReturnType,
@Nonnull GHTeam team,
@CheckForNull GHDiscussion baseInstance) {
super(GHDiscussion.class, intermediateReturnType, team.root, baseInstance);

public GHDiscussionBuilder(GHTeam team) {
this.team = team;
this.builder = team.root.createRequest();

if (baseInstance != null) {
requester.with("title", baseInstance.getTitle());
requester.with("body", baseInstance.getBody());
}
}

/**
* Title for this discussion.
*
* @param title
* @param value
* title of discussion
* @return a builder to continue with building
* @return either a continuing builder or an updated {@link GHDiscussion}
*/
public GHDiscussionBuilder title(String title) {
this.builder.with("title", title);
return this;
@Nonnull
public S title(String value) throws IOException {
return with("title", value);
}

/**
* Body content for this discussion.
*
* @param body
* title of discussion
* @return a builder to continue with building
*/
public GHDiscussionBuilder body(String body) {
this.builder.with("body", body);
return this;
}

/**
* Creates a discussion with all the parameters.
*
* @return the gh discussion
* @throws IOException
* if discussion cannot be created
*/
public GHDiscussion create() throws IOException {
return builder.method("POST")
.withUrlPath("/orgs/" + team.getOrganization().getLogin() + "/teams/" + team.getSlug() + "/discussions")
.fetch(GHDiscussion.class)
.wrapUp(team);
}

/**
* Update a discussion with all the parameters.
* @param value
* body of discussion
*
* @param number
* number of the discussion to be updated
* @return the gh discussion
* @return either a continuing builder or an updated {@link GHDiscussion}
*/
public GHDiscussion update(String number) {
try {
return builder.method("PATCH")
.withUrlPath("/orgs/" + team.getOrganization().getLogin() + "/teams/" + team.getSlug()
+ "/discussions/" + number)
.fetch(GHDiscussion.class)
.wrapUp(team);
} catch (IOException e) {
throw new GHException("Discussion to be updated not found", e);
}
@Nonnull
public S body(String value) throws IOException {
return with("body", value);
}

/**
* Delete this discussion from the team.
*
* @param number
* number of the discussion
* @throws IOException
* the io exception
*/
public void delete(String number) throws IOException {
builder.method("DELETE")
.withUrlPath("/orgs/" + team.getOrganization().getLogin() + "/teams/" + team.getSlug() + "/discussions/"
+ number)
.send();
@Nonnull
@Override
public GHDiscussion done() throws IOException {
return super.done().wrapUp(team);
}
}
Loading