diff --git a/src/main/java/org/gitlab4j/api/ProjectApi.java b/src/main/java/org/gitlab4j/api/ProjectApi.java index 1183103ad68dfc15a4fb4c045ea6b43bc160aae4..848f6bdca2394f4000ec574b86da34d8bf2529d5 100644 --- a/src/main/java/org/gitlab4j/api/ProjectApi.java +++ b/src/main/java/org/gitlab4j/api/ProjectApi.java @@ -54,6 +54,8 @@ import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.ProjectApprovalsConfig; import org.gitlab4j.api.models.ProjectFetches; import org.gitlab4j.api.models.ProjectFilter; +import org.gitlab4j.api.models.ProjectGroupsFilter; +import org.gitlab4j.api.models.ProjectGroup; import org.gitlab4j.api.models.ProjectHook; import org.gitlab4j.api.models.ProjectUser; import org.gitlab4j.api.models.PushRules; @@ -1624,7 +1626,7 @@ public class ProjectApi extends AbstractApi implements Constants { * @throws GitLabApiException if any exception occurs */ public Member getMember(Object projectIdOrPath, Long userId) throws GitLabApiException { - return (getMember(projectIdOrPath, userId, false)); + return (getMember(projectIdOrPath, userId, false)); } /** @@ -1926,6 +1928,90 @@ public class ProjectApi extends AbstractApi implements Constants { return (getProjectUsers(projectIdOrPath, search, getDefaultPerPage()).stream()); } + /** + * Get a list of the ancestor groups for a given project. + * + *
GitLab Endpoint: GET /projects/:id/groups
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance, required + * @return the ancestor groups for a given project + * @throws GitLabApiException if any exception occurs + */ + public List getProjectGroups(Object projectIdOrPath) throws GitLabApiException { + return (getProjectGroups(projectIdOrPath, new ProjectGroupsFilter(), getDefaultPerPage()).all()); + } + + /** + * Get a Pager of the ancestor groups for a given project. + * + *
GitLab Endpoint: GET /projects/:id/groups
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance + * @param itemsPerPage the number of Project instances that will be fetched per page + * @return a Pager of the ancestor groups for a given project + * @throws GitLabApiException if any exception occurs + */ + public Pager getProjectGroups(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException { + return (getProjectGroups(projectIdOrPath, new ProjectGroupsFilter(), itemsPerPage)); + } + + /** + * Get a Stream of the ancestor groups for a given project. + * + *
GitLab Endpoint: GET /projects/:id/groups
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance, required + * @return a Stream of the ancestor groups for a given project + * @throws GitLabApiException if any exception occurs + */ + public Stream getProjectGroupsStream(Object projectIdOrPath) throws GitLabApiException { + return (getProjectGroups(projectIdOrPath, new ProjectGroupsFilter(), getDefaultPerPage()).stream()); + } + + /** + * Get a list of the ancestor groups for a given project matching the specified filter. + * + *
GitLab Endpoint: GET /projects/:id/groups
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance, required + * @param filter the ProjectGroupsFilter to match against + * @return the ancestor groups for a given project + * @throws GitLabApiException if any exception occurs + */ + public List getProjectGroups(Object projectIdOrPath, ProjectGroupsFilter filter) throws GitLabApiException { + return (getProjectGroups(projectIdOrPath, filter, getDefaultPerPage()).all()); + } + + /** + * Get a Pager of the ancestor groups for a given project matching the specified filter. + * + *
GitLab Endpoint: GET /projects/:id/groups
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance + * @param filter the ProjectGroupsFilter to match against + * @param itemsPerPage the number of Project instances that will be fetched per page + * @return a Pager of the ancestor groups for a given project + * @throws GitLabApiException if any exception occurs + */ + public Pager getProjectGroups(Object projectIdOrPath, ProjectGroupsFilter filter, int itemsPerPage) throws GitLabApiException { + GitLabApiForm formData = filter.getQueryParams(); + return (new Pager(this, ProjectGroup.class, itemsPerPage, formData.asMap(), "projects", getProjectIdOrPath(projectIdOrPath), "groups")); + } + + /** + * Get a Stream of the ancestor groups for a given project matching the specified filter. + * + *
GitLab Endpoint: GET /projects/:id/groups
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance, required + * @param filter the ProjectGroupsFilter to match against + * @return a Stream of the ancestor groups for a given project + * @throws GitLabApiException if any exception occurs + */ + public Stream getProjectGroupsStream(Object projectIdOrPath, ProjectGroupsFilter filter) throws GitLabApiException { + return (getProjectGroups(projectIdOrPath, filter, getDefaultPerPage()).stream()); + } + /** * Get the project events for specific project. Sorted from newest to latest. * diff --git a/src/main/java/org/gitlab4j/api/models/AbstractGroup.java b/src/main/java/org/gitlab4j/api/models/AbstractGroup.java new file mode 100644 index 0000000000000000000000000000000000000000..ac990e89736811f8a82f8871e701d8a7258c2fb6 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/AbstractGroup.java @@ -0,0 +1,106 @@ + +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) +public abstract class AbstractGroup> { + + private Long id; + private String name; + private String avatarUrl; + private String webUrl; + private String fullName; + private String fullPath; + + public Long getId() { + return this.id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAvatarUrl() { + return avatarUrl; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + + public String getWebUrl() { + return webUrl; + } + + public void setWebUrl(String webUrl) { + this.webUrl = webUrl; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getFullPath() { + return fullPath; + } + + public void setFullPath(String fullPath) { + this.fullPath = fullPath; + } + + @SuppressWarnings("unchecked") + public G withId(Long id) { + this.id = id; + return (G)this; + } + + @SuppressWarnings("unchecked") + public G withName(String name) { + this.name = name; + return (G)this; + } + + @SuppressWarnings("unchecked") + public G withAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + return (G)this; + } + + @SuppressWarnings("unchecked") + public G withWebUrl(String url) { + this.webUrl = url; + return (G)this; + } + + @SuppressWarnings("unchecked") + public G withFullName(String fullName) { + this.fullName = fullName; + return (G)this; + } + + @SuppressWarnings("unchecked") + public G withFullPath(String fullPath) { + this.fullPath = fullPath; + return (G)this; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/Group.java b/src/main/java/org/gitlab4j/api/models/Group.java index 21209d6dfabdfa0d33e4e38376779160c51b06ec..d7d4d056086f6112dcdbb1f71ffc55c3f37141b1 100644 --- a/src/main/java/org/gitlab4j/api/models/Group.java +++ b/src/main/java/org/gitlab4j/api/models/Group.java @@ -7,7 +7,7 @@ import org.gitlab4j.api.utils.JacksonJson; import java.util.Date; import java.util.List; -public class Group { +public class Group extends AbstractGroup { public class Statistics { private Long storageSize; @@ -49,17 +49,11 @@ public class Group { } - private Long id; - private String name; private String path; private String description; private Visibility visibility; private Boolean lfsEnabled; - private String avatarUrl; - private String webUrl; private Boolean requestAccessEnabled; - private String fullName; - private String fullPath; private Long parentId; private Integer sharedRunnersMinutesLimit; private Statistics statistics; @@ -71,22 +65,6 @@ public class Group { @JsonSerialize(using = JacksonJson.DateOnlySerializer.class) private Date markedForDeletionOn; - public Long getId() { - return this.id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - public String getPath() { return this.path; } @@ -119,22 +97,6 @@ public class Group { this.lfsEnabled = lfsEnabled; } - public String getAvatarUrl() { - return avatarUrl; - } - - public void setAvatarUrl(String avatarUrl) { - this.avatarUrl = avatarUrl; - } - - public String getWebUrl() { - return webUrl; - } - - public void setWebUrl(String webUrl) { - this.webUrl = webUrl; - } - public Boolean getRequestAccessEnabled() { return requestAccessEnabled; } @@ -143,22 +105,6 @@ public class Group { this.requestAccessEnabled = requestAccessEnabled; } - public String getFullName() { - return fullName; - } - - public void setFullName(String fullName) { - this.fullName = fullName; - } - - public String getFullPath() { - return fullPath; - } - - public void setFullPath(String fullPath) { - this.fullPath = fullPath; - } - public Long getParentId() { return parentId; } @@ -223,16 +169,6 @@ public class Group { this.runnersToken = runnersToken; } - public Group withId(Long id) { - this.id = id; - return this; - } - - public Group withName(String name) { - this.name = name; - return this; - } - public Group withPath(String path) { this.path = path; return this; @@ -253,31 +189,11 @@ public class Group { return this; } - public Group withAvatarUrl(String avatarUrl) { - this.avatarUrl = avatarUrl; - return this; - } - - public Group withWebUrl(String url) { - this.webUrl = url; - return this; - } - public Group withRequestAccessEnabled(boolean requestAccessEnabled) { this.requestAccessEnabled = requestAccessEnabled; return this; } - public Group withFullName(String fullName) { - this.fullName = fullName; - return this; - } - - public Group withFullPath(String fullPath) { - this.fullPath = fullPath; - return this; - } - public Group withParentId(Long parentId) { this.parentId = parentId; return this; diff --git a/src/main/java/org/gitlab4j/api/models/ProjectGroup.java b/src/main/java/org/gitlab4j/api/models/ProjectGroup.java new file mode 100644 index 0000000000000000000000000000000000000000..b918d411c2852feb8a04ddf898ec10081215b23c --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ProjectGroup.java @@ -0,0 +1,4 @@ +package org.gitlab4j.api.models; + +public class ProjectGroup extends AbstractGroup { +} diff --git a/src/main/java/org/gitlab4j/api/models/ProjectGroupsFilter.java b/src/main/java/org/gitlab4j/api/models/ProjectGroupsFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..fec744748fee6c6d4fcada179f960969dd34e088 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ProjectGroupsFilter.java @@ -0,0 +1,87 @@ +package org.gitlab4j.api.models; + +import java.util.List; + +import org.gitlab4j.api.GitLabApiForm; + +/** + * This class is used to filter Groups when getting lists of groups for a specified project. + */ +public class ProjectGroupsFilter { + + private String search; + private AccessLevel sharedMinAccessLevel; + private Boolean sharedVisibleOnly; + private List skipGroups; + private Boolean withShared; + + /** + * Search for specific groups. + * + * @param search the search criteria + * @return the reference to this ProjectGroupsFilter instance + */ + public ProjectGroupsFilter withSearch(String search) { + this.search = search; + return (this); + } + + /** + * Limit to shared groups with at least this role. + * + * @param sharedMinAccessLevel the minimal role + * @return the reference to this ProjectGroupsFilter instance + */ + public ProjectGroupsFilter withSharedMinAccessLevel(AccessLevel sharedMinAccessLevel) { + this.sharedMinAccessLevel = sharedMinAccessLevel; + return (this); + } + + /** + * Limit to shared groups user has access to. + * + * @param sharedVisibleOnly if true limit to the shared groups user has access to. + * @return the reference to this ProjectGroupsFilter instance + */ + public ProjectGroupsFilter withSharedVisibleOnly(Boolean sharedVisibleOnly) { + this.sharedVisibleOnly = sharedVisibleOnly; + return (this); + } + + /** + * Do not include the provided groups IDs. + * + * @param skipGroups List of group IDs to not include in the search + * @return the reference to this ProjectGroupsFilter instance + */ + public ProjectGroupsFilter withSkipGroups(List skipGroups) { + this.skipGroups = skipGroups; + return (this); + } + + /** + * Include projects shared with this group. + * + * @param withShared if true include projects shared with this group. + * @return the reference to this ProjectGroupsFilter instance + */ + public ProjectGroupsFilter withWithShared(Boolean withShared) { + this.withShared = withShared; + return (this); + } + + /** + * Get the query params specified by this filter. + * + * @return a GitLabApiForm instance holding the query parameters for this ProjectGroupsFilter instance + */ + public GitLabApiForm getQueryParams() { + return (new GitLabApiForm() + .withParam("search", search) + .withParam("shared_min_access_level", sharedMinAccessLevel) + .withParam("shared_visible_only", sharedVisibleOnly) + .withParam("skip_groups", skipGroups) + .withParam("with_shared", withShared) + ); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java index e57743850951a4e3498a4498afeb3c4ecff84f18..0afb446e5e4554e98ccb092945b4163d9380f68d 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java @@ -90,6 +90,7 @@ import org.gitlab4j.api.models.PackageFile; import org.gitlab4j.api.models.Pipeline; import org.gitlab4j.api.models.PipelineSchedule; import org.gitlab4j.api.models.Project; +import org.gitlab4j.api.models.ProjectGroup; import org.gitlab4j.api.models.ProjectApprovalsConfig; import org.gitlab4j.api.models.ProjectFetches; import org.gitlab4j.api.models.ProjectHook; @@ -456,6 +457,12 @@ public class TestGitLabApiBeans { assertTrue(compareJson(artifactFile, "artifacts-file.json")); } + @Test + public void testProjectGroups() throws Exception { + List projectGroups = unmarshalResourceList(ProjectGroup.class, "project-groups.json"); + assertTrue(compareJson(projectGroups, "project-groups.json")); + } + @Test public void testProjectLanguages() throws Exception { Map projectLanguages = unmarshalResourceMap(Float.class, "project-languages.json"); diff --git a/src/test/resources/org/gitlab4j/api/project-groups.json b/src/test/resources/org/gitlab4j/api/project-groups.json new file mode 100644 index 0000000000000000000000000000000000000000..bdea9c542a630f791ed0297f0c9d5b4380dc66de --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/project-groups.json @@ -0,0 +1,18 @@ +[ + { + "id": 1, + "name": "Foobar Group", + "avatar_url": "http://localhost:3000/uploads/group/avatar/1/foo.jpg", + "web_url": "http://localhost:3000/groups/foo-bar", + "full_name": "Foobar Group", + "full_path": "foo-bar" + }, + { + "id": 2, + "name": "Shared Group", + "avatar_url": "http://gitlab.example.com/uploads/group/avatar/1/bar.jpg", + "web_url": "http://gitlab.example.com/groups/foo/bar", + "full_name": "Shared Group", + "full_path": "foo/shared" + } +]