package org.abapgit.adt.backend.internal; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.stream.Collectors; import org.abapgit.adt.backend.IFileService; import org.abapgit.adt.backend.model.abapgitexternalrepo.IExternalRepositoryInfoRequest; import org.abapgit.adt.backend.model.abapgitstaging.IAbapGitFile; import org.eclipse.core.runtime.NullProgressMonitor; import com.sap.adt.communication.batch.AdtBatchResourceFactory; import com.sap.adt.communication.batch.IAdtBatchPartDelayedResponse; import com.sap.adt.communication.batch.IAdtBatchResource; import com.sap.adt.communication.message.HeadersFactory; import com.sap.adt.communication.message.IHeaders; import com.sap.adt.communication.message.IMessageBody; import com.sap.adt.communication.message.IResponse; import com.sap.adt.communication.resources.AdtRestResourceFactory; import com.sap.adt.communication.resources.IRestResource; import com.sap.adt.communication.resources.IRestResourceRequestFilter; import com.sap.adt.communication.resources.IRestResourceResponseFilter; import com.sap.adt.communication.session.AdtSystemSessionFactory; import com.sap.adt.communication.session.ISystemSession; import com.sap.adt.compatibility.batch.AdtBatchUriDiscoveryFactory; import com.sap.adt.compatibility.filter.AdtCompatibleRestResourceFilterFactory; import com.sap.adt.compatibility.filter.IAdtCompatibleRestResourceFilter; import com.sap.adt.tools.core.model.atom.IAtomLink; @SuppressWarnings("restriction") public class FileService implements IFileService { @Override public String readLocalFileContents(IAbapGitFile file, IExternalRepositoryInfoRequest credentials, String destinationId) throws IOException { return readFileContents(file, LOCAL_VERSION, credentials, destinationId); } @Override public String readRemoteFileContents(IAbapGitFile file, IExternalRepositoryInfoRequest credentials, String destinationId) throws IOException { return readFileContents(file, REMOTE_VERSION, credentials, destinationId); } private String readFileContents(IAbapGitFile file, String version, IExternalRepositoryInfoRequest credentials, String destinationId) throws IOException { URI uri; if (version.equals(LOCAL_VERSION)) { uri = getHrefFromAtomLink(file, IFileService.RELATION_FILE_FETCH_LOCAL); } else { uri = getHrefFromAtomLink(file, IFileService.RELATION_FILE_FETCH_REMOTE); } if (uri != null) { IRestResource restResource = AdtRestResourceFactory.createRestResourceFactory().createResourceWithStatelessSession(uri, destinationId); IAdtCompatibleRestResourceFilter compatibilityFilter = AdtCompatibleRestResourceFilterFactory .createFilter(IFileService.MIME_TEXT_PLAIN); restResource.addRequestFilter(compatibilityFilter); restResource.addResponseFilter(compatibilityFilter); IHeaders headers = null; if (credentials != null) { headers = getHttpHeadersForCredentials(credentials.getUser(), credentials.getPassword()); } IMessageBody body = restResource.get(new NullProgressMonitor(), headers, IMessageBody.class); if (body != null) { return convert(body.getContent(), StandardCharsets.UTF_8); } } return null; } @Override public List<String> readFileContentsBatch(IAbapGitFile file, IExternalRepositoryInfoRequest credentials, String destinationId) throws IOException { URI defaultBatchUri = AdtBatchUriDiscoveryFactory.createBatchUriDiscovery(destinationId) .getDefaultBatchURI(new NullProgressMonitor()); ISystemSession session = AdtSystemSessionFactory.createSystemSessionFactory().createStatelessSession(destinationId); IAdtBatchResource resource = AdtBatchResourceFactory.createBatchResource(session, defaultBatchUri); //add local file fetch request to batch IAdtBatchPartDelayedResponse<IResponse> localFileResponse = readLocalFileContent(resource, file, credentials); //add remote file fetch request to batch IAdtBatchPartDelayedResponse<IResponse> remoteFileResponse = readRemoteFileContent(resource, file, credentials); //submit batch request resource.submit(new NullProgressMonitor()); List<String> fileContents = new ArrayList<>(); //read local file contents from batch response IMessageBody body = localFileResponse.getResult().getBody(); if (body != null) { fileContents.add(convert(body.getContent(), StandardCharsets.UTF_8)); } //read remote file contents from batch response body = remoteFileResponse.getResult().getBody(); if (body != null) { fileContents.add(convert(body.getContent(), StandardCharsets.UTF_8)); } return fileContents; } private IAdtBatchPartDelayedResponse<IResponse> readLocalFileContent(IAdtBatchResource resource, IAbapGitFile file, IExternalRepositoryInfoRequest credentials) { return readFileContentBatch(getHrefFromAtomLink(file, IFileService.RELATION_FILE_FETCH_LOCAL), credentials, resource); } private IAdtBatchPartDelayedResponse<IResponse> readRemoteFileContent(IAdtBatchResource resource, IAbapGitFile file, IExternalRepositoryInfoRequest credentials) { return readFileContentBatch(getHrefFromAtomLink(file, IFileService.RELATION_FILE_FETCH_REMOTE), credentials, resource); } private IAdtBatchPartDelayedResponse<IResponse> readFileContentBatch(URI uri, IExternalRepositoryInfoRequest credentials, IAdtBatchResource resource) { IAdtCompatibleRestResourceFilter compatibilityFilter = AdtCompatibleRestResourceFilterFactory .createFilter(IFileService.MIME_TEXT_PLAIN); List<IRestResourceRequestFilter> reqFilters = new ArrayList<>(); reqFilters.add(compatibilityFilter); List<IRestResourceResponseFilter> respFilters = new ArrayList<>(); respFilters.add(compatibilityFilter); IHeaders headers = null; if (credentials != null) { headers = getHttpHeadersForCredentials(credentials.getUser(), credentials.getPassword()); } IAdtBatchPartDelayedResponse<IResponse> response = resource.addGetRequestPart(uri, IResponse.class, headers, null, null, reqFilters, respFilters); return response; } /** * Converts input stream from the back-end request response to string */ private String convert(InputStream inputStream, Charset charset) throws IOException { try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, charset))) { return br.lines().collect(Collectors.joining(System.lineSeparator())); } } /** * Returns the request headers for sending github account user name and * password to back-end */ private IHeaders getHttpHeadersForCredentials(String username, String password) { IHeaders headers = HeadersFactory.newHeaders(); IHeaders.IField userField = HeadersFactory.newField("Username", username); //$NON-NLS-1$ headers.addField(userField); Base64.Encoder encoder = Base64.getMimeEncoder(); IHeaders.IField passwordField = HeadersFactory.newField("Password", //$NON-NLS-1$ encoder.encodeToString(password.getBytes(StandardCharsets.UTF_8))); headers.addField(passwordField); return headers; } private URI getHrefFromAtomLink(IAbapGitFile file, String relation) { for (IAtomLink link : file.getLinks()) { if (link.getRel().equalsIgnoreCase(relation)) { return link.getHrefAsUri(); } } return null; } }