package org.kohsuke.github; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.FileNotFoundException; import java.io.IOException; import java.net.URL; import java.util.Date; /** * A conversation in the notification API. * * @author Kohsuke Kawaguchi * @see documentation * @see GHNotificationStream */ @SuppressFBWarnings(value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" }, justification = "JSON API") public class GHThread extends GHObject { private GHRepository repository; private Subject subject; private String reason; private boolean unread; private String last_read_at; private String url, subscription_url; static class Subject { String title; String url; String latest_comment_url; String type; } private GHThread() {// no external construction allowed } /** * Returns null if the entire thread has never been read. * * @return the last read at */ public Date getLastReadAt() { return GitHubClient.parseDate(last_read_at); } /** * @deprecated This object has no HTML URL. */ @Override public URL getHtmlUrl() { return null; } /** * Gets reason. * * @return the reason */ public String getReason() { return reason; } /** * Gets repository. * * @return the repository */ public GHRepository getRepository() { return repository; } // TODO: how to expose the subject? /** * Is read boolean. * * @return the boolean */ public boolean isRead() { return !unread; } /** * Gets title. * * @return the title */ public String getTitle() { return subject.title; } /** * Gets type. * * @return the type */ public String getType() { return subject.type; } /** * Gets last comment url. * * @return the last comment url */ public String getLastCommentUrl() { return subject.latest_comment_url; } /** * If this thread is about an issue, return that issue. * * @return null if this thread is not about an issue. * @throws IOException * the io exception */ public GHIssue getBoundIssue() throws IOException { if (!"Issue".equals(subject.type) && "PullRequest".equals(subject.type)) return null; return repository.getIssue(Integer.parseInt(subject.url.substring(subject.url.lastIndexOf('/') + 1))); } /** * If this thread is about a pull request, return that pull request. * * @return null if this thread is not about a pull request. * @throws IOException * the io exception */ public GHPullRequest getBoundPullRequest() throws IOException { if (!"PullRequest".equals(subject.type)) return null; return repository.getPullRequest(Integer.parseInt(subject.url.substring(subject.url.lastIndexOf('/') + 1))); } /** * If this thread is about a commit, return that commit. * * @return null if this thread is not about a commit. * @throws IOException * the io exception */ public GHCommit getBoundCommit() throws IOException { if (!"Commit".equals(subject.type)) return null; return repository.getCommit(subject.url.substring(subject.url.lastIndexOf('/') + 1)); } GHThread wrap(GitHub root) { this.root = root; if (this.repository != null) this.repository.wrap(root); return this; } /** * Marks this thread as read. * * @throws IOException * the io exception */ public void markAsRead() throws IOException { root.createRequest().method("PATCH").withUrlPath(url).send(); } /** * Subscribes to this conversation to get notifications. * * @param subscribed * the subscribed * @param ignored * the ignored * @return the gh subscription * @throws IOException * the io exception */ public GHSubscription subscribe(boolean subscribed, boolean ignored) throws IOException { return root.createRequest() .method("PUT") .with("subscribed", subscribed) .with("ignored", ignored) .withUrlPath(subscription_url) .fetch(GHSubscription.class) .wrapUp(root); } /** * Returns the current subscription for this thread. * * @return null if no subscription exists. * @throws IOException * the io exception */ public GHSubscription getSubscription() throws IOException { try { return root.createRequest() .method("POST") .withUrlPath(subscription_url) .fetch(GHSubscription.class) .wrapUp(root); } catch (FileNotFoundException e) { return null; } } }