diff --git a/src/main/java/org/gitlab4j/api/EpicsApi.java b/src/main/java/org/gitlab4j/api/EpicsApi.java index 5be668c44..9bf4505ba 100644 --- a/src/main/java/org/gitlab4j/api/EpicsApi.java +++ b/src/main/java/org/gitlab4j/api/EpicsApi.java @@ -9,9 +9,14 @@ import jakarta.ws.rs.core.GenericType; import jakarta.ws.rs.core.Response; +import org.gitlab4j.api.models.ChildEpic; +import org.gitlab4j.api.models.CreatedChildEpic; import org.gitlab4j.api.models.Epic; import org.gitlab4j.api.models.EpicIssue; import org.gitlab4j.api.models.EpicIssueLink; +import org.gitlab4j.api.models.LinkType; +import org.gitlab4j.api.models.RelatedEpic; +import org.gitlab4j.api.models.RelatedEpicLink; /** * This class implements the client side API for the GitLab Epics and Epic Issues API calls. @@ -458,4 +463,208 @@ public List updateIssue(Object groupIdOrPath, Long epicIid, Long epic "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", epicIssueId); return response.readEntity(new GenericType>() {}); } + + /** + * Gets all child epics of an epic and the authenticated user has access to. + * + *
GitLab Endpoint: GET /groups/:id/epics/:epic_iid/epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the IID of the epic to get child epics for + * @return a list of all child epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public List getChildEpics(Object groupIdOrPath, Long epicIid) throws GitLabApiException { + return (getChildEpics(groupIdOrPath, epicIid, getDefaultPerPage()).all()); + } + + /** + * Get a Pager of all child epics of an epic and the authenticated user has access to. + * + *
GitLab Endpoint: GET /groups/:id/epics/:epic_iid/epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the IID of the epic to get child epics for + * @param itemsPerPage the number of child epics per page + * @return the Pager of all child epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public Pager getChildEpics(Object groupIdOrPath, Long epicIid, int itemsPerPage) throws GitLabApiException { + return (new Pager(this, ChildEpic.class, itemsPerPage, null, "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "epics")); + } + + /** + * Gets all child epics of an epic and the authenticated user has access to as a Stream. + * + *
GitLab Endpoint: GET /groups/:id/epics/:epic_iid/epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the IID of the epic to get child epics for + * @return a Stream of all child epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public Stream getChildEpicsStream(Object groupIdOrPath, Long epicIid) throws GitLabApiException { + return (getChildEpics(groupIdOrPath, epicIid, getDefaultPerPage()).stream()); + } + + /** + * Creates an association between two epics, designating one as the parent epic and the other as the child epic. A parent epic can have multiple child epics. If the new child epic already belonged to another epic, it is unassigned from that previous parent. + * + *
GitLab Endpoint: POST /groups/:id/epics/:epic_iid/epics/:child_epic_id
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the Epic IID to assign the child epic to + * @param childEpicId the global ID of the child epic. Epic IID can’t be used because they can conflict with epics from other groups. + * @return an ChildEpic instance containing info on the newly assigned child epic + * @throws GitLabApiException if any exception occurs + */ + public ChildEpic assignChildEpic(Object groupIdOrPath, Long epicIid, Long childEpicId) throws GitLabApiException { + Response response = post(Response.Status.CREATED, (Form)null, + "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "epics", childEpicId); + return (response.readEntity(ChildEpic.class)); + } + + /** + * Creates a new epic and associates it with provided parent epic. + * + *
GitLab Endpoint: POST /groups/:id/epics/:epic_iid/epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the Epic IID to assign the child epic to (of the future parent epic) + * @param title the title of a newly created epic + * @param confidential whether the epic should be confidential (optional) + * @return an ChildEpic instance containing info on the newly created and assigned child epic + * @throws GitLabApiException if any exception occurs + */ + public CreatedChildEpic createAndAssignChildEpic(Object groupIdOrPath, Long epicIid, String title, Boolean confidential) throws GitLabApiException { + Form formData = new GitLabApiForm() + .withParam("title", title, true) + .withParam("confidential", confidential); + Response response = post(Response.Status.CREATED, formData.asMap(), + "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "epics"); + return (response.readEntity(CreatedChildEpic.class)); + } + + /** + * Re-order a child epic + * + *
GitLab Endpoint: PUT /groups/:id/epics/:epic_iid/epics/:child_epic_id
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the Epic IID that the child epic is assigned to + * @param childEpicId the ID of the child epic. Epic IID can’t be used because they can conflict with epics from other groups. + * @param moveBeforeId the ID of a sibling epic that should be placed before the child epic (optional) + * @param moveAfterId the ID of a sibling epic that should be placed after the child epic (optional) + * @return a list of all child epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public List reOrderChildEpic(Object groupIdOrPath, Long epicIid, Long childEpicId, Long moveBeforeId, Long moveAfterId) throws GitLabApiException { + GitLabApiForm form = new GitLabApiForm() + .withParam("move_before_id", moveBeforeId) + .withParam("move_after_id", moveAfterId); + Response response = put(Response.Status.OK, form.asMap(), + "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "epics", childEpicId); + return response.readEntity(new GenericType>() {}); + } + + /** + * Unassigns a child epic from a parent epic. + * + *
GitLab Endpoint: DELETE /groups/:id/epics/:epic_iid/epics/:child_epic_id
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the Epic IID to remove the child epic from + * @param childEpicId the ID of the child epic. Epic IID can’t be used because they can conflict with epics from other groups. + * @return an ChildEpic instance containing info on the removed child epic + * @throws GitLabApiException if any exception occurs + */ + public ChildEpic unassignChildEpic(Object groupIdOrPath, Long epicIid, Long childEpicId) throws GitLabApiException { + Response response = delete(Response.Status.OK, null, + "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "epics", childEpicId); + return (response.readEntity(ChildEpic.class)); + } + + /** + * Gets all linked epics of an epic filtered according to the user authorizations. + * + *
GitLab Endpoint: GET /groups/:id/epics/:epic_iid/related_epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the IID of the epic to get child epics for + * @return a list of all related epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public List getRelatedEpics(Object groupIdOrPath, Long epicIid) throws GitLabApiException { + return (getRelatedEpics(groupIdOrPath, epicIid, getDefaultPerPage()).all()); + } + + /** + * Get a Pager of all linked epics of an epic filtered according to the user authorizations. + * + *
GitLab Endpoint: GET /groups/:id/epics/:epic_iid/related_epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the IID of the epic to get child epics for + * @param itemsPerPage the number of child epics per page + * @return the Pager of all related epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public Pager getRelatedEpics(Object groupIdOrPath, Long epicIid, int itemsPerPage) throws GitLabApiException { + return (new Pager(this, RelatedEpic.class, itemsPerPage, null, "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "related_epics")); + } + + /** + * Gets all linked epics of an epic filtered according to the user authorizations to as a Stream. + * + *
GitLab Endpoint: GET /groups/:id/epics/:epic_iid/related_epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the IID of the epic to get child epics for + * @return a Stream of all related epics of the specified epic + * @throws GitLabApiException if any exception occurs + */ + public Stream getRelatedEpicsStream(Object groupIdOrPath, Long epicIid) throws GitLabApiException { + return (getRelatedEpics(groupIdOrPath, epicIid, getDefaultPerPage()).stream()); + } + + /** + * Create a two-way relation between two epics. The user must have at least the Guest role for both groups. + * + *
GitLab Endpoint: POST /groups/:id/epics/:epic_iid/related_epics
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the Epic IID to assign the child epic to + * @param targetGroupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path of the target group’s epic + * @param targetEpicIid the Epic IID of the target group’s epic. + * @param linkType the type of the relation (optional), defaults to {@link LinkType#RELATES_TO}. + * @return an RelatedEpic instance containing info on the newly assigned child epic + * @throws GitLabApiException if any exception occurs + */ + public RelatedEpicLink createRelatedEpicLink(Object groupIdOrPath, Long epicIid, Object targetGroupIdOrPath, Long targetEpicIid, LinkType linkType) throws GitLabApiException { + Form formData = new GitLabApiForm() + .withParam("target_group_id", getGroupIdOrPath(targetGroupIdOrPath), true) + .withParam("target_epic_iid", targetEpicIid, true) + .withParam("link_type", linkType); + Response response = post(Response.Status.CREATED, formData.asMap(), + "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "related_epics"); + return (response.readEntity(RelatedEpicLink.class)); + } + + /** + * Delete a two-way relation between two epics. The user must have at least the Guest role for both groups. + * + *
GitLab Endpoint: DELETE /groups/:id/epics/:epic_iid/related_epics/:related_epic_link_id
+ * + * @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path + * @param epicIid the Epic IID to remove the child epic from + * @param relatedEpicLinkId the ID a related epic link. + * @return an RelatedEpicLink instance containing info on the removed related epic + * @throws GitLabApiException if any exception occurs + */ + public RelatedEpicLink deleteRelatedEpicLink(Object groupIdOrPath, Long epicIid, Long relatedEpicLinkId) throws GitLabApiException { + Response response = delete(Response.Status.OK, null, + "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "related_epics", relatedEpicLinkId); + return (response.readEntity(RelatedEpicLink.class)); + } + } diff --git a/src/main/java/org/gitlab4j/api/models/AbstractEpic.java b/src/main/java/org/gitlab4j/api/models/AbstractEpic.java new file mode 100644 index 000000000..b531f2c2b --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/AbstractEpic.java @@ -0,0 +1,234 @@ +package org.gitlab4j.api.models; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.gitlab4j.api.utils.JacksonJsonEnumHelper; +import org.gitlab4j.api.utils.JacksonJson; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + +public class AbstractEpic> extends AbstractMinimalEpic { + + public enum EpicState { + OPENED, CLOSED, ALL; + + private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(EpicState.class); + + @JsonCreator + public static EpicState forValue(String value) { + return enumHelper.forValue(value); + } + + @JsonValue + public String toValue() { + return (enumHelper.toString(this)); + } + + public String toString() { + return (enumHelper.toString(this)); + } + } + + private Long parentIid; + private String description; + private EpicState state; + private String webUrl; + private References references; + private Author author; + private List labels; + private Date startDate; + private Date dueDate; + private Date endDate; + private Date createdAt; + private Date updatedAt; + private Date closedAt; + private Integer downvotes; + private Integer upvotes; + private String color; + @JsonProperty("_links") + private Map links; + + public Long getParentIid() { + return parentIid; + } + + public void setParentIid(Long parentIid) { + this.parentIid = parentIid; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @SuppressWarnings("unchecked") + public E withDescription(String description) { + this.description = description; + return (E) (this); + } + + public EpicState getState() { + return state; + } + + public void setState(EpicState state) { + this.state = state; + } + + public String getWebUrl() { + return webUrl; + } + + public void setWebUrl(String webUrl) { + this.webUrl = webUrl; + } + + public References getReferences() { + return references; + } + + public void setReferences(References references) { + this.references = references; + } + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } + + @SuppressWarnings("unchecked") + public E withAuthor(Author author) { + this.author = author; + return (E) (this); + } + + public List getLabels() { + return labels; + } + + public void setLabels(List labels) { + this.labels = labels; + } + + @SuppressWarnings("unchecked") + public E withLabels(List labels) { + this.labels = labels; + return (E) (this); + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + @SuppressWarnings("unchecked") + public E withStartDate(Date startDate) { + this.startDate = startDate; + return (E) (this); + } + + public Date getDueDate() { + return dueDate; + } + + public void setDueDate(Date dueDate) { + this.dueDate = dueDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + @SuppressWarnings("unchecked") + public E withEndDate(Date endDate) { + this.endDate = endDate; + return (E) (this); + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Date getClosedAt() { + return closedAt; + } + + public void setClosedAt(Date closedAt) { + this.closedAt = closedAt; + } + + public Integer getDownvotes() { + return downvotes; + } + + public void setDownvotes(Integer downvotes) { + this.downvotes = downvotes; + } + + public Integer getUpvotes() { + return upvotes; + } + + public void setUpvotes(Integer upvotes) { + this.upvotes = upvotes; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + public Map getLinks() { + return links; + } + + public void setLinks(Map links) { + this.links = links; + } + + @JsonIgnore + public String getLinkByName(String name) { + if (links == null || links.isEmpty()) { + return (null); + } + + return (links.get(name)); + } + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/AbstractMinimalEpic.java b/src/main/java/org/gitlab4j/api/models/AbstractMinimalEpic.java new file mode 100644 index 000000000..a65634a80 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/AbstractMinimalEpic.java @@ -0,0 +1,71 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +public class AbstractMinimalEpic> { + + private Long id; + private Long iid; + private Long groupId; + private Long parentId; + private String title; + private String reference; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getIid() { + return iid; + } + + public void setIid(Long iid) { + this.iid = iid; + } + + public Long getGroupId() { + return groupId; + } + + public void setGroupId(Long groupId) { + this.groupId = groupId; + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @SuppressWarnings("unchecked") + public E withTitle(String title) { + this.title = title; + return (E) (this); + } + + public String getReference() { + return reference; + } + + public void setReference(String reference) { + this.reference = reference; + } + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/ChildEpic.java b/src/main/java/org/gitlab4j/api/models/ChildEpic.java new file mode 100644 index 000000000..365c7020b --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ChildEpic.java @@ -0,0 +1,10 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +public class ChildEpic extends AbstractEpic { + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/CreatedChildEpic.java b/src/main/java/org/gitlab4j/api/models/CreatedChildEpic.java new file mode 100644 index 000000000..065f9660c --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/CreatedChildEpic.java @@ -0,0 +1,47 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +public class CreatedChildEpic extends AbstractMinimalEpic { + + private Boolean hasChildren; + private Boolean hasIssues; + private String url; + private String relationUrl; + + public Boolean getHasChildren() { + return hasChildren; + } + + public void setHasChildren(Boolean hasChildren) { + this.hasChildren = hasChildren; + } + + public Boolean getHasIssues() { + return hasIssues; + } + + public void setHasIssues(Boolean hasIssues) { + this.hasIssues = hasIssues; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getRelationUrl() { + return relationUrl; + } + + public void setRelationUrl(String relationUrl) { + this.relationUrl = relationUrl; + } + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/Epic.java b/src/main/java/org/gitlab4j/api/models/Epic.java index 0effae185..318833372 100644 --- a/src/main/java/org/gitlab4j/api/models/Epic.java +++ b/src/main/java/org/gitlab4j/api/models/Epic.java @@ -1,204 +1,15 @@ package org.gitlab4j.api.models; import java.util.Date; -import java.util.List; -import java.util.Map; -import org.gitlab4j.api.utils.JacksonJsonEnumHelper; import org.gitlab4j.api.utils.JacksonJson; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; +public class Epic extends AbstractEpic { -public class Epic { - - public enum EpicState { - OPENED, CLOSED, ALL; - - private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(EpicState.class); - - @JsonCreator - public static EpicState forValue(String value) { - return enumHelper.forValue(value); - } - - @JsonValue - public String toValue() { - return (enumHelper.toString(this)); - } - - public String toString() { - return (enumHelper.toString(this)); - } - } - - private Long id; - private Long iid; - private Long groupId; - private Long parentId; - private Long parentIid; - private String title; - private String description; - private EpicState state; - private String webUrl; - private String reference; - private References references; - private Author author; - private List labels; - private Date startDate; private Boolean startDateIsFixed; - private Date dueDate; private Boolean dueDateIsFixed; private Date dueDateFromInheritedSource; - private Date endDate; - private Date createdAt; - private Date updatedAt; - private Date closedAt; - private Integer downvotes; - private Integer upvotes; - private String color; private Boolean subscribed; - @JsonProperty("_links") - private Map links; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Long getIid() { - return iid; - } - - public void setIid(Long iid) { - this.iid = iid; - } - - public Long getGroupId() { - return groupId; - } - - public void setGroupId(Long groupId) { - this.groupId = groupId; - } - - public Long getParentId() { - return parentId; - } - - public void setParentId(Long parentId) { - this.parentId = parentId; - } - - public Long getParentIid() { - return parentIid; - } - - public void setParentIid(Long parentIid) { - this.parentIid = parentIid; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Epic withTitle(String title) { - this.title = title; - return (this); - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Epic withDescription(String description) { - this.description = description; - return (this); - } - - public EpicState getState() { - return state; - } - - public void setState(EpicState state) { - this.state = state; - } - - public String getWebUrl() { - return webUrl; - } - - public void setWebUrl(String webUrl) { - this.webUrl = webUrl; - } - - public String getReference() { - return reference; - } - - public void setReference(String reference) { - this.reference = reference; - } - - public References getReferences() { - return references; - } - - public void setReferences(References references) { - this.references = references; - } - - public Author getAuthor() { - return author; - } - - public void setAuthor(Author author) { - this.author = author; - } - - public Epic withAuthor(Author author) { - this.author = author; - return (this); - } - - public List getLabels() { - return labels; - } - - public void setLabels(List labels) { - this.labels = labels; - } - - public Epic withLabels(List labels) { - this.labels = labels; - return (this); - } - - public Date getStartDate() { - return startDate; - } - - public void setStartDate(Date startDate) { - this.startDate = startDate; - } - - public Epic withStartDate(Date startDate) { - this.startDate = startDate; - return (this); - } public Boolean getStartDateIsFixed() { return startDateIsFixed; @@ -208,14 +19,6 @@ public void setStartDateIsFixed(Boolean startDateIsFixed) { this.startDateIsFixed = startDateIsFixed; } - public Date getDueDate() { - return dueDate; - } - - public void setDueDate(Date dueDate) { - this.dueDate = dueDate; - } - public Boolean getDueDateIsFixed() { return dueDateIsFixed; } @@ -232,92 +35,14 @@ public void setDueDateFromInheritedSource(Date dueDateFromInheritedSource) { this.dueDateFromInheritedSource = dueDateFromInheritedSource; } - public Date getEndDate() { - return endDate; - } - - public void setEndDate(Date endDate) { - this.endDate = endDate; - } - - public Epic withEndDate(Date endDate) { - this.endDate = endDate; - return (this); - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - - public Date getClosedAt() { - return closedAt; - } - - public void setClosedAt(Date closedAt) { - this.closedAt = closedAt; - } - - public Integer getDownvotes() { - return downvotes; - } - - public void setDownvotes(Integer downvotes) { - this.downvotes = downvotes; - } - - public Integer getUpvotes() { - return upvotes; - } - - public void setUpvotes(Integer upvotes) { - this.upvotes = upvotes; - } - - public String getColor() { - return color; - } - - public void setColor(String color) { - this.color = color; - } - - public Boolean getSubscribed() { + public Boolean getSubscribed() { return subscribed; } - public void setSubscribed(Boolean subscribed) { + public void setSubscribed(Boolean subscribed) { this.subscribed = subscribed; } - public Map getLinks() { - return links; - } - - public void setLinks(Map links) { - this.links = links; - } - - @JsonIgnore - public String getLinkByName(String name) { - if (links == null || links.isEmpty()) { - return (null); - } - - return (links.get(name)); - } - public String toString() { return (JacksonJson.toJsonString(this)); } diff --git a/src/main/java/org/gitlab4j/api/models/EpicInLink.java b/src/main/java/org/gitlab4j/api/models/EpicInLink.java new file mode 100644 index 000000000..4eded2f84 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/EpicInLink.java @@ -0,0 +1,10 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +public class EpicInLink extends AbstractEpic { + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/RelatedEpic.java b/src/main/java/org/gitlab4j/api/models/RelatedEpic.java new file mode 100644 index 000000000..4315a1b55 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/RelatedEpic.java @@ -0,0 +1,76 @@ +package org.gitlab4j.api.models; + +import java.util.Date; + +import org.gitlab4j.api.utils.JacksonJson; + +public class RelatedEpic extends AbstractEpic { + + private Boolean startDateIsFixed; + private Boolean dueDateIsFixed; + private Date dueDateFromInheritedSource; + private Long relatedEpicLinkId; + private LinkType linkType; + private Date linkCreatedAt; + private Date linkUpdatedAt; + + public Boolean getStartDateIsFixed() { + return startDateIsFixed; + } + + public void setStartDateIsFixed(Boolean startDateIsFixed) { + this.startDateIsFixed = startDateIsFixed; + } + + public Boolean getDueDateIsFixed() { + return dueDateIsFixed; + } + + public void setDueDateIsFixed(Boolean dueDateIsFixed) { + this.dueDateIsFixed = dueDateIsFixed; + } + + public Date getDueDateFromInheritedSource() { + return dueDateFromInheritedSource; + } + + public void setDueDateFromInheritedSource(Date dueDateFromInheritedSource) { + this.dueDateFromInheritedSource = dueDateFromInheritedSource; + } + + public Long getRelatedEpicLinkId() { + return relatedEpicLinkId; + } + + public void setRelatedEpicLinkId(Long relatedEpicLinkId) { + this.relatedEpicLinkId = relatedEpicLinkId; + } + + public LinkType getLinkType() { + return linkType; + } + + public void setLinkType(LinkType linkType) { + this.linkType = linkType; + } + + public Date getLinkCreatedAt() { + return linkCreatedAt; + } + + public void setLinkCreatedAt(Date linkCreatedAt) { + this.linkCreatedAt = linkCreatedAt; + } + + public Date getLinkUpdatedAt() { + return linkUpdatedAt; + } + + public void setLinkUpdatedAt(Date linkUpdatedAt) { + this.linkUpdatedAt = linkUpdatedAt; + } + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/RelatedEpicLink.java b/src/main/java/org/gitlab4j/api/models/RelatedEpicLink.java new file mode 100644 index 000000000..d33f60b61 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/RelatedEpicLink.java @@ -0,0 +1,67 @@ +package org.gitlab4j.api.models; + +import java.util.Date; + +import org.gitlab4j.api.utils.JacksonJson; + +public class RelatedEpicLink { + + private Long id; + private EpicInLink sourceEpic; + private EpicInLink targetEpic; + private LinkType linkType; + private Date createdAt; + private Date updatedAt; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public EpicInLink getSourceEpic() { + return sourceEpic; + } + + public void setSourceEpic(EpicInLink sourceEpic) { + this.sourceEpic = sourceEpic; + } + + public EpicInLink getTargetEpic() { + return targetEpic; + } + + public void setTargetEpic(EpicInLink targetEpic) { + this.targetEpic = targetEpic; + } + + public LinkType getLinkType() { + return linkType; + } + + public void setLinkType(LinkType linkType) { + this.linkType = linkType; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java index bd35e27d8..f501d3fd6 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java @@ -45,12 +45,14 @@ import org.gitlab4j.api.models.Blame; import org.gitlab4j.api.models.Board; import org.gitlab4j.api.models.Branch; +import org.gitlab4j.api.models.ChildEpic; import org.gitlab4j.api.models.Comment; import org.gitlab4j.api.models.Commit; import org.gitlab4j.api.models.CommitPayload; import org.gitlab4j.api.models.CommitStatus; import org.gitlab4j.api.models.CompareResults; import org.gitlab4j.api.models.Contributor; +import org.gitlab4j.api.models.CreatedChildEpic; import org.gitlab4j.api.models.DeployKey; import org.gitlab4j.api.models.DeployToken; import org.gitlab4j.api.models.Deployment; @@ -93,15 +95,17 @@ 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.ProjectGroup; import org.gitlab4j.api.models.ProjectHook; import org.gitlab4j.api.models.ProjectUser; import org.gitlab4j.api.models.ProtectedBranch; import org.gitlab4j.api.models.ProtectedTag; import org.gitlab4j.api.models.PushRules; import org.gitlab4j.api.models.RegistryRepository; +import org.gitlab4j.api.models.RelatedEpic; +import org.gitlab4j.api.models.RelatedEpicLink; import org.gitlab4j.api.models.Release; import org.gitlab4j.api.models.RemoteMirror; import org.gitlab4j.api.models.RepositoryFile; @@ -179,6 +183,18 @@ public void testBranch() throws Exception { assertTrue(!Branch.isValid(branch)); } + @Test + public void testCreatedChildEpic() throws Exception { + CreatedChildEpic childEpic = unmarshalResource(CreatedChildEpic.class, "created-child-epic.json"); + assertTrue(compareJson(childEpic, "created-child-epic.json")); + } + + @Test + public void testChildEpic() throws Exception { + ChildEpic childEpic = unmarshalResource(ChildEpic.class, "child-epic.json"); + assertTrue(compareJson(childEpic, "child-epic.json")); + } + @Test public void testCommit() throws Exception { Commit commit = unmarshalResource(Commit.class, "commit.json"); @@ -539,6 +555,18 @@ public void testRegistryRepositories() throws Exception { assertTrue(compareJson(repos, "registry-repositories.json")); } + @Test + public void testRelatedEpicLink() throws Exception { + RelatedEpicLink relatedEpics = unmarshalResource(RelatedEpicLink.class, "related-epic-link.json"); + assertTrue(compareJson(relatedEpics, "related-epic-link.json")); + } + + @Test + public void testRelatedEpics() throws Exception { + List relatedEpics = unmarshalResourceList(RelatedEpic.class, "related-epics.json"); + assertTrue(compareJson(relatedEpics, "related-epics.json")); + } + @Test public void testReleases() throws Exception { List releases = unmarshalResourceList(Release.class, "releases.json"); diff --git a/src/test/resources/org/gitlab4j/api/child-epic.json b/src/test/resources/org/gitlab4j/api/child-epic.json new file mode 100644 index 000000000..cc474e693 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/child-epic.json @@ -0,0 +1,39 @@ +{ + "id": 30, + "iid": 5, + "group_id": 7, + "parent_id": 3, + "parent_iid": 8, + "title": "Ea cupiditate dolores ut vero consequatur quasi veniam voluptatem et non.", + "description": "Molestias dolorem eos vitae expedita impedit necessitatibus quo voluptatum.", + "state": "opened", + "web_url": "http://gitlab.example.com/groups/test/-/epics/5", + "reference": "&5", + "references": { + "short": "&5", + "relative": "&5", + "full": "test&5" + }, + "author":{ + "id": 7, + "name": "Pamella Huel", + "username": "arnita", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a2f5c6fcef64c9c69cb8779cb292be1b?s=80&d=identicon", + "web_url": "http://gitlab.example.com/arnita" + }, + "start_date": "2018-07-01T00:00:00Z", + "due_date": "2018-07-31T00:00:00Z", + "created_at": "2018-07-17T13:36:22.770Z", + "updated_at": "2018-07-18T12:22:05.239Z", + "closed_at": "2018-08-18T12:22:05.239Z", + "labels": [], + "upvotes": 4, + "downvotes": 0, + "color": "#1068bf", + "_links":{ + "self": "http://gitlab.example.com/api/v4/groups/7/epics/5", + "epic_issues": "http://gitlab.example.com/api/v4/groups/7/epics/5/issues", + "group":"http://gitlab.example.com/api/v4/groups/7" + } +} \ No newline at end of file diff --git a/src/test/resources/org/gitlab4j/api/created-child-epic.json b/src/test/resources/org/gitlab4j/api/created-child-epic.json new file mode 100644 index 000000000..11129ef78 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/created-child-epic.json @@ -0,0 +1,12 @@ +{ + "id": 42, + "iid": 3, + "title": "this is a test", + "group_id": 139, + "parent_id": 25, + "has_children": false, + "has_issues": false, + "reference": "&3", + "url": "https://gitlab.example.com/groups/a-group/-/epics/3", + "relation_url": "https://gitlab.example.com/groups/a-group/-/epics/1/links/42" +} \ No newline at end of file diff --git a/src/test/resources/org/gitlab4j/api/related-epic-link.json b/src/test/resources/org/gitlab4j/api/related-epic-link.json new file mode 100644 index 000000000..245cbd748 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/related-epic-link.json @@ -0,0 +1,72 @@ +{ + "id": 1, + "created_at": "2022-01-31T15:10:44.988Z", + "updated_at": "2022-01-31T15:10:44.988Z", + "link_type": "relates_to", + "source_epic": { + "id": 21, + "iid": 1, + "color": "#1068bf", + "group_id": 26, + "title": "Aspernatur recusandae distinctio omnis et qui est iste.", + "description": "some description", + "author": { + "id": 15, + "username": "trina", + "name": "Theresia Robel", + "state": "active", + "avatar_url": "https://www.gravatar.com/avatar/085e28df717e16484cbf6ceca75e9a93?s=80&d=identicon", + "web_url": "http://gitlab.example.com/trina" + }, + "state": "opened", + "web_url": "http://gitlab.example.com/groups/flightjs/-/epics/1", + "references": { + "short": "&1", + "relative": "&1", + "full": "flightjs&1" + }, + "created_at": "2022-01-31T15:10:44.988Z", + "updated_at": "2022-03-16T09:32:35.712Z", + "labels": [], + "upvotes": 0, + "downvotes": 0, + "_links": { + "self": "http://gitlab.example.com/api/v4/groups/26/epics/1", + "epic_issues": "http://gitlab.example.com/api/v4/groups/26/epics/1/issues", + "group": "http://gitlab.example.com/api/v4/groups/26" + } + }, + "target_epic": { + "id": 25, + "iid": 5, + "color": "#1068bf", + "group_id": 26, + "title": "Aut assumenda id nihil distinctio fugiat vel numquam est.", + "description": "some description", + "author": { + "id": 3, + "username": "valerie", + "name": "Erika Wolf", + "state": "active", + "avatar_url": "https://www.gravatar.com/avatar/9ef7666abb101418a4716a8ed4dded80?s=80&d=identicon", + "web_url": "http://gitlab.example.com/valerie" + }, + "state": "opened", + "web_url": "http://gitlab.example.com/groups/flightjs/-/epics/5", + "references": { + "short": "&5", + "relative": "&5", + "full": "flightjs&5" + }, + "created_at": "2022-01-31T15:10:45.080Z", + "updated_at": "2022-03-16T09:32:35.842Z", + "labels": [], + "upvotes": 0, + "downvotes": 0, + "_links": { + "self": "http://gitlab.example.com/api/v4/groups/26/epics/5", + "epic_issues": "http://gitlab.example.com/api/v4/groups/26/epics/5/issues", + "group": "http://gitlab.example.com/api/v4/groups/26" + } + } +} \ No newline at end of file diff --git a/src/test/resources/org/gitlab4j/api/related-epics.json b/src/test/resources/org/gitlab4j/api/related-epics.json new file mode 100644 index 000000000..483138a99 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/related-epics.json @@ -0,0 +1,48 @@ +[ + { + "id": 30, + "iid": 5, + "group_id": 7, + "parent_id": 3, + "parent_iid": 8, + "title": "Ea cupiditate dolores ut vero consequatur quasi veniam voluptatem et non.", + "description": "Molestias dolorem eos vitae expedita impedit necessitatibus quo voluptatum.", + "state": "opened", + "web_url": "http://gitlab.example.com/groups/test/-/epics/5", + "reference": "&5", + "references": { + "short": "&5", + "relative": "&5", + "full": "test&5" + }, + "author":{ + "id": 7, + "name": "Pamella Huel", + "username": "arnita", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a2f5c6fcef64c9c69cb8779cb292be1b?s=80&d=identicon", + "web_url": "http://gitlab.example.com/arnita" + }, + "start_date": "2018-07-01T00:00:00Z", + "start_date_is_fixed": false, + "due_date": "2018-07-31T00:00:00Z", + "due_date_is_fixed": false, + "due_date_from_inherited_source": "2018-07-31T00:00:00Z", + "created_at": "2018-07-17T13:36:22.770Z", + "updated_at": "2018-07-18T12:22:05.239Z", + "closed_at": "2018-08-18T12:22:05.239Z", + "labels": [], + "upvotes": 4, + "downvotes": 0, + "color": "#1068bf", + "_links":{ + "self": "http://gitlab.example.com/api/v4/groups/7/epics/5", + "epic_issues": "http://gitlab.example.com/api/v4/groups/7/epics/5/issues", + "group":"http://gitlab.example.com/api/v4/groups/7" + }, + "related_epic_link_id": 1, + "link_type": "relates_to", + "link_created_at": "2022-08-23T13:53:37Z", + "link_updated_at": "2022-08-23T13:53:37Z" + } +] \ No newline at end of file