org.eclipse.sw360.rest.resourceserver.attachment.Sw360AttachmentService.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.sw360.rest.resourceserver.attachment.Sw360AttachmentService.java

Source

/*
 * Copyright Siemens AG, 2017-2018.
 * Copyright Bosch Software Innovations GmbH, 2017.
 * Part of the SW360 Portal Project.
 *
 * SPDX-License-Identifier: EPL-1.0
 *
 * 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
 */

package org.eclipse.sw360.rest.resourceserver.attachment;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransportException;
import org.eclipse.sw360.commonIO.AttachmentFrontendUtils;
import org.eclipse.sw360.datahandler.common.DatabaseSettings;
import org.eclipse.sw360.datahandler.common.Duration;
import org.eclipse.sw360.datahandler.couchdb.AttachmentConnector;
import org.eclipse.sw360.datahandler.thrift.attachments.*;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.rest.resourceserver.core.RestControllerHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.hateoas.Resource;
import org.springframework.hateoas.Resources;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class Sw360AttachmentService {
    @Value("${sw360.thrift-server-url:http://localhost:8080}")
    private String thriftServerUrl;

    @Value("${sw360.couchdb-url:http://localhost:5984}")
    private String couchdbUrl;

    @NonNull
    private final RestControllerHelper restControllerHelper;

    private static final Logger log = Logger.getLogger(Sw360AttachmentService.class);
    private final Duration downloadTimeout = Duration.durationOf(30, TimeUnit.SECONDS);
    private AttachmentConnector attachmentConnector;

    public AttachmentInfo getAttachmentById(String id) throws TException {
        AttachmentService.Iface attachmentClient = getThriftAttachmentClient();
        List<Attachment> attachments = attachmentClient.getAttachmentsByIds(Collections.singleton(id));
        return createAttachmentInfo(attachmentClient, attachments);
    }

    public AttachmentInfo getAttachmentBySha1(String sha1) throws TException {
        AttachmentService.Iface attachmentClient = getThriftAttachmentClient();
        List<Attachment> attachments = attachmentClient.getAttachmentsBySha1s(Collections.singleton(sha1));
        return createAttachmentInfo(attachmentClient, attachments);
    }

    private AttachmentInfo createAttachmentInfo(AttachmentService.Iface attachmentClient,
            List<Attachment> attachments) throws TException {
        AttachmentInfo attachmentInfo = new AttachmentInfo(getValidAttachment(attachments));
        String attachmentId = attachmentInfo.getAttachment().getAttachmentContentId();
        attachmentInfo
                .setOwner(attachmentClient.getAttachmentOwnersByIds(Collections.singleton(attachmentId)).get(0));
        return attachmentInfo;
    }

    private Attachment getValidAttachment(List<Attachment> attachments) {
        if (attachments.isEmpty()) {
            throw new ResourceNotFoundException();
        }
        return attachments.get(0);
    }

    public void downloadAttachmentWithContext(Object context, String attachmentId, HttpServletResponse response,
            OAuth2Authentication oAuth2Authentication) {
        User sw360User = restControllerHelper.getSw360UserFromAuthentication(oAuth2Authentication);
        AttachmentContent attachmentContent = getAttachmentContent(attachmentId);

        String filename = attachmentContent.getFilename();
        String contentType = attachmentContent.getContentType();

        try (InputStream attachmentStream = getStreamToAttachments(Collections.singleton(attachmentContent),
                sw360User, context)) {
            response.setContentType(contentType);
            response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", filename));
            FileCopyUtils.copy(attachmentStream, response.getOutputStream());
        } catch (TException | IOException e) {
            log.error(e.getMessage());
        }
    }

    public <T> InputStream getStreamToAttachments(Set<AttachmentContent> attachments, User sw360User, T context)
            throws IOException, TException {
        return new AttachmentFrontendUtils().getStreamToServeAFile(attachments, sw360User, context);
    }

    public Attachment uploadAttachment(MultipartFile file, Attachment newAttachment, User sw360User)
            throws IOException, TException {
        String fileName = file.getOriginalFilename(); // TODO: shouldn't the fileName be taken from newAttachment?
        String contentType = file.getContentType();
        final AttachmentContent attachmentContent = makeAttachmentContent(fileName, contentType);

        final AttachmentConnector attachmentConnector = getConnector();
        Attachment attachment = new AttachmentFrontendUtils().uploadAttachmentContent(attachmentContent,
                file.getInputStream(), sw360User);
        attachment.setSha1(attachmentConnector.getSha1FromAttachmentContentId(attachmentContent.getId()));

        AttachmentType attachmentType = newAttachment.getAttachmentType();
        if (attachmentType != null) {
            attachment.setAttachmentType(attachmentType);
        }

        CheckStatus checkStatus = newAttachment.getCheckStatus();
        if (checkStatus != null) {
            attachment.setCheckStatus(checkStatus);
        }

        return attachment;
    }

    private AttachmentContent makeAttachmentContent(String filename, String contentType) {
        AttachmentContent attachment = new AttachmentContent().setContentType(contentType).setFilename(filename)
                .setOnlyRemote(false);
        return makeAttachmentContent(attachment);
    }

    private AttachmentContent makeAttachmentContent(AttachmentContent content) {
        try {
            return new AttachmentFrontendUtils().makeAttachmentContent(content);
        } catch (TException e) {
            throw new RuntimeException(e);
        }
    }

    public AttachmentContent getAttachmentContent(String id) {
        try {
            return new AttachmentFrontendUtils().getAttachmentContent(id);
        } catch (TException e) {
            throw new RuntimeException(e);
        }
    }

    private AttachmentConnector getConnector() throws TException {
        if (attachmentConnector == null)
            makeConnector();
        return attachmentConnector;
    }

    private synchronized void makeConnector() throws TException {
        if (attachmentConnector == null) {
            try {
                attachmentConnector = new AttachmentConnector(DatabaseSettings.getConfiguredHttpClient(),
                        DatabaseSettings.COUCH_DB_ATTACHMENTS, downloadTimeout);
            } catch (MalformedURLException e) {
                log.error("Invalid database address received...", e);
                throw new TException(e);
            }
        }
    }

    private AttachmentService.Iface getThriftAttachmentClient() throws TTransportException {
        THttpClient thriftClient = new THttpClient(thriftServerUrl + "/attachments/thrift");
        TProtocol protocol = new TCompactProtocol(thriftClient);
        return new AttachmentService.Client(protocol);
    }

    public Resources<Resource<Attachment>> getResourcesFromList(Set<Attachment> attachmentList) {
        final List<Resource<Attachment>> attachmentResources = new ArrayList<>();
        for (final Attachment attachment : attachmentList) {
            final Attachment embeddedAttachment = restControllerHelper.convertToEmbeddedAttachment(attachment);
            final Resource<Attachment> attachmentResource = new Resource<>(embeddedAttachment);
            attachmentResources.add(attachmentResource);
        }
        return new Resources<>(attachmentResources);
    }
}