From edaf762799587d7168dcec3a7055c3fe68c76438 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Mar 2019 09:34:14 +0100 Subject: [PATCH 01/33] Parts dealing with TAIR locus name changed to id --- .../services/annotators/KeggAnnotator.java | 17 +++++-- .../services/annotators/TairAnnotator.java | 4 +- .../services/annotators/UniprotAnnotator.java | 48 ++++++++++++++++++- .../annotators/KeggAnnotatorTest.java | 2 +- .../annotators/TairAnnotatorTest.java | 2 +- .../annotators/UniprotAnnotatorTest.java | 24 ++++++++++ 6 files changed, 87 insertions(+), 10 deletions(-) diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java index eba58560f..c07010123 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java @@ -152,6 +152,9 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService logger.warn("Cannot find kegg data for id: " + identifier); } catch (IOException exception) { throw new AnnotatorException(exception); + } catch (UniprotSearchException e) { + logger.warn(e, e); + return false; } } object.addMiriamData(annotations); @@ -181,8 +184,9 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService * organisms names. If the value has not been set by the user, null * will be passed. * @return {@link MiriamType#PUBMED}s found on the page + * @throws UniprotSearchException */ - private Collection parseKegg(String pageContent, AnnotatorData params) { + private Collection parseKegg(String pageContent, AnnotatorData params) throws UniprotSearchException { // Retrieve Pubmeds Collection result = new HashSet<>(); @@ -201,10 +205,13 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService } else { m = athOrthologMatcher.matcher(pageContent); if (m.find()) { - String[] tairCodes = m.group(1).trim().split(" "); - for (String tairCode : tairCodes) { - tairCode = tairCode.split("\\(")[0]; // some codes are in the form AT1G08510(FATB) - result.add(new MiriamData(MiriamType.TAIR_LOCUS, tairCode)); + String[] tairLocusNames = m.group(1).trim().split(" "); + for (String tairLocusName : tairLocusNames) { + tairLocusName = tairLocusName.split("\\(")[0]; // some codes are in the form AT1G08510(FATB) + MiriamData md = uniprotAnnotator.uniprotTairLocusToId(tairLocusName); + if (!md.equals(new MiriamData())){ + result.add(md); + } } } } diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java index 44b767900..0c3eb9948 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java @@ -97,8 +97,8 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService * @return URL to UniProt result page with the TAIR mapping */ private String getUniProtUrl(String tairId) { - return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair%29+database%3A%28type%3Atair+" + tairId - + "%29&format=list&columns=id"; + return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair%29+" + tairId + + "&format=list&columns=id"; } /** diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java index 6a593f108..685d8641b 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java @@ -59,6 +59,12 @@ public class UniprotAnnotator extends ElementAnnotator implements IExternalServi */ private Pattern uniprotToEC = Pattern .compile("EC=((\\d+\\.-\\.-\\.-)|(\\d+\\.\\d+\\.-\\.-)|(\\d+\\.\\d+\\.\\d+\\.-)|(\\d+\\.\\d+\\.\\d+\\.\\d+))"); + + /** + * Pattern used for finding EC symbol from UniProt info page . + */ + private Pattern uniprotTairLocusToId = Pattern + .compile("locus:(\\d*)"); /** * Default constructor. @@ -136,6 +142,19 @@ public class UniprotAnnotator extends ElementAnnotator implements IExternalServi private String getUniprotUrl(String uniprotId) { return "https://www.uniprot.org/uniprot/" + uniprotId + ".txt"; } + + /** + * Returns URL to UniProt result containing mapped UniProtIds for submitted TAIR + * entry. + * + * @param tairId + * TAIR identifier + * @return URL to UniProt result page with the TAIR mapping + */ + private String getUniProtTairLocus2IdUrl(String tairLocus) { + return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair%29+"+tairLocus+ + "&format=tab&columns=id,database(tair) "; + } /** * Parse uniprot webpage to find information about {@link MiriamType#ENTREZ} and @@ -250,7 +269,34 @@ public class UniprotAnnotator extends ElementAnnotator implements IExternalServi } } - + + /** + * Transform TAIR Locus name into TAIR Locus identifier. + * UniProt is used for this task because TAIR i) does not have + * an API and ii) restricts the number of accesses. + * + * @param tairLocus + * String with the TAIR Locus name. + * @return {@link MiriamData} with TAIR Locus ID + * @throws UniprotSearchException + * thrown when there is a problem with accessing external database + */ + public MiriamData uniprotTairLocusToId(String tairLocus) throws UniprotSearchException { + String accessUrl = getUniProtTairLocus2IdUrl(tairLocus); + try { + String pageContent = getWebPageContent(accessUrl); + Matcher m = uniprotTairLocusToId.matcher(pageContent); + if (m.find()) { + return new MiriamData(MiriamType.TAIR_LOCUS, m.group(1)); + } else { + logger.warn("No TAIR ID found for locus: " + tairLocus); + return new MiriamData(); + } + } catch (IOException e) { + throw new UniprotSearchException("Problem with accessing uniprot webpage", e); + } + } + @Override public String getCommonName() { return MiriamType.UNIPROT.getCommonName(); diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotatorTest.java index 6a44ecd37..7db8c0f41 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotatorTest.java @@ -189,7 +189,7 @@ public class KeggAnnotatorTest extends AnnotationTestFunctions { try { Species protein = new GenericProtein("id"); protein.setName("bla"); - protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "AT3G25110")); + protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "2090285")); //TAIR locus AT3G25110 keggAnnotator.annotateElement(protein); diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java index 75d58d8fd..bb96ba99f 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java @@ -156,7 +156,7 @@ public class TairAnnotatorTest extends AnnotationTestFunctions { // @Ignore("TAIR DB restricts queries by IP") public void testTairToUniprot() throws Exception { try { - assertTrue(tairAnnotator.tairToUniprot(new MiriamData(MiriamType.TAIR_LOCUS, "AT1G01030")) + assertTrue(tairAnnotator.tairToUniprot(new MiriamData(MiriamType.TAIR_LOCUS, "2200950")) // TAIR locus AT1G01030 .contains(new MiriamData(MiriamType.UNIPROT, "Q9MAN1"))); } catch (Exception e) { e.printStackTrace(); diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java index 04e04bd7d..7fa99b9d2 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java @@ -278,6 +278,30 @@ public class UniprotAnnotatorTest extends AnnotationTestFunctions { throw e; } } + + @Test + public void testUniprotTairLocusToId() throws Exception { + try { + assertEquals(new MiriamData(MiriamType.TAIR_LOCUS, "2201786"), + uniprotAnnotator.uniprotTairLocusToId("AT1G08510") ); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testUniprotWrongTairLocusToId() throws Exception { + try { + assertEquals(new MiriamData(), + uniprotAnnotator.uniprotTairLocusToId("XXXXXX")); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test public void testStatus() throws Exception { -- GitLab From 2a895d17d0f3facd7e47d466c56eca23549459c7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Apr 2019 09:45:09 +0200 Subject: [PATCH 02/33] tair name; tair and string annotator only annotate based on human annotated miriam data --- .../services/annotators/KeggAnnotator.java | 2 +- .../services/annotators/StringAnnotator.java | 10 ++++- .../services/annotators/TairAnnotator.java | 40 +++++++++++++++---- .../services/annotators/UniprotAnnotator.java | 9 ++--- .../annotators/StringAnnotatorTest.java | 25 ++++++++++-- .../annotators/TairAnnotatorTest.java | 21 +++++++++- .../annotators/UniprotAnnotatorTest.java | 4 +- 7 files changed, 89 insertions(+), 22 deletions(-) diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java index c07010123..dbc1b48d3 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/KeggAnnotator.java @@ -208,7 +208,7 @@ public class KeggAnnotator extends ElementAnnotator implements IExternalService String[] tairLocusNames = m.group(1).trim().split(" "); for (String tairLocusName : tairLocusNames) { tairLocusName = tairLocusName.split("\\(")[0]; // some codes are in the form AT1G08510(FATB) - MiriamData md = uniprotAnnotator.uniprotTairLocusToId(tairLocusName); + MiriamData md = uniprotAnnotator.uniprotTairLocusNameToId(tairLocusName); if (!md.equals(new MiriamData())){ result.add(md); } diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java index 7fd79cc71..f32e7904e 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotator.java @@ -32,6 +32,12 @@ public class StringAnnotator extends ElementAnnotator implements IExternalServic /** * Service used for annotation of entities using {@link MiriamType#TAIR_LOCUS * TAIR}. + * Note that STRING annotation process will annotate only + * records which have a TAIR ID assigned by a human annotator. + * Otherwise, it would generate UniProt miriam records also for + * TAIR IDs generated from, e.g., KEGG annotator, i.e. for homologues + * and these UniProt IDs would be indistinguishable from the + * UniProt IDs describing the molecule. */ private TairAnnotator tairAnnotator; @@ -54,7 +60,9 @@ public class StringAnnotator extends ElementAnnotator implements IExternalServic throws AnnotatorException { List mdUniprots = new ArrayList<>(); if (identifier.getDataType().equals(MiriamType.TAIR_LOCUS)) { - mdUniprots.addAll(tairAnnotator.tairToUniprot(identifier)); + if (identifier.getAnnotator() == null) { + mdUniprots.addAll(tairAnnotator.tairToUniprot(identifier)); + } } else if (identifier.getDataType().equals(MiriamType.UNIPROT)) { mdUniprots.add(identifier); } else { diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java index 0c3eb9948..ca616846a 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotator.java @@ -5,6 +5,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.apache.log4j.Logger; import org.springframework.stereotype.Service; @@ -28,6 +30,13 @@ import lcsb.mapviewer.model.user.annotator.AnnotatorOutputParameter; /** * This is a class that implements a backend to TAIR. + * Note that TAIR annotation process will annotate only + * records which have a TAIR ID assigned by a human annotator. + * Otherwise, it would generate UniProt miriam records also for + * TAIR IDs generated from, e.g., KEGG annotator, i.e. for homologues + * and these UniProt IDs would be indistinguishable from the + * UniProt IDs describing the molecule. + * * * @author David Hoksza * @@ -39,6 +48,14 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService * Default class logger. */ private static Logger logger = Logger.getLogger(TairAnnotator.class); + + /** + * Pattern used for getting Tair Locus ID symbol from UniProt result page. + */ + private Pattern getUniprotIdParsePattern(String tairId) { + return Pattern.compile("(\\w*)\\tlocus:" + tairId); + } + /** * Default constructor. @@ -74,7 +91,13 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService @Override public boolean annotateElement(BioEntityProxy object, MiriamData identifier, AnnotatorData parameters) throws AnnotatorException { + + if (identifier.getAnnotator() != null) { + return false; + } if (identifier.getDataType().equals(MiriamType.TAIR_LOCUS)) { + //UniProt are only obained from TAIR's which were provided by the annotator (otherwise we would get + //also UniProt IDs for, e.g., homologous genes' TAIR IDs obtained from KEGG Collection collection = tairToUniprot(identifier); if (collection.size() > 0) { object.addMiriamData(collection); @@ -97,8 +120,8 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService * @return URL to UniProt result page with the TAIR mapping */ private String getUniProtUrl(String tairId) { - return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair%29+" + tairId - + "&format=list&columns=id"; + return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair%29+" + tairId + "&format=tab&columns=id,database(tair)"; +// return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair+"+tairId+"%29&format=list&columns=id"; } /** @@ -110,11 +133,14 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService * uniprot REST API result page * @return uniprot identifier found on the page */ - private Collection parseUniprotUniprot(String pageContent) { + private Collection parseUniprotUniprot(String pageContent, String tairId) { Collection result = new HashSet(); if (!pageContent.isEmpty()) { - String[] sPageContent = pageContent.split("\\R"); - result.add(new MiriamData(MiriamType.UNIPROT, sPageContent[0])); + //the query returns a list of possible matches which needs to be pruned + Matcher m = getUniprotIdParsePattern(tairId).matcher(pageContent); + if (m.find()) { + result.add(new MiriamData(MiriamType.UNIPROT, m.group(1))); + } } return result; } @@ -144,7 +170,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService try { String accessUrl = getUniProtUrl(tair.getResource()); String pageContent = getWebPageContent(accessUrl); - return parseUniprotUniprot(pageContent); + return parseUniprotUniprot(pageContent, tair.getResource()); } catch (WrongResponseCodeIOException exception) { logger.warn("Wrong reponse code when accessing tair data with id: " + tair.getResource()); return null; @@ -185,7 +211,7 @@ public class TairAnnotator extends ElementAnnotator implements IExternalService @Override public MiriamData getExampleValidAnnotation() { - return new MiriamData(MiriamType.TAIR_LOCUS, "AT1G01030"); + return new MiriamData(MiriamType.TAIR_LOCUS, "2200950"); } } diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java index 685d8641b..3fbe2c065 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotator.java @@ -61,7 +61,7 @@ public class UniprotAnnotator extends ElementAnnotator implements IExternalServi .compile("EC=((\\d+\\.-\\.-\\.-)|(\\d+\\.\\d+\\.-\\.-)|(\\d+\\.\\d+\\.\\d+\\.-)|(\\d+\\.\\d+\\.\\d+\\.\\d+))"); /** - * Pattern used for finding EC symbol from UniProt info page . + * Pattern used for getting Tair Locus ID symbol from UniProt result page. */ private Pattern uniprotTairLocusToId = Pattern .compile("locus:(\\d*)"); @@ -151,9 +151,8 @@ public class UniprotAnnotator extends ElementAnnotator implements IExternalServi * TAIR identifier * @return URL to UniProt result page with the TAIR mapping */ - private String getUniProtTairLocus2IdUrl(String tairLocus) { - return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair%29+"+tairLocus+ - "&format=tab&columns=id,database(tair) "; + private String getUniProtTairLocus2IdUrl(String tairLocusName) { + return "https://www.uniprot.org/uniprot/?query=database%3A%28type%3Atair+" + tairLocusName + "%29&format=tab&columns=id,database(tair)"; } /** @@ -281,7 +280,7 @@ public class UniprotAnnotator extends ElementAnnotator implements IExternalServi * @throws UniprotSearchException * thrown when there is a problem with accessing external database */ - public MiriamData uniprotTairLocusToId(String tairLocus) throws UniprotSearchException { + public MiriamData uniprotTairLocusNameToId(String tairLocus) throws UniprotSearchException { String accessUrl = getUniProtTairLocus2IdUrl(tairLocus); try { String pageContent = getWebPageContent(accessUrl); diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java index 4c1f91dd1..2c9b90664 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/StringAnnotatorTest.java @@ -57,12 +57,12 @@ public class StringAnnotatorTest extends AnnotationTestFunctions { } @Test - @Ignore("TAIR DB restricts queries by IP") +// @Ignore("TAIR DB restricts queries by IP") public void testAnnotateTair() throws Exception { try { Species bioEntity = new GenericProtein("id"); - bioEntity.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "AT1G01030")); + bioEntity.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "2200950")); testedAnnotator.annotateElement(bioEntity); @@ -70,18 +70,35 @@ public class StringAnnotatorTest extends AnnotationTestFunctions { for (MiriamData md : bioEntity.getMiriamData()) { if (md.getDataType().equals(MiriamType.STRING)) { - mdString = md; // there should be only one EC number for that TAIR<->UNIPROT record + mdString = md; } } assertTrue("No STRING annotation extracted from STRING annotator", mdString != null); - assertTrue("Wrong number of annotations extract from STRING annotator", bioEntity.getMiriamData().size() == 3); + assertTrue("Wrong number of annotations extract from STRING annotator", bioEntity.getMiriamData().size() == 2); } catch (Exception e) { e.printStackTrace(); throw e; } } + + @Test +//@Ignore("TAIR DB restricts queries by IP") +public void testAnnotateTairOnlyFromHumanAnnotator() throws Exception { + try { + + Species bioEntity = new GenericProtein("id"); + bioEntity.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "2200950", KeggAnnotator.class)); + + testedAnnotator.annotateElement(bioEntity); + + assertTrue(bioEntity.getMiriamData().size() == 1); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } +} @Test public void testAnnotateInvalidEmpty() throws Exception { diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java index bb96ba99f..8c2b7fb4b 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/TairAnnotatorTest.java @@ -1,6 +1,7 @@ package lcsb.mapviewer.annotation.services.annotators; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -45,7 +46,7 @@ public class TairAnnotatorTest extends AnnotationTestFunctions { Species protein = new GenericProtein("id"); protein.setName("bla"); - protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "AT1G01030")); + protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "2200950")); //AT1G01030 tairAnnotator.annotateElement(protein); @@ -74,7 +75,7 @@ public class TairAnnotatorTest extends AnnotationTestFunctions { Species protein = new GenericProtein("id"); protein.setName("bla"); - protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "AT1G15950")); + protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "2200427")); protein.addMiriamData(new MiriamData(MiriamType.UNIPROT, "P32246")); // Human version of the protein tairAnnotator.annotateElement(protein); @@ -163,6 +164,22 @@ public class TairAnnotatorTest extends AnnotationTestFunctions { throw e; } } + + @Test + public void testTairToUniprotFromKEGG() throws Exception { + //TAIR Loci comming from annotators should be ignored by TAIR (only TAIR LOCI provided by the human annotator should be considered) + try { + Species protein = new GenericProtein("id"); + protein.setName("bla"); + protein.addMiriamData(new MiriamData(MiriamType.TAIR_LOCUS, "2200427", KeggAnnotator.class)); + tairAnnotator.annotateElement(protein); + assertTrue( protein.getMiriamData().size() == 1); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + @Test // @Ignore("TAIR DB restricts queries by IP") diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java index 7fa99b9d2..aaa118d44 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/annotators/UniprotAnnotatorTest.java @@ -283,7 +283,7 @@ public class UniprotAnnotatorTest extends AnnotationTestFunctions { public void testUniprotTairLocusToId() throws Exception { try { assertEquals(new MiriamData(MiriamType.TAIR_LOCUS, "2201786"), - uniprotAnnotator.uniprotTairLocusToId("AT1G08510") ); + uniprotAnnotator.uniprotTairLocusNameToId("AT1G08510") ); } catch (Exception e) { e.printStackTrace(); throw e; @@ -294,7 +294,7 @@ public class UniprotAnnotatorTest extends AnnotationTestFunctions { public void testUniprotWrongTairLocusToId() throws Exception { try { assertEquals(new MiriamData(), - uniprotAnnotator.uniprotTairLocusToId("XXXXXX")); + uniprotAnnotator.uniprotTairLocusNameToId("bla")); } catch (Exception e) { e.printStackTrace(); throw e; -- GitLab From 1ea2b1957397d2bed11d66c7abe4dcf9f3a2127a Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Mon, 13 May 2019 19:33:30 +0200 Subject: [PATCH 03/33] changelog updated --- CHANGELOG | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f758efea9..ac257c202 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -minerva (13.1.0~alpha.0) unstable; urgency=low +minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and outputs used by annotator (#617) * Feature: changes in admin panel doesn't require saving - they are saved @@ -68,10 +68,10 @@ minerva (13.1.0~alpha.0) unstable; urgency=low * Bug fix: plugin contect element width is adjusted when link to tabs are wrapped in more than one line (#758) * Bug fix: export to CellDesigner preserve font size (#803) - * Bug fix: layout data was ignored for some reactions when improting from + * Bug fix: layout data was ignored for some reactions when importing from SBML (#812) - -- Piotr Gawron Tue, 7 May 2019 15:00:00 +0200 + -- Piotr Gawron Mon, 13 May 2019 19:00:00 +0200 minerva (13.0.0) stable; urgency=medium * Bug fix: Since Oracle Java cannot be installed as debian dependency we use -- GitLab From 829b5269f5ed0efa891707376ea28f3a0ba68d1e Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 16 May 2019 16:18:56 +0200 Subject: [PATCH 04/33] changelog updated --- CHANGELOG | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 2eef00a6c..47fd6f79e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +minerva (12.3.1~beta.1) unstable; urgency=low + * Bug fix: tair locus identifiers were used improperly - instead of id the + name was used + minerva (12.3.0~alpha.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and outputs used by annotator (#617) -- GitLab From 15098e705a0610ad6a3e1977bdd3d7bbeb3fe78e Mon Sep 17 00:00:00 2001 From: Ewa Smula Date: Fri, 17 May 2019 15:47:18 +0200 Subject: [PATCH 05/33] Issue number corrected --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index cb7445880..4012bfdff 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -71,7 +71,7 @@ minerva (13.1.0~beta.0) unstable; urgency=low having the aa change information * Bug fix: plugin contect element width is adjusted when link to tabs are wrapped in more than one line (#758) - * Bug fix: export to CellDesigner preserve font size (#803) + * Bug fix: export to CellDesigner preserve font size (#798) * Bug fix: layout data was ignored for some reactions when importing from SBML (#812) -- GitLab From dace90d224d8c0a3af4195d5a87b031a4ce25890 Mon Sep 17 00:00:00 2001 From: Ewa Smula Date: Mon, 20 May 2019 13:34:17 +0200 Subject: [PATCH 06/33] #758 corrected on #798 --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index cb7445880..f03cfe476 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,7 +18,7 @@ minerva (13.1.0~beta.0) unstable; urgency=low comment dialog (#680) * Small improvement: Left logo is configurable (#731) * Small improvement: list of element types in choose annotator dialog is - sorted (#758) + sorted (#798) * Small improvement: Plugin API provides list of overview images (#702) * Small improvement: Plugin API allows to show/hide overview images (#702) * Small improvement: Plugin API allows to trigger search on the map (#702) -- GitLab From 0dcae56e61dc6440e6c12e1ee1ffe5839e45d724 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 15:14:06 +0200 Subject: [PATCH 07/33] ssl certificate is valid for ctdbase hoomepage --- .../java/lcsb/mapviewer/annotation/services/ChemicalParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChemicalParser.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChemicalParser.java index 0ecb5a69c..3277764f5 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChemicalParser.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChemicalParser.java @@ -70,7 +70,7 @@ public class ChemicalParser extends CachableInterface implements IExternalServic /** * Home page of ctd database. */ - static final String URL = "http://ctdbase.org/"; + static final String URL = "https://ctdbase.org/"; /** * URL to get a list of chemicals by disease id. -- GitLab From 9e20511fca0b3f20c3eb255c637be6576057424d Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 16:50:12 +0200 Subject: [PATCH 08/33] plugin tab didn't resize content properly when new plugin link was in a new line --- CHANGELOG | 2 ++ frontend-js/src/main/js/plugin/PluginManager.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index d0e92f85e..815cb0ba9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: tair locus identifiers were used improperly - instead of id the name was used + * Bug fix: plugin tab header wasn't properly resized after adding plugins + that introduced second line for tab selection (#758) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/plugin/PluginManager.js b/frontend-js/src/main/js/plugin/PluginManager.js index 8fbf00c05..a04aa1628 100644 --- a/frontend-js/src/main/js/plugin/PluginManager.js +++ b/frontend-js/src/main/js/plugin/PluginManager.js @@ -70,6 +70,7 @@ PluginManager.prototype.getGuiUtils = function () { */ PluginManager.prototype.addPlugin = function (options) { var self = this; + var oldLinkHeight = $(".nav-tabs", self.getElement()).height(); $(self.getElement()).show(); if (self._panels === undefined) { self.getGuiUtils().initTabContent(self); @@ -78,7 +79,6 @@ PluginManager.prototype.addPlugin = function (options) { self.getGuiUtils().addTab(self, {name: "PLUGIN", content: element}); - var oldLinkHeight = $(".nav-tabs", self.getElement()).height(); var plugin; return Promise.resolve().then(function () { if (options instanceof Plugin) { -- GitLab From b4ce4d37ebbe350b10c98d4d20bdfddf142fe78e Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 17:33:15 +0200 Subject: [PATCH 09/33] invisible layer is not drawn --- CHANGELOG | 1 + .../graphics/AbstractImageGenerator.java | 4 +- .../graphics/AbstractImageGeneratorTest.java | 40 +++++++++++++++++-- frontend-js/package-lock.json | 4 +- 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 815cb0ba9..ad83b4e59 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low name was used * Bug fix: plugin tab header wasn't properly resized after adding plugins that introduced second line for tab selection (#758) + * Bug fix: invisible layer shouldn't be shown in the on th map (#813) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AbstractImageGenerator.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AbstractImageGenerator.java index 002935df6..14c9ca968 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AbstractImageGenerator.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AbstractImageGenerator.java @@ -711,7 +711,9 @@ public abstract class AbstractImageGenerator { List bioEntities = new ArrayList<>(); bioEntities.addAll(params.getModel().getBioEntities()); for (Layer layer : params.getModel().getLayers()) { - bioEntities.addAll(layer.getDrawables()); + if (layer.isVisible()) { + bioEntities.addAll(layer.getDrawables()); + } } bioEntities.sort(BioEntity.Z_INDEX_COMPARATOR); diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/AbstractImageGeneratorTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/AbstractImageGeneratorTest.java index 83896981a..977d5ba5d 100644 --- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/AbstractImageGeneratorTest.java +++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/AbstractImageGeneratorTest.java @@ -13,6 +13,8 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import lcsb.mapviewer.model.map.layout.graphics.Layer; +import lcsb.mapviewer.model.map.layout.graphics.LayerRect; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelFullIndexed; import lcsb.mapviewer.model.map.reaction.Reaction; @@ -68,6 +70,33 @@ public class AbstractImageGeneratorTest extends GraphicsTestFunctions { } } + @Test + public void testDrawMapWithInvisibleLayerNesting() throws Exception { + try { + Graphics2D graphics = createGraphicsMock(); + + Model model = createEmptyModel(); + Layer layer = new Layer(); + layer.setVisible(false); + LayerRect rect = new LayerRect(); + rect.setX(10.0); + rect.setX(10.0); + rect.setWidth(20.); + rect.setHeight(20.); + layer.addLayerRect(rect); + model.addLayer(layer); + + AbstractImageGenerator gen = createAbstractImageGeneratorMock(graphics, model); + gen.setParams(new AbstractImageGenerator.Params().model(model).nested(true)); + gen.draw(); + + // 3 times for proteins and 4 times for reaction + verify(graphics, times(0)).draw(any()); + } catch (Exception e) { + throw e; + } + } + @Test public void testDrawSimpleMapWithWhenNestingHidesElement() throws Exception { try { @@ -88,9 +117,7 @@ public class AbstractImageGeneratorTest extends GraphicsTestFunctions { } private Model createSimpleModel() { - Model model = new ModelFullIndexed(null); - model.setWidth(100); - model.setHeight(100); + Model model = createEmptyModel(); GenericProtein protein1 = createProtein(); model.addElement(protein1); @@ -110,6 +137,13 @@ public class AbstractImageGeneratorTest extends GraphicsTestFunctions { return model; } + private Model createEmptyModel() { + Model model = new ModelFullIndexed(null); + model.setWidth(100); + model.setHeight(100); + return model; + } + private AbstractImageGenerator createAbstractImageGeneratorMock(Graphics2D graphics, Model model) throws Exception { AbstractImageGenerator result = Mockito.mock(AbstractImageGenerator.class, Mockito.CALLS_REAL_METHODS); result.setGraphics(graphics); diff --git a/frontend-js/package-lock.json b/frontend-js/package-lock.json index 17af1d3c7..2e2d590df 100644 --- a/frontend-js/package-lock.json +++ b/frontend-js/package-lock.json @@ -87,6 +87,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -3309,7 +3310,8 @@ "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "optional": true }, "loose-envify": { "version": "1.3.1", -- GitLab From 99910708e38f3644fbd40c91678fd1c81361bf25 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 17:39:37 +0200 Subject: [PATCH 10/33] list of available annotators is sorted alphabetically --- CHANGELOG | 1 + .../src/main/js/gui/admin/ChooseAnnotatorsDialog.js | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ad83b4e59..4ade19782 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: plugin tab header wasn't properly resized after adding plugins that introduced second line for tab selection (#758) * Bug fix: invisible layer shouldn't be shown in the on th map (#813) + * Bug fix: list of availbale annotators is sorted alphabetically (#815) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js index 570935cda..9f5d57956 100644 --- a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js +++ b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js @@ -197,6 +197,15 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) { } entries.push(entry); } + entries.sort(function (entryA, entryB) { + if (entryA.name < entryB.name) { + return -1; + } + if (entryA.name > entryB.name) { + return 1; + } + return 0; + }); var checkboxList = new MultiCheckboxList(selectElement, { entries: entries, listTitle: "Available annotators", -- GitLab From 503d2b6706216d1bb5088e17bcef0e120f158a42 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 17:50:46 +0200 Subject: [PATCH 11/33] sort of protein type fixed --- CHANGELOG | 2 + frontend-js/src/main/js/Configuration.js | 11 +++++ frontend-js/src/test/js/Configuration-test.js | 40 +++++++++++++++---- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4ade19782..89c6d061a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low that introduced second line for tab selection (#758) * Bug fix: invisible layer shouldn't be shown in the on th map (#813) * Bug fix: list of availbale annotators is sorted alphabetically (#815) + * Bug fix: protein types are sorted properly in "Select valid annotations" + dialog (#815) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/Configuration.js b/frontend-js/src/main/js/Configuration.js index cb3ffc766..2b9f2ce45 100644 --- a/frontend-js/src/main/js/Configuration.js +++ b/frontend-js/src/main/js/Configuration.js @@ -704,6 +704,16 @@ Configuration.prototype.getElementTypeTree = function () { }; } + var sortFunction = function (entryA, entryB) { + if (entryA.text < entryB.text) { + return -1; + } + if (entryA.text > entryB.text) { + return 1; + } + return 0; + }; + for (var treeNodeName in treeNodes) { if (treeNodes.hasOwnProperty(treeNodeName)) { var treeNode = treeNodes[treeNodeName]; @@ -712,6 +722,7 @@ Configuration.prototype.getElementTypeTree = function () { //prevent compartment subclass specific nodes and reaction subclass specific nodes if (parentNode.data === undefined || (parentNode.data.name !== "Compartment" && parentNode.data.name !== "Generic Reaction")) { parentNode.children.push(treeNode); + parentNode.children.sort(sortFunction); } } } diff --git a/frontend-js/src/test/js/Configuration-test.js b/frontend-js/src/test/js/Configuration-test.js index 2398e8fd3..d847f89f0 100644 --- a/frontend-js/src/test/js/Configuration-test.js +++ b/frontend-js/src/test/js/Configuration-test.js @@ -155,16 +155,40 @@ describe('Configuration', function () { }); }); - it('getElementTypeTree', function () { + describe('getElementTypeTree', function () { + it('default', function () { - return ServerConnector.getConfiguration().then(function (configuration) { - var treeData = configuration.getElementTypeTree(); + return ServerConnector.getConfiguration().then(function (configuration) { + var treeData = configuration.getElementTypeTree(); - assert.ok(treeData); - assert.ok(treeData.text); - assert.ok(treeData.children); - assert.equal(2, treeData.children.length); - }) + assert.ok(treeData); + assert.ok(treeData.text); + assert.ok(treeData.children); + assert.equal(2, treeData.children.length); + }) + }); + it('check sorting', function () { + /** + * + * @param {BioEntityTypeTreeNode[]} children + */ + function checkChildrenSorted(children) { + var i; + for (i = 1; i < children.length; i++) { + assert.ok(children[i - 1].text < children[i].text, "children are not sorted: " + children[i - 1].text + " ; " + children[i].text); + } + for (i = 0; i < children.length; i++) { + if (children[i].children != null) { + checkChildrenSorted(children[i].children); + } + } + } + + return ServerConnector.getConfiguration().then(function (configuration) { + var treeData = configuration.getElementTypeTree(); + checkChildrenSorted(treeData.children); + }) + }); }); -- GitLab From 43f3322089f1dcc1f7d35f20c7dd742a515c7fc1 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 18:37:09 +0200 Subject: [PATCH 12/33] proper status code is returned when trying to update configuration option with invalid data --- .../ConfigurationController.java | 2 +- .../configuration/AllConfigurationTests.java | 4 +- .../ConfigurationControllerTest.java | 56 +++++++++++++++++++ .../services/impl/ConfigurationService.java | 1 + 4 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 rest-api/src/test/java/lcsb/mapviewer/api/configuration/ConfigurationControllerTest.java diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java index e9a8bf9d2..949e03b59 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationController.java @@ -73,7 +73,7 @@ public class ConfigurationController extends BaseController { @RequestMapping(value = "/configuration/options/{option}", method = { RequestMethod.PATCH }, produces = { MediaType.APPLICATION_JSON_VALUE }) - public Map getOption( + public Map updateOption( @RequestBody String body, @CookieValue(value = Configuration.AUTH_TOKEN) String token, @PathVariable(value = "option") String option diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/configuration/AllConfigurationTests.java b/rest-api/src/test/java/lcsb/mapviewer/api/configuration/AllConfigurationTests.java index 14956fb65..1a95c6013 100644 --- a/rest-api/src/test/java/lcsb/mapviewer/api/configuration/AllConfigurationTests.java +++ b/rest-api/src/test/java/lcsb/mapviewer/api/configuration/AllConfigurationTests.java @@ -5,7 +5,9 @@ import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) -@SuiteClasses({ ConfigurationRestImplTest.class }) +@SuiteClasses({ + ConfigurationControllerTest.class, + ConfigurationRestImplTest.class }) public class AllConfigurationTests { } diff --git a/rest-api/src/test/java/lcsb/mapviewer/api/configuration/ConfigurationControllerTest.java b/rest-api/src/test/java/lcsb/mapviewer/api/configuration/ConfigurationControllerTest.java new file mode 100644 index 000000000..40eee3082 --- /dev/null +++ b/rest-api/src/test/java/lcsb/mapviewer/api/configuration/ConfigurationControllerTest.java @@ -0,0 +1,56 @@ +package lcsb.mapviewer.api.configuration; + +import static org.junit.Assert.fail; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +import com.google.gson.Gson; + +import lcsb.mapviewer.api.QueryException; +import lcsb.mapviewer.api.SpringRestApiTestConfig; +import lcsb.mapviewer.model.user.ConfigurationElementType; +import lcsb.mapviewer.services.interfaces.IUserService; + +@ContextConfiguration(classes = SpringRestApiTestConfig.class) +@WebAppConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +public class ConfigurationControllerTest { + + @Autowired + ConfigurationController configurationController; + + @Autowired + IUserService userService; + + @Test + public void testSetSmtpPortToInvalid() throws Exception { + try { + // assume that we have admin account with all the privileges + String adminToken = userService.login("admin", "admin"); + + Map option= new HashMap<>(); + option.put("value", "not a number"); + option.put("type", "not a number"); + Map data= new HashMap<>(); + data.put("option", option); + + String body = new Gson().toJson(data); + configurationController.updateOption(body, adminToken, ConfigurationElementType.MAX_NUMBER_OF_MAP_LEVELS.name()); + fail("Exception expected"); + } catch (QueryException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + +} diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ConfigurationService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ConfigurationService.java index 14141d92d..336ddc20c 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/ConfigurationService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/ConfigurationService.java @@ -65,6 +65,7 @@ public class ConfigurationService implements IConfigurationService { } @Override + @Transactional(noRollbackFor = InvalidArgumentException.class) public void setConfigurationValue(ConfigurationElementType type, String value) { if (value == null) { throw new InvalidArgumentException("null is not a proper value"); -- GitLab From 36a0947902e5682e60edc9b7d0c9b2a1fa630dc1 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 19:02:17 +0200 Subject: [PATCH 13/33] error reported to the frontend is more readable --- .../main/js/gui/admin/ConfigurationAdminPanel.js | 15 ++++++++++++++- .../java/lcsb/mapviewer/api/BaseController.java | 12 ++++++++---- .../api/configuration/ConfigurationRestImpl.java | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js b/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js index c2357d11f..7c7fe4c9c 100644 --- a/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js +++ b/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js @@ -6,9 +6,11 @@ var ConfigurationType = require('../../ConfigurationType'); var Functions = require('../../Functions'); var GuiConnector = require('../../GuiConnector'); +var NetworkError = require('../../NetworkError'); var ValidationError = require('../../ValidationError'); var logger = require('../../logger'); +var HttpStatus = require('http-status-codes'); var Promise = require("bluebird"); var xss = require("xss"); @@ -253,9 +255,11 @@ ConfigurationAdminPanel.prototype.saveOption = function (type) { value = element.val(); } + var oldVal; GuiConnector.showProcessing(); return self.getServerConnector().getConfiguration().then(function (configuration) { option = configuration.getOption(type); + oldVal = option.getValue(); if (option === undefined) { return Promise.reject(new ValidationError("Unknown configuration type: " + type)); } @@ -317,7 +321,16 @@ ConfigurationAdminPanel.prototype.saveOption = function (type) { } }); } - }).catch(GuiConnector.alert).finally(GuiConnector.hideProcessing); + }).catch(function (e) { + if (e instanceof NetworkError && e.statusCode === HttpStatus.BAD_REQUEST) { + var content = e.content; + GuiConnector.alert(new ValidationError(content.reason)); + option.setValue(oldVal); + element.val(oldVal); + } else { + GuiConnector.alert(e); + } + }).finally(GuiConnector.hideProcessing); }; /** diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java index 7bc7a6182..68c9d1300 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java @@ -3,8 +3,9 @@ package lcsb.mapviewer.api; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.util.TreeMap; +import java.util.HashMap; import java.util.Map; +import java.util.TreeMap; import org.apache.log4j.Logger; import org.springframework.http.HttpHeaders; @@ -37,7 +38,8 @@ public abstract class BaseController { } else if (e instanceof ObjectExistsException) { return createErrorResponse("Object already exists.", e.getMessage(), new HttpHeaders(), HttpStatus.CONFLICT); } else if (e instanceof OperationNotAllowedException) { - return createErrorResponse("Operation not allowed.", e.getMessage(), new HttpHeaders(), HttpStatus.METHOD_NOT_ALLOWED); + return createErrorResponse("Operation not allowed.", e.getMessage(), new HttpHeaders(), + HttpStatus.METHOD_NOT_ALLOWED); } else if (e instanceof QueryException) { logger.error(e, e); return createErrorResponse("Query server error.", e.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST); @@ -53,8 +55,10 @@ public abstract class BaseController { private ResponseEntity createErrorResponse(String errorMessage, String error, HttpHeaders httpHeaders, HttpStatus status) { - return new ResponseEntity( - "{\"error\" : \"" + errorMessage + "\",\"reason\":" + new Gson().toJson(error) + "}", httpHeaders, status); + Map response = new HashMap<>(); + response.put("error", errorMessage); + response.put("reason", error); + return new ResponseEntity(new Gson().toJson(response), httpHeaders, status); } public Map parseBody(String body) throws IOException, JsonParseException, JsonMappingException { diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java index 326e14652..e956cad4a 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java @@ -293,7 +293,7 @@ public class ConfigurationRestImpl extends BaseRestImpl { try { configurationService.setConfigurationValue(type, value); } catch (InvalidArgumentException e) { - throw new QueryException(e); + throw new QueryException(e.getMessage(), e); } return optionToMap(configurationService.getValue(type)); } -- GitLab From 2180ef48387169df1735b5808d63d1160c699436 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 19:12:56 +0200 Subject: [PATCH 14/33] frontend test fixed (some asynchronous calls weren't waited for) --- frontend-js/src/test/js/gui/admin/EditUserDialog-test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js b/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js index 5a407a11b..47919a1c8 100644 --- a/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js +++ b/frontend-js/src/test/js/gui/admin/EditUserDialog-test.js @@ -148,8 +148,9 @@ describe('EditUserDialog', function () { dialog = createEditUserDialog(project, user); return dialog.init(); }).then(function () { - $("[name=privilege-int]", dialog.getElement()).val("101010"); - $("[name=privilege-int]", dialog.getElement()).trigger("change"); + var element = $("[name=privilege-int]", dialog.getElement())[0]; + $(element).val("101010"); + return helper.triggerJqueryEvent(element, "change"); }).then(function () { expect(serializedPrivileges).not.to.deep.equal(user.privilegesToExport(helper.getConfiguration())); dialog.destroy(); -- GitLab From dd0ccb13c36044d24c2afe3d25b9edaea94bb71c Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 19:50:56 +0200 Subject: [PATCH 15/33] submap description is available --- CHANGELOG | 2 ++ .../main/js/gui/leftPanel/ProjectInfoPanel.js | 16 +++++++++++++++ .../src/main/js/gui/leftPanel/SubmapPanel.js | 13 +++++++++++- frontend-js/src/main/js/map/data/MapModel.js | 20 +++++++++++++++++++ .../api/projects/models/ModelRestImpl.java | 1 + 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 89c6d061a..5c753265b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: list of availbale annotators is sorted alphabetically (#815) * Bug fix: protein types are sorted properly in "Select valid annotations" dialog (#815) + * Bug fix: if there is a description of (sub)map then it is available in + info/submap panel (#824) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js index 4c61b833f..0ed1dc7a4 100644 --- a/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/ProjectInfoPanel.js @@ -235,6 +235,22 @@ ProjectInfoPanel.prototype._createInfoPanelGui = function () { authorsTab.appendChild(guiUtils.createAuthorsList(self.getProject().getModels()[0].getAuthors())); } + if (self.getProject().getModels()[0].getDescription() !== null && self.getProject().getModels()[0].getDescription() !== "") { + var descriptionTab = Functions.createElement({ + type: "div" + }); + infoDiv.appendChild(descriptionTab); + + descriptionTab.appendChild(Functions.createElement({ + type: "h4", + content: 'Description:' + })); + descriptionTab.appendChild(Functions.createElement({ + type: "p", + content: self.getProject().getModels()[0].getDescription() + })); + } + }; diff --git a/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js b/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js index 150c09f77..dfe1ea7c4 100644 --- a/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js +++ b/frontend-js/src/main/js/gui/leftPanel/SubmapPanel.js @@ -64,7 +64,8 @@ SubmapPanel.prototype.createRow = function (model) { var nameTd = Functions.createElement({type: "td", content: model.getName(), style: "position:relative"}); - if (model.getReferences().length > 0 || model.getAuthors().length > 0) { + if (model.getReferences().length > 0 || model.getAuthors().length > 0 || + (model.getDescription() !== null && model.getDescription() !== "")) { var referencesTab = Functions.createElement({ type: "div", className: "minerva-search-data-hidden" @@ -88,6 +89,16 @@ SubmapPanel.prototype.createRow = function (model) { referencesTab.appendChild(authors); referencesTab.appendChild(guiUtils.createAuthorsList(model.getAuthors())); } + if (model.getDescription() !== null && model.getDescription() !== "") { + referencesTab.appendChild(Functions.createElement({ + type: "div", + content: 'Description:' + })); + referencesTab.appendChild(Functions.createElement({ + type: "p", + content: model.getDescription() + })); + } var expandButton = Functions.createElement({ type: "button", diff --git a/frontend-js/src/main/js/map/data/MapModel.js b/frontend-js/src/main/js/map/data/MapModel.js index 0149eed1f..ed7ff8b9c 100644 --- a/frontend-js/src/main/js/map/data/MapModel.js +++ b/frontend-js/src/main/js/map/data/MapModel.js @@ -23,6 +23,7 @@ var Reaction = require('./Reaction'); * @typedef {Object} MapModelOptions * @property {number} idObject * @property {string} name + * @property {string} description * @property {number} tileSize * @property {number} width * @property {number} height @@ -90,6 +91,7 @@ function MapModel(configuration) { this.setAuthors(configuration.getAuthors()); this.setModificationDates(configuration.getModificationDates()); this.setCreationDate(configuration.getCreationDate()); + this.setDescription(configuration.getDescription()); } else { this.setId(configuration.idObject); this.setName(configuration.name); @@ -106,6 +108,7 @@ function MapModel(configuration) { this.setAuthors(configuration.authors); this.setModificationDates(configuration.modificationDates); this.setCreationDate(configuration.creationDate); + this.setDescription(configuration.description); } } } @@ -980,4 +983,21 @@ MapModel.prototype.setCreationDate = function (creationDate) { this._creationDate = creationDate; }; +/** + * + * @returns {string|null} + */ +MapModel.prototype.getDescription = function () { + return this._description; +}; + +/** + * + * @param {string} description + */ +MapModel.prototype.setDescription = function (description) { + this._description = description; +}; + + module.exports = MapModel; diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java index 133f407c2..17926f381 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/projects/models/ModelRestImpl.java @@ -116,6 +116,7 @@ public class ModelRestImpl extends BaseRestImpl { result.put("authors", submodel.getAuthors()); result.put("creationDate", super.prepareDate(submodel.getCreationDate())); result.put("modificationDates", super.prepareDates(submodel.getModificationDates())); + result.put("description", submodel.getNotes()); return result; } } -- GitLab From eca47d9fc3be441e6f7cd03e252cbb4dfc274dbe Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Wed, 5 Jun 2019 20:01:44 +0200 Subject: [PATCH 16/33] logger formatting changed --- frontend-js/src/test/js/logger.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend-js/src/test/js/logger.js b/frontend-js/src/test/js/logger.js index bc36fa1aa..8bf92b10d 100644 --- a/frontend-js/src/test/js/logger.js +++ b/frontend-js/src/test/js/logger.js @@ -41,7 +41,7 @@ logger.getErrors = function () { var buffer = inMemoryAppender.buffer.default; for (var i = 0; i < buffer.length; i++) { var message = buffer[i]; - if (message.indexOf("'ERROR'") !== -1) { + if (message.indexOf("ERROR") !== -1) { result.push(message); } } @@ -52,7 +52,7 @@ logger.getWarnings = function () { var buffer = inMemoryAppender.buffer.default; for (var i = 0; i < buffer.length; i++) { var message = buffer[i]; - if (message.indexOf("'WARN'") !== -1) { + if (message.indexOf("WARN") !== -1) { result.push(message); } } -- GitLab From 5ecea463b6d27bf14ea91de2352422ebd5815d61 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 18:49:31 +0200 Subject: [PATCH 17/33] there was a need to close edit-project dialog twice --- CHANGELOG | 2 ++ frontend-js/src/main/js/gui/admin/EditProjectDialog.js | 4 ++++ frontend-js/src/main/js/gui/admin/EditUserDialog.js | 4 ++++ 3 files changed, 10 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 89c6d061a..6968ebb99 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: list of availbale annotators is sorted alphabetically (#815) * Bug fix: protein types are sorted properly in "Select valid annotations" dialog (#815) + * Bug fix: when changing data in edit user dialog there was a need to click + close button twice (#818) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js index 12d1f3bfa..8826c677c 100644 --- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js @@ -1018,6 +1018,10 @@ EditProjectDialog.prototype.open = function () { width: window.innerWidth * 0.75, height: window.innerHeight / 2 }); + $(".ui-dialog-titlebar-close", $(div).dialog().siblings('.ui-dialog-titlebar')).on("mousedown", function () { + //we need to close dialog on mouse down, because processing modal dialogs prevents the click to finish happening + $(div).dialog("close"); + }); } $(div).dialog("open"); }; diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js index 81f3b8b4c..beec0a2cc 100644 --- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js @@ -625,6 +625,10 @@ EditUserDialog.prototype.open = function () { width: window.innerWidth / 2, height: window.innerHeight / 2 }); + $(".ui-dialog-titlebar-close", $(div).dialog().siblings('.ui-dialog-titlebar')).on("mousedown", function () { + //we need to close dialog on mouse down, because processing modal dialogs prevents the click to finish happening + $(div).dialog("close"); + }); } $(div).dialog("open"); }; -- GitLab From 80b9bd0affebcf93a384af0f7650cfd90a9fe4b4 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 18:49:31 +0200 Subject: [PATCH 18/33] there was a need to close edit-project dialog twice --- CHANGELOG | 4 +++- frontend-js/src/main/js/gui/admin/EditProjectDialog.js | 4 ++++ frontend-js/src/main/js/gui/admin/EditUserDialog.js | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 5c753265b..c95232feb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,8 +7,10 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: list of availbale annotators is sorted alphabetically (#815) * Bug fix: protein types are sorted properly in "Select valid annotations" dialog (#815) - * Bug fix: if there is a description of (sub)map then it is available in + * Bug fix: if there is a description of (sub)map then it is available in info/submap panel (#824) + * Bug fix: when changing data in edit user dialog there was a need to click + close button twice (#818) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js index 12d1f3bfa..8826c677c 100644 --- a/frontend-js/src/main/js/gui/admin/EditProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditProjectDialog.js @@ -1018,6 +1018,10 @@ EditProjectDialog.prototype.open = function () { width: window.innerWidth * 0.75, height: window.innerHeight / 2 }); + $(".ui-dialog-titlebar-close", $(div).dialog().siblings('.ui-dialog-titlebar')).on("mousedown", function () { + //we need to close dialog on mouse down, because processing modal dialogs prevents the click to finish happening + $(div).dialog("close"); + }); } $(div).dialog("open"); }; diff --git a/frontend-js/src/main/js/gui/admin/EditUserDialog.js b/frontend-js/src/main/js/gui/admin/EditUserDialog.js index 81f3b8b4c..beec0a2cc 100644 --- a/frontend-js/src/main/js/gui/admin/EditUserDialog.js +++ b/frontend-js/src/main/js/gui/admin/EditUserDialog.js @@ -625,6 +625,10 @@ EditUserDialog.prototype.open = function () { width: window.innerWidth / 2, height: window.innerHeight / 2 }); + $(".ui-dialog-titlebar-close", $(div).dialog().siblings('.ui-dialog-titlebar')).on("mousedown", function () { + //we need to close dialog on mouse down, because processing modal dialogs prevents the click to finish happening + $(div).dialog("close"); + }); } $(div).dialog("open"); }; -- GitLab From c9ddb4112a0948b237bc73433cad9ded6534e231 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 19:01:32 +0200 Subject: [PATCH 19/33] redirect url from export panel fixed --- CHANGELOG | 1 + frontend-js/src/main/js/gui/Header.js | 2 +- frontend-js/src/main/js/minerva.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6968ebb99..9b047981e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low that introduced second line for tab selection (#758) * Bug fix: invisible layer shouldn't be shown in the on th map (#813) * Bug fix: list of availbale annotators is sorted alphabetically (#815) + * Bug fix: redirect url from export panel is fixed (#819) * Bug fix: protein types are sorted properly in "Select valid annotations" dialog (#815) * Bug fix: when changing data in edit user dialog there was a need to click diff --git a/frontend-js/src/main/js/gui/Header.js b/frontend-js/src/main/js/gui/Header.js index 531b2c3ff..6597b8364 100644 --- a/frontend-js/src/main/js/gui/Header.js +++ b/frontend-js/src/main/js/gui/Header.js @@ -111,7 +111,7 @@ Header.prototype._createHeaderGui = function (guiParams) { content: ' ' + projectName, xss: false }); - homeLink.href = self.getServerConnector().getServerBaseUrl() + "?id=" + projectId; + homeLink.href = self.getServerConnector().getServerBaseUrl() + "index.xhtml?id=" + projectId; self.getElement().appendChild(homeLink); }; diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js index aa67ae902..036f1f1eb 100644 --- a/frontend-js/src/main/js/minerva.js +++ b/frontend-js/src/main/js/minerva.js @@ -772,7 +772,7 @@ function createLoginDiv(configuration) { }); $('#go_to_map_button', result).click(function () { return ServerConnector.getProjectId().then(function (projectId) { - window.location.href = ServerConnector.getServerBaseUrl() + '?id=' + projectId; + window.location.href = ServerConnector.getServerBaseUrl() + 'index.xhtml?id=' + projectId; }); }); $('#register_button', result).click(function () { -- GitLab From dcfc788dd8788be011bf0a8a54e6e78f26fe7b21 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 19:24:07 +0200 Subject: [PATCH 20/33] when empty or null color is provided throw proper exception --- .../lcsb/mapviewer/common/geometry/ColorParser.java | 4 ++++ .../mapviewer/common/geometry/ColorParserTest.java | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java b/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java index 2af7761b6..d9bc3ab0b 100644 --- a/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java +++ b/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java @@ -47,6 +47,10 @@ public class ColorParser { * @return {@link Color} obtained from input text */ public Color parse(String string) { + if (string==null || string.isEmpty()) { + throw new InvalidArgumentException( + "Invalid color value: " + string + ". Correct format: #xxxxxx (where x is a hex value)"); + } if (string.charAt(0) != '#') { string = "#" + string; } diff --git a/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java b/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java index 710cfa151..4b927108f 100644 --- a/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java +++ b/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java @@ -64,6 +64,18 @@ public class ColorParserTest { } } + @Test(expected=InvalidArgumentException.class) + public void testParseNull() throws Exception { + ColorParser parser = new ColorParser(); + parser.parse(null); + } + + @Test(expected=InvalidArgumentException.class) + public void testParseEmpty() throws Exception { + ColorParser parser = new ColorParser(); + parser.parse(""); + } + @Test public void testSetColorToHtmlString() throws Exception { try { -- GitLab From 2050ea80f49bfb8690780c7f94f75cd75855e736 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 19:31:37 +0200 Subject: [PATCH 21/33] proper exception is thrown when color is invalid --- .../services/utils/ColorSchemaReader.java | 12 ++++++++++-- .../services/utils/ColorSchemaReaderTest.java | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index b2085821e..87b27aa82 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -229,7 +229,11 @@ public class ColorSchemaReader { } } if (colorColumn != null) { - schema.setColor(colorParser.parse(values[colorColumn])); + try { + schema.setColor(colorParser.parse(values[colorColumn])); + } catch (InvalidArgumentException e) { + throw new InvalidColorSchemaException(errorPrefix + e.getMessage(), e); + } } if (identifierColumn != null && !values[identifierColumn].equals("")) { processGeneralIdentifier(values[identifierColumn], schema, errorPrefix); @@ -535,7 +539,11 @@ public class ColorSchemaReader { schema.setValue(parseValueColumn(values[valueColumn], errorPrefix)); } if (colorColumn != null && !values[colorColumn].isEmpty()) { - schema.setColor(colorParser.parse(values[colorColumn])); + try { + schema.setColor(colorParser.parse(values[colorColumn])); + } catch (InvalidArgumentException e) { + throw new InvalidColorSchemaException(errorPrefix + e.getMessage(), e); + } } if (schema.getValue() != null && schema.getColor() != null) { throw new InvalidColorSchemaException(errorPrefix + "Either color or value can be defined but found both"); diff --git a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java index 8f38ead28..20d037fa2 100644 --- a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java @@ -378,6 +378,23 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { } } + @Test + public void testColoringWithEmptyColor() throws Exception { + try { + ColorSchemaReader reader = new ColorSchemaReader(); + Map params = new HashMap<>(); + params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); + + String input = "name\tcolor\ns1\tx"; + reader.readColorSchema(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)), params); + fail("Exception expected"); + } catch (InvalidColorSchemaException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + @Test public void testColoringWithInvalidValueAndColor2() throws Exception { try { -- GitLab From a43d12fa4a2c1af1fd633c50ff2e3a87c69ec15d Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 19:32:56 +0200 Subject: [PATCH 22/33] changelog updated --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 8c261f3e0..90f4e9746 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,6 @@ minerva (12.3.1~beta.1) unstable; urgency=low + * Bug fix: invalid color in data overlay provides proper feedback to the user + (#822) * Bug fix: tair locus identifiers were used improperly - instead of id the name was used * Bug fix: plugin tab header wasn't properly resized after adding plugins -- GitLab From 5d252147ecc48dd4d80dcd4630c3409ad8bc3bb5 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 20:03:50 +0200 Subject: [PATCH 23/33] genetic variant overlay without name caused problems --- CHANGELOG | 1 + .../services/utils/ColorSchemaReader.java | 2 +- .../services/utils/ColorSchemaReaderTest.java | 97 ++++++++----------- .../testFiles/coloring/gene_variants_id.txt | 5 + 4 files changed, 48 insertions(+), 57 deletions(-) create mode 100644 service/testFiles/coloring/gene_variants_id.txt diff --git a/CHANGELOG b/CHANGELOG index 90f4e9746..71510373a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: invalid color in data overlay provides proper feedback to the user (#822) + * Bug fix: genetic variant overlay without name caused problems (#832) * Bug fix: tair locus identifiers were used improperly - instead of id the name was used * Bug fix: plugin tab header wasn't properly resized after adding plugins diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index 87b27aa82..93f051717 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -292,7 +292,7 @@ public class ColorSchemaReader { gv.setContig(values[contigColumn]); schema.addGeneVariation(gv); - if (schema.getName().contains(";")) { + if (schema.getName()!=null && schema.getName().contains(";")) { String[] names = schema.getName().split(";"); for (String string : names) { if (!string.trim().isEmpty()) { diff --git a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java index 20d037fa2..119fb2531 100644 --- a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java @@ -11,6 +11,8 @@ import java.awt.Color; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Collection; @@ -75,21 +77,27 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { public void testReadGeneVariantsSchema() throws Exception { try { File f = new File("testFiles/coloring/gene_variants.txt"); - InputStream in = new FileInputStream(f); + byte[] data = fileToByteArray(f); - byte[] buff = new byte[8000]; - - int bytesRead = 0; + ByteArrayInputStream bin = new ByteArrayInputStream(data); - ByteArrayOutputStream bao = new ByteArrayOutputStream(); + ColorSchemaReader reader = new ColorSchemaReader(); - while ((bytesRead = in.read(buff)) != -1) { - bao.write(buff, 0, bytesRead); - } - in.close(); - bao.close(); + Collection schemas = reader.readColorSchema(bin, + TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); + assertNotNull(schemas); + assertEquals(3, schemas.size()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } - byte[] data = bao.toByteArray(); + @Test + public void testReadGeneVariantByIdSchema() throws Exception { + try { + File f = new File("testFiles/coloring/gene_variants_id.txt"); + byte[] data = fileToByteArray(f); ByteArrayInputStream bin = new ByteArrayInputStream(data); @@ -98,32 +106,37 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { Collection schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); - assertEquals(3, schemas.size()); + assertEquals(1, schemas.size()); } catch (Exception e) { e.printStackTrace(); throw e; } } - @Test - public void testReadGeneVariantsWithAminoAcidChange() throws Exception { - try { - File f = new File("testFiles/coloring/gene_variants_aa_change.txt"); - InputStream in = new FileInputStream(f); + private byte[] fileToByteArray(File f) throws FileNotFoundException, IOException { + InputStream in = new FileInputStream(f); - byte[] buff = new byte[8000]; + byte[] buff = new byte[8000]; - int bytesRead = 0; + int bytesRead = 0; - ByteArrayOutputStream bao = new ByteArrayOutputStream(); + ByteArrayOutputStream bao = new ByteArrayOutputStream(); - while ((bytesRead = in.read(buff)) != -1) { - bao.write(buff, 0, bytesRead); - } - in.close(); - bao.close(); + while ((bytesRead = in.read(buff)) != -1) { + bao.write(buff, 0, bytesRead); + } + in.close(); + bao.close(); - byte[] data = bao.toByteArray(); + byte[] data = bao.toByteArray(); + return data; + } + + @Test + public void testReadGeneVariantsWithAminoAcidChange() throws Exception { + try { + File f = new File("testFiles/coloring/gene_variants_aa_change.txt"); + byte[] data = fileToByteArray(f); ByteArrayInputStream bin = new ByteArrayInputStream(data); @@ -151,21 +164,7 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { public void testReadGeneVariantsWithNewNamingSchema() throws Exception { try { File f = new File("testFiles/coloring/gene_variants_new_naming.txt"); - InputStream in = new FileInputStream(f); - - byte[] buff = new byte[8000]; - - int bytesRead = 0; - - ByteArrayOutputStream bao = new ByteArrayOutputStream(); - - while ((bytesRead = in.read(buff)) != -1) { - bao.write(buff, 0, bytesRead); - } - in.close(); - bao.close(); - - byte[] data = bao.toByteArray(); + byte[] data = fileToByteArray(f); ByteArrayInputStream bin = new ByteArrayInputStream(data); @@ -185,21 +184,7 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { public void testReadGeneVariantsSchemaWithAF() throws Exception { try { File f = new File("testFiles/coloring/gene_variants_all_freq.txt"); - InputStream in = new FileInputStream(f); - - byte[] buff = new byte[8000]; - - int bytesRead = 0; - - ByteArrayOutputStream bao = new ByteArrayOutputStream(); - - while ((bytesRead = in.read(buff)) != -1) { - bao.write(buff, 0, bytesRead); - } - in.close(); - bao.close(); - - byte[] data = bao.toByteArray(); + byte[] data = fileToByteArray(f); ByteArrayInputStream bin = new ByteArrayInputStream(data); diff --git a/service/testFiles/coloring/gene_variants_id.txt b/service/testFiles/coloring/gene_variants_id.txt new file mode 100644 index 000000000..d2ee60249 --- /dev/null +++ b/service/testFiles/coloring/gene_variants_id.txt @@ -0,0 +1,5 @@ +#TYPE=GENETIC_VARIANT +#GENOME_TYPE=UCSC +#GENOME_VERSION=hg38 +position original_dna alternative_dna Entrez gene description color contig +10146 AC A 123456 upstream #ff0000 chr1 -- GitLab From 2f7a2aaca4a8de8f8be242dba13972e1f20ae598 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 20:52:39 +0200 Subject: [PATCH 24/33] allow to reupload data overlay file without closing dialog --- CHANGELOG | 2 ++ frontend-js/src/main/js/gui/AddOverlayDialog.js | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 71510373a..3c08eb6f1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: invisible layer shouldn't be shown in the on th map (#813) * Bug fix: list of availbale annotators is sorted alphabetically (#815) * Bug fix: redirect url from export panel is fixed (#819) + * Bug fix: allow to reupload the same file without closing add overlay dialog + (#833) * Bug fix: protein types are sorted properly in "Select valid annotations" dialog (#815) * Bug fix: if there is a description of (sub)map then it is available in diff --git a/frontend-js/src/main/js/gui/AddOverlayDialog.js b/frontend-js/src/main/js/gui/AddOverlayDialog.js index 5fff0a74a..f860127de 100644 --- a/frontend-js/src/main/js/gui/AddOverlayDialog.js +++ b/frontend-js/src/main/js/gui/AddOverlayDialog.js @@ -94,7 +94,9 @@ AddOverlayDialog.prototype.createGui = function () { name: "overlay-file" }); fileInput.addEventListener("change", function () { - return self.processFile(fileInput.files[0]).then(null, GuiConnector.alert); + return self.processFile(fileInput.files[0]).then(function () { + $(fileInput).val(""); + }).catch(GuiConnector.alert); }, false); content.appendChild(fileInput); content.appendChild(guiUtils.createNewLine()); -- GitLab From 1fcaaaef050d01ccfa8af6476fffb7dc7aa5e301 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Thu, 6 Jun 2019 21:06:14 +0200 Subject: [PATCH 25/33] gene name column is allowed only in genetic variant data overlay --- CHANGELOG | 2 ++ .../lcsb/mapviewer/services/utils/ColorSchemaReader.java | 5 ++++- .../mapviewer/services/utils/data/ColorSchemaColumn.java | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 3c08eb6f1..34e4b4e66 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: redirect url from export panel is fixed (#819) * Bug fix: allow to reupload the same file without closing add overlay dialog (#833) + * Bug fix: gene_name column is allowed only in the genetic variant data + overlay * Bug fix: protein types are sorted properly in "Select valid annotations" dialog (#815) * Bug fix: if there is a description of (sub)map then it is available in diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index 93f051717..3b2eb71dc 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -162,6 +162,9 @@ public class ColorSchemaReader { Integer nameColumn = schemaColumns.get(ColorSchemaColumn.NAME); if (nameColumn == null) { nameColumn = schemaColumns.get(ColorSchemaColumn.GENE_NAME); + } else if (schemaColumns.get(ColorSchemaColumn.GENE_NAME) != null) { + throw new InvalidColorSchemaException(ColorSchemaColumn.GENE_NAME + " and " + ColorSchemaColumn.NAME + + " column cannot appear in the same dataset"); } Integer modelNameColumn = schemaColumns.get(ColorSchemaColumn.MODEL_NAME); Integer identifierColumn = schemaColumns.get(ColorSchemaColumn.IDENTIFIER); @@ -292,7 +295,7 @@ public class ColorSchemaReader { gv.setContig(values[contigColumn]); schema.addGeneVariation(gv); - if (schema.getName()!=null && schema.getName().contains(";")) { + if (schema.getName() != null && schema.getName().contains(";")) { String[] names = schema.getName().split(";"); for (String string : names) { if (!string.trim().isEmpty()) { diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java b/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java index 8fd9276df..5cbcc2e70 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java @@ -21,7 +21,7 @@ public enum ColorSchemaColumn { */ NAME(new ColorSchemaType[] { ColorSchemaType.GENERIC, ColorSchemaType.GENETIC_VARIANT }), - GENE_NAME(new ColorSchemaType[] { ColorSchemaType.GENERIC, ColorSchemaType.GENETIC_VARIANT }), + GENE_NAME(new ColorSchemaType[] { ColorSchemaType.GENETIC_VARIANT }), /** * Name of the element. -- GitLab From b7067b12d72af52e771d35b483b2077fbc9df871 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 13:52:00 +0200 Subject: [PATCH 26/33] allow empty type for data overlay --- CHANGELOG | 1 + .../services/utils/ColorSchemaReader.java | 22 ++++---- .../services/utils/ColorSchemaReaderTest.java | 50 ++++++------------- 3 files changed, 27 insertions(+), 46 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 34e4b4e66..bd089b970 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low info/submap panel (#824) * Bug fix: when changing data in edit user dialog there was a need to click close button twice (#818) + * Bug fix: empty type for data overlay is allowed (#827) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index 3b2eb71dc..40a7e3168 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -591,21 +591,23 @@ public class ColorSchemaReader { return result; } - private List> parseSpeciesTypes(String typesString, String errorPrefix) + List> parseSpeciesTypes(String typesString, String errorPrefix) throws InvalidColorSchemaException { List> result = new ArrayList<>(); String[] types = typesString.split(","); for (String string : types) { - SpeciesMapping mapping = SpeciesMapping.getMappingByString(string); - if (mapping != null) { - result.add(mapping.getModelClazz()); - } else { - String validStrings = ""; - for (SpeciesMapping speciesMapping : SpeciesMapping.values()) { - validStrings += speciesMapping.getCellDesignerString() + ", "; + if (!string.isEmpty()) { + SpeciesMapping mapping = SpeciesMapping.getMappingByString(string); + if (mapping != null) { + result.add(mapping.getModelClazz()); + } else { + String validStrings = ""; + for (SpeciesMapping speciesMapping : SpeciesMapping.values()) { + validStrings += speciesMapping.getCellDesignerString() + ", "; + } + throw new InvalidColorSchemaException( + errorPrefix + "Unknown class type: " + string + ". Valid values are: " + validStrings); } - throw new InvalidColorSchemaException( - errorPrefix + "Unknown class type: " + string + ". Valid values are: " + validStrings); } } return result; diff --git a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java index 119fb2531..2f02c8685 100644 --- a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java @@ -17,6 +17,7 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -28,19 +29,24 @@ import org.junit.Test; import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorModelCommand; import lcsb.mapviewer.common.TextFileUtils; +import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.MiriamData; import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.layout.GeneVariation; import lcsb.mapviewer.model.map.layout.GeneVariationColorSchema; import lcsb.mapviewer.model.map.layout.InvalidColorSchemaException; import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.services.ServiceTestFunctions; public class ColorSchemaReaderTest extends ServiceTestFunctions { Logger logger = Logger.getLogger(ColorSchemaReaderTest.class); + ColorSchemaReader reader; + @Before public void setUp() throws Exception { + reader = new ColorSchemaReader(); } @After @@ -50,8 +56,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testReadSchema() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema("testFiles/enricoData/ageing.txt"); assertNotNull(schemas); @@ -81,8 +85,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { ByteArrayInputStream bin = new ByteArrayInputStream(data); - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); @@ -101,8 +103,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { ByteArrayInputStream bin = new ByteArrayInputStream(data); - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); @@ -140,8 +140,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { ByteArrayInputStream bin = new ByteArrayInputStream(data); - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); @@ -168,8 +166,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { ByteArrayInputStream bin = new ByteArrayInputStream(data); - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); @@ -188,8 +184,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { ByteArrayInputStream bin = new ByteArrayInputStream(data); - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); @@ -203,8 +197,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testReadInvalidGeneVariantsSchema() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - reader.readColorSchema("testFiles/coloring/gene_variants_invalid_genome.txt"); fail("Exception expected"); } catch (InvalidColorSchemaException e) { @@ -217,8 +209,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testReadSchema2() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema("testFiles/coloring/goodSchema.txt"); assertNotNull(schemas); @@ -234,7 +224,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { public void testReadSchema3() throws Exception { try { try { - ColorSchemaReader reader = new ColorSchemaReader(); reader.readColorSchema("testFiles/coloring/wrongSchema.txt"); fail("Excepion expected"); } catch (InvalidColorSchemaException e) { @@ -248,7 +237,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testProblematicStephanSchema3() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); reader.readColorSchema("testFiles/coloring/problematicSchema.txt"); } catch (Exception e) { e.printStackTrace(); @@ -259,7 +247,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testReadReactionSchema() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); Collection collection = reader.readColorSchema("testFiles/coloring/reactionSchema.txt"); assertEquals(1, collection.size()); ColorSchema schema = collection.iterator().next(); @@ -275,8 +262,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test(timeout = 15000) public void testNextVersionReadSchema() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema("testFiles/coloring/goodLayout.v=1.0.txt"); assertNotNull(schemas); @@ -295,8 +280,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { Model model = getModelForFile("testFiles/coloring/protein_to_color.xml", false); - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema("testFiles/coloring/problematicSchema.txt"); ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); factory.execute(); @@ -312,7 +295,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testColoringWithValueOrColor() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); Map params = new HashMap<>(); params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); @@ -331,7 +313,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testElementsByType() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); Map params = new HashMap<>(); params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); @@ -349,7 +330,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testColoringWithInvalidValueAndColor() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); Map params = new HashMap<>(); params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); @@ -366,7 +346,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testColoringWithEmptyColor() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); Map params = new HashMap<>(); params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); @@ -383,7 +362,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testColoringWithInvalidValueAndColor2() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); Map params = new HashMap<>(); params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); @@ -398,8 +376,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testSchemasWithId() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema("testFiles/coloring/schemaWithIdentifiers.txt"); for (ColorSchema colorSchema : schemas) { for (MiriamData md : colorSchema.getMiriamData()) { @@ -417,9 +393,8 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testSchemasWithIdSnakeCase() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - - Collection schemas = reader.readColorSchema("testFiles/coloring/schema_with_identifiers_in_snake_case.txt"); + Collection schemas = reader + .readColorSchema("testFiles/coloring/schema_with_identifiers_in_snake_case.txt"); for (ColorSchema colorSchema : schemas) { for (MiriamData md : colorSchema.getMiriamData()) { assertNotNull(md.getResource()); @@ -436,8 +411,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testSchemasWithEmptyNameAndId() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); - Collection schemas = reader.readColorSchema("testFiles/coloring/schemaIdWithoutName.txt"); for (ColorSchema colorSchema : schemas) { for (MiriamData md : colorSchema.getMiriamData()) { @@ -455,7 +428,6 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testSimpleNameSchemas() throws Exception { try { - ColorSchemaReader reader = new ColorSchemaReader(); String input = "#header\ns1\ns2\n"; Collection schemas = reader .readSimpleNameColorSchema(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8))); @@ -466,4 +438,10 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { } } + @Test + public void testParseSpeciesTypesForEmptyString() throws Exception { + List> classes = reader.parseSpeciesTypes("", null); + assertEquals(0, classes.size()); + } + } -- GitLab From b5b1738397d5d1e8dc5179e91725591a4d797ea3 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 14:02:13 +0200 Subject: [PATCH 27/33] model_name renamed to map_name --- CHANGELOG | 2 + .../services/impl/LayoutService.java | 4 +- .../services/utils/ColorSchemaReader.java | 6 +-- .../services/utils/ColorSchemaXlsxReader.java | 4 +- .../utils/data/ColorSchemaColumn.java | 4 +- .../services/utils/ColorSchemaReaderTest.java | 37 +++++++++++++++++++ 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bd089b970..8ffa5ce73 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,6 @@ minerva (12.3.1~beta.1) unstable; urgency=low + * Small improvement: model_name renamed to map_name in data overlay columns + (#827) * Bug fix: invalid color in data overlay provides proper feedback to the user (#822) * Bug fix: genetic variant overlay without name caused problems (#832) diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java index f3379ed42..a6ba78e93 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java @@ -672,7 +672,7 @@ public class LayoutService implements ILayoutService { sb.append("\t"); } else if (column.equals(ColorSchemaColumn.NAME)) { sb.append(schema.getName() + "\t"); - } else if (column.equals(ColorSchemaColumn.MODEL_NAME)) { + } else if (column.equals(ColorSchemaColumn.MAP_NAME)) { sb.append(schema.getModelName() + "\t"); } else if (column.equals(ColorSchemaColumn.VALUE)) { sb.append(schema.getValue() + "\t"); @@ -727,7 +727,7 @@ public class LayoutService implements ILayoutService { sb.append("\t"); } else if (column.equals(ColorSchemaColumn.NAME)) { sb.append(schema.getName() + "\t"); - } else if (column.equals(ColorSchemaColumn.MODEL_NAME)) { + } else if (column.equals(ColorSchemaColumn.MAP_NAME)) { sb.append(schema.getModelName() + "\t"); } else if (column.equals(ColorSchemaColumn.VALUE)) { sb.append(schema.getValue() + "\t"); diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index 40a7e3168..fb49f55ff 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -166,7 +166,7 @@ public class ColorSchemaReader { throw new InvalidColorSchemaException(ColorSchemaColumn.GENE_NAME + " and " + ColorSchemaColumn.NAME + " column cannot appear in the same dataset"); } - Integer modelNameColumn = schemaColumns.get(ColorSchemaColumn.MODEL_NAME); + Integer modelNameColumn = schemaColumns.get(ColorSchemaColumn.MAP_NAME); Integer identifierColumn = schemaColumns.get(ColorSchemaColumn.IDENTIFIER); Integer variantIdentifierColumn = schemaColumns.get(ColorSchemaColumn.VARIANT_IDENTIFIER); Integer allelFrequencyColumn = schemaColumns.get(ColorSchemaColumn.ALLEL_FREQUENCY); @@ -493,7 +493,7 @@ public class ColorSchemaReader { Integer valueColumn = schemaColumns.get(ColorSchemaColumn.VALUE); Integer colorColumn = schemaColumns.get(ColorSchemaColumn.COLOR); Integer nameColumn = schemaColumns.get(ColorSchemaColumn.NAME); - Integer modelNameColumn = schemaColumns.get(ColorSchemaColumn.MODEL_NAME); + Integer modelNameColumn = schemaColumns.get(ColorSchemaColumn.MAP_NAME); Integer identifierColumn = schemaColumns.get(ColorSchemaColumn.IDENTIFIER); Integer elementIdentifierColumn = schemaColumns.get(ColorSchemaColumn.ELEMENT_IDENTIFIER); if (elementIdentifierColumn == null) { @@ -789,7 +789,7 @@ public class ColorSchemaReader { result.add(ColorSchemaColumn.NAME); } if (schema.getModelName() != null) { - result.add(ColorSchemaColumn.MODEL_NAME); + result.add(ColorSchemaColumn.MAP_NAME); } if (schema.getElementId() != null) { result.add(ColorSchemaColumn.ELEMENT_IDENTIFIER); diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java index 1437bd379..631a20734 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java @@ -156,7 +156,7 @@ public class ColorSchemaXlsxReader { valueColumn = foundSchemaColumns.get(ColorSchemaColumn.VALUE); colorColumn = foundSchemaColumns.get(ColorSchemaColumn.COLOR); nameColumn = foundSchemaColumns.get(ColorSchemaColumn.NAME); - modelNameColumn = foundSchemaColumns.get(ColorSchemaColumn.MODEL_NAME); + modelNameColumn = foundSchemaColumns.get(ColorSchemaColumn.MAP_NAME); identifierColumn = foundSchemaColumns.get(ColorSchemaColumn.IDENTIFIER); elementIdentifierColumn = foundSchemaColumns.get(ColorSchemaColumn.ELEMENT_IDENTIFIER); if (elementIdentifierColumn == null) { @@ -326,7 +326,7 @@ public class ColorSchemaXlsxReader { result.add(ColorSchemaColumn.NAME); } if (schema.getModelName() != null) { - result.add(ColorSchemaColumn.MODEL_NAME); + result.add(ColorSchemaColumn.MAP_NAME); } if (schema.getElementId() != null) { result.add(ColorSchemaColumn.ELEMENT_IDENTIFIER); diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java b/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java index 5cbcc2e70..045198598 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java @@ -24,9 +24,9 @@ public enum ColorSchemaColumn { GENE_NAME(new ColorSchemaType[] { ColorSchemaType.GENETIC_VARIANT }), /** - * Name of the element. + * Name of the map. */ - MODEL_NAME(new ColorSchemaType[] { ColorSchemaType.GENERIC, ColorSchemaType.GENETIC_VARIANT }), + MAP_NAME("model_name",new ColorSchemaType[] { ColorSchemaType.GENERIC, ColorSchemaType.GENETIC_VARIANT }), /** * Value that will be transformed into new color. diff --git a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java index 2f02c8685..7041b25df 100644 --- a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java @@ -444,4 +444,41 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { assertEquals(0, classes.size()); } + @Test + public void testColoringWithModelName() throws Exception { + try { + String input = "name\tcolor\tmodel_name\n" + + "s1\t#ff0000\txxx\n" ; + Map params = new HashMap<>(); + params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); + + Collection schemas = reader + .readColorSchema(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)), params); + assertEquals(1, schemas.size()); + assertNotNull(schemas.iterator().next().getModelName()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testColoringWithMapName() throws Exception { + try { + String input = "name\tcolor\tmap_name\n" + + "s1\t#ff0000\txxx\n" ; + Map params = new HashMap<>(); + params.put(TextFileUtils.COLUMN_COUNT_PARAM, "3"); + + Collection schemas = reader + .readColorSchema(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)), params); + assertEquals(1, schemas.size()); + assertNotNull(schemas.iterator().next().getModelName()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + } -- GitLab From d04da2a3437fca7550c12678f5a280677225c4eb Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 14:41:35 +0200 Subject: [PATCH 28/33] color parameter is not ignored in gene variants --- CHANGELOG | 1 + .../java/lcsb/mapviewer/services/utils/ColorSchemaReader.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8ffa5ce73..8b544c0a4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -22,6 +22,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: when changing data in edit user dialog there was a need to click close button twice (#818) * Bug fix: empty type for data overlay is allowed (#827) + * Bug fix: genetic variants data overlay was ignoring color parameter (#827) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index fb49f55ff..2471473e5 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -435,7 +435,7 @@ public class ColorSchemaReader { } } for (ColorSchema colorSchema : schemasByName.values()) { - if (colorSchema instanceof GeneVariationColorSchema) { + if (colorSchema instanceof GeneVariationColorSchema && colorSchema.getColor() == null) { colorSchema.setColor(getGeneVariantsColor(((GeneVariationColorSchema) colorSchema).getGeneVariations())); } } @@ -446,7 +446,7 @@ public class ColorSchemaReader { * Gets color that should be assigned to {@link GeneVariationColorSchema}. * * @param geneVariations - * list of viariants + * list of variants * @return {@link Color} that should be assigned to * {@link GeneVariationColorSchema} */ -- GitLab From 5eaef346f2dfe3618e24964103bc5801abb469a4 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 15:00:11 +0200 Subject: [PATCH 29/33] some columns are marked as deprecated --- CHANGELOG | 5 +++++ .../mapviewer/services/utils/ColorSchemaReader.java | 11 ++++++++++- .../services/utils/data/ColorSchemaColumn.java | 6 ++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 8b544c0a4..484adae3d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Small improvement: model_name renamed to map_name in data overlay columns (#827) + * Small improvement: name, type, reference_genome_type and + reference_genome_version column in genetic variant data overlay are + deprecated (#827) + * Bug fix: deprecated columns in data overlay are not visible to the end user + (#827) * Bug fix: invalid color in data overlay provides proper feedback to the user (#822) * Bug fix: genetic variant overlay without name caused problems (#832) diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java index 2471473e5..e9f873955 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -7,6 +7,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -720,7 +721,15 @@ public class ColorSchemaReader { } else { String columnNames = ""; for (ColorSchemaColumn schemaColumn : ColorSchemaColumn.values()) { - if (schemaColumn.getTypes().contains(type)) { + boolean deprecated = false; + try { + Field f = ColorSchemaColumn.class.getField(schemaColumn.name()); + if (f.isAnnotationPresent(Deprecated.class)) + deprecated = true; + } catch (NoSuchFieldException | SecurityException e) { + } + + if (schemaColumn.getTypes().contains(type) && !deprecated) { columnNames += schemaColumn.getColumnName() + ", "; } } diff --git a/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java b/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java index 045198598..fd9e21311 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/data/ColorSchemaColumn.java @@ -19,7 +19,7 @@ public enum ColorSchemaColumn { /** * Name of the element. */ - NAME(new ColorSchemaType[] { ColorSchemaType.GENERIC, ColorSchemaType.GENETIC_VARIANT }), + NAME(new ColorSchemaType[] { ColorSchemaType.GENERIC}), GENE_NAME(new ColorSchemaType[] { ColorSchemaType.GENETIC_VARIANT }), @@ -43,7 +43,7 @@ public enum ColorSchemaColumn { /** * Class type of the element. */ - TYPE(new ColorSchemaType[] { ColorSchemaType.GENERIC, ColorSchemaType.GENETIC_VARIANT }), + TYPE(new ColorSchemaType[] { ColorSchemaType.GENERIC}), /** * New element/reaction color. @@ -99,11 +99,13 @@ public enum ColorSchemaColumn { /** * What's the {@link ReferenceGenomeType}. */ + @Deprecated REFERENCE_GENOME_TYPE(new ColorSchemaType[] { ColorSchemaType.GENETIC_VARIANT }), /** * {@link ReferenceGenome#version Version} of the reference genome. */ + @Deprecated REFERENCE_GENOME_VERSION(new ColorSchemaType[] { ColorSchemaType.GENETIC_VARIANT }), /** -- GitLab From ec7dad53adfa7c4f10afb5d16942db71f1023aba Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 16:24:45 +0200 Subject: [PATCH 30/33] pathways can be drawn using glyphs --- CHANGELOG | 1 + .../mapviewer/converter/ProjectFactory.java | 20 ++++++++ .../converter/ProjectFactoryTest.java | 49 +++++++++++++++++++ .../commands/CreateHierarchyCommand.java | 5 +- .../model/map/layout/graphics/LayerText.java | 19 +++++++ .../V13.1.0.20190607__text_contains_glyph.sql | 5 ++ 6 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 persist/src/main/resources/db/migration/13.1.0~beta.1/V13.1.0.20190607__text_contains_glyph.sql diff --git a/CHANGELOG b/CHANGELOG index 484adae3d..d91c26390 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -28,6 +28,7 @@ minerva (12.3.1~beta.1) unstable; urgency=low close button twice (#818) * Bug fix: empty type for data overlay is allowed (#827) * Bug fix: genetic variants data overlay was ignoring color parameter (#827) + * Bug fix: pathways can be drawn using glyphs (#825) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java index dd5c55cbb..3b576a5fb 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java @@ -18,8 +18,11 @@ import lcsb.mapviewer.converter.zip.LayoutZipEntryFile; import lcsb.mapviewer.converter.zip.ZipEntryFile; import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.map.layout.graphics.Glyph; +import lcsb.mapviewer.model.map.layout.graphics.Layer; +import lcsb.mapviewer.model.map.layout.graphics.LayerText; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelData; +import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; import lcsb.mapviewer.model.map.species.Element; public class ProjectFactory { @@ -90,7 +93,15 @@ public class ProjectFactory { } private void assignGlyphsToElements(Project project) throws InvalidGlyphFile { + Set models = new HashSet<>(); + models.addAll(project.getModels()); + for (ModelData model : project.getModels()) { + for (ModelSubmodelConnection connection : model.getSubmodels()) { + models.add(connection.getSubmodel()); + } + } + for (ModelData model : models) { for (Element element : model.getElements()) { Glyph glyph = extractGlyph(project, element.getNotes()); if (glyph != null) { @@ -98,6 +109,15 @@ public class ProjectFactory { element.setGlyph(glyph); } } + for (Layer layer : model.getLayers()) { + for (LayerText text : layer.getTexts()) { + Glyph glyph = extractGlyph(project, text.getNotes()); + if (glyph != null) { + text.setNotes(removeGlyph(text.getNotes())); + text.setGlyph(glyph); + } + } + } } } diff --git a/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java b/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java index ad6b5dc39..b882d44aa 100644 --- a/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java +++ b/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java @@ -23,6 +23,8 @@ import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.map.OverviewImage; import lcsb.mapviewer.model.map.OverviewLink; import lcsb.mapviewer.model.map.OverviewModelLink; +import lcsb.mapviewer.model.map.layout.graphics.Layer; +import lcsb.mapviewer.model.map.layout.graphics.LayerText; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelData; import lcsb.mapviewer.model.map.model.ModelFullIndexed; @@ -211,6 +213,53 @@ public class ProjectFactoryTest extends ConverterTestFunctions { } + @Test + public void testParseGlyphsAndPutThemAsTextGlyphs() throws Exception { + try { + Model model = new ModelFullIndexed(null); + Layer layer = new Layer(); + + LayerText text = new LayerText(); + text.setNotes("Glyph: glyphs/g1.png"); + layer.addLayerText(text); + model.addLayer(layer); + + MockConverter.modelToBeReturned = model; + + ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class); + ProjectFactory projectFactory = new ProjectFactory(converter); + + ComplexZipConverterParams params = new ComplexZipConverterParams(); + params.zipFile(new ZipFile("testFiles/complex_with_glyphs.zip")); + params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null)); + + ZipFile zipFile = new ZipFile("testFiles/complex_with_glyphs.zip"); + + ZipEntryFileFactory factory = new ZipEntryFileFactory(); + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if (!entry.isDirectory()) { + params.entry(factory.createZipEntryFile(entry, zipFile)); + } + } + + Project project = projectFactory.create(params); + assertNotNull(project); + model = project.getModels().iterator().next().getModel(); + + LayerText fetchedProtein = model.getLayers().iterator().next().getTexts().get(0); + + assertFalse("Glyph field should be removed from notes", fetchedProtein.getNotes().contains("Glyph")); + assertNotNull("Glyph in the protein is not defined but should", fetchedProtein.getGlyph()); + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + + } + private GenericProtein createProtein() { GenericProtein result = new GenericProtein("s" + elementCounter++); return result; diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/CreateHierarchyCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/CreateHierarchyCommand.java index adb506142..294b1fb29 100644 --- a/model-command/src/main/java/lcsb/mapviewer/commands/CreateHierarchyCommand.java +++ b/model-command/src/main/java/lcsb/mapviewer/commands/CreateHierarchyCommand.java @@ -43,11 +43,11 @@ public class CreateHierarchyCommand extends ModelCommand { private static final double LOG_4 = Math.log(4); /** - * Top left corner x coordinate of the text associated with compratment. + * Top left corner x coordinate of the text associated with compartment. */ private static final double DEFAULT_TITLE_X_COORD_IN_ARTIFITIAL_COMPARTMENT = 10; /** - * Top left corner y coordinate of the text associated with compratment. + * Top left corner y coordinate of the text associated with compartment. */ private static final double DEFAULT_TITLE_Y_COORD_IN_ARTIFITIAL_COMPARTMENT = 10; @@ -180,6 +180,7 @@ public class CreateHierarchyCommand extends ModelCommand { compartment.setName(extractNameFromText(text.getNotes())); compartment.setNotes(extractNotesFromText(text.getNotes())); compartment.setZ(text.getZ()); + compartment.setGlyph(text.getGlyph()); rap.processNotes(compartment); compartment.setNamePoint(new Point2D.Double(text.getX() + DEFAULT_TITLE_X_COORD_IN_ARTIFITIAL_COMPARTMENT, diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerText.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerText.java index d866c3e6e..ecd49c6f8 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerText.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/LayerText.java @@ -5,9 +5,11 @@ import java.awt.geom.Rectangle2D; import java.io.Serializable; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.ManyToOne; import org.apache.log4j.Logger; @@ -92,6 +94,12 @@ public class LayerText implements Serializable, Drawable { */ private Double fontSize = DEFAULT_LAYER_FONT_SIZE; + /** + * Glyph used for drawing (instead of text). + */ + @ManyToOne(fetch = FetchType.LAZY) + private Glyph glyph = null; + /** * Default constructor. */ @@ -130,6 +138,9 @@ public class LayerText implements Serializable, Drawable { height = layerText.getHeight(); notes = layerText.getNotes(); fontSize = layerText.getFontSize(); + if (layerText.getGlyph() != null) { + setGlyph(new Glyph(layerText.getGlyph())); + } } /** @@ -377,4 +388,12 @@ public class LayerText implements Serializable, Drawable { return "x=" + x + ";y=" + y + "; w=" + width + ", h=" + height; } + public Glyph getGlyph() { + return glyph; + } + + public void setGlyph(Glyph glyph) { + this.glyph = glyph; + } + } diff --git a/persist/src/main/resources/db/migration/13.1.0~beta.1/V13.1.0.20190607__text_contains_glyph.sql b/persist/src/main/resources/db/migration/13.1.0~beta.1/V13.1.0.20190607__text_contains_glyph.sql new file mode 100644 index 000000000..8c1f1ac83 --- /dev/null +++ b/persist/src/main/resources/db/migration/13.1.0~beta.1/V13.1.0.20190607__text_contains_glyph.sql @@ -0,0 +1,5 @@ +alter table layer_text_table add column glyph_id integer; +alter table layer_text_table add constraint layer_text_table_glyph_fk FOREIGN KEY (glyph_id) + REFERENCES glyph_table (id) MATCH SIMPLE + ON UPDATE NO ACTION ON DELETE NO ACTION; + -- GitLab From 33246d8c6c970f38fd22996fcb886d344893fbd0 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 16:59:23 +0200 Subject: [PATCH 31/33] empty data overlay doesn't have glyph --- CHANGELOG | 2 ++ .../main/java/lcsb/mapviewer/commands/ColorModelCommand.java | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index d91c26390..37d26a057 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -29,6 +29,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: empty type for data overlay is allowed (#827) * Bug fix: genetic variants data overlay was ignoring color parameter (#827) * Bug fix: pathways can be drawn using glyphs (#825) + * Bug fix: empty background overlay doesn't show glyphs, instead standard + visualization is used (#826) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java index 0604eb7b4..9f73f3e35 100644 --- a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java +++ b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java @@ -337,6 +337,7 @@ public class ColorModelCommand extends ModelCommand { for (Element element : result.getElements()) { element.setColor(Color.WHITE); + element.setGlyph(null); } for (Reaction reaction : result.getReactions()) { for (AbstractNode node : reaction.getNodes()) { -- GitLab From f27822891157ae4c1780cb9a1bcc1771b657ecf0 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 17:11:26 +0200 Subject: [PATCH 32/33] asynchronous data overlay visualization might cause problems due to data loading latency --- CHANGELOG | 2 ++ .../src/main/js/map/surface/AliasSurface.js | 6 +++++- .../test/js/map/surface/AliasSurface-test.js | 21 ++++++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 37d26a057..3e476a9e7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -31,6 +31,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: pathways can be drawn using glyphs (#825) * Bug fix: empty background overlay doesn't show glyphs, instead standard visualization is used (#826) + * Bug fix: asynchronous cals on showing/hiding data overlays might cause + problems due to network latency (#830) minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and diff --git a/frontend-js/src/main/js/map/surface/AliasSurface.js b/frontend-js/src/main/js/map/surface/AliasSurface.js index b78839878..c0f5ae665 100644 --- a/frontend-js/src/main/js/map/surface/AliasSurface.js +++ b/frontend-js/src/main/js/map/surface/AliasSurface.js @@ -177,7 +177,11 @@ AliasSurface.prototype.setBoundsForAlias = function (startX, endX) { var pointB = new Point(alias.getX() + endX * alias.getWidth(), alias.getY() + alias.getHeight()); var bounds = new Bounds(pointA, pointB); - this.getMapCanvasObjects()[0].setBounds(bounds); + + var mapCanvasObjects = this.getMapCanvasObjects(); + for (var i = 0; i < mapCanvasObjects.length; i++) { + mapCanvasObjects[i].setBounds(bounds); + } }; /** diff --git a/frontend-js/src/test/js/map/surface/AliasSurface-test.js b/frontend-js/src/test/js/map/surface/AliasSurface-test.js index 4c98a6eb0..db8483335 100644 --- a/frontend-js/src/test/js/map/surface/AliasSurface-test.js +++ b/frontend-js/src/test/js/map/surface/AliasSurface-test.js @@ -61,11 +61,30 @@ describe('AliasSurface', function () { var bounds = surface.getBounds(); surface.setBoundsForAlias(1, 3); var bounds2 = surface.getBounds(); - assert.equal(bounds.getRightBottom().y, bounds2.getRightBottom().y); + assert.equal(bounds.getRightBottom().y, bounds2.getRightBottom().y, helper.EPSILON); assert.ok(bounds.getRightBottom().x !== bounds2.getRightBottom().x); }); }); + it("before alias init", function () { + var map; + var alias, surface; + return ServerConnector.getProject().then(function (project) { + map = helper.createCustomMap(project); + return map.getModel().getAliasById(329171); + }).then(function (result) { + alias = result; + surface = new AliasSurface({ + alias: result, + overlayData: [helper.createLayoutAlias(alias)], + map: map + }); + surface.setBoundsForAlias(1, 3); + var bounds = surface.getBounds(); + assert.ok(bounds); + }); + }); + it("from element with data overlay", function () { var map = helper.createCustomMap(); var alias = helper.createAlias(map); -- GitLab From 41feac00ad89d6c3baf0322dc673c8d8856db3f6 Mon Sep 17 00:00:00 2001 From: Piotr Gawron Date: Fri, 7 Jun 2019 17:26:55 +0200 Subject: [PATCH 33/33] Update CHANGELOG --- CHANGELOG | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 3e476a9e7..eb71d783a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -minerva (12.3.1~beta.1) unstable; urgency=low +minerva (13.1.0~beta.1) unstable; urgency=low * Small improvement: model_name renamed to map_name in data overlay columns (#827) * Small improvement: name, type, reference_genome_type and @@ -34,6 +34,8 @@ minerva (12.3.1~beta.1) unstable; urgency=low * Bug fix: asynchronous cals on showing/hiding data overlays might cause problems due to network latency (#830) + -- Piotr Gawron Fri, 7 Jun 2019 17:00:00 +0200 + minerva (13.1.0~beta.0) unstable; urgency=low * Feature: annotators are more flexible - you can define set of input and outputs used by annotator (#617) -- GitLab