Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Sawicki2011-05-12 00:59:05 +0000
committerKevin Sawicki2011-05-12 00:59:05 +0000
commit0d93fc473545becca69c0595289ac472afaea68f (patch)
treed13058e842837a7feb2375cb0a48c798976570ae /org.eclipse.egit.github.core
parent31e119034516c7674964a6c7c87fedefd57376b8 (diff)
downloadegit-github-0d93fc473545becca69c0595289ac472afaea68f.tar.gz
egit-github-0d93fc473545becca69c0595289ac472afaea68f.tar.xz
egit-github-0d93fc473545becca69c0595289ac472afaea68f.zip
Add new core GitHub API plug-in and unit tests.
This moves the current API unit tests from the mylyn test plug-in and creates a new package of live tests that can be run directly against a GitHub instance. The new core API plug-in has no Eclipse dependencies and only relies on GSON and Apache Commons HTTP client. Change-Id: I2b4dc436760818e5fcf1503f7ba80e351aca4fb6 Signed-off-by: Kevin Sawicki <kevin@github.com>
Diffstat (limited to 'org.eclipse.egit.github.core')
-rw-r--r--org.eclipse.egit.github.core/.classpath7
-rw-r--r--org.eclipse.egit.github.core/.gitignore2
-rw-r--r--org.eclipse.egit.github.core/.project28
-rw-r--r--org.eclipse.egit.github.core/.settings/org.eclipse.jdt.core.prefs8
-rw-r--r--org.eclipse.egit.github.core/META-INF/MANIFEST.MF19
-rw-r--r--org.eclipse.egit.github.core/build.properties5
-rw-r--r--org.eclipse.egit.github.core/plugin.properties2
-rw-r--r--org.eclipse.egit.github.core/pom.xml26
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Assert.java69
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Comment.java69
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/FieldError.java75
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Gist.java189
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistChangeStatus.java45
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistFile.java70
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistRevision.java66
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceCollector.java31
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceProvider.java30
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Id.java29
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Issue.java201
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Label.java79
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/ListResourceCollector.java54
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Milestone.java122
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequest.java204
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestDiscussion.java188
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestMarker.java62
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Repository.java276
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/RequestError.java43
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/User.java119
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/DateFormatter.java68
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java344
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubRequest.java101
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java80
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/IGitHubConstants.java178
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java112
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PagedRequest.java44
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/RequestException.java62
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GistService.java159
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GitHubService.java76
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java276
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/LabelService.java108
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/MilestoneService.java68
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/PullRequestService.java109
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/RepositoryService.java95
-rw-r--r--org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/util/LabelComparator.java36
44 files changed, 4034 insertions, 0 deletions
diff --git a/org.eclipse.egit.github.core/.classpath b/org.eclipse.egit.github.core/.classpath
new file mode 100644
index 00000000..ad32c83a
--- /dev/null
+++ b/org.eclipse.egit.github.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.egit.github.core/.gitignore b/org.eclipse.egit.github.core/.gitignore
new file mode 100644
index 00000000..d567ba01
--- /dev/null
+++ b/org.eclipse.egit.github.core/.gitignore
@@ -0,0 +1,2 @@
+bin
+target
diff --git a/org.eclipse.egit.github.core/.project b/org.eclipse.egit.github.core/.project
new file mode 100644
index 00000000..f139a16d
--- /dev/null
+++ b/org.eclipse.egit.github.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.egit.github.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.egit.github.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.egit.github.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..0d90fbeb
--- /dev/null
+++ b/org.eclipse.egit.github.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Wed May 11 10:19:26 PDT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/org.eclipse.egit.github.core/META-INF/MANIFEST.MF b/org.eclipse.egit.github.core/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..fda2872b
--- /dev/null
+++ b/org.eclipse.egit.github.core/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-Localization: plugin
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.egit.github.core
+Bundle-Version: 0.1.0.qualifier
+Bundle-Vendor: %providerName
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Import-Package: com.google.gson;version="1.6.0",
+ com.google.gson.annotations;version="1.6.0",
+ com.google.gson.reflect;version="1.6.0",
+ org.apache.commons.httpclient;version="3.1.0",
+ org.apache.commons.httpclient.auth;version="3.1.0",
+ org.apache.commons.httpclient.methods;version="3.1.0",
+ org.apache.commons.httpclient.protocol;version="3.1.0"
+Export-Package: org.eclipse.egit.github.core,
+ org.eclipse.egit.github.core.client,
+ org.eclipse.egit.github.core.service,
+ org.eclipse.egit.github.core.util
diff --git a/org.eclipse.egit.github.core/build.properties b/org.eclipse.egit.github.core/build.properties
new file mode 100644
index 00000000..aa1a0082
--- /dev/null
+++ b/org.eclipse.egit.github.core/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties
diff --git a/org.eclipse.egit.github.core/plugin.properties b/org.eclipse.egit.github.core/plugin.properties
new file mode 100644
index 00000000..19877154
--- /dev/null
+++ b/org.eclipse.egit.github.core/plugin.properties
@@ -0,0 +1,2 @@
+pluginName=EGit GitHub API Core (Incubation)
+providerName=Eclipse EGit \ No newline at end of file
diff --git a/org.eclipse.egit.github.core/pom.xml b/org.eclipse.egit.github.core/pom.xml
new file mode 100644
index 00000000..7c2a8462
--- /dev/null
+++ b/org.eclipse.egit.github.core/pom.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2011, Chris Aniszczyk <caniszczyk@gmail.com>
+
+ All rights reserved. This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.eclipse.mylyn.github</groupId>
+ <artifactId>github-parent</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>org.eclipse.egit.github.core</artifactId>
+ <packaging>eclipse-plugin</packaging>
+ <name>Eclipse EGit GitHub API Core (Incubation)</name>
+ <version>0.1.0-SNAPSHOT</version>
+</project>
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Assert.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Assert.java
new file mode 100644
index 00000000..52663c0d
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Assert.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+/**
+ *
+ */
+public abstract class Assert {
+
+ /**
+ * Throw an {@link IllegalArgumentException} if the specified object is
+ * null.
+ *
+ * @param message
+ * @param object
+ * @throws IllegalArgumentException
+ */
+ public static void notNull(String message, Object object)
+ throws IllegalArgumentException {
+ if (object == null)
+ throw new IllegalArgumentException(message);
+ }
+
+ /**
+ * Throw an {@link IllegalArgumentException} if the specified object is
+ * null.
+ *
+ * @param object
+ * @throws IllegalArgumentException
+ */
+ public static void notNull(Object object) throws IllegalArgumentException {
+ notNull("Illegal null argument", object); //$NON-NLS-1$
+ }
+
+ /**
+ * Throw an {@link IllegalArgumentException} if the specified string is
+ * empty. This method does not check if the string is null.
+ * {@link #notNull(Object)} should be used to first assert the string is
+ * non-null if that is a requirement of the argument.
+ *
+ * @param message
+ * @param string
+ * @throws IllegalArgumentException
+ */
+ public static void notEmpty(String message, String string)
+ throws IllegalArgumentException {
+ if (string.length() == 0)
+ throw new IllegalArgumentException(message);
+ }
+
+ /**
+ * Throw an {@link IllegalArgumentException} if the specified string is null
+ * or empty.
+ *
+ * @param string
+ * @throws IllegalArgumentException
+ */
+ public static void notEmpty(String string) throws IllegalArgumentException {
+ notEmpty("Illegal empty string argument", string); //$NON-NLS-1$
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Comment.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Comment.java
new file mode 100644
index 00000000..3f1d109d
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Comment.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Date;
+
+/**
+ * GitHub issue comment class.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class Comment {
+
+ private Date createdAt;
+
+ private Date updatedAt;
+
+ private String body;
+
+ private String url;
+
+ private User user;
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt != null ? new Date(this.createdAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return updatedAt
+ */
+ public Date getUpdatedAt() {
+ return this.updatedAt != null ? new Date(this.updatedAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return body
+ */
+ public String getBody() {
+ return this.body;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/FieldError.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/FieldError.java
new file mode 100644
index 00000000..8440e63b
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/FieldError.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+
+/**
+ * Field error
+ */
+public class FieldError {
+
+ /**
+ * CODE_INVALID
+ */
+ public static final String CODE_INVALID = "invalid"; //$NON-NLS-1$
+
+ /**
+ * CODE_MISSING
+ */
+ public static final String CODE_MISSING = "missing"; //$NON-NLS-1$
+
+ /**
+ * CODE_MISSING_FIELD
+ */
+ public static final String CODE_MISSING_FIELD = "missing_field"; //$NON-NLS-1$
+
+ /**
+ * CODE_ALREADY_EXISTS
+ */
+ public static final String CODE_ALREADY_EXISTS = "already_exists"; //$NON-NLS-1$
+
+ private String code;
+
+ private String field;
+
+ private String resource;
+
+ private String value;
+
+ /**
+ * @return code
+ */
+ public String getCode() {
+ return this.code;
+ }
+
+ /**
+ * @return field
+ */
+ public String getField() {
+ return this.field;
+ }
+
+ /**
+ * @return resource
+ */
+ public String getResource() {
+ return this.resource;
+ }
+
+ /**
+ * @return value
+ */
+ public String getValue() {
+ return this.value;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Gist.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Gist.java
new file mode 100644
index 00000000..bc2ff35a
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Gist.java
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * GitHub gist class.
+ */
+public class Gist {
+
+ @SerializedName("public")
+ private boolean isPublic;
+
+ private Date createdAt;
+
+ private Date updatedAt;
+
+ private int comments;
+
+ private List<GistRevision> history;
+
+ private Map<String, GistFile> files;
+
+ private String description;
+
+ private String gitPullUrl;
+
+ private String gitPushUrl;
+
+ private String htmlUrl;
+
+ private String id;
+
+ private String url;
+
+ private User user;
+
+ /**
+ * @return isPublic
+ */
+ public boolean isPublic() {
+ return this.isPublic;
+ }
+
+ /**
+ * @param isPublic
+ * @return this gist
+ */
+ public Gist setPublic(boolean isPublic) {
+ this.isPublic = isPublic;
+ return this;
+ }
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt != null ? new Date(this.createdAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return comments
+ */
+ public int getComments() {
+ return this.comments;
+ }
+
+ /**
+ * @return files
+ */
+ public Map<String, GistFile> getFiles() {
+ return this.files;
+ }
+
+ /**
+ * @param files
+ * @return this gist
+ */
+ public Gist setFiles(Map<String, GistFile> files) {
+ this.files = files;
+ return this;
+ }
+
+ /**
+ * @return description
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * @param description
+ * @return this gist
+ */
+ public Gist setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ /**
+ * @return gitPullUrl
+ */
+ public String getGitPullUrl() {
+ return this.gitPullUrl;
+ }
+
+ /**
+ * @return gitPushUrl
+ */
+ public String getGitPushUrl() {
+ return this.gitPushUrl;
+ }
+
+ /**
+ * @return history
+ */
+ public List<GistRevision> getHistory() {
+ return this.history;
+ }
+
+ /**
+ * @return htmlUrl
+ */
+ public String getHtmlUrl() {
+ return this.htmlUrl;
+ }
+
+ /**
+ * @return id
+ */
+ public String getId() {
+ return this.id;
+ }
+
+ /**
+ * @param id
+ * @return this gist
+ */
+ public Gist setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ /**
+ * @return updatedAt
+ */
+ public Date getUpdatedAt() {
+ return this.updatedAt != null ? new Date(this.updatedAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+ /**
+ * @param user
+ * @return this gist
+ */
+ public Gist setUser(User user) {
+ this.user = user;
+ return this;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistChangeStatus.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistChangeStatus.java
new file mode 100644
index 00000000..b5f90e5d
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistChangeStatus.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+/**
+ * Gist change status class.
+ */
+public class GistChangeStatus {
+
+ private int additions;
+
+ private int deletions;
+
+ private int total;
+
+ /**
+ * @return additions
+ */
+ public int getAdditions() {
+ return this.additions;
+ }
+
+ /**
+ * @return deletions
+ */
+ public int getDeletions() {
+ return this.deletions;
+ }
+
+ /**
+ * @return total
+ */
+ public int getTotal() {
+ return this.total;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistFile.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistFile.java
new file mode 100644
index 00000000..2817993b
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistFile.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+/**
+ * Gist file class.
+ */
+public class GistFile {
+
+ private int size;
+
+ private String content;
+
+ private String filename;
+
+ private String rawUrl;
+
+ /**
+ * @return size
+ */
+ public int getSize() {
+ return this.size;
+ }
+
+ /**
+ * @return content
+ */
+ public String getContent() {
+ return this.content;
+ }
+
+ /**
+ * @param content
+ * @return this gist file
+ */
+ public GistFile setContent(String content) {
+ this.content = content;
+ return this;
+ }
+
+ /**
+ * @return filename
+ */
+ public String getFilename() {
+ return this.filename;
+ }
+
+ /**
+ * @param filename
+ */
+ public void setFilename(String filename) {
+ this.filename = filename;
+ }
+
+ /**
+ * @return rawUrl
+ */
+ public String getRawUrl() {
+ return this.rawUrl;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistRevision.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistRevision.java
new file mode 100644
index 00000000..211cfa68
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/GistRevision.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Date;
+
+/**
+ * Gist revision class.
+ */
+public class GistRevision {
+
+ private Date committedAt;
+
+ private GistChangeStatus changeStatus;
+
+ private String url;
+
+ private String version;
+
+ private User user;
+
+ /**
+ * @return committedAt
+ */
+ public Date getCommittedAt() {
+ return this.committedAt != null ? new Date(this.committedAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return changeStatus
+ */
+ public GistChangeStatus getChangeStatus() {
+ return this.changeStatus;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * @return version
+ */
+ public String getVersion() {
+ return this.version;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceCollector.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceCollector.java
new file mode 100644
index 00000000..273a884f
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceCollector.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Collection;
+
+/**
+ * Interface for accepting collections of resources page by page.
+ *
+ * @param <V>
+ */
+public interface IResourceCollector<V> {
+
+ /**
+ * Accept page response.
+ *
+ * @param page
+ * @param response
+ * @return true to continue collecting, false to abort
+ */
+ boolean accept(int page, Collection<V> response);
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceProvider.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceProvider.java
new file mode 100644
index 00000000..c0fa58da
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/IResourceProvider.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.List;
+
+/**
+ * Interface for container classes that can provide a collection of resources of
+ * the same type.
+ *
+ * @param <V>
+ */
+public interface IResourceProvider<V> {
+
+ /**
+ * Get collection of resources
+ *
+ * @return non-null but possibly empty collection
+ */
+ List<V> getResources();
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Id.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Id.java
new file mode 100644
index 00000000..93660068
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Id.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+/**
+ * Id class.
+ */
+public class Id {
+
+ private String id;
+
+ /**
+ * Get id
+ *
+ * @return id
+ */
+ public String getId() {
+ return this.id;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Issue.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Issue.java
new file mode 100644
index 00000000..4e673053
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Issue.java
@@ -0,0 +1,201 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * GitHub issue class.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class Issue {
+
+ private Date closedAt;
+
+ private Date createdAt;
+
+ private Date updatedAt;
+
+ private int comments;
+
+ private int number;
+
+ private List<Label> labels;
+
+ private Milestone milestone;
+
+ private String body;
+
+ private String htmlUrl;
+
+ private String state;
+
+ private String title;
+
+ private String url;
+
+ private User assignee;
+
+ private User user;
+
+ /**
+ * @return closedAt
+ */
+ public Date getClosedAt() {
+ return this.closedAt != null ? new Date(this.closedAt.getTime()) : null;
+ }
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt != null ? new Date(this.createdAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return updatedAt
+ */
+ public Date getUpdatedAt() {
+ return this.updatedAt != null ? new Date(this.updatedAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return comments
+ */
+ public int getComments() {
+ return this.comments;
+ }
+
+ /**
+ * @return number
+ */
+ public int getNumber() {
+ return this.number;
+ }
+
+ /**
+ * @param number
+ */
+ public void setNumber(int number) {
+ this.number = number;
+ }
+
+ /**
+ * @return labels
+ */
+ public List<Label> getLabels() {
+ return this.labels;
+ }
+
+ /**
+ * @return milestone
+ */
+ public Milestone getMilestone() {
+ return this.milestone;
+ }
+
+ /**
+ * @param milestone
+ * @return this issue
+ */
+ public Issue setMilestone(Milestone milestone) {
+ this.milestone = milestone;
+ return this;
+ }
+
+ /**
+ * @return body
+ */
+ public String getBody() {
+ return this.body;
+ }
+
+ /**
+ * @param body
+ * @return this issue
+ */
+ public Issue setBody(String body) {
+ this.body = body;
+ return this;
+ }
+
+ /**
+ * @return htmlUrl
+ */
+ public String getHtmlUrl() {
+ return this.htmlUrl;
+ }
+
+ /**
+ * @return state
+ */
+ public String getState() {
+ return this.state;
+ }
+
+ /**
+ * @param state
+ */
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ /**
+ * @return title
+ */
+ public String getTitle() {
+ return this.title;
+ }
+
+ /**
+ * @param title
+ * @return this issue
+ */
+ public Issue setTitle(String title) {
+ this.title = title;
+ return this;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * @return assignee
+ */
+ public User getAssignee() {
+ return this.assignee;
+ }
+
+ /**
+ * @param assignee
+ * @return this issue
+ */
+ public Issue setAssignee(User assignee) {
+ this.assignee = assignee;
+ return this;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Label.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Label.java
new file mode 100644
index 00000000..8316dbca
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Label.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+/**
+ * GitHub issue label class.
+ */
+public class Label {
+
+ private String color;
+
+ private String name;
+
+ private String url;
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+
+ return obj instanceof Label && this.name != null
+ && this.name.equals(((Label) obj).name);
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return this.name.hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return this.name;
+ }
+
+ /**
+ * @return color
+ */
+ public String getColor() {
+ return this.color;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * @param name
+ * @return this label
+ */
+ public Label setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/ListResourceCollector.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/ListResourceCollector.java
new file mode 100644
index 00000000..ef81dbc2
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/ListResourceCollector.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * {@link LinkedList} based resource collector
+ *
+ * @param <V>
+ */
+public class ListResourceCollector<V> implements IResourceCollector<V> {
+
+ private List<V> resources = new LinkedList<V>();
+
+ /**
+ * Clear resources from collector
+ *
+ * @return this collector
+ */
+ public ListResourceCollector<V> clear() {
+ this.resources.clear();
+ return this;
+ }
+
+ /**
+ * Get resources
+ *
+ * @return collection of resources
+ */
+ public List<V> getResources() {
+ return this.resources;
+ }
+
+ /**
+ * @see org.eclipse.egit.github.core.IResourceCollector#accept(int,
+ * java.util.Collection)
+ */
+ public boolean accept(int page, Collection<V> resources) {
+ return this.resources.addAll(resources);
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Milestone.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Milestone.java
new file mode 100644
index 00000000..da243dbd
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Milestone.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Date;
+
+/**
+ * GitHub issue milestone class.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class Milestone {
+
+ private Date createdAt;
+
+ private Date dueOn;
+
+ private int closedIssues;
+
+ private int number;
+
+ private int openIssues;
+
+ private String description;
+
+ private String state;
+
+ private String title;
+
+ private String url;
+
+ private User creator;
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt != null ? new Date(this.createdAt.getTime())
+ : null;
+ }
+
+ /**
+ * @return dueOn
+ */
+ public Date getDueOn() {
+ return this.dueOn != null ? new Date(this.dueOn.getTime()) : null;
+ }
+
+ /**
+ * @return closedIssues
+ */
+ public int getClosedIssues() {
+ return this.closedIssues;
+ }
+
+ /**
+ * @return number
+ */
+ public int getNumber() {
+ return this.number;
+ }
+
+ /**
+ * @param number
+ * @return this milestone
+ */
+ public Milestone setNumber(int number) {
+ this.number = number;
+ return this;
+ }
+
+ /**
+ * @return openIssues
+ */
+ public int getOpenIssues() {
+ return this.openIssues;
+ }
+
+ /**
+ * @return description
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * @return state
+ */
+ public String getState() {
+ return this.state;
+ }
+
+ /**
+ * @return title
+ */
+ public String getTitle() {
+ return this.title;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * @return creator
+ */
+ public User getCreator() {
+ return this.creator;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequest.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequest.java
new file mode 100644
index 00000000..3fa65185
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequest.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Pull request model class.
+ */
+public class PullRequest {
+
+ private Date closedAt;
+ private Date createdAt;
+ private Date issueCreatedAt;
+ private Date issueUpdatedAt;
+ private Date mergedAt;
+ private Date updatedAt;
+
+ private double position;
+
+ private int comments;
+ private int number;
+ private int votes;
+
+ private List<PullRequestDiscussion> discussion;
+ private List<String> labels;
+
+ private PullRequestMarker base;
+ private PullRequestMarker head;
+
+ private String body;
+ private String diffUrl;
+ private String htmlUrl;
+ private String patchUrl;
+ private String state;
+ private String title;
+
+ private User issueUser;
+ private User user;
+
+ /**
+ * @return closedAt
+ */
+ public Date getClosedAt() {
+ return this.closedAt;
+ }
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt;
+ }
+
+ /**
+ * @return issueCreatedAt
+ */
+ public Date getIssueCreatedAt() {
+ return this.issueCreatedAt;
+ }
+
+ /**
+ * @return issueUpdatedAt
+ */
+ public Date getIssueUpdatedAt() {
+ return this.issueUpdatedAt;
+ }
+
+ /**
+ * @return mergedAt
+ */
+ public Date getMergedAt() {
+ return this.mergedAt;
+ }
+
+ /**
+ * @return updatedAt
+ */
+ public Date getUpdatedAt() {
+ return this.updatedAt;
+ }
+
+ /**
+ * @return position
+ */
+ public double getPosition() {
+ return this.position;
+ }
+
+ /**
+ * @return comments
+ */
+ public int getComments() {
+ return this.comments;
+ }
+
+ /**
+ * @return number
+ */
+ public int getNumber() {
+ return this.number;
+ }
+
+ /**
+ * @return votes
+ */
+ public int getVotes() {
+ return this.votes;
+ }
+
+ /**
+ * @return discussion
+ */
+ public List<PullRequestDiscussion> getDiscussion() {
+ return this.discussion;
+ }
+
+ /**
+ * @return labels
+ */
+ public List<String> getLabels() {
+ return this.labels;
+ }
+
+ /**
+ * @return base
+ */
+ public PullRequestMarker getBase() {
+ return this.base;
+ }
+
+ /**
+ * @return head
+ */
+ public PullRequestMarker getHead() {
+ return this.head;
+ }
+
+ /**
+ * @return body
+ */
+ public String getBody() {
+ return this.body;
+ }
+
+ /**
+ * @return diffUrl
+ */
+ public String getDiffUrl() {
+ return this.diffUrl;
+ }
+
+ /**
+ * @return htmlUrl
+ */
+ public String getHtmlUrl() {
+ return this.htmlUrl;
+ }
+
+ /**
+ * @return patchUrl
+ */
+ public String getPatchUrl() {
+ return this.patchUrl;
+ }
+
+ /**
+ * @return state
+ */
+ public String getState() {
+ return this.state;
+ }
+
+ /**
+ * @return title
+ */
+ public String getTitle() {
+ return this.title;
+ }
+
+ /**
+ * @return issueUser
+ */
+ public User getIssueUser() {
+ return this.issueUser;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestDiscussion.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestDiscussion.java
new file mode 100644
index 00000000..6581c425
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestDiscussion.java
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Pull request discussion model class.
+ */
+public class PullRequestDiscussion {
+
+ /**
+ * TYPE_COMMIT
+ */
+ public static final String TYPE_COMMIT = "Commit";
+
+ /**
+ * TYPE_ISSUE_COMMENT
+ */
+ public static final String TYPE_ISSUE_COMMENT = "IssueComment";
+
+ private Date authoredDate;
+ private Date commitedDate;
+ private Date createdAt;
+ private Date updatedAt;
+
+ private int position;
+
+ private List<Id> parents;
+
+ private String body;
+ private String commitId;
+ private String id;
+ private String diffHunk;
+ private String gravatarId;
+ private String message;
+ private String originalCommitId;
+ private String path;
+ private String tree;
+ private String type;
+
+ private User author;
+ private User committer;
+ private User user;
+
+ /**
+ * @return authoredDate
+ */
+ public Date getAuthoredDate() {
+ return this.authoredDate;
+ }
+
+ /**
+ * @return commitedDate
+ */
+ public Date getCommitedDate() {
+ return this.commitedDate;
+ }
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt;
+ }
+
+ /**
+ * @return updatedAt
+ */
+ public Date getUpdatedAt() {
+ return this.updatedAt;
+ }
+
+ /**
+ * @return position
+ */
+ public int getPosition() {
+ return this.position;
+ }
+
+ /**
+ * @return parents
+ */
+ public List<Id> getParents() {
+ return this.parents;
+ }
+
+ /**
+ * @return body
+ */
+ public String getBody() {
+ return this.body;
+ }
+
+ /**
+ * @return commitId
+ */
+ public String getCommitId() {
+ return this.commitId;
+ }
+
+ /**
+ * @return id
+ */
+ public String getId() {
+ return this.id;
+ }
+
+ /**
+ * @return diffHunk
+ */
+ public String getDiffHunk() {
+ return this.diffHunk;
+ }
+
+ /**
+ * @return gravatarId
+ */
+ public String getGravatarId() {
+ return this.gravatarId;
+ }
+
+ /**
+ * @return message
+ */
+ public String getMessage() {
+ return this.message;
+ }
+
+ /**
+ * @return originalCommitId
+ */
+ public String getOriginalCommitId() {
+ return this.originalCommitId;
+ }
+
+ /**
+ * @return path
+ */
+ public String getPath() {
+ return this.path;
+ }
+
+ /**
+ * @return tree
+ */
+ public String getTree() {
+ return this.tree;
+ }
+
+ /**
+ * @return type
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * @return author
+ */
+ public User getAuthor() {
+ return this.author;
+ }
+
+ /**
+ * @return committer
+ */
+ public User getCommitter() {
+ return this.committer;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestMarker.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestMarker.java
new file mode 100644
index 00000000..ed7bbff7
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/PullRequestMarker.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+
+/**
+ * Pull request marker model class.
+ */
+public class PullRequestMarker {
+
+ private Repository repository;
+
+ private String label;
+ private String ref;
+ private String sha;
+
+ private User user;
+
+ /**
+ * @return repository
+ */
+ public Repository getRepository() {
+ return this.repository;
+ }
+
+ /**
+ * @return label
+ */
+ public String getLabel() {
+ return this.label;
+ }
+
+ /**
+ * @return ref
+ */
+ public String getRef() {
+ return this.ref;
+ }
+
+ /**
+ * @return sha
+ */
+ public String getSha() {
+ return this.sha;
+ }
+
+ /**
+ * @return user
+ */
+ public User getUser() {
+ return this.user;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Repository.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Repository.java
new file mode 100644
index 00000000..badf1760
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/Repository.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Date;
+
+/**
+ * GitHub Repository class.
+ */
+public class Repository {
+
+ /**
+ * Create repository from url.
+ *
+ * @see Repository#createFromId(String)
+ * @param url
+ * @return repository or null if parsing fails
+ */
+ public static Repository createFromUrl(URL url) {
+ return url != null ? createFromId(url.getPath()) : null;
+ }
+
+ /**
+ * Create repository from id. The id is split on the '/' character and the
+ * last two non-empty segments are interpreted to be the repository owner
+ * and name.
+ *
+ * @param id
+ * @return repository
+ */
+ public static Repository createFromId(String id) {
+ if (id == null)
+ return null;
+ String owner = null;
+ String name = null;
+ String[] segments = id.split("/"); //$NON-NLS-1$
+ for (int i = segments.length - 1; i >= 0; i--)
+ if (segments[i].length() > 0)
+ if (name == null)
+ name = segments[i];
+ else if (owner == null)
+ owner = segments[i];
+ else
+ break;
+
+ return owner != null && name != null ? new Repository(owner, name)
+ : null;
+ }
+
+ /**
+ * Create from string url
+ *
+ * @see Repository#createFromUrl(URL)
+ * @param url
+ * @return repository or null if it could not be parsed from url path
+ */
+ public static Repository createFromUrl(String url) {
+ try {
+ return url != null ? createFromUrl(new URL(url)) : null;
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ private boolean fork;
+ private boolean hasDownloads;
+ private boolean hasIssues;
+ private boolean hasWiki;
+ @SerializedName("private")
+ private boolean isPrivate;
+
+ private Date createdAt;
+ private Date pushedAt;
+
+ private String description;
+ private String homepage;
+ private String language;
+ private String name;
+ private String owner;
+ private String url;
+
+ private int forks;
+ private int openIssues;
+ private int size;
+ private int watchers;
+
+ /**
+ * Create repository with owner and name
+ *
+ * @param owner
+ * @param name
+ */
+ public Repository(String owner, String name) {
+ Assert.notNull("Owner cannot be null", owner); //$NON-NLS-1$
+ Assert.notEmpty("Owner cannot be empty", owner); //$NON-NLS-1$
+ Assert.notNull("Name cannot be null", name); //$NON-NLS-1$
+ Assert.notEmpty("Name cannot be empty", name); //$NON-NLS-1$
+
+ this.owner = owner;
+ this.name = name;
+ }
+
+ /**
+ * Create repository
+ */
+ Repository() {
+
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return getId().hashCode();
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ else if (obj instanceof Repository)
+ return getId().equals(((Repository) obj).getId());
+ else
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return getId();
+ }
+
+ /**
+ * Get unique identifier for repository
+ *
+ * @return id
+ */
+ public String getId() {
+ return this.owner + '/' + this.name;
+ }
+
+ /**
+ * @return owner
+ */
+ public String getOwner() {
+ return this.owner;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * @return fork
+ */
+ public boolean isFork() {
+ return this.fork;
+ }
+
+ /**
+ * @return hasDownloads
+ */
+ public boolean isHasDownloads() {
+ return this.hasDownloads;
+ }
+
+ /**
+ * @return hasIssues
+ */
+ public boolean isHasIssues() {
+ return this.hasIssues;
+ }
+
+ /**
+ * @return hasWiki
+ */
+ public boolean isHasWiki() {
+ return this.hasWiki;
+ }
+
+ /**
+ * @return isPrivate
+ */
+ public boolean isPrivate() {
+ return this.isPrivate;
+ }
+
+ /**
+ * @return createdAt
+ */
+ public Date getCreatedAt() {
+ return this.createdAt;
+ }
+
+ /**
+ * @return pushedAt
+ */
+ public Date getPushedAt() {
+ return this.pushedAt;
+ }
+
+ /**
+ * @return description
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * @return homepage
+ */
+ public String getHomepage() {
+ return this.homepage;
+ }
+
+ /**
+ * @return language
+ */
+ public String getLanguage() {
+ return this.language;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+ /**
+ * @return forks
+ */
+ public int getForks() {
+ return this.forks;
+ }
+
+ /**
+ * @return openIssues
+ */
+ public int getOpenIssues() {
+ return this.openIssues;
+ }
+
+ /**
+ * @return size
+ */
+ public int getSize() {
+ return this.size;
+ }
+
+ /**
+ * @return watchers
+ */
+ public int getWatchers() {
+ return this.watchers;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/RequestError.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/RequestError.java
new file mode 100644
index 00000000..b3e342d8
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/RequestError.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+import java.util.List;
+
+
+/**
+ * GitHub request error class
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class RequestError {
+
+ private String message;
+
+ private List<FieldError> errors;
+
+ /**
+ * @return message
+ */
+ public String getMessage() {
+ return this.message;
+ }
+
+ /**
+ * Get errors
+ *
+ * @return list of errors
+ */
+ public List<FieldError> getErrors() {
+ return this.errors;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/User.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/User.java
new file mode 100644
index 00000000..0397ac11
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/User.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core;
+
+/**
+ * GitHub user class.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class User {
+
+ private String blob;
+
+ private String company;
+
+ private String email;
+
+ private String gravatarUrl;
+
+ private String location;
+
+ private String login;
+
+ private String name;
+
+ private String type;
+
+ private String url;
+
+ /**
+ * @return blob
+ */
+ public String getBlob() {
+ return this.blob;
+ }
+
+ /**
+ * @return company
+ */
+ public String getCompany() {
+ return this.company;
+ }
+
+ /**
+ * @return email
+ */
+ public String getEmail() {
+ return this.email;
+ }
+
+ /**
+ * @return gravatarUrl
+ */
+ public String getGravatarUrl() {
+ return this.gravatarUrl;
+ }
+
+ /**
+ * @return location
+ */
+ public String getLocation() {
+ return this.location;
+ }
+
+ /**
+ * @return login
+ */
+ public String getLogin() {
+ return this.login;
+ }
+
+ /**
+ * @param login
+ * @return this user
+ */
+ public User setLogin(String login) {
+ this.login = login;
+ return this;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * @param name
+ * @return this user
+ */
+ public User setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ /**
+ * @return type
+ */
+ public String getType() {
+ return this.type;
+ }
+
+ /**
+ * @return url
+ */
+ public String getUrl() {
+ return this.url;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/DateFormatter.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/DateFormatter.java
new file mode 100644
index 00000000..f0a2d14e
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/DateFormatter.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+
+import java.lang.reflect.Type;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TimeZone;
+
+
+/**
+ * Formatter for date formats present in the GitHub v2 and v3 API.
+ */
+public class DateFormatter implements JsonDeserializer<Date> {
+
+ private List<DateFormat> formats;
+
+ /**
+ * Create date formatter
+ */
+ public DateFormatter() {
+ this.formats = new LinkedList<DateFormat>();
+ this.formats.add(new SimpleDateFormat(IGitHubConstants.DATE_FORMAT));
+ this.formats
+ .add(new SimpleDateFormat(IGitHubConstants.DATE_FORMAT_V2_1));
+ this.formats
+ .add(new SimpleDateFormat(IGitHubConstants.DATE_FORMAT_V2_2));
+ TimeZone timeZone = TimeZone.getTimeZone("Zulu"); //$NON-NLS-1$
+ for (DateFormat format : this.formats)
+ format.setTimeZone(timeZone);
+ }
+
+ /**
+ * @see com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement,
+ * java.lang.reflect.Type, com.google.gson.JsonDeserializationContext)
+ */
+ public Date deserialize(JsonElement json, Type typeOfT,
+ JsonDeserializationContext context) throws JsonParseException {
+ JsonParseException exception = null;
+ for (DateFormat format : this.formats)
+ try {
+ synchronized (format) {
+ return format.parse(json.getAsString());
+ }
+ } catch (ParseException e) {
+ exception = new JsonParseException(e);
+ }
+ throw exception;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java
new file mode 100644
index 00000000..6ceaed08
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubClient.java
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonParseException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.httpclient.Credentials;
+import org.apache.commons.httpclient.HostConfiguration;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.NameValuePair;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.auth.BasicScheme;
+import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.RequestError;
+
+/**
+ * Client class for interacting with GitHub HTTP/JSON API.
+ */
+public class GitHubClient {
+
+ private static final NameValuePair PER_PAGE_PARAM = new NameValuePair(
+ IGitHubConstants.PARAM_PER_PAGE, Integer.toString(100));
+
+ private static final AuthScope ANY_SCOPE = new AuthScope(
+ AuthScope.ANY_HOST, AuthScope.ANY_PORT);
+
+ private HostConfiguration hostConfig;
+
+ private HttpClient client = new HttpClient();
+
+ private Gson gson = new GsonBuilder()
+ .registerTypeAdapter(Date.class, new DateFormatter())
+ .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
+ .serializeNulls().create();
+
+ private boolean sendCredentials = false;
+
+ /**
+ * Create default client
+ */
+ public GitHubClient() {
+ this.hostConfig = new HostConfiguration();
+ this.hostConfig.setHost(IGitHubConstants.HOST_API, -1,
+ Protocol.getProtocol(IGitHubConstants.PROTOCOL_HTTPS));
+ }
+
+ /**
+ * Create client for configuration
+ *
+ * @param configuration
+ */
+ public GitHubClient(HostConfiguration configuration) {
+ Assert.notNull("Configuration cannot be null", configuration); //$NON-NLS-1$
+ this.hostConfig = configuration;
+ }
+
+ /**
+ * Create standard post method
+ *
+ * @param uri
+ * @return post
+ */
+ protected PostMethod createPost(String uri) {
+ PostMethod method = new PostMethod(uri);
+ setMethodDefaults(method);
+ return method;
+ }
+
+ /**
+ * Create standard post method
+ *
+ * @param uri
+ * @return post
+ */
+ protected PutMethod createPut(String uri) {
+ PutMethod method = new PutMethod(uri);
+ setMethodDefaults(method);
+ return method;
+ }
+
+ /**
+ * Set method defaults
+ *
+ * @param method
+ * @return method
+ */
+ protected HttpMethod setMethodDefaults(HttpMethod method) {
+ if (this.sendCredentials) {
+ method.setDoAuthentication(true);
+ method.getHostAuthState().setPreemptive();
+ method.getHostAuthState().setAuthScheme(new BasicScheme());
+ }
+ return method;
+ }
+
+ /**
+ * Create get method
+ *
+ * @param uri
+ * @return get method
+ */
+ protected GetMethod createGet(String uri) {
+ GetMethod method = new GetMethod(uri);
+ method.setFollowRedirects(true);
+ setMethodDefaults(method);
+ return method;
+ }
+
+ /**
+ * Set credentials
+ *
+ * @param user
+ * @param password
+ */
+ public void setCredentials(String user, String password) {
+ this.sendCredentials = user != null && password != null;
+ Credentials credentials = null;
+ if (this.sendCredentials)
+ credentials = new UsernamePasswordCredentials(user, password);
+ this.client.getState().setCredentials(ANY_SCOPE, credentials);
+ }
+
+ /**
+ * Parse json to specified type
+ *
+ * @param <V>
+ * @param method
+ * @param type
+ * @return type
+ * @throws IOException
+ */
+ protected <V> V parseJson(HttpMethodBase method, Type type)
+ throws IOException {
+ InputStream stream = method.getResponseBodyAsStream();
+ if (stream == null)
+ throw new JsonParseException("Empty body"); //$NON-NLS-1$
+ InputStreamReader reader = new InputStreamReader(stream);
+ try {
+ return this.gson.fromJson(reader, type);
+ } catch (JsonParseException jpe) {
+ jpe.printStackTrace();
+ throw new IOException(jpe);
+ }
+ }
+
+ /**
+ * Get name value pairs for data map.
+ *
+ * @param data
+ * @param page
+ * @return name value pair array
+ */
+ protected NameValuePair[] getPairs(Map<String, String> data, int page) {
+ if (data == null || data.isEmpty())
+ return new NameValuePair[] {
+ new NameValuePair(IGitHubConstants.PARAM_PAGE,
+ Integer.toString(page)), PER_PAGE_PARAM };
+
+ int size = data.containsKey(IGitHubConstants.PARAM_PER_PAGE) ? data
+ .size() : data.size() + 1;
+ NameValuePair[] pairs = new NameValuePair[size];
+ int i = 0;
+ for (Entry<String, String> entry : data.entrySet())
+ pairs[i++] = new NameValuePair(entry.getKey(), entry.getValue());
+ if (i < size)
+ pairs[i] = PER_PAGE_PARAM;
+ return pairs;
+ }
+
+ /**
+ * Get response stream from uri. It is the responsibility of the calling
+ * method to close the returned stream.
+ *
+ * @param request
+ * @return stream
+ * @throws IOException
+ */
+ public InputStream getStream(GitHubRequest request) throws IOException {
+ GetMethod method = createGet(request.getUri());
+ if (method.getQueryString() == null)
+ method.setQueryString(getPairs(request.getParams(),
+ request.getPage()));
+ try {
+ int status = this.client.executeMethod(this.hostConfig, method);
+ switch (status) {
+ case 200:
+ return method.getResponseBodyAsStream();
+ case 400:
+ case 401:
+ case 403:
+ case 404:
+ case 422:
+ case 500:
+ RequestError error = parseJson(method, RequestError.class);
+ throw new RequestException(error, status);
+ default:
+ throw new IOException(method.getStatusText());
+ }
+ } catch (JsonParseException jpe) {
+ throw new IOException(jpe.getMessage());
+ }
+ }
+
+ /**
+ * Get response from uri and bind to specified type
+ *
+ * @param request
+ * @return response
+ * @throws IOException
+ */
+ public GitHubResponse get(GitHubRequest request) throws IOException {
+ GetMethod method = createGet(request.getUri());
+ if (method.getQueryString() == null)
+ method.setQueryString(getPairs(request.getParams(),
+ request.getPage()));
+ try {
+ int status = this.client.executeMethod(this.hostConfig, method);
+ switch (status) {
+ case 200:
+ return new GitHubResponse(method, parseJson(method,
+ request.getType()));
+ case 400:
+ case 401:
+ case 403:
+ case 404:
+ case 422:
+ case 500:
+ RequestError error = parseJson(method, RequestError.class);
+ throw new RequestException(error, status);
+ default:
+ throw new IOException(method.getStatusText());
+ }
+ } catch (JsonParseException jpe) {
+ throw new IOException(jpe.getMessage());
+ } finally {
+ method.releaseConnection();
+ }
+ }
+
+ /**
+ * Send json using specified method
+ *
+ * @param <V>
+ * @param method
+ * @param params
+ * @param type
+ * @return resource
+ * @throws IOException
+ */
+ protected <V> V sendJson(EntityEnclosingMethod method, Object params,
+ Type type) throws IOException {
+ if (params != null) {
+ StringBuilder payload = new StringBuilder();
+ this.gson.toJson(params, payload);
+ method.setRequestEntity(new StringRequestEntity(payload.toString(),
+ IGitHubConstants.CONTENT_TYPE_JSON,
+ IGitHubConstants.CHARSET_UTF8));
+ }
+
+ try {
+ int status = this.client.executeMethod(this.hostConfig, method);
+ switch (status) {
+ case 200:
+ case 201:
+ if (type != null)
+ return parseJson(method, type);
+ case 204:
+ break;
+ case 400:
+ case 401:
+ case 403:
+ case 404:
+ case 422:
+ case 500:
+ RequestError error = parseJson(method, RequestError.class);
+ throw new RequestException(error, status);
+ default:
+ throw new IOException(method.getStatusText());
+ }
+ } finally {
+ method.releaseConnection();
+ }
+ return null;
+ }
+
+ /**
+ * Post data to uri
+ *
+ * @param <V>
+ * @param uri
+ * @param params
+ * @param type
+ * @return response
+ * @throws IOException
+ */
+ public <V> V post(String uri, Object params, Type type) throws IOException {
+ PostMethod method = createPost(uri);
+ return sendJson(method, params, type);
+ }
+
+ /**
+ * Put data to uri
+ *
+ * @param <V>
+ * @param uri
+ * @param params
+ * @param type
+ * @return response
+ * @throws IOException
+ */
+ public <V> V put(String uri, Object params, Type type) throws IOException {
+ PutMethod method = createPut(uri);
+ return sendJson(method, params, type);
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubRequest.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubRequest.java
new file mode 100644
index 00000000..b0196258
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubRequest.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+
+/**
+ * GitHub API request class.
+ */
+public class GitHubRequest {
+
+ private String uri;
+
+ private Map<String, String> params;
+
+ private Type type;
+
+ private int page = 1;
+
+ /**
+ * @return uri
+ */
+ public String getUri() {
+ return this.uri;
+ }
+
+ /**
+ * @param uri
+ * @return this request
+ */
+ public GitHubRequest setUri(StringBuilder uri) {
+ return setUri(uri != null ? uri.toString() : null);
+ }
+
+ /**
+ * @param uri
+ * @return this request
+ */
+ public GitHubRequest setUri(String uri) {
+ this.uri = uri;
+ return this;
+ }
+
+ /**
+ * @return params
+ */
+ public Map<String, String> getParams() {
+ return this.params;
+ }
+
+ /**
+ * @param params
+ * @return this request
+ */
+ public GitHubRequest setParams(Map<String, String> params) {
+ this.params = params;
+ return this;
+ }
+
+ /**
+ * @return type
+ */
+ public Type getType() {
+ return this.type;
+ }
+
+ /**
+ * @param type
+ * @return this request
+ */
+ public GitHubRequest setType(Type type) {
+ this.type = type;
+ return this;
+ }
+
+ /**
+ * @return page
+ */
+ public int getPage() {
+ return this.page;
+ }
+
+ /**
+ * @param page
+ * @return this request
+ */
+ public GitHubRequest setPage(int page) {
+ this.page = page;
+ return this;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java
new file mode 100644
index 00000000..43c2a3d2
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/GitHubResponse.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import org.apache.commons.httpclient.HttpMethod;
+
+/**
+ * GitHub API response class.
+ */
+public class GitHubResponse {
+
+ private PageLinks links;
+
+ private Object body;
+
+ /**
+ * Create response
+ *
+ * @param method
+ * @param body
+ */
+ public GitHubResponse(HttpMethod method, Object body) {
+ links = new PageLinks(method);
+ this.body = body;
+ }
+
+ /**
+ * Get link uri to first page
+ *
+ * @return possibly null uri
+ */
+ public String getFirst() {
+ return this.links.getFirst();
+ }
+
+ /**
+ * Get link uri to previous page
+ *
+ * @return possibly null uri
+ */
+ public String getPrevious() {
+ return this.links.getPrev();
+ }
+
+ /**
+ * Get link uri to next page
+ *
+ * @return possibly null uri
+ */
+ public String getNext() {
+ return this.links.getNext();
+ }
+
+ /**
+ * Get link uri to last page
+ *
+ * @return possibly null uri
+ */
+ public String getLast() {
+ return this.links.getLast();
+ }
+
+ /**
+ * Parsed response body
+ *
+ * @return body
+ */
+ public Object getBody() {
+ return this.body;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/IGitHubConstants.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/IGitHubConstants.java
new file mode 100644
index 00000000..7b0decef
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/IGitHubConstants.java
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+/**
+ * GitHub constants
+ */
+public interface IGitHubConstants {
+
+ /**
+ * REPOS_SEGMENT
+ */
+ String SEGMENT_REPOS = "/repos"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_SHOW
+ */
+ String SEGMENT_SHOW = "/show"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_ORGANIZATIONS
+ */
+ String SEGMENT_ORGANIZATIONS = "/organizations"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_REPOSITORIES
+ */
+ String SEGMENT_REPOSITORIES = "/repositories"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_ISSUES
+ */
+ String SEGMENT_ISSUES = "/issues"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_COMMENTS
+ */
+ String SEGMENT_COMMENTS = "/comments"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_LABELS
+ */
+ String SEGMENT_LABELS = "/labels"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_MILESTONES
+ */
+ String SEGMENT_MILESTONES = "/milestones"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_GISTS
+ */
+ String SEGMENT_GISTS = "/gists"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_PULLS
+ */
+ String SEGMENT_PULLS = "/pulls"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_USERS
+ */
+ String SEGMENT_USERS = "/users"; //$NON-NLS-1$
+
+ /**
+ * SEGMENT_V2_API
+ */
+ String SEGMENT_V2_API = "/api/v2/json"; //$NON-NLS-1$
+
+ /**
+ * HOST_API
+ */
+ String HOST_API = "api.github.com"; //$NON-NLS-1$
+
+ /**
+ * HOST_API_V2
+ */
+ String HOST_API_V2 = "github.com"; //$NON-NLS-1$
+
+ /**
+ * PROTOCOL_HTTPS
+ */
+ String PROTOCOL_HTTPS = "https"; //$NON-NLS-1$
+
+ /**
+ * URL_API
+ */
+ String URL_API = PROTOCOL_HTTPS + "://" + HOST_API; //$NON-NLS-1$
+
+ /**
+ * URL_API_V2
+ */
+ String URL_API_V2 = PROTOCOL_HTTPS + "://" + HOST_API_V2; //$NON-NLS-1$
+
+ /**
+ * DATE_FORMAT
+ */
+ String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
+
+ /**
+ * DATE_FORMAT_V2_1
+ */
+ String DATE_FORMAT_V2_1 = "yyyy/MM/dd HH:mm:ss Z"; //$NON-NLS-N$
+
+ /**
+ * DATE_FORMAT_V2_2
+ */
+ String DATE_FORMAT_V2_2 = "yyyy-MM-dd'T'HH:mm:ss"; //$NON-NLS-1$
+
+ /**
+ * CONTENT_TYPE_JSON
+ */
+ String CONTENT_TYPE_JSON = "application/json"; //$NON-NLS-1$
+
+ /**
+ * CHARSET_UTF8
+ */
+ String CHARSET_UTF8 = "UTF-8"; //$NON-NLS-1$
+
+ /**
+ * PARAM_PER_PAGE
+ */
+ String PARAM_PER_PAGE = "per_page"; //$NON-NLS-1$
+
+ /**
+ * PARAM_PAGE
+ */
+ String PARAM_PAGE = "page"; //$NON-NLS-1$
+
+ /**
+ * HEADER_LINK
+ */
+ String HEADER_LINK = "Link"; //$NON-NLS-1$
+
+ /**
+ * HEADER_NEXT
+ */
+ String HEADER_NEXT = "X-Next"; //$NON-NLS-1$
+
+ /**
+ * HEADER_LAST
+ */
+ String HEADER_LAST = "X-Last"; //$NON-NLS-1$
+
+ /**
+ * META_REL
+ */
+ String META_REL = "rel"; //$NON-NLS-1$
+
+ /**
+ * META_LAST
+ */
+ String META_LAST = "last"; //$NON-NLS-1$
+
+ /**
+ * META_NEXT
+ */
+ String META_NEXT = "next"; //$NON-NLS-1$
+
+ /**
+ * META_FIRST
+ */
+ String META_FIRST = "first"; //$NON-NLS-1$
+
+ /**
+ * META_PREV
+ */
+ String META_PREV = "prev"; //$NON-NLS-1$
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java
new file mode 100644
index 00000000..d08cef8d
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PageLinks.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpMethod;
+
+/**
+ * Page link class to be used to determine the links to other pages of request
+ * responses encoded in the current response. These will be present if the
+ * result set size exceeds the per page limit.
+ */
+public class PageLinks {
+
+ private static final String DELIM_LINKS = ","; //$NON-NLS-1$
+
+ private static final String DELIM_LINK_PARAM = ";"; //$NON-NLS-1;$
+
+ private String first;
+ private String last;
+ private String next;
+ private String prev;
+
+ /**
+ * Parse links from executed method
+ *
+ * @param method
+ */
+ public PageLinks(HttpMethod method) {
+ Header[] linkHeaders = method
+ .getResponseHeaders(IGitHubConstants.HEADER_LINK);
+ if (linkHeaders.length > 0) {
+ String[] links = linkHeaders[0].getValue().split(DELIM_LINKS);
+ for (String link : links) {
+ String[] segments = link.split(DELIM_LINK_PARAM);
+ if (segments.length < 2)
+ continue;
+
+ String linkPart = segments[0].trim();
+ if (!linkPart.startsWith("<") || !linkPart.endsWith(">")) //$NON-NLS-1$ //$NON-NLS-2$
+ continue;
+ linkPart = linkPart.substring(1, linkPart.length() - 1);
+
+ for (int i = 1; i < segments.length; i++) {
+ String[] rel = segments[i].trim().split("="); //$NON-NLS-1$
+ if (rel.length < 2
+ || !IGitHubConstants.META_REL.equals(rel[0]))
+ continue;
+
+ String relValue = rel[1];
+ if (relValue.startsWith("\"") && relValue.endsWith("\"")) //$NON-NLS-1$ //$NON-NLS-2$
+ relValue = relValue.substring(1, relValue.length() - 1);
+
+ if (IGitHubConstants.META_FIRST.equals(relValue))
+ first = linkPart;
+ else if (IGitHubConstants.META_LAST.equals(relValue))
+ last = linkPart;
+ else if (IGitHubConstants.META_NEXT.equals(relValue))
+ next = linkPart;
+ else if (IGitHubConstants.META_PREV.equals(relValue))
+ prev = linkPart;
+ }
+ }
+ } else {
+ Header[] nextHeaders = method
+ .getResponseHeaders(IGitHubConstants.HEADER_NEXT);
+ if (nextHeaders.length > 0)
+ next = nextHeaders[0].getValue();
+
+ Header[] lastHeaders = method
+ .getResponseHeaders(IGitHubConstants.HEADER_LAST);
+ if (lastHeaders.length > 0)
+ last = lastHeaders[0].getValue();
+ }
+ }
+
+ /**
+ * @return first
+ */
+ public String getFirst() {
+ return this.first;
+ }
+
+ /**
+ * @return last
+ */
+ public String getLast() {
+ return this.last;
+ }
+
+ /**
+ * @return next
+ */
+ public String getNext() {
+ return this.next;
+ }
+
+ /**
+ * @return prev
+ */
+ public String getPrev() {
+ return this.prev;
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PagedRequest.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PagedRequest.java
new file mode 100644
index 00000000..1137eab5
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/PagedRequest.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.IResourceCollector;
+
+/**
+ * Pages request class that contains a collector for accept resources page by
+ * page.
+ *
+ * @param <V>
+ */
+public class PagedRequest<V> extends GitHubRequest {
+
+ private IResourceCollector<V> collector;
+
+ /**
+ * Create paged request with non-null collector
+ *
+ * @param collector
+ * must be non-null
+ */
+ public PagedRequest(IResourceCollector<V> collector) {
+ Assert.notNull("Collector cannot be null", collector); //$NON-NLS-1$
+ this.collector = collector;
+ }
+
+ /**
+ * @return collector
+ */
+ public IResourceCollector<V> getCollector() {
+ return this.collector;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/RequestException.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/RequestException.java
new file mode 100644
index 00000000..c27844ed
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/client/RequestException.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.client;
+
+import java.io.IOException;
+
+import org.eclipse.egit.github.core.RequestError;
+
+/**
+ * Request exception class that wraps an {@link RequestError} object.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class RequestException extends IOException {
+
+ /**
+ * serialVersionUID
+ */
+ private static final long serialVersionUID = 1197051396535284852L;
+
+ private RequestError error;
+ private int status;
+
+ /**
+ * Create request exception
+ *
+ * @param error
+ * @param status
+ */
+ public RequestException(RequestError error, int status) {
+ super();
+ this.error = error;
+ this.status = status;
+ }
+
+ /**
+ * Get error
+ *
+ * @return error
+ */
+ public RequestError getError() {
+ return this.error;
+ }
+
+ /**
+ * Get status
+ *
+ * @return status
+ */
+ public int getStatus() {
+ return this.status;
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GistService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GistService.java
new file mode 100644
index 00000000..047e2e37
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GistService.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.Comment;
+import org.eclipse.egit.github.core.Gist;
+import org.eclipse.egit.github.core.ListResourceCollector;
+import org.eclipse.egit.github.core.User;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.GitHubRequest;
+import org.eclipse.egit.github.core.client.IGitHubConstants;
+import org.eclipse.egit.github.core.client.PagedRequest;
+
+/**
+ * Service class for getting and list gists.
+ */
+public class GistService extends GitHubService {
+
+ /**
+ * Create gist service
+ *
+ * @param client
+ */
+ public GistService(GitHubClient client) {
+ super(client);
+ }
+
+ /**
+ * Get gist
+ *
+ * @param id
+ * @return gist
+ * @throws IOException
+ */
+ public Gist getGist(String id) throws IOException {
+ Assert.notNull("Gist id cannot be null", id); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_GISTS);
+ uri.append('/').append(id);
+ GitHubRequest request = new GitHubRequest();
+ request.setUri(uri);
+ request.setType(Gist.class);
+ return (Gist) this.client.get(request).getBody();
+ }
+
+ /**
+ * Get gists for specified user
+ *
+ * @param user
+ * @return list of gists
+ * @throws IOException
+ */
+ public List<Gist> getGists(String user) throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_USERS);
+ uri.append('/').append(user);
+ uri.append(IGitHubConstants.SEGMENT_GISTS);
+ ListResourceCollector<Gist> collector = new ListResourceCollector<Gist>();
+ PagedRequest<Gist> request = new PagedRequest<Gist>(collector);
+ request.setUri(uri).setType(new TypeToken<List<Gist>>() {
+ }.getType());
+ getAll(request);
+ return collector.getResources();
+ }
+
+ /**
+ * Create a gist
+ *
+ * @param gist
+ * @return created gist
+ * @throws IOException
+ */
+ public Gist createGist(Gist gist) throws IOException {
+ Assert.notNull("Gist cannot be null", gist);
+ StringBuilder uri = new StringBuilder();
+ User user = gist.getUser();
+ if (user != null) {
+ String login = user.getLogin();
+ Assert.notNull("User login name cannot be null", login);
+ uri.append(IGitHubConstants.SEGMENT_USERS);
+ uri.append('/').append(login);
+ }
+ uri.append(IGitHubConstants.SEGMENT_GISTS);
+ return this.client.post(uri.toString(), gist, Gist.class);
+ }
+
+ /**
+ * Update a gist
+ *
+ * @param gist
+ * @return updated gist
+ * @throws IOException
+ */
+ public Gist updateGist(Gist gist) throws IOException {
+ Assert.notNull("Gist cannot be null", gist); //$NON-NLS-1$
+ String id = gist.getId();
+ Assert.notNull("Gist id cannot be null", id); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_GISTS);
+ uri.append('/').append(id);
+ return this.client.post(uri.toString(), gist, Gist.class);
+ }
+
+ /**
+ * Create comment on specified gist id
+ *
+ * @param gistId
+ * @param comment
+ * @return created issue
+ * @throws IOException
+ */
+ public Comment createComment(String gistId, String comment)
+ throws IOException {
+ Assert.notNull("Gist id cannot be null", gistId); //$NON-NLS-1$
+ Assert.notNull("Gist comment cannot be null", comment);
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_GISTS);
+ uri.append('/').append(gistId);
+ uri.append(IGitHubConstants.SEGMENT_COMMENTS);
+
+ Map<String, String> params = new HashMap<String, String>(1, 1);
+ params.put(IssueService.FIELD_BODY, comment);
+ return this.client.post(uri.toString(), params, Comment.class);
+ }
+
+ /**
+ * Get comments for specified gist id
+ *
+ * @param gistId
+ * @return list of comments
+ * @throws IOException
+ */
+ public List<Comment> getComments(String gistId) throws IOException {
+ Assert.notNull("Gist id cannot be null", gistId); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_GISTS);
+ uri.append('/').append(gistId);
+ uri.append(IGitHubConstants.SEGMENT_COMMENTS);
+ ListResourceCollector<Comment> collector = new ListResourceCollector<Comment>();
+ PagedRequest<Comment> request = new PagedRequest<Comment>(collector);
+ request.setUri(uri).setType(new TypeToken<List<Comment>>() {
+ }.getType());
+ getAll(request);
+ return collector.getResources();
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GitHubService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GitHubService.java
new file mode 100644
index 00000000..39cab331
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/GitHubService.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.IResourceCollector;
+import org.eclipse.egit.github.core.IResourceProvider;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.GitHubResponse;
+import org.eclipse.egit.github.core.client.PagedRequest;
+
+/**
+ * Base GitHub service class.
+ */
+public abstract class GitHubService {
+
+ /**
+ * Client field
+ */
+ protected GitHubClient client;
+
+ /**
+ * Create service for client
+ *
+ * @param client
+ */
+ public GitHubService(GitHubClient client) {
+ Assert.notNull("Client cannot be null", client); //$NON-NLS-1$
+ this.client = client;
+ }
+
+ /**
+ * Get paged request by performing multiple requests until no more pages are
+ * available of the request collector no longer accepts resource results.
+ *
+ * @param <V>
+ * @param request
+ * @throws IOException
+ */
+ @SuppressWarnings("unchecked")
+ protected <V> void getAll(PagedRequest<V> request) throws IOException {
+ IResourceCollector<V> collector = request.getCollector();
+ String next = null;
+ int page = 1;
+ do {
+ GitHubResponse response = client.get(request);
+ Collection<V> resources = null;
+ Object body = response.getBody();
+ if (body instanceof Collection)
+ resources = (Collection<V>) body;
+ else if (body instanceof IResourceProvider)
+ resources = ((IResourceProvider<V>) body).getResources();
+ else
+ resources = (Collection<V>) Collections.singletonList(body);
+
+ if (!collector.accept(page, resources))
+ break;
+ next = response.getNext();
+ if (next != null)
+ request.setUri(next);
+ page++;
+ } while (next != null);
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java
new file mode 100644
index 00000000..2844029b
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/IssueService.java
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.Comment;
+import org.eclipse.egit.github.core.Issue;
+import org.eclipse.egit.github.core.ListResourceCollector;
+import org.eclipse.egit.github.core.Milestone;
+import org.eclipse.egit.github.core.User;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.GitHubRequest;
+import org.eclipse.egit.github.core.client.IGitHubConstants;
+import org.eclipse.egit.github.core.client.PagedRequest;
+
+/**
+ * Issue service class for listing, searching, and fetching {@link Issue}
+ * objects using a {@link GitHubClient}.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class IssueService extends GitHubService {
+
+ /**
+ * Filter by issue assignee
+ */
+ public static final String FILTER_ASSIGNEE = "assignee"; //$NON-NLS-1$
+
+ /**
+ * Filter by issue's milestone
+ */
+ public static final String FILTER_MILESTONE = "milestone"; //$NON-NLS-1$
+
+ /**
+ * Filter by user mentioned in issue
+ */
+ public static final String FILTER_MENTIONED = "mentioned"; //$NON-NLS-1$
+
+ /**
+ * Filter by issue's labels
+ */
+ public static final String FILTER_LABELS = "labels"; //$NON-NLS-1$
+
+ /**
+ * Filter by issue's state
+ */
+ public static final String FILTER_STATE = "state"; //$NON-NLS-1$
+
+ /**
+ * Issue open state filter value
+ */
+ public static final String STATE_OPEN = "open"; //$NON-NLS-1$
+
+ /**
+ * Issue closed state filter value
+ */
+ public static final String STATE_CLOSED = "closed"; //$NON-NLS-1$
+
+ /**
+ * Issue body field name
+ */
+ public static final String FIELD_BODY = "body"; //$NON-NLS-1$
+
+ /**
+ * Issue title field name
+ */
+ public static final String FIELD_TITLE = "title"; //$NON-NLS-1$
+
+ /**
+ * Create issue service
+ *
+ * @param client
+ * cannot be null
+ */
+ public IssueService(GitHubClient client) {
+ super(client);
+ }
+
+ /**
+ * Get issue
+ *
+ * @param user
+ * @param repository
+ * @param id
+ * @return issue
+ * @throws IOException
+ */
+ public Issue getIssue(String user, String repository, String id)
+ throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Id cannot be null", id); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_ISSUES);
+ uri.append('/').append(id);
+ GitHubRequest request = new GitHubRequest();
+ request.setUri(uri);
+ request.setType(Issue.class);
+ return (Issue) client.get(request).getBody();
+ }
+
+ /**
+ * Get an issue's comments
+ *
+ * @param user
+ * @param repository
+ * @param id
+ * @return list of matching issues
+ * @throws IOException
+ */
+ public List<Comment> getComments(String user, String repository, String id)
+ throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Id cannot be null", id); //$NON-NLS-1$
+ StringBuilder builder = new StringBuilder(
+ IGitHubConstants.SEGMENT_REPOS);
+ builder.append('/').append(user).append('/').append(repository);
+ builder.append(IGitHubConstants.SEGMENT_ISSUES);
+ builder.append('/').append(id);
+ builder.append(IGitHubConstants.SEGMENT_COMMENTS);
+ ListResourceCollector<Comment> collector = new ListResourceCollector<Comment>();
+ PagedRequest<Comment> request = new PagedRequest<Comment>(collector);
+ request.setUri(builder.toString()).setType(
+ new TypeToken<List<Comment>>() {
+ }.getType());
+ getAll(request);
+ return collector.getResources();
+ }
+
+ /**
+ * Get a list of {@link Issue} objects that match the specified filter data
+ *
+ * @param user
+ * @param repository
+ * @param filterData
+ * @return list of issues
+ * @throws IOException
+ */
+ public List<Issue> getIssues(String user, String repository,
+ Map<String, String> filterData) throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_ISSUES);
+ ListResourceCollector<Issue> collector = new ListResourceCollector<Issue>();
+ PagedRequest<Issue> request = new PagedRequest<Issue>(collector);
+ request.setParams(filterData).setUri(uri);
+ request.setType(new TypeToken<List<Issue>>() {
+ }.getType());
+ getAll(request);
+ return collector.getResources();
+ }
+
+ /**
+ * Create issue map for issue
+ *
+ * @param issue
+ * @param newIssue
+ * @return map
+ */
+ protected Map<String, String> createIssueMap(Issue issue, boolean newIssue) {
+ Map<String, String> params = new HashMap<String, String>();
+ if (issue != null) {
+ params.put(FIELD_BODY, issue.getBody());
+ params.put(FIELD_TITLE, issue.getTitle());
+ User assignee = issue.getAssignee();
+ if (assignee != null && !newIssue)
+ params.put(FILTER_ASSIGNEE, assignee.getName());
+
+ Milestone milestone = issue.getMilestone();
+ if (milestone != null) {
+ int number = milestone.getNumber();
+ if (number > 0)
+ params.put(FILTER_MILESTONE, Integer.toString(number));
+ else {
+ if (!newIssue)
+ params.put(FILTER_MILESTONE, null);
+ }
+ }
+ }
+ return params;
+ }
+
+ /**
+ * Create issue
+ *
+ * @param user
+ * @param repository
+ * @param issue
+ * @return created issue
+ * @throws IOException
+ */
+ public Issue createIssue(String user, String repository, Issue issue)
+ throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_ISSUES);
+
+ Map<String, String> params = createIssueMap(issue, true);
+ return this.client.post(uri.toString(), params, Issue.class);
+ }
+
+ /**
+ * Edit issue
+ *
+ * @param user
+ * @param repository
+ * @param issue
+ * @return created issue
+ * @throws IOException
+ */
+ public Issue editIssue(String user, String repository, Issue issue)
+ throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Issue cannot be null", issue); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_ISSUES);
+ uri.append('/').append(issue.getNumber());
+
+ Map<String, String> params = createIssueMap(issue, false);
+ String state = issue.getState();
+ if (state != null)
+ params.put(FILTER_STATE, state);
+ return this.client.post(uri.toString(), params, Issue.class);
+ }
+
+ /**
+ * Create comment on specified issue id
+ *
+ * @param user
+ * @param repository
+ * @param issueId
+ * @param comment
+ * @return created issue
+ * @throws IOException
+ */
+ public Comment createComment(String user, String repository,
+ String issueId, String comment) throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Issue id cannot be null", issueId); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_ISSUES);
+ uri.append('/').append(issueId);
+ uri.append(IGitHubConstants.SEGMENT_COMMENTS);
+
+ Map<String, String> params = new HashMap<String, String>(1, 1);
+ params.put(FIELD_BODY, comment);
+
+ return this.client.post(uri.toString(), params, Comment.class);
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/LabelService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/LabelService.java
new file mode 100644
index 00000000..557065da
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/LabelService.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.Label;
+import org.eclipse.egit.github.core.ListResourceCollector;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.IGitHubConstants;
+import org.eclipse.egit.github.core.client.PagedRequest;
+
+/**
+ * Label service class for listing {@link Label} objects in use for a given user
+ * and repository.
+ */
+public class LabelService extends GitHubService {
+
+ /**
+ * Create label service for client
+ *
+ * @param client
+ */
+ public LabelService(GitHubClient client) {
+ super(client);
+ }
+
+ /**
+ * Get labels
+ *
+ * @param user
+ * @param repository
+ * @return list of labels
+ * @throws IOException
+ */
+ public List<Label> getLabels(String user, String repository)
+ throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_LABELS);
+ ListResourceCollector<Label> collector = new ListResourceCollector<Label>();
+ PagedRequest<Label> request = new PagedRequest<Label>(collector);
+ request.setUri(uri).setType(new TypeToken<List<Label>>() {
+ }.getType());
+ getAll(request);
+ return collector.getResources();
+ }
+
+ /**
+ * Set the labels for an issue
+ *
+ * @param user
+ * @param repository
+ * @param issueId
+ * @param labels
+ * @return list of labels
+ * @throws IOException
+ */
+ public List<Label> setLabels(String user, String repository,
+ String issueId, List<Label> labels) throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Issue id cannot be null", issueId); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_ISSUES).append('/').append(issueId);
+ uri.append(IGitHubConstants.SEGMENT_LABELS);
+
+ return this.client.put(uri.toString(), labels,
+ new TypeToken<List<Label>>() {
+ }.getType());
+ }
+
+ /**
+ * Create label
+ *
+ * @param user
+ * @param repository
+ * @param label
+ * @return created label
+ * @throws IOException
+ */
+ public Label createLabel(String user, String repository, Label label)
+ throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Label cannot be null", label); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_LABELS);
+ return this.client.post(uri.toString(), label, Label.class);
+ }
+
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/MilestoneService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/MilestoneService.java
new file mode 100644
index 00000000..1d239c0e
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/MilestoneService.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import com.google.gson.reflect.TypeToken;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.ListResourceCollector;
+import org.eclipse.egit.github.core.Milestone;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.IGitHubConstants;
+import org.eclipse.egit.github.core.client.PagedRequest;
+
+/**
+ * Milestone service class for listing the {@link Milestone} objects in use by a
+ * repository and user accessed via a {@link GitHubClient}.
+ */
+public class MilestoneService extends GitHubService {
+
+ /**
+ * Create milestone service
+ *
+ * @param client
+ * cannot be null
+ */
+ public MilestoneService(GitHubClient client) {
+ super(client);
+ }
+
+ /**
+ * Get milestones
+ *
+ * @param user
+ * @param repository
+ * @param state
+ * @return list of milestones
+ * @throws IOException
+ */
+ public List<Milestone> getMilestones(String user, String repository,
+ String state) throws IOException {
+ Assert.notNull("User cannot be null", user); //$NON-NLS-1$
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_REPOS);
+ uri.append('/').append(user).append('/').append(repository);
+ uri.append(IGitHubConstants.SEGMENT_MILESTONES);
+ ListResourceCollector<Milestone> collector = new ListResourceCollector<Milestone>();
+ PagedRequest<Milestone> request = new PagedRequest<Milestone>(collector);
+ if (state != null)
+ request.setParams(Collections.singletonMap(
+ IssueService.FILTER_STATE, state));
+ request.setUri(uri).setType(new TypeToken<List<Milestone>>() {
+ }.getType());
+ getAll(request);
+ return collector.getResources();
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/PullRequestService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/PullRequestService.java
new file mode 100644
index 00000000..a7e59c45
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/PullRequestService.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.egit.github.core.Assert;
+import org.eclipse.egit.github.core.PullRequest;
+import org.eclipse.egit.github.core.Repository;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.GitHubRequest;
+import org.eclipse.egit.github.core.client.GitHubResponse;
+import org.eclipse.egit.github.core.client.IGitHubConstants;
+
+/**
+ * Service class getting and listing pull requests.
+ */
+public class PullRequestService extends GitHubService {
+
+ /**
+ * Pull request wrapper
+ */
+ private static class PullRequestWrapper {
+
+ private PullRequest pull;
+
+ public PullRequest getPull() {
+ return this.pull;
+ }
+
+ }
+
+ /**
+ * Pull requests wrapper
+ */
+ private static class PullRequestsWrapper {
+
+ private List<PullRequest> pulls;
+
+ public List<PullRequest> getPulls() {
+ return this.pulls;
+ }
+
+ }
+
+ /**
+ * @param client
+ */
+ public PullRequestService(GitHubClient client) {
+ super(client);
+ }
+
+ /**
+ * Get pull request from repository with id
+ *
+ * @param repository
+ * @param id
+ * @return pull request
+ * @throws IOException
+ */
+ public PullRequest getPullRequest(Repository repository, String id)
+ throws IOException {
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("Id cannot be null", id); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_V2_API);
+ uri.append(IGitHubConstants.SEGMENT_PULLS);
+ uri.append('/').append(repository.getId());
+ uri.append('/').append(id);
+ GitHubRequest request = new GitHubRequest();
+ request.setUri(uri);
+ request.setType(PullRequestWrapper.class);
+ GitHubResponse response = this.client.get(request);
+ return ((PullRequestWrapper) response.getBody()).getPull();
+ }
+
+ /**
+ * Get pull requests from repository matching state
+ *
+ * @param repository
+ * @param state
+ * @return list of pull requests
+ * @throws IOException
+ */
+ public List<PullRequest> getPullRequests(Repository repository, String state)
+ throws IOException {
+ Assert.notNull("Repository cannot be null", repository); //$NON-NLS-1$
+ Assert.notNull("State cannot be null", state); //$NON-NLS-1$
+ String repositoryId = repository.getId();
+ Assert.notNull("Repository id cannot be null", repositoryId); //$NON-NLS-1$
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_V2_API);
+ uri.append(IGitHubConstants.SEGMENT_PULLS);
+ uri.append('/').append(repositoryId);
+ uri.append('/').append(state);
+ GitHubRequest request = new GitHubRequest();
+ request.setUri(uri);
+ request.setType(PullRequestsWrapper.class);
+ GitHubResponse response = this.client.get(request);
+ return ((PullRequestsWrapper) response.getBody()).getPulls();
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/RepositoryService.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/RepositoryService.java
new file mode 100644
index 00000000..94cb74db
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/service/RepositoryService.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.service;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.egit.github.core.IResourceProvider;
+import org.eclipse.egit.github.core.ListResourceCollector;
+import org.eclipse.egit.github.core.Repository;
+import org.eclipse.egit.github.core.client.GitHubClient;
+import org.eclipse.egit.github.core.client.IGitHubConstants;
+import org.eclipse.egit.github.core.client.PagedRequest;
+
+/**
+ * Repository service class.
+ *
+ * @author Kevin Sawicki (kevin@github.com)
+ */
+public class RepositoryService extends GitHubService {
+
+ private static class RepositoryContainer implements
+ IResourceProvider<Repository> {
+
+ private List<Repository> repositories;
+
+ /**
+ * @see org.eclipse.egit.github.core.IResourceProvider#getResources()
+ */
+ public List<Repository> getResources() {
+ return this.repositories;
+ }
+
+ }
+
+ /**
+ * Create repository service
+ *
+ * @param client
+ * cannot be null
+ */
+ public RepositoryService(GitHubClient client) {
+ super(client);
+ }
+
+ /**
+ * Get all repositories accessible through organizational membership
+ *
+ * @return list of repositories
+ * @throws IOException
+ */
+
+ public List<Repository> getOrganizationRepositories() throws IOException {
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_V2_API);
+ uri.append(IGitHubConstants.SEGMENT_ORGANIZATIONS).append(
+ IGitHubConstants.SEGMENT_REPOSITORIES);
+
+ ListResourceCollector<Repository> collector = new ListResourceCollector<Repository>();
+ PagedRequest<Repository> request = new PagedRequest<Repository>(
+ collector);
+ request.setUri(uri);
+ request.setType(RepositoryContainer.class);
+ getAll(request);
+ return collector.getResources();
+ }
+
+ /**
+ * Get repositories
+ *
+ * @param user
+ * @return list of repositories
+ * @throws IOException
+ */
+ public List<Repository> getRepositories(String user) throws IOException {
+ StringBuilder uri = new StringBuilder(IGitHubConstants.SEGMENT_V2_API);
+ uri.append(IGitHubConstants.SEGMENT_REPOS)
+ .append(IGitHubConstants.SEGMENT_SHOW).append('/').append(user);
+
+ ListResourceCollector<Repository> collector = new ListResourceCollector<Repository>();
+ PagedRequest<Repository> request = new PagedRequest<Repository>(
+ collector);
+ request.setUri(uri);
+ request.setType(RepositoryContainer.class);
+ getAll(request);
+ return collector.getResources();
+ }
+}
diff --git a/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/util/LabelComparator.java b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/util/LabelComparator.java
new file mode 100644
index 00000000..535e1662
--- /dev/null
+++ b/org.eclipse.egit.github.core/src/org/eclipse/egit/github/core/util/LabelComparator.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 GitHub Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.github.core.util;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.eclipse.egit.github.core.Label;
+
+
+/**
+ * Label comparator using case-insensitive name comparisons.
+ */
+public class LabelComparator implements Comparator<Label>, Serializable {
+
+ /**
+ * serialVersionUID
+ */
+ private static final long serialVersionUID = -3185701121586168554L;
+
+ /**
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Label label1, Label label2) {
+ return label1.getName().compareToIgnoreCase(label2.getName());
+ }
+
+}

Back to the top