org.eclipse.packagedrone.repo.channel.util.DownloadHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.packagedrone.repo.channel.util.DownloadHelper.java

Source

/*******************************************************************************
 * Copyright (c) 2014, 2016 IBH SYSTEMS GmbH.
 * 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:
 *     IBH SYSTEMS GmbH - initial API and implementation
 *******************************************************************************/
package org.eclipse.packagedrone.repo.channel.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;
import java.util.function.Function;

import javax.servlet.http.HttpServletResponse;

import org.eclipse.packagedrone.repo.MetaKey;
import org.eclipse.packagedrone.repo.channel.ArtifactInformation;
import org.eclipse.packagedrone.repo.channel.ChannelArtifactInformation;
import org.eclipse.packagedrone.repo.channel.ChannelNotFoundException;
import org.eclipse.packagedrone.repo.channel.ChannelService;
import org.eclipse.packagedrone.repo.channel.ChannelService.By;
import org.eclipse.packagedrone.repo.channel.ReadableChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.io.ByteStreams;

public final class DownloadHelper {
    private static final MetaKey KEY_MIME_TYPE = new MetaKey("mime", "type");

    private final static Logger logger = LoggerFactory.getLogger(DownloadHelper.class);

    private DownloadHelper() {
    }

    public static final String APPLICATION_OCTET_STREAM = "application/octet-stream";

    public static void streamArtifact(final HttpServletResponse response, final ChannelService service,
            final String channelId, final String artifactId, final String mimetype, final boolean download)
            throws IOException {
        streamArtifact(response, service, channelId, artifactId, mimetype, download, ArtifactInformation::getName);
    }

    public static void streamArtifact(final HttpServletResponse response, final ChannelService service,
            final String channelId, final String artifactId, final Optional<String> mimetype,
            final boolean download, final Function<ArtifactInformation, String> nameFunc) throws IOException {
        try {
            service.accessRun(By.id(channelId), ReadableChannel.class, channel -> {

                final ArtifactInformation artifact = channel.getContext().getArtifacts().get(artifactId);
                if (artifact == null) {
                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    response.setContentType("text/plain");
                    response.getWriter().format("Artifact '%s' in channel '%s' could not be found", artifact,
                            channelId);
                    return;
                }

                streamArtifact(response, artifact, mimetype, download, channel, nameFunc);
            });
        } catch (final ChannelNotFoundException e) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            response.setContentType("text/plain");
            response.getWriter().format("Channel '%s' could not be found", channelId);
        }
    }

    public static void streamArtifact(final HttpServletResponse response, final ChannelService service,
            final String channelId, final String artifactId, final String mimetype, final boolean download,
            final Function<ArtifactInformation, String> nameFunc) throws IOException {
        streamArtifact(response, service, channelId, artifactId, Optional.ofNullable(mimetype), download, nameFunc);
    }

    public static boolean streamArtifact(final HttpServletResponse response, final String artifactId,
            final Optional<String> mimetype, final boolean download, final ReadableChannel channel,
            final Function<ArtifactInformation, String> nameFunc) throws IOException {
        final Optional<ChannelArtifactInformation> artifact = channel.getArtifact(artifactId);
        if (!artifact.isPresent()) {
            return false;
        }

        return channel.getContext().stream(artifactId, stream -> {
            streamArtifact(response, artifact.get(), stream, mimetype, download, nameFunc);
        });
    }

    public static boolean streamArtifact(final HttpServletResponse response, final ArtifactInformation artifact,
            final Optional<String> mimetype, final boolean download, final ReadableChannel channel,
            final Function<ArtifactInformation, String> nameFunc) throws IOException {
        return channel.getContext().stream(artifact.getId(), stream -> {
            streamArtifact(response, artifact, stream, mimetype, download, nameFunc);
        });
    }

    public static void streamArtifact(final HttpServletResponse response, final ArtifactInformation artifact,
            final InputStream stream, final Optional<String> mimetype, final boolean download,
            final Function<ArtifactInformation, String> nameFunc) throws IOException {
        final String mt = mimetype.orElseGet(() -> evalMimeType(artifact));

        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType(mt);
        response.setDateHeader("Last-Modified", artifact.getCreationInstant().toEpochMilli());
        response.setContentLengthLong(artifact.getSize());

        if (download) {
            if (nameFunc != null) {
                response.setHeader("Content-Disposition",
                        String.format("attachment; filename=%s", nameFunc.apply(artifact)));
            } else {
                response.setHeader("Content-Disposition",
                        String.format("attachment; filename=%s", artifact.getName()));
            }
        }

        final long size = ByteStreams.copy(stream, response.getOutputStream());
        logger.debug("Copyied {} bytes", size);
    }

    private static String evalMimeType(final ArtifactInformation artifact) {
        final String mimetype = artifact.getMetaData().get(KEY_MIME_TYPE);
        return mimetype == null ? APPLICATION_OCTET_STREAM : mimetype;
    }

}