001package org.nasdanika.models.gitlab.util; 002 003import java.io.ByteArrayInputStream; 004import java.io.ByteArrayOutputStream; 005import java.io.IOException; 006import java.io.InputStream; 007import java.io.OutputStream; 008import java.util.Collections; 009import java.util.List; 010import java.util.Map; 011 012import org.eclipse.emf.common.util.URI; 013import org.eclipse.emf.ecore.resource.URIHandler; 014import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; 015import org.gitlab4j.api.GitLabApi; 016import org.gitlab4j.api.GitLabApiException; 017import org.gitlab4j.api.RepositoryApi; 018import org.gitlab4j.api.RepositoryFileApi; 019import org.gitlab4j.api.models.TreeItem; 020import org.nasdanika.common.Util; 021import org.nasdanika.models.gitlab.GitLabFactory; 022import org.nasdanika.models.gitlab.Tree; 023 024/** 025 * A very simple implementation of {@link URIHandler} to retrieve content from GitLab using REST API 026 * URI format: <code>gitlab://projectid/ref/path</code> 027 */ 028public class GitLabURIHandler implements URIHandler { 029 030 public static final String GITLAB_URI_SCHEME = "gitlab"; 031 032 protected RepositoryFileApi repositoryFileApi; 033 protected GitLabApi gitLabApi; 034 protected RepositoryApi repositoryApi; 035 036 public GitLabURIHandler(GitLabApi gitLabApi) { 037 this.gitLabApi = gitLabApi; 038 this.repositoryFileApi = gitLabApi.getRepositoryFileApi(); 039 this.repositoryApi = gitLabApi.getRepositoryApi(); 040 } 041 042 @Override 043 public boolean canHandle(URI uri) { 044 return GITLAB_URI_SCHEME.equals(uri.scheme()); 045 } 046 047 @Override 048 public InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException { 049 if (Util.isBlank(uri.lastSegment())) { 050 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 051 XMIResourceImpl resource = new XMIResourceImpl(uri); 052 try (baos) { 053 Tree tree = GitLabFactory.eINSTANCE.createTree(); 054 resource.getContents().add(tree); 055 List<TreeItem> treeItems = repositoryApi.getTree(getProjectIdOrPath(uri), getPath(uri), getRef(uri)); 056 for (TreeItem treeItem: treeItems) { 057 switch (treeItem.getType()) { 058 case TREE: 059 org.nasdanika.models.gitlab.Tree subTree = GitLabFactory.eINSTANCE.createTree(); 060 subTree.setId(treeItem.getId()); 061 subTree.setName(treeItem.getName()); 062 subTree.setPath(treeItem.getPath()); 063 tree.getTreeItems().add(subTree); 064 break; 065 case BLOB: 066 org.nasdanika.models.gitlab.Blob blob = GitLabFactory.eINSTANCE.createBlob(); 067 blob.setId(treeItem.getId()); 068 blob.setName(treeItem.getName()); 069 blob.setPath(treeItem.getPath()); 070 tree.getTreeItems().add(blob); 071 break; 072 case COMMIT: 073 break; 074 default: 075 break; 076 077 } 078 } 079 } catch (GitLabApiException e) { 080 throw new IOException(e); 081 } 082 083 resource.save(baos, options); 084 return new ByteArrayInputStream(baos.toByteArray()); 085 } 086 087 try { 088 return repositoryFileApi.getRawFile( 089 getProjectIdOrPath(uri), 090 getRef(uri), 091 getPath(uri)); 092 } catch (GitLabApiException e) { 093 throw new IOException(e); 094 } 095 } 096 097 /** 098 * This method returns URI authority parsed as Long. Override as needed 099 * @param uri 100 * @return 101 */ 102 protected Object getProjectIdOrPath(URI uri) { 103 try { 104 return Long.parseLong(uri.authority()); 105 } catch (NumberFormatException e) { 106 return uri.authority(); 107 } 108 } 109 110 /** 111 * This method returns the first (0) URI segment 112 * @param uri 113 * @return 114 */ 115 protected String getRef(URI uri) { 116 return uri.segment(0); 117 } 118 119 protected String getPath(URI uri) { 120 return uri.path().substring(uri.segment(0).length() + 2); 121 } 122 123 @Override 124 public OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException { 125 throw new UnsupportedOperationException(); 126 } 127 128 @Override 129 public void delete(URI uri, Map<?, ?> options) throws IOException { 130 throw new UnsupportedOperationException(); 131 } 132 133 @Override 134 public Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException { 135 return Collections.emptyMap(); 136 } 137 138 @Override 139 public boolean exists(URI uri, Map<?, ?> options) { 140 return true; // Need a better way 141 } 142 143 @Override 144 public Map<String, ?> getAttributes(URI uri, Map<?, ?> options) { 145 return Collections.emptyMap(); 146 } 147 148 @Override 149 public void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException { 150 throw new UnsupportedOperationException(); 151 } 152 153}