From 7ab646d9e56d483878fee619db097bb85a38fb9b Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Mon, 7 Apr 2025 14:57:26 +0200
Subject: [PATCH] possibility to add non matching alpha attribute

---
 CHANGELOG                                     |  1 +
 .../converter/ComplexZipConverter.java        |  5 +++
 .../converter/zip/ZipEntryFileFactory.java    |  2 ++
 .../mapviewer/model/overlay/DataOverlay.java  | 18 +++++++++++
 ...9.0.0.20250407__add_not_matching_alpha.sql |  2 ++
 ...9.0.0.20250407__add_not_matching_alpha.sql |  2 ++
 .../services/impl/DataOverlayService.java     |  5 +++
 .../web/OverlayControllerIntegrationTest.java | 31 +++++++++++++++++++
 .../lcsb/mapviewer/web/api/NewApiDocs.java    |  4 +++
 9 files changed, 70 insertions(+)
 create mode 100644 persist/src/main/resources/db/migration/hsql/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql
 create mode 100644 persist/src/main/resources/db/migration/postgres/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql

diff --git a/CHANGELOG b/CHANGELOG
index dadb727914..a697bece18 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -19,6 +19,7 @@ minerva (19.0.0~alpha.0) stable; urgency=medium
   * Small improvement: layers called "text" are visible on the map (#2138)
   * Small improvement: modification residues have text location (#2141)
   * Small improvement: layers have z-index (#2215)
+  * Small improvement: NON_MATCHING_ALPHA attribute to overlay (#2263)
   * Bug fix: text coordinates for multimer species are computed based on
     multimer value when importing from CellDesigner (#2131)
   * Bug fix: when removing project the layer texts/rectangles/ovals were not
diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java
index cf641959f4..d63ae8ef3f 100644
--- a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java
+++ b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java
@@ -394,6 +394,11 @@ public class ComplexZipConverter {
       colorSchemaType = DataOverlayType.GENERIC;
     }
 
+    String nonMatchingAlpha = parameters.get(ZipEntryFileFactory.NON_MATCHING_ALPHA);
+    if (nonMatchingAlpha != null) {
+      layout.setNotMatchingAlpha(nonMatchingAlpha);
+    }
+
     layout.setColorSchemaType(colorSchemaType);
     layout.setInputData(fileEntry);
     layout.setPublic(true);
diff --git a/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java
index 8bc71e00b2..e1073b246f 100644
--- a/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java
+++ b/converter/src/main/java/lcsb/mapviewer/converter/zip/ZipEntryFileFactory.java
@@ -23,6 +23,8 @@ public class ZipEntryFileFactory {
    * corresponding to the {@link LayoutZipEntryFile#type type}.
    */
   public static final String LAYOUT_HEADER_PARAM_TYPE = "TYPE";
+  
+  public static final String NON_MATCHING_ALPHA = "NON_MATCHING_ALPHA";
   /**
    * Name of the parameter in {@link LayoutZipEntryFile file describing layout}
    * corresponding to the {@link LayoutZipEntryFile#genomeType genome type}.
diff --git a/model/src/main/java/lcsb/mapviewer/model/overlay/DataOverlay.java b/model/src/main/java/lcsb/mapviewer/model/overlay/DataOverlay.java
index d3847ea6ec..a47fc95e5c 100644
--- a/model/src/main/java/lcsb/mapviewer/model/overlay/DataOverlay.java
+++ b/model/src/main/java/lcsb/mapviewer/model/overlay/DataOverlay.java
@@ -28,6 +28,8 @@ import javax.persistence.ManyToOne;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.Version;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashSet;
@@ -73,6 +75,10 @@ public class DataOverlay implements MinervaEntity {
   @JsonProperty("publicOverlay")
   private boolean isPublic = false;
 
+  @Max(255)
+  @Min(0)
+  private Integer notMatchingAlpha;
+
   /**
    * Data overlay type. It can be null in such case it should be obtained from
    * {@link #inputData}.
@@ -252,4 +258,16 @@ public class DataOverlay implements MinervaEntity {
   public void setGroup(final DataOverlayGroup group) {
     this.group = group;
   }
+
+  public Integer getNotMatchingAlpha() {
+    return notMatchingAlpha;
+  }
+
+  public void setNotMatchingAlpha(final int notMatchingAlpha) {
+    this.notMatchingAlpha = notMatchingAlpha;
+  }
+
+  public void setNotMatchingAlpha(final String notMatchingAlpha) {
+    this.notMatchingAlpha = Integer.parseInt(notMatchingAlpha);
+  }
 }
diff --git a/persist/src/main/resources/db/migration/hsql/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql b/persist/src/main/resources/db/migration/hsql/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql
new file mode 100644
index 0000000000..455a107138
--- /dev/null
+++ b/persist/src/main/resources/db/migration/hsql/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql
@@ -0,0 +1,2 @@
+alter table public.data_overlay_table
+    add column not_matching_alpha integer;
diff --git a/persist/src/main/resources/db/migration/postgres/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql b/persist/src/main/resources/db/migration/postgres/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql
new file mode 100644
index 0000000000..455a107138
--- /dev/null
+++ b/persist/src/main/resources/db/migration/postgres/19.0.0~alpha.0/V19.0.0.20250407__add_not_matching_alpha.sql
@@ -0,0 +1,2 @@
+alter table public.data_overlay_table
+    add column not_matching_alpha integer;
diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/DataOverlayService.java b/service/src/main/java/lcsb/mapviewer/services/impl/DataOverlayService.java
index 96fb86cac5..bcbecca8fc 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/DataOverlayService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/DataOverlayService.java
@@ -100,6 +100,11 @@ public class DataOverlayService implements IDataOverlayService {
     overlay.setCreator(params.getUser());
     overlay.addEntries(schemas);
 
+    String nonMatchingAlpha = parameters.get(ZipEntryFileFactory.NON_MATCHING_ALPHA);
+    if (nonMatchingAlpha != null) {
+      overlay.setNotMatchingAlpha(nonMatchingAlpha);
+    }
+
     if (colorSchemaType == DataOverlayType.GENETIC_VARIANT) {
       final String genomeVersion = parameters.get(ZipEntryFileFactory.LAYOUT_HEADER_PARAM_GENOME_VERSION);
       ReferenceGenomeType genomeType = ReferenceGenomeType.UCSC;
diff --git a/web/src/test/java/lcsb/mapviewer/web/OverlayControllerIntegrationTest.java b/web/src/test/java/lcsb/mapviewer/web/OverlayControllerIntegrationTest.java
index 6dd0ad2982..e6f02f2239 100644
--- a/web/src/test/java/lcsb/mapviewer/web/OverlayControllerIntegrationTest.java
+++ b/web/src/test/java/lcsb/mapviewer/web/OverlayControllerIntegrationTest.java
@@ -1365,6 +1365,10 @@ public class OverlayControllerIntegrationTest extends ControllerIntegrationTest
         fieldWithPath("order")
             .description("sort order")
             .type(JsonFieldType.NUMBER),
+        fieldWithPath("notMatchingAlpha")
+            .description("alpha to be used for all not matching bioEntities when highlighting this overlay")
+            .optional()
+            .type(JsonFieldType.NUMBER),
         fieldWithPath("type")
             .description("type; available options: " + new ProjectSnippets().getOptionsAsString(DataOverlayType.class))
             .type(JsonFieldType.STRING),
@@ -1753,4 +1757,31 @@ public class OverlayControllerIntegrationTest extends ControllerIntegrationTest
         .andExpect(status().isForbidden());
   }
 
+  @Test
+  public void testCreateOverlayWithNotMatchingAlpha() throws Exception {
+    final User admin = userService.getUserByLogin(BUILT_IN_TEST_ADMIN_LOGIN);
+
+    final UploadedFileEntry file = createFile("#NON_MATCHING_ALPHA=243\nelement_identifier\tvalue\tcolor\n", admin);
+
+    final MockHttpSession session = createSession(BUILT_IN_TEST_ADMIN_LOGIN, BUILT_IN_TEST_ADMIN_PASSWORD);
+
+    final String body = EntityUtils.toString(new UrlEncodedFormEntity(Arrays.asList(
+        new BasicNameValuePair("fileId", String.valueOf(file.getId())),
+        new BasicNameValuePair("name", "overlay name"),
+        new BasicNameValuePair("description", "overlay name"),
+        new BasicNameValuePair("filename", "overlay name"),
+        new BasicNameValuePair("type", "GENERIC"))));
+
+    final RequestBuilder request = post("/minerva/api/projects/{projectId}/overlays/", TEST_PROJECT)
+        .contentType(MediaType.APPLICATION_FORM_URLENCODED)
+        .content(body)
+        .session(session);
+
+    mockMvc.perform(request)
+        .andExpect(status().is2xxSuccessful());
+
+    DataOverlay overlay = dataOverlayService.getDataOverlaysByProject(project).get(0);
+    assertEquals((Integer) 243, overlay.getNotMatchingAlpha());
+  }
+
 }
diff --git a/web/src/test/java/lcsb/mapviewer/web/api/NewApiDocs.java b/web/src/test/java/lcsb/mapviewer/web/api/NewApiDocs.java
index b157a93fc5..a0d15eec7c 100644
--- a/web/src/test/java/lcsb/mapviewer/web/api/NewApiDocs.java
+++ b/web/src/test/java/lcsb/mapviewer/web/api/NewApiDocs.java
@@ -487,6 +487,10 @@ public class NewApiDocs {
             .description("group identifier")
             .optional()
             .type(JsonFieldType.NUMBER),
+        fieldWithPath(prefix + "notMatchingAlpha")
+            .description("alpha to be used for all not matching bioEntities when highlighting this overlay")
+            .optional()
+            .type(JsonFieldType.NUMBER),
         fieldWithPath(prefix + "id")
             .description("id")
             .type(JsonFieldType.NUMBER),
-- 
GitLab