From efc91b8de2e6acc5fd198d092104fbb5016951e7 Mon Sep 17 00:00:00 2001 From: Jeremie Bresson Date: Mon, 9 Dec 2024 09:16:13 +0100 Subject: [PATCH] BoardApi fixes and group support --- .../main/java/org/gitlab4j/api/BoardsApi.java | 417 +++++++++++++++++- .../org/gitlab4j/api/models/AbstractUser.java | 9 + .../java/org/gitlab4j/api/models/Board.java | 56 ++- .../org/gitlab4j/api/models/BoardList.java | 54 +++ .../org/gitlab4j/api/models/Iteration.java | 6 + .../java/org/gitlab4j/api/models/Label.java | 9 + .../gitlab4j/models/TestGitLabApiBeans.java | 8 +- .../org/gitlab4j/models/epic-issue.json | 4 +- .../org/gitlab4j/models/group-board.json | 102 +++++ .../resources/org/gitlab4j/models/issue.json | 4 +- .../org/gitlab4j/models/iteration.json | 4 +- .../org/gitlab4j/models/project-board.json | 35 +- 12 files changed, 685 insertions(+), 23 deletions(-) create mode 100644 gitlab4j-models/src/test/resources/org/gitlab4j/models/group-board.json diff --git a/gitlab4j-api/src/main/java/org/gitlab4j/api/BoardsApi.java b/gitlab4j-api/src/main/java/org/gitlab4j/api/BoardsApi.java index 2cf0fe78a..8a585dfc9 100644 --- a/gitlab4j-api/src/main/java/org/gitlab4j/api/BoardsApi.java +++ b/gitlab4j-api/src/main/java/org/gitlab4j/api/BoardsApi.java @@ -122,8 +122,6 @@ public Optional getOptionalBoard(Object projectIdOrPath, Long boardId) { /** * Creates a new Issue Board. * - *

NOTE: This is only available in GitLab EE

- * *
GitLab Endpoint: POST /projects/:id/boards
* * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance @@ -141,13 +139,13 @@ public Board createBoard(Object projectIdOrPath, String name) throws GitLabApiEx /** * Updates an existing Issue Board. * - *

NOTE: This is only available in GitLab EE

- * *
GitLab Endpoint: PUT /projects/:id/boards/:board_id
* * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance, required * @param boardId the ID of the board, required * @param name the new name of the board, optional (can be null) + * @param hideBacklogList hide the Open list, optional (can be null) + * @param hideClosedList hide the Closed list, optional (can be null) * @param assigneeId the assignee the board should be scoped to, optional (can be null) * @param milestoneId the milestone the board should be scoped to, optional (can be null) * @param labels a comma-separated list of label names which the board should be scoped to, optional (can be null) @@ -155,10 +153,12 @@ public Board createBoard(Object projectIdOrPath, String name) throws GitLabApiEx * @return the updated Board instance * @throws GitLabApiException if any exception occurs */ - public BoardList updateBoard( + public Board updateBoard( Object projectIdOrPath, Long boardId, String name, + Boolean hideBacklogList, + Boolean hideClosedList, Long assigneeId, Long milestoneId, String labels, @@ -166,10 +166,13 @@ public BoardList updateBoard( throws GitLabApiException { GitLabApiForm formData = new GitLabApiForm() .withParam("name", name) + .withParam("hide_backlog_list", hideBacklogList) + .withParam("hide_closed_list", hideClosedList) .withParam("assignee_id", assigneeId) .withParam("milestone_id", milestoneId) .withParam("labels", labels) .withParam("weight", weight); + Response response = put( Response.Status.OK, formData.asMap(), @@ -177,14 +180,12 @@ public BoardList updateBoard( getProjectIdOrPath(projectIdOrPath), "boards", boardId); - return (response.readEntity(BoardList.class)); + return (response.readEntity(Board.class)); } /** * Soft deletes an existing Issue Board. * - *

NOTE: This is only available in GitLab EE

- * *
GitLab Endpoint: DELETE /projects/:id/boards/:board_id
* * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance @@ -323,12 +324,21 @@ public Optional getOptionalBoardList(Object projectIdOrPath, Long boa * * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance * @param boardId the ID of the board - * @param labelId the ID of the label + * @param labelId the ID of the label, optional (can be null) + * @param assigneeId The ID of a user. Premium and Ultimate only, optional (can be null) + * @param milestoneId The ID of a milestone. Premium and Ultimate only, optional (can be null) + * @param iterationId The ID of a milestone. Premium and Ultimate only, optional (can be null) * @return the created BoardList instance * @throws GitLabApiException if any exception occurs */ - public BoardList createBoardList(Object projectIdOrPath, Long boardId, Long labelId) throws GitLabApiException { - GitLabApiForm formData = new GitLabApiForm().withParam("label_id", labelId, true); + public BoardList createBoardList( + Object projectIdOrPath, Long boardId, Long labelId, Long assigneeId, Long milestoneId, Long iterationId) + throws GitLabApiException { + GitLabApiForm formData = new GitLabApiForm() + .withParam("label_id", labelId) + .withParam("assignee_id", assigneeId) + .withParam("milestone_id", milestoneId) + .withParam("iteration_id", iterationId); Response response = post( Response.Status.CREATED, formData, @@ -340,6 +350,23 @@ public BoardList createBoardList(Object projectIdOrPath, Long boardId, Long labe return (response.readEntity(BoardList.class)); } + /** + * Creates a new Issue Board list. + * + *
GitLab Endpoint: POST /projects/:id/boards/:board_id/lists
+ * + * @param projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance + * @param boardId the ID of the board + * @param labelId the ID of the label + * @return the created BoardList instance + * @throws GitLabApiException if any exception occurs + * @deprecated use {@link #createBoardList(Object, Long, Long, Long, Long, Long)} instead + */ + @Deprecated + public BoardList createBoardList(Object projectIdOrPath, Long boardId, Long labelId) throws GitLabApiException { + return createBoardList(projectIdOrPath, boardId, labelId, null, null, null); + } + /** * Updates an existing Issue Board list. This call is used to change list position. * @@ -388,4 +415,372 @@ public void deleteBoardList(Object projectIdOrPath, Long boardId, Long listId) t "lists", listId); } + + /** + * Lists Issue Boards in the given group. + * + *
GitLab Endpoint: GET /groups/:id/boards
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @return a list of group's issue boards + * @throws GitLabApiException if any exception occurs + */ + public List getGroupBoards(Object groupIdOrPath) throws GitLabApiException { + return (getGroupBoards(groupIdOrPath, getDefaultPerPage()).all()); + } + + /** + * Get all issue boards for the specified group using the specified page and per page setting + * + *
GitLab Endpoint: GET /groups/:id/boards
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param page the page to get + * @param perPage the number of items per page + * @return a list of group's Boards in the specified range + * @throws GitLabApiException if any exception occurs + */ + public List getGroupBoards(Object groupIdOrPath, int page, int perPage) throws GitLabApiException { + Response response = get( + jakarta.ws.rs.core.Response.Status.OK, + getPageQueryParams(page, perPage), + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards"); + return (response.readEntity(new GenericType>() {})); + } + + /** + * Get a Pager of all issue boards for the specified group. + * + *
GitLab Endpoint: GET /groups/:id/boards
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param itemsPerPage the number of items per page + * @return a Pager of group's issue boards + * @throws GitLabApiException if any exception occurs + */ + public Pager getGroupBoards(Object groupIdOrPath, int itemsPerPage) throws GitLabApiException { + return (new Pager( + this, Board.class, itemsPerPage, null, "groups", getGroupIdOrPath(groupIdOrPath), "boards")); + } + + /** + * Get a Stream of all issue boards for the specified group. + * + *
GitLab Endpoint: GET /groups/:id/boards
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @return a Stream of group's issue boards + * @throws GitLabApiException if any exception occurs + */ + public Stream getGroupBoardsStream(Object groupIdOrPath) throws GitLabApiException { + return (getGroupBoards(groupIdOrPath, getDefaultPerPage()).stream()); + } + + /** + * Get a single issue board. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @return a Board instance for the specified board ID + * @throws GitLabApiException if any exception occurs + */ + public Board getGroupBoard(Object groupIdOrPath, Long boardId) throws GitLabApiException { + Response response = get(Response.Status.OK, null, "groups", getGroupIdOrPath(groupIdOrPath), "boards", boardId); + return (response.readEntity(Board.class)); + } + + /** + * Get an issue board as an Optional instance. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @return the Board instance for the specified board ID as an Optional instance + */ + public Optional getOptionalGroupBoard(Object groupIdOrPath, Long boardId) { + try { + return (Optional.ofNullable(getGroupBoard(groupIdOrPath, boardId))); + } catch (GitLabApiException glae) { + return (GitLabApi.createOptionalFromException(glae)); + } + } + + /** + * Creates a new Issue Board. + * + *
GitLab Endpoint: POST /groups/:id/boards
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param name the name for the new board + * @return the created Board instance + * @throws GitLabApiException if any exception occurs + */ + public Board createGroupBoard(Object groupIdOrPath, String name) throws GitLabApiException { + GitLabApiForm formData = new GitLabApiForm().withParam("name", name, true); + Response response = + post(Response.Status.CREATED, formData.asMap(), "groups", getGroupIdOrPath(groupIdOrPath), "boards"); + return (response.readEntity(Board.class)); + } + + /** + * Updates an existing Issue Board. + * + *
GitLab Endpoint: PUT /groups/:id/boards/:board_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance, required + * @param boardId the ID of the board, required + * @param name the new name of the board, optional (can be null) + * @param hideBacklogList hide the Open list, optional (can be null) + * @param hideClosedList hide the Closed list, optional (can be null) + * @param assigneeId the assignee the board should be scoped to, optional (can be null) + * @param milestoneId the milestone the board should be scoped to, optional (can be null) + * @param labels a comma-separated list of label names which the board should be scoped to, optional (can be null) + * @param weight the weight range from 0 to 9, to which the board should be scoped to, optional (can be null) + * @return the updated Board instance + * @throws GitLabApiException if any exception occurs + */ + public Board updateGroupBoard( + Object groupIdOrPath, + Long boardId, + String name, + Boolean hideBacklogList, + Boolean hideClosedList, + Long assigneeId, + Long milestoneId, + String labels, + Integer weight) + throws GitLabApiException { + GitLabApiForm formData = new GitLabApiForm() + .withParam("name", name) + .withParam("hide_backlog_list", hideBacklogList) + .withParam("hide_closed_list", hideClosedList) + .withParam("assignee_id", assigneeId) + .withParam("milestone_id", milestoneId) + .withParam("labels", labels) + .withParam("weight", weight); + Response response = + put(Response.Status.OK, formData.asMap(), "groups", getGroupIdOrPath(groupIdOrPath), "boards", boardId); + return (response.readEntity(Board.class)); + } + + /** + * Soft deletes an existing Issue Board. + * + *
GitLab Endpoint: DELETE /groups/:id/boards/:board_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @throws GitLabApiException if any exception occurs + */ + public void deleteGroupBoard(Object groupIdOrPath, Long boardId) throws GitLabApiException { + delete(Response.Status.NO_CONTENT, null, "groups", getGroupIdOrPath(groupIdOrPath), "boards", boardId); + } + + /** + * Get a list of the board’s lists. Does not include open and closed lists. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id/lists
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @return a list of the issue board's lists + * @throws GitLabApiException if any exception occurs + */ + public List getGroupBoardLists(Object groupIdOrPath, Long boardId) throws GitLabApiException { + return (getGroupBoardLists(groupIdOrPath, boardId, getDefaultPerPage()).all()); + } + + /** + * Get a list of the board’s lists for the specified group to using the specified page and per page setting. + * Does not include open and closed lists. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id/lists
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param page the page to get + * @param perPage the number of Boards per page + * @return a list of the issue board's lists in the specified range + * @throws GitLabApiException if any exception occurs + */ + public List getGroupBoardLists(Object groupIdOrPath, Long boardId, int page, int perPage) + throws GitLabApiException { + Response response = get( + jakarta.ws.rs.core.Response.Status.OK, + getPageQueryParams(page, perPage), + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards", + boardId, + "lists"); + return (response.readEntity(new GenericType>() {})); + } + + /** + * Get a Pager of the board’s lists. Does not include open and closed lists. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id/lists
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param itemsPerPage the number of Board instances that will be fetched per page + * @return a Pager of the issue board's lists + * @throws GitLabApiException if any exception occurs + */ + public Pager getGroupBoardLists(Object groupIdOrPath, Long boardId, int itemsPerPage) + throws GitLabApiException { + return (new Pager( + this, + BoardList.class, + itemsPerPage, + null, + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards", + boardId, + "lists")); + } + + /** + * Get a Stream of the board’s lists. Does not include open and closed lists. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id/lists
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @return a Stream of the issue board's lists + * @throws GitLabApiException if any exception occurs + */ + public Stream getGroupBoardsListsStream(Object groupIdOrPath, Long boardId) throws GitLabApiException { + return (getGroupBoardLists(groupIdOrPath, boardId, getDefaultPerPage()).stream()); + } + + /** + * Get a single issue board list. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id/lists/:list_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param listId the ID of the board lists to get + * @return a BoardList instance for the specified board ID and list ID + * @throws GitLabApiException if any exception occurs + */ + public BoardList getGroupBoardList(Object groupIdOrPath, Long boardId, Long listId) throws GitLabApiException { + Response response = get( + Response.Status.OK, + null, + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards", + boardId, + "lists", + listId); + return (response.readEntity(BoardList.class)); + } + + /** + * Get a single issue board list as an Optional instance. + * + *
GitLab Endpoint: GET /groups/:id/boards/:board_id/lists/:list_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param listId the ID of the board lists to get + * @return a BoardList instance for the specified board ID and list ID as an Optional instance + */ + public Optional getOptionalGroupBoardList(Object groupIdOrPath, Long boardId, Long listId) { + try { + return (Optional.ofNullable(getGroupBoardList(groupIdOrPath, boardId, listId))); + } catch (GitLabApiException glae) { + return (GitLabApi.createOptionalFromException(glae)); + } + } + + /** + * Creates a new Issue Board list. + * + *
GitLab Endpoint: POST /groups/:id/boards/:board_id/lists
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param labelId the ID of the label + * @param assigneeId The ID of a user. Premium and Ultimate only, optional (can be null) + * @param milestoneId The ID of a milestone. Premium and Ultimate only, optional (can be null) + * @param iterationId The ID of a milestone. Premium and Ultimate only, optional (can be null) + * @return the created BoardList instance + * @throws GitLabApiException if any exception occurs + */ + public BoardList createGroupBoardList( + Object groupIdOrPath, Long boardId, Long labelId, Long assigneeId, Long milestoneId, Long iterationId) + throws GitLabApiException { + GitLabApiForm formData = new GitLabApiForm() + .withParam("label_id", labelId) + .withParam("assignee_id", assigneeId) + .withParam("milestone_id", milestoneId) + .withParam("iteration_id", iterationId); + Response response = post( + Response.Status.CREATED, + formData, + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards", + boardId, + "lists"); + return (response.readEntity(BoardList.class)); + } + + /** + * Updates an existing Issue Board list. This call is used to change list position. + * + *
GitLab Endpoint: PUT /groups/:id/boards/:board_id/lists/:list_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param listId the ID of the list + * @param position the new position for the list + * @return the updated BoardList instance + * @throws GitLabApiException if any exception occurs + */ + public BoardList updateGroupBoardList(Object groupIdOrPath, Long boardId, Long listId, Integer position) + throws GitLabApiException { + GitLabApiForm formData = new GitLabApiForm().withParam("position", position, true); + Response response = putWithFormData( + Response.Status.OK, + formData, + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards", + boardId, + "lists", + listId); + return (response.readEntity(BoardList.class)); + } + + /** + * Soft deletes an existing Issue Board list. Only for admins and group owners. + * + *
GitLab Endpoint: DELETE /groups/:id/boards/:board_id/lists/:list_id
+ * + * @param groupIdOrPath the group in the form of an Long(ID), String(path), or Group instance + * @param boardId the ID of the board + * @param listId the ID of the list + * @throws GitLabApiException if any exception occurs + */ + public void deleteGroupBoardList(Object groupIdOrPath, Long boardId, Long listId) throws GitLabApiException { + delete( + Response.Status.NO_CONTENT, + null, + "groups", + getGroupIdOrPath(groupIdOrPath), + "boards", + boardId, + "lists", + listId); + } } diff --git a/gitlab4j-models/src/main/java/org/gitlab4j/api/models/AbstractUser.java b/gitlab4j-models/src/main/java/org/gitlab4j/api/models/AbstractUser.java index fe22106e5..dadc9b741 100644 --- a/gitlab4j-models/src/main/java/org/gitlab4j/api/models/AbstractUser.java +++ b/gitlab4j-models/src/main/java/org/gitlab4j/api/models/AbstractUser.java @@ -17,6 +17,7 @@ public abstract class AbstractUser> implements Seriali private Long id; private String name; private String state; + private Boolean locked; private String username; private String webUrl; @@ -60,6 +61,14 @@ public void setName(String name) { this.name = name; } + public Boolean getLocked() { + return locked; + } + + public void setLocked(Boolean locked) { + this.locked = locked; + } + public String getState() { return state; } diff --git a/gitlab4j-models/src/main/java/org/gitlab4j/api/models/Board.java b/gitlab4j-models/src/main/java/org/gitlab4j/api/models/Board.java index 802bd78eb..5e5b2b355 100644 --- a/gitlab4j-models/src/main/java/org/gitlab4j/api/models/Board.java +++ b/gitlab4j-models/src/main/java/org/gitlab4j/api/models/Board.java @@ -10,9 +10,15 @@ public class Board implements Serializable { private Long id; private String name; + private Boolean hideBacklogList; + private Boolean hideClosedList; private Project project; - private Milestone milestone; private List lists; + private Group group; + private Milestone milestone; + private Assignee assignee; + private List