Java tutorial
/******************************************************************************* * Copyright (c) 2015, 2016 Bosch Software Innovations GmbH and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * The Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Bosch Software Innovations GmbH - Please refer to git log *******************************************************************************/ package org.eclipse.vorto.repository.web; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.List; import java.util.Objects; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import org.eclipse.vorto.repository.model.ModelId; import org.eclipse.vorto.repository.model.ModelResource; import org.eclipse.vorto.repository.service.IModelRepository; import org.eclipse.vorto.repository.service.IModelRepository.ContentType; import org.springframework.beans.factory.annotation.Autowired; 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.RestController; import org.springframework.web.multipart.MultipartFile; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; /** * @author Alexander Edelmann - Robert Bosch (SEA) Pte. Ltd. */ @Api(value = "Model Controller", description = "REST API to manage Models") @RestController @RequestMapping(value = "/rest/model") public class ModelRepositoryController { private static final String ATTACHMENT_FILENAME = "attachment; filename = "; private static final String XMI = ".xmi"; private static final String APPLICATION_OCTET_STREAM = "application/octet-stream"; private static final String CONTENT_DISPOSITION = "content-disposition"; @Autowired private IModelRepository modelRepository; private static Logger logger = Logger.getLogger(ModelRepositoryController.class); @ApiOperation(value = "Search in the model repository for the expression") @RequestMapping(value = "/query={expression:.*}", method = RequestMethod.GET) public List<ModelResource> searchByExpression( @ApiParam(value = "Search expression", required = true) @PathVariable String expression) { List<ModelResource> modelResources = modelRepository.search(expression); logger.info("searchByExpression: [" + expression + "] Rows returned: " + modelResources.size()); return modelResources; } @ApiOperation(value = "Returns the Model for a specific Model ID") @RequestMapping(value = "/{namespace}/{name}/{version:.+}", method = RequestMethod.GET) public ModelResource getModelResource( @ApiParam(value = "Namespace", required = true) final @PathVariable String namespace, @ApiParam(value = "name", required = true) final @PathVariable String name, @ApiParam(value = "version", required = true) final @PathVariable String version) { Objects.requireNonNull(namespace, "namespace must not be null"); Objects.requireNonNull(name, "name must not be null"); Objects.requireNonNull(version, "version must not be null"); final ModelId modelId = new ModelId(name, namespace, version); logger.info("getModelResource: [" + modelId.toString() + "] - Fullpath: [" + modelId.getFullPath() + "]"); return modelRepository.getById(modelId); } @ApiOperation(value = "Deletes the Model for a specific Model ID") @RequestMapping(value = "/{namespace}/{name}/{version:.+}", method = RequestMethod.DELETE) public void deleteModelResource( @ApiParam(value = "Namespace", required = true) final @PathVariable String namespace, @ApiParam(value = "name", required = true) final @PathVariable String name, @ApiParam(value = "version", required = true) final @PathVariable String version) { Objects.requireNonNull(namespace, "namespace must not be null"); Objects.requireNonNull(name, "name must not be null"); Objects.requireNonNull(version, "version must not be null"); final ModelId modelId = new ModelId(name, namespace, version); logger.info("getModelResource: [" + modelId.toString() + "] - Fullpath: [" + modelId.getFullPath() + "]"); modelRepository.removeModel(modelId); } @ApiOperation(value = "Returns the image of a Model") @RequestMapping(value = "/image/{namespace}/{name}/{version:.+}", method = RequestMethod.GET) public void getModelImage(@ApiParam(value = "Namespace", required = true) final @PathVariable String namespace, @ApiParam(value = "Namespace", required = true) final @PathVariable String name, @ApiParam(value = "Namespace", required = true) final @PathVariable String version, @ApiParam(value = "Response", required = true) final HttpServletResponse response) { Objects.requireNonNull(namespace, "namespace must not be null"); Objects.requireNonNull(name, "name must not be null"); Objects.requireNonNull(version, "version must not be null"); final ModelId modelId = new ModelId(name, namespace, version); byte[] modelImage = modelRepository.getModelImage(modelId); response.setHeader(CONTENT_DISPOSITION, ATTACHMENT_FILENAME + modelId.getName() + ".png"); response.setContentType(APPLICATION_OCTET_STREAM); try { IOUtils.copy(new ByteArrayInputStream(modelImage), response.getOutputStream()); response.flushBuffer(); } catch (IOException e) { throw new RuntimeException("Error copying file.", e); } } @ApiOperation(value = "Model Image upload") @RequestMapping(value = "/image", method = RequestMethod.POST) public void uploadModelImage( @ApiParam(value = "Image", required = true) @RequestParam("file") MultipartFile file, @ApiParam(value = "Namespace", required = true) final @RequestParam String namespace, @ApiParam(value = "name", required = true) final @RequestParam String name, @ApiParam(value = "version", required = true) final @RequestParam String version) { logger.info("uploadImage: [" + file.getOriginalFilename() + "]"); try { modelRepository.addModelImage(new ModelId(name, namespace, version), file.getBytes()); } catch (IOException e) { throw new RuntimeException(e); } } @ApiOperation(value = "Download a Model specified by Model ID") @RequestMapping(value = "/file/{namespace}/{name}/{version:.+}", method = RequestMethod.GET) public void downloadModelById( @ApiParam(value = "Namespace", required = true) final @PathVariable String namespace, @ApiParam(value = "Name", required = true) final @PathVariable String name, @ApiParam(value = "Version", required = true) final @PathVariable String version, @ApiParam(value = "Output Type", required = true) final @RequestParam(value = "output", required = false) String outputType, @ApiParam(value = "Response", required = true) final HttpServletResponse response) { Objects.requireNonNull(namespace, "namespace must not be null"); Objects.requireNonNull(name, "name must not be null"); Objects.requireNonNull(version, "version must not be null"); final ModelId modelId = new ModelId(name, namespace, version); logger.info("downloadModelById: [" + modelId.toString() + "] - Fullpath: [" + modelId.getFullPath() + "]"); final ContentType contentType = getContentType(outputType); byte[] modelContent = modelRepository.getModelContent(modelId, contentType); if (modelContent != null && modelContent.length > 0) { final ModelResource modelResource = modelRepository.getById(modelId); response.setHeader(CONTENT_DISPOSITION, ATTACHMENT_FILENAME + getFileName(modelResource, contentType)); response.setContentType(APPLICATION_OCTET_STREAM); try { IOUtils.copy(new ByteArrayInputStream(modelContent), response.getOutputStream()); response.flushBuffer(); } catch (IOException e) { throw new RuntimeException("Error copying file.", e); } } else { throw new RuntimeException("File not found."); } } @ApiOperation(value = "Download a specified Model by Model ID, including all References") @RequestMapping(value = "/zip/{namespace}/{name}/{version:.+}", method = RequestMethod.GET) public void downloadModelByIdWithReferences( @ApiParam(value = "Namespace", required = true) final @PathVariable String namespace, @ApiParam(value = "Name", required = true) final @PathVariable String name, @ApiParam(value = "Version", required = true) final @PathVariable String version, @ApiParam(value = "Output Type", required = true) final @RequestParam(value = "output", required = false) String outputType, @ApiParam(value = "Response", required = true) final HttpServletResponse response) { Objects.requireNonNull(namespace, "namespace must not be null"); Objects.requireNonNull(name, "name must not be null"); Objects.requireNonNull(version, "version must not be null"); final ModelId modelId = new ModelId(name, namespace, version); logger.info("downloadModelById: [" + modelId.toString() + "] - Fullpath: [" + modelId.getFullPath() + "]"); final ContentType contentType = getContentType(outputType); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(baos); try { addModelToZip(zos, modelId, contentType); zos.close(); baos.close(); response.setHeader(CONTENT_DISPOSITION, ATTACHMENT_FILENAME + modelId.getNamespace() + "_" + modelId.getName() + "_" + modelId.getVersion() + ".zip"); response.setContentType(APPLICATION_OCTET_STREAM); try { IOUtils.copy(new ByteArrayInputStream(baos.toByteArray()), response.getOutputStream()); response.flushBuffer(); } catch (IOException e) { throw new RuntimeException("Error copying file.", e); } } catch (Exception ex) { throw new RuntimeException(ex); } } private void addModelToZip(ZipOutputStream zipOutputStream, ModelId modelId, ContentType contentType) throws Exception { byte[] modelContent = modelRepository.getModelContent(modelId, contentType); ModelResource modelResource = modelRepository.getById(modelId); try { ZipEntry zipEntry = new ZipEntry(getFileName(modelResource, contentType)); zipOutputStream.putNextEntry(zipEntry); zipOutputStream.write(modelContent); zipOutputStream.closeEntry(); } catch (Exception ex) { // entry possible exists already, so skipping TODO: ugly hack!! } for (ModelId reference : modelResource.getReferences()) { addModelToZip(zipOutputStream, reference, contentType); } } private String getFileName(ModelResource modelResource, ContentType contentType) { if (contentType == ContentType.XMI) { return modelResource.getId().getName() + XMI; } else { return modelResource.getId().getName() + modelResource.getModelType().getExtension(); } } private ContentType getContentType(String output) { if (output == null || output.isEmpty()) { return ContentType.DSL; } else { return ContentType.valueOf(output.toUpperCase()); } } @ApiOperation(value = "Getting all mapped Resources") @RequestMapping(value = "/mapping/zip/{namespace}/{name}/{version:.+}/{targetPlatform}", method = RequestMethod.GET) public void getMappingResources( @ApiParam(value = "Namespace", required = true) final @PathVariable String namespace, @ApiParam(value = "Name", required = true) final @PathVariable String name, @ApiParam(value = "Version", required = true) final @PathVariable String version, @ApiParam(value = "Target Platform", required = true) final @PathVariable String targetPlatform, @ApiParam(value = "Response", required = true) final HttpServletResponse response) { Objects.requireNonNull(namespace, "namespace must not be null"); Objects.requireNonNull(name, "name must not be null"); Objects.requireNonNull(version, "version must not be null"); final ModelId modelId = new ModelId(name, namespace, version); List<ModelResource> mappingResources = modelRepository.getMappingModelsForTargetPlatform(modelId, targetPlatform); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(baos); final ContentType contentType = ContentType.DSL; try { for (ModelResource mappingResource : mappingResources) { addModelToZip(zos, mappingResource.getId(), contentType); } zos.close(); baos.close(); } catch (Exception ex) { throw new RuntimeException(ex); } response.setHeader(CONTENT_DISPOSITION, ATTACHMENT_FILENAME + modelId.getNamespace() + "_" + modelId.getName() + "_" + modelId.getVersion() + ".zip"); response.setContentType(APPLICATION_OCTET_STREAM); try { IOUtils.copy(new ByteArrayInputStream(baos.toByteArray()), response.getOutputStream()); response.flushBuffer(); } catch (IOException e) { throw new RuntimeException("Error copying file.", e); } } }