From ecbfdd7315ef2cf04b2be7f11a072ce0bd00c396 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sun, 18 Apr 2010 21:07:10 -0700 Subject: [PATCH] initial version --- .gitignore | 4 + pom.xml | 96 ++++++++++ .../java/org/kohsuke/github/DeleteToken.java | 31 ++++ .../java/org/kohsuke/github/GHRepository.java | 150 ++++++++++++++++ src/main/java/org/kohsuke/github/GHUser.java | 164 ++++++++++++++++++ src/main/java/org/kohsuke/github/GitHub.java | 108 ++++++++++++ .../org/kohsuke/github/JsonCollaborators.java | 33 ++++ .../org/kohsuke/github/JsonRepositories.java | 33 ++++ .../org/kohsuke/github/JsonRepository.java | 31 ++++ .../java/org/kohsuke/github/JsonUser.java | 31 ++++ src/main/java/org/kohsuke/github/Poster.java | 108 ++++++++++++ src/test/java/org/kohsuke/AppTest.java | 21 +++ 12 files changed, 810 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/org/kohsuke/github/DeleteToken.java create mode 100644 src/main/java/org/kohsuke/github/GHRepository.java create mode 100644 src/main/java/org/kohsuke/github/GHUser.java create mode 100644 src/main/java/org/kohsuke/github/GitHub.java create mode 100644 src/main/java/org/kohsuke/github/JsonCollaborators.java create mode 100644 src/main/java/org/kohsuke/github/JsonRepositories.java create mode 100644 src/main/java/org/kohsuke/github/JsonRepository.java create mode 100644 src/main/java/org/kohsuke/github/JsonUser.java create mode 100644 src/main/java/org/kohsuke/github/Poster.java create mode 100644 src/test/java/org/kohsuke/AppTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..097367121 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +target +*.iml +*.ipr +*.iws diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..04238d8b1 --- /dev/null +++ b/pom.xml @@ -0,0 +1,96 @@ + + 4.0.0 + org.kohsuke + github-api + jar + 1.0-SNAPSHOT + GitHub API for Java + http://kohsuke.org/github-api/ + GitHub API for Java + + + + java.net-m2-repository + java-net:/maven2-repository/trunk/repository/ + + + kohsuke.org + scp://kohsuke.org/home/kohsuke/kohsuke.org/github-api/ + + + + + + + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.apache.maven.plugins + maven-release-plugin + 2.0 + + + org.apache.maven.scm + maven-scm-provider-gitexe + 1.2 + + + + + org.apache.maven.plugins + maven-scm-plugin + 1.3 + + + + + org.jvnet.wagon-svn + wagon-svn + 1.9 + + + + + + scm:git:git@github.com:kohsuke/github-api.git + + + + + kohsuke + Kohsuke Kawaguchi + + + + + + MIT License + repository + http://www.opensource.org/licenses/mit-license.php + + + + + + junit + junit + 3.8.1 + test + + + org.codehaus.jackson + jackson-mapper-asl + 1.5.0 + + + commons-io + commons-io + 1.4 + + + diff --git a/src/main/java/org/kohsuke/github/DeleteToken.java b/src/main/java/org/kohsuke/github/DeleteToken.java new file mode 100644 index 000000000..eb6101192 --- /dev/null +++ b/src/main/java/org/kohsuke/github/DeleteToken.java @@ -0,0 +1,31 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +/** + * @author Kohsuke Kawaguchi + */ +class DeleteToken { + public String delete_token; +} diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java new file mode 100644 index 000000000..68a71dfd8 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -0,0 +1,150 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import static java.util.Arrays.asList; + +/** + * @author Kohsuke Kawaguchi + */ +public class GHRepository { + /*package almost final*/ GitHub root; + + private String description, homepage, url, name, owner; + private boolean has_issues, has_wiki, fork, _private, has_downloads; + private int watchers,forks; + + public String getDescription() { + return description; + } + + public String getHomepage() { + return homepage; + } + + public String getUrl() { + return url; + } + + public String getName() { + return name; + } + + public GHUser getOwner() throws IOException { + return root.getUser(owner); + } + + public boolean hasIssues() { + return has_issues; + } + + public boolean hasWiki() { + return has_wiki; + } + + public boolean isFork() { + return fork; + } + + public int getForks() { + return forks; + } + + public boolean isPrivate() { + return _private; + } + + public boolean hasDownloads() { + return has_downloads; + } + + public int getWatchers() { + return watchers; + } + + /** + * Gets the collaborators on this repository. + * This set always appear to include the owner. + */ + public Set getCollaborators() throws IOException { + Set r = new HashSet(); + for (String u : root.retrieve("/repos/show/"+owner+"/"+name+"/collaborators",JsonCollaborators.class).collaborators) + r.add(root.getUser(u)); + return Collections.unmodifiableSet(r); + } + + public void addCollaborators(GHUser... users) throws IOException { + addCollaborators(asList(users)); + } + + public void addCollaborators(Collection users) throws IOException { + modifyCollaborators(users, "/add/"); + } + + public void removeCollaborators(GHUser... users) throws IOException { + removeCollaborators(asList(users)); + } + + public void removeCollaborators(Collection users) throws IOException { + modifyCollaborators(users, "/remove/"); + } + + private void modifyCollaborators(Collection users, String op) throws IOException { + root.requireCredential(); + verifyMine(); + for (GHUser user : users) { + new Poster(root).withCredential().to(root.getApiURL("/repos/collaborators/"+name+ op +user.getLogin())); + } + } + + /** + * Deletes this repository. + */ + public void delete() throws IOException { + root.requireCredential(); + verifyMine(); + Poster poster = new Poster(root).withCredential(); + URL url = root.getApiURL("/repos/delete/" + name); + + DeleteToken token = poster.to(url, DeleteToken.class); + poster.with("delete_token",token.delete_token).to(url); + } + + private void verifyMine() throws IOException { + if (!root.login.equals(owner)) + throw new IOException("Operation not applicable to a repository owned by someone else: "+owner); + } + + @Override + public String toString() { + return "Repository:"+owner+":"+name; + } +} diff --git a/src/main/java/org/kohsuke/github/GHUser.java b/src/main/java/org/kohsuke/github/GHUser.java new file mode 100644 index 000000000..2a5b73f1f --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHUser.java @@ -0,0 +1,164 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; + +import static org.kohsuke.github.GitHub.MAPPER; + +/** + * Represents an user of GitHub. + * + * @author Kohsuke Kawaguchi + */ +public class GHUser { + /*package almost final*/ GitHub root; + + private String gravatar_id,name,company,location,created_at,blog,login,email; + private int public_gist_count,public_repo_count,following_count,id,followers_count; + + /** + * Repositories that this user owns. + */ + private transient Map repositories; + + /** + * Gravatar ID of this user, like 0cb9832a01c22c083390f3c5dcb64105 + */ + public String getGravatarId() { + return gravatar_id; + } + + /** + * Gets the human-readable name of the user, like "Kohsuke Kawaguchi" + */ + public String getName() { + return name; + } + + /** + * Gets the company name of this user, like "Sun Microsystems, Inc." + */ + public String getCompany() { + return company; + } + + /** + * Gets the location of this user, like "Santa Clara, California" + */ + public String getLocation() { + return location; + } + + public String getCreatedAt() { + return created_at; + } + + /** + * Gets the blog URL of this user. + */ + public String getBlog() { + return blog; + } + + /** + * Gets the login ID of this user, like 'kohsuke' + */ + public String getLogin() { + return login; + } + + /** + * Gets the e-mail address of the user. + */ + public String getEmail() { + return email; + } + + public int getPublicGistCount() { + return public_gist_count; + } + + public int getPublicRepoCount() { + return public_repo_count; + } + + public int getFollowingCount() { + return following_count; + } + + /** + * What appears to be a GitHub internal unique number that identifies this user. + */ + public int getId() { + return id; + } + + public int getFollowersCount() { + return followers_count; + } + + /** + * Gets the repositories this user owns. + */ + public Map getRepositories() throws IOException { + if (repositories==null) { + repositories = new TreeMap(); + URL url = new URL("http://github.com/api/v2/json/repos/show/" + login); + for (GHRepository r : MAPPER.readValue(url, JsonRepositories.class).repositories) { + r.root = root; + repositories.put(r.getName(),r); + } + } + + return Collections.unmodifiableMap(repositories); + } + + public GHRepository getRepository(String name) throws IOException { + return getRepositories().get(name); + } + + @Override + public String toString() { + return "User:"+login; + } + + @Override + public int hashCode() { + return login.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof GHUser) { + GHUser that = (GHUser) obj; + return this.login.equals(that.login); + } + return false; + } +} diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java new file mode 100644 index 000000000..4b2ca258c --- /dev/null +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -0,0 +1,108 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +import org.codehaus.jackson.map.DeserializationConfig.Feature; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.introspect.VisibilityChecker.Std; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.ANY; +import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE; + +/** + * Root of the GitHub API. + * + * @author Kohsuke Kawaguchi + */ +public class GitHub { + /*package*/ final String login; + /*package*/ final String token; + + private final Map users = new HashMap(); + + /** + * Connects to GitHub anonymously. + * + * All operations that requires authentication will fail. + */ + public GitHub() { + this(null,null); + } + + public GitHub(String login, String apiToken) { + this.login = login; + this.token = apiToken; + } + + /*package*/ void requireCredential() { + if (login ==null || token ==null) + throw new IllegalStateException("This operation requires a credential but none is given to the GitHub constructor"); + } + + /*package*/ URL getApiURL(String tail) throws IOException { + return new URL("http://github.com/api/v2/json"+tail); + } + + /*package*/ T retrieve(String tail, Class type) throws IOException { + return MAPPER.readValue(getApiURL(tail),type); + } + + public GHUser getUser(String login) throws IOException { + GHUser u = users.get(login); + if (u==null) { + u = MAPPER.readValue(getApiURL("/user/show/"+login), JsonUser.class).user; + u.root = this; + users.put(login,u); + } + return u; + } + + /** + * Creates a new repository. + * + * @return + * Newly created repository. + */ + public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException { + requireCredential(); + GHRepository r = new Poster(this).withCredential() + .with("name", name).with("description", description).with("homepage", homepage) + .with("public", isPublic ? 1 : 0).to(getApiURL("/repos/create"), JsonRepository.class).repository; + r.root = this; + return r; + } + + + /*package*/ static final ObjectMapper MAPPER = new ObjectMapper(); + + static { + MAPPER.setVisibilityChecker(new Std(NONE, NONE, NONE, NONE, ANY)); + MAPPER.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } +} diff --git a/src/main/java/org/kohsuke/github/JsonCollaborators.java b/src/main/java/org/kohsuke/github/JsonCollaborators.java new file mode 100644 index 000000000..3d21c77ad --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonCollaborators.java @@ -0,0 +1,33 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +import java.util.List; + +/** + * @author Kohsuke Kawaguchi + */ +class JsonCollaborators { + List collaborators; +} diff --git a/src/main/java/org/kohsuke/github/JsonRepositories.java b/src/main/java/org/kohsuke/github/JsonRepositories.java new file mode 100644 index 000000000..b3a08853a --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonRepositories.java @@ -0,0 +1,33 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +import java.util.List; + +/** + * @author Kohsuke Kawaguchi + */ +class JsonRepositories { + public List repositories; +} diff --git a/src/main/java/org/kohsuke/github/JsonRepository.java b/src/main/java/org/kohsuke/github/JsonRepository.java new file mode 100644 index 000000000..1f13a196b --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonRepository.java @@ -0,0 +1,31 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +/** + * @author Kohsuke Kawaguchi + */ +class JsonRepository { + public GHRepository repository; +} diff --git a/src/main/java/org/kohsuke/github/JsonUser.java b/src/main/java/org/kohsuke/github/JsonUser.java new file mode 100644 index 000000000..1fae836dc --- /dev/null +++ b/src/main/java/org/kohsuke/github/JsonUser.java @@ -0,0 +1,31 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +/** + * @author Kohsuke Kawaguchi + */ +class JsonUser { + public GHUser user; +} diff --git a/src/main/java/org/kohsuke/github/Poster.java b/src/main/java/org/kohsuke/github/Poster.java new file mode 100644 index 000000000..f1e91e5fb --- /dev/null +++ b/src/main/java/org/kohsuke/github/Poster.java @@ -0,0 +1,108 @@ +/* + * The MIT License + * + * Copyright (c) 2010, Kohsuke Kawaguchi + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.kohsuke.github; + +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import static org.kohsuke.github.GitHub.MAPPER; + +/** + * Handles HTTP POST. + * @author Kohsuke Kawaguchi + */ +class Poster { + private final GitHub root; + private final Map args = new HashMap(); + + Poster(GitHub root) { + this.root = root; + } + + public Poster withCredential() { + return with("login",root.login).with("token",root.token); + } + + public Poster with(String key, int value) { + return with(key,String.valueOf(value)); + } + + public Poster with(String key, String value) { + if (value!=null) + this.args.put(key,value); + return this; + } + + public void to(URL url) throws IOException { + to(url,null); + } + + /** + * POSTs the form to the specified URL. + * + * @throws IOException + * if the server returns 4xx/5xx responses. + * @return + * {@link Reader} that reads the response. + */ + public T to(URL url, Class type) throws IOException { + HttpURLConnection uc = (HttpURLConnection) url.openConnection(); + + uc.setDoOutput(true); + uc.setRequestProperty("Content-type","application/x-www-form-urlencoded"); + uc.setRequestMethod("POST"); + + + StringBuilder body = new StringBuilder(); + for (Entry e : args.entrySet()) { + if (body.length()>0) body.append('&'); + body.append(URLEncoder.encode(e.getKey(),"UTF-8")); + body.append('='); + body.append(URLEncoder.encode(e.getValue(),"UTF-8")); + } + + OutputStreamWriter o = new OutputStreamWriter(uc.getOutputStream(), "UTF-8"); + o.write(body.toString()); + o.close(); + + + try { + InputStreamReader r = new InputStreamReader(uc.getInputStream(), "UTF-8"); + if (type==null) return null; + return MAPPER.readValue(r,type); + } catch (IOException e) { + throw (IOException)new IOException(IOUtils.toString(uc.getErrorStream(),"UTF-8")).initCause(e); + } + } +} diff --git a/src/test/java/org/kohsuke/AppTest.java b/src/test/java/org/kohsuke/AppTest.java new file mode 100644 index 000000000..c6e4c9bab --- /dev/null +++ b/src/test/java/org/kohsuke/AppTest.java @@ -0,0 +1,21 @@ +package org.kohsuke; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.kohsuke.github.GitHub; + +import java.io.IOException; + +/** + * Unit test for simple App. + */ +public class AppTest extends TestCase { + public void testApp() throws IOException { + GitHub hub = new GitHub("kohsuke","9138245daf860415dfc66419177d95da"); +// hub.createRepository("test","test repository",null,true); +// hub.getUser("kohsuke").getRepository("test").delete(); + + System.out.println(hub.getUser("kohsuke").getRepository("hudson").getCollaborators()); + } +}