Skip to content

Fix #858: Added missing TopicsApi #1012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/main/java/org/gitlab4j/api/GitLabApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public String getApiNamespace() {
private SystemHooksApi systemHooksApi;
private TagsApi tagsApi;
private TodosApi todosApi;
private TopicsApi topicsApi;
private UserApi userApi;
private UncyclosApi wikisApi;
private KeysApi keysApi;
Expand Down Expand Up @@ -1463,7 +1464,7 @@ public ReleaseLinksApi getReleaseLinksApi() {

return releaseLinksApi;
}

/**
* Gets the ReleasesApi instance owned by this GitLabApi instance. The ReleasesApi is used
* to perform all release related API calls.
Expand Down Expand Up @@ -1654,6 +1655,25 @@ public TagsApi getTagsApi() {
return (tagsApi);
}

/**
* Gets the TagsApi instance owned by this GitLabApi instance. The TagsApi is used
* to perform all tag and release related API calls.
*
* @return the TagsApi instance owned by this GitLabApi instance
*/
public TopicsApi getTopicsApi() {

if (topicsApi == null) {
synchronized (this) {
if (topicsApi == null) {
topicsApi = new TopicsApi(this);
}
}
}

return (topicsApi);
}

/**
* Gets the SnippetsApi instance owned by this GitLabApi instance. The SnippetsApi is used
* to perform all snippet related API calls.
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/gitlab4j/api/GitLabApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public void close() {
*
* @param logger the Logger instance to log to
* @param level the logging level (SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST)
* @param maxEntitySize maximum number of entity bytes to be logged. When logging if the maxEntitySize
* @param maxEntityLength maximum number of entity bytes to be logged. When logging if the maxEntitySize
* is reached, the entity logging will be truncated at maxEntitySize and "...more..." will be added at
* the end of the log entry. If maxEntitySize is <= 0, entity logging will be disabled
* @param maskedHeaderNames a list of header names that should have the values masked
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/org/gitlab4j/api/ProjectApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,10 @@ public Project createProject(Project project, String importUrl) throws GitLabApi
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
throw new IllegalArgumentException("GitLab API v3 does not support tag lists when creating projects");
}

if (project.getTopics() != null && !project.getTopics().isEmpty()) {
throw new IllegalArgumentException("GitLab API v3 does not support topics when creating projects");
}
} else {
Visibility visibility = (project.getVisibility() != null ? project.getVisibility() :
project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null);
Expand All @@ -1051,6 +1055,10 @@ public Project createProject(Project project, String importUrl) throws GitLabApi
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
formData.withParam("tag_list", String.join(",", project.getTagList()));
}

if (project.getTopics() != null && !project.getTopics().isEmpty()) {
formData.withParam("topics", String.join(",", project.getTopics()));
}
}

Response response = post(Response.Status.CREATED, formData, "projects");
Expand Down Expand Up @@ -1314,6 +1322,10 @@ public Project updateProject(Project project) throws GitLabApiException {
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
throw new IllegalArgumentException("GitLab API v3 does not support tag lists when updating projects");
}

if (project.getTopics() != null && !project.getTopics().isEmpty()) {
throw new IllegalArgumentException("GitLab API v3 does not support topics when updating projects");
}
} else {
Visibility visibility = (project.getVisibility() != null ? project.getVisibility() :
project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null);
Expand All @@ -1322,6 +1334,10 @@ public Project updateProject(Project project) throws GitLabApiException {
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
formData.withParam("tag_list", String.join(",", project.getTagList()));
}

if (project.getTopics() != null && !project.getTopics().isEmpty()) {
formData.withParam("topics", String.join(",", project.getTopics()));
}
}

Response response = putWithFormData(Response.Status.OK, formData, "projects", projectIdentifier);
Expand Down
192 changes: 192 additions & 0 deletions src/main/java/org/gitlab4j/api/TopicsApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package org.gitlab4j.api;

import org.gitlab4j.api.models.Topic;
import org.gitlab4j.api.models.TopicParams;

import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import java.io.File;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class TopicsApi extends AbstractApi{

public TopicsApi(GitLabApi gitLabApi) {
super(gitLabApi);
}

/**
* <p>Get a list of Topics. </p>
*
* <strong>WARNING:</strong> Do not use this method to fetch Topics from https://gitlab.com,
* gitlab.com has many 1,000's of public topics and it will a long time to fetch all of them.
* Instead use {@link #getTopics(int itemsPerPage)} which will return a Pager of Topic instances.
*
* <pre><code>GitLab Endpoint: GET /topics</code></pre>
*
* @return the list of topics viewable by the authenticated user
* @throws GitLabApiException if any exception occurs
*/
public List<Topic> getTopics() throws GitLabApiException {
return (getTopics(getDefaultPerPage()).all());
}

/**
* Get a list of topics (As user: my , as admin: all groups) and in the specified page range.
*
* <pre><code>GitLab Endpoint: GET /topics</code></pre>
*
* @param page the page to get
* @param perPage the number of Group instances per page
* @return the list of groups viewable by the authenticated userin the specified page range
* @throws GitLabApiException if any exception occurs
*/
public List<Topic> getTopics(int page, int perPage) throws GitLabApiException {
Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "topics");
return (response.readEntity(new GenericType<List<Topic>>() {}));
}

/**
* Get a Pager of groups. (As user: my groups, as admin: all groups)
*
* <pre><code>GitLab Endpoint: GET /topics</code></pre>
*
* @param itemsPerPage the number of Group instances that will be fetched per page
* @return the list of groups viewable by the authenticated user
* @throws GitLabApiException if any exception occurs
*/
public Pager<Topic> getTopics(int itemsPerPage) throws GitLabApiException {
return (new Pager<Topic>(this, Topic.class, itemsPerPage, null, "topics"));
}

/**
* Get a Stream of groups. (As user: my groups, as admin: all groups)
*
* <pre><code>GitLab Endpoint: GET /topics</code></pre>
*
* @return a Stream of groups viewable by the authenticated user
* @throws GitLabApiException if any exception occurs
*/
public Stream<Topic> getGroupsStream() throws GitLabApiException {
return (getTopics(getDefaultPerPage()).stream());
}

/**
* Get all details of a group.
*
* <pre><code>GitLab Endpoint: GET /topics/:id</code></pre>
*
* @param id the group ID, path of the group, or a Group instance holding the group ID or path
* @return the Group instance for the specified group path
* @throws GitLabApiException if any exception occurs
*/
public Topic getTopic(Integer id) throws GitLabApiException {
Response response = get(Response.Status.OK, null, "topics", id);
return (response.readEntity(Topic.class));
}

/**
* Get all details of a group as an Optional instance.
*
* <pre><code>GitLab Endpoint: GET /topics/:id</code></pre>
*
* @param id the topic ID
* @return the Topic for the specified topic id as an Optional instance
*/
public Optional<Topic> getOptionalGroup(Integer id) {
try {
return (Optional.ofNullable(getTopic(id)));
} catch (GitLabApiException glae) {
return (GitLabApi.createOptionalFromException(glae));
}
}

/**
* Creates a new Topic. Available only for users who can create topics.
*
* <pre><code>GitLab Endpoint: POST /topics</code></pre>
*
* @param params a TopicParams instance holding the parameters for the topic creation
* @return the created Group instance
* @throws GitLabApiException if any exception occurs
*/
public Topic createTopic(TopicParams params) throws GitLabApiException {
Response response = post(Response.Status.CREATED, params.getForm(true), "topics");
return (response.readEntity(Topic.class));
}

/**
* Updates the project group. Only available to group owners and administrators.
*
* <pre><code>GitLab Endpoint: PUT /groups</code></pre>
*
* @param id the topic I
* @param params a TopicParams instance holding the properties to Update
* @return updated Group instance
* @throws GitLabApiException at any exception
*/
public Topic updateTopic(Integer id, TopicParams params) throws GitLabApiException {
Response response = putWithFormData(Response.Status.OK,
params.getForm(false), "topics", id);
return (response.readEntity(Topic.class));
}

/**
* Uploads and sets the topic's avatar for the specified topic.
*
* <pre><code>PUT /topics/:id</code></pre>
*
* @param id the topic in the form of an Integer
* @param avatarFile the File instance of the avatar file to upload
* @return the updated Topic instance
* @throws GitLabApiException if any exception occurs
*/
public Topic updateTopicAvatar(final Integer id, File avatarFile) throws GitLabApiException {
Response response = putUpload(Response.Status.OK, "avatar", avatarFile, "topics", id);
return (response.readEntity(Topic.class));
}

/**
* Delete the topic's avatar for the specified topic.
*
* <pre><code>PUT /topics/:id</code></pre>
*
* @param id the topic in the form of an Integer
* @return the updated Topic instance
* @throws GitLabApiException if any exception occurs
*/
public Topic deleteTopicAvatar(final Integer id) throws GitLabApiException {
Response response = putUpload(Response.Status.OK, "avatar", null, "topics", id);
return (response.readEntity(Topic.class));
}

/**
* You must be an administrator to delete a project topic. When you delete a project topic, you also delete the topic assignment for projects.
*
* <pre><code>DELETE /topics/:id</code></pre>
*
* @param id the topic in the form of an Integer
* @throws GitLabApiException if any exception occurs
*/
public void deleteTopic(Integer id) throws GitLabApiException {
if(isApiVersion(GitLabApi.ApiVersion.V3)){
throw new GitLabApiException("Topics need api v4+");
}
delete(Response.Status.NO_CONTENT,null, "topics", id);
}

/**
* You must be an administrator to merge a source topic into a target topic. When you merge topics, you delete the source topic and move all assigned projects to the target topic.
*
* <pre><code>DELETE /topics/:id</code></pre>
*
* @param sourceTopicId ID of source project topic
* @param targetTopicId ID of target project topic
* @throws GitLabApiException if any exception occurs
*/
public Topic mergeTopics(Integer sourceTopicId, Integer targetTopicId) throws GitLabApiException {
Response response = post(Response.Status.OK,new GitLabApiForm().withParam("source_topic_id",sourceTopicId).withParam("target_topic_id",targetTopicId),"topics/merge");
return (response.readEntity(Topic.class));
}
}
29 changes: 28 additions & 1 deletion src/main/java/org/gitlab4j/api/models/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ public String toString() {
private Boolean snippetsEnabled;
private String sshUrlToRepo;
private Integer starCount;

private List<String> tagList;
private List<String> topics;
private Integer visibilityLevel;
private Visibility visibility;
private Boolean wallEnabled;
Expand Down Expand Up @@ -542,19 +544,44 @@ public void setStarCount(Integer starCount) {
this.starCount = starCount;
}

/**
* Tags will be removed in API v5
*/
@Deprecated
public List<String> getTagList() {
return tagList;
}

/**
* Tags will be removed in API v5
*/
@Deprecated
public void setTagList(List<String> tagList) {
this.tagList = tagList;
}

/**
* Tags will be removed in API v5
*/
@Deprecated
public Project withTagList(List<String> tagList) {
this.tagList = tagList;
return (this);
}

public List<String> getTopics() {
return topics;
}

public void setTopics(List<String> topics) {
this.topics = topics;
}

public Project withTopics(List<String> topics) {
this.topics = topics;
return (this);
}

public Visibility getVisibility() {
return visibility;
}
Expand Down Expand Up @@ -733,7 +760,7 @@ public String toString() {
* Formats a fully qualified project path based on the provided namespace and project path.
*
* @param namespace the namespace, either a user name or group name
* @param path the project path
* @param path the project path
* @return a fully qualified project path based on the provided namespace and project path
*/
public static final String getPathWithNammespace(String namespace, String path) {
Expand Down
Loading