Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.

Commit 4660c6d

Browse files
committed
Merge pull request hub4j#192
Changing GHHook to abstract is a binary incompatible change in theory, but given the way this class is designed it is difficult to imagine any client code instantiating this class. So I think it is OK.
2 parents 8b4312a + e239ef5 commit 4660c6d

7 files changed

Lines changed: 251 additions & 54 deletions

File tree

src/main/java/org/kohsuke/github/GHEvent.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public enum GHEvent {
2929
PULL_REQUEST_REVIEW_COMMENT,
3030
PUSH,
3131
RELEASE,
32+
REPOSITORY, // only valid for org hooks
3233
STATUS,
3334
TEAM_ADD,
3435
WATCH,

src/main/java/org/kohsuke/github/GHHook.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,12 @@
1111
/**
1212
* @author Kohsuke Kawaguchi
1313
*/
14-
public class GHHook extends GHObject {
15-
/**
16-
* Repository that the hook belongs to.
17-
*/
18-
/*package*/ transient GHRepository repository;
19-
14+
public abstract class GHHook extends GHObject {
2015
String name;
2116
List<String> events;
2217
boolean active;
2318
Map<String,String> config;
2419

25-
/*package*/ GHHook wrap(GHRepository owner) {
26-
this.repository = owner;
27-
return this;
28-
}
29-
3020
public String getName() {
3121
return name;
3222
}
@@ -50,7 +40,7 @@ public Map<String, String> getConfig() {
5040
* Deletes this hook.
5141
*/
5242
public void delete() throws IOException {
53-
new Requester(repository.root).method("DELETE").to(String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id));
43+
new Requester(getRoot()).method("DELETE").to(getApiRoute());
5444
}
5545

5646
/**
@@ -60,4 +50,8 @@ public void delete() throws IOException {
6050
public URL getHtmlUrl() {
6151
return null;
6252
}
53+
54+
abstract GitHub getRoot();
55+
56+
abstract String getApiRoute();
6357
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package org.kohsuke.github;
2+
3+
import java.io.IOException;
4+
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.Collection;
7+
import java.util.List;
8+
import java.util.Locale;
9+
import java.util.Map;
10+
11+
/**
12+
* Utility class for creating and retrieving webhooks; removes duplication between GHOrganization and GHRepository
13+
* functionality
14+
*/
15+
class GHHooks {
16+
static abstract class Context {
17+
private final GitHub root;
18+
19+
private Context(GitHub root) {
20+
this.root = root;
21+
}
22+
23+
public List<GHHook> getHooks() throws IOException {
24+
List<GHHook> list = new ArrayList<GHHook>(Arrays.asList(
25+
root.retrieve().to(collection(), collectionClass())));
26+
for (GHHook h : list)
27+
wrap(h);
28+
return list;
29+
}
30+
31+
public GHHook getHook(int id) throws IOException {
32+
GHHook hook = root.retrieve().to(collection() + "/" + id, clazz());
33+
return wrap(hook);
34+
}
35+
36+
public GHHook createHook(String name, Map<String, String> config, Collection<GHEvent> events, boolean active) throws IOException {
37+
List<String> ea = null;
38+
if (events!=null) {
39+
ea = new ArrayList<String>();
40+
for (GHEvent e : events)
41+
ea.add(e.name().toLowerCase(Locale.ENGLISH));
42+
}
43+
44+
GHHook hook = new Requester(root)
45+
.with("name", name)
46+
.with("active", active)
47+
._with("config", config)
48+
._with("events", ea)
49+
.to(collection(), clazz());
50+
51+
return wrap(hook);
52+
}
53+
54+
abstract String collection();
55+
56+
abstract Class<? extends GHHook[]> collectionClass();
57+
58+
abstract Class<? extends GHHook> clazz();
59+
60+
abstract GHHook wrap(GHHook hook);
61+
}
62+
63+
private static class RepoContext extends Context {
64+
private final GHRepository repository;
65+
private final GHUser owner;
66+
67+
private RepoContext(GHRepository repository, GHUser owner) {
68+
super(repository.root);
69+
this.repository = repository;
70+
this.owner = owner;
71+
}
72+
73+
@Override
74+
String collection() {
75+
return String.format("/repos/%s/%s/hooks", owner.getLogin(), repository.getName());
76+
}
77+
78+
@Override
79+
Class<? extends GHHook[]> collectionClass() {
80+
return GHRepoHook[].class;
81+
}
82+
83+
@Override
84+
Class<? extends GHHook> clazz() {
85+
return GHRepoHook.class;
86+
}
87+
88+
@Override
89+
GHHook wrap(GHHook hook) {
90+
return ((GHRepoHook)hook).wrap(repository);
91+
}
92+
}
93+
94+
private static class OrgContext extends Context {
95+
private final GHOrganization organization;
96+
97+
private OrgContext(GHOrganization organization) {
98+
super(organization.root);
99+
this.organization = organization;
100+
}
101+
102+
@Override
103+
String collection() {
104+
return String.format("/orgs/%s/hooks", organization.getLogin());
105+
}
106+
107+
@Override
108+
Class<? extends GHHook[]> collectionClass() {
109+
return GHOrgHook[].class;
110+
}
111+
112+
@Override
113+
Class<? extends GHHook> clazz() {
114+
return GHOrgHook.class;
115+
}
116+
117+
@Override
118+
GHHook wrap(GHHook hook) {
119+
return ((GHOrgHook)hook).wrap(organization);
120+
}
121+
}
122+
123+
static Context repoContext(GHRepository repository, GHUser owner) {
124+
return new RepoContext(repository, owner);
125+
}
126+
127+
static Context orgContext(GHOrganization organization) {
128+
return new OrgContext(organization);
129+
}
130+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* © Copyright 2015 - SourceClear Inc
3+
*/
4+
5+
package org.kohsuke.github;
6+
7+
class GHOrgHook extends GHHook {
8+
/**
9+
* Organization that the hook belongs to.
10+
*/
11+
/*package*/ transient GHOrganization organization;
12+
13+
/*package*/ GHOrgHook wrap(GHOrganization owner) {
14+
this.organization = owner;
15+
return this;
16+
}
17+
18+
@Override
19+
GitHub getRoot() {
20+
return organization.root;
21+
}
22+
23+
@Override
24+
String getApiRoute() {
25+
return String.format("/orgs/%s/hooks/%d", organization.getLogin(), id);
26+
}
27+
}

src/main/java/org/kohsuke/github/GHOrganization.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package org.kohsuke.github;
22

33
import java.io.IOException;
4+
import java.net.URL;
45
import java.util.ArrayList;
56
import java.util.Arrays;
67
import java.util.Collection;
8+
import java.util.Collections;
79
import java.util.List;
10+
import java.util.Locale;
811
import java.util.Map;
912
import java.util.TreeMap;
1013

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

3235
public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException {
@@ -252,4 +255,39 @@ protected void wrapUp(GHRepository[] page) {
252255
}
253256
};
254257
}
258+
259+
/**
260+
* Retrieves the currently configured hooks.
261+
*/
262+
public List<GHHook> getHooks() throws IOException {
263+
return GHHooks.orgContext(this).getHooks();
264+
}
265+
266+
public GHHook getHook(int id) throws IOException {
267+
return GHHooks.orgContext(this).getHook(id);
268+
}
269+
270+
/**
271+
*
272+
* See https://api.github.com/hooks for possible names and their configuration scheme.
273+
* TODO: produce type-safe binding
274+
*
275+
* @param name
276+
* Type of the hook to be created. See https://api.github.com/hooks for possible names.
277+
* @param config
278+
* The configuration hash.
279+
* @param events
280+
* Can be null. Types of events to hook into.
281+
*/
282+
public GHHook createHook(String name, Map<String,String> config, Collection<GHEvent> events, boolean active) throws IOException {
283+
return GHHooks.orgContext(this).createHook(name, config, events, active);
284+
}
285+
286+
public GHHook createWebHook(URL url, Collection<GHEvent> events) throws IOException {
287+
return createHook("web", Collections.singletonMap("url", url.toExternalForm()),events,true);
288+
}
289+
290+
public GHHook createWebHook(URL url) throws IOException {
291+
return createWebHook(url, null);
292+
}
255293
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.kohsuke.github;
2+
3+
class GHRepoHook extends GHHook {
4+
/**
5+
* Repository that the hook belongs to.
6+
*/
7+
/*package*/ transient GHRepository repository;
8+
9+
/*package*/ GHRepoHook wrap(GHRepository owner) {
10+
this.repository = owner;
11+
return this;
12+
}
13+
14+
@Override
15+
GitHub getRoot() {
16+
return repository.root;
17+
}
18+
19+
@Override
20+
String getApiRoute() {
21+
return String.format("/repos/%s/%s/hooks/%d", repository.getOwnerName(), repository.getName(), id);
22+
}
23+
}

0 commit comments

Comments
 (0)