org.eclipse.egit.github.core.service.DownloadService.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.egit.github.core.service.DownloadService.java

Source

/******************************************************************************
 *  Copyright (c) 2011 GitHub Inc.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
 *****************************************************************************/
package org.eclipse.egit.github.core.service;

import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_DOWNLOADS;
import static org.eclipse.egit.github.core.client.IGitHubConstants.SEGMENT_REPOS;
import static org.eclipse.egit.github.core.client.PagedRequest.PAGE_FIRST;
import static org.eclipse.egit.github.core.client.PagedRequest.PAGE_SIZE;

import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ProxySelector;
import java.util.List;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.ProxySelectorRoutePlanner;
import org.eclipse.egit.github.core.Download;
import org.eclipse.egit.github.core.DownloadResource;
import org.eclipse.egit.github.core.IRepositoryIdProvider;
import org.eclipse.egit.github.core.client.GitHubClient;
import org.eclipse.egit.github.core.client.GitHubRequest;
import org.eclipse.egit.github.core.client.PageIterator;
import org.eclipse.egit.github.core.client.PagedRequest;

/**
 * Service for accessing, creating, and deleting repositories downloads.
 *
 * @see <a href="http://developer.github.com/v3/repos/downloads">GitHub
 *      downloads API documentation</a>
 */
public class DownloadService extends GitHubService {

    /**
     * UPLOAD_KEY
     */
    public static final String UPLOAD_KEY = "key"; //$NON-NLS-1$

    /**
     * UPLOAD_ACL
     */
    public static final String UPLOAD_ACL = "acl"; //$NON-NLS-1$

    /**
     * UPLOAD_SUCCESS_ACTION_STATUS
     */
    public static final String UPLOAD_SUCCESS_ACTION_STATUS = "success_action_status"; //$NON-NLS-1$

    /**
     * UPLOAD_FILENAME
     */
    public static final String UPLOAD_FILENAME = "Filename"; //$NON-NLS-1$

    /**
     * UPLOAD_AWS_ACCESS_KEY_ID
     */
    public static final String UPLOAD_AWS_ACCESS_KEY_ID = "AWSAccessKeyId"; //$NON-NLS-1$

    /**
     * UPLOAD_POLICY
     */
    public static final String UPLOAD_POLICY = "Policy"; //$NON-NLS-1$

    /**
     * UPLOAD_SIGNATURE
     */
    public static final String UPLOAD_SIGNATURE = "Signature"; //$NON-NLS-1$

    /**
     * UPLOAD_FILE
     */
    public static final String UPLOAD_FILE = "file"; //$NON-NLS-1$

    private static class SizedInputStreamBody extends InputStreamBody {

        private final long size;

        /**
         * @param in
         * @param size
         */
        public SizedInputStreamBody(InputStream in, long size) {
            super(in, null);
            this.size = size;
        }

        public long getContentLength() {
            return size;
        }
    }

    /**
     * Create download service
     */
    public DownloadService() {
        super();
    }

    /**
     * Create download service
     *
     * @param client
     */
    public DownloadService(GitHubClient client) {
        super(client);
    }

    /**
     * Get download metadata for given repository and id
     *
     * @param repository
     * @param id
     * @return download
     * @throws IOException
     */
    public Download getDownload(IRepositoryIdProvider repository, int id) throws IOException {
        final String repoId = getId(repository);
        StringBuilder uri = new StringBuilder(SEGMENT_REPOS);
        uri.append('/').append(repoId);
        uri.append(SEGMENT_DOWNLOADS);
        uri.append('/').append(id);
        GitHubRequest request = createRequest();
        request.setUri(uri);
        request.setType(Download.class);
        return (Download) client.get(request).getBody();
    }

    /**
     * Create paged downloads request
     *
     * @param repository
     * @param start
     * @param size
     * @return request
     */
    protected PagedRequest<Download> createDownloadsRequest(IRepositoryIdProvider repository, int start, int size) {
        final String repoId = getId(repository);
        StringBuilder uri = new StringBuilder(SEGMENT_REPOS);
        uri.append('/').append(repoId);
        uri.append(SEGMENT_DOWNLOADS);
        PagedRequest<Download> request = createPagedRequest(start, size);
        request.setType(new TypeToken<List<Download>>() {
        }.getType());
        request.setUri(uri);
        return request;
    }

    /**
     * Get metadata for all downloads for given repository
     *
     * @param repository
     * @return non-null but possibly empty list of download metadata
     * @throws IOException
     */
    public List<Download> getDownloads(IRepositoryIdProvider repository) throws IOException {
        return getAll(pageDownloads(repository));
    }

    /**
     * Page metadata for downloads for given repository
     *
     * @param repository
     * @return iterator over pages of downloads
     */
    public PageIterator<Download> pageDownloads(IRepositoryIdProvider repository) {
        return pageDownloads(repository, PAGE_SIZE);
    }

    /**
     * Page downloads for given repository
     *
     * @param repository
     * @param size
     * @return iterator over pages of downloads
     */
    public PageIterator<Download> pageDownloads(IRepositoryIdProvider repository, int size) {
        return pageDownloads(repository, PAGE_FIRST, size);
    }

    /**
     * Page downloads for given repository
     *
     * @param repository
     * @param start
     * @param size
     * @return iterator over pages of downloads
     */
    public PageIterator<Download> pageDownloads(IRepositoryIdProvider repository, int start, int size) {
        PagedRequest<Download> request = createDownloadsRequest(repository, start, size);
        return createPageIterator(request);
    }

    /**
     * Delete download with given id from given repository
     *
     * @param repository
     * @param id
     * @throws IOException
     */
    public void deleteDownload(IRepositoryIdProvider repository, int id) throws IOException {
        final String repoId = getId(repository);
        StringBuilder uri = new StringBuilder(SEGMENT_REPOS);
        uri.append('/').append(repoId);
        uri.append(SEGMENT_DOWNLOADS);
        uri.append('/').append(id);
        client.delete(uri.toString());
    }

    /**
     * Create a new resource for download associated with the given repository
     *
     * @param repository
     * @param download
     * @return download resource
     * @throws IOException
     */
    public DownloadResource createResource(IRepositoryIdProvider repository, Download download) throws IOException {
        final String repoId = getId(repository);

        StringBuilder uri = new StringBuilder(SEGMENT_REPOS);
        uri.append('/').append(repoId);
        uri.append(SEGMENT_DOWNLOADS);
        return client.post(uri.toString(), download, DownloadResource.class);
    }

    /**
     * Create client to use to upload a resource to
     *
     * @return non-null http client
     */
    protected HttpClient createDownloadClient() {
        DefaultHttpClient client = new DefaultHttpClient();
        client.setRoutePlanner(new ProxySelectorRoutePlanner(client.getConnectionManager().getSchemeRegistry(),
                ProxySelector.getDefault()));
        return client;
    }

    /**
     * Upload a resource to be available as the download described by the given
     * resource.
     *
     * @param resource
     * @param content
     * @param size
     * @throws IOException
     */
    public void uploadResource(DownloadResource resource, InputStream content, long size) throws IOException {
        if (resource == null)
            throw new IllegalArgumentException("Download resource cannot be null"); //$NON-NLS-1$
        if (content == null)
            throw new IllegalArgumentException("Content input stream cannot be null"); //$NON-NLS-1$

        HttpClient client = createDownloadClient();

        HttpPost post = new HttpPost(resource.getS3Url());
        MultipartEntity entity = new MultipartEntity();
        entity.addPart(UPLOAD_KEY, new StringBody(resource.getPath()));
        entity.addPart(UPLOAD_ACL, new StringBody(resource.getAcl()));
        entity.addPart(UPLOAD_SUCCESS_ACTION_STATUS, new StringBody(Integer.toString(HttpStatus.SC_CREATED)));
        entity.addPart(UPLOAD_FILENAME, new StringBody(resource.getName()));
        entity.addPart(UPLOAD_AWS_ACCESS_KEY_ID, new StringBody(resource.getAccesskeyid()));
        entity.addPart(UPLOAD_POLICY, new StringBody(resource.getPolicy()));
        entity.addPart(UPLOAD_SIGNATURE, new StringBody(resource.getSignature()));
        entity.addPart(HttpHeaders.CONTENT_TYPE, new StringBody(resource.getMimeType()));
        entity.addPart(UPLOAD_FILE, new SizedInputStreamBody(content, size));
        post.setEntity(entity);

        HttpResponse response = client.execute(post);
        int status = response.getStatusLine().getStatusCode();
        if (status != HttpStatus.SC_CREATED)
            throw new IOException("Unexpected response status of " + status); //$NON-NLS-1$
    }

    /**
     * Create download and set the content to be the content of given input
     * stream. This is a convenience method that performs a
     * {@link #createResource(IRepositoryIdProvider, Download)} followed by a
     * {@link #uploadResource(DownloadResource, InputStream, long)} with the
     * results.
     *
     * @param repository
     * @param download
     *            metadata about the download
     * @param content
     *            raw content of the download
     * @param size
     *            size of content in the input stream
     * @throws IOException
     */
    public void createDownload(IRepositoryIdProvider repository, Download download, InputStream content, long size)
            throws IOException {
        DownloadResource resource = createResource(repository, download);
        uploadResource(resource, content, size);
    }

    /**
     * Create download from content of given file.
     *
     * @see #createDownload(IRepositoryIdProvider, Download, InputStream, long)
     * @param repository
     * @param download
     *            metadata about the download
     * @param file
     *            must be non-null
     * @throws IOException
     */
    public void createDownload(IRepositoryIdProvider repository, Download download, File file) throws IOException {
        if (file == null)
            throw new IllegalArgumentException("File cannot be null"); //$NON-NLS-1$

        createDownload(repository, download, new FileInputStream(file), file.length());
    }
}