Skip to content

Commit

Permalink
Enable creation and retrieval of org webhooks
Browse files Browse the repository at this point in the history
made GHHook abstract and created two concrete subclasses for org
and repo hooks. Created utility class GHHooks to manage creation
and retrieval of org/repo hooks with minimal code duplication. These
are invoked by GHOrganization and GHRepository respectively.
  • Loading branch information
Chris Hut committed May 15, 2015
1 parent b976e0e commit f4b105b
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 54 deletions.
1 change: 1 addition & 0 deletions src/main/java/org/kohsuke/github/GHEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public enum GHEvent {
PULL_REQUEST_REVIEW_COMMENT,
PUSH,
RELEASE,
REPOSITORY, // only valid for org hooks
STATUS,
TEAM_ADD,
WATCH
Expand Down
18 changes: 6 additions & 12 deletions src/main/java/org/kohsuke/github/GHHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,12 @@
/**
* @author Kohsuke Kawaguchi
*/
public class GHHook extends GHObject {
/**
* Repository that the hook belongs to.
*/
/*package*/ transient GHRepository repository;

public abstract class GHHook extends GHObject {
String name;
List<String> events;
boolean active;
Map<String,String> config;

/*package*/ GHHook wrap(GHRepository owner) {
this.repository = owner;
return this;
}

public String getName() {
return name;
}
Expand All @@ -50,7 +40,7 @@ public Map<String, String> getConfig() {
* Deletes this hook.
*/
public void delete() throws IOException {
new Requester(repository.root).method("DELETE").to(String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id));
new Requester(root()).method("DELETE").to(path());
}

/**
Expand All @@ -60,4 +50,8 @@ public void delete() throws IOException {
public URL getHtmlUrl() {
return null;
}

abstract GitHub root();

abstract String path();
}
130 changes: 130 additions & 0 deletions src/main/java/org/kohsuke/github/GHHooks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.kohsuke.github;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
* Utility class for creating and retrieving webhooks; removes duplication between GHOrganization and GHRepository
* functionality
*/
class GHHooks {
static abstract class Context {
private final GitHub root;

private Context(GitHub root) {
this.root = root;
}

public List<GHHook> getHooks() throws IOException {
List<GHHook> list = new ArrayList<GHHook>(Arrays.asList(
root.retrieve().to(collection(), collectionClass())));
for (GHHook h : list)
wrap(h);
return list;
}

public GHHook getHook(int id) throws IOException {
GHHook hook = root.retrieve().to(collection() + "/" + id, clazz());
return wrap(hook);
}

public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active) throws IOException {
List<String> ea = null;
if (events!=null) {
ea = new ArrayList<String>();
for (GHEvent e : events)
ea.add(e.name().toLowerCase(Locale.ENGLISH));
}

GHHook hook = new Requester(root)
.with("name", name)
.with("active", active)
._with("config", config)
._with("events", ea)
.to(collection(), clazz());

return wrap(hook);
}

abstract String collection();

abstract Class<? extends GHHook[]> collectionClass();

abstract Class<? extends GHHook> clazz();

abstract GHHook wrap(GHHook hook);
}

private static class RepoContext extends Context {
private final GHRepository repository;
private final GHUser owner;

private RepoContext(GHRepository repository, GHUser owner) {
super(repository.root);
this.repository = repository;
this.owner = owner;
}

@Override
String collection() {
return String.format("/repos/%s/%s/hooks", owner.getLogin(), repository.getName());
}

@Override
Class<? extends GHHook[]> collectionClass() {
return GHRepoHook[].class;
}

@Override
Class<? extends GHHook> clazz() {
return GHRepoHook.class;
}

@Override
GHHook wrap(GHHook hook) {
return ((GHRepoHook)hook).wrap(repository);
}
}

private static class OrgContext extends Context {
private final GHOrganization organization;

private OrgContext(GHOrganization organization) {
super(organization.root);
this.organization = organization;
}

@Override
String collection() {
return String.format("/orgs/%s/hooks", organization.getLogin());
}

@Override
Class<? extends GHHook[]> collectionClass() {
return GHOrgHook[].class;
}

@Override
Class<? extends GHHook> clazz() {
return GHOrgHook.class;
}

@Override
GHHook wrap(GHHook hook) {
return ((GHOrgHook)hook).wrap(organization);
}
}

static Context repoContext(GHRepository repository, GHUser owner) {
return new RepoContext(repository, owner);
}

static Context orgContext(GHOrganization organization) {
return new OrgContext(organization);
}
}
27 changes: 27 additions & 0 deletions src/main/java/org/kohsuke/github/GHOrgHook.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* © Copyright 2015 - SourceClear Inc
*/

package org.kohsuke.github;

class GHOrgHook extends GHHook {
/**
* Organization that the hook belongs to.
*/
/*package*/ transient GHOrganization organization;

/*package*/ GHOrgHook wrap(GHOrganization owner) {
this.organization = owner;
return this;
}

@Override
GitHub root() {
return organization.root;
}

@Override
String path() {
return String.format("/orgs/%s/hooks/%d", organization.getLogin(), id);
}
}
40 changes: 39 additions & 1 deletion src/main/java/org/kohsuke/github/GHOrganization.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.kohsuke.github;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

Expand All @@ -26,7 +29,7 @@ public GHRepository createRepository(String name, String description, String hom
GHTeam t = getTeams().get(team);
if (t==null)
throw new IllegalArgumentException("No such team: "+team);
return createRepository(name,description,homepage,t,isPublic);
return createRepository(name, description, homepage, t, isPublic);
}

public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException {
Expand Down Expand Up @@ -252,4 +255,39 @@ protected void wrapUp(GHRepository[] page) {
}
};
}

/**
* Retrieves the currently configured hooks.
*/
public List<GHHook> getHooks() throws IOException {
return GHHooks.orgContext(this).getHooks();
}

public GHHook getHook(int id) throws IOException {
return GHHooks.orgContext(this).getHook(id);
}

/**
*
* See https://api.github.com/hooks for possible names and their configuration scheme.
* TODO: produce type-safe binding
*
* @param name
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
* @param config
* The configuration hash.
* @param events
* Can be null. Types of events to hook into.
*/
public GHHook createHook(String name, Map<String,String> config, Collection<GHEvent> events, boolean active) throws IOException {
return GHHooks.orgContext(this).createHook(name, config, events, active);
}

public GHHook createWebHook(URL url, Collection<GHEvent> events) throws IOException {
return createHook("web", Collections.singletonMap("url", url.toExternalForm()),events,true);
}

public GHHook createWebHook(URL url) throws IOException {
return createWebHook(url, null);
}
}
23 changes: 23 additions & 0 deletions src/main/java/org/kohsuke/github/GHRepoHook.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.kohsuke.github;

class GHRepoHook extends GHHook {
/**
* Repository that the hook belongs to.
*/
/*package*/ transient GHRepository repository;

/*package*/ GHRepoHook wrap(GHRepository owner) {
this.repository = owner;
return this;
}

@Override
GitHub root() {
return repository.root;
}

@Override
String path() {
return String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id);
}
}
Loading

0 comments on commit f4b105b

Please sign in to comment.