From f26a0e38ce8a2c977845deb4729f917755b7c345 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <p.gawron@atcomp.pl> Date: Wed, 9 Apr 2025 10:13:23 +0200 Subject: [PATCH] fix problem with uploading data overlay --- .../mapviewer/services/impl/FileService.java | 22 +++++++----- .../services/interfaces/IFileService.java | 5 +-- .../project/overlay/NewDataOverlayDTO.java | 10 ++++++ .../project/overlay/NewOverlayController.java | 29 ++++++++++++++-- .../overlay/NewOverlayControllerTest.java | 34 +++++++++++++++++++ 5 files changed, 86 insertions(+), 14 deletions(-) diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/FileService.java b/service/src/main/java/lcsb/mapviewer/services/impl/FileService.java index c92d07d336..9344c78568 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/FileService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/FileService.java @@ -1,25 +1,24 @@ package lcsb.mapviewer.services.impl; -import java.io.FileNotFoundException; - -import org.hibernate.Hibernate; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - import lcsb.mapviewer.annotation.cache.BigFileCache; import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.persist.dao.cache.UploadedFileEntryDao; import lcsb.mapviewer.services.interfaces.IFileService; +import org.hibernate.Hibernate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.io.FileNotFoundException; @Transactional @Service public class FileService implements IFileService { - private UploadedFileEntryDao uploadedFileEntryDao; + private final UploadedFileEntryDao uploadedFileEntryDao; - private BigFileCache bigFileCache; + private final BigFileCache bigFileCache; @Autowired public FileService(final UploadedFileEntryDao uploadedFileEntryDao, final BigFileCache bigFileCache) { @@ -66,4 +65,9 @@ public class FileService implements IFileService { uploadedFileEntryDao.delete(fileEntry); } + @Override + public byte[] getContentById(final Integer fileId) { + return getById(fileId).getFileContent(); + } + } diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/IFileService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/IFileService.java index 505469a71e..c5638e49c9 100644 --- a/service/src/main/java/lcsb/mapviewer/services/interfaces/IFileService.java +++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/IFileService.java @@ -1,10 +1,10 @@ package lcsb.mapviewer.services.interfaces; -import java.io.FileNotFoundException; - import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.user.User; +import java.io.FileNotFoundException; + public interface IFileService { UploadedFileEntry getById(final Integer id); @@ -19,4 +19,5 @@ public interface IFileService { void delete(UploadedFileEntry fileEntry); + byte[] getContentById(Integer fileId); } diff --git a/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewDataOverlayDTO.java b/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewDataOverlayDTO.java index 93b51ca8b2..cbfe920314 100644 --- a/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewDataOverlayDTO.java +++ b/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewDataOverlayDTO.java @@ -30,6 +30,8 @@ public class NewDataOverlayDTO extends AbstractDTO { @Min(0) private Integer orderIndex; + private Integer fileId; + @NotNull private String description; @@ -112,4 +114,12 @@ public class NewDataOverlayDTO extends AbstractDTO { public void setGroup(final Integer group) { this.group = group; } + + public Integer getFileId() { + return fileId; + } + + public void setFileId(final Integer fileId) { + this.fileId = fileId; + } } diff --git a/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayController.java b/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayController.java index af9b4188ba..ae5be3ee31 100644 --- a/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayController.java +++ b/web/src/main/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayController.java @@ -3,6 +3,9 @@ package lcsb.mapviewer.web.api.project.overlay; import lcsb.mapviewer.api.BaseController; import lcsb.mapviewer.api.QueryException; import lcsb.mapviewer.common.Pair; +import lcsb.mapviewer.common.TextFileUtils; +import lcsb.mapviewer.converter.ColorSchemaReader; +import lcsb.mapviewer.converter.zip.ZipEntryFileFactory; import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.map.BioEntity; @@ -10,6 +13,7 @@ import lcsb.mapviewer.model.map.model.ModelData; import lcsb.mapviewer.model.overlay.DataOverlay; import lcsb.mapviewer.model.overlay.DataOverlayEntry; import lcsb.mapviewer.model.overlay.DataOverlayGroup; +import lcsb.mapviewer.model.overlay.InvalidDataOverlayException; import lcsb.mapviewer.model.security.PrivilegeType; import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.persist.dao.map.DataOverlayGroupProperty; @@ -45,8 +49,10 @@ import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; import javax.validation.constraints.NotNull; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -134,7 +140,7 @@ public class NewOverlayController extends BaseController { final @Valid @NotBlank @PathVariable(value = "projectId") String projectId, final @Valid @RequestBody NewDataOverlayDTO data, final Authentication authentication) - throws QueryException, ObjectNotFoundException { + throws QueryException, ObjectNotFoundException, IOException, InvalidDataOverlayException { final User user = userService.getUserByLogin(authentication.getName()); final Project project = projectService.getProjectByProjectId(projectId); @@ -142,12 +148,29 @@ public class NewOverlayController extends BaseController { throw new ObjectNotFoundException("Project with given projectId does not exist"); } - final UploadedFileEntry entry = createEmptyFile(user); - final DataOverlay overlay = new DataOverlay(); data.saveToDataOverlay(overlay, getGroupIdToGroup(projectId, user.getLogin())); overlay.setProject(project); overlay.setCreator(user); + + UploadedFileEntry entry; + if (data.getFileId() != null) { + entry = fileService.getById(data.getFileId()); + byte[] content = fileService.getContentById(data.getFileId()); + + final ColorSchemaReader reader = new ColorSchemaReader(); + + final Map<String, String> parameters = TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(content)); + final Collection<DataOverlayEntry> schemas = reader.readColorSchema(new ByteArrayInputStream(content), parameters); + overlay.addEntries(schemas); + String nonMatchingAlpha = parameters.get(ZipEntryFileFactory.NON_MATCHING_ALPHA); + if (nonMatchingAlpha != null) { + overlay.setNotMatchingAlpha(nonMatchingAlpha); + } + } else { + entry = createEmptyFile(user); + } + overlay.setInputData(entry); dataOverlayService.add(overlay); diff --git a/web/src/test/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayControllerTest.java b/web/src/test/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayControllerTest.java index 0c8297e06c..b4aeab4eba 100644 --- a/web/src/test/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayControllerTest.java +++ b/web/src/test/java/lcsb/mapviewer/web/api/project/overlay/NewOverlayControllerTest.java @@ -2,13 +2,16 @@ package lcsb.mapviewer.web.api.project.overlay; import com.fasterxml.jackson.core.type.TypeReference; import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.converter.zip.ZipEntryFileFactory; import lcsb.mapviewer.model.Project; +import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.map.layout.ReferenceGenomeType; import lcsb.mapviewer.model.map.model.ModelData; import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.overlay.DataOverlay; +import lcsb.mapviewer.model.overlay.DataOverlayEntry; import lcsb.mapviewer.model.overlay.DataOverlayGroup; import lcsb.mapviewer.model.overlay.DataOverlayType; import lcsb.mapviewer.model.security.PrivilegeType; @@ -32,8 +35,10 @@ import org.springframework.test.web.servlet.RequestBuilder; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; +import java.util.Set; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -530,4 +535,33 @@ public class NewOverlayControllerTest extends ControllerIntegrationTest { mockMvc.perform(request) .andExpect(status().isForbidden()); } + + @Test + public void testCreateOverlayWithFile() throws Exception { + String content = "#" + ZipEntryFileFactory.NON_MATCHING_ALPHA + "=125\n" + createOverlayContentForAllEntities(map); + UploadedFileEntry file = createFile(content, admin); + final MockHttpSession session = createSession(BUILT_IN_TEST_ADMIN_LOGIN, BUILT_IN_TEST_ADMIN_PASSWORD); + + final NewDataOverlayDTO data = createDataOverlayDTO(); + data.setFileId(file.getId()); + + final RequestBuilder request = post("/minerva/new_api/projects/{projectId}/overlays/", TEST_PROJECT) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(data)) + .session(session); + + final MockHttpServletResponse response = mockMvc.perform(request) + .andExpect(status().isCreated()) + .andReturn().getResponse(); + assertNotNull(response.getHeader("ETag")); + final Map<String, Object> result = objectMapper.readValue(response.getContentAsString(), new TypeReference<Map<String, Object>>() { + }); + + Set<DataOverlayEntry> entries = dataOverlayService.getDataOverlayEntriesById(TEST_PROJECT, (int) result.get("id")); + + assertFalse(entries.isEmpty()); + + DataOverlay overlay = dataOverlayService.getDataOverlayById((int) result.get("id")); + assertEquals((Integer) 125, overlay.getNotMatchingAlpha()); + } } -- GitLab