package com.aemreunal.controller.region; /* * *********************** * * Copyright (c) 2015 * * * * This code belongs to: * * * * @author Ahmet Emre Ünal * * S001974 * * * * aemreunal@gmail.com * * emre.unal@ozu.edu.tr * * * * aemreunal.com * * *********************** * */ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.util.UriComponentsBuilder; import com.aemreunal.config.GlobalSettings; import com.aemreunal.domain.Region; import com.aemreunal.exception.imageStorage.ImageLoadException; import com.aemreunal.exception.imageStorage.ImageSaveException; import com.aemreunal.exception.region.MultipartFileReadException; import com.aemreunal.exception.region.WrongFileTypeSubmittedException; import com.aemreunal.service.RegionService; @Controller @RequestMapping(GlobalSettings.REGION_PATH_MAPPING) public class RegionController { @Autowired private RegionService regionService; /** * Get regions that belong to a project. * * @param username * The username of the owner of the region. * @param projectId * The ID of the project the region belongs to. * * @return The list of regions that belong to the project. */ @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<List<Region>> getRegionsOfProject(@PathVariable String username, @PathVariable Long projectId, @RequestParam(value = "name", required = false, defaultValue = "") String regionName) { if (regionName.equals("")) { List<Region> regions = regionService.getAllRegionsOf(username, projectId); return new ResponseEntity<List<Region>>(regions, HttpStatus.OK); } else { List<Region> regions = regionService.findRegionsBySpecs(username, projectId, regionName); return new ResponseEntity<List<Region>>(regions, HttpStatus.OK); } } /** * Get the region with specified ID. * * @param username * The username of the owner of the region. * @param projectId * The ID of the project the region belongs to. * @param regionId * The ID of the region. * * @return The region. */ @RequestMapping(method = RequestMethod.GET, value = GlobalSettings.REGION_ID_MAPPING, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Region> getRegion(@PathVariable String username, @PathVariable Long projectId, @PathVariable Long regionId) { Region region = regionService.getRegion(username, projectId, regionId); // TODO add links return new ResponseEntity<Region>(region, HttpStatus.OK); } /** * Create a new region in project. The [REST] method accepts the region JSON and the * region image file as Multipart files. The region JSON Multipart file must be named * {@code region} and the region image Multipart file must be named {@code image}. * <p> * For the image file, the method accepts {@link org.springframework.http.MediaType#IMAGE_JPEG * JPEG}, {@link org.springframework.http.MediaType#IMAGE_PNG PNG}, and {@link * org.springframework.http.MediaType#IMAGE_GIF GIF} images. The image size must be <= * {@link com.aemreunal.config.GlobalSettings#MAX_UPLOAD_SIZE_BYTES * MAX_UPLOAD_SIZE_BYTES} Bytes. * * @param username * The username of the owner of the project. * @param projectId * The ID of the project the region belongs to. * @param region * The region object to be created. * @param imageMultipartFile * The region map image file as a {@link org.springframework.web.multipart.MultipartFile * MultipartFile}. * @param builder * The URI builder for post-creation redirect. * * @return The created region as JSON. * * @throws WrongFileTypeSubmittedException * The file type of the {@link org.springframework.web.multipart.MultipartFile * MultipartFile} file submitted as the region map image is of some other type * than JPEG, GIF, or PNG. * @throws ImageSaveException * If the server is unable to save the region map image. * @throws MultipartFileReadException * If the Multipart file couldn't be read. */ @RequestMapping(method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Region> createRegion(@PathVariable String username, @PathVariable Long projectId, @RequestPart(value = "region") Region region, @RequestPart(value = "image") MultipartFile imageMultipartFile, UriComponentsBuilder builder) throws WrongFileTypeSubmittedException, ImageSaveException, MultipartFileReadException { Region savedRegion = regionService.saveNewRegion(username, projectId, region, imageMultipartFile); GlobalSettings.log("Saved region with ID = \'" + savedRegion.getRegionId() + "\' name = \'" + savedRegion.getName() + "\' in project with ID = \'" + projectId + "\'"); return buildCreateResponse(username, builder, savedRegion); } private ResponseEntity<Region> buildCreateResponse(String username, UriComponentsBuilder builder, Region savedRegion) { HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path(GlobalSettings.REGION_SPECIFIC_MAPPING) .buildAndExpand( username, savedRegion.getProject().getProjectId(), savedRegion.getRegionId()) .toUri()); return new ResponseEntity<Region>(savedRegion, headers, HttpStatus.CREATED); } /** * Download the region map image. The image is sent as a byte stream. * * @param username * The username of the owner of the region. * @param projectId * The ID of the project the region belongs to. * @param regionId * The ID of the region. * * @return The region map image as {@code byte[]}. * * @throws ImageLoadException * If the map image couldn't be loaded from the filesystem. */ @RequestMapping(method = RequestMethod.GET, value = GlobalSettings.REGION_MAP_IMAGE_MAPPING, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) // When RegionNotFoundException is triggered as a result of this method, an HttpMediaTypeNotAcceptableException // exception is raised. It's not raised if the exception handler also returns ResponseEntity<byte[]>. // TODO Fix. public ResponseEntity<byte[]> downloadRegionMapImage(@PathVariable String username, @PathVariable Long projectId, @PathVariable Long regionId) throws ImageLoadException { return new ResponseEntity<byte[]>(regionService.getMapImage(username, projectId, regionId), HttpStatus.OK); } /** * Delete the specified region. * * @param username * The username of the owner of the region. * @param projectId * The ID of the project the region belongs to. * @param regionId * The ID of the region. * * @return The deleted region. */ @RequestMapping(method = RequestMethod.DELETE, value = GlobalSettings.REGION_ID_MAPPING, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Region> deleteRegion(@PathVariable String username, @PathVariable Long projectId, @PathVariable Long regionId, @RequestParam(value = "confirm", required = true) String confirmation) { if (confirmation.toLowerCase().equals("yes")) { Region deletedRegion = regionService.delete(username, projectId, regionId); return new ResponseEntity<Region>(deletedRegion, HttpStatus.OK); } else { return new ResponseEntity<Region>(HttpStatus.PRECONDITION_FAILED); } } }