de.unimannheim.spa.process.rest.ProjectRestController.java Source code

Java tutorial

Introduction

Here is the source code for de.unimannheim.spa.process.rest.ProjectRestController.java

Source

/*******************************************************************************
 * Copyright 2016 University of Mannheim
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *          http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package de.unimannheim.spa.process.rest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.ResponseEntity.BodyBuilder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.noodlesandwich.rekord.Rekord;
import com.noodlesandwich.rekord.serialization.MapSerializer;

import de.unima.core.application.SPA;
import de.unima.core.domain.model.DataBucket;
import de.unima.core.domain.model.DataPool;
import de.unima.core.domain.model.Project;
import de.unimannheim.spa.process.rekord.builders.DataPoolBuilder;
import de.unimannheim.spa.process.rekord.builders.ProjectBuilder;
import de.unimannheim.spa.process.util.FileUtils;

@RestController
@RequestMapping("/projects")
public class ProjectRestController {

    private final static String PROJECT_BASE_URL = "http://www.uni-mannheim.de/spa/Project/";
    private final static String PROCESS_BASE_URL = "http://www.uni-mannheim.de/spa/DataBucket/";

    private final static MediaType JSON_CONTENT_TYPE = new MediaType(MediaType.APPLICATION_JSON.getType(),
            MediaType.APPLICATION_JSON.getSubtype(), Charsets.UTF_8);
    private final MediaType OCTET_CONTENT_TYPE = new MediaType(MediaType.APPLICATION_OCTET_STREAM.getType(),
            MediaType.APPLICATION_OCTET_STREAM.getSubtype(), Charset.forName("utf8"));

    private final SPA spaService;

    @Autowired
    public ProjectRestController(SPA spaService) {
        this.spaService = spaService;
    }

    @RequestMapping(method = RequestMethod.GET)
    public ResponseEntity<List<Map<String, Object>>> getAllProjects() {
        List<Map<String, Object>> allProjects = Lists.newArrayList();
        for (Project project : spaService.findAllProjects()) {
            Rekord<Project> projectTmp = ProjectBuilder.rekord.with(ProjectBuilder.id, project.getId())
                    .with(ProjectBuilder.label, project.getLabel())
                    .with(ProjectBuilder.dataPools,
                            DataPoolBuilder.rekord.with(DataPoolBuilder.buckets,
                                    project.getDataPools().get(0).getDataBuckets()))
                    .with(ProjectBuilder.linkedSchemas, project.getLinkedSchemas());
            allProjects.add(projectTmp.serialize(new MapSerializer()));
        }
        return ResponseEntity.ok().contentType(JSON_CONTENT_TYPE).body(allProjects);
    }

    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<Map<String, Object>> createProject(@RequestParam String projectLabel) {
        Project projectCreated = spaService.createProject(projectLabel);
        spaService.saveProject(projectCreated);
        spaService.createDataPool(projectCreated, "Default DataPool");
        return ResponseEntity.status(HttpStatus.CREATED).contentType(JSON_CONTENT_TYPE)
                .body(serializeProject(projectCreated));
    }

    private Map<String, Object> serializeProject(Project projectCreated) {
        return ProjectBuilder.rekord.with(ProjectBuilder.id, projectCreated.getId())
                .with(ProjectBuilder.label, projectCreated.getLabel())
                .with(ProjectBuilder.dataPools,
                        DataPoolBuilder.rekord.with(DataPoolBuilder.buckets,
                                projectCreated.getDataPools().get(0).getDataBuckets()))
                .with(ProjectBuilder.linkedSchemas, projectCreated.getLinkedSchemas())
                .serialize(new MapSerializer());
    }

    @RequestMapping(value = "/{projectID}", method = RequestMethod.DELETE)
    public ResponseEntity<Void> removeProject(@PathVariable String projectID) {
        ResponseEntity<Void> response = null;
        final Optional<Project> projectToRemove = spaService.findProjectById(PROJECT_BASE_URL + projectID);
        if (projectToRemove.isPresent()) {
            spaService.deleteProject(projectToRemove.get());
            response = ResponseEntity.ok().build();
        } else {
            response = ResponseEntity.notFound().build();
        }
        return response;
    }

    @RequestMapping(value = "/{projectID}/processes", method = RequestMethod.GET)
    public ResponseEntity<Map<String, Object>> getAllProcesses(@PathVariable String projectID) {
        return spaService.findProjectById(PROJECT_BASE_URL + projectID).map(project -> project.getDataPools())
                .map(processes -> {
                    return ResponseEntity.ok().contentType(JSON_CONTENT_TYPE)
                            .body(serializeDataPool(processes.get(0).getDataBuckets()));
                }).orElseGet(() -> ResponseEntity.status(HttpStatus.NOT_FOUND).contentType(JSON_CONTENT_TYPE)
                        .body(Collections.emptyMap()));
    }

    private Map<String, Object> serializeDataPool(List<DataBucket> buckets) {
        return DataPoolBuilder.rekord.with(DataPoolBuilder.buckets, buckets).serialize(new MapSerializer());
    }

    @RequestMapping(value = "/{projectID}/processes", method = RequestMethod.POST)
    public ResponseEntity<Object> createProcessWithFile(@PathVariable("projectID") String projectID,
            @RequestParam("processLabel") String processLabel, @RequestParam("format") String format,
            @RequestPart("processFile") MultipartFile processFile) throws IllegalStateException, IOException {
        ResponseEntity<Object> resp = null;
        if (spaService.findProjectById(PROJECT_BASE_URL + projectID).isPresent()) {
            Project project = spaService.findProjectById(PROJECT_BASE_URL + projectID).get();
            final DataPool dataPool = project.getDataPools().get(0);
            File fileToImport = FileUtils.convertMultipartToFile(processFile);
            DataBucket process = spaService.importData(fileToImport, format, processLabel, dataPool);
            fileToImport.delete();
            resp = ResponseEntity.status(HttpStatus.CREATED).contentType(JSON_CONTENT_TYPE).body(process);
        } else {
            resp = ResponseEntity.status(HttpStatus.NOT_FOUND).contentType(JSON_CONTENT_TYPE).body(null);
        }
        return resp;
    }

    @RequestMapping(value = "/importformats", method = RequestMethod.GET)
    public ResponseEntity<List<String>> getSupportedImportFormats() {
        return ResponseEntity.status(HttpStatus.OK).contentType(JSON_CONTENT_TYPE)
                .body(spaService.getSupportedImportFormats());
    }

    @RequestMapping(value = "/{projectID}/processes/{processID}", method = RequestMethod.DELETE)
    public ResponseEntity<Void> deleteProcessFromProject(@PathVariable("projectID") String projectID,
            @PathVariable("processID") String processID) {
        BodyBuilder resp = null;
        final Optional<DataPool> dataPool = spaService.findProjectById(PROJECT_BASE_URL + projectID)
                .map(project -> project.getDataPools().get(0));
        final Optional<DataBucket> dataBucketToRemove = (dataPool.isPresent())
                ? dataPool.get().findDataBucketById(PROCESS_BASE_URL + processID)
                : Optional.empty();
        if (dataPool.isPresent() && dataBucketToRemove.isPresent()) {
            spaService.removeDataBucket(dataPool.get(), dataBucketToRemove.get());
            resp = ResponseEntity.status(HttpStatus.OK);
        } else {
            resp = ResponseEntity.status(HttpStatus.NOT_FOUND);
        }
        return resp.build();
    }

    @RequestMapping(value = "/{projectID}/processes/{processID}", method = RequestMethod.GET, produces = "application/octet-stream")
    public ResponseEntity<InputStreamResource> downloadProcessFile(@PathVariable("projectID") String projectID,
            @PathVariable("processID") String processID) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");

        final Optional<DataPool> dataPool = spaService.findProjectById(PROJECT_BASE_URL + projectID)
                .map(project -> project.getDataPools().get(0));
        final Optional<DataBucket> dataBucketToDownload = (dataPool.isPresent())
                ? dataPool.get().findDataBucketById(PROCESS_BASE_URL + processID)
                : Optional.empty();
        final File processFile = Files.createTempFile(dataBucketToDownload.get().getLabel(), "").toFile();

        spaService.exportData(dataBucketToDownload.get(), "BPMN2", processFile);

        headers.add("Content-Disposition", "attachment; filename=" + processFile.getName() + ".bpmn");
        headers.add("Access-Control-Expose-Headers", "Content-Disposition");

        return ResponseEntity.ok().headers(headers).contentLength(processFile.length())
                .contentType(OCTET_CONTENT_TYPE).body(new InputStreamResource(new FileInputStream(processFile)));
    }

}