package com.nju.edu.gitlab.service.impl; import com.nju.edu.gitlab.service.api.ProjectService; import com.nju.edu.gitlab.util.ApplicationProperties; import com.nju.edu.gitlab.web.dto.*; import org.gitlab4j.api.GitLabApi; import org.gitlab4j.api.GitLabApiException; import org.gitlab4j.api.models.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.*; import java.util.Base64; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @Component public class ProjectServiceImpl implements ProjectService { private final GitLabApi gitlabApi; private final String gitlabHost; private final String token; @Autowired public ProjectServiceImpl(ApplicationProperties properties) { this.gitlabHost=properties.getHost(); this.token= properties.getToken(); this.gitlabApi = new GitLabApi(this.gitlabHost, this.token); } @Override public Integer createProject(ProjectDTO projectDTO) throws GitLabApiException { String projectName=projectDTO.getProjectName(); Visibility visibility=projectDTO.getVisibility(); Project project=new Project(); project.setName(projectName); project.setVisibility(visibility); project=gitlabApi.getProjectApi().createProject(project); return project.getId(); } @Override public Integer forkProject(UserForkDTO userForkDTO) throws GitLabApiException { int userId=userForkDTO.getUserId(); int projectId=userForkDTO.getProjectId(); Integer namespaceId=fetchNameSpaceId(gitlabApi.getUserApi().getUser(userId).getUsername()); if (namespaceId == null) throw new NullPointerException(); Project project; try{ gitlabApi.setSudoAsId(userId); project=gitlabApi.getProjectApi().forkProject(projectId,namespaceId); project.setVisibility(Visibility.PRIVATE); project=gitlabApi.getProjectApi().updateProject(project); }finally { gitlabApi.unsudo(); } return project!=null?project.getId():null; } @Override public Integer forkGroupProject(GroupForkDTO groupForkDTO) throws GitLabApiException { int groupId=groupForkDTO.getGroupId(); int projectId=groupForkDTO.getProjectId(); Integer namespaceId=fetchGroupNameSpaceId(gitlabApi.getGroupApi().getGroup(groupId).getName()); if (namespaceId == null) throw new NullPointerException(); Project project; try{ gitlabApi.sudo("root"); project=gitlabApi.getProjectApi().forkProject(projectId,namespaceId); project.setVisibility(Visibility.PRIVATE); project=gitlabApi.getProjectApi().updateProject(project); }finally { gitlabApi.unsudo(); } return project!=null?project.getId():null; } private Integer fetchGroupNameSpaceId(String name) throws GitLabApiException { Namespace namespace; namespace = gitlabApi.getNamespaceApi().findNamespaces(name) .stream() .filter(ns -> "group".equals(ns.getKind())) .reduce((ns1, ns2) -> ns1.getId() > ns2.getId() ? ns1 : ns2) .orElse(null); return namespace != null ? namespace.getId() : null; } @Override public Set compare(int projectId, String fromBash, String toBash) throws GitLabApiException { CompareResults compareResults = gitlabApi.getRepositoryApi().compare(projectId, fromBash, toBash); return new HashSet<>(compareResults.getDiffs()); } @Override public boolean addWebHook(WebHookDTO webHookDTO) throws GitLabApiException { int projectId=webHookDTO.getProjectId(); String url= webHookDTO.getUrl(); boolean doPushEvents=webHookDTO.isDoPushEvents(); boolean doIssueEvents=webHookDTO.isDoIssueEvents(); boolean doMergeRequestsEvents=webHookDTO.isDoMergeRequestsEvents(); gitlabApi.getProjectApi().addHook(projectId, url, doPushEvents, doIssueEvents, doMergeRequestsEvents); return true; } @Override public boolean archiveProject(int projectId) throws GitLabApiException { gitlabApi.getProjectApi().deleteProject(projectId); return true; } @Override public String getProjectFile(int projectId,ProjectFileDTO projectFileDTO) throws UnsupportedEncodingException, GitLabApiException { String branch=projectFileDTO.getBranch(); String path=projectFileDTO.getPath(); RepositoryFile repositoryFile = gitlabApi.getRepositoryFileApi().getFile(projectId, path,branch); if(repositoryFile!=null){ return new String(Base64.getDecoder().decode(repositoryFile.getContent()), "UTF-8"); } return null; } @Override public String getProjectRawFile(int projectId, ProjectRawFileDTO projectRawFileDTO) throws GitLabApiException, IOException { String commitOrBranchName = projectRawFileDTO.getCommitOrBranchName(); String path=projectRawFileDTO.getPath(); InputStream inputStream=gitlabApi.getRepositoryFileApi().getRawFile(projectId,commitOrBranchName,path); if (inputStream==null){ return null; } ByteArrayOutputStream bos=new ByteArrayOutputStream(); byte[] buf=new byte[inputStream.available()]; int len=-1; while ((len=inputStream.read(buf))!=-1){ bos.write(buf,0,len); } String content=bos.toString(); inputStream.close(); bos.close(); return content; } @Override public Commit createCommit(int projectId, CommitDTO commitDTO) throws GitLabApiException { String branch=commitDTO.getBranch(); String commitMsg=commitDTO.getCommitMessage(); String username=commitDTO.getUsername(); String email=commitDTO.getEmail(); List actions=commitDTO.getActions(); Commit commit=gitlabApi.getCommitsApi().createCommit(projectId,branch,commitMsg,null,email,username,actions); return commit; } @Override public List getAllCommitMessage(int projectId, String commitHash) throws GitLabApiException { return gitlabApi.getCommitsApi().getCommits(projectId,commitHash,null,null); } @Override public List getProjectBranches(int projectId) throws GitLabApiException { return gitlabApi.getRepositoryApi().getBranches(projectId); } private Integer fetchNameSpaceId(String username) throws GitLabApiException { Namespace namespace; namespace = gitlabApi.getNamespaceApi().findNamespaces(username) .stream() .filter(ns -> "user".equals(ns.getKind())) .reduce((ns1, ns2) -> ns1.getId() > ns2.getId() ? ns1 : ns2) .orElse(null); return namespace != null ? namespace.getId() : null; } }