diff --git a/.gitignore b/.gitignore index a835f014ea46a3f4ba1a4b75fd0d8bae20913ff4..cb15bd31b7ef18ef93f0626ade6555547475ac33 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ map_images/ */target/ web/src/main/webapp/svnversion.txt *.war +/target/ diff --git a/CHANGELOG b/CHANGELOG index a2e0df44a3e219b497dca08b621f1b274b3975ba..335e550153f90d24799f4f35be877dec6d5c3dd0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,15 @@ +minerva (10.0.3) stable; urgency=medium + + * Bug fix: login cannot contain whitespace + * Bug fix: search for multiple drugs will not return more drugs than + queried for + * Bug fix: drug list for some proteins (like RHOA) hung webpage + * Bug fix: comments on submaps issue + * Bug fix: link to submap from comment panel + * Overlay coloring can be defined in Configuration + + -- Piotr Gawron <piotr.gawron@uni.lu> Thu, 10 Oct 2016 10:01:16 +0200 + minerva (10.0.2) stable; urgency=medium * Bug fix: markers for mirna targets visibility diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChEMBLParser.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChEMBLParser.java index ef61c8e976e766cdf205b3115ea83022334f01e5..34536aadd6ce6da6c461b4e45804d70f1e0126c8 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChEMBLParser.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/ChEMBLParser.java @@ -68,7 +68,12 @@ public class ChEMBLParser extends DrugAnnotation implements IExternalService { /** * Url that list of all child nodes for chembl ontology term. */ - private static final String PARENT_CHILD_API_URL = "https://www.ebi.ac.uk/chembl/api/data/molecule_form?parent="; + private static final String PARENT_CHILD_API_URL = "https://www.ebi.ac.uk/chembl/api/data/molecule_form/"; + + /** + * Suffix that should be added to {@link #PARENT_CHILD_API_URL}. + */ + private static final String PARENT_CHILD_API_URL_SUFFIX = ".xml"; /** * Url used for finding targets containing uniprot identifiers. Important - @@ -420,7 +425,7 @@ public class ChEMBLParser extends DrugAnnotation implements IExternalService { List<Target> targets = new ArrayList<>(); try { String id = drugId.getResource(); - String query = PARENT_CHILD_API_URL + id; + String query = PARENT_CHILD_API_URL + id + PARENT_CHILD_API_URL_SUFFIX; String page = getWebPageContent(query); Document document = super.getXmlDocumentFromString(page); diff --git a/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java b/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java index 29bee7c1502da3159913fa9388d92f8b9fb868f3..31ae9e1054c9102af86ba23196d2760ae1cb06e2 100644 --- a/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java +++ b/annotation/src/main/java/lcsb/mapviewer/annotation/services/PubmedParser.java @@ -54,7 +54,7 @@ public class PubmedParser extends CachableInterface implements IExternalService /** * Version of the remote API thnat is supported by this connecting class. */ - static final String SUPPORTED_VERSION = "4.5.2"; + static final String SUPPORTED_VERSION = "4.5.3"; /** * Connector used for accessing data from miriam registry. diff --git a/annotation/src/test/java/lcsb/mapviewer/annotation/services/ChEMBLParserTest.java b/annotation/src/test/java/lcsb/mapviewer/annotation/services/ChEMBLParserTest.java index 1728b89ca0562b23bae6bfe4db2d880468e9af65..d843e6c88850a26210ba6fa9b5270fd9ee2dc1fe 100644 --- a/annotation/src/test/java/lcsb/mapviewer/annotation/services/ChEMBLParserTest.java +++ b/annotation/src/test/java/lcsb/mapviewer/annotation/services/ChEMBLParserTest.java @@ -18,7 +18,6 @@ import java.util.Set; import org.apache.log4j.Logger; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; @@ -64,7 +63,7 @@ public class ChEMBLParserTest extends AnnotationTestFunctions { @Test public void test1FindDrug() throws Exception { try { - //do it with cache turned on + // do it with cache turned on chemblParser.setCache(cache); Drug drug = chemblParser.findDrug("CABOZANTINIB"); @@ -213,11 +212,11 @@ public class ChEMBLParserTest extends AnnotationTestFunctions { @Test public void test9FindDrug() throws Exception { try { - String n = "PONATINIB"; - Drug test = chemblParser.findDrug(n); + String name = "PONATINIB"; + Drug test = chemblParser.findDrug(name); assertEquals("CHEMBL1171837", test.getSources().get(0).getResource()); - assertEquals("PONATINIB", test.getName()); + assertEquals(name, test.getName()); assertNull(test.getDescription()); assertEquals(3, test.getTargets().size()); } catch (Exception e) { @@ -228,7 +227,6 @@ public class ChEMBLParserTest extends AnnotationTestFunctions { } @Test - @Ignore("Bug 452") public void test10FindDrug() throws Exception { try { String n = "DEXAMETHASONE"; diff --git a/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java b/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java new file mode 100644 index 0000000000000000000000000000000000000000..f76dce4edb7f08ab22821bdf6633a1e4a7bff89a --- /dev/null +++ b/commons/src/main/java/lcsb/mapviewer/common/geometry/ColorParser.java @@ -0,0 +1,59 @@ +package lcsb.mapviewer.common.geometry; + +import java.awt.Color; + +import lcsb.mapviewer.common.exception.InvalidArgumentException; + +/** + * Parser clas to extract {@link Color} objects from {@link String}. + * + * @author Piotr Gawron + * + */ +public class ColorParser { + + /** + * Base of the hex representation. + */ + private static final int HEX_BASE = 16; + + /** + * Length of the string describing color in rgb: "#RRGGBB". + */ + private static final int COLOR_STRING_LENGTH = 7; + + /** + * Where starts description of red color in stirng representing color. + */ + private static final int COLOR_SUBSTRING_START_RED = 1; + + /** + * Where starts description of green color in stirng representing color. + */ + private static final int COLOR_SUBSTRING_START_GREEN = 3; + + /** + * Where starts description of blue color in stirng representing color. + */ + private static final int COLOR_SUBSTRING_START_BLUE = 5; + + /** + * Extracts {@link Color} from input {@link String}. + * + * @param string + * text to process + * @return {@link Color} obtained from input text + */ + public Color parse(String string) { + if (string.charAt(0) != '#') { + string = "#" + string; + } + if (string.length() != COLOR_STRING_LENGTH) { + throw new InvalidArgumentException("Invalid color value: " + string + ". Correct format: #xxxxxx (where x is a hex value)"); + } else { + return new Color(Integer.valueOf(string.substring(COLOR_SUBSTRING_START_RED, COLOR_SUBSTRING_START_GREEN), HEX_BASE), // + Integer.valueOf(string.substring(COLOR_SUBSTRING_START_GREEN, COLOR_SUBSTRING_START_BLUE), HEX_BASE), // + Integer.valueOf(string.substring(COLOR_SUBSTRING_START_BLUE, COLOR_STRING_LENGTH), HEX_BASE)); + } + } +} diff --git a/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java b/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6fde224cd5b10f04b1de254d4c180a6e04dddb43 --- /dev/null +++ b/commons/src/test/java/lcsb/mapviewer/common/geometry/ColorParserTest.java @@ -0,0 +1,68 @@ +package lcsb.mapviewer.common.geometry; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.awt.Color; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +import lcsb.mapviewer.common.exception.InvalidArgumentException; + +public class ColorParserTest { + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + + @Test + public void testSetInvalidColor() throws Exception { + try { + ColorParser parser = new ColorParser(); + parser.parse("qwe"); + fail("Exception expected"); + } catch (InvalidArgumentException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testSetInvalidColor2() throws Exception { + try { + ColorParser parser = new ColorParser(); + parser.parse("fffffff"); + fail("Exception expected"); + } catch (InvalidArgumentException e) { + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testSetColor() throws Exception { + try { + ColorParser parser = new ColorParser(); + Color color = parser.parse("#ffffff"); + assertEquals(Color.WHITE, color); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + +} diff --git a/converter-graphics/pom.xml b/converter-graphics/pom.xml index 97ca0f2fc5f8c303f0ada2e28090099813304264..c48f3778fb7caccd86741b6fc26f0c84a9d51681 100644 --- a/converter-graphics/pom.xml +++ b/converter-graphics/pom.xml @@ -1,63 +1,70 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>lcsb.mapviewer</groupId> - <artifactId>parent</artifactId> - <version>1.0</version> - </parent> - <artifactId>converter-graphics</artifactId> - <name>MapViewer graphics converter</name> - <description>Converter that allows to transform model into graphic representation</description> - - <dependencies> - - <!-- dependency from the MapViewer model --> - - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>model</artifactId> - <version>1.0</version> - </dependency> - - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>model-command</artifactId> - <version>1.0</version> - </dependency> - - <!-- Log4J --> - <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - <version>${log4j.version}</version> - </dependency> - - <!-- Library used for generating svg --> - <dependency> - <groupId>org.apache.xmlgraphics</groupId> - <artifactId>batik-rasterizer</artifactId> - <version>${batik.version}</version> - </dependency> - - <dependency> - <groupId>org.apache.xmlgraphics</groupId> - <artifactId>batik-svggen</artifactId> - <version>${batik.version}</version> - </dependency> - - <!-- iText library for generating pdf --> - <dependency> - <groupId>com.itextpdf</groupId> - <artifactId>itextpdf</artifactId> - <version>${itext.version}</version> - </dependency> - - <dependency> - <groupId>com.itextpdf</groupId> - <artifactId>itextpdf</artifactId> - <version>${itext.version}</version> - </dependency> - - </dependencies> - +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>lcsb.mapviewer</groupId> + <artifactId>parent</artifactId> + <version>1.0</version> + </parent> + <artifactId>converter-graphics</artifactId> + <name>MapViewer graphics converter</name> + <description>Converter that allows to transform model into graphic representation</description> + + <dependencies> + + <!-- dependency from the MapViewer model --> + + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>model</artifactId> + <version>1.0</version> + </dependency> + + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>model-command</artifactId> + <version>1.0</version> + </dependency> + + <!-- Log4J --> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>${log4j.version}</version> + </dependency> + + <!-- Library used for generating svg --> + <dependency> + <groupId>org.apache.xmlgraphics</groupId> + <artifactId>batik-rasterizer</artifactId> + <version>${batik.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.xmlgraphics</groupId> + <artifactId>batik-svggen</artifactId> + <version>${batik.version}</version> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <version>${mockito.version}</version> + <scope>test</scope> + </dependency> + + <!-- iText library for generating pdf --> + <dependency> + <groupId>com.itextpdf</groupId> + <artifactId>itextpdf</artifactId> + <version>${itext.version}</version> + </dependency> + + <dependency> + <groupId>com.itextpdf</groupId> + <artifactId>itextpdf</artifactId> + <version>${itext.version}</version> + </dependency> + + </dependencies> + </project> \ No newline at end of file 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 efa912097a3a7a923a240cd04f191b28ce4e729e..ad46b1dcf3705e3940a9111a82cbef4830113ca7 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 @@ -14,6 +14,7 @@ import java.util.Map; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.MimeType; import lcsb.mapviewer.converter.graphics.layer.LayerConverter; import lcsb.mapviewer.converter.graphics.reaction.ReactionConverter; @@ -26,6 +27,7 @@ import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.species.Complex; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.modelutils.map.ElementUtils; /** * This class is responsible for creation of the image from the model. It's an @@ -93,6 +95,16 @@ public abstract class AbstractImageGenerator { */ private Rectangle2D.Double border = null; + /** + * Object that helps to convert {@link ColorSchema} values into colors. + */ + private ColorExtractor colorExtractor = null; + + /** + * Util class for simple operations on {@link Element elements}. + */ + private ElementUtils eu = new ElementUtils(); + /** * This class contains a list of params that are used for drawing. * @@ -170,6 +182,16 @@ public abstract class AbstractImageGenerator { */ private List<Map<Object, ColorSchema>> visibleLayouts = new ArrayList<>(); + /** + * Color that should be used for drawing overlays with minimum value. + */ + private Color minColor = Color.BLACK; + + /** + * Color that should be used for drawing overlays with maximum value. + */ + private Color maxColor = Color.BLACK; + /** * @param scale * scale to set @@ -481,6 +503,50 @@ public abstract class AbstractImageGenerator { return result; } + /** + * Returns {@link Color} that should be used for drawing overlays with + * maximum value. + * + * @return {@link Color} that should be used for drawing overlays with + * maximum value + */ + public Color getMaxColor() { + return maxColor; + } + + /** + * Returns {@link Color} that should be used for drawing overlays with + * minimum value. + * + * @return {@link Color} that should be used for drawing overlays with + * minimum value + */ + public Color getMinColor() { + return minColor; + } + + /** + * @param minColor + * minColor to set + * @return object with all parameters + * @see #minColor + */ + public Params minColor(Color minColor) { + this.minColor = minColor; + return this; + } + + /** + * @param maxColor + * maxColor to set + * @return object with all parameters + * @see #maxColor + */ + public Params maxColor(Color maxColor) { + this.maxColor = maxColor; + return this; + } + } /** @@ -526,6 +592,8 @@ public abstract class AbstractImageGenerator { this.level = params.getLevel(); this.scale = params.getScale(); + colorExtractor = new ColorExtractor(params.getMinColor(), params.getMaxColor()); + // set border frame extended by a margin border = new Rectangle2D.Double( params.getX() - SINGLE_FRAME_MARGIN, params.getY() - SINGLE_FRAME_MARGIN, params.getWidth() * scale + 2 * SINGLE_FRAME_MARGIN, @@ -557,17 +625,18 @@ public abstract class AbstractImageGenerator { // Get the SBGN display format option from the model this.sbgnFormat = params.getModel().isSbgnFormat(); - // Correct order of displaying is: aliases, reactions, compartments, layers. + // Correct order of displaying is: elements, reactions, compartments, + // layers. // In this way we can display all reactions and overlay them by compartments // or layers if they should be solid and hide complexity behind it - // draw all aliases - for (Element alias : params.getModel().getSortedSpeciesList()) { - // draw only aliases that don't have parents (aren't included in any + // draw all elements + for (Element element : params.getModel().getSortedSpeciesList()) { + // draw only elements that don't have parents (aren't included in any // compartment/complexes) - if (alias instanceof Species) { - if (((Species) alias).getComplex() == null) { - drawAlias((Species) alias, params.getVisibleLayoutsForElement(alias)); + if (element instanceof Species) { + if (((Species) element).getComplex() == null) { + drawSpecies((Species) element, params.getVisibleLayoutsForElement(element)); } } } @@ -576,11 +645,11 @@ public abstract class AbstractImageGenerator { drawReaction(reaction, params.getVisibleLayoutsForElement(reaction)); } // draw all compartments - for (Compartment ca : params.getModel().getSortedCompartments()) { - // draw only aliases that don't have parents (aren't included in any + for (Compartment compartment : params.getModel().getSortedCompartments()) { + // draw only compartment that don't have parents (aren't included in any // compartment/complexes) - if (ca.getCompartment() == null) { - drawCompartmentAlias(ca, params.isNested(), params.getVisibleLayoutsForElement(ca), params); + if (compartment.getCompartment() == null) { + drawCompartment(compartment, params.isNested(), params.getVisibleLayoutsForElement(compartment), params); } } @@ -611,25 +680,26 @@ public abstract class AbstractImageGenerator { } /** - * This method draw a compartment alias on a graphics. + * This method draw a {@link Compartment} on a graphics. * - * @param compAlias + * @param compartment * object that we want to draw * @param nested * are the compartments drawn in hierarchical view * @param visibleLayouts - * list of {@link ColorSchema} used for coloring alias in layouts + * list of {@link ColorSchema} used for coloring element in layouts * @param params * list of all params to create apropriate image * @throws DrawingException - * thrown when there was a problem with drawing compartment alias + * thrown when there was a problem with drawing {@link Compartment} */ - protected void drawCompartmentAlias(final Compartment compAlias, final boolean nested, List<ColorSchema> visibleLayouts, Params params) + protected void drawCompartment(final Compartment compartment, final boolean nested, List<ColorSchema> visibleLayouts, Params params) throws DrawingException { - // If 'compAlias' has not the big enough visibility level then should not be + // If 'compartment' has not the big enough visibility level then should not + // be // visible. - if (compAlias.getVisibilityLevel() > level) { + if (compartment.getVisibilityLevel() > level) { return; } @@ -640,25 +710,25 @@ public abstract class AbstractImageGenerator { */ boolean fill = true; - if (compAlias.getTransparencyLevel() <= level) { + if (compartment.getTransparencyLevel() <= level) { fill = false; } // get a converter for this compartment - AliasConverter converter = new AliasConverter(compAlias); + ElementConverterImpl converter = new ElementConverterImpl(compartment, colorExtractor); ConverterParams compartmentParams = new ConverterParams().textCentered(fill).level(level); if (nested) { compartmentParams.fill(fill).scale(Math.max(scale, 1)); } - // we draw compartment alias only when we have hierarchical view or it's - // standard compartment (not the artifital pathway) - if (nested || !(compAlias instanceof PathwayCompartment)) { + // we draw compartment only when we have hierarchical view or it's + // standard compartment (not the pathway) + if (nested || !(compartment instanceof PathwayCompartment)) { try { - converter.drawAlias(compAlias, graphics, compartmentParams, visibleLayouts); + converter.drawElement(compartment, graphics, compartmentParams, visibleLayouts); } catch (Exception e) { - throw new DrawingException("Problem with drawing alias \"" + compAlias.getElementId() + "\" (name: \"" + compAlias.getName() + "\").", e); + throw new DrawingException(eu.getElementTag(compartment) + "Problem with drawing element.", e); } } @@ -668,48 +738,48 @@ public abstract class AbstractImageGenerator { if (fill) { return; } - List<Element> result = new ArrayList<Element>(); - result.addAll(compAlias.getElements()); + List<Element> result = new ArrayList<>(); + result.addAll(compartment.getElements()); Collections.sort(result, Element.SIZE_COMPARATOR); // draw all children of this compartment - for (Element alias : result) { - // if a child is a standard alias - if (alias instanceof Species) { - drawAlias((Species) alias, params.getVisibleLayoutsForElement(alias)); - } else if (alias instanceof Compartment) { - drawCompartmentAlias((Compartment) alias, nested, params.getVisibleLayoutsForElement(alias), params); + for (Element element : result) { + // if a child is a standard species + if (element instanceof Species) { + drawSpecies((Species) element, params.getVisibleLayoutsForElement(element)); + } else if (element instanceof Compartment) { + drawCompartment((Compartment) element, nested, params.getVisibleLayoutsForElement(element), params); } else { - // if a child is not a compartment or an alias then we have a + // if a child is not a compartment or a species then we have a // problem - throw new DrawingException("Unknown AliasType: " + alias.getClass().getName()); + throw new DrawingException(eu.getElementTag(compartment) + "Unknown Element type"); } } - if (!compAlias.containsIdenticalSpecies()) { - if (!(compAlias instanceof PathwayCompartment)) { - converter.drawText(compAlias, graphics, compartmentParams); + if (!compartment.containsIdenticalSpecies()) { + if (!(compartment instanceof PathwayCompartment)) { + converter.drawText(compartment, graphics, compartmentParams); } } } /** - * This method draw a species alias on a graphics. + * This method draw a {@link Species} on a graphics. * - * @param alias + * @param species * object to be drawn * @param visibleLayouts - * list of {@link ColorSchema} used for coloring alias in layouts + * list of {@link ColorSchema} used for coloring species in layouts * @throws DrawingException - * thrown when there was a problem with drawing an alias + * thrown when there was a problem with drawing a {@link Species} */ - protected void drawAlias(final Species alias, List<ColorSchema> visibleLayouts) throws DrawingException { + protected void drawSpecies(final Species species, List<ColorSchema> visibleLayouts) throws DrawingException { - // The displaying of alias is indicated by values of VisibilityLevel. If + // The displaying of species is indicated by values of VisibilityLevel. If // VisibilityLevel is big enough, then it is // displayed. - if (alias.getVisibilityLevel() > level) { + if (species.getVisibilityLevel() > level) { return; } @@ -718,42 +788,43 @@ public abstract class AbstractImageGenerator { * most bottom Complexes. */ - if (!cross(alias.getBorder())) { + if (!cross(species.getBorder())) { return; } boolean rescale = false; - if (alias instanceof Complex) { - if (((Complex) alias).getElements().size() == 0) { + if (species instanceof Complex) { + if (((Complex) species).getElements().size() == 0) { rescale = true; - } else if (((Complex) alias).getElements().get(0).getVisibilityLevel() > level) { + } else if (((Complex) species).getElements().get(0).getVisibilityLevel() > level) { rescale = true; } } // at the beginning try to find an appropriate converter - AliasConverter converter = new AliasConverter(alias, sbgnFormat); + ElementConverterImpl converter = new ElementConverterImpl(species, sbgnFormat, colorExtractor); double customScale = 1; if (rescale) { customScale = scale; } try { - converter.drawAlias(alias, graphics, new ConverterParams().scale(customScale).textCentered(rescale).level(level).sbgnFormat(sbgnFormat), visibleLayouts); + converter + .drawElement(species, graphics, new ConverterParams().scale(customScale).textCentered(rescale).level(level).sbgnFormat(sbgnFormat), visibleLayouts); } catch (Exception e) { - throw new DrawingException("Problem with drawing alias \"" + alias.getElementId() + "\".", e); + throw new DrawingException(eu.getElementTag(species) + "Problem with drawing element.", e); } - // if the alias is a complex alias then we may want to draw children + // if the species is a complex then we may want to draw children // objects - if (alias instanceof Complex) { - Complex complex = (Complex) alias; + if (species instanceof Complex) { + Complex complex = (Complex) species; // before drawing children check if the view is not set to brief // mode if (!complex.getState().equalsIgnoreCase("brief")) { // depending on current zoom level, children are drawn or not if (complex.getTransparencyLevel() <= level) { for (Species a : complex.getElements()) { - drawAlias(a, visibleLayouts); + drawSpecies(a, visibleLayouts); } } } @@ -772,7 +843,7 @@ public abstract class AbstractImageGenerator { if (!cross(reaction.getLines())) { return; } - ReactionConverter converter = new ReactionConverter(); + ReactionConverter converter = new ReactionConverter(colorExtractor); converter.drawReaction(reaction, graphics, sbgnFormat, visibleLayouts); } diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AliasConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AliasConverter.java deleted file mode 100644 index 1a16acb1e47488a4f637628e0099d9f5167b4996..0000000000000000000000000000000000000000 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/AliasConverter.java +++ /dev/null @@ -1,207 +0,0 @@ -package lcsb.mapviewer.converter.graphics; - -import java.awt.Graphics2D; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; - -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.converter.graphics.compartment.ArtifitialCompartmentConverter; -import lcsb.mapviewer.converter.graphics.compartment.BottomSquareCompartmentConverter; -import lcsb.mapviewer.converter.graphics.compartment.LeftSquareCompartmentConverter; -import lcsb.mapviewer.converter.graphics.compartment.OvalCompartmentConverter; -import lcsb.mapviewer.converter.graphics.compartment.RightSquareCompartmentConverter; -import lcsb.mapviewer.converter.graphics.compartment.SquareCompartmentConverter; -import lcsb.mapviewer.converter.graphics.compartment.TopSquareCompartmentConverter; -import lcsb.mapviewer.converter.graphics.species.AntisenseRnaConverter; -import lcsb.mapviewer.converter.graphics.species.ComplexConverter; -import lcsb.mapviewer.converter.graphics.species.DegradedConverter; -import lcsb.mapviewer.converter.graphics.species.DrugConverter; -import lcsb.mapviewer.converter.graphics.species.GeneConverter; -import lcsb.mapviewer.converter.graphics.species.IonConverter; -import lcsb.mapviewer.converter.graphics.species.PhenotypeConverter; -import lcsb.mapviewer.converter.graphics.species.ProteinConverter; -import lcsb.mapviewer.converter.graphics.species.RnaConverter; -import lcsb.mapviewer.converter.graphics.species.SBGNNucleicAcidFeatureConverter; -import lcsb.mapviewer.converter.graphics.species.SimpleMoleculeConverter; -import lcsb.mapviewer.converter.graphics.species.UnknownConverter; -import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment; -import lcsb.mapviewer.model.map.compartment.LeftSquareCompartment; -import lcsb.mapviewer.model.map.compartment.OvalCompartment; -import lcsb.mapviewer.model.map.compartment.PathwayCompartment; -import lcsb.mapviewer.model.map.compartment.RightSquareCompartment; -import lcsb.mapviewer.model.map.compartment.SquareCompartment; -import lcsb.mapviewer.model.map.compartment.TopSquareCompartment; -import lcsb.mapviewer.model.map.layout.ColorSchema; -import lcsb.mapviewer.model.map.species.Element; -import lcsb.mapviewer.model.map.species.AntisenseRna; -import lcsb.mapviewer.model.map.species.Complex; -import lcsb.mapviewer.model.map.species.Degraded; -import lcsb.mapviewer.model.map.species.Drug; -import lcsb.mapviewer.model.map.species.Gene; -import lcsb.mapviewer.model.map.species.GenericProtein; -import lcsb.mapviewer.model.map.species.Ion; -import lcsb.mapviewer.model.map.species.IonChannelProtein; -import lcsb.mapviewer.model.map.species.Phenotype; -import lcsb.mapviewer.model.map.species.ReceptorProtein; -import lcsb.mapviewer.model.map.species.Rna; -import lcsb.mapviewer.model.map.species.SimpleMolecule; -import lcsb.mapviewer.model.map.species.TruncatedProtein; -import lcsb.mapviewer.model.map.species.Unknown; - -/** - * This class is designed to convert any type of alias into a graphic glyph that - * will be visualized on the graphgics2d object. It contains static instances of - * converter for every type and use one that is needed for currently processed - * alias. - * - * @author Piotr Gawron - * - */ -public class AliasConverter implements IAliasConverter<Element> { - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(AliasConverter.class.getName()); - - // ***************************************************************** - // - // STATIC PART - // - // ***************************************************************** - - /** - * Static map of graphic alias converters used for conversion of aliases. Key - * in this map is a class of alias. Value is the converter that can process - * this type of alias. - */ - private static Map<Class<? extends Element>, IAliasConverter<?>> aliasConverters = new HashMap<Class<? extends Element>, IAliasConverter<?>>(); - - static { - // at the beginning lets add all implemented aliases - - // for element reference - addAliasConverter(GenericProtein.class, new ProteinConverter()); - addAliasConverter(IonChannelProtein.class, new ProteinConverter()); - addAliasConverter(ReceptorProtein.class, new ProteinConverter()); - addAliasConverter(TruncatedProtein.class, new ProteinConverter()); - addAliasConverter(Degraded.class, new DegradedConverter()); - addAliasConverter(Complex.class, new ComplexConverter()); - addAliasConverter(SimpleMolecule.class, new SimpleMoleculeConverter()); - addAliasConverter(Drug.class, new DrugConverter()); - addAliasConverter(Ion.class, new IonConverter()); - addAliasConverter(Phenotype.class, new PhenotypeConverter()); - addAliasConverter(Rna.class, new RnaConverter()); - addAliasConverter(AntisenseRna.class, new AntisenseRnaConverter()); - addAliasConverter(Gene.class, new GeneConverter()); - addAliasConverter(Unknown.class, new UnknownConverter()); - - // for compartment aliases - addAliasConverter(SquareCompartment.class, new SquareCompartmentConverter()); - addAliasConverter(OvalCompartment.class, new OvalCompartmentConverter()); - addAliasConverter(PathwayCompartment.class, new ArtifitialCompartmentConverter()); - addAliasConverter(BottomSquareCompartment.class, new BottomSquareCompartmentConverter()); - addAliasConverter(TopSquareCompartment.class, new TopSquareCompartmentConverter()); - addAliasConverter(LeftSquareCompartment.class, new LeftSquareCompartmentConverter()); - addAliasConverter(RightSquareCompartment.class, new RightSquareCompartmentConverter()); - - } - - /** - * Method that set a converter for specific alias type. - * - * @param clazz - * class type of alias - * @param converter - * converter that should be used for conversion of this alias - */ - protected static void addAliasConverter(final Class<? extends Element> clazz, final IAliasConverter<?> converter) { - if (aliasConverters.get(clazz) != null) { - logger.warn("Converter for " + clazz + " has been already added"); - } - aliasConverters.put(clazz, converter); - } - - /** - * Returns a converter for given alias. If converter doesn't exist then null - * is returned. - * - * @param alias - * alias for which we are loooking for a converter - * @return converter that can be applied for the given alias; null if such - * converter doesn't exist - */ - private static IAliasConverter<? extends Element> getConverterForAlias(final Element alias) { - if (alias == null) { - throw new InvalidArgumentException("alias cannot be null"); - } - IAliasConverter<?> result = aliasConverters.get(alias.getClass()); - return result; - } - - // ******************************************************* - // - // NON-STATIC CLASS DEFINITION - // - // ******************************************************* - - /** - * Converter used for conversion of the alias given in constructor. - */ - @SuppressWarnings("rawtypes") - private IAliasConverter aliasConverter = null; - - /** - * Support constructor. Used in case of SBGN format display - * - * @param alias - * alias for which this converter will be used - * @param sbgnFormat - * boolean value indicating if SBGN display format should be used - */ - public AliasConverter(final Element alias, final boolean sbgnFormat) { - - // If alias is a nucleic acid feature to be displayed in SBGN - if (sbgnFormat && (alias instanceof AntisenseRna || alias instanceof Rna || alias instanceof Gene)) { - aliasConverter = new SBGNNucleicAcidFeatureConverter(); - } else { - // If not, at the beginning try to find an appropriate converter - aliasConverter = getConverterForAlias(alias); - } - - // if we don't know which converter to use then throw an exception - if (aliasConverter == null) { - throw new InvalidArgumentException("Unknown converter for class: " + alias.getClass() + ". Alias id: " + alias.getElementId()); - } - } - - /** - * Default constructor. - * - * @param alias - * alias for which this converter will be used - */ - public AliasConverter(final Element alias) { - this(alias, false); - } - - @SuppressWarnings("unchecked") - @Override - public void drawAlias(final Element alias, final Graphics2D graphics, final ConverterParams params) { - aliasConverter.drawAlias(alias, graphics, params); - } - - @SuppressWarnings("unchecked") - @Override - public void drawText(final Element compAlias, final Graphics2D graphics, final ConverterParams params) throws DrawingException { - aliasConverter.drawText(compAlias, graphics, params); - } - - @SuppressWarnings("unchecked") - @Override - public void drawAlias(Element alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas) { - aliasConverter.drawAlias(alias, graphics, params, visualizedLayoutsColorSchemas); - } -} diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/IAliasConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ElementConverter.java similarity index 86% rename from converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/IAliasConverter.java rename to converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ElementConverter.java index d06ea04b21b468695840450ee1b1ca3689a82188..d1992b796ce8c4c30531713a9f4e9451cfd89a05 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/IAliasConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ElementConverter.java @@ -15,7 +15,7 @@ import lcsb.mapviewer.model.map.species.Element; * @param <T> * class of alias to convert */ -public interface IAliasConverter<T extends Element> { +public interface ElementConverter<T extends Element> { /** * Alpha value (0..255) used for visualizing layout data that are normally * visualized in javascript. @@ -35,7 +35,7 @@ public interface IAliasConverter<T extends Element> { * {@link ConverterParams} * */ - void drawAlias(T alias, Graphics2D graphics, ConverterParams params); + void drawElement(T alias, Graphics2D graphics, ConverterParams params); /** * This function draw representation of the alias on the graphics object. @@ -53,7 +53,7 @@ public interface IAliasConverter<T extends Element> { * alias in different layouts that should be overlayed on the alias * */ - void drawAlias(T alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas); + void drawElement(T alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas); /** * This function will find proper font size to display text within it. Then it diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ElementConverterImpl.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ElementConverterImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e96615f6ef559df3540a69e0ad871d6760fa35bd --- /dev/null +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ElementConverterImpl.java @@ -0,0 +1,192 @@ +package lcsb.mapviewer.converter.graphics; + +import java.awt.Graphics2D; +import java.util.List; + +import org.apache.log4j.Logger; + +import lcsb.mapviewer.commands.ColorExtractor; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.common.exception.NotImplementedException; +import lcsb.mapviewer.converter.graphics.compartment.BottomSquareCompartmentConverter; +import lcsb.mapviewer.converter.graphics.compartment.LeftSquareCompartmentConverter; +import lcsb.mapviewer.converter.graphics.compartment.OvalCompartmentConverter; +import lcsb.mapviewer.converter.graphics.compartment.PathwayCompartmentConverter; +import lcsb.mapviewer.converter.graphics.compartment.RightSquareCompartmentConverter; +import lcsb.mapviewer.converter.graphics.compartment.SquareCompartmentConverter; +import lcsb.mapviewer.converter.graphics.compartment.TopSquareCompartmentConverter; +import lcsb.mapviewer.converter.graphics.species.AntisenseRnaConverter; +import lcsb.mapviewer.converter.graphics.species.ComplexConverter; +import lcsb.mapviewer.converter.graphics.species.DegradedConverter; +import lcsb.mapviewer.converter.graphics.species.DrugConverter; +import lcsb.mapviewer.converter.graphics.species.GeneConverter; +import lcsb.mapviewer.converter.graphics.species.IonConverter; +import lcsb.mapviewer.converter.graphics.species.PhenotypeConverter; +import lcsb.mapviewer.converter.graphics.species.ProteinConverter; +import lcsb.mapviewer.converter.graphics.species.RnaConverter; +import lcsb.mapviewer.converter.graphics.species.SBGNNucleicAcidFeatureConverter; +import lcsb.mapviewer.converter.graphics.species.SimpleMoleculeConverter; +import lcsb.mapviewer.converter.graphics.species.UnknownConverter; +import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment; +import lcsb.mapviewer.model.map.compartment.LeftSquareCompartment; +import lcsb.mapviewer.model.map.compartment.OvalCompartment; +import lcsb.mapviewer.model.map.compartment.PathwayCompartment; +import lcsb.mapviewer.model.map.compartment.RightSquareCompartment; +import lcsb.mapviewer.model.map.compartment.SquareCompartment; +import lcsb.mapviewer.model.map.compartment.TopSquareCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.AntisenseRna; +import lcsb.mapviewer.model.map.species.Complex; +import lcsb.mapviewer.model.map.species.Degraded; +import lcsb.mapviewer.model.map.species.Drug; +import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.map.species.Gene; +import lcsb.mapviewer.model.map.species.GenericProtein; +import lcsb.mapviewer.model.map.species.Ion; +import lcsb.mapviewer.model.map.species.IonChannelProtein; +import lcsb.mapviewer.model.map.species.Phenotype; +import lcsb.mapviewer.model.map.species.ReceptorProtein; +import lcsb.mapviewer.model.map.species.Rna; +import lcsb.mapviewer.model.map.species.SimpleMolecule; +import lcsb.mapviewer.model.map.species.TruncatedProtein; +import lcsb.mapviewer.model.map.species.Unknown; +import lcsb.mapviewer.modelutils.map.ElementUtils; + +/** + * This class is designed to convert any type of {@link Element} into a graphic + * glyph that will be visualized on the {@link Graphics2D} object. + * + * @author Piotr Gawron + * + */ +public class ElementConverterImpl implements ElementConverter<Element> { + + /** + * Default class logger. + */ + @SuppressWarnings("unused") + private static Logger logger = Logger.getLogger(ElementConverterImpl.class.getName()); + + /** + * Returns a converter for given element. If converter doesn't exist then + * exception is thrown. + * + * @param element + * {@link Element} for which we are loooking for a converter + * @param colorExtractor + * object that helps to convert overlay values into colors + * @return converter that can be applied for the given element + */ + private ElementConverter<? extends Element> getConverterForElement(Element element, ColorExtractor colorExtractor) { + if (element == null) { + throw new InvalidArgumentException("element cannot be null"); + } + if (element instanceof GenericProtein) { + return new ProteinConverter(colorExtractor); + } else if (element instanceof IonChannelProtein) { + return new ProteinConverter(colorExtractor); + } else if (element instanceof ReceptorProtein) { + return new ProteinConverter(colorExtractor); + } else if (element instanceof TruncatedProtein) { + return new ProteinConverter(colorExtractor); + } else if (element instanceof Degraded) { + return new DegradedConverter(colorExtractor); + } else if (element instanceof Complex) { + return new ComplexConverter(colorExtractor); + } else if (element instanceof SimpleMolecule) { + return new SimpleMoleculeConverter(colorExtractor); + } else if (element instanceof Drug) { + return new DrugConverter(colorExtractor); + } else if (element instanceof Ion) { + return new IonConverter(colorExtractor); + } else if (element instanceof Phenotype) { + return new PhenotypeConverter(colorExtractor); + } else if (element instanceof Rna) { + return new RnaConverter(colorExtractor); + } else if (element instanceof AntisenseRna) { + return new AntisenseRnaConverter(colorExtractor); + } else if (element instanceof Gene) { + return new GeneConverter(colorExtractor); + } else if (element instanceof Unknown) { + return new UnknownConverter(colorExtractor); + } else if (element instanceof SquareCompartment) { + return new SquareCompartmentConverter(colorExtractor); + } else if (element instanceof OvalCompartment) { + return new OvalCompartmentConverter(colorExtractor); + } else if (element instanceof PathwayCompartment) { + return new PathwayCompartmentConverter(colorExtractor); + } else if (element instanceof BottomSquareCompartment) { + return new BottomSquareCompartmentConverter(colorExtractor); + } else if (element instanceof TopSquareCompartment) { + return new TopSquareCompartmentConverter(colorExtractor); + } else if (element instanceof LeftSquareCompartment) { + return new LeftSquareCompartmentConverter(colorExtractor); + } else if (element instanceof RightSquareCompartment) { + return new RightSquareCompartmentConverter(colorExtractor); + } else { + throw new NotImplementedException(new ElementUtils().getElementTag(element) + "Unknown element class"); + } + } + + /** + * Converter used for conversion of the {@link Element} given in constructor. + */ + @SuppressWarnings("rawtypes") + private ElementConverter elementConverter = null; + + /** + * Support constructor. Used in case of SBGN format display + * + * @param element + * {@link Element} for which this converter will be used + * @param colorExtractor + * object that helps to convert overlay values into colors + * @param sbgnFormat + * boolean value indicating if SBGN display format should be used + */ + public ElementConverterImpl(final Element element, final boolean sbgnFormat, ColorExtractor colorExtractor) { + + // If element is a nucleic acid feature to be displayed in SBGN + if (sbgnFormat && (element instanceof AntisenseRna || element instanceof Rna || element instanceof Gene)) { + elementConverter = new SBGNNucleicAcidFeatureConverter(colorExtractor); + } else { + // If not, at the beginning try to find an appropriate converter + elementConverter = getConverterForElement(element, colorExtractor); + } + + // if we don't know which converter to use then throw an exception + if (elementConverter == null) { + throw new InvalidArgumentException("Unknown converter for class: " + element.getClass() + ". Element id: " + element.getElementId()); + } + } + + /** + * Default constructor. + * + * @param colorExtractor + * object that helps to convert overlay values into colors + * @param element + * {@link Element} for which this converter will be used + */ + public ElementConverterImpl(final Element element, ColorExtractor colorExtractor) { + this(element, false, colorExtractor); + } + + @SuppressWarnings("unchecked") + @Override + public void drawElement(final Element element, final Graphics2D graphics, final ConverterParams params) { + elementConverter.drawElement(element, graphics, params); + } + + @SuppressWarnings("unchecked") + @Override + public void drawText(final Element element, final Graphics2D graphics, final ConverterParams params) throws DrawingException { + elementConverter.drawText(element, graphics, params); + } + + @SuppressWarnings("unchecked") + @Override + public void drawElement(Element element, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas) { + elementConverter.drawElement(element, graphics, params, visualizedLayoutsColorSchemas); + } +} diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ImageGenerators.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ImageGenerators.java index 6c244b13891361d1139e88140ad0a512e502102d..9498239a8b6119e74b3b51136d462066af9f336a 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ImageGenerators.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ImageGenerators.java @@ -1,172 +1,173 @@ -package lcsb.mapviewer.converter.graphics; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.log4j.Logger; - -import lcsb.mapviewer.common.MimeType; -import lcsb.mapviewer.common.Pair; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.common.exception.InvalidStateException; -import lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.model.ModelFullIndexed; - -/** - * This class is a util class containing information about all currently - * available implementations of {@link AbstractImageGenerator} class. - * - * @author Piotr Gawron - * - */ -public class ImageGenerators { - /** - * Default class logger. - */ - @SuppressWarnings("unused") - private final Logger logger = Logger.getLogger(ImageGenerators.class); - /** - * List of {@link AbstractImageGenerator} classes available in the system. - */ - private List<Pair<String, Class<? extends AbstractImageGenerator>>> availableGenerators; - - /** - * List of all possible objects extending {@link AbstractImageGenerator} - * interface that are available in the system. - */ - private List<AbstractImageGenerator> generatorInstances = null; - - /** - * Default constructor. - */ - public ImageGenerators() { - try { - availableGenerators = new ArrayList<Pair<String, Class<? extends AbstractImageGenerator>>>(); - Model model = new ModelFullIndexed(null); - AbstractImageGenerator.Params params = new AbstractImageGenerator.Params().// - model(model).// - width(1).// - height(1); - generatorInstances = new ArrayList<>(); - generatorInstances.add(new PngImageGenerator(params)); - generatorInstances.add(new PdfImageGenerator(params)); -// generatorInstances.add(new SvgImageGenerator(params)); -// generatorInstances.add(new JpgImageGenerator(params)); - for (AbstractImageGenerator abstractImageGenerator : generatorInstances) { - availableGenerators.add(new Pair<String, Class<? extends AbstractImageGenerator>>(abstractImageGenerator.getFormatName(), abstractImageGenerator - .getClass())); - } - - } catch (DrawingException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } - } - - /** - * Returns {@link #availableGenerators}. - * - * @return {@link #availableGenerators} - */ - public List<Pair<String, Class<? extends AbstractImageGenerator>>> getAvailableImageGenerators() { - return availableGenerators; - } - - /** - * Generates image and saves it to a file. - * - * @param generatorClass - * which {@link AbstractImageGenerator} should be used to generate an - * image - * @param params - * parameters of the image generation process (scaling, size, - * nesting, etc) - * @param filename - * name of the file where result should be saved - * @return {@link MimeType} of the generated object - * @throws IOException - * thrown when there is a problem with output file - */ - public MimeType generate(Class<? extends AbstractImageGenerator> generatorClass, AbstractImageGenerator.Params params, String filename) throws IOException { - try { - AbstractImageGenerator generator = generatorClass.getConstructor(AbstractImageGenerator.Params.class).newInstance(params); - generator.saveToFile(filename); - return generator.getMimeType(); - } catch (InstantiationException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } catch (IllegalAccessException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } catch (IllegalArgumentException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } catch (InvocationTargetException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } catch (NoSuchMethodException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } catch (SecurityException e) { - throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); - } - } - - /** - * Generates image and saves it to a file. - * - * @param generatorClass - * name of the {@link AbstractImageGenerator} implementation that - * should be used to generate an image - * @param params - * parameters of the image generation process (scaling, size, - * nesting, etc) - * @param filename - * name of the file where result should be saved - * @return {@link MimeType} of the generated object - * @throws IOException - * thrown when there is a problem with output file - */ - public MimeType generate(String generatorClass, Params params, String filename) throws IOException { - for (Pair<String, Class<? extends AbstractImageGenerator>> element : availableGenerators) { - if (element.getRight().getCanonicalName().equals(generatorClass)) { - return generate(element.getRight(), params, filename); - } - } - throw new InvalidArgumentException("Unknown class type: " + generatorClass); - - } - - /** - * Returns file extension that should be used for files generated by - * implementation of {@link AbstractImageGenerator} class. - * - * @param generatorClass - * name of the class that extends {@link AbstractImageGenerator} - * @return file extension that should be used for files generated by - * implementation of {@link AbstractImageGenerator} class - */ - public String getExtension(String generatorClass) { - for (Pair<String, Class<? extends AbstractImageGenerator>> element : availableGenerators) { - if (element.getRight().getCanonicalName().equals(generatorClass)) { - return getExtension(element.getRight()); - } - } - throw new InvalidArgumentException("Unknown class type: " + generatorClass); - } - - /** - * Returns file extension that should be used for files generated by - * implementation of {@link AbstractImageGenerator} class. - * - * @param generatorClass - * class that extends {@link AbstractImageGenerator} - * @return file extension that should be used for files generated by - * implementation of {@link AbstractImageGenerator} class - */ - public String getExtension(Class<? extends AbstractImageGenerator> generatorClass) { - for (AbstractImageGenerator imageGenerator : generatorInstances) { - if (generatorClass.isAssignableFrom(imageGenerator.getClass())) { - return imageGenerator.getFileExtension(); - } - } - throw new InvalidArgumentException("Unknown class type: " + generatorClass); - } -} +package lcsb.mapviewer.converter.graphics; + +import java.awt.Color; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.log4j.Logger; + +import lcsb.mapviewer.common.MimeType; +import lcsb.mapviewer.common.Pair; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.common.exception.InvalidStateException; +import lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelFullIndexed; + +/** + * This class is a util class containing information about all currently + * available implementations of {@link AbstractImageGenerator} class. + * + * @author Piotr Gawron + * + */ +public class ImageGenerators { + /** + * Default class logger. + */ + @SuppressWarnings("unused") + private final Logger logger = Logger.getLogger(ImageGenerators.class); + /** + * List of {@link AbstractImageGenerator} classes available in the system. + */ + private List<Pair<String, Class<? extends AbstractImageGenerator>>> availableGenerators; + + /** + * List of all possible objects extending {@link AbstractImageGenerator} + * interface that are available in the system. + */ + private List<AbstractImageGenerator> generatorInstances = null; + + /** + * Default constructor. + */ + public ImageGenerators() { + try { + availableGenerators = new ArrayList<Pair<String, Class<? extends AbstractImageGenerator>>>(); + Model model = new ModelFullIndexed(null); + AbstractImageGenerator.Params params = new AbstractImageGenerator.Params().// + model(model).// + width(1).// + minColor(Color.WHITE).maxColor(Color.WHITE).height(1); + generatorInstances = new ArrayList<>(); + generatorInstances.add(new PngImageGenerator(params)); + generatorInstances.add(new PdfImageGenerator(params)); + // generatorInstances.add(new SvgImageGenerator(params)); + // generatorInstances.add(new JpgImageGenerator(params)); + for (AbstractImageGenerator abstractImageGenerator : generatorInstances) { + availableGenerators + .add(new Pair<String, Class<? extends AbstractImageGenerator>>(abstractImageGenerator.getFormatName(), abstractImageGenerator.getClass())); + } + + } catch (DrawingException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } + } + + /** + * Returns {@link #availableGenerators}. + * + * @return {@link #availableGenerators} + */ + public List<Pair<String, Class<? extends AbstractImageGenerator>>> getAvailableImageGenerators() { + return availableGenerators; + } + + /** + * Generates image and saves it to a file. + * + * @param generatorClass + * which {@link AbstractImageGenerator} should be used to generate an + * image + * @param params + * parameters of the image generation process (scaling, size, + * nesting, etc) + * @param filename + * name of the file where result should be saved + * @return {@link MimeType} of the generated object + * @throws IOException + * thrown when there is a problem with output file + */ + public MimeType generate(Class<? extends AbstractImageGenerator> generatorClass, AbstractImageGenerator.Params params, String filename) throws IOException { + try { + AbstractImageGenerator generator = generatorClass.getConstructor(AbstractImageGenerator.Params.class).newInstance(params); + generator.saveToFile(filename); + return generator.getMimeType(); + } catch (InstantiationException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } catch (IllegalAccessException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } catch (IllegalArgumentException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } catch (InvocationTargetException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } catch (NoSuchMethodException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } catch (SecurityException e) { + throw new InvalidStateException("Problem with ImageGenarater instance creation...", e); + } + } + + /** + * Generates image and saves it to a file. + * + * @param generatorClass + * name of the {@link AbstractImageGenerator} implementation that + * should be used to generate an image + * @param params + * parameters of the image generation process (scaling, size, + * nesting, etc) + * @param filename + * name of the file where result should be saved + * @return {@link MimeType} of the generated object + * @throws IOException + * thrown when there is a problem with output file + */ + public MimeType generate(String generatorClass, Params params, String filename) throws IOException { + for (Pair<String, Class<? extends AbstractImageGenerator>> element : availableGenerators) { + if (element.getRight().getCanonicalName().equals(generatorClass)) { + return generate(element.getRight(), params, filename); + } + } + throw new InvalidArgumentException("Unknown class type: " + generatorClass); + + } + + /** + * Returns file extension that should be used for files generated by + * implementation of {@link AbstractImageGenerator} class. + * + * @param generatorClass + * name of the class that extends {@link AbstractImageGenerator} + * @return file extension that should be used for files generated by + * implementation of {@link AbstractImageGenerator} class + */ + public String getExtension(String generatorClass) { + for (Pair<String, Class<? extends AbstractImageGenerator>> element : availableGenerators) { + if (element.getRight().getCanonicalName().equals(generatorClass)) { + return getExtension(element.getRight()); + } + } + throw new InvalidArgumentException("Unknown class type: " + generatorClass); + } + + /** + * Returns file extension that should be used for files generated by + * implementation of {@link AbstractImageGenerator} class. + * + * @param generatorClass + * class that extends {@link AbstractImageGenerator} + * @return file extension that should be used for files generated by + * implementation of {@link AbstractImageGenerator} class + */ + public String getExtension(Class<? extends AbstractImageGenerator> generatorClass) { + for (AbstractImageGenerator imageGenerator : generatorInstances) { + if (generatorClass.isAssignableFrom(imageGenerator.getClass())) { + return imageGenerator.getFileExtension(); + } + } + throw new InvalidArgumentException("Unknown class type: " + generatorClass); + } +} diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/BottomSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/BottomSquareCompartmentConverter.java index 25d9cdd4f3a5f8996c28ad3132986912046a1ede..07087ec3cda0e74b620bdda4b2b59ed1a0e90fe5 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/BottomSquareCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/BottomSquareCompartmentConverter.java @@ -9,9 +9,12 @@ import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.Species; import org.apache.log4j.Logger; @@ -29,8 +32,19 @@ public class BottomSquareCompartmentConverter extends CompartmentConverter<Botto @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(BottomSquareCompartmentConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public BottomSquareCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final BottomSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final BottomSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { // keep the old values of colors and line Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/CompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/CompartmentConverter.java index 0c13be576a94d63084d3ce6c71666edb38080af4..ce31fb93bb7d3440fb7c0aeb93c28c7a37cc4e09 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/CompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/CompartmentConverter.java @@ -8,12 +8,13 @@ import java.util.List; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.geometry.EllipseTransformation; import lcsb.mapviewer.common.geometry.LineTransformation; import lcsb.mapviewer.converter.graphics.ConverterParams; -import lcsb.mapviewer.converter.graphics.IAliasConverter; +import lcsb.mapviewer.converter.graphics.ElementConverter; import lcsb.mapviewer.converter.graphics.geometry.FontFinder; import lcsb.mapviewer.converter.graphics.geometry.RectangleTooSmallException; import lcsb.mapviewer.converter.graphics.placefinder.PlaceFinder; @@ -30,7 +31,7 @@ import lcsb.mapviewer.model.map.layout.ColorSchema; * class for which the comparator is created * */ -public abstract class CompartmentConverter<T extends Compartment> implements IAliasConverter<T> { +public abstract class CompartmentConverter<T extends Compartment> implements ElementConverter<T> { /** * Default class logger. @@ -79,9 +80,20 @@ public abstract class CompartmentConverter<T extends Compartment> implements IAl private String placeFinderSynchronization = ""; /** - * Default constructor. + * Object that helps to convert {@link ColorSchema} values into colors. */ - protected CompartmentConverter() { + private ColorExtractor colorExtractor; + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing elements + * + */ + protected CompartmentConverter(ColorExtractor colorExtractor) { + this.colorExtractor = colorExtractor; }; @Override @@ -163,8 +175,8 @@ public abstract class CompartmentConverter<T extends Compartment> implements IAl } @Override - public void drawAlias(T alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas) { - drawAlias(alias, graphics, params); + public void drawElement(T alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas) { + drawElement(alias, graphics, params); Color oldColor = graphics.getColor(); int count = 0; @@ -177,7 +189,7 @@ public abstract class CompartmentConverter<T extends Compartment> implements IAl int x = (int) (startX * alias.getWidth() + alias.getX()); graphics.drawRect(x, alias.getY().intValue(), (int) width, alias.getHeight().intValue()); - Color color = schema.getNormalizedColor(); + Color color = colorExtractor.getNormalizedColor(schema); Color bgAlphaColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), LAYOUT_ALPHA); graphics.setColor(bgAlphaColor); graphics.fillRect(x, alias.getY().intValue(), (int) width, alias.getHeight().intValue()); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/LeftSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/LeftSquareCompartmentConverter.java index 5d3f1a7fa506f6c6fe4d03091ba87469fb5ee1ce..a3cac76c0bfe0a722fcc95c45f004c942ce9431e 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/LeftSquareCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/LeftSquareCompartmentConverter.java @@ -9,9 +9,11 @@ import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.LeftSquareCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; import org.apache.log4j.Logger; @@ -22,14 +24,27 @@ import org.apache.log4j.Logger; * */ public class LeftSquareCompartmentConverter extends CompartmentConverter<LeftSquareCompartment> { + /** * Default class logger. */ @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(LeftSquareCompartmentConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing elements + * + */ + public LeftSquareCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final LeftSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final LeftSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { // keep the old values of color and line type Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/OvalCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/OvalCompartmentConverter.java index e13e233558f04ca5a2d5562c2e8e1896a5ddb00a..3c385168fb6c31a65aa5eff8c7e1873afa43b57d 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/OvalCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/OvalCompartmentConverter.java @@ -8,10 +8,13 @@ import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Point2D; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.OvalCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.map.species.Species; /** * Class responsible for drawing OvalCompartment on the Graphics2D. @@ -21,6 +24,17 @@ import lcsb.mapviewer.model.map.species.Element; */ public class OvalCompartmentConverter extends CompartmentConverter<OvalCompartment> { + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public OvalCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + /** * Returns shape representing alias. * @@ -33,7 +47,7 @@ public class OvalCompartmentConverter extends CompartmentConverter<OvalCompartme } @Override - public void drawAlias(final OvalCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final OvalCompartment alias, final Graphics2D graphics, final ConverterParams params) { // keep the old values of color and line type Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/ArtifitialCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/PathwayCompartmentConverter.java similarity index 64% rename from converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/ArtifitialCompartmentConverter.java rename to converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/PathwayCompartmentConverter.java index 17dd4f37e2730f74b23630eb67a559ca80999e8c..a3d6fd00ffdb31571a81b3acd9e92cc60a7c9554 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/ArtifitialCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/PathwayCompartmentConverter.java @@ -7,24 +7,40 @@ import java.awt.Stroke; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.PathwayCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.Species; /** - * This class allows to draw ArtifitialCompartment on the Graphics2D class. + * This class allows to draw {@link PathwayCompartment} on the + * {@link Graphics2D} class. * * @author Piotr Gawron * */ -public class ArtifitialCompartmentConverter extends CompartmentConverter<PathwayCompartment> { +public class PathwayCompartmentConverter extends CompartmentConverter<PathwayCompartment> { + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public PathwayCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + /** * Background color of drawn compartments. */ - private Color backgroundColor = Color.LIGHT_GRAY; + private Color backgroundColor = Color.LIGHT_GRAY; @Override - public void drawAlias(final PathwayCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final PathwayCompartment alias, final Graphics2D graphics, final ConverterParams params) { // keep the old values of colors and line Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/RightSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/RightSquareCompartmentConverter.java index 5fa37bec8fa4d36d78c84b0e93c7394ae680bb4c..72099129b6492cce9758c90f0e32d4e25c0d44cf 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/RightSquareCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/RightSquareCompartmentConverter.java @@ -9,9 +9,12 @@ import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.RightSquareCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.Species; import org.apache.log4j.Logger; @@ -22,14 +25,26 @@ import org.apache.log4j.Logger; * */ public class RightSquareCompartmentConverter extends CompartmentConverter<RightSquareCompartment> { + /** * Default class logger. */ @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(RightSquareCompartmentConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public RightSquareCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final RightSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final RightSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { // keep the old values of color and line type Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/SquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/SquareCompartmentConverter.java index d07657464f021191aebafcdb57b7ca17e1064997..e67b330c239c03743dc7cb27accd089e80a8efc3 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/SquareCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/SquareCompartmentConverter.java @@ -8,12 +8,15 @@ import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; +import org.apache.log4j.Logger; + +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.SquareCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; - -import org.apache.log4j.Logger; +import lcsb.mapviewer.model.map.species.Species; /** * Class responsible for drawing SquareCompartment on the Graphics2D. @@ -26,12 +29,23 @@ public class SquareCompartmentConverter extends CompartmentConverter<SquareCompa * How big is the arc in the corner of rectangle that represents square * compartment. */ - private static final int RECTANGLE_CORNER_ARC_SIZE = 20; + private static final int RECTANGLE_CORNER_ARC_SIZE = 20; /** * Default class logger. */ @SuppressWarnings("unused") - private static Logger logger = Logger.getLogger(SquareCompartmentConverter.class.getName()); + private static Logger logger = Logger.getLogger(SquareCompartmentConverter.class.getName()); + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public SquareCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } /** * Returns shape representing alias. @@ -45,7 +59,7 @@ public class SquareCompartmentConverter extends CompartmentConverter<SquareCompa } @Override - public void drawAlias(final SquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final SquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { // keep the old values of color and line type Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/TopSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/TopSquareCompartmentConverter.java index afc5febcff0fffa9647abe7febc0809f126f12a6..b074e084f5a04ee262d697be3c8896df9cf3f0fc 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/TopSquareCompartmentConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/compartment/TopSquareCompartmentConverter.java @@ -9,9 +9,12 @@ import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.compartment.TopSquareCompartment; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.Species; import org.apache.log4j.Logger; @@ -29,8 +32,19 @@ public class TopSquareCompartmentConverter extends CompartmentConverter<TopSquar @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(TopSquareCompartmentConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public TopSquareCompartmentConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final TopSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final TopSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) { Color oldColor = graphics.getColor(); Stroke oldStroke = graphics.getStroke(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverter.java index 37120db85f0dd98fed970070fd5e19423ab39586..2697266eb836e792f109627dfb8afde82d028b29 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverter.java @@ -13,6 +13,7 @@ import java.util.List; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.Pair; import lcsb.mapviewer.common.geometry.LineTransformation; import lcsb.mapviewer.common.geometry.PointTransformation; @@ -102,12 +103,22 @@ public class ReactionConverter { */ private PointTransformation pointTransformation = new PointTransformation(); + /** + * Object that helps to convert {@link ColorSchema} values into colors. + */ + private ColorExtractor colorExtractor; + /** * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Reaction} */ - public ReactionConverter() { + public ReactionConverter(ColorExtractor colorExtractor) { super(); descFont = new Font(Font.SANS_SERIF, Font.BOLD, DESCRIPTION_FONT_SIZE); + this.colorExtractor = colorExtractor; } /** @@ -273,7 +284,7 @@ public class ReactionConverter { private void applyColorSchema(Reaction reaction, ColorSchema colorSchema) { for (AbstractNode node : reaction.getNodes()) { PolylineData pd = new PolylineData(node.getLine()); - pd.setColor(colorSchema.getNormalizedColor()); + pd.setColor(colorExtractor.getNormalizedColor(colorSchema)); if (colorSchema.getLineWidth() != null) { pd.setWidth(colorSchema.getLineWidth()); } diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/AntisenseRnaConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/AntisenseRnaConverter.java index 1bbb52b6c37c1fda1d805179078cef5cf06b85af..acc16bc98c697e1728e5f007131d20e9e1fc7698 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/AntisenseRnaConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/AntisenseRnaConverter.java @@ -13,8 +13,11 @@ import java.awt.geom.Point2D; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.AntisenseRna; import lcsb.mapviewer.model.map.species.field.AntisenseRnaRegion; import lcsb.mapviewer.model.map.species.field.ModificationState; @@ -34,8 +37,20 @@ public class AntisenseRnaConverter extends SpeciesConverter<AntisenseRna> { @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(AntisenseRnaConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public AntisenseRnaConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + + @Override - public void drawAlias(final AntisenseRna alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final AntisenseRna alias, final Graphics2D graphics, final ConverterParams params) { GeneralPath path = getAntisenseRnaPath(alias); Color c = graphics.getColor(); graphics.setColor(alias.getColor()); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ComplexConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ComplexConverter.java index ac517c50d6d1055edb7b6acd090f136224062e1a..6a59e89cc68ad9229d7118f5df8ebefaac3a4695 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ComplexConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ComplexConverter.java @@ -11,11 +11,14 @@ import java.awt.geom.PathIterator; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.converter.graphics.geometry.FontFinder; import lcsb.mapviewer.converter.graphics.geometry.RectangleTooSmallException; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Complex; /** @@ -42,8 +45,20 @@ public class ComplexConverter extends SpeciesConverter<Complex> { */ private static Logger logger = Logger.getLogger(ComplexConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public ComplexConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + + @Override - public void drawAlias(final Complex alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final Complex alias, final Graphics2D graphics, final ConverterParams params) { if (alias.getState().equalsIgnoreCase("complexnoborder")) { return; } diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DegradedConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DegradedConverter.java index 44c0b254b2033e89cbdfe47bc0ebb7c53673738c..de6bcebb35da9439fd6481b637120d3c3532410d 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DegradedConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DegradedConverter.java @@ -9,13 +9,16 @@ import java.awt.geom.GeneralPath; import java.awt.geom.Path2D; import java.awt.geom.PathIterator; +import org.apache.log4j.Logger; + +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.Degraded; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; -import org.apache.log4j.Logger; - /** * This class defines methods used for drawing Degraded SpeciesAlias on the * graphics2d object. @@ -23,19 +26,31 @@ import org.apache.log4j.Logger; * @author Piotr Gawron * */ -public class DegradedConverter extends SpeciesConverter<Species> { +public class DegradedConverter extends SpeciesConverter<Degraded> { /** * Part of height of the line used to cross degraded circle that goes behind * this circle. */ - private static final int CROSS_LINE_EXTENDED_LENGTH = 7; + private static final int CROSS_LINE_EXTENDED_LENGTH = 7; + /** * Default class logger. */ - private static Logger logger = Logger.getLogger(DegradedConverter.class.getName()); + private static Logger logger = Logger.getLogger(DegradedConverter.class.getName()); + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public DegradedConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } @Override - public void drawAlias(final Species alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final Degraded alias, final Graphics2D graphics, final ConverterParams params) { double diameter = getDiameter(alias); double x = getXCoord(alias, diameter); double y = getYCoord(alias); @@ -109,12 +124,12 @@ public class DegradedConverter extends SpeciesConverter<Species> { } @Override - public String getText(final Species alias) { + public String getText(Degraded alias) { return ""; } @Override - public PathIterator getBoundPathIterator(final Species alias) { + public PathIterator getBoundPathIterator(Degraded alias) { throw new InvalidStateException("This class doesn't have bound"); } diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DrugConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DrugConverter.java index f737787cac91a953f5a6f8091c0035d73f03f50f..f55cf04258bfecf782c8c28dd94e6fddad6b9fc8 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DrugConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/DrugConverter.java @@ -10,7 +10,10 @@ import java.awt.geom.Point2D; import java.awt.geom.RoundRectangle2D; import java.util.ArrayList; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; +import lcsb.mapviewer.model.map.species.Drug; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; @@ -23,22 +26,36 @@ import org.apache.log4j.Logger; * @author Piotr Gawron * */ -public class DrugConverter extends SpeciesConverter<Species> { +public class DrugConverter extends SpeciesConverter<Drug> { + /** * Distance between internal and external border of drug graphical * representation. */ private static final int OFFSET_BETWEEN_BORDERS = 4; + /** * How big should be the arc in rectangle for drug representation. */ private static final int RECTANGLE_CORNER_ARC_SIZE = 40; + /** * Default class logger. */ @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(DrugConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public DrugConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + /** * Returns shape of the Drug . * @@ -51,7 +68,7 @@ public class DrugConverter extends SpeciesConverter<Species> { } @Override - public void drawAlias(final Species alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(Drug alias, final Graphics2D graphics, final ConverterParams params) { Shape a1 = getDrugShape(alias); double offset = OFFSET_BETWEEN_BORDERS; Shape a2 = new RoundRectangle2D.Double( @@ -99,7 +116,7 @@ public class DrugConverter extends SpeciesConverter<Species> { } @Override - public PathIterator getBoundPathIterator(final Species alias) { + public PathIterator getBoundPathIterator(Drug alias) { return getDrugShape(alias).getPathIterator(new AffineTransform()); } diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/GeneConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/GeneConverter.java index 195dd99d7c0a7ff240785f6e204065c75847f6f4..f5493ee149bf9f9270bc0b25eeb205ca0bcf3b2b 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/GeneConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/GeneConverter.java @@ -13,9 +13,12 @@ import java.awt.geom.Point2D; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Gene; +import lcsb.mapviewer.model.map.species.Species; import lcsb.mapviewer.model.map.species.field.ModificationResidue; import lcsb.mapviewer.model.map.species.field.ModificationState; @@ -33,8 +36,19 @@ public class GeneConverter extends SpeciesConverter<Gene> { @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(GeneConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public GeneConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final Gene alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final Gene alias, final Graphics2D graphics, final ConverterParams params) { Shape shape = getGeneShape(alias); Color c = graphics.getColor(); graphics.setColor(alias.getColor()); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/IonConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/IonConverter.java index 34f5a147c07650ed66011f25c5da64944307be88..fe8699ac7232e1d7468cc45a52834fb9c2309c89 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/IonConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/IonConverter.java @@ -8,29 +8,44 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; +import org.apache.log4j.Logger; + +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; +import lcsb.mapviewer.model.map.species.Ion; import lcsb.mapviewer.model.map.species.Species; -import org.apache.log4j.Logger; - /** * This class defines methods used for drawing SpeciesAlias of - * {@link lcsb.mapviewer.converter.model.celldesigner.structure.db.model.map.species.Ion Ion} on the {@link Graphics2D} - * object. + * {@link lcsb.mapviewer.converter.model.celldesigner.structure.db.model.map.species.Ion + * Ion} on the {@link Graphics2D} object. * * @author Piotr Gawron * */ -public class IonConverter extends SpeciesConverter<Species> { +public class IonConverter extends SpeciesConverter<Ion> { + /** * Default class logger. */ - private static Logger logger = Logger.getLogger(IonConverter.class.getName()); + private static Logger logger = Logger.getLogger(IonConverter.class.getName()); + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public IonConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } @Override - public void drawAlias(final Species alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(Ion alias, final Graphics2D graphics, final ConverterParams params) { double diameter = getDiameter(alias); double x = getXCoord(alias, diameter); double y = getYCoord(alias); @@ -90,12 +105,12 @@ public class IonConverter extends SpeciesConverter<Species> { } @Override - public PathIterator getBoundPathIterator(final Species alias) { + public PathIterator getBoundPathIterator(Ion alias) { throw new InvalidStateException("This class doesn't have bound"); } @Override - public Point2D getPointCoordinatesOnBorder(final Species alias, final double angle) { + public Point2D getPointCoordinatesOnBorder(Ion alias, final double angle) { if (alias.getWidth() == 0 && alias.getHeight() == 0) { logger.warn("Looking for coordinates for the alias with 0 size"); return alias.getCenter(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/PhenotypeConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/PhenotypeConverter.java index 6dba03ff813dfab8eedbcf7a481e5a3ab5c191e2..4ca043e2104412058387ac522854ba0350a028f6 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/PhenotypeConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/PhenotypeConverter.java @@ -8,29 +8,43 @@ import java.awt.geom.GeneralPath; import java.awt.geom.Path2D; import java.awt.geom.PathIterator; +import org.apache.log4j.Logger; + +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; -import lcsb.mapviewer.model.map.species.Species; - -import org.apache.log4j.Logger; +import lcsb.mapviewer.model.map.species.Phenotype; /** * This class defines methods used for drawing SpeciesAlias of - * {@link lcsb.mapviewer.converter.model.celldesigner.structure.db.model.map.species.Phenotype Phenotype} on the - * {@link Graphics2D} object. + * {@link lcsb.mapviewer.converter.model.celldesigner.structure.db.model.map.species.Phenotype + * Phenotype} on the {@link Graphics2D} object. * * @author Piotr Gawron * */ -public class PhenotypeConverter extends SpeciesConverter<Species> { +public class PhenotypeConverter extends SpeciesConverter<Phenotype> { /** * Default class logger. */ @SuppressWarnings("unused") - private static Logger logger = Logger.getLogger(PhenotypeConverter.class.getName()); + private static Logger logger = Logger.getLogger(PhenotypeConverter.class.getName()); + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing elements + * + */ + public PhenotypeConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } @Override - public void drawAlias(final Species alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(Phenotype alias, final Graphics2D graphics, final ConverterParams params) { GeneralPath path = getPhenotypePath(alias); Color c = graphics.getColor(); @@ -66,7 +80,7 @@ public class PhenotypeConverter extends SpeciesConverter<Species> { } @Override - public PathIterator getBoundPathIterator(final Species alias) { + public PathIterator getBoundPathIterator(Phenotype alias) { return getPhenotypePath(alias).getPathIterator(new AffineTransform()); } diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ProteinConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ProteinConverter.java index 4940e5d439bfb89945ccdecee6ba3fb5ad8f49df..b3af8c09cb91bea6ed909a61ab5a3a002e12a1c3 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ProteinConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/ProteinConverter.java @@ -17,10 +17,12 @@ import java.util.ArrayList; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.GenericProtein; import lcsb.mapviewer.model.map.species.IonChannelProtein; @@ -40,6 +42,7 @@ import lcsb.mapviewer.modelutils.map.ElementUtils; * */ public class ProteinConverter extends SpeciesConverter<Protein> { + /** * Width of the ion part in the open channel representation. */ @@ -63,6 +66,17 @@ public class ProteinConverter extends SpeciesConverter<Protein> { */ private ElementUtils eu = new ElementUtils(); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public ProteinConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + /** * Returns shape of generic protein. * @@ -75,7 +89,7 @@ public class ProteinConverter extends SpeciesConverter<Protein> { } @Override - public void drawAlias(final Protein alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final Protein alias, final Graphics2D graphics, final ConverterParams params) { // Local variable setting the SBGN visualization boolean sbgnFormat = params.isSbgnFormat(); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/RnaConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/RnaConverter.java index 67e92e517fb18929070a49930720d2b0a90453c4..6b13ac398f659d0b965f6f2d8797e720511443e4 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/RnaConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/RnaConverter.java @@ -1,3 +1,10 @@ + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ package lcsb.mapviewer.converter.graphics.species; import java.awt.Color; @@ -13,9 +20,12 @@ import java.awt.geom.Point2D; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Rna; +import lcsb.mapviewer.model.map.species.Species; import lcsb.mapviewer.model.map.species.field.ModificationState; import lcsb.mapviewer.model.map.species.field.RnaRegion; @@ -33,8 +43,19 @@ public class RnaConverter extends SpeciesConverter<Rna> { @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(RnaConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public RnaConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final Rna alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final Rna alias, final Graphics2D graphics, final ConverterParams params) { GeneralPath path = getRnaPath(alias); Color c = graphics.getColor(); graphics.setColor(alias.getColor()); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SBGNNucleicAcidFeatureConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SBGNNucleicAcidFeatureConverter.java index 00048fa5567e150811d9ee8296200b2186fe9f8f..8dc25a7ffdc7ca1c1062f006dcc39fc15f75612b 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SBGNNucleicAcidFeatureConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SBGNNucleicAcidFeatureConverter.java @@ -8,7 +8,9 @@ import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; @@ -28,6 +30,17 @@ public class SBGNNucleicAcidFeatureConverter extends SpeciesConverter<Species> { */ private static final int RECTANGLE_CORNER_ARC_SIZE = 5; + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public SBGNNucleicAcidFeatureConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + /** * Returns shape of SBGN Nucleic acid feature. * @@ -51,7 +64,7 @@ public class SBGNNucleicAcidFeatureConverter extends SpeciesConverter<Species> { } @Override - public void drawAlias(Species alias, Graphics2D graphics, ConverterParams params) { + public void drawElement(Species alias, Graphics2D graphics, ConverterParams params) { // Unit of information text - multimer cardinality String unitOfInformationText = null; if (alias.getStatePrefix() != null && alias.getStateLabel() != null) { diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SimpleMoleculeConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SimpleMoleculeConverter.java index 4825edbcbf2efdd98de61165da1f7664898824e0..ca287bfc971da7cc9ab21e0174bc187887b99543 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SimpleMoleculeConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SimpleMoleculeConverter.java @@ -10,9 +10,12 @@ import java.awt.geom.Point2D; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.graphics.ConverterParams; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.SimpleMolecule; +import lcsb.mapviewer.model.map.species.Species; /** * This class defines methods used for drawing {@link SimpleMolecule} on @@ -27,8 +30,19 @@ public class SimpleMoleculeConverter extends SpeciesConverter<SimpleMolecule> { */ private static Logger logger = Logger.getLogger(SimpleMoleculeConverter.class.getName()); + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public SimpleMoleculeConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } + @Override - public void drawAlias(final SimpleMolecule alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(final SimpleMolecule alias, final Graphics2D graphics, final ConverterParams params) { int homodir; if (params.isSbgnFormat()) { // If the SBGN display mode is set, multimer is shown as two stacked diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverter.java index 66bb702701978c54629e16a33e64c375c5cf0422..cf3ca8313cb36184ca0b76ab1da5090fe3f8ac53 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverter.java @@ -15,12 +15,13 @@ import java.util.List; import org.apache.log4j.Logger; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.common.geometry.EllipseTransformation; import lcsb.mapviewer.common.geometry.LineTransformation; import lcsb.mapviewer.converter.graphics.ConverterParams; -import lcsb.mapviewer.converter.graphics.IAliasConverter; +import lcsb.mapviewer.converter.graphics.ElementConverter; import lcsb.mapviewer.model.graphics.LineType; import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Complex; @@ -28,15 +29,15 @@ import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; /** - * This class defines basics used for drawing aliases of {@link Species} - * (node in the graph representation) on the graphics2d object. + * This class defines basics used for drawing aliases of {@link Species} (node + * in the graph representation) on the graphics2d object. * * @param <T> * alias class that can be drawn with this converter * @author Piotr Gawron * */ -public abstract class SpeciesConverter<T extends Species> implements IAliasConverter<T> { +public abstract class SpeciesConverter<T extends Species> implements ElementConverter<T> { /** * PI value. @@ -144,11 +145,21 @@ public abstract class SpeciesConverter<T extends Species> implements IAliasConve */ public static final int HOMODIMER_OFFSET = 6; + /** + * Object that helps to convert {@link ColorSchema} values into colors. + */ + private ColorExtractor colorExtractor; + /** * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} */ - protected SpeciesConverter() { + protected SpeciesConverter(ColorExtractor colorExtractor) { structuralFont = new Font(Font.SANS_SERIF, 0, DEFAULT_SPECIES_MODIFIER_FONT_SIZE); + this.colorExtractor = colorExtractor; }; /** @@ -565,8 +576,8 @@ public abstract class SpeciesConverter<T extends Species> implements IAliasConve } @Override - public void drawAlias(T alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas) { - drawAlias(alias, graphics, params); + public void drawElement(T alias, Graphics2D graphics, ConverterParams params, List<ColorSchema> visualizedLayoutsColorSchemas) { + drawElement(alias, graphics, params); Color oldColor = graphics.getColor(); int count = 0; @@ -579,7 +590,7 @@ public abstract class SpeciesConverter<T extends Species> implements IAliasConve int x = (int) (startX * alias.getWidth() + alias.getX()); graphics.drawRect(x, alias.getY().intValue(), (int) width, alias.getHeight().intValue()); - Color color = schema.getNormalizedColor(); + Color color = colorExtractor.getNormalizedColor(schema); Color bgAlphaColor = new Color(color.getRed(), color.getGreen(), color.getBlue(), LAYOUT_ALPHA); graphics.setColor(bgAlphaColor); graphics.fillRect(x, alias.getY().intValue(), (int) width, alias.getHeight().intValue()); diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/UnknownConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/UnknownConverter.java index 7063ad399c80761b16b912cd1c881ed82a1a2ba3..4d2045ebf9b86289bebdfb842b970ed688d1f31c 100644 --- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/UnknownConverter.java +++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/species/UnknownConverter.java @@ -8,29 +8,44 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; +import org.apache.log4j.Logger; + +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.graphics.LineType; +import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.species.Species; - -import org.apache.log4j.Logger; +import lcsb.mapviewer.model.map.species.Unknown; /** * This class defines methods used for drawing SpeciesAlias of - * {@link lcsb.mapviewer.converter.model.celldesigner.structure.db.model.map.species.Unknown Unknown} on the - * {@link Graphics2D} object. + * {@link lcsb.mapviewer.converter.model.celldesigner.structure.db.model.map.species.Unknown + * Unknown} on the {@link Graphics2D} object. * * @author Piotr Gawron * */ -public class UnknownConverter extends SpeciesConverter<Species> { +public class UnknownConverter extends SpeciesConverter<Unknown> { + /** * Default class logger. */ - private static Logger logger = Logger.getLogger(UnknownConverter.class.getName()); + private static Logger logger = Logger.getLogger(UnknownConverter.class.getName()); + + /** + * Default constructor. + * + * @param colorExtractor + * Object that helps to convert {@link ColorSchema} values into + * colors when drawing {@link Species} + */ + public UnknownConverter(ColorExtractor colorExtractor) { + super(colorExtractor); + } @Override - public void drawAlias(final Species alias, final Graphics2D graphics, final ConverterParams params) { + public void drawElement(Unknown alias, final Graphics2D graphics, final ConverterParams params) { if (alias.getActivity()) { int border = ACTIVITY_BORDER_DISTANCE; alias.increaseBorder(border); @@ -51,12 +66,12 @@ public class UnknownConverter extends SpeciesConverter<Species> { } @Override - public PathIterator getBoundPathIterator(final Species alias) { + public PathIterator getBoundPathIterator(Unknown alias) { throw new InvalidStateException("This class doesn't provide boundPath"); } @Override - public Point2D getPointCoordinatesOnBorder(final Species alias, final double angle) { + public Point2D getPointCoordinatesOnBorder(Unknown alias, final double angle) { if (alias.getWidth() == 0 && alias.getHeight() == 0) { logger.warn("Looking for coordinates for unknown of 0 size"); return alias.getCenter(); diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/ConverterTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/ConverterTest.java index cf5bba155b99e404d87ee662aaf335f4534d2508..66e7eaa7edd963b522a6713a7e7c66d0bd7ad385 100644 --- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/ConverterTest.java +++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/ConverterTest.java @@ -1,11 +1,12 @@ package lcsb.mapviewer.converter.graphics; -import static org.junit.Assert.fail; +import java.awt.Color; import org.junit.After; import org.junit.Before; import org.junit.Test; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment; import lcsb.mapviewer.model.map.compartment.LeftSquareCompartment; import lcsb.mapviewer.model.map.compartment.RightSquareCompartment; @@ -24,13 +25,14 @@ public class ConverterTest { @Test public void test() { try { - new AliasConverter(new BottomSquareCompartment("id1")); - new AliasConverter(new TopSquareCompartment("id2")); - new AliasConverter(new LeftSquareCompartment("id3")); - new AliasConverter(new RightSquareCompartment("id4")); - }catch (Exception e) { + ColorExtractor colorExtractor = new ColorExtractor(Color.BLUE, Color.RED); + new ElementConverterImpl(new BottomSquareCompartment("id1"), colorExtractor); + new ElementConverterImpl(new TopSquareCompartment("id2"), colorExtractor); + new ElementConverterImpl(new LeftSquareCompartment("id3"), colorExtractor); + new ElementConverterImpl(new RightSquareCompartment("id4"), colorExtractor); + } catch (Exception e) { e.printStackTrace(); - fail("Unknown exception"); + throw e; } } diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/NormalImageGeneratorTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/NormalImageGeneratorTest.java index 3ba9e0c966a8b6f4210875b30d435c1147988538..36d384f0070428c4f17bd8681ab851e7a1fa8a9b 100644 --- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/NormalImageGeneratorTest.java +++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/NormalImageGeneratorTest.java @@ -1,7 +1,6 @@ package lcsb.mapviewer.converter.graphics; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import java.awt.Color; import java.awt.Graphics2D; @@ -13,19 +12,16 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.CreateHierarchyCommand; import lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params; -import lcsb.mapviewer.converter.graphics.compartment.ArtifitialCompartmentConverter; import lcsb.mapviewer.converter.graphics.species.ComplexConverter; import lcsb.mapviewer.model.graphics.PolylineData; -import lcsb.mapviewer.model.map.compartment.PathwayCompartment; 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.ModelFullIndexed; import lcsb.mapviewer.model.map.species.Complex; -import lcsb.mapviewer.model.map.species.GenericProtein; -import lcsb.mapviewer.model.map.species.Species; public class NormalImageGeneratorTest { static Logger logger = Logger.getLogger(NormalImageGenerator.class); @@ -51,85 +47,19 @@ public class NormalImageGeneratorTest { } class TmpComplexConverter extends ComplexConverter { - @Override - public void drawText(Complex compAlias, Graphics2D graphics, ConverterParams params) { - setScale(params.getScale()); - setCentered(params.isTextCentered()); - super.drawText(compAlias, graphics, params); - } - - } - - @Test - public void testComplexConversion() throws Exception { - scale = null; - try { - AliasConverter.addAliasConverter(Complex.class, new TmpComplexConverter()); - - Model model = createComplexModel(); - new CreateHierarchyCommand(model, 2, 2).execute(); - new PngImageGenerator(new Params().scale(2).width(600).height(600).model(model).level(0).nested(true)); - - // test if font was scaled - assertTrue(scale > 1.0); - - } catch (Exception e) { - e.printStackTrace(); - throw e; + public TmpComplexConverter(ColorExtractor colorExtractor) { + super(colorExtractor); } - } - - private Model createComplexModel() { - Model model = new ModelFullIndexed(null); - model.setWidth(600); - model.setHeight(600); - Complex alias = new Complex("1"); - alias.setName("a"); - alias.setX(10); - alias.setY(10); - alias.setWidth(200); - alias.setHeight(50); - model.addElement(alias); - - Species a2 = new GenericProtein("2"); - a2.setName("b"); - a2.setX(10); - a2.setY(100); - a2.setWidth(200); - a2.setHeight(50); - a2.setFontSize(30); - model.addElement(a2); - return model; - } - - class TmpArtifitialConverter extends ArtifitialCompartmentConverter { @Override - public void drawText(PathwayCompartment compAlias, Graphics2D graphics, ConverterParams params) { + public void drawText(Complex compAlias, Graphics2D graphics, ConverterParams params) { setScale(params.getScale()); setCentered(params.isTextCentered()); - setArtifitialCalled(true); super.drawText(compAlias, graphics, params); } } - @Test - public void testNestedCompartmentsConversion() throws Exception { - scale = null; - try { - AliasConverter.addAliasConverter(PathwayCompartment.class, new TmpArtifitialConverter()); - Model model = createCompartmentModel(); - new CreateHierarchyCommand(model, 2, 2).execute(); - new PngImageGenerator(new Params().scale(2).width(600).height(600).model(model).level(0).nested(true)); - - assertTrue(centered); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - private Model createCompartmentModel() { Model model = new ModelFullIndexed(null); model.setWidth(526); @@ -164,7 +94,9 @@ public class NormalImageGeneratorTest { public void testArtifitialInNonHierarchicalView() throws Exception { scale = null; try { - AliasConverter.addAliasConverter(PathwayCompartment.class, new TmpArtifitialConverter()); + // TODO fix it + // AliasConverter.addAliasConverter(PathwayCompartment.class, new + // TmpArtifitialConverter()); setArtifitialCalled(false); Model model = createCompartmentModel(); diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverterTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverterTest.java index 199487232b6226636d96a4a9fa18a37e5c9c2538..fa4a9c6b2b145e8f3f3ea2f6b450c254a06d6f96 100644 --- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverterTest.java +++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/reaction/ReactionConverterTest.java @@ -17,6 +17,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.model.graphics.PolylineData; import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.layout.GenericColorSchema; @@ -28,6 +29,8 @@ import lcsb.mapviewer.model.map.reaction.Reaction; public class ReactionConverterTest { + ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN); + @Before public void setUp() throws Exception { } @@ -41,7 +44,7 @@ public class ReactionConverterTest { try { BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = bi.createGraphics(); - ReactionConverter rc = new ReactionConverter(); + ReactionConverter rc = new ReactionConverter(colorExtractor); Reaction reaction = createReaction(5.0); rc.drawReaction(reaction, graphics, false); @@ -85,7 +88,7 @@ public class ReactionConverterTest { try { BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = bi.createGraphics(); - ReactionConverter rc = new ReactionConverter(); + ReactionConverter rc = new ReactionConverter(colorExtractor); Reaction reaction = createReaction(1.0); rc.drawReaction(reaction, graphics, false); @@ -132,7 +135,7 @@ public class ReactionConverterTest { try { BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = bi.createGraphics(); - ReactionConverter rc = new ReactionConverter(); + ReactionConverter rc = new ReactionConverter(colorExtractor); Reaction reaction = createReaction(3.0); rc.drawReaction(reaction, graphics, false); diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverterTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverterTest.java index 64c6307dd48471c0bbe6b221f1b83f19d7d7f336..bc8c2b2eaf147564f64e636c39878aee078b08c5 100644 --- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverterTest.java +++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/species/SpeciesConverterTest.java @@ -5,7 +5,6 @@ import static org.junit.Assert.assertTrue; import java.awt.Color; import java.awt.Graphics2D; -import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; @@ -14,14 +13,16 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.converter.graphics.ConverterParams; import lcsb.mapviewer.model.map.layout.ColorSchema; import lcsb.mapviewer.model.map.layout.GenericColorSchema; import lcsb.mapviewer.model.map.species.GenericProtein; -import lcsb.mapviewer.model.map.species.Protein; public class SpeciesConverterTest { + ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN); + @Before public void setUp() throws Exception { } @@ -33,27 +34,22 @@ public class SpeciesConverterTest { @Test public void testGetResidueCoords() throws Exception { try { - final class Conv extends ProteinConverter { - public Point2D getCoordinate(Protein alias, double angle) { - return super.getResidueCoordinates(alias, angle); - } - } GenericProtein alias = new GenericProtein("id"); alias.setX(135); alias.setY(194.0); alias.setWidth(130); alias.setHeight(67); - Conv conv = new Conv(); - assertEquals(135.0, conv.getCoordinate(alias, 3.141592653589793).getX(), 2); - assertEquals(265., conv.getCoordinate(alias, 0.0).getX(), 2); - assertEquals(135.0, conv.getCoordinate(alias, 2.41).getX(), 2); - assertEquals(194.0, conv.getCoordinate(alias, 1.98).getY(), 2); - assertEquals(194.0, conv.getCoordinate(alias, 1.59).getY(), 2); - assertEquals(265.0, conv.getCoordinate(alias, 6.28).getX(), 2); - assertEquals(261.0, conv.getCoordinate(alias, 4.13).getY(), 2); - assertEquals(261.0, conv.getCoordinate(alias, 4.86).getY(), 2); - assertEquals(265.0, conv.getCoordinate(alias, 5.69).getX(), 2); - assertEquals(194.0, conv.getCoordinate(alias, 0.99).getY(), 2); + ProteinConverter conv = new ProteinConverter(null); + assertEquals(135.0, conv.getResidueCoordinates(alias, 3.141592653589793).getX(), 2); + assertEquals(265., conv.getResidueCoordinates(alias, 0.0).getX(), 2); + assertEquals(135.0, conv.getResidueCoordinates(alias, 2.41).getX(), 2); + assertEquals(194.0, conv.getResidueCoordinates(alias, 1.98).getY(), 2); + assertEquals(194.0, conv.getResidueCoordinates(alias, 1.59).getY(), 2); + assertEquals(265.0, conv.getResidueCoordinates(alias, 6.28).getX(), 2); + assertEquals(261.0, conv.getResidueCoordinates(alias, 4.13).getY(), 2); + assertEquals(261.0, conv.getResidueCoordinates(alias, 4.86).getY(), 2); + assertEquals(265.0, conv.getResidueCoordinates(alias, 5.69).getX(), 2); + assertEquals(194.0, conv.getResidueCoordinates(alias, 0.99).getY(), 2); } catch (Exception e) { e.printStackTrace(); @@ -66,10 +62,10 @@ public class SpeciesConverterTest { try { BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = bi.createGraphics(); - ProteinConverter rc = new ProteinConverter(); + ProteinConverter rc = new ProteinConverter(colorExtractor); GenericProtein alias = createAlias(); - rc.drawAlias(alias, graphics, new ConverterParams()); + rc.drawElement(alias, graphics, new ConverterParams()); int val = bi.getRGB((int) alias.getCenterX(), (int) alias.getCenterY()); @@ -83,7 +79,7 @@ public class SpeciesConverterTest { List<ColorSchema> schemas = new ArrayList<>(); schemas.add(schema); - rc.drawAlias(alias2, graphics, new ConverterParams(), schemas); + rc.drawElement(alias2, graphics, new ConverterParams(), schemas); int val2 = bi.getRGB((int) alias.getCenterX(), (int) alias.getCenterY()); @@ -99,10 +95,10 @@ public class SpeciesConverterTest { try { BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = bi.createGraphics(); - ProteinConverter rc = new ProteinConverter(); + ProteinConverter rc = new ProteinConverter(colorExtractor); GenericProtein alias = createAlias(); - rc.drawAlias(alias, graphics, new ConverterParams()); + rc.drawElement(alias, graphics, new ConverterParams()); int val = bi.getRGB((int) alias.getCenterX(), (int) alias.getCenterY()); @@ -116,14 +112,14 @@ public class SpeciesConverterTest { List<ColorSchema> schemas = new ArrayList<>(); schemas.add(schema); - rc.drawAlias(alias2, graphics, new ConverterParams(), schemas); + rc.drawElement(alias2, graphics, new ConverterParams(), schemas); int val2 = bi.getRGB((int) alias.getCenterX(), (int) alias.getCenterY()); bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); graphics = bi.createGraphics(); - rc.drawAlias(alias2, graphics, new ConverterParams(), new ArrayList<>()); + rc.drawElement(alias2, graphics, new ConverterParams(), new ArrayList<>()); int val3 = bi.getRGB((int) alias.getCenterX(), (int) alias.getCenterY()); @@ -140,10 +136,10 @@ public class SpeciesConverterTest { try { BufferedImage bi = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = bi.createGraphics(); - ProteinConverter rc = new ProteinConverter(); + ProteinConverter rc = new ProteinConverter(colorExtractor); GenericProtein alias = createAlias(); - rc.drawAlias(alias, graphics, new ConverterParams()); + rc.drawElement(alias, graphics, new ConverterParams()); int val = bi.getRGB((int) alias.getCenterX(), (int) alias.getCenterY()); @@ -161,7 +157,7 @@ public class SpeciesConverterTest { schema.setColor(Color.BLUE); schemas.add(schema); - rc.drawAlias(alias2, graphics, new ConverterParams(), schemas); + rc.drawElement(alias2, graphics, new ConverterParams(), schemas); int val2 = bi.getRGB((int) (alias.getX() + alias.getWidth() / 4), (int) alias.getCenterY()); int val3 = bi.getRGB((int) (alias.getCenterX()), (int) alias.getCenterY()); diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/ClearColorModelCommand.java b/model-command/src/main/java/lcsb/mapviewer/commands/ClearColorModelCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..891434f015e8b5a93073963b4f34532f7317c20f --- /dev/null +++ b/model-command/src/main/java/lcsb/mapviewer/commands/ClearColorModelCommand.java @@ -0,0 +1,46 @@ +package lcsb.mapviewer.commands; + +import java.awt.Color; +import java.util.ArrayList; + +import lcsb.mapviewer.model.map.model.Model; + +/** + * This {@link ModelCommand} clear info about colors in a model. + * + * @author Piotr Gawron + * + */ +public class ClearColorModelCommand extends ModelCommand { + + /** + * Coloring command that will clear colors. + */ + private ColorModelCommand colorModelCommand; + + /** + * Default constructor. + * + * @param model + * original model + */ + public ClearColorModelCommand(Model model) { + super(model); + colorModelCommand = new ColorModelCommand(model, new ArrayList<>(), new ColorExtractor(Color.WHITE, Color.WHITE)); + } + + @Override + protected void undoImplementation() throws CommandExecutionException { + colorModelCommand.undo(); + } + + @Override + protected void redoImplementation() throws CommandExecutionException { + colorModelCommand.redo(); + } + + @Override + protected void executeImplementation() throws CommandExecutionException { + colorModelCommand.execute(); + } +} diff --git a/model-command/src/main/java/lcsb/mapviewer/commands/ColorExtractor.java b/model-command/src/main/java/lcsb/mapviewer/commands/ColorExtractor.java new file mode 100644 index 0000000000000000000000000000000000000000..1a6d5d5d31976885404440319dab3dc8e4304507 --- /dev/null +++ b/model-command/src/main/java/lcsb/mapviewer/commands/ColorExtractor.java @@ -0,0 +1,96 @@ +package lcsb.mapviewer.commands; + +import java.awt.Color; + +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.model.map.layout.ColorSchema; + +/** + * Class that extracts color that should be used for drawing from + * {@link ColorSchema}. + * + * @author Piotr Gawron + * + */ +public class ColorExtractor { + + /** + * Color that should be used for min values of {@link ColorSchema#value}. + */ + private Color minColor; + + /** + * Color that should be used for maxvalues of {@link ColorSchema#value}. + */ + private Color maxColor; + + /** + * Default constructor. + * + * @param minColor + * Color that should be used for min values of + * {@link ColorSchema#value} + * @param maxColor + * Color that should be used for max values of + * {@link ColorSchema#value} + */ + public ColorExtractor(Color minColor, Color maxColor) { + if (minColor == null || maxColor == null) { + throw new InvalidArgumentException("Parameters cannot be null"); + } + this.minColor = minColor; + this.maxColor = maxColor; + } + + /** + * Extracts color from {@link ColorSchema} object. + * + * @param colorSchema + * {@link ColorSchema} from which {@link Color} should be extracted + * + * @return color from {@link ColorSchema} object + */ + public Color getNormalizedColor(ColorSchema colorSchema) { + if (colorSchema.getColor() != null) { + return colorSchema.getColor(); + } else { + return getColorForValue(colorSchema.getValue()); + } + } + + /** + * Returns color from red - green scale for the given normalized double value + * (from range -1,1). + * + * @param value + * double value that should be converted into color + * @return color for the double value + */ + protected Color getColorForValue(Double value) { + if (value > 0) { + double ratio = value; + return new Color((int) (maxColor.getRed() * ratio), (int) (maxColor.getGreen() * ratio), (int) (maxColor.getBlue() * ratio)); + } + if (value < 0) { + double ratio = -value; + return new Color((int) (minColor.getRed() * ratio), (int) (minColor.getGreen() * ratio), (int) (minColor.getBlue() * ratio)); + } + return Color.WHITE; + } + + /** + * @return the minColor + * @see #minColor + */ + public Color getMinColor() { + return minColor; + } + + /** + * @return the maxColor + * @see #maxColor + */ + public Color getMaxColor() { + return maxColor; + } +} 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 87d848c59c4a5217069f0c173a27d0c58afc8398..427c7f77216e77e1ae31c62cef008510adeec1f4 100644 --- a/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java +++ b/model-command/src/main/java/lcsb/mapviewer/commands/ColorModelCommand.java @@ -12,6 +12,7 @@ import org.apache.log4j.Logger; import lcsb.mapviewer.common.Pair; import lcsb.mapviewer.common.exception.NotImplementedException; import lcsb.mapviewer.model.graphics.ArrowTypeData; +import lcsb.mapviewer.model.map.AnnotatedObject; import lcsb.mapviewer.model.map.MiriamData; import lcsb.mapviewer.model.map.MiriamRelationType; import lcsb.mapviewer.model.map.MiriamType; @@ -26,6 +27,7 @@ import lcsb.mapviewer.model.map.reaction.Reactant; import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.modelutils.map.ElementUtils; /** * This {@link ModelCommand} colors a model (nodes and reactions) according to @@ -47,17 +49,32 @@ public class ColorModelCommand extends ModelCommand { */ private Collection<ColorSchema> schemas; + /** + * Object that helps to convert {@link ColorSchema} values into colors. + * + */ + private ColorExtractor colorExtractor; + + /** + * Util class for all {@link AnnotatedObject} elements. + */ + private ElementUtils eu = new ElementUtils(); + /** * Default constructor. * + * @param colorExtractor + * object that helps to convert {@link ColorSchema} values into + * colors * @param model * original model * @param schemas * set of color schemas used in this command to color model. */ - public ColorModelCommand(Model model, Collection<ColorSchema> schemas) { + public ColorModelCommand(Model model, Collection<ColorSchema> schemas, ColorExtractor colorExtractor) { super(model); this.schemas = schemas; + this.colorExtractor = colorExtractor; } /** @@ -68,14 +85,14 @@ public class ColorModelCommand extends ModelCommand { * @param schema * color schema to be used * @throws InvalidColorSchemaException - * thrown when alias was already colored by other schema + * thrown when {@link Reaction} was already colored by other schema */ private void applyColor(Reaction reaction, ColorSchema schema) throws InvalidColorSchemaException { if (!reaction.getReactants().get(0).getLine().getColor().equals(Color.BLACK)) { throw new InvalidColorSchemaException("At least two rows try to set color to reaction: " + reaction.getIdReaction()); } - Color color = schema.getNormalizedColor(); + Color color = colorExtractor.getNormalizedColor(schema); for (AbstractNode node : reaction.getNodes()) { node.getLine().setColor(color); if (schema.getLineWidth() != null) { @@ -101,8 +118,8 @@ public class ColorModelCommand extends ModelCommand { * reaction to which coloring schema is checked * @param schema * coloring schema - * @return <code>true</code> if coloring schema should be used for alias, - * <code>false</code> otherwise + * @return <code>true</code> if coloring schema should be used for + * {@link Reaction}, <code>false</code> otherwise */ private boolean match(Reaction reaction, ColorSchema schema) { if (schema.getName() != null) { @@ -133,59 +150,57 @@ public class ColorModelCommand extends ModelCommand { } /** - * Applies color schema into the alias. + * Applies color schema into the {@link Element}. * - * @param alias + * @param element * object to be colored * @param schema * color schema to be used * @throws InvalidColorSchemaException * thrown when alias was already colored by other schema */ - private void applyColor(Element alias, ColorSchema schema) throws InvalidColorSchemaException { - if (alias instanceof Species) { - if (!alias.getColor().equals(Color.WHITE)) { - throw new InvalidColorSchemaException("At least two rows try to set color to element: " + alias.getName()); + private void applyColor(Element element, ColorSchema schema) throws InvalidColorSchemaException { + if (element instanceof Species) { + if (!element.getColor().equals(Color.WHITE)) { + throw new InvalidColorSchemaException("At least two rows try to set color to element: " + element.getName()); } - - alias.setColor(schema.getNormalizedColor()); + element.setColor(colorExtractor.getNormalizedColor(schema)); } - } /** - * Checks if the coloring schema should be used for the alias. + * Checks if the coloring schema should be used for the {@link Element}. * - * @param alias - * alias to which coloring schema is checked + * @param element + * {@link Element} for which coloring schema is checked * @param schema * coloring schema - * @return <code>true</code> if coloring schema should be used for alias, - * <code>false</code> otherwise + * @return <code>true</code> if coloring schema should be used for + * {@link Element}, <code>false</code> otherwise */ - protected boolean match(Element alias, ColorSchema schema) { - if (alias instanceof Species) { + protected boolean match(Element element, ColorSchema schema) { + if (element instanceof Species) { if (schema.getName() != null) { - if (!alias.getName().equalsIgnoreCase(schema.getName())) { + if (!element.getName().equalsIgnoreCase(schema.getName())) { return false; } } if (schema.getTypes().size() > 0) { - if (!schema.getTypes().contains(alias.getClass())) { + if (!schema.getTypes().contains(element.getClass())) { return false; } } if (schema.getGeneralIdentifier() != null && !schema.getGeneralIdentifier().equals("")) { MiriamData md = MiriamType.getMiriamDataFromIdentifier(schema.getGeneralIdentifier()); - if (!alias.getMiriamData().contains(md)) { + if (!element.getMiriamData().contains(md)) { return false; } } for (Pair<MiriamType, String> pair : schema.getIdentifierColumns()) { if (pair.getRight() != null && !pair.getRight().equals("")) { MiriamData md = new MiriamData(MiriamRelationType.BQ_BIOL_IS_DESCRIBED_BY, pair.getLeft(), pair.getRight()); - if (!alias.getMiriamData().contains(md)) { + if (!element.getMiriamData().contains(md)) { return false; } } @@ -193,10 +208,10 @@ public class ColorModelCommand extends ModelCommand { if (schema.getCompartments().size() > 0) { boolean found = false; - for (Compartment cAlias : alias.getModelData().getModel().getCompartments()) { + for (Compartment compartment : element.getModelData().getModel().getCompartments()) { for (String compartmentName : schema.getCompartments()) { - if (cAlias.getName().equalsIgnoreCase(compartmentName)) { - if (cAlias.cross(alias)) { + if (compartment.getName().equalsIgnoreCase(compartmentName)) { + if (compartment.cross(element)) { found = true; } } @@ -226,8 +241,8 @@ public class ColorModelCommand extends ModelCommand { List<ColorSchema> result = new ArrayList<ColorSchema>(); for (ColorSchema schema : schemas) { boolean found = false; - for (Element alias : getModel().getElements()) { - if (match(alias, schema)) { + for (Element element : getModel().getElements()) { + if (match(element, schema)) { found = true; } } @@ -245,7 +260,7 @@ public class ColorModelCommand extends ModelCommand { /** * Returns list of elements ({@link Reaction reactions} and {@link Element - * aliases}) that are modified by the coloring command. + * elements}) that are modified by the coloring command. * * @return {@link Map}, where key corresponds to modified {@link Reaction} or * {@link Element} and value is a {@link ColorSchema} that should be @@ -261,18 +276,18 @@ public class ColorModelCommand extends ModelCommand { models.addAll(getModel().getSubmodels()); for (Model model2 : models) { for (ColorSchema schema : schemas) { - for (Element alias : model2.getElements()) { - if (match(alias, schema)) { - if (result.get(alias) != null && !result.get(alias).getNormalizedColor().equals(Color.WHITE)) { - throw new InvalidColorSchemaException("Alias " + alias.getElementId() + " is colored by more than one rule."); + for (Element element : model2.getElements()) { + if (match(element, schema)) { + if (result.get(element) != null && !colorExtractor.getNormalizedColor(result.get(element)).equals(Color.WHITE)) { + throw new InvalidColorSchemaException(eu.getElementTag(element) + "Element is colored by more than one rule."); } - result.put(alias, schema); + result.put(element, schema); } } for (Reaction reaction : model2.getReactions()) { if (match(reaction, schema)) { - if (result.get(reaction) != null && !result.get(reaction).getNormalizedColor().equals(Color.WHITE)) { - throw new InvalidColorSchemaException("Reaction " + reaction.getIdReaction() + " is colored by more than one rule."); + if (result.get(reaction) != null && !colorExtractor.getNormalizedColor(result.get(reaction)).equals(Color.WHITE)) { + throw new InvalidColorSchemaException(eu.getElementTag(reaction) + "Reaction is colored by more than one rule."); } result.put(reaction, schema); } @@ -306,8 +321,8 @@ public class ColorModelCommand extends ModelCommand { */ private void colorModel(Model result, boolean top) throws InvalidColorSchemaException { - for (Element alias : result.getElements()) { - alias.setColor(Color.WHITE); + for (Element element : result.getElements()) { + element.setColor(Color.WHITE); } for (Reaction reaction : result.getReactions()) { for (AbstractNode node : reaction.getNodes()) { @@ -316,10 +331,10 @@ public class ColorModelCommand extends ModelCommand { } for (ColorSchema schema : schemas) { - for (Element alias : result.getElements()) { - if (match(alias, schema)) { + for (Element element : result.getElements()) { + if (match(element, schema)) { schema.setMatches(schema.getMatches() + 1); - applyColor(alias, schema); + applyColor(element, schema); } } for (Reaction reaction : result.getReactions()) { diff --git a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java index e4972598fac3f1912be32d96b162f0e87a08d37e..14d934650b6eec46884d8f889e27d8e8472fcbbc 100644 --- a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java +++ b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java @@ -29,7 +29,9 @@ import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.GenericProtein; public class ColorModelCommandTest extends CommandTestFunctions { - Logger logger = Logger.getLogger(ColorModelCommandTest.class); + Logger logger = Logger.getLogger(ColorModelCommandTest.class); + + ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN); @Before public void setUp() throws Exception { @@ -58,7 +60,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setName("CNC"); schema.setValue(-1.0); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(coloredModel, schemas); + ColorModelCommand factory = new ColorModelCommand(coloredModel, schemas, colorExtractor); assertFalse(Color.RED.equals(coloredModel.getElementByElementId("sa14").getColor())); @@ -94,7 +96,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setValue(1.0); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); Collection<ColorSchema> missing = factory.getMissingSchema(); assertEquals(1, missing.size()); @@ -112,7 +114,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { Reaction re4 = model.getReactionByReactionId("re4"); Collection<ColorSchema> schemas = new ArrayList<ColorSchema>(); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); assertFalse(Color.BLACK.equals(re4.getNodes().get(0).getLine().getColor())); factory.execute(); @@ -137,7 +139,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setColor(Color.RED); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); assertEquals(Color.BLACK, re1.getNodes().get(0).getLine().getColor()); factory.execute(); @@ -162,7 +164,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setValue(-1.0); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); assertEquals(Color.BLACK, re2.getNodes().get(0).getLine().getColor()); factory.execute(); @@ -191,7 +193,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setValue(-1.0); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); assertEquals(Color.BLACK, re3.getNodes().get(0).getLine().getColor()); @@ -216,7 +218,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { Collection<ColorSchema> schemas = new ArrayList<>(); Model coloredModel = new CopyCommand(model).execute(); - new ColorModelCommand(coloredModel, schemas).execute(); + new ColorModelCommand(coloredModel, schemas, colorExtractor).execute(); Model coloredModel2 = coloredModel.getSubmodelConnections().iterator().next().getSubmodel().getModel(); Model coloredModel3 = coloredModel.getSubmodelByConnectionName("BLA"); @@ -243,7 +245,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setName("BDH1"); schema.setColor(Color.BLUE); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); Map<Object, ColorSchema> map = factory.getModifiedElements(); assertEquals(2, map.size()); @@ -268,7 +270,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setName(""); schema.setReverseReaction(true); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); Map<Object, ColorSchema> map = factory.getModifiedElements(); assertEquals(0, map.size()); @@ -290,7 +292,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { schema.setName(null); schema.setReverseReaction(true); schemas.add(schema); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); Map<Object, ColorSchema> map = factory.getModifiedElements(); assertEquals(1, map.size()); @@ -319,7 +321,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { List<ColorSchema> schemas = new ArrayList<>(); schemas.add(colorSchema); - ColorModelCommand factory = new ColorModelCommand(new ModelFullIndexed(null), schemas); + ColorModelCommand factory = new ColorModelCommand(new ModelFullIndexed(null), schemas, colorExtractor); assertFalse(factory.match(alias, colorSchema)); diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java index 89840fce6753e72466ead3a93a1239b68894c15a..4b2c13e3e2ee5ed59bbd8ffeff5e72869170bfbb 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/ColorSchema.java @@ -26,37 +26,6 @@ public abstract class ColorSchema implements Serializable { */ private static final long serialVersionUID = 1L; - /** - * Base of the hex representation. - */ - private static final int HEX_BASE = 16; - - /** - * Length of the string describing color in rgb: "#RRGGBB". - */ - private static final int COLOR_STRING_LENGTH = 7; - - /** - * Where starts description of red color in stirng representing color. - */ - private static final int COLOR_SUBSTRING_START_RED = 1; - - /** - * Where starts description of green color in stirng representing color. - */ - private static final int COLOR_SUBSTRING_START_GREEN = 3; - - /** - * Where starts description of blue color in stirng representing color. - */ - private static final int COLOR_SUBSTRING_START_BLUE = 5; - - /** - * Defines the maximum value of primary colors in RGB model (every color is - * from range 0..255). - */ - private static final int MAX_SINGLE_COLOR_VALUE_IN_RGB_FORMAT = 255; - /** * Name of the {@link Element Element}. If null * then this field will be skiped. @@ -197,29 +166,6 @@ public abstract class ColorSchema implements Serializable { } } - /** - * Sets {@link #color} from the string. - * - * @param string - * color in text representation - * @throws InvalidColorSchemaException - * thrown when string describing color is invalid - */ - public void setColor(String string) throws InvalidColorSchemaException { - if (string.length() != COLOR_STRING_LENGTH) { - throw new InvalidColorSchemaException("Invalid color value: " + string + ". Correct format: #xxxxxx (where x is a hex value)"); - } - if (string.charAt(0) != '#') { - throw new InvalidColorSchemaException("Invalid color value: " + string + ". Correct format: #xxxxxx (where x is a hex value)"); - - } else { - setColor(new Color(Integer.valueOf(string.substring(COLOR_SUBSTRING_START_RED, COLOR_SUBSTRING_START_GREEN), HEX_BASE), // - Integer.valueOf(string.substring(COLOR_SUBSTRING_START_GREEN, COLOR_SUBSTRING_START_BLUE), HEX_BASE), // - Integer.valueOf(string.substring(COLOR_SUBSTRING_START_BLUE, COLOR_STRING_LENGTH), HEX_BASE))); - } - - } - @Override public String toString() { StringBuilder result = new StringBuilder(); @@ -483,39 +429,6 @@ public abstract class ColorSchema implements Serializable { this.types.add(clazz); } - /** - * Extracts color from {@link ColorSchema} object. - * - * @return color from {@link ColorSchema} object - */ - public Color getNormalizedColor() { - if (getColor() != null) { - return getColor(); - } else { - return getColorForValue(getValue()); - } - } - - /** - * Returns color from red - green scale for the given normalized double value - * (from range -1,1). - * - * @param value - * double value that should be converted into color - * @return color for the double value - */ - protected Color getColorForValue(Double value) { - if (value > 0) { - int val = (int) ((1 - value) * MAX_SINGLE_COLOR_VALUE_IN_RGB_FORMAT); - return new Color(val, MAX_SINGLE_COLOR_VALUE_IN_RGB_FORMAT, val); - } - if (value < 0) { - int val = (int) ((1 + value) * MAX_SINGLE_COLOR_VALUE_IN_RGB_FORMAT); - return new Color(MAX_SINGLE_COLOR_VALUE_IN_RGB_FORMAT, val, val); - } - return Color.WHITE; - } - /** * @return the description * @see #description diff --git a/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementEditType.java b/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementEditType.java new file mode 100644 index 0000000000000000000000000000000000000000..2b6256c70aa80e106c834518710bf14809d4b957 --- /dev/null +++ b/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementEditType.java @@ -0,0 +1,45 @@ +package lcsb.mapviewer.model.user; + +/** + * Defines how the {@link ConfigurationElementType} should be edited (what kind + * of values we are storing). + * + * @author Piotr Gawron + * + */ +public enum ConfigurationElementEditType { + /** + * Double value. + */ + DOUBLE, + + /** + * Integer value. + */ + INTEGER, + + /** + * String value. + */ + STRING, + + /** + * Color value (for color picker). + */ + COLOR, + + /** + * Url value. + */ + URL, + + /** + * Email value. + */ + EMAIL, + + /** + * Password value. + */ + PASSWORD, +} diff --git a/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java b/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java index d77ddc26da96f9b903854fec6f14f24633f114e7..28da787bfb92ba337c94225b83fa5601e2f71867 100644 --- a/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java +++ b/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java @@ -1,162 +1,187 @@ -package lcsb.mapviewer.model.user; - -/** - * This enum defines all possible configuration parameter that are configurable - * by the user. - * - * @author Piotr Gawron - * - */ -public enum ConfigurationElementType { - - /** - * Email address used for sending email from the system. - */ - EMAIL_ADDRESS("E-mail address", "your.account@domain.com"), // - - /** - * Login for the email account. - */ - EMAIL_LOGIN("E-mail server login", "your@login"), // - - /** - * Password for the email account. - */ - EMAIL_PASSWORD("E-mail server password", "email.secret.password"), // - - /** - * Addres of the imap server. - */ - EMAIL_IMAP_SERVER("IMAP server", "your.imap.domain.com"), // - - /** - * Address of the smtp server. - */ - EMAIL_SMTP_SERVER("SMTP server", "your.smtp.domain.com"), // - - /** - * Port used for smtp connection (sending emails). - */ - EMAIL_SMTP_PORT("SMTP port", "25"), // - - /** - * Default map that should be presented if no map is selected by user side. - */ - DEFAULT_MAP("Default Project Id", "empty"), // - - /** - * Logo presented in the system. - */ - LOGO_IMG("Logo icon", "udl.png"), // - - /** - * Address connected to the logo. - */ - LOGO_LINK("Logo link (after click)", "http://wwwen.uni.lu/"), // - - /** - * Maximum distance (in pixels) that is allowed during finding closest element - * on the map. - */ - SEARCH_DISTANCE("Max distance for clicking on element (px)", "10"), - - /** - * Email used for requesting an account (in client side). - */ - REQUEST_ACCOUNT_EMAIL("Email used for requesting an account", "your.email@domain.com"), - - /** - * Max number of results in search box. - */ - SEARCH_RESULT_NUMBER("Max number of results in search box. ", "100"), - - /** - * Google Analytics tracking ID used for statistics. This tracking ID should - * look like "UA-000000-01". More information about tracking ID can be found - * <a href="https://support.google.com/analytics/answer/1032385?hl=en"> here - * </a>. - */ - GOOGLE_ANALYTICS_IDENTIFIER("Google Analytics tracking ID used for statistics", ""), - - /** - * Description of the logo presented in the system. - */ - LOGO_TEXT("Logo description", "University of Luxembourg"), - - /** - * Domain allowed to connect via x-frame technology. - */ - X_FRAME_DOMAIN("Domain allowed to connect via x-frame technology", ""), - - /** - * Relative directory (in webapps folder) where big files will be stored. - */ - BIG_FILE_STORAGE_DIR("Path to store big files", "minerva-big/"), - - /** - * File where legend 1/4 is stored. - */ - LENGEND_FILE_1("Legend 1 image file", "resources/images/legend_a.png"), - - /** - * File where legend 2/4 is stored. - */ - LENGEND_FILE_2("Legend 2 image file", "resources/images/legend_b.png"), - - /** - * File where legend 3/4 is stored. - */ - LENGEND_FILE_3("Legend 3 image file", "resources/images/legend_c.png"), - - /** - * File where legend 4/4 is stored. - */ - LENGEND_FILE_4("Legend 4 image file", "resources/images/legend_d.png"), - - /** - * File where legend 4/4 is stored. - */ - USER_MANUAL_FILE("User manual file", "resources/other/user_guide.pdf"); - - - /** - * Default value of the configuration parameter (it will be used only when - * value doesn't exist in the DAO). - */ - private String defaultValue = ""; - - /** - * Common name used for visualization (query user). - */ - private String commonName = ""; - - /** - * Default constructor. - * - * @param commonName - * common name used for this parameter - * @param defaultVal - * default value assigned to this parameter - */ - ConfigurationElementType(String commonName, String defaultVal) { - this.defaultValue = defaultVal; - this.commonName = commonName; - } - - /** - * @return the defaultValue - * @see #defaultValue - */ - public String getDefaultValue() { - return defaultValue; - } - - /** - * @return the commonName - * @see #commonName - */ - public String getCommonName() { - return commonName; - } - -} +package lcsb.mapviewer.model.user; + +/** + * This enum defines all possible configuration parameter that are configurable + * by the user. + * + * @author Piotr Gawron + * + */ +public enum ConfigurationElementType { + + /** + * Email address used for sending email from the system. + */ + EMAIL_ADDRESS("E-mail address", "your.account@domain.com", ConfigurationElementEditType.EMAIL), // + + /** + * Login for the email account. + */ + EMAIL_LOGIN("E-mail server login", "your@login", ConfigurationElementEditType.STRING), // + + /** + * Password for the email account. + */ + EMAIL_PASSWORD("E-mail server password", "email.secret.password", ConfigurationElementEditType.PASSWORD), // + + /** + * Addres of the imap server. + */ + EMAIL_IMAP_SERVER("IMAP server", "your.imap.domain.com", ConfigurationElementEditType.STRING), // + + /** + * Address of the smtp server. + */ + EMAIL_SMTP_SERVER("SMTP server", "your.smtp.domain.com", ConfigurationElementEditType.STRING), // + + /** + * Port used for smtp connection (sending emails). + */ + EMAIL_SMTP_PORT("SMTP port", "25", ConfigurationElementEditType.INTEGER), // + + /** + * Default map that should be presented if no map is selected by user side. + */ + DEFAULT_MAP("Default Project Id", "empty", ConfigurationElementEditType.STRING), // + + /** + * Logo presented in the system. + */ + LOGO_IMG("Logo icon", "udl.png", ConfigurationElementEditType.URL), // + + /** + * Address connected to the logo. + */ + LOGO_LINK("Logo link (after click)", "http://wwwen.uni.lu/", ConfigurationElementEditType.URL), // + + /** + * Maximum distance (in pixels) that is allowed during finding closest element + * on the map. + */ + SEARCH_DISTANCE("Max distance for clicking on element (px)", "10", ConfigurationElementEditType.DOUBLE), + + /** + * Email used for requesting an account (in client side). + */ + REQUEST_ACCOUNT_EMAIL("Email used for requesting an account", "your.email@domain.com", ConfigurationElementEditType.EMAIL), + + /** + * Max number of results in search box. + */ + SEARCH_RESULT_NUMBER("Max number of results in search box. ", "100", ConfigurationElementEditType.INTEGER), + + /** + * Google Analytics tracking ID used for statistics. This tracking ID should + * look like "UA-000000-01". More information about tracking ID can be found + * <a href="https://support.google.com/analytics/answer/1032385?hl=en"> here + * </a>. + */ + GOOGLE_ANALYTICS_IDENTIFIER("Google Analytics tracking ID used for statistics", "", ConfigurationElementEditType.STRING), + + /** + * Description of the logo presented in the system. + */ + LOGO_TEXT("Logo description", "University of Luxembourg", ConfigurationElementEditType.STRING), + + /** + * Domain allowed to connect via x-frame technology. + */ + X_FRAME_DOMAIN("Domain allowed to connect via x-frame technology", "", ConfigurationElementEditType.URL), + + /** + * Relative directory (in webapps folder) where big files will be stored. + */ + BIG_FILE_STORAGE_DIR("Path to store big files", "minerva-big/", ConfigurationElementEditType.STRING), + + /** + * File where legend 1/4 is stored. + */ + LENGEND_FILE_1("Legend 1 image file", "resources/images/legend_a.png", ConfigurationElementEditType.URL), + + /** + * File where legend 2/4 is stored. + */ + LENGEND_FILE_2("Legend 2 image file", "resources/images/legend_b.png", ConfigurationElementEditType.URL), + + /** + * File where legend 3/4 is stored. + */ + LENGEND_FILE_3("Legend 3 image file", "resources/images/legend_c.png", ConfigurationElementEditType.URL), + + /** + * File where legend 4/4 is stored. + */ + LENGEND_FILE_4("Legend 4 image file", "resources/images/legend_d.png", ConfigurationElementEditType.URL), + + /** + * File where legend 4/4 is stored. + */ + USER_MANUAL_FILE("User manual file", "resources/other/user_guide.pdf", ConfigurationElementEditType.URL), + + /** + * Color used for negative overlay values. + */ + MIN_COLOR_VAL("Overlay color for negative values", "FF0000", ConfigurationElementEditType.COLOR), + + /** + * Color used for positive overlay values. + */ + MAX_COLOR_VAL("Overlay color for postive values", "0000FF", ConfigurationElementEditType.COLOR); + + /** + * Default value of the configuration parameter (it will be used only when + * value doesn't exist in the DAO). + */ + private String defaultValue = ""; + + /** + * Common name used for visualization (query user). + */ + private String commonName = ""; + + /** + * How we want to edit specific param. + */ + private ConfigurationElementEditType editType = null; + + /** + * Default constructor. + * + * @param commonName + * common name used for this parameter + * @param editType + * type defining how we want to edit this configuration param + * @param defaultVal + * default value assigned to this parameter + */ + ConfigurationElementType(String commonName, String defaultVal, ConfigurationElementEditType editType) { + this.defaultValue = defaultVal; + this.commonName = commonName; + this.editType = editType; + } + + /** + * @return the defaultValue + * @see #defaultValue + */ + public String getDefaultValue() { + return defaultValue; + } + + /** + * @return the commonName + * @see #commonName + */ + public String getCommonName() { + return commonName; + } + + /** + * @return the editType + * @see #editType + */ + public ConfigurationElementEditType getEditType() { + return editType; + } + +} diff --git a/model/src/main/java/lcsb/mapviewer/model/user/User.java b/model/src/main/java/lcsb/mapviewer/model/user/User.java index c35c58ac5c5b020db4ae66d57df25e40bddc675d..3cc421f8f51a6d229836e00d244be48821b286f4 100644 --- a/model/src/main/java/lcsb/mapviewer/model/user/User.java +++ b/model/src/main/java/lcsb/mapviewer/model/user/User.java @@ -1,263 +1,312 @@ -package lcsb.mapviewer.model.user; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.Table; - -/** - * Class representing user. - * - * @author Piotr Gawron - * - */ -@Entity -@Table(name = "user_table") -public class User implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Unique identifier in the database. - */ - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "idDb", unique = true, nullable = false) - private Integer id; - - /** - * User login. - */ - private String login; - - /** - * Password in encrypted form. For the encryption PasswordEncoder spring bean - * is used. - */ - private String cryptedPassword; - - /** - * Name of the user. - */ - private String name; - - /** - * Family name of the user. - */ - private String surname; - - /** - * Email address of the user. - */ - private String email; - - /** - * Is the user removed. - */ - private boolean removed = false; - - /** - * Set of user privileges. - */ - @OneToMany(fetch = FetchType.EAGER, mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL) - private Set<BasicPrivilege> privileges = new HashSet<BasicPrivilege>(); - - /** - * Default annotations schema used by this user. - */ - @OneToOne(cascade = CascadeType.ALL) - @JoinColumn(nullable = true) - private UserAnnotationSchema annotationSchema; - - /** - * Default constructor. - */ - public User() { - } - - /** - * Adds privilege to the user. - * - * @param privilege - * privilege to add - */ - public void addPrivilege(BasicPrivilege privilege) { - privileges.add(privilege); - } - - /** - * @return the id - * @see #id - */ - public Integer getId() { - return id; - } - - /** - * @param id - * the id to set - * @see #id - */ - public void setId(Integer id) { - this.id = id; - } - - /** - * @return the login - * @see #login - */ - public String getLogin() { - return login; - } - - /** - * @param login - * the login to set - * @see #login - */ - public void setLogin(String login) { - this.login = login; - } - - /** - * @return the cryptedPassword - * @see #cryptedPassword - */ - public String getCryptedPassword() { - return cryptedPassword; - } - - /** - * @param cryptedPassword - * the cryptedPassword to set - * @see #cryptedPassword - */ - public void setCryptedPassword(String cryptedPassword) { - this.cryptedPassword = cryptedPassword; - } - - /** - * @return the name - * @see #name - */ - public String getName() { - return name; - } - - /** - * @param name - * the name to set - * @see #name - */ - public void setName(String name) { - this.name = name; - } - - /** - * @return the surname - * @see #surname - */ - public String getSurname() { - return surname; - } - - /** - * @param surname - * the surname to set - * @see #surname - */ - public void setSurname(String surname) { - this.surname = surname; - } - - /** - * @return the email - * @see #email - */ - public String getEmail() { - return email; - } - - /** - * @param email - * the email to set - * @see #email - */ - public void setEmail(String email) { - this.email = email; - } - - /** - * @return the privileges - * @see #privileges - */ - public Set<BasicPrivilege> getPrivileges() { - return privileges; - } - - /** - * @param privileges - * the privileges to set - * @see #privileges - */ - public void setPrivileges(Set<BasicPrivilege> privileges) { - this.privileges = privileges; - } - - /** - * @return the removed - * @see #removed - */ - public boolean isRemoved() { - return removed; - } - - /** - * @param removed - * the removed to set - * @see #removed - */ - public void setRemoved(boolean removed) { - this.removed = removed; - } - - /** - * @return the annotationSchema - * @see #annotationSchema - */ - public UserAnnotationSchema getAnnotationSchema() { - return annotationSchema; - } - - /** - * @param annotationSchema - * the annotationSchema to set - * @see #annotationSchema - */ - public void setAnnotationSchema(UserAnnotationSchema annotationSchema) { - this.annotationSchema = annotationSchema; - if (!this.equals(annotationSchema.getUser())) { - annotationSchema.setUser(this); - } - } - - @Override - public String toString() { - return "[" + this.getClass().getSimpleName() + "] " + getName() + " " + getSurname(); - } - -} +package lcsb.mapviewer.model.user; + +import java.awt.Color; +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * Class representing user. + * + * @author Piotr Gawron + * + */ +@Entity +@Table(name = "user_table") +public class User implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Unique identifier in the database. + */ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "idDb", unique = true, nullable = false) + private Integer id; + + /** + * User login. + */ + private String login; + + /** + * Password in encrypted form. For the encryption PasswordEncoder spring bean + * is used. + */ + private String cryptedPassword; + + /** + * Name of the user. + */ + private String name; + + /** + * Family name of the user. + */ + private String surname; + + /** + * Email address of the user. + */ + private String email; + + /** + * User defined color overriding system + * {@link ConfigurationElementType#MIN_COLOR_VAL}. Used for coloring minimum + * values in overlays. + */ + private Color minColor; + + /** + * User defined color overriding system + * {@link ConfigurationElementType#MAX_COLOR_VAL}. Used for coloring maximum + * values in overlays. + */ + private Color maxColor; + + /** + * Is the user removed. + */ + private boolean removed = false; + + /** + * Set of user privileges. + */ + @OneToMany(fetch = FetchType.EAGER, mappedBy = "user", orphanRemoval = true, cascade = CascadeType.ALL) + private Set<BasicPrivilege> privileges = new HashSet<BasicPrivilege>(); + + /** + * Default annotations schema used by this user. + */ + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(nullable = true) + private UserAnnotationSchema annotationSchema; + + /** + * Default constructor. + */ + public User() { + } + + /** + * Adds privilege to the user. + * + * @param privilege + * privilege to add + */ + public void addPrivilege(BasicPrivilege privilege) { + privileges.add(privilege); + } + + /** + * @return the id + * @see #id + */ + public Integer getId() { + return id; + } + + /** + * @param id + * the id to set + * @see #id + */ + public void setId(Integer id) { + this.id = id; + } + + /** + * @return the login + * @see #login + */ + public String getLogin() { + return login; + } + + /** + * @param login + * the login to set + * @see #login + */ + public void setLogin(String login) { + this.login = login; + } + + /** + * @return the cryptedPassword + * @see #cryptedPassword + */ + public String getCryptedPassword() { + return cryptedPassword; + } + + /** + * @param cryptedPassword + * the cryptedPassword to set + * @see #cryptedPassword + */ + public void setCryptedPassword(String cryptedPassword) { + this.cryptedPassword = cryptedPassword; + } + + /** + * @return the name + * @see #name + */ + public String getName() { + return name; + } + + /** + * @param name + * the name to set + * @see #name + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the surname + * @see #surname + */ + public String getSurname() { + return surname; + } + + /** + * @param surname + * the surname to set + * @see #surname + */ + public void setSurname(String surname) { + this.surname = surname; + } + + /** + * @return the email + * @see #email + */ + public String getEmail() { + return email; + } + + /** + * @param email + * the email to set + * @see #email + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * @return the privileges + * @see #privileges + */ + public Set<BasicPrivilege> getPrivileges() { + return privileges; + } + + /** + * @param privileges + * the privileges to set + * @see #privileges + */ + public void setPrivileges(Set<BasicPrivilege> privileges) { + this.privileges = privileges; + } + + /** + * @return the removed + * @see #removed + */ + public boolean isRemoved() { + return removed; + } + + /** + * @param removed + * the removed to set + * @see #removed + */ + public void setRemoved(boolean removed) { + this.removed = removed; + } + + /** + * @return the annotationSchema + * @see #annotationSchema + */ + public UserAnnotationSchema getAnnotationSchema() { + return annotationSchema; + } + + /** + * @param annotationSchema + * the annotationSchema to set + * @see #annotationSchema + */ + public void setAnnotationSchema(UserAnnotationSchema annotationSchema) { + this.annotationSchema = annotationSchema; + if (!this.equals(annotationSchema.getUser())) { + annotationSchema.setUser(this); + } + } + + @Override + public String toString() { + return "[" + this.getClass().getSimpleName() + "] " + getName() + " " + getSurname(); + } + + /** + * @return the minColor + * @see #minColor + */ + public Color getMinColor() { + return minColor; + } + + /** + * @param minColor + * the minColor to set + * @see #minColor + */ + public void setMinColor(Color minColor) { + this.minColor = minColor; + } + + /** + * @return the maxColor + * @see #maxColor + */ + public Color getMaxColor() { + return maxColor; + } + + /** + * @param maxColor + * the maxColor to set + * @see #maxColor + */ + public void setMaxColor(Color maxColor) { + this.maxColor = maxColor; + } + +} diff --git a/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java b/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java index 181cce38fadefea6779a548ccf367130209b1207..afeb53d81fd42d5d4e12e6d71dfe3e2891d8da3b 100644 --- a/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java +++ b/model/src/test/java/lcsb/mapviewer/model/map/layout/ColorSchemaTest.java @@ -2,7 +2,6 @@ package lcsb.mapviewer.model.map.layout; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; import java.awt.Color; import java.util.ArrayList; @@ -75,73 +74,6 @@ public class ColorSchemaTest { } } - @Test - public void testSetInvalidColor() throws Exception { - try { - ColorSchema cs = new GenericColorSchema(); - cs.setColor("qwe"); - fail("Exception expected"); - } catch (InvalidColorSchemaException e) { - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testSetInvalidColor2() throws Exception { - try { - ColorSchema cs = new GenericColorSchema(); - cs.setColor("fffffff"); - fail("Exception expected"); - } catch (InvalidColorSchemaException e) { - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testSetColor() throws Exception { - try { - ColorSchema cs = new GenericColorSchema(); - cs.setColor("#ffffff"); - assertEquals(Color.WHITE, cs.getColor()); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetColorForValue() throws Exception { - try { - ColorSchema cs = new GenericColorSchema(); - assertEquals(Color.GREEN, cs.getColorForValue(1.0)); - assertEquals(Color.RED, cs.getColorForValue(-1.0)); - assertEquals(Color.WHITE, cs.getColorForValue(0.0)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testGetNormalizedColor() throws Exception { - try { - ColorSchema cs = new GenericColorSchema(); - cs.setColor(Color.BLUE); - assertEquals(Color.BLUE, cs.getNormalizedColor()); - - cs = new GenericColorSchema(); - cs.setValue(1.0); - assertEquals(Color.GREEN, cs.getNormalizedColor()); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - @Test public void testToString() throws Exception { try { diff --git a/persist/src/db/10.0.3/fix_db_20161012.sql b/persist/src/db/10.0.3/fix_db_20161012.sql new file mode 100644 index 0000000000000000000000000000000000000000..feb19a62f92713f41e2972391a17379c6f2c2410 --- /dev/null +++ b/persist/src/db/10.0.3/fix_db_20161012.sql @@ -0,0 +1,2 @@ +alter table user_table add column maxcolor bytea; +alter table user_table add column mincolor bytea; diff --git a/service/pom.xml b/service/pom.xml index b91fcbc8c5ff6cbe6ff2cd8490c47a7cb47ea531..683846f0af0938281b311caf2ece1656b55c0516 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -1,122 +1,131 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 - http://maven.apache.org/xsd/maven-4.0.0.xsd"> - - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>lcsb.mapviewer</groupId> - <artifactId>parent</artifactId> - <version>1.0</version> - </parent> - - <artifactId>service</artifactId> - <name>Service layer</name> - - <dependencies> - - <!-- dependency from the MapViewer model --> - - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>model</artifactId> - <version>1.0</version> - </dependency> - - <!-- dependency from the MapViewer dao --> - - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>persist</artifactId> - <version>1.0</version> - </dependency> - - <!-- dependency from the MapViewer dao --> - - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>model-command</artifactId> - <version>1.0</version> - </dependency> - - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>annotation</artifactId> - <version>1.0</version> - </dependency> - - <!-- dependency from the MapViewer cell designer parser --> - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>converter-CellDesigner</artifactId> - <version>1.0</version> - </dependency> - - <!-- dependency from the MapViewer SBGN-ML parser --> - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>converter-SBGNML</artifactId> - <version>1.0</version> - </dependency> - - <!-- dependency from the MapViewer graphics converter --> - <dependency> - <groupId>lcsb.mapviewer</groupId> - <artifactId>converter-graphics</artifactId> - <version>1.0</version> - </dependency> - - <!-- Log4J --> - <dependency> - <groupId>log4j</groupId> - <artifactId>log4j</artifactId> - <version>${log4j.version}</version> - </dependency> - - <!-- Spring --> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - <version>${springframework.version}</version> - </dependency> - - <!-- Primefaces, used for overlay objects that are passed to the client - side --> - <dependency> - <groupId>org.primefaces</groupId> - <artifactId>primefaces</artifactId> - <version>${primafaces.version}</version> - </dependency> - - <!-- Jsf, used for objects that are passed to the client side --> - <dependency> - <groupId>com.sun.faces</groupId> - <artifactId>jsf-api</artifactId> - <version>${jsf.version}</version> - </dependency> - - <!-- Gson --> - <dependency> - <groupId>com.google.code.gson</groupId> - <artifactId>gson</artifactId> - <version>${gson.version}</version> - <scope>compile</scope> - </dependency> - - <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi</artifactId> - <version>3.10-FINAL</version> - </dependency> - <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi</artifactId> - <version>3.12</version> - </dependency> - <dependency> - <groupId>org.apache.poi</groupId> - <artifactId>poi-ooxml</artifactId> - <version>3.12</version> - </dependency> - </dependencies> - +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>lcsb.mapviewer</groupId> + <artifactId>parent</artifactId> + <version>1.0</version> + </parent> + + <artifactId>service</artifactId> + <name>Service layer</name> + + <dependencies> + + <!-- dependency from the MapViewer model --> + + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>model</artifactId> + <version>1.0</version> + </dependency> + + <!-- dependency from the MapViewer dao --> + + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>persist</artifactId> + <version>1.0</version> + </dependency> + + <!-- dependency from the MapViewer dao --> + + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>model-command</artifactId> + <version>1.0</version> + </dependency> + + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>annotation</artifactId> + <version>1.0</version> + </dependency> + + <!-- dependency from the MapViewer cell designer parser --> + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>converter-CellDesigner</artifactId> + <version>1.0</version> + </dependency> + + <!-- dependency from the MapViewer SBGN-ML parser --> + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>converter-SBGNML</artifactId> + <version>1.0</version> + </dependency> + + <!-- dependency from the MapViewer graphics converter --> + <dependency> + <groupId>lcsb.mapviewer</groupId> + <artifactId>converter-graphics</artifactId> + <version>1.0</version> + </dependency> + + <!-- Log4J --> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>${log4j.version}</version> + </dependency> + + <!-- Spring --> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${springframework.version}</version> + </dependency> + + <!-- Primefaces, used for overlay objects that are passed to the client + side --> + <dependency> + <groupId>org.primefaces</groupId> + <artifactId>primefaces</artifactId> + <version>${primafaces.version}</version> + </dependency> + + <!-- Jsf, used for objects that are passed to the client side --> + <dependency> + <groupId>com.sun.faces</groupId> + <artifactId>jsf-api</artifactId> + <version>${jsf.version}</version> + </dependency> + + <!-- Gson --> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>${gson.version}</version> + <scope>compile</scope> + </dependency> + + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi</artifactId> + <version>3.10-FINAL</version> + </dependency> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi</artifactId> + <version>3.12</version> + </dependency> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>poi-ooxml</artifactId> + <version>3.12</version> + </dependency> + +<!-- mockito used for testing --> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <version>${mockito.version}</version> + <scope>test</scope> + </dependency> + + </dependencies> + </project> \ No newline at end of file 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 599b71bcf3e310bead3f33ac8917bd173c143aca..b01498f5f532dc6c23274980a15b9b4f43c4071a 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/LayoutService.java @@ -1,5 +1,6 @@ package lcsb.mapviewer.services.impl; +import java.awt.Color; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -10,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.annotation.PostConstruct; import javax.mail.MessagingException; import org.apache.commons.io.IOUtils; @@ -18,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import lcsb.mapviewer.annotation.services.MiriamConnector; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorModelCommand; import lcsb.mapviewer.commands.CommandExecutionException; import lcsb.mapviewer.commands.CopyCommand; @@ -119,6 +122,19 @@ public class LayoutService implements ILayoutService { @Autowired private DbUtils dbUtils; + /** + * Object that sends emails. + */ + private EmailSender emailSender; + + /** + * Method called after spring initialized all interfaces. + */ + @PostConstruct + public void springInit() { + emailSender = new EmailSender(configurationService); + } + @Override public boolean userCanAddLayout(Model model, User user) { // if we don't have privileges to view the object then we cannot add layouts @@ -277,8 +293,7 @@ public class LayoutService implements ILayoutService { final Collection<ColorSchema> schemas = reader .readColorSchema(params.getColorInputStream(), TextFileUtils.getHeaderParametersFromFile(params.getColorInputStream())); final Model colorModel = new CopyCommand(params.getModel()).execute(); - new ColorModelCommand(params.getModel(), schemas).execute(); - final EmailSender sender = new EmailSender(configurationService); + new ColorModelCommand(params.getModel(), schemas, userService.getColorExtractorForUser(params.getUser())).execute(); String[] tmp = params.getDirectory().split("[\\\\/]"); String simpleDir = tmp[tmp.length - 1]; @@ -291,7 +306,7 @@ public class LayoutService implements ILayoutService { dbUtils.createSessionForCurrentThread(); } } - final Map<Model, Integer> layoutIdByModel = new HashMap<Model, Integer>(); + final Map<Model, Integer> layoutIdByModel = new HashMap<>(); Layout topLayout = new Layout(params.getName(), simpleDir, false); if (params.getUser() == null) { @@ -400,7 +415,7 @@ public class LayoutService implements ILayoutService { layoutDao.update(layout); try { - sender.sendEmail( + emailSender.sendEmail( "MapViewer status", "There was a problem with generating layout " + params.getName() + ". Contact administrator to solve this issue.", params.getUser()); } catch (MessagingException e1) { @@ -432,7 +447,7 @@ public class LayoutService implements ILayoutService { // check if we can color our model using this schema, // if not then exception will be thrown and passed up try { - new ColorModelCommand(params.getModel(), schemas).execute(); + new ColorModelCommand(params.getModel(), schemas, userService.getColorExtractorForUser(params.getUser())).execute(); } catch (CommandExecutionException e) { throw new InvalidColorSchemaException(e); } @@ -601,7 +616,6 @@ public class LayoutService implements ILayoutService { * thrown when there is a problem with sending email */ protected void sendSuccesfullRemoveEmail(String projectId, String layoutName, String email) throws MessagingException { - EmailSender emailSender = new EmailSender(configurationService); StringBuilder content = new StringBuilder("Layout " + layoutName + " in map " + projectId + " was successfully removed.<br/>"); emailSender.sendEmail("MapViewer notification", content.toString(), email); } @@ -617,7 +631,6 @@ public class LayoutService implements ILayoutService { * thrown when there is a problem with sending email */ protected void sendSuccessfullGenerationEmail(final CreateLayoutParams params, final Collection<ColorSchema> schemas) throws MessagingException { - EmailSender emailSender = new EmailSender(configurationService); StringBuilder content = new StringBuilder("Layout " + params.getName() + " generated successfully.\n"); content.append("Result of coloring:<br/>"); @@ -886,9 +899,9 @@ public class LayoutService implements ILayoutService { public List<LightLayoutAliasView> getAliasesForLayout(Model model, int layoutId) { try { ColorSchemaReader reader = new ColorSchemaReader(); - Collection<ColorSchema> schemas; - schemas = reader.readColorSchema(getInputDataForLayout(layoutId)); - ColorModelCommand command = new ColorModelCommand(model, schemas); + Collection<ColorSchema> schemas = reader.readColorSchema(getInputDataForLayout(layoutId)); + // colors here are not important + ColorModelCommand command = new ColorModelCommand(model, schemas, new ColorExtractor(Color.BLACK, Color.BLACK)); LightLayoutAliasViewFactory factory = new LightLayoutAliasViewFactory(); List<LightLayoutAliasView> result = new ArrayList<>(); for (Map.Entry<Object, ColorSchema> entry : command.getModifiedElements().entrySet()) { @@ -908,9 +921,9 @@ public class LayoutService implements ILayoutService { public List<LightLayoutReactionView> getReactionsForLayout(Model model, int layoutId) { try { ColorSchemaReader reader = new ColorSchemaReader(); - Collection<ColorSchema> schemas; - schemas = reader.readColorSchema(getInputDataForLayout(layoutId)); - ColorModelCommand command = new ColorModelCommand(model, schemas); + Collection<ColorSchema> schemas = reader.readColorSchema(getInputDataForLayout(layoutId)); + // colors here are not important + ColorModelCommand command = new ColorModelCommand(model, schemas, new ColorExtractor(Color.BLACK, Color.BLACK)); LightLayoutReactionViewFactory factory = new LightLayoutReactionViewFactory(); List<LightLayoutReactionView> result = new ArrayList<>(); for (Map.Entry<Object, ColorSchema> entry : command.getModifiedElements().entrySet()) { @@ -932,7 +945,8 @@ public class LayoutService implements ILayoutService { ColorSchemaReader reader = new ColorSchemaReader(); Collection<ColorSchema> schemas; schemas = reader.readColorSchema(getInputDataForLayout(layoutId)); - ColorModelCommand command = new ColorModelCommand(model, schemas); + // colors here are not important + ColorModelCommand command = new ColorModelCommand(model, schemas, new ColorExtractor(Color.BLACK, Color.BLACK)); return command.getModifiedElements(); } catch (InvalidColorSchemaException e) { throw new InvalidStateException(e); @@ -952,7 +966,8 @@ public class LayoutService implements ILayoutService { ColorSchemaReader reader = new ColorSchemaReader(); Collection<ColorSchema> schemas; schemas = reader.readColorSchema(getInputDataForLayout(layoutId)); - ColorModelCommand command = new ColorModelCommand(model, schemas); + // colors here are not important + ColorModelCommand command = new ColorModelCommand(model, schemas, new ColorExtractor(Color.BLACK, Color.BLACK)); FullLayoutAliasViewFactory factory = new FullLayoutAliasViewFactory(); List<FullLayoutAliasView> result = new ArrayList<>(); @@ -972,4 +987,14 @@ public class LayoutService implements ILayoutService { throw new InvalidStateException(e); } } + + @Override + public EmailSender getEmailSender() { + return emailSender; + } + + @Override + public void setEmailSender(EmailSender emailSender) { + this.emailSender = emailSender; + } } diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java index d011bcb4568127dbafedbae38010cb727c10897b..8288bfdfce3141b5d603d23824545f7fb2b43517 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java @@ -36,7 +36,7 @@ import lcsb.mapviewer.annotation.services.TaxonomyBackend; import lcsb.mapviewer.annotation.services.TaxonomySearchException; import lcsb.mapviewer.annotation.services.annotators.AnnotatorException; import lcsb.mapviewer.annotation.services.annotators.ElementAnnotator; -import lcsb.mapviewer.commands.ColorModelCommand; +import lcsb.mapviewer.commands.ClearColorModelCommand; import lcsb.mapviewer.commands.CommandExecutionException; import lcsb.mapviewer.commands.CopyCommand; import lcsb.mapviewer.commands.CreateHierarchyCommand; @@ -603,7 +603,7 @@ public class ProjectService implements IProjectService { } if (layout.getTitle().equals(BuildInLayout.CLEAN.getTitle())) { output = new CopyCommand(model).execute(); - new ColorModelCommand(output, new ArrayList<>()).execute(); + new ClearColorModelCommand(output).execute(); } final double imgCounter = counter; diff --git a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java index 4b7a98cd2e38534eb5cbe89fa1666352e5400f8d..3687c437bd4d143220891a882d28d5115eea1021 100644 --- a/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java +++ b/service/src/main/java/lcsb/mapviewer/services/impl/UserService.java @@ -1,419 +1,465 @@ -package lcsb.mapviewer.services.impl; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import lcsb.mapviewer.common.ObjectUtils; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.model.Project; -import lcsb.mapviewer.model.log.LogType; -import lcsb.mapviewer.model.user.BasicPrivilege; -import lcsb.mapviewer.model.user.ObjectPrivilege; -import lcsb.mapviewer.model.user.PrivilegeType; -import lcsb.mapviewer.model.user.User; -import lcsb.mapviewer.persist.dao.ProjectDao; -import lcsb.mapviewer.persist.dao.user.PrivilegeDao; -import lcsb.mapviewer.persist.dao.user.UserDao; -import lcsb.mapviewer.services.interfaces.ILogService; -import lcsb.mapviewer.services.interfaces.ILogService.LogParams; -import lcsb.mapviewer.services.interfaces.IUserService; -import lcsb.mapviewer.services.view.PrivilegeView; -import lcsb.mapviewer.services.view.UserView; -import lcsb.mapviewer.services.view.UserView.UserProjectPrivilegeView; -import lcsb.mapviewer.services.view.UserViewFactory; - -import org.apache.log4j.Logger; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.transaction.annotation.Transactional; - -/** - * Implementation of the service that manages users. - * - * @author Piotr Gawron - * - */ -@Transactional(value = "txManager") -public class UserService implements IUserService { - /** - * Default class logger. - */ - private static Logger logger = Logger.getLogger(UserService.class); - - /** - * Data access object for users. - */ - @Autowired - private UserDao userDao; - - /** - * Data access object for projects. - */ - @Autowired - private ProjectDao projectDao; - - /** - * Data access object for privileges. - */ - @Autowired - private PrivilegeDao privilegeDao; - - /** - * Factory object for {@link UserView} elements. - */ - @Autowired - private UserViewFactory userViewFactory; - - /** - * Service that provides password encoding. - */ - @Autowired - private PasswordEncoder passwordEncoder; - - /** - * Service used for logging. - */ - @Autowired - private ILogService logService; - - @Override - public boolean login(String login, String password) { - return userDao.getUserByLoginAndPassword(login, password) != null; - } - - @Override - public boolean userHasPrivilege(User user, PrivilegeType type) { - return getUserPrivilegeLevel(user, type) > 0; - } - - @Override - public boolean userHasPrivilege(User user, PrivilegeType type, Object object) { - return getUserPrivilegeLevel(user, type, object) > 0; - } - - @Override - public void setUserPrivilege(User user, BasicPrivilege privilege) { - privilege.setUser(user); - BasicPrivilege oldPrivilege = null; - for (BasicPrivilege privilegeIter : user.getPrivileges()) { - if (privilegeIter.equalsPrivilege(privilege)) { - oldPrivilege = privilegeIter; - } - } - if (oldPrivilege != null) { - user.getPrivileges().remove(oldPrivilege); - oldPrivilege.setUser(null); - } - user.getPrivileges().add(privilege); - updateUser(user); - userDao.flush(); - } - - @Override - public void addUser(User user) { - userDao.add(user); - LogParams params = new LogParams().description("User " + user.getLogin() + " created.") - .type(LogType.USER_CREATED).object(user); - logService.log(params); - } - - @Override - public void updateUser(User user) { - userDao.update(user); - } - - @Override - public void deleteUser(User user) { - userDao.delete(user); - LogParams params = new LogParams().description("User " + user.getLogin() + " removed.") - .type(LogType.USER_CREATED).object(user); - logService.log(params); - } - - @Override - public User getUserById(int id) { - User result = userDao.getById(id); - if (result != null) { - userDao.refresh(result); - } - return result; - } - - @Override - public User getUserByLogin(String login) { - User result = userDao.getUserByLogin(login); - if (result != null) { - userDao.refresh(result); - } - return result; - } - - @Override - public List<UserView> getAllUserRows() { - List<Project> projects = projectDao.getAll(); - - List<UserView> result = new ArrayList<UserView>(); - List<User> fullList = userDao.getAll(); - for (User user : fullList) { - result.add(userViewFactory.create(user, projects)); - } - - return result; - } - - @Override - public UserView getUserRow(User user) { - List<Project> projects = projectDao.getAll(); - return userViewFactory.create(user, projects); - } - - @Override - public void updateUser(UserView userRow) { - User user = null; - if (userRow.getIdObject() == null || userRow.getIdObject() == 0) { - user = new User(); - user.setLogin(userRow.getLogin()); - } else { - user = getUserById(userRow.getIdObject()); - } - if (userRow.getPassword() != null && !userRow.getPassword().trim().equals("")) { - user.setCryptedPassword(passwordEncoder.encode(userRow.getPassword())); - } - - user.setEmail(userRow.getEmail()); - user.setName(userRow.getName()); - user.setSurname(userRow.getSurname()); - if (user.getId() == null) { - addUser(user); - } else { - updateUser(user); - } - - userRow.setIdObject(user.getId()); - - for (PrivilegeView pRow : userRow.getBasicPrivileges()) { - if (pRow.getNumeric()) { - setUserPrivilege(user, new BasicPrivilege(pRow.getLevel(), pRow.getType(), user)); - } else if (pRow.getSelected()) { - setUserPrivilege(user, new BasicPrivilege(1, pRow.getType(), user)); - } else { - setUserPrivilege(user, new BasicPrivilege(0, pRow.getType(), user)); - } - } - for (UserProjectPrivilegeView upRow : userRow.getProjectPrivileges()) { - for (PrivilegeView pRow : upRow.getProjectPrivileges()) { - Project project = projectDao.getById(upRow.getIdObject()); - if (pRow.getNumeric()) { - setUserPrivilege(user, new ObjectPrivilege(project, pRow.getLevel(), pRow.getType(), user)); - } else if (pRow.getSelected()) { - setUserPrivilege(user, new ObjectPrivilege(project, 1, pRow.getType(), user)); - } else { - setUserPrivilege(user, new ObjectPrivilege(project, 0, pRow.getType(), user)); - } - } - } - } - - @Override - public void deleteUser(UserView selectedUser) { - if (selectedUser.getIdObject() != null && selectedUser.getIdObject() != 0) { - deleteUser(getUserById(selectedUser.getIdObject())); - } - } - - @Override - public void dropPrivilegesForObjectType(PrivilegeType type, int id) { - // this will be slow when number of user will increase (we fetch all - // users and drop privileges one by one) - List<User> users = userDao.getAll(); - for (User user : users) { - List<BasicPrivilege> toRemove = new ArrayList<BasicPrivilege>(); - for (BasicPrivilege privilege : user.getPrivileges()) { - if (privilege.getType().equals(type) && privilege instanceof ObjectPrivilege - && ((ObjectPrivilege) privilege).getIdObject() == id) { - toRemove.add(privilege); - } - } - if (toRemove.size() > 0) { - user.getPrivileges().removeAll(toRemove); - userDao.update(user); - } - } - } - - @Override - public int getUserPrivilegeLevel(User user, PrivilegeType type) { - if (type.getPrivilegeClassType() != BasicPrivilege.class) { - throw new InvalidArgumentException("This privilege requires additional information"); - } - for (BasicPrivilege privilege : user.getPrivileges()) { - if (privilege.getType().equals(type)) { - return privilege.getLevel(); - } - } - return 0; - } - - @Override - public int getUserPrivilegeLevel(User user, PrivilegeType type, Object object) { - if (type.getPrivilegeClassType() != ObjectPrivilege.class) { - throw new InvalidArgumentException("This privilege doesn't accept object parameter"); - } - if (object == null) { - throw new InvalidArgumentException("Object cannot be null"); - } - if (!type.getPrivilegeObjectType().isAssignableFrom(object.getClass())) { - throw new InvalidArgumentException("This privilege accept only " + type.getPrivilegeObjectType() - + " objects parameter, but " + object.getClass() + " class found."); - } - Integer id = null; - try { - id = ObjectUtils.getIdOfObject(object); - } catch (Exception e) { - logger.error(e.getMessage(), e); - throw new InvalidArgumentException( - "Internal server error. Problem with accessing id of the parameter object"); - } - if (id == null) { - throw new InvalidArgumentException("Parameter object has null id value"); - } - if (user == null) { - throw new InvalidArgumentException("User cannot be null"); - } - - // refresh user from db - if (user.getId() != null) { - user = userDao.getById(user.getId()); - } - for (BasicPrivilege privilege : user.getPrivileges()) { - if (privilege.getClass() == ObjectPrivilege.class) { - ObjectPrivilege oPrivilege = (ObjectPrivilege) privilege; - if (oPrivilege.getType().equals(type) && oPrivilege.getIdObject().equals(id)) { - return privilege.getLevel(); - } - } - } - return -1; - } - - @Override - public void addUser(UserView userRow) { - updateUser(userRow); - } - - @Override - public void setUserPrivilege(User user, PrivilegeType type) { - BasicPrivilege privilege = new BasicPrivilege(1, type, user); - - BasicPrivilege oldPrivilege = null; - for (BasicPrivilege privilegeIter : user.getPrivileges()) { - if (privilegeIter.getType().equals(type)) { - oldPrivilege = privilegeIter; - } - } - if (oldPrivilege != null) { - user.getPrivileges().remove(oldPrivilege); - oldPrivilege.setUser(null); - } - user.getPrivileges().add(privilege); - updateUser(user); - userDao.flush(); - - } - - /** - * @return the userDao - * @see #userDao - */ - public UserDao getUserDao() { - return userDao; - } - - /** - * @param userDao - * the userDao to set - * @see #userDao - */ - public void setUserDao(UserDao userDao) { - this.userDao = userDao; - } - - /** - * @return the projectDao - * @see #projectDao - */ - public ProjectDao getProjectDao() { - return projectDao; - } - - /** - * @param projectDao - * the projectDao to set - * @see #projectDao - */ - public void setProjectDao(ProjectDao projectDao) { - this.projectDao = projectDao; - } - - /** - * @return the privilegeDao - * @see #privilegeDao - */ - public PrivilegeDao getPrivilegeDao() { - return privilegeDao; - } - - /** - * @param privilegeDao - * the privilegeDao to set - * @see #privilegeDao - */ - public void setPrivilegeDao(PrivilegeDao privilegeDao) { - this.privilegeDao = privilegeDao; - } - - /** - * @return the passwordEncoder - * @see #passwordEncoder - */ - public PasswordEncoder getPasswordEncoder() { - return passwordEncoder; - } - - /** - * @param passwordEncoder - * the passwordEncoder to set - * @see #passwordEncoder - */ - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { - this.passwordEncoder = passwordEncoder; - } - - @Override - public UserView createEmptyUserRow() { - return userViewFactory.create(null); - } - - @Override - public void updateUsers(Collection<UserView> users) { - for (UserView user : users) { - updateUser(user); - } - } - - /** - * @param password - * input password - * @return encoded password - */ - @Override - public String encodePassword(String password) { - return passwordEncoder.encode(password); - } - - @Override - public User getUserByNameSurname(String nameSurnameString) { - return userDao.getUserByNameSurname(nameSurnameString); - } -} +package lcsb.mapviewer.services.impl; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.transaction.annotation.Transactional; + +import lcsb.mapviewer.commands.ColorExtractor; +import lcsb.mapviewer.common.ObjectUtils; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.common.geometry.ColorParser; +import lcsb.mapviewer.model.Project; +import lcsb.mapviewer.model.log.LogType; +import lcsb.mapviewer.model.user.BasicPrivilege; +import lcsb.mapviewer.model.user.ConfigurationElementType; +import lcsb.mapviewer.model.user.ObjectPrivilege; +import lcsb.mapviewer.model.user.PrivilegeType; +import lcsb.mapviewer.model.user.User; +import lcsb.mapviewer.persist.dao.ProjectDao; +import lcsb.mapviewer.persist.dao.user.PrivilegeDao; +import lcsb.mapviewer.persist.dao.user.UserDao; +import lcsb.mapviewer.services.interfaces.IConfigurationService; +import lcsb.mapviewer.services.interfaces.ILogService; +import lcsb.mapviewer.services.interfaces.ILogService.LogParams; +import lcsb.mapviewer.services.interfaces.IUserService; +import lcsb.mapviewer.services.view.PrivilegeView; +import lcsb.mapviewer.services.view.UserView; +import lcsb.mapviewer.services.view.UserView.UserProjectPrivilegeView; +import lcsb.mapviewer.services.view.UserViewFactory; + +/** + * Implementation of the service that manages users. + * + * @author Piotr Gawron + * + */ +@Transactional(value = "txManager") +public class UserService implements IUserService { + /** + * Default class logger. + */ + private static Logger logger = Logger.getLogger(UserService.class); + + /** + * Data access object for users. + */ + @Autowired + private UserDao userDao; + + /** + * Data access object for projects. + */ + @Autowired + private ProjectDao projectDao; + + /** + * Data access object for privileges. + */ + @Autowired + private PrivilegeDao privilegeDao; + + /** + * Factory object for {@link UserView} elements. + */ + @Autowired + private UserViewFactory userViewFactory; + + /** + * Service that provides password encoding. + */ + @Autowired + private PasswordEncoder passwordEncoder; + + /** + * Service used for logging. + */ + @Autowired + private ILogService logService; + + /** + * Service used for accessing confguration parameters. + */ + @Autowired + private IConfigurationService configurationService; + + @Override + public boolean login(String login, String password) { + return userDao.getUserByLoginAndPassword(login, password) != null; + } + + @Override + public boolean userHasPrivilege(User user, PrivilegeType type) { + return getUserPrivilegeLevel(user, type) > 0; + } + + @Override + public boolean userHasPrivilege(User user, PrivilegeType type, Object object) { + return getUserPrivilegeLevel(user, type, object) > 0; + } + + @Override + public void setUserPrivilege(User user, BasicPrivilege privilege) { + privilege.setUser(user); + BasicPrivilege oldPrivilege = null; + for (BasicPrivilege privilegeIter : user.getPrivileges()) { + if (privilegeIter.equalsPrivilege(privilege)) { + oldPrivilege = privilegeIter; + } + } + if (oldPrivilege != null) { + user.getPrivileges().remove(oldPrivilege); + oldPrivilege.setUser(null); + } + user.getPrivileges().add(privilege); + updateUser(user); + userDao.flush(); + } + + @Override + public void addUser(User user) { + userDao.add(user); + LogParams params = new LogParams().description("User " + user.getLogin() + " created.").type(LogType.USER_CREATED).object(user); + logService.log(params); + } + + @Override + public void updateUser(User user) { + userDao.update(user); + } + + @Override + public void deleteUser(User user) { + userDao.delete(user); + LogParams params = new LogParams().description("User " + user.getLogin() + " removed.").type(LogType.USER_CREATED).object(user); + logService.log(params); + } + + @Override + public User getUserById(int id) { + User result = userDao.getById(id); + if (result != null) { + userDao.refresh(result); + } + return result; + } + + @Override + public User getUserByLogin(String login) { + User result = userDao.getUserByLogin(login); + if (result != null) { + userDao.refresh(result); + } + return result; + } + + @Override + public List<UserView> getAllUserRows() { + List<Project> projects = projectDao.getAll(); + + List<UserView> result = new ArrayList<UserView>(); + List<User> fullList = userDao.getAll(); + for (User user : fullList) { + result.add(userViewFactory.create(user, projects)); + } + + return result; + } + + @Override + public UserView getUserRow(User user) { + List<Project> projects = projectDao.getAll(); + return userViewFactory.create(user, projects); + } + + @Override + public void updateUser(UserView userRow) { + User user = null; + if (userRow.getIdObject() == null || userRow.getIdObject() == 0) { + user = new User(); + user.setLogin(userRow.getLogin()); + } else { + user = getUserById(userRow.getIdObject()); + } + if (userRow.getPassword() != null && !userRow.getPassword().trim().equals("")) { + user.setCryptedPassword(passwordEncoder.encode(userRow.getPassword())); + } + + user.setEmail(userRow.getEmail()); + user.setName(userRow.getName()); + user.setSurname(userRow.getSurname()); + if (user.getId() == null) { + addUser(user); + } else { + updateUser(user); + } + + userRow.setIdObject(user.getId()); + + for (PrivilegeView pRow : userRow.getBasicPrivileges()) { + if (pRow.getNumeric()) { + setUserPrivilege(user, new BasicPrivilege(pRow.getLevel(), pRow.getType(), user)); + } else if (pRow.getSelected()) { + setUserPrivilege(user, new BasicPrivilege(1, pRow.getType(), user)); + } else { + setUserPrivilege(user, new BasicPrivilege(0, pRow.getType(), user)); + } + } + for (UserProjectPrivilegeView upRow : userRow.getProjectPrivileges()) { + for (PrivilegeView pRow : upRow.getProjectPrivileges()) { + Project project = projectDao.getById(upRow.getIdObject()); + if (pRow.getNumeric()) { + setUserPrivilege(user, new ObjectPrivilege(project, pRow.getLevel(), pRow.getType(), user)); + } else if (pRow.getSelected()) { + setUserPrivilege(user, new ObjectPrivilege(project, 1, pRow.getType(), user)); + } else { + setUserPrivilege(user, new ObjectPrivilege(project, 0, pRow.getType(), user)); + } + } + } + } + + @Override + public void deleteUser(UserView selectedUser) { + if (selectedUser.getIdObject() != null && selectedUser.getIdObject() != 0) { + deleteUser(getUserById(selectedUser.getIdObject())); + } + } + + @Override + public void dropPrivilegesForObjectType(PrivilegeType type, int id) { + // this will be slow when number of user will increase (we fetch all + // users and drop privileges one by one) + List<User> users = userDao.getAll(); + for (User user : users) { + List<BasicPrivilege> toRemove = new ArrayList<BasicPrivilege>(); + for (BasicPrivilege privilege : user.getPrivileges()) { + if (privilege.getType().equals(type) && privilege instanceof ObjectPrivilege && ((ObjectPrivilege) privilege).getIdObject() == id) { + toRemove.add(privilege); + } + } + if (toRemove.size() > 0) { + user.getPrivileges().removeAll(toRemove); + userDao.update(user); + } + } + } + + @Override + public int getUserPrivilegeLevel(User user, PrivilegeType type) { + if (type.getPrivilegeClassType() != BasicPrivilege.class) { + throw new InvalidArgumentException("This privilege requires additional information"); + } + for (BasicPrivilege privilege : user.getPrivileges()) { + if (privilege.getType().equals(type)) { + return privilege.getLevel(); + } + } + return 0; + } + + @Override + public int getUserPrivilegeLevel(User user, PrivilegeType type, Object object) { + if (type.getPrivilegeClassType() != ObjectPrivilege.class) { + throw new InvalidArgumentException("This privilege doesn't accept object parameter"); + } + if (object == null) { + throw new InvalidArgumentException("Object cannot be null"); + } + if (!type.getPrivilegeObjectType().isAssignableFrom(object.getClass())) { + throw new InvalidArgumentException( + "This privilege accept only " + type.getPrivilegeObjectType() + " objects parameter, but " + object.getClass() + " class found."); + } + Integer id = null; + try { + id = ObjectUtils.getIdOfObject(object); + } catch (Exception e) { + logger.error(e.getMessage(), e); + throw new InvalidArgumentException("Internal server error. Problem with accessing id of the parameter object"); + } + if (id == null) { + throw new InvalidArgumentException("Parameter object has null id value"); + } + if (user == null) { + throw new InvalidArgumentException("User cannot be null"); + } + + // refresh user from db + if (user.getId() != null) { + user = userDao.getById(user.getId()); + } + for (BasicPrivilege privilege : user.getPrivileges()) { + if (privilege.getClass() == ObjectPrivilege.class) { + ObjectPrivilege oPrivilege = (ObjectPrivilege) privilege; + if (oPrivilege.getType().equals(type) && oPrivilege.getIdObject().equals(id)) { + return privilege.getLevel(); + } + } + } + return -1; + } + + @Override + public void addUser(UserView userRow) { + updateUser(userRow); + } + + @Override + public void setUserPrivilege(User user, PrivilegeType type) { + BasicPrivilege privilege = new BasicPrivilege(1, type, user); + + BasicPrivilege oldPrivilege = null; + for (BasicPrivilege privilegeIter : user.getPrivileges()) { + if (privilegeIter.getType().equals(type)) { + oldPrivilege = privilegeIter; + } + } + if (oldPrivilege != null) { + user.getPrivileges().remove(oldPrivilege); + oldPrivilege.setUser(null); + } + user.getPrivileges().add(privilege); + updateUser(user); + userDao.flush(); + + } + + /** + * @return the userDao + * @see #userDao + */ + public UserDao getUserDao() { + return userDao; + } + + /** + * @param userDao + * the userDao to set + * @see #userDao + */ + public void setUserDao(UserDao userDao) { + this.userDao = userDao; + } + + /** + * @return the projectDao + * @see #projectDao + */ + public ProjectDao getProjectDao() { + return projectDao; + } + + /** + * @param projectDao + * the projectDao to set + * @see #projectDao + */ + public void setProjectDao(ProjectDao projectDao) { + this.projectDao = projectDao; + } + + /** + * @return the privilegeDao + * @see #privilegeDao + */ + public PrivilegeDao getPrivilegeDao() { + return privilegeDao; + } + + /** + * @param privilegeDao + * the privilegeDao to set + * @see #privilegeDao + */ + public void setPrivilegeDao(PrivilegeDao privilegeDao) { + this.privilegeDao = privilegeDao; + } + + /** + * @return the passwordEncoder + * @see #passwordEncoder + */ + public PasswordEncoder getPasswordEncoder() { + return passwordEncoder; + } + + /** + * @param passwordEncoder + * the passwordEncoder to set + * @see #passwordEncoder + */ + public void setPasswordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + } + + @Override + public UserView createEmptyUserRow() { + return userViewFactory.create(null); + } + + @Override + public void updateUsers(Collection<UserView> users) { + for (UserView user : users) { + updateUser(user); + } + } + + /** + * @param password + * input password + * @return encoded password + */ + @Override + public String encodePassword(String password) { + return passwordEncoder.encode(password); + } + + @Override + public User getUserByNameSurname(String nameSurnameString) { + return userDao.getUserByNameSurname(nameSurnameString); + } + + @Override + public ColorExtractor getColorExtractorForUser(User loggedUser) { + Color colorMin = null; + Color colorMax = null; + if (loggedUser != null) { + User dbUser = getUserById(loggedUser.getId()); + if (dbUser != null) { + colorMin = dbUser.getMinColor(); + colorMax = dbUser.getMaxColor(); + } + } + ColorParser parser = new ColorParser(); + + if (colorMin == null) { + colorMin = parser.parse(configurationService.getConfigurationValue(ConfigurationElementType.MIN_COLOR_VAL)); + } + if (colorMax == null) { + colorMax = parser.parse(configurationService.getConfigurationValue(ConfigurationElementType.MAX_COLOR_VAL)); + } + return new ColorExtractor(colorMin, colorMax); + } + + /** + * @return the configurationService + * @see #configurationService + */ + public IConfigurationService getConfigurationService() { + return configurationService; + } + + /** + * @param configurationService + * the configurationService to set + * @see #configurationService + */ + public void setConfigurationService(IConfigurationService configurationService) { + this.configurationService = configurationService; + } +} diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java index 98a3696f4e2b3840ae8f7e62fe5b1a0a7096c57c..853599bdbb9c9376b149be8a73ab9a802c49d40a 100644 --- a/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java +++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/ILayoutService.java @@ -16,6 +16,7 @@ import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.services.search.layout.FullLayoutAliasView; import lcsb.mapviewer.services.search.layout.LightLayoutAliasView; import lcsb.mapviewer.services.search.layout.LightLayoutReactionView; +import lcsb.mapviewer.services.utils.EmailSender; import lcsb.mapviewer.services.utils.data.ColorSchemaType; import lcsb.mapviewer.services.view.LayoutView; @@ -491,4 +492,19 @@ public interface ILayoutService { */ List<FullLayoutAliasView> getFullAliasesForLayoutByIds(Model model, List<Pair<Integer, Integer>> identifiers, int layoutId); + /** + * Returns {@link EmailSender} used by the service. + * + * @return {@link EmailSender} used by the service + */ + EmailSender getEmailSender(); + + /** + * Sets {@link EmailSender} used by the service. + * + * @param emailSender + * {@link EmailSender} used by the service + */ + void setEmailSender(EmailSender emailSender); + } diff --git a/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java b/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java index 67042365b9f581f49455236b6a33305f1779aa1c..aed818b54d8a58a0aa67476ba7cc40cf6f7e8dfe 100644 --- a/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java +++ b/service/src/main/java/lcsb/mapviewer/services/interfaces/IUserService.java @@ -1,230 +1,241 @@ -package lcsb.mapviewer.services.interfaces; - -import java.util.Collection; -import java.util.List; - -import lcsb.mapviewer.model.user.BasicPrivilege; -import lcsb.mapviewer.model.user.PrivilegeType; -import lcsb.mapviewer.model.user.User; -import lcsb.mapviewer.services.view.UserView; - -/** - * Service that manages users. - * - * @author Piotr Gawron - * - */ -public interface IUserService { - /** - * Check if its possible to login using given login and password. - * - * @param login - * user login - * @param password - * plan password - * @return <code>true</code> if credentials are ok, <code>false</code> - * otherwise - */ - boolean login(String login, String password); - - /** - * Returns user by login. - * - * @param login - * user login - * @return user if the login is valid, <code>null</code> otherwise - */ - User getUserByLogin(String login); - - /** - * Checks if user has a given privilege. - * - * @param user - * user for which the check is performed - * @param type - * type of the privilege - * @return <code>true</code> if user has privilege, <code>false</code> - * otherwise - */ - boolean userHasPrivilege(User user, PrivilegeType type); - - /** - * Returns level of the user privilege. - * - * @param user - * user for which the check is performed - * @param type - * type of the privilege - * @return level of the privilege - */ - int getUserPrivilegeLevel(User user, PrivilegeType type); - - /** - * Checks if user has a given privilege on the object. - * - * @param user - * user for which the check is performed - * @param type - * type of the privilege - * @param object - * object of the privilege - * @return <code>true</code> if user has privilege, <code>false</code> - * otherwise - */ - boolean userHasPrivilege(User user, PrivilegeType type, Object object); - - /** - * Returns level of the user privilege. - * - * @param object - * object of the privilege - * @param user - * user for which the check is performed - * @param type - * type of the privilege - * @return level of the privilege - */ - int getUserPrivilegeLevel(User user, PrivilegeType type, Object object); - - /** - * Sets the user privilege. - * - * @param user - * user for whom the privilege should be granted/dropped - * @param privilege - * user privilege - */ - void setUserPrivilege(User user, BasicPrivilege privilege); - - /** - * Adds user to the system. - * - * @param user - * user to be added - */ - void addUser(User user); - - /** - * Updates user in the system. - * - * @param user - * user to be updated - */ - void updateUser(User user); - - /** - * Removes user from the system. - * - * @param user - * user to be removed - */ - void deleteUser(User user); - - /** - * Returns user by the database identifier. - * - * @param id - * database identifier - * @return user for the given identifier, null if user doesn't exist - * - */ - User getUserById(int id); - - /** - * Returns user views for all users. - * - * @return list of user {@link lcsb.mapviewer.services.view.AbstractView - * views} for all users - */ - List<UserView> getAllUserRows(); - - /** - * @param user - * user that will have view. - * @return view for one user. - */ - UserView getUserRow(User user); - - /** - * Updates user from user {@link lcsb.mapviewer.services.view.AbstractView - * view}. - * - * @param selectedUser - * user {@link lcsb.mapviewer.services.view.AbstractView view} to - * update - */ - void updateUser(UserView selectedUser); - - /** - * Removes user based on user - * {@link lcsb.mapviewer.services.view.AbstractView view}. - * - * @param selectedUser - * user {@link lcsb.mapviewer.services.view.AbstractView view} to - * be removed - */ - void deleteUser(UserView selectedUser); - - /** - * Creates empty view. - * - * @return empty user {@link lcsb.mapviewer.services.view.AbstractView view} - * . - */ - UserView createEmptyUserRow(); - - /** - * Drops privileges for every user on the given object and type. - * - * @param type - * type of privilege that should be dropped - * @param objectId - * identifier of the object to which privileges should be dropped - */ - void dropPrivilegesForObjectType(PrivilegeType type, int objectId); - - /** - * Adds user from user view. - * - * @param selectedUser - * user view representation that should be added - */ - void addUser(UserView selectedUser); - - /** - * Adds privilege to the user. - * - * @param user - * user to which privilege should be added - * @param type - * type of the privilege - */ - void setUserPrivilege(User user, PrivilegeType type); - - /** - * Updates users from list of user - * {@link lcsb.mapviewer.services.view.AbstractView view}. - * - * @param users - * user {@link lcsb.mapviewer.services.view.AbstractView views} - * to update - */ - void updateUsers(Collection<UserView> users); - - /** - * @param password - * input password - * @return encoded password - */ - String encodePassword(String password); - - /** - * Returns {@link User} for given "name surname" string. - * - * @param nameSurnameString - * string identifing user with name and surname separated by single - * space - * @return {@link User} for given "name surname" string - */ - User getUserByNameSurname(String nameSurnameString); -} +package lcsb.mapviewer.services.interfaces; + +import java.util.Collection; +import java.util.List; + +import lcsb.mapviewer.commands.ColorExtractor; +import lcsb.mapviewer.model.user.BasicPrivilege; +import lcsb.mapviewer.model.user.PrivilegeType; +import lcsb.mapviewer.model.user.User; +import lcsb.mapviewer.services.view.UserView; + +/** + * Service that manages users. + * + * @author Piotr Gawron + * + */ +public interface IUserService { + /** + * Check if its possible to login using given login and password. + * + * @param login + * user login + * @param password + * plan password + * @return <code>true</code> if credentials are ok, <code>false</code> + * otherwise + */ + boolean login(String login, String password); + + /** + * Returns user by login. + * + * @param login + * user login + * @return user if the login is valid, <code>null</code> otherwise + */ + User getUserByLogin(String login); + + /** + * Checks if user has a given privilege. + * + * @param user + * user for which the check is performed + * @param type + * type of the privilege + * @return <code>true</code> if user has privilege, <code>false</code> + * otherwise + */ + boolean userHasPrivilege(User user, PrivilegeType type); + + /** + * Returns level of the user privilege. + * + * @param user + * user for which the check is performed + * @param type + * type of the privilege + * @return level of the privilege + */ + int getUserPrivilegeLevel(User user, PrivilegeType type); + + /** + * Checks if user has a given privilege on the object. + * + * @param user + * user for which the check is performed + * @param type + * type of the privilege + * @param object + * object of the privilege + * @return <code>true</code> if user has privilege, <code>false</code> + * otherwise + */ + boolean userHasPrivilege(User user, PrivilegeType type, Object object); + + /** + * Returns level of the user privilege. + * + * @param object + * object of the privilege + * @param user + * user for which the check is performed + * @param type + * type of the privilege + * @return level of the privilege + */ + int getUserPrivilegeLevel(User user, PrivilegeType type, Object object); + + /** + * Sets the user privilege. + * + * @param user + * user for whom the privilege should be granted/dropped + * @param privilege + * user privilege + */ + void setUserPrivilege(User user, BasicPrivilege privilege); + + /** + * Adds user to the system. + * + * @param user + * user to be added + */ + void addUser(User user); + + /** + * Updates user in the system. + * + * @param user + * user to be updated + */ + void updateUser(User user); + + /** + * Removes user from the system. + * + * @param user + * user to be removed + */ + void deleteUser(User user); + + /** + * Returns user by the database identifier. + * + * @param id + * database identifier + * @return user for the given identifier, null if user doesn't exist + * + */ + User getUserById(int id); + + /** + * Returns user views for all users. + * + * @return list of user {@link lcsb.mapviewer.services.view.AbstractView + * views} for all users + */ + List<UserView> getAllUserRows(); + + /** + * @param user + * user that will have view. + * @return view for one user. + */ + UserView getUserRow(User user); + + /** + * Updates user from user {@link lcsb.mapviewer.services.view.AbstractView + * view}. + * + * @param selectedUser + * user {@link lcsb.mapviewer.services.view.AbstractView view} to + * update + */ + void updateUser(UserView selectedUser); + + /** + * Removes user based on user {@link lcsb.mapviewer.services.view.AbstractView + * view}. + * + * @param selectedUser + * user {@link lcsb.mapviewer.services.view.AbstractView view} to be + * removed + */ + void deleteUser(UserView selectedUser); + + /** + * Creates empty view. + * + * @return empty user {@link lcsb.mapviewer.services.view.AbstractView view} . + */ + UserView createEmptyUserRow(); + + /** + * Drops privileges for every user on the given object and type. + * + * @param type + * type of privilege that should be dropped + * @param objectId + * identifier of the object to which privileges should be dropped + */ + void dropPrivilegesForObjectType(PrivilegeType type, int objectId); + + /** + * Adds user from user view. + * + * @param selectedUser + * user view representation that should be added + */ + void addUser(UserView selectedUser); + + /** + * Adds privilege to the user. + * + * @param user + * user to which privilege should be added + * @param type + * type of the privilege + */ + void setUserPrivilege(User user, PrivilegeType type); + + /** + * Updates users from list of user + * {@link lcsb.mapviewer.services.view.AbstractView view}. + * + * @param users + * user {@link lcsb.mapviewer.services.view.AbstractView views} to + * update + */ + void updateUsers(Collection<UserView> users); + + /** + * @param password + * input password + * @return encoded password + */ + String encodePassword(String password); + + /** + * Returns {@link User} for given "name surname" string. + * + * @param nameSurnameString + * string identifing user with name and surname separated by single + * space + * @return {@link User} for given "name surname" string + */ + User getUserByNameSurname(String nameSurnameString); + + /** + * Returns {@link ColorExtractor} that transform overlay values into colors + * for given user. + * + * @param user + * {@link User} for which {@link ColorExtractor} will be obtained + * @return {@link ColorExtractor} that transform overlay values into colors + * for given user + */ + ColorExtractor getColorExtractorForUser(User user); +} diff --git a/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugService.java b/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugService.java index 83108406d921a8c7a8078530d39ff235801827ce..e39214a40fcc5f1640ccac5a3c2366d9c4e073d3 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugService.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugService.java @@ -30,6 +30,7 @@ import lcsb.mapviewer.model.map.species.Protein; import lcsb.mapviewer.model.map.statistics.SearchType; import lcsb.mapviewer.services.interfaces.ISearchHistoryService; import lcsb.mapviewer.services.search.db.DbSearchCriteria; +import lcsb.mapviewer.services.view.AnnotationView; /** * Implementation of the service that allows access information about drugs. @@ -85,14 +86,25 @@ public class DrugService implements IDrugService { @Override public List<DrugView> getByNames(List<String> names, DbSearchCriteria searchCriteria) { - List<DrugView> result = new ArrayList<DrugView>(); + List<DrugView> result = new ArrayList<>(); + + Set<String> processedDrugIds = new HashSet<>(); int oldSet = searchCriteria.getColorSet(); for (String string : names) { searchCriteria.colorSet(searchCriteria.getColorSet() + 1); DrugView drug = getByName(string, searchCriteria); if (drug != null) { - result.add(drug); + boolean isNewDrug = false; + for (AnnotationView id : drug.getDrugLinks()) { + if (!processedDrugIds.contains(id.toString())) { + isNewDrug = true; + } + processedDrugIds.add(id.toString()); + } + if (isNewDrug) { + result.add(drug); + } } } searchCriteria.colorSet(oldSet); diff --git a/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugView.java b/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugView.java index 640997c1f86dc9d64276076cf69a2a5870ead1a4..7ca8fa38243d77711cd80e28a78eb6a2436fedb9 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugView.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/db/drug/DrugView.java @@ -66,27 +66,31 @@ public class DrugView extends AbstractView<Drug> implements Serializable, ISearc * List of links to extenral databases. */ private List<AnnotationView> drugLinks = new ArrayList<>(); + /** * List of targets for the drug. */ - private List<TargetView> targetRows = new ArrayList<>(); + private List<TargetView> targetRows = new ArrayList<>(); /** * Description of the drug. */ private String description; + /** * Status of blood brain barries for the drug. */ private String bloodBrainBarrier = "N/A"; + /** * Known brand names. */ - private List<String> brandNames = new ArrayList<String>(); + private List<String> brandNames = new ArrayList<>(); + /** * Known synonyms. */ - private List<String> synonyms = new ArrayList<String>(); + private List<String> synonyms = new ArrayList<>(); /** * Constructor that initialize the data with information from the parameter diff --git a/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutAliasViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutAliasViewFactory.java index d58e285eff71e012da61010728b7134e70350deb..e42bc74452ab802039cdd8f87ac09afeb0eff40f 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutAliasViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/layout/FullLayoutAliasViewFactory.java @@ -29,7 +29,7 @@ public class FullLayoutAliasViewFactory extends ElementViewFactory<Pair<Element, ColorSchema schema = pair.getRight(); FullLayoutAliasView result = new FullLayoutAliasView(pair.getLeft()); - result.setColor(schema.getNormalizedColor()); + result.setColor(schema.getColor()); result.setValue(schema.getValue()); result.setDescription(schema.getDescription()); if (schema instanceof GeneVariationColorSchema) { diff --git a/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutAliasViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutAliasViewFactory.java index 4d0c874fd4ccdb43ba5b1fce35c77faa03fa3dba..0f37f3a0afe17a79edab2d9858bb2aed061e0d71 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutAliasViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutAliasViewFactory.java @@ -25,7 +25,7 @@ public class LightLayoutAliasViewFactory extends ElementViewFactory<Pair<Element @Override public LightLayoutAliasView create(Pair<Element, ColorSchema> pair) { LightLayoutAliasView result = new LightLayoutAliasView(pair.getLeft()); - result.setColor(pair.getRight().getNormalizedColor()); + result.setColor(pair.getRight().getColor()); result.setValue(pair.getRight().getValue()); return result; } diff --git a/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionView.java b/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionView.java index 8053477586e6fd760889aa7fafeb7b0a767b9631..cf1bec9e84d510b5504e9267b3d7331d482f58f7 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionView.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionView.java @@ -1,115 +1,137 @@ -package lcsb.mapviewer.services.search.layout; - -import java.awt.Color; - -import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.services.search.ElementView; - -/** - * Light {@link ElementView view} for {@link Reaction} representing data that - * should be send to client about reaction related to - * {@link lcsb.mapviewer.model.map.layout.Layout}. - * - * @author Piotr Gawron - * - */ -public class LightLayoutReactionView extends ElementView { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Width of highlighted {@link Reaction} in a a layout. - */ - private Double width; - - /** - * Color used to highlight {@link Reaction} in a layout. - */ - private Color color; - - /** - * Should the reaction be reversed when visualizing.. - */ - private Boolean reverse; - - /** - * Default constructor. - * - * @param reaction - * original object from which this on is created - */ - public LightLayoutReactionView(Reaction reaction) { - super(reaction.getId(), reaction.getModel().getId()); - } - - /** - * Constructor that should be used only for (de)serialization. - */ - protected LightLayoutReactionView() { - super(); - } - - /** - * @return the color - * @see #color - */ - public Color getColor() { - return color; - } - - /** - * @param color - * the color to set - * @see #color - */ - public void setColor(Color color) { - this.color = color; - } - - @Override - public String toString() { - return "[" + this.getClass().getSimpleName() + "] " + // - "reaction_id: " + getIdObject() + ", " + // - "width: " + getWidth() + ", " + // - "color: " + getColor() + ", "; - - } - - /** - * @return the width - * @see #width - */ - public Double getWidth() { - return width; - } - - /** - * @param width - * the width to set - * @see #width - */ - public void setWidth(Double width) { - this.width = width; - } - - /** - * @return the reverse - * @see #reverse - */ - public Boolean getReverse() { - return reverse; - } - - /** - * @param reverse - * the reverse to set - * @see #reverse - */ - public void setReverse(Boolean reverse) { - this.reverse = reverse; - } - -} +package lcsb.mapviewer.services.search.layout; + +import java.awt.Color; + +import lcsb.mapviewer.model.map.reaction.Reaction; +import lcsb.mapviewer.services.search.ElementView; + +/** + * Light {@link ElementView view} for {@link Reaction} representing data that + * should be send to client about reaction related to + * {@link lcsb.mapviewer.model.map.layout.Layout}. + * + * @author Piotr Gawron + * + */ +public class LightLayoutReactionView extends ElementView { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Width of highlighted {@link Reaction} in a a layout. + */ + private Double width; + + /** + * Color used to highlight {@link Reaction} in a layout. + */ + private Color color; + + /** + * Should the reaction be reversed when visualizing.. + */ + private Boolean reverse; + + /** + * Normalized value repesenting expresion (used instead of color). + */ + private Double value; + + /** + * Default constructor. + * + * @param reaction + * original object from which this on is created + */ + public LightLayoutReactionView(Reaction reaction) { + super(reaction.getId(), reaction.getModel().getId()); + } + + /** + * Constructor that should be used only for (de)serialization. + */ + protected LightLayoutReactionView() { + super(); + } + + /** + * @return the color + * @see #color + */ + public Color getColor() { + return color; + } + + /** + * @param color + * the color to set + * @see #color + */ + public void setColor(Color color) { + this.color = color; + } + + @Override + public String toString() { + return "[" + this.getClass().getSimpleName() + "] " + // + "reaction_id: " + getIdObject() + ", " + // + "width: " + getWidth() + ", " + // + "color: " + getColor() + ", "; + + } + + /** + * @return the width + * @see #width + */ + public Double getWidth() { + return width; + } + + /** + * @param width + * the width to set + * @see #width + */ + public void setWidth(Double width) { + this.width = width; + } + + /** + * @return the reverse + * @see #reverse + */ + public Boolean getReverse() { + return reverse; + } + + /** + * @param reverse + * the reverse to set + * @see #reverse + */ + public void setReverse(Boolean reverse) { + this.reverse = reverse; + } + + /** + * @return the value + * @see #value + */ + public Double getValue() { + return value; + } + + /** + * @param value + * the value to set + * @see #value + */ + public void setValue(Double value) { + this.value = value; + } + +} diff --git a/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionViewFactory.java index fc7ff5ccacad18cb7a8ae6f8ee6b7cc24a3060ee..2728acc532abc62f22ab274b08a04d095eb4fa08 100644 --- a/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/search/layout/LightLayoutReactionViewFactory.java @@ -25,7 +25,8 @@ public class LightLayoutReactionViewFactory extends ElementViewFactory<Pair<Reac @Override public LightLayoutReactionView create(Pair<Reaction, ColorSchema> pair) { LightLayoutReactionView result = new LightLayoutReactionView(pair.getLeft()); - result.setColor(pair.getRight().getNormalizedColor()); + result.setColor(pair.getRight().getColor()); + result.setValue(pair.getRight().getValue()); result.setWidth(pair.getRight().getLineWidth()); result.setReverse(pair.getRight().getReverseReaction()); return result; 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 292e215ede6f12722e724897b5bf0b69798df127..d06c19183f1019116142d54131801dac457b6f4c 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaReader.java @@ -24,6 +24,7 @@ import lcsb.mapviewer.common.Pair; import lcsb.mapviewer.common.TextFileUtils; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.NotImplementedException; +import lcsb.mapviewer.common.geometry.ColorParser; import lcsb.mapviewer.converter.model.celldesigner.species.SpeciesMapping; import lcsb.mapviewer.converter.zip.ZipEntryFileFactory; import lcsb.mapviewer.model.map.MiriamData; @@ -62,6 +63,11 @@ public class ColorSchemaReader { */ private static final int MIN_GV_RED_VALUE = 128; + /** + * Object that parses colors from string. + */ + private ColorParser colorParser = new ColorParser(); + /** * Default class logger. */ @@ -200,7 +206,7 @@ public class ColorSchemaReader { } } if (colorColumn != null) { - schema.setColor(values[colorColumn]); + schema.setColor(colorParser.parse(values[colorColumn])); } if (identifierColumn != null && !values[identifierColumn].equals("")) { if (mc.isValidIdentifier(values[identifierColumn])) { @@ -280,7 +286,7 @@ public class ColorSchemaReader { * @param schema * {@link ColorSchema} where name should be set * @param type - * {@link MiriamType} type of the identifier + * {@link MiriamType} type of the identifier * @param content * content of the cell where identifier of given type is stored */ @@ -496,7 +502,7 @@ public class ColorSchemaReader { } if (colorColumn != null) { - schema.setColor(values[colorColumn]); + schema.setColor(colorParser.parse(values[colorColumn])); } if (reactionIdentifierColumn != null) { processReactionIdentifier(schema, values[reactionIdentifierColumn]); 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 8e23dbec6d9e88e63ff106a9565930ff2b39c1c4..f852f697bcb65ecf669503a0bd3a3022d3010e0a 100644 --- a/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java +++ b/service/src/main/java/lcsb/mapviewer/services/utils/ColorSchemaXlsxReader.java @@ -25,6 +25,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook; import lcsb.mapviewer.annotation.services.MiriamConnector; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.Pair; +import lcsb.mapviewer.common.geometry.ColorParser; import lcsb.mapviewer.converter.model.celldesigner.species.SpeciesMapping; import lcsb.mapviewer.model.map.MiriamType; import lcsb.mapviewer.model.map.layout.ColorSchema; @@ -48,18 +49,18 @@ public class ColorSchemaXlsxReader { /** * @param fileName - * file name + * file name * @param sheetName - * sheet name. + * sheet name. * @return list of ColorSchema. * @throws IOException - * exception related to opening the input stream. + * exception related to opening the input stream. * @throws InvalidColorSchemaException - * invalid color schema exception. + * invalid color schema exception. */ - public Collection<ColorSchema> readColorSchema(String fileName, String sheetName) - throws IOException, InvalidColorSchemaException { - List<ColorSchema> result = new ArrayList<ColorSchema>(); + public Collection<ColorSchema> readColorSchema(String fileName, String sheetName) throws IOException, InvalidColorSchemaException { + ColorParser colorParser = new ColorParser(); + List<ColorSchema> result = new ArrayList<>(); FileInputStream file = null; Workbook workbook = null; @@ -134,8 +135,7 @@ public class ColorSchemaXlsxReader { } if (!found) { if (acceptableIdentifiers.keySet().contains(value.toLowerCase())) { - foundCustomIdentifiers.add(new Pair<MiriamType, Integer>( - acceptableIdentifiers.get(value.toLowerCase()), columnIndex - 1)); + foundCustomIdentifiers.add(new Pair<MiriamType, Integer>(acceptableIdentifiers.get(value.toLowerCase()), columnIndex - 1)); } else { String columnNames = ""; for (ColorSchemaColumn schemaColumn : ColorSchemaColumn.values()) { @@ -144,8 +144,7 @@ public class ColorSchemaXlsxReader { for (String string : acceptableIdentifiers.keySet()) { columnNames += ", " + string; } - throw new InvalidColorSchemaException( - "Unknown column type: " + value + ". Acceptable column name: " + columnNames); + throw new InvalidColorSchemaException("Unknown column type: " + value + ". Acceptable column name: " + columnNames); } } } @@ -163,15 +162,12 @@ public class ColorSchemaXlsxReader { throw new InvalidColorSchemaException("Schema can contain only one of these two columns: "); } - if (nameColumn == null && identifierColumn == null && foundCustomIdentifiers.size() == 0 - && reactionIdentifierColumn == null) { - throw new InvalidColorSchemaException( - "One of these columns is obligatory: name, identifier, reactionIdentifier"); + if (nameColumn == null && identifierColumn == null && foundCustomIdentifiers.size() == 0 && reactionIdentifierColumn == null) { + throw new InvalidColorSchemaException("One of these columns is obligatory: name, identifier, reactionIdentifier"); } if (valueColumn == null && colorColumn == null) { - throw new InvalidColorSchemaException( - "Schema must contain one of these two columns: value, name"); + throw new InvalidColorSchemaException("Schema must contain one of these two columns: value, name"); } } else { @@ -185,13 +181,11 @@ public class ColorSchemaXlsxReader { cell.setCellType(Cell.CELL_TYPE_STRING); schema.setValue(Double.parseDouble(cell.getStringCellValue().replace(",", "."))); } catch (Exception e) { - throw new InvalidColorSchemaException("[Line " + lineIndex - + "] Problem with parsing value for value column. Cell value" + cell); + throw new InvalidColorSchemaException("[Line " + lineIndex + "] Problem with parsing value for value column. Cell value" + cell); } - if (schema.getValue() > 1 + Configuration.EPSILON - || schema.getValue() < -1 - Configuration.EPSILON) { - throw new InvalidColorSchemaException("[Line " + lineIndex + "] Value " + schema.getValue() - + " out of range. Only values between -1 and 1 are allowed."); + if (schema.getValue() > 1 + Configuration.EPSILON || schema.getValue() < -1 - Configuration.EPSILON) { + throw new InvalidColorSchemaException( + "[Line " + lineIndex + "] Value " + schema.getValue() + " out of range. Only values between -1 and 1 are allowed."); } } if (compartmentColumn != null) { @@ -216,7 +210,7 @@ public class ColorSchemaXlsxReader { } } if (colorColumn != null) { - schema.setColor(row.getCell(colorColumn).getStringCellValue()); + schema.setColor(colorParser.parse(row.getCell(colorColumn).getStringCellValue())); } if (reactionIdentifierColumn != null) { schema.setReactionIdentifier(row.getCell(reactionIdentifierColumn).getStringCellValue()); @@ -229,8 +223,7 @@ public class ColorSchemaXlsxReader { try { schema.setLineWidth(Double.parseDouble(value.replace(",", "."))); } catch (NumberFormatException e) { - throw new InvalidColorSchemaException( - "[Line " + lineIndex + "] Problem with parsing value: \"" + value + "\""); + throw new InvalidColorSchemaException("[Line " + lineIndex + "] Problem with parsing value: \"" + value + "\""); } } } @@ -249,28 +242,24 @@ public class ColorSchemaXlsxReader { if (miriamConnector.isValidIdentifier(value)) { schema.setGeneralIdentifier(value); } else { - throw new InvalidColorSchemaException( - "[Line " + lineIndex + "]" + " Invalid identifier: " + value); + throw new InvalidColorSchemaException("[Line " + lineIndex + "]" + " Invalid identifier: " + value); } } } for (Pair<MiriamType, Integer> pair : foundCustomIdentifiers) { cell = row.getCell(pair.getRight()); if (cell != null) { - schema.addIdentifierColumn( - new Pair<MiriamType, String>(pair.getLeft(), cell.getStringCellValue())); + schema.addIdentifierColumn(new Pair<MiriamType, String>(pair.getLeft(), cell.getStringCellValue())); } } - if ((schema.getValue() != null && schema.getColor() != null) - || (schema.getValue() == null && schema.getColor() == null)) { + if ((schema.getValue() != null && schema.getColor() != null) || (schema.getValue() == null && schema.getColor() == null)) { throw new InvalidColorSchemaException("Value or Color is needed not both"); } - if (schema.getName() == null && schema.getGeneralIdentifier() == null - && foundCustomIdentifiers.size() == 0 && schema.getReactionIdentifier() == null) { - throw new InvalidColorSchemaException( - "One of these columns values is obligatory: name, identifier, reactionIdentifier"); + if (schema.getName() == null && schema.getGeneralIdentifier() == null && foundCustomIdentifiers.size() == 0 + && schema.getReactionIdentifier() == null) { + throw new InvalidColorSchemaException("One of these columns values is obligatory: name, identifier, reactionIdentifier"); } result.add(schema); } @@ -292,11 +281,10 @@ public class ColorSchemaXlsxReader { } /** - * Returns list of columns that should be printed for given coloring - * schemas. + * Returns list of columns that should be printed for given coloring schemas. * * @param schemas - * list of schemas + * list of schemas * @return list of columns that should be printed (were set in the coloring * schemas) */ diff --git a/service/src/main/java/lcsb/mapviewer/services/view/CommentView.java b/service/src/main/java/lcsb/mapviewer/services/view/CommentView.java index b9b0cc85ebc9676957107f1ce2bc171caf2c6d7b..0cffa23ff649c375f47ef58cec582288f11ac1cd 100644 --- a/service/src/main/java/lcsb/mapviewer/services/view/CommentView.java +++ b/service/src/main/java/lcsb/mapviewer/services/view/CommentView.java @@ -1,270 +1,292 @@ -package lcsb.mapviewer.services.view; - -import java.io.Serializable; - -import lcsb.mapviewer.model.map.Comment; - -/** - * View representation of the Comment. - * - * @author Piotr Gawron - * - */ - -public class CommentView extends AbstractView<Comment> implements Serializable { - - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Author of the comment. - */ - private String author; - - /** - * Email of the comment. - */ - private String email; - - /** - * Content of the comment. - */ - private String content; - - /** - * Title of the comment. - */ - private String title; - - /** - * Is the comment visible on the map. - */ - private String pinned; - - /** - * Is the comment removed. - */ - private String removed; - - /** - * X coordinate on the map. - */ - private String xCoord; - - /** - * Y coordinate on the map. - */ - private String yCoord; - - /** - * Zoom level at which comment should be investigated on the map (to see - * details). - */ - private String zoom; - - /** - * Constructor that initialize the view with the data from original comment. - * - * @param comment - * data required for initialization - */ - protected CommentView(final Comment comment) { - super(comment); - } - - /** - * Default constructor. Should be used only for deserialization. - */ - protected CommentView() { - } - - /** - * @return the author - * @see #author - */ - public String getAuthor() { - return author; - } - - /** - * @param author - * the author to set - * @see #author - */ - public void setAuthor(String author) { - this.author = author; - } - - /** - * @return the email - * @see #email - */ - public String getEmail() { - return email; - } - - /** - * @param email - * the email to set - * @see #email - */ - public void setEmail(String email) { - this.email = email; - } - - /** - * @return the content - * @see #content - */ - public String getContent() { - return content; - } - - /** - * @param content - * the content to set - * @see #content - */ - public void setContent(String content) { - this.content = content; - } - - /** - * @return the title - * @see #title - */ - public String getTitle() { - return title; - } - - /** - * @param title - * the title to set - * @see #title - */ - public void setTitle(String title) { - this.title = title; - } - - /** - * @return the pinned - * @see #pinned - */ - public String getPinned() { - return pinned; - } - - /** - * @param pinned - * the pinned to set - * @see #pinned - */ - public void setPinned(String pinned) { - this.pinned = pinned; - } - - /** - * @return the removed - * @see #removed - */ - public String getRemoved() { - return removed; - } - - /** - * @param removed - * the removed to set - * @see #removed - */ - public void setRemoved(String removed) { - this.removed = removed; - } - - /** - * @return the xCoord - * @see #xCoord - */ - public String getxCoord() { - return xCoord; - } - - /** - * @param xCoord - * the xCoord to set - * @see #xCoord - */ - public void setxCoord(String xCoord) { - this.xCoord = xCoord; - } - - /** - * @return the yCoord - * @see #yCoord - */ - public String getyCoord() { - return yCoord; - } - - /** - * @param yCoord - * the yCoord to set - * @see #yCoord - */ - public void setyCoord(String yCoord) { - this.yCoord = yCoord; - } - - /** - * @return the zoom - * @see #zoom - */ - public String getZoom() { - return zoom; - } - - /** - * @param zoom - * the zoom to set - * @see #zoom - */ - public void setZoom(String zoom) { - this.zoom = zoom; - } - - /** - * @param pinned - * the pinned to set - * @see #pinned - */ - public void setPinned(final boolean pinned) { - if (pinned) { - setPinned("YES"); - } else { - setPinned("NO"); - } - } - - /** - * Sets x coordinate. - * - * @param x - * x coordinate to set - * @see #xCoord - */ - public void setxCoord(double x) { - this.xCoord = x + ""; - } - - /** - * Sets y coordinate. - * - * @param y - * y coordinate to set - * @see #yCoord - */ - public void setyCoord(double y) { - this.yCoord = y + ""; - } -}; +package lcsb.mapviewer.services.view; + +import java.io.Serializable; + +import lcsb.mapviewer.model.map.Comment; + +/** + * View representation of the Comment. + * + * @author Piotr Gawron + * + */ + +public class CommentView extends AbstractView<Comment> implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Author of the comment. + */ + private String author; + + /** + * Email of the comment. + */ + private String email; + + /** + * Content of the comment. + */ + private String content; + + /** + * Title of the comment. + */ + private String title; + + /** + * Is the comment visible on the map. + */ + private String pinned; + + /** + * Is the comment removed. + */ + private String removed; + + /** + * X coordinate on the map. + */ + private String xCoord; + + /** + * Y coordinate on the map. + */ + private String yCoord; + + /** + * Zoom level at which comment should be investigated on the map (to see + * details). + */ + private String zoom; + + /** + * Submap on which comment was placed. + */ + private String submap; + + /** + * Constructor that initialize the view with the data from original comment. + * + * @param comment + * data required for initialization + */ + protected CommentView(final Comment comment) { + super(comment); + } + + /** + * Default constructor. Should be used only for deserialization. + */ + protected CommentView() { + } + + /** + * @return the author + * @see #author + */ + public String getAuthor() { + return author; + } + + /** + * @param author + * the author to set + * @see #author + */ + public void setAuthor(String author) { + this.author = author; + } + + /** + * @return the email + * @see #email + */ + public String getEmail() { + return email; + } + + /** + * @param email + * the email to set + * @see #email + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * @return the content + * @see #content + */ + public String getContent() { + return content; + } + + /** + * @param content + * the content to set + * @see #content + */ + public void setContent(String content) { + this.content = content; + } + + /** + * @return the title + * @see #title + */ + public String getTitle() { + return title; + } + + /** + * @param title + * the title to set + * @see #title + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return the pinned + * @see #pinned + */ + public String getPinned() { + return pinned; + } + + /** + * @param pinned + * the pinned to set + * @see #pinned + */ + public void setPinned(String pinned) { + this.pinned = pinned; + } + + /** + * @return the removed + * @see #removed + */ + public String getRemoved() { + return removed; + } + + /** + * @param removed + * the removed to set + * @see #removed + */ + public void setRemoved(String removed) { + this.removed = removed; + } + + /** + * @return the xCoord + * @see #xCoord + */ + public String getxCoord() { + return xCoord; + } + + /** + * @param xCoord + * the xCoord to set + * @see #xCoord + */ + public void setxCoord(String xCoord) { + this.xCoord = xCoord; + } + + /** + * @return the yCoord + * @see #yCoord + */ + public String getyCoord() { + return yCoord; + } + + /** + * @param yCoord + * the yCoord to set + * @see #yCoord + */ + public void setyCoord(String yCoord) { + this.yCoord = yCoord; + } + + /** + * @return the zoom + * @see #zoom + */ + public String getZoom() { + return zoom; + } + + /** + * @param zoom + * the zoom to set + * @see #zoom + */ + public void setZoom(String zoom) { + this.zoom = zoom; + } + + /** + * @param pinned + * the pinned to set + * @see #pinned + */ + public void setPinned(final boolean pinned) { + if (pinned) { + setPinned("YES"); + } else { + setPinned("NO"); + } + } + + /** + * Sets x coordinate. + * + * @param x + * x coordinate to set + * @see #xCoord + */ + public void setxCoord(double x) { + this.xCoord = x + ""; + } + + /** + * Sets y coordinate. + * + * @param y + * y coordinate to set + * @see #yCoord + */ + public void setyCoord(double y) { + this.yCoord = y + ""; + } + + /** + * @return the submap + * @see #submap + */ + public String getSubmap() { + return submap; + } + + /** + * @param submap + * the submap to set + * @see #submap + */ + public void setSubmap(String submap) { + this.submap = submap; + } +}; diff --git a/service/src/main/java/lcsb/mapviewer/services/view/CommentViewFactory.java b/service/src/main/java/lcsb/mapviewer/services/view/CommentViewFactory.java index f3cf4961cdfa55f0bc7a6f9d345732bee46f6deb..09b831833228255f96aa223f8f49373fc0ad7562 100644 --- a/service/src/main/java/lcsb/mapviewer/services/view/CommentViewFactory.java +++ b/service/src/main/java/lcsb/mapviewer/services/view/CommentViewFactory.java @@ -7,6 +7,7 @@ import org.apache.log4j.Logger; import com.google.gson.Gson; import lcsb.mapviewer.common.Configuration; +import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.NotImplementedException; import lcsb.mapviewer.model.map.Comment; import lcsb.mapviewer.model.map.model.Model; @@ -50,15 +51,22 @@ public class CommentViewFactory extends AbstractViewFactory<Comment, CommentView return result; } - result.setAuthor((comment.getName())); - result.setContent((comment.getContent())); - result.setEmail((comment.getEmail())); + result.setAuthor(comment.getName()); + result.setContent(comment.getContent()); + result.setEmail(comment.getEmail()); result.setPinned(comment.isPinned()); if (comment.isDeleted()) { result.setRemoved("YES (" + comment.getRemoveReason() + ")"); } else { result.setRemoved("NO"); } + if (comment.getSubmodelData() != null) { + result.setSubmap(comment.getSubmodelData().getId() + ""); + model = model.getSubmodelById(comment.getSubmodelData().getId()); + if (model == null) { + throw new InvalidArgumentException("Cannot find submodel with id: " + comment.getSubmodelData().getId()); + } + } String title = ""; Point2D coordinates = null; @@ -87,12 +95,11 @@ public class CommentViewFactory extends AbstractViewFactory<Comment, CommentView } } } - result.setTitle((title)); + result.setTitle(title); if (coordinates != null) { result.setxCoord(coordinates.getX()); result.setyCoord(coordinates.getY()); result.setZoom("" + (Configuration.MIN_ZOOM_LEVEL + model.getZoomLevels() - 1)); - } return result; } diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/ConfigurationServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/ConfigurationServiceTest.java index 0dc9a7020328b4055010efbee47ca62173bcb020..ff1a5e29d35ab08dbf99a4ca3e48de0e5ba7a706 100644 --- a/service/src/test/java/lcsb/mapviewer/services/impl/ConfigurationServiceTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/impl/ConfigurationServiceTest.java @@ -2,7 +2,6 @@ package lcsb.mapviewer.services.impl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; import java.util.List; @@ -103,29 +102,4 @@ public class ConfigurationServiceTest extends ServiceTestFunctions { } } - @Test - public void testGetMemoryUsage() throws Exception { - try { - Long size = configurationService.getMemoryUsage(); - Long maxMem = configurationService.getMaxMemory(); - int len = 10000000; - int t[]; - Integer x = (int) (Math.random() * 1000); - t = new int[len + x]; - for (int i = 0; i < len; i++) { - t[i] = (int) Math.random() * 1000 + x; - x += t[i]; - } - Long size2 = configurationService.getMemoryUsage(); - Long maxMem2 = configurationService.getMaxMemory(); - - assertNotNull(x); - assertEquals(maxMem, maxMem2); - assertTrue(size2 >= size); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - - } } diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java index b3ff1818218050e179607fdec263a71ae44efb9b..ad2bd21b548a27e2cf1ea9f15fa5b55b87ac04b4 100644 --- a/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/impl/ExporterServiceTest.java @@ -526,5 +526,4 @@ public class ExporterServiceTest extends ServiceTestFunctions { throw e; } } - } diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest.java b/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest.java index 4db59b43d61c1ef4a91cb425e110ba97551e7b8d..83d7140ecf90c0e98fe78055789589a3255b673d 100644 --- a/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest.java @@ -17,6 +17,7 @@ import org.apache.log4j.Logger; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import lcsb.mapviewer.common.Configuration; @@ -34,9 +35,11 @@ import lcsb.mapviewer.model.user.PrivilegeType; import lcsb.mapviewer.model.user.User; import lcsb.mapviewer.persist.dao.map.LayoutDao; import lcsb.mapviewer.services.ServiceTestFunctions; +import lcsb.mapviewer.services.interfaces.ILayoutService; import lcsb.mapviewer.services.interfaces.ILayoutService.CreateLayoutParams; import lcsb.mapviewer.services.search.layout.LightLayoutAliasView; import lcsb.mapviewer.services.search.layout.LightLayoutReactionView; +import lcsb.mapviewer.services.utils.EmailSender; import lcsb.mapviewer.services.view.LayoutView; public class LayoutServiceTest extends ServiceTestFunctions { @@ -50,6 +53,11 @@ public class LayoutServiceTest extends ServiceTestFunctions { @Autowired LayoutDao layoutDao; + + EmailSender originalSender; + + @Autowired + ILayoutService layoutService; @Before public void setUp() throws Exception { @@ -60,6 +68,7 @@ public class LayoutServiceTest extends ServiceTestFunctions { // commit at the end of the test case dbUtils.createSessionForCurrentThread(); + dbUtils.setAutoFlush(false); project = projectDao.getProjectByProjectId(projectId); if (project != null) { @@ -85,6 +94,9 @@ public class LayoutServiceTest extends ServiceTestFunctions { createUser2(); userService.addUser(user2); + + originalSender = layoutService.getEmailSender(); + layoutService.setEmailSender(Mockito.mock(EmailSender.class)); } @After @@ -95,7 +107,9 @@ public class LayoutServiceTest extends ServiceTestFunctions { // close session dbUtils.closeSessionForCurrentThread(); - } + + layoutService.setEmailSender(originalSender); +} @Test public void testUserCanAddLayout() throws Exception { @@ -398,41 +412,29 @@ public class LayoutServiceTest extends ServiceTestFunctions { @Test public void testInputDataInLayout() throws Exception { try { - logger.debug("A"); List<LayoutView> layouts = layoutService.getCustomLayouts(model, user); - logger.debug("A"); assertNotNull(layouts); assertEquals(0, layouts.size()); userService.setUserPrivilege(user, new BasicPrivilege(1, PrivilegeType.CUSTOM_LAYOUTS, user)); - logger.debug("A"); CreateLayoutParams params = new CreateLayoutParams().name("Test").// directory("testDir").// model(model).// colorInputStream(new FileInputStream("testFiles/enricoData/ge001.txt")).// user(user).// async(false); - logger.debug("A"); LayoutView row = layoutService.createLayout(params); - logger.debug("A"); assertNotNull(row); assertNotNull(row.getIdObject()); - logger.debug("A"); assertTrue("true".equalsIgnoreCase(row.getInputDataAvailable())); - logger.debug("A"); byte[] inputData = layoutService.getInputDataForLayout(row); - logger.debug("A"); assertNotNull(inputData); - logger.debug("A"); byte[] originalData = IOUtils.toByteArray(new FileInputStream("testFiles/enricoData/ge001.txt")); - logger.debug("A"); assertEquals(new String(originalData, StandardCharsets.UTF_8), new String(inputData, StandardCharsets.UTF_8)); - logger.debug("A"); layoutService.removeLayout(row, null); - logger.debug("A"); } catch (Exception e) { e.printStackTrace(); diff --git a/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java b/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java index d26b05ac5129c24daac4c86d7824cb5ef073eef4..3d409a1875ba3518299d2c78f88b95ec5cc1d51c 100644 --- a/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java +++ b/service/src/test/java/lcsb/mapviewer/services/impl/LayoutServiceTest2.java @@ -15,6 +15,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorModelCommand; import lcsb.mapviewer.common.Pair; import lcsb.mapviewer.common.TextFileUtils; @@ -35,7 +36,8 @@ import lcsb.mapviewer.services.utils.data.ColorSchemaColumn; import lcsb.mapviewer.services.utils.data.ColorSchemaType; public class LayoutServiceTest2 { - Logger logger = Logger.getLogger(LayoutServiceTest2.class); + Logger logger = Logger.getLogger(LayoutServiceTest2.class); + ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN); @Before public void setUp() throws Exception { @@ -214,7 +216,7 @@ public class LayoutServiceTest2 { final Collection<ColorSchema> schemas = reader .readColorSchema(params.getColorInputStream(), TextFileUtils.getHeaderParametersFromFile(params.getColorInputStream())); - ColorModelCommand command = new ColorModelCommand(model, schemas); + ColorModelCommand command = new ColorModelCommand(model, schemas, colorExtractor); command.execute(); command.getModifiedElements(); 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 13ba77479e16faf515a042176fcf771fe7977103..4cb1a9685bf767d2ca8bd5c15997f7577282b9e5 100644 --- a/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/utils/ColorSchemaReaderTest.java @@ -19,6 +19,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorModelCommand; import lcsb.mapviewer.common.Pair; import lcsb.mapviewer.common.TextFileUtils; @@ -69,27 +70,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); + 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(); - ByteArrayInputStream bin = new ByteArrayInputStream(data); + ByteArrayInputStream bin = new ByteArrayInputStream(data); ColorSchemaReader reader = new ColorSchemaReader(); - Collection<ColorSchema> schemas = reader.readColorSchema(bin,TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); + Collection<ColorSchema> schemas = reader.readColorSchema(bin, TextFileUtils.getHeaderParametersFromFile(new ByteArrayInputStream(data))); assertNotNull(schemas); assertEquals(3, schemas.size()); } catch (Exception e) { @@ -189,12 +190,14 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { @Test public void testColoring3() throws Exception { try { + ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN); + Model model = getModelForFile("testFiles/coloring/protein_to_color.xml", false); ColorSchemaReader reader = new ColorSchemaReader(); Collection<ColorSchema> schemas = reader.readColorSchema("testFiles/coloring/problematicSchema.txt"); - ColorModelCommand factory = new ColorModelCommand(model, schemas); + ColorModelCommand factory = new ColorModelCommand(model, schemas, colorExtractor); factory.execute(); assertFalse(model.getElementByElementId("sa1").getColor().equals(Color.WHITE)); @@ -212,7 +215,7 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { Collection<ColorSchema> schemas = reader.readColorSchema("testFiles/coloring/schemaWithIdentifiers.txt"); for (ColorSchema colorSchema : schemas) { - for (Pair<MiriamType,String> pair: colorSchema.getIdentifierColumns()) { + for (Pair<MiriamType, String> pair : colorSchema.getIdentifierColumns()) { assertNotNull(pair.getRight()); assertFalse(pair.getRight().isEmpty()); } @@ -231,7 +234,7 @@ public class ColorSchemaReaderTest extends ServiceTestFunctions { Collection<ColorSchema> schemas = reader.readColorSchema("testFiles/coloring/schemaIdWithoutName.txt"); for (ColorSchema colorSchema : schemas) { - for (Pair<MiriamType,String> pair: colorSchema.getIdentifierColumns()) { + for (Pair<MiriamType, String> pair : colorSchema.getIdentifierColumns()) { assertFalse(pair.getRight().isEmpty()); assertNull(colorSchema.getName()); } diff --git a/service/src/test/java/lcsb/mapviewer/services/view/CommentViewFactoryTest.java b/service/src/test/java/lcsb/mapviewer/services/view/CommentViewFactoryTest.java index e187e52775eb09943a3b8542bbb82344a9db6a59..13aeba6fe5b5d9beb2c177d9398dc57587ddb169 100644 --- a/service/src/test/java/lcsb/mapviewer/services/view/CommentViewFactoryTest.java +++ b/service/src/test/java/lcsb/mapviewer/services/view/CommentViewFactoryTest.java @@ -1,46 +1,84 @@ -package lcsb.mapviewer.services.view; - -import static org.junit.Assert.assertNotNull; -import lcsb.mapviewer.services.ServiceTestFunctions; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; - -public class CommentViewFactoryTest extends ServiceTestFunctions{ - - @Autowired - CommentViewFactory commentViewFactory; - - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testCreateEmpty() throws Exception { - try { - Object object = commentViewFactory.create(null); - assertNotNull(object); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - @Test - public void testCreateGson() throws Exception { - try { - CommentView object = commentViewFactory.create(null); - assertNotNull(commentViewFactory.createGson(object)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - -} +package lcsb.mapviewer.services.view; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import lcsb.mapviewer.model.map.Comment; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelFullIndexed; +import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; +import lcsb.mapviewer.model.map.model.SubmodelType; +import lcsb.mapviewer.model.map.species.GenericProtein; +import lcsb.mapviewer.model.map.species.Species; +import lcsb.mapviewer.services.ServiceTestFunctions; + +public class CommentViewFactoryTest extends ServiceTestFunctions { + + Logger logger = Logger.getLogger(CommentViewFactoryTest.class); + + @Autowired + CommentViewFactory commentViewFactory; + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testCreateEmpty() throws Exception { + try { + Object object = commentViewFactory.create(null); + assertNotNull(object); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testCreateGson() throws Exception { + try { + CommentView object = commentViewFactory.create(null); + assertNotNull(commentViewFactory.createGson(object)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testCreateOnSubmap() throws Exception { + try { + Model model = new ModelFullIndexed(null); + Model submodel = new ModelFullIndexed(null); + submodel.setId(1); + Species species = new GenericProtein("id"); + species.setId(23); + species.setName("ProteinName"); + submodel.addElement(species); + + model.addSubmodelConnection(new ModelSubmodelConnection(submodel, SubmodelType.UNKNOWN)); + + Comment comment = new Comment(); + comment.setModel(model); + comment.setSubmodel(submodel); + comment.setTableName(species.getClass()); + comment.setTableId(species.getId()); + CommentView object = commentViewFactory.create(comment,model); + assertTrue(object.getTitle().contains(species.getName())); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + +} diff --git a/target/.gitignore b/target/.gitignore deleted file mode 100644 index 456983799efa61b8ec06e3a34596d7314084b921..0000000000000000000000000000000000000000 --- a/target/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/classes/ -/test-classes/ diff --git a/web/src/main/java/lcsb/mapviewer/bean/AbstractMarkerManagerBean.java b/web/src/main/java/lcsb/mapviewer/bean/AbstractMarkerManagerBean.java index 31a07505632336a1e841ecace2ad2f514ac51fa4..2ec5a5d19c3b97f84650149c6cbc4b0756376154 100644 --- a/web/src/main/java/lcsb/mapviewer/bean/AbstractMarkerManagerBean.java +++ b/web/src/main/java/lcsb/mapviewer/bean/AbstractMarkerManagerBean.java @@ -109,12 +109,16 @@ public abstract class AbstractMarkerManagerBean<T extends ISearchResultView> ext if ("".equals(overlayCollection)) { logger.warn(this.getClass().getSimpleName() + ": Cannot refresh data in JavaScript, because overlayCollection is not set"); } else { - String json = "null"; + Gson gsonParser = new Gson(); + String dataEncoded = "null"; if (dataToSend != null) { - json = new Gson().toJson(dataToSend); + dataEncoded = gsonParser.toJson(dataToSend); } - String javascriptCode = "ServerConnector.updateOverviewElementDetailData('" + overlayCollection + "','" + searchResultIdentifier + "'," - + new Gson().toJson(ei) + ", " + json + ");\n"; + String nameEncoded = gsonParser.toJson(overlayCollection); + String resultResultIdEncoded = gsonParser.toJson(searchResultIdentifier); + String elementIdEncoded = gsonParser.toJson(ei); + String javascriptCode = "ServerConnector.updateOverviewElementDetailData(" + nameEncoded + "," + resultResultIdEncoded + "," + elementIdEncoded + ", " + + dataEncoded + ");\n"; executeJavascript(javascriptCode.toString()); } } diff --git a/web/src/main/java/lcsb/mapviewer/bean/ConfigurationBean.java b/web/src/main/java/lcsb/mapviewer/bean/ConfigurationBean.java index 188034072a1b3516267093ddd444fe835e5a7cc8..57a20716a7a0a113445bb8f54f6321b25a60d9e3 100644 --- a/web/src/main/java/lcsb/mapviewer/bean/ConfigurationBean.java +++ b/web/src/main/java/lcsb/mapviewer/bean/ConfigurationBean.java @@ -83,7 +83,7 @@ public class ConfigurationBean extends AbstractManagedBean implements Serializab /** * List of values for all possible configurable parameters. */ - private List<ConfigurationView> values = new ArrayList<ConfigurationView>(); + private List<ConfigurationView> values = new ArrayList<>(); /** * Release version of the framework. @@ -472,4 +472,26 @@ public class ConfigurationBean extends AbstractManagedBean implements Serializab return NumberFormat.getInstance().format(configurationService.getMaxMemory()) + " MB"; } + /** + * Returns {@link ConfigurationElementType#MIN_COLOR_VAL color} used for + * representing overlay element with negative values. + * + * @return {@link ConfigurationElementType#MIN_COLOR_VAL color} used for + * representing overlay element with negative values + */ + public String getMinColor() { + return valueMap.get(ConfigurationElementType.MIN_COLOR_VAL); + } + + /** + * Returns {@link ConfigurationElementType#MIN_COLOR_VAL color} used for + * representing overlay element with negative values. + * + * @return {@link ConfigurationElementType#MIN_COLOR_VAL color} used for + * representing overlay element with positive values + */ + public String getMaxColor() { + return valueMap.get(ConfigurationElementType.MAX_COLOR_VAL); + } + } diff --git a/web/src/main/java/lcsb/mapviewer/bean/DrugBean.java b/web/src/main/java/lcsb/mapviewer/bean/DrugBean.java index 41e848d6b1b3e949f73f34ebf588443bcf6b980d..49d95dfe844de83d4b7f94d3e708e1874dcba5d7 100644 --- a/web/src/main/java/lcsb/mapviewer/bean/DrugBean.java +++ b/web/src/main/java/lcsb/mapviewer/bean/DrugBean.java @@ -184,13 +184,9 @@ public class DrugBean extends AbstractMarkerManagerBean<DrugView> implements Ser // drugs are comma separated List<String> names = splitQuery(query, true); - int set = 0; - for (String string : names) { - DrugView drug = drugService.getByName(string, new DbSearchCriteria().ipAddress(ipAddress).model(model).organisms(mapBean.getOrganism()).colorSet(set++)); - if (drug != null) { - addResult(drug); - } - } + List<DrugView> drugs = drugService + .getByNames(names, new DbSearchCriteria().ipAddress(ipAddress).model(model).organisms(mapBean.getOrganism()).colorSet(0)); + addResults(drugs); // format results if (getResults().size() == 0) { // if there are no results, add empty drug diff --git a/web/src/main/java/lcsb/mapviewer/bean/ExportBean.java b/web/src/main/java/lcsb/mapviewer/bean/ExportBean.java index 9650be2c4d8e7bbfba278a4ebc4fb3a2343798dd..5239964562e98d259b70dda5aa2e92be601910bc 100644 --- a/web/src/main/java/lcsb/mapviewer/bean/ExportBean.java +++ b/web/src/main/java/lcsb/mapviewer/bean/ExportBean.java @@ -34,6 +34,8 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import lcsb.mapviewer.bean.MapBean.ClientMapData; +import lcsb.mapviewer.commands.ClearColorModelCommand; +import lcsb.mapviewer.commands.ColorExtractor; import lcsb.mapviewer.commands.ColorModelCommand; import lcsb.mapviewer.commands.CopyCommand; import lcsb.mapviewer.commands.SubModelCommand; @@ -58,11 +60,11 @@ import lcsb.mapviewer.model.map.layout.Layout; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; import lcsb.mapviewer.model.map.reaction.Reaction; -import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.AntisenseRna; import lcsb.mapviewer.model.map.species.Complex; import lcsb.mapviewer.model.map.species.Degraded; import lcsb.mapviewer.model.map.species.Drug; +import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Gene; import lcsb.mapviewer.model.map.species.Ion; import lcsb.mapviewer.model.map.species.Phenotype; @@ -74,6 +76,7 @@ import lcsb.mapviewer.model.map.species.Unknown; import lcsb.mapviewer.services.interfaces.IExporterService; import lcsb.mapviewer.services.interfaces.IExporterService.ExporterParameters; import lcsb.mapviewer.services.interfaces.ILayoutService; +import lcsb.mapviewer.services.interfaces.IUserService; import lcsb.mapviewer.services.utils.ColorSchemaReader; import lcsb.mapviewer.services.utils.data.BuildInLayout; import lcsb.mapviewer.services.utils.data.ExportColumn; @@ -254,6 +257,12 @@ public class ExportBean extends AbstractManagedBean { @ManagedProperty(value = "#{ExporterService}") private transient IExporterService exporterService; + /** + * Service that allows to access data abaout users. + */ + @ManagedProperty(value = "#{UserService}") + private transient IUserService userService; + /** * Service that deal with {@link Layout layouts}. */ @@ -266,6 +275,12 @@ public class ExportBean extends AbstractManagedBean { @ManagedProperty(value = "#{mapMB}") private transient MapBean mapBean; + /** + * Bean managing currently logged user. + */ + @ManagedProperty(value = "#{userMB}") + private transient UserBean userBean; + /** * Default constructor. */ @@ -1142,12 +1157,13 @@ public class ExportBean extends AbstractManagedBean { if (layout.getInputData() != null) { ColorSchemaReader reader = new ColorSchemaReader(); Collection<ColorSchema> schemas = reader.readColorSchema(layout.getInputData().getFileContent()); - new ColorModelCommand(colorModel, schemas).execute(); + + new ColorModelCommand(colorModel, schemas, userService.getColorExtractorForUser(userBean.getLoggedUser())).execute(); } else if (layout.getTitle().equals(BuildInLayout.CLEAN.getTitle())) { // this might not return true if we change CLEAN.title in future... // if it's clean then remove coloring - new ColorModelCommand(colorModel, new HashSet<>()).execute(); + new ClearColorModelCommand(colorModel).execute(); } for (Element alias : colorModel.getElements()) { alias.setVisibilityLevel(0); @@ -1185,6 +1201,8 @@ public class ExportBean extends AbstractManagedBean { scale /= 2; } + ColorExtractor colorExtractor = userService.getColorExtractorForUser(userBean.getLoggedUser()); + Params params = new Params().// x(minX).// y(minY).// @@ -1193,6 +1211,8 @@ public class ExportBean extends AbstractManagedBean { level(level).// nested(false).// automatically set nested view as invalid scale(scale).// + minColor(colorExtractor.getMinColor()).// + maxColor(colorExtractor.getMaxColor()).// model(colorModel); List<Integer> visibleLayoutIds = deserializeIdList(visibleLayouts); for (Integer integer : visibleLayoutIds) { @@ -1334,4 +1354,38 @@ public class ExportBean extends AbstractManagedBean { public void nop() { } + /** + * @return the userBean + * @see #userBean + */ + public UserBean getUserBean() { + return userBean; + } + + /** + * @param userBean + * the userBean to set + * @see #userBean + */ + public void setUserBean(UserBean userBean) { + this.userBean = userBean; + } + + /** + * @return the userService + * @see #userService + */ + public IUserService getUserService() { + return userService; + } + + /** + * @param userService + * the userService to set + * @see #userService + */ + public void setUserService(IUserService userService) { + this.userService = userService; + } + } diff --git a/web/src/main/java/lcsb/mapviewer/bean/FeedbackBean.java b/web/src/main/java/lcsb/mapviewer/bean/FeedbackBean.java index aefdf5dc47eb4a93caf4fe8ffae5a4aa5d39df6c..3f3b3709b74d69d9e8d846def50d887b95f3a752 100644 --- a/web/src/main/java/lcsb/mapviewer/bean/FeedbackBean.java +++ b/web/src/main/java/lcsb/mapviewer/bean/FeedbackBean.java @@ -232,9 +232,8 @@ public class FeedbackBean extends AbstractMarkerManagerBean<FullCommentView> imp double lng = Double.parseDouble(lngCoord); latLng = new LatLng(lat, lng); - CoordinationConverter cc = new CoordinationConverter(getCurrentTopModel()); - commentedSubmodel = getCurrentTopModel().getSubmodelById(modelIdentifier); + CoordinationConverter cc = new CoordinationConverter(commentedSubmodel); lastCommentCoordinates = cc.toPoint(latLng); diff --git a/web/src/main/java/lcsb/mapviewer/validator/LoginValidator.java b/web/src/main/java/lcsb/mapviewer/validator/LoginValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..a082908bf44b281d10c26696b4dd32f8613a1016 --- /dev/null +++ b/web/src/main/java/lcsb/mapviewer/validator/LoginValidator.java @@ -0,0 +1,38 @@ +package lcsb.mapviewer.validator; + +import java.util.regex.Pattern; + +import javax.faces.application.FacesMessage; +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.validator.FacesValidator; +import javax.faces.validator.Validator; +import javax.faces.validator.ValidatorException; + +/** + * Validator of login field. + * + * @author Piotr Gawron + * + */ +@FacesValidator("loginValidator") +public class LoginValidator implements Validator { + + /** + * Regex pattern used for login validation. + */ + private static final Pattern LOGIN_PATTERN = Pattern.compile("[a-zA-Z0-9_\\.\\-]+"); + + @Override + public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { + if (value == null) { + return; // Let required="true" handle. + } + if (!LOGIN_PATTERN.matcher((String) value).matches()) { + String summary = "Incorrect login."; + String detail = "Only alphanumeric characters and \"-\", \"_\", \".\" special characters are allowed"; + throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail)); + } + } + +} \ No newline at end of file diff --git a/web/src/main/java/lcsb/mapviewer/validator/package-info.java b/web/src/main/java/lcsb/mapviewer/validator/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..9a25482ee1e1e843c2966da8084edf5c68e0d7e2 --- /dev/null +++ b/web/src/main/java/lcsb/mapviewer/validator/package-info.java @@ -0,0 +1,4 @@ +/** + * Provides validator for JSF forms. + */ +package lcsb.mapviewer.validator; diff --git a/web/src/main/webapp/WEB-INF/components/map/map.xhtml b/web/src/main/webapp/WEB-INF/components/map/map.xhtml index 24b62afcea47b6d6608d959a475f5a394e65e62f..cc80c2722f065760219ac9cf52501a14ec6c8262 100644 --- a/web/src/main/webapp/WEB-INF/components/map/map.xhtml +++ b/web/src/main/webapp/WEB-INF/components/map/map.xhtml @@ -59,7 +59,14 @@ </h:form> <h:form id="configurationForm"> - <h:inputHidden id="configurationGson" value="#{mapMB.gsonConfiguration}"/> + <h:inputHidden id="configurationGson" value="#{mapMB.gsonConfiguration}"/> + </h:form> + + <h:form id="overlayConfigForm"> + <h:inputHidden id="userMinColor" value="#{userMB.loggedUser.minColor}"/> + <h:inputHidden id="userMaxColor" value="#{userMB.loggedUser.maxColor}"/> + <h:inputHidden id="systemMinColor" value="#{configurationMB.minColor}"/> + <h:inputHidden id="systemMaxColor" value="#{configurationMB.maxColor}"/> </h:form> <h:form id="searchForm"> @@ -80,6 +87,12 @@ <p:remoteCommand name="_sendReferenceGenomeDetailRequest" actionListener="#{referenceGenomeMB.requestJavasciptGenomeDetails}" /> </h:form> + <h:form id="createSubmodelDialog"> + <p:remoteCommand name="_createSubmodelDialog" actionListener="#{mapMB.createSubmodelDialog}" async="false"/> + </h:form> + + + <!-- loading dialog used for informing user that data is being loaded --> <p:dialog header="Loading" widgetVar="loadingDlg" resizable="false" id="loadingDlg" showEffect="fade" modal="true" closable="false"> diff --git a/web/src/main/webapp/WEB-INF/components/map/submapPanel.xhtml b/web/src/main/webapp/WEB-INF/components/map/submapPanel.xhtml index 304a6d2987501e4279c1a2fdb2e6962a4aa489eb..c586e22bb27eb641a756351450bed4f9a76dceec 100644 --- a/web/src/main/webapp/WEB-INF/components/map/submapPanel.xhtml +++ b/web/src/main/webapp/WEB-INF/components/map/submapPanel.xhtml @@ -19,21 +19,13 @@ <h:panelGroup layout="block" > <p:dataTable id="submapDataTable" var="submap" value="#{mapMB.mapDataList}"> -<!-- <p:column sortBy="id" headerText="Id"> - <h:outputText id="id" value="#{submap.mapConfig.idObject}" /> - </p:column> --> - <p:column sortBy="name" headerText="Name"> <h:outputText id="name" value="#{submap.mapConfig.name}" /> </p:column> -<!-- <p:column sortBy="type" headerText="Type"> - <h:outputText id="type" value="#{submap.type}" /> - </p:column> --> - <p:column headerText=""> <p:commandLink actionListener="#{mapMB.createSubmodelDialog}" - oncomplete="GuiConnector.openDialog(#{submap.mapConfig.idObject}); customMap.openLayoutById('#{mapMB.selectedLayoutIdentifier}');" id="opener" ajax="true" icon="ui-icon-document" title="View"> + oncomplete="GuiConnector.openDialog(#{submap.mapConfig.idObject});" id="opener" ajax="true" icon="ui-icon-document" title="View"> <f:param name="submodelId" value="#{submap.mapConfig.idObject}"/> <p:graphicImage height="24" width="24" diff --git a/web/src/main/webapp/admin/comments.xhtml b/web/src/main/webapp/admin/comments.xhtml index 40bb86deea0ef0fd692ae82d42e4b9c8194621c4..7da4892f98a88aa8c4e2b3adf77565c2c5ef92f4 100644 --- a/web/src/main/webapp/admin/comments.xhtml +++ b/web/src/main/webapp/admin/comments.xhtml @@ -29,7 +29,9 @@ </p:column> <p:column sortBy="title" headerText="Title"> - <h:link value="#{comment.title}" outcome="/index.xhtml?id=#{mapMB.currentMapId}&x=#{comment.xCoord}&y=#{comment.yCoord}&zoom=#{comment.zoom}&comments=on" target="_map"/> + <h:link value="#{comment.title}" + outcome="/index.xhtml?id=#{mapMB.currentMapId}&x=#{comment.xCoord}&y=#{comment.yCoord}&zoom=#{comment.zoom}&comments=on&submap=#{comment.submap}" + target="_map"/> </p:column> <p:column sortBy="author" headerText="Author"> diff --git a/web/src/main/webapp/admin/configuration.xhtml b/web/src/main/webapp/admin/configuration.xhtml index 9202732b32a8ff4f7c5f3eb1402644802258eb47..7c63080fcaff4eed72e339864048b1951a29717f 100644 --- a/web/src/main/webapp/admin/configuration.xhtml +++ b/web/src/main/webapp/admin/configuration.xhtml @@ -56,6 +56,7 @@ global parameters of the MINERVA instance. More information can be found in the <p:column sortBy="value" headerText="Value"> <p:inputText value="#{configuration.value}" /> + <p:colorPicker value="#{configuration.value}" rendered="#{configuration.type.editType == 'COLOR'}"/> </p:column> </p:dataTable> diff --git a/web/src/main/webapp/admin/users.xhtml b/web/src/main/webapp/admin/users.xhtml index ecfa0731adc2064ccbf758092cf1f9c6f7be4bb3..ca235f5ae35553b0488c61e12fd51cef0f611d41 100644 --- a/web/src/main/webapp/admin/users.xhtml +++ b/web/src/main/webapp/admin/users.xhtml @@ -78,7 +78,7 @@ <h:outputText value="Login:" /> </td> <td> - <p:inputText value="#{usersMB.selectedUser.login}" styleClass="bold" rendered="#{empty usersMB.selectedUser.login}"/> + <p:inputText value="#{usersMB.selectedUser.login}" styleClass="bold" rendered="#{empty usersMB.selectedUser.login}" validator="loginValidator"/> <h:outputText autocomplete="off" value="#{usersMB.selectedUser.login}" class="bold" rendered="#{not empty usersMB.selectedUser.login}"/> </td> </tr> diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml index e2790ddf3bbfb79d624ae129568f8a5c00324009..74afff6b04596b2ac9603e28cede3e9b4575b136 100644 --- a/web/src/main/webapp/index.xhtml +++ b/web/src/main/webapp/index.xhtml @@ -1,252 +1,265 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" -"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" - xmlns:h="http://java.sun.com/jsf/html" - xmlns:f="http://java.sun.com/jsf/core" - xmlns:ui="http://java.sun.com/jsf/facelets" - xmlns:p="http://primefaces.org/ui" - xmlns:c="http://java.sun.com/jsp/jstl/core" - > - -<f:view contentType="text/html"> - - -<h:head> - <title>#{mapMB.currentProject.name}</title> - - <!-- Google Maps API version 3.20 --> - <script src="https://maps.google.com/maps/api/js?libraries=drawing&v=3.22" type="text/javascript"/> - - <link rel="shortcut icon" href="./resources/images/favicon.png" type="image/png" /> - -<!-- log4javascript library --> - <h:outputScript library="js" name="log4javascript.js" /> -<!-- configuration for log4javascript --> - <h:outputScript library="js" name="LogConfig.js" /> - - <h:outputScript library="js" name="ObjectWithListeners.js"/> - - <h:outputScript library="js" name="AbstractCustomMap.js" /> - <h:outputScript library="js" name="AbstractInfoWindow.js"/> - <h:outputScript library="js" name="AbstractMarker.js"/> - <h:outputScript library="js" name="Alias.js" /> - <h:outputScript library="js" name="AliasInfoWindow.js" /> - <h:outputScript library="js" name="AliasMarker.js" /> - <h:outputScript library="js" name="AliasOverlay.js" /> - <h:outputScript library="js" name="Configuration.js" /> - <h:outputScript library="js" name="CustomMap.js" /> - <h:outputScript library="js" name="CustomMapOptions.js" /> - <h:outputScript library="js" name="Functions.js" /> - <h:outputScript library="js" name="GeneVariant.js" /> - <h:outputScript library="js" name="GuiConnector.js" /> - <h:outputScript library="js" name="IdentifiedElement.js" /> - <h:outputScript library="js" name="LayoutAlias.js" /> - <h:outputScript library="js" name="LayoutData.js" /> - <h:outputScript library="js" name="LayoutReaction.js" /> - <h:outputScript library="js" name="MapModel.js"/> - <h:outputScript library="js" name="OverlayCollection.js" /> - <h:outputScript library="js" name="pileup.js"/> - <h:outputScript library="js" name="PointData.js"/> - <h:outputScript library="js" name="PointInfoWindow.js"/> - <h:outputScript library="js" name="PointMarker.js"/> - <h:outputScript library="js" name="Reaction.js" /> - <h:outputScript library="js" name="ReactionMarker.js" /> - <h:outputScript library="js" name="ReactionInfoWindow.js" /> - <h:outputScript library="js" name="ReactionOverlay.js" /> - <h:outputScript library="js" name="ReferenceGenome.js" /> - <h:outputScript library="js" name="ReferenceGenomeGeneMapping.js" /> - <h:outputScript library="js" name="SearchPanel.js" /> - <h:outputScript library="js" name="ServerConnector.js" /> - <h:outputScript library="js" name="Submap.js" /> - <h:outputScript library="js" name="TabNavi.js" /> - <h:outputScript library="js" name="TouchMap.js" /> - - <ui:include src="/WEB-INF/components/map/statistics.xhtml" /> - - <script type="text/javascript"> -//<![CDATA[ - var DEBUG_ON =false; - - if (browser.name=="IE") { - if (browser.version<=8 || browser.compatibilityMode) { - alert("This webpage works only with Internet Explorer version 9 or greater.\n" + - "If you have Internet Explorer version 9 or greater and still see this message, please, turn the 'Compatibility modeoff:\n" + - "Open Internet Explorer and press the Alt key on your keyboard.\n" + - "Select 'Tools' menu item. \n" + - "Select the 'Compatibility View' settings option. \n" + - "Make sure the 'Display all websites in Compatibility View' check box is unchecked and that the 'Compatibility View; list of websites is cleared.\n" + - "\n"+ - "Alternatively, please, use other browsers: Chrome, Firefox or Safari."); - } - } - var configuration = new Configuration(); - -function processUrlGetParams() { - if (GuiConnector.getParams["x"]!=undefined && GuiConnector.getParams["y"]!=undefined){ - ServerConnector.setCenterCoordinateX(GuiConnector.getParams["x"]); - ServerConnector.setCenterCoordinateY(GuiConnector.getParams["y"]); - } - if (GuiConnector.getParams["zoom"]!=undefined ){ - ServerConnector.setZoomLevel(GuiConnector.getParams["zoom"]); - } -} - -function updateConfig() { - var json = document.getElementById('configurationForm:configurationGson').value; -//there are some strange problems here... - json = json.replace(/\n/g," "); - configuration.loadFromModelView(JSON.parse(json)); -} - -function initMap(){ - processUrlGetParams(); - - updateConfig(); - - searchPanel = new SearchPanel(document.getElementById('tabView:mainForm:searchText_input'), - document.getElementById('tabView:mainForm:searchButton'), - function(){ - tabViewVar.select(0); - } - ); - - var mapElement = gmtls.getMap(); - if (configuration.MAPS!=null) { - - var windowsTouchInterface = ((navigator.appVersion.indexOf("Win")!=-1) && ('ontouchstart' in document.documentElement)); - var overviewDiv = document.getElementById("overviewDiv"); - customMap = new CustomMap({ - map : mapElement, - configuration : configuration, - hideDiv : document.getElementById('leftPanel'), - markerOptimization : !windowsTouchInterface, - bigLogo : windowsTouchInterface, - overviewDiv : overviewDiv, - customTouchInterface: windowsTouchInterface - }); - - ServerConnector.setCustomMap(customMap); - GuiConnector.showGoogleMap(); - - ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "search")); - ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "missingConnection")); - ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "drug",true, true)); - ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "chemical",#{chemicalMB.linkedToDisease()}, #{chemicalMB.linkedToDisease() == true})); - ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "mirna",true, true)); - ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "comment",false, true)); - - customMap.refreshOverlays(); - - - if (GuiConnector.getParams["search"]!=undefined) { - searchPanel.search(GuiConnector.getParams["search"]); - } - - if (GuiConnector.getParams["comments"]=="on") { - document.getElementById('comment_checkbox').click(); - } - if (GuiConnector.getParams["layout"]!=undefined) { - document.getElementById('tabView:layoutForm3:hidden2').value=GuiConnector.getParams["layout"]; - getVisualizedLayoutDetails(); - } - - } - //when I try to hide legend from the beginning or in the same thread it's hidden forever... ;/ - setTimeout(function() { - GuiConnector.hideLegend(); - }, 0); -} - - -function removeMissingConnection(id) { - document.getElementById('missingConnectionForm:connectionId').value=""+id; - dlg4.show(); -} - -function removeComment(id) { - document.getElementById('missingConnectionForm:commentId').value=""+id; - dlg5.show(); -} - - -//]]> - </script> -</h:head> -<h:body onload="initMap();" > -<h:outputStylesheet library="css" name="style.css"/> -<h:outputStylesheet library="css" name="pileup.css"/> - - <h:outputScript library="primefaces" name="jquery/jquery.js" target="head" /> - <div class = "containerClass"> - <div id="leftPanel" class ="leftPanelClass"> - - <ui:include src="/WEB-INF/components/admin/header.xhtml" /> - -<!-- <div class="tabNavigation"> - <a href="javascript:;" onclick="GuiConnector.tabNaviShow('prev');" class="naviLeft"><i class="fa fa-chevron-left"></i></a> - <a href="javascript:;" onclick="GuiConnector.tabNaviShow('next');" class="naviRight"><i class="fa fa-chevron-right"></i></a> - </div> ---> - - <p:tabView id="tabView" widgetVar="tabViewVar" styleClass="leftTabView" activeIndex="0" > - <p:tab id="searchTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-search maintab'></i><br>SEARCH</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/searchPanel.xhtml" /> - </p:tab > - <p:tab id="drugTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-map-marker maintab'></i><br>DRUG</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/drugPanel.xhtml" /> - </p:tab > - <p:tab id="chemicalTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-map-marker maintab'></i><br>CHEMICAL</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/chemicalPanel.xhtml" /> - </p:tab > - <p:tab id="miRNATab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-map-marker maintab'></i><br>MiRNA</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/miRNAPanel.xhtml" /> - </p:tab > - <p:tab id="layoutTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-th-list maintab'></i><br>OVERLAYS</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/layoutPanel.xhtml" /> - </p:tab > - <p:tab id="loginTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-sign-in maintab'></i><br>LOGIN</div>" styleClass="leftTab" rendered ="#{userMB.loggedUser.login=='anonymous'}"> - <ui:include src="/WEB-INF/components/map/loginPanel.xhtml" /> - </p:tab > - <p:tab id="profileTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-user maintab'></i><br>PROFILE</div>" styleClass="leftTab" rendered ="#{not (userMB.loggedUser.login=='anonymous')}"> - <ui:include src="/WEB-INF/components/map/profilePanel.xhtml" /> - </p:tab > - <p:tab id="submapTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-sitemap maintab'></i><br>SUBMAPS</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/submapPanel.xhtml" /> - </p:tab > - <p:tab id="infoTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-info maintab'></i><br>PROJECT</div>" styleClass="leftTab"> - <ui:include src="/WEB-INF/components/map/infoPanel.xhtml" /> - </p:tab > -<!-- -<p:tab id="sample1" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-envelope maintab'></i><br>SAMPLE 1</div>" styleClass="leftTab hide"> -</p:tab > - -<p:tab id="sample2" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-envelope maintab'></i><br>SAMPLE 2</div>" styleClass="leftTab hide"> -</p:tab > - -<p:tab id="sample3" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-envelope maintab'></i><br>SAMPLE 3</div>" styleClass="leftTab hide"> -</p:tab > ---> - </p:tabView > - - - <div id="footerLinks"> - <a href="admin.xhtml?id=#{mapMB.currentMapId}" style="float:left; padding-left:25px;"><i class="fa fa-lock" style="font-size:17px"></i> ADMIN</a> - <a href="#{configurationMB.userManual}" target="_user_manual_" style="float:left; padding-left:50px;"><i class="fa" style="font-size:17px"></i> MANUAL</a> - <a href="export.xhtml?id=#{mapMB.currentMapId}" style="float:right; padding-right:25px;">EXPORT <i class="fa fa-mail-forward" style="font-size:17px"></i></a> - </div> - - </div> - <div> - <ui:include src="/WEB-INF/components/map/map.xhtml" /> - </div> - </div> - - <!--<ui:include src="/WEB-INF/components/map/footer.xhtml" />--> - - <ui:include src="/WEB-INF/components/map/feedbackDialog.xhtml" /> - <ui:include src="/WEB-INF/components/map/missingConnectionDialog.xhtml" /> - -</h:body> -</f:view> -</html> +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:p="http://primefaces.org/ui" + xmlns:c="http://java.sun.com/jsp/jstl/core" + > + +<f:view contentType="text/html"> + + +<h:head> + <title>#{mapMB.currentProject.name}</title> + + <!-- Google Maps API version 3.20 --> + <script src="https://maps.google.com/maps/api/js?libraries=drawing&v=3.22" type="text/javascript"/> + + <link rel="shortcut icon" href="./resources/images/favicon.png" type="image/png" /> + +<!-- log4javascript library --> + <h:outputScript library="js" name="log4javascript.js" /> +<!-- configuration for log4javascript --> + <h:outputScript library="js" name="LogConfig.js" /> + + <h:outputScript library="js" name="ObjectWithListeners.js"/> + + <h:outputScript library="js" name="AbstractCustomMap.js" /> + <h:outputScript library="js" name="AbstractInfoWindow.js"/> + <h:outputScript library="js" name="AbstractMarker.js"/> + <h:outputScript library="js" name="AbstractOverlayElement.js"/> + <h:outputScript library="js" name="Alias.js" /> + <h:outputScript library="js" name="AliasInfoWindow.js" /> + <h:outputScript library="js" name="AliasMarker.js" /> + <h:outputScript library="js" name="AliasOverlay.js" /> + <h:outputScript library="js" name="Configuration.js" /> + <h:outputScript library="js" name="CustomMap.js" /> + <h:outputScript library="js" name="CustomMapOptions.js" /> + <h:outputScript library="js" name="Functions.js" /> + <h:outputScript library="js" name="GeneVariant.js" /> + <h:outputScript library="js" name="GuiConnector.js" /> + <h:outputScript library="js" name="IdentifiedElement.js" /> + <h:outputScript library="js" name="LayoutAlias.js" /> + <h:outputScript library="js" name="LayoutData.js" /> + <h:outputScript library="js" name="LayoutReaction.js" /> + <h:outputScript library="js" name="MapModel.js"/> + <h:outputScript library="js" name="OverlayCollection.js" /> + <h:outputScript library="js" name="pileup.js"/> + <h:outputScript library="js" name="PointData.js"/> + <h:outputScript library="js" name="PointInfoWindow.js"/> + <h:outputScript library="js" name="PointMarker.js"/> + <h:outputScript library="js" name="Reaction.js" /> + <h:outputScript library="js" name="ReactionMarker.js" /> + <h:outputScript library="js" name="ReactionInfoWindow.js" /> + <h:outputScript library="js" name="ReactionOverlay.js" /> + <h:outputScript library="js" name="ReferenceGenome.js" /> + <h:outputScript library="js" name="ReferenceGenomeGeneMapping.js" /> + <h:outputScript library="js" name="SearchPanel.js" /> + <h:outputScript library="js" name="ServerConnector.js" /> + <h:outputScript library="js" name="Submap.js" /> + <h:outputScript library="js" name="TabNavi.js" /> + <h:outputScript library="js" name="TouchMap.js" /> + + <ui:include src="/WEB-INF/components/map/statistics.xhtml" /> + + <script type="text/javascript"> +//<![CDATA[ + var DEBUG_ON =false; + + if (browser.name=="IE") { + if (browser.version<=8 || browser.compatibilityMode) { + alert("This webpage works only with Internet Explorer version 9 or greater.\n" + + "If you have Internet Explorer version 9 or greater and still see this message, please, turn the 'Compatibility modeoff:\n" + + "Open Internet Explorer and press the Alt key on your keyboard.\n" + + "Select 'Tools' menu item. \n" + + "Select the 'Compatibility View' settings option. \n" + + "Make sure the 'Display all websites in Compatibility View' check box is unchecked and that the 'Compatibility View; list of websites is cleared.\n" + + "\n"+ + "Alternatively, please, use other browsers: Chrome, Firefox or Safari."); + } + } + var configuration = new Configuration(); + +function processUrlGetParams() { + if (GuiConnector.getParams["submap"]==null || configuration.ID_MODEL==GuiConnector.getParams["submap"]) { + if (GuiConnector.getParams["x"]!=undefined && GuiConnector.getParams["y"]!=undefined){ + ServerConnector.setCenterCoordinateX(GuiConnector.getParams["x"]); + ServerConnector.setCenterCoordinateY(GuiConnector.getParams["y"]); + } + if (GuiConnector.getParams["zoom"]!=undefined){ + ServerConnector.setZoomLevel(GuiConnector.getParams["zoom"]); + } + } +} + +function updateConfig() { + var json = document.getElementById('configurationForm:configurationGson').value; +//there are some strange problems here... + json = json.replace(/\n/g," "); + configuration.loadFromModelView(JSON.parse(json)); +} + +function initMap(){ + updateConfig(); + processUrlGetParams(); + + + searchPanel = new SearchPanel(document.getElementById('tabView:mainForm:searchText_input'), + document.getElementById('tabView:mainForm:searchButton'), + function(){ + tabViewVar.select(0); + } + ); + + var mapElement = gmtls.getMap(); + if (configuration.MAPS!=null) { + + var windowsTouchInterface = ((navigator.appVersion.indexOf("Win")!=-1) && ('ontouchstart' in document.documentElement)); + var overviewDiv = document.getElementById("overviewDiv"); + customMap = new CustomMap({ + map : mapElement, + configuration : configuration, + hideDiv : document.getElementById('leftPanel'), + markerOptimization : !windowsTouchInterface, + bigLogo : windowsTouchInterface, + overviewDiv : overviewDiv, + customTouchInterface: windowsTouchInterface + }); + + ServerConnector.setCustomMap(customMap); + GuiConnector.showGoogleMap(); + + ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "search")); + ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "missingConnection")); + ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "drug",true, true)); + ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "chemical",#{chemicalMB.linkedToDisease()}, #{chemicalMB.linkedToDisease() == true})); + ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "mirna",true, true)); + ServerConnector.addOverlayCollection(new OverlayCollection(customMap, "comment",false, true)); + + customMap.refreshOverlays(); + + + if (GuiConnector.getParams["search"]!=undefined) { + searchPanel.search(GuiConnector.getParams["search"]); + } + + if (GuiConnector.getParams["comments"]=="on") { + document.getElementById('comment_checkbox').click(); + } + if (GuiConnector.getParams["layout"]!=undefined) { + document.getElementById('tabView:layoutForm3:hidden2').value=GuiConnector.getParams["layout"]; + getVisualizedLayoutDetails(); + } + + } + //when I try to hide legend from the beginning or in the same thread it's hidden forever... ;/ + setTimeout(function() { + GuiConnector.hideLegend(); + var submodelId = GuiConnector.getParams["submap"]; + if (submodelId!=undefined) { + _createSubmodelDialog([{name:'submodelId', value: submodelId}]); + //for some reason the call above is not sync (even though it's required) + var waitingForResponse = setInterval(function() { + if (GuiConnector.getJsPopupForSubmodelId(submodelId)!=null) { + GuiConnector.openDialog(submodelId); + clearInterval(waitingForResponse); + if (GuiConnector.getParams["zoom"]!=undefined){ + customMap.setZoom(submodelId,parseInt(GuiConnector.getParams["zoom"])); + } + if (GuiConnector.getParams["x"]!=undefined && GuiConnector.getParams["y"]!=undefined){ + var x = GuiConnector.getParams["x"]; + var y = GuiConnector.getParams["y"]; + var point = new google.maps.Point(x, y); + customMap.setCenter(submodelId,point); + } + } + },100); + } + }, 0); +} + + +function removeMissingConnection(id) { + document.getElementById('missingConnectionForm:connectionId').value=""+id; + dlg4.show(); +} + +function removeComment(id) { + document.getElementById('missingConnectionForm:commentId').value=""+id; + dlg5.show(); +} + + +//]]> + </script> +</h:head> +<h:body onload="initMap();" > +<h:outputStylesheet library="css" name="style.css"/> +<h:outputStylesheet library="css" name="pileup.css"/> + + <h:outputScript library="primefaces" name="jquery/jquery.js" target="head" /> + <div class = "containerClass"> + <div id="leftPanel" class ="leftPanelClass"> + + <ui:include src="/WEB-INF/components/admin/header.xhtml" /> + +<!-- <div class="tabNavigation"> + <a href="javascript:;" onclick="GuiConnector.tabNaviShow('prev');" class="naviLeft"><i class="fa fa-chevron-left"></i></a> + <a href="javascript:;" onclick="GuiConnector.tabNaviShow('next');" class="naviRight"><i class="fa fa-chevron-right"></i></a> + </div> +--> + + <p:tabView id="tabView" widgetVar="tabViewVar" styleClass="leftTabView" activeIndex="0" > + <p:tab id="searchTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-search maintab'></i><br>SEARCH</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/searchPanel.xhtml" /> + </p:tab > + <p:tab id="drugTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-map-marker maintab'></i><br>DRUG</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/drugPanel.xhtml" /> + </p:tab > + <p:tab id="chemicalTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-map-marker maintab'></i><br>CHEMICAL</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/chemicalPanel.xhtml" /> + </p:tab > + <p:tab id="miRNATab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-map-marker maintab'></i><br>MiRNA</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/miRNAPanel.xhtml" /> + </p:tab > + <p:tab id="layoutTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-th-list maintab'></i><br>OVERLAYS</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/layoutPanel.xhtml" /> + </p:tab > + <p:tab id="loginTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-sign-in maintab'></i><br>LOGIN</div>" styleClass="leftTab" rendered ="#{userMB.loggedUser.login=='anonymous'}"> + <ui:include src="/WEB-INF/components/map/loginPanel.xhtml" /> + </p:tab > + <p:tab id="profileTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-user maintab'></i><br>PROFILE</div>" styleClass="leftTab" rendered ="#{not (userMB.loggedUser.login=='anonymous')}"> + <ui:include src="/WEB-INF/components/map/profilePanel.xhtml" /> + </p:tab > + <p:tab id="submapTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-sitemap maintab'></i><br>SUBMAPS</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/submapPanel.xhtml" /> + </p:tab > + <p:tab id="infoTab" title="<div class='tngContainer'><div class='tng'></div></div><div class='maintabdiv'><i class='fa fa-info maintab'></i><br>PROJECT</div>" styleClass="leftTab"> + <ui:include src="/WEB-INF/components/map/infoPanel.xhtml" /> + </p:tab > + </p:tabView > + + + <div id="footerLinks"> + <a href="admin.xhtml?id=#{mapMB.currentMapId}" style="float:left; padding-left:25px;"><i class="fa fa-lock" style="font-size:17px"></i> ADMIN</a> + <a href="#{configurationMB.userManual}" target="_user_manual_" style="float:left; padding-left:50px;"><i class="fa" style="font-size:17px"></i> MANUAL</a> + <a href="export.xhtml?id=#{mapMB.currentMapId}" style="float:right; padding-right:25px;">EXPORT <i class="fa fa-mail-forward" style="font-size:17px"></i></a> + </div> + + </div> + <div> + <ui:include src="/WEB-INF/components/map/map.xhtml" /> + </div> + </div> + + <!--<ui:include src="/WEB-INF/components/map/footer.xhtml" />--> + + <ui:include src="/WEB-INF/components/map/feedbackDialog.xhtml" /> + <ui:include src="/WEB-INF/components/map/missingConnectionDialog.xhtml" /> + +</h:body> +</f:view> +</html> diff --git a/web/src/main/webapp/resources/js/AbstractOverlayElement.js b/web/src/main/webapp/resources/js/AbstractOverlayElement.js new file mode 100644 index 0000000000000000000000000000000000000000..ed6e378901475376998f2680a96b83cfecd38a7f --- /dev/null +++ b/web/src/main/webapp/resources/js/AbstractOverlayElement.js @@ -0,0 +1,45 @@ +/** + * Class representing abstract overlay element on the map relevant for a specific + * layout. + */ +function AbstractOverlayElement() { +}; + +AbstractOverlayElement.prototype.overlayToColor = function(elementOverlay) { + if (elementOverlay==null) { + logger.error("elementOverlay cannot be null!"); + } + if (elementOverlay.color!=null) { + return intToColorString(elementOverlay.color.value); + } else if (elementOverlay.value!=null) { + var ratio =0; + var color; + if (elementOverlay.value<0) { + ratio = -elementOverlay.value; + color = ServerConnector.getMinOverlayColorInt(); + } else { + ratio = elementOverlay.value; + color = ServerConnector.getMaxOverlayColorInt(); + } + var red = color & 0xFF0000; + red = red*ratio; + red = parseInt(red); + red = red & 0xFF0000; + + var green = color & 0x00FF00; + green = green*ratio; + green = parseInt(green); + green = green & 0x00FF00; + + var blue = color & 0x0000FF; + blue = blue*ratio; + blue = parseInt(blue); + blue = blue & 0x0000FF; + + var color = red | green | blue; + return intToColorString(color); + } else { + logger.error("elementOverlay doesn't have neither color nor value set!"); + } +}; + diff --git a/web/src/main/webapp/resources/js/AliasOverlay.js b/web/src/main/webapp/resources/js/AliasOverlay.js index 139cb513874055084519eb954bd5b9c27844b682..8fb7581b19ea9132ae4ceefde64979055406f833 100644 --- a/web/src/main/webapp/resources/js/AliasOverlay.js +++ b/web/src/main/webapp/resources/js/AliasOverlay.js @@ -1,104 +1,111 @@ -/** - * Class representing overlay of the alias on the map relevant for a specific - * layout. - */ -function AliasOverlay(paramObj, map, aliasData) { - // google map object associated with the alias - this.gmapObj = paramObj; - // AbstractCustomMap where the alias is located - this.customMap = map; - // original data - this.aliasData = aliasData; - - var self = this; - var onclick = (function() { - var aliasOverlayData = self; - return function() { - customMap.openInfoWindowForAlias(aliasOverlayData.aliasData.id, - aliasOverlayData.customMap.id); - }; - })(); - google.maps.event.addListener(paramObj, 'click', onclick); -}; - -/** - * Sets Google map to this {@link AliasOverlay}. - * - * @param map - * map to set - */ -AliasOverlay.prototype.setMap = function(map) { - this.gmapObj.setMap(map); -} - -/** - * Function used to recalculate boundaries of the {@link AliasOverlay}. - * Boundaries define how big part of original alias is taken by this layout - * visualization. - * - * @param startX - * value between 0..1 defininf where should be the start on OX axis - * @param endX - * value between 0..1 defininf where should be the end on OX axis - */ -AliasOverlay.prototype.setBoundsForAlias = function(startX, endX) { - var pointA = new google.maps.Point(this.aliasData.x + startX - * this.aliasData.width, this.aliasData.y); - var pointB = new google.maps.Point(this.aliasData.x + endX - * this.aliasData.width, this.aliasData.y + this.aliasData.height); - var latLngA = this.customMap.fromPointToLatLng(pointA); - var latLngB = this.customMap.fromPointToLatLng(pointB); - - var bounds = new google.maps.LatLngBounds(); - bounds.extend(latLngA); - bounds.extend(latLngB); - - this.gmapObj.setBounds(bounds); -} - -/** - * Creates {@link AliasOverlay} from input data. - * - * @param layoutAlias - * {@link LayoutAlias} for which overlay is created - * @param aliasData - * {@link Alias data} of the alias - * @param map - * {@link AbstractCustomMap} where overlay should be placed - * @param startX - * this is the ratio on OX axis that should be use as a starting - * point of the overlay. For instance when there are three layouts to - * visualize then - * <ul> - * <li>the first layout have startX=0.0; endX=0.33333</li> - * <li>second layout have startX=0.33333; endX=0.66666</li> - * <li>the last layout have startX=0.66666; endX=1.0</li> - * </ul> - * @param endX - * this is the ratio on OX axis that should be use as a starting - * point of the overlay - * @returns {AliasOverlay} - */ -AliasOverlay.create = function(layoutAlias, aliasData, map, startX, endX) { - var pointA = new google.maps.Point(aliasData.x + startX * aliasData.width, - aliasData.y); - var pointB = new google.maps.Point(aliasData.x + endX * aliasData.width, - aliasData.y + aliasData.height); - var latLngA = map.fromPointToLatLng(pointA); - var latLngB = map.fromPointToLatLng(pointB); - - var bounds = new google.maps.LatLngBounds(); - bounds.extend(latLngA); - bounds.extend(latLngB); - var color = intToColorString(layoutAlias.color.value); - var rectangle = new google.maps.Rectangle({ - fillColor : color, - fillOpacity : 0.8, - strokeWeight : 1, - map : map.map, - bounds : bounds - }); - var result = new AliasOverlay(rectangle, map, aliasData); - - return result; -}; +/** + * Class representing overlay of the alias on the map relevant for a specific + * layout. + */ +function AliasOverlay(paramObj, map, aliasData) { + // call super constructor + AbstractOverlayElement.call(); + + // google map object associated with the alias + this.gmapObj = paramObj; + // AbstractCustomMap where the alias is located + this.customMap = map; + // original data + this.aliasData = aliasData; + + var self = this; + var onclick = (function() { + var aliasOverlayData = self; + return function() { + customMap.openInfoWindowForAlias(aliasOverlayData.aliasData.id, + aliasOverlayData.customMap.id); + }; + })(); + google.maps.event.addListener(paramObj, 'click', onclick); +}; + +AliasOverlay.prototype = Object.create(AbstractOverlayElement.prototype); +AliasOverlay.prototype.constructor = AliasOverlay; + + +/** + * Sets Google map to this {@link AliasOverlay}. + * + * @param map + * map to set + */ +AliasOverlay.prototype.setMap = function(map) { + this.gmapObj.setMap(map); +} + +/** + * Function used to recalculate boundaries of the {@link AliasOverlay}. + * Boundaries define how big part of original alias is taken by this layout + * visualization. + * + * @param startX + * value between 0..1 defininf where should be the start on OX axis + * @param endX + * value between 0..1 defininf where should be the end on OX axis + */ +AliasOverlay.prototype.setBoundsForAlias = function(startX, endX) { + var pointA = new google.maps.Point(this.aliasData.x + startX + * this.aliasData.width, this.aliasData.y); + var pointB = new google.maps.Point(this.aliasData.x + endX + * this.aliasData.width, this.aliasData.y + this.aliasData.height); + var latLngA = this.customMap.fromPointToLatLng(pointA); + var latLngB = this.customMap.fromPointToLatLng(pointB); + + var bounds = new google.maps.LatLngBounds(); + bounds.extend(latLngA); + bounds.extend(latLngB); + + this.gmapObj.setBounds(bounds); +} + +/** + * Creates {@link AliasOverlay} from input data. + * + * @param layoutAlias + * {@link LayoutAlias} for which overlay is created + * @param aliasData + * {@link Alias data} of the alias + * @param map + * {@link AbstractCustomMap} where overlay should be placed + * @param startX + * this is the ratio on OX axis that should be use as a starting + * point of the overlay. For instance when there are three layouts to + * visualize then + * <ul> + * <li>the first layout have startX=0.0; endX=0.33333</li> + * <li>second layout have startX=0.33333; endX=0.66666</li> + * <li>the last layout have startX=0.66666; endX=1.0</li> + * </ul> + * @param endX + * this is the ratio on OX axis that should be use as a starting + * point of the overlay + * @returns {AliasOverlay} + */ +AliasOverlay.create = function(layoutAlias, aliasData, map, startX, endX) { + var pointA = new google.maps.Point(aliasData.x + startX * aliasData.width, + aliasData.y); + var pointB = new google.maps.Point(aliasData.x + endX * aliasData.width, + aliasData.y + aliasData.height); + var latLngA = map.fromPointToLatLng(pointA); + var latLngB = map.fromPointToLatLng(pointB); + + var bounds = new google.maps.LatLngBounds(); + bounds.extend(latLngA); + bounds.extend(latLngB); + var rectangle = new google.maps.Rectangle({ + fillOpacity : 0.8, + strokeWeight : 1, + map : map.map, + bounds : bounds + }); + var result = new AliasOverlay(rectangle, map, aliasData); + var color = result.overlayToColor(layoutAlias); +rectangle.setOptions({fillColor: color}); + + return result; +}; diff --git a/web/src/main/webapp/resources/js/CustomMap.js b/web/src/main/webapp/resources/js/CustomMap.js index 443eb5ab987b75f740239fd90ee0b9138e924fcf..5cc4d0487070994fe9715650f51739244c79897b 100644 --- a/web/src/main/webapp/resources/js/CustomMap.js +++ b/web/src/main/webapp/resources/js/CustomMap.js @@ -1,1735 +1,1741 @@ -/** - * Default constructor. - * - * @param globalMap - * google.maps.Map object representing the map - * @param configuration - * Configuration object representing our data in the map - * @param bigButtons - * boolean value determining if the buttons on the map should be big, - * and if the map is run on the touch interface - * @param hideDiv - * - */ -function CustomMap(options) { - if (!(options instanceof CustomMapOptions)) { - options = new CustomMapOptions(options); - } - AbstractCustomMap.call(this, options); - - // set config parameters - this.map = options.getMap(); - - if (options.isCustomTouchInterface()) { - this._touchInterface = new TouchMap(this); - } - - // create function that override primefaces fitBounds with default google - // implementation - var fitBounds = function(bounds) { - var tmp = this.fitBounds; - this.fitBounds = google.maps.Map.prototype.fitBounds; - this.fitBounds(bounds); - this.fitBounds = tmp; - }; - this.map.fitBounds2 = fitBounds; - - this.buttons = []; - - this.createSubmaps(); - - this.selectedLayouts = []; - - this.setupLayouts(); - - this.createBelt(); - - this.customizeGoogleMapView(); - - this.createMapChangedCallbacks(); - - this.createClientServerListeners(); - - this.overlayCollections = []; - - // which submap is active (where user made interaction for the last time) - this._activeSubmapId = null; - - this.initialized = true; - - // list of reference genomes - this._referenceGenome = []; - - ServerConnector.actualizeSessionData(); -} - -CustomMap.prototype = Object.create(AbstractCustomMap.prototype); - -CustomMap.prototype.constructor = CustomMap; - -CustomMap.prototype.createSubmaps = function() { - this.submaps = []; - for (var i = 0; i < this.getConfiguration().SUBMODELS.length; i++) { - this.submaps.push(new Submap(this, - this.getConfiguration().SUBMODELS[i].ID_MODEL)); - } -}; - -CustomMap.prototype.createLogo = function() { - - var logoControlDiv = document.createElement('DIV'); - var logo = document.createElement('IMG'); - var url = ServerConnector.getLogoImg(); - if (!/^(f|ht)tps?:\/\//i.test(url)) { - url = GuiConnector.getImgPrefix() + url; - } - logo.src = url; - logo.style.cursor = 'pointer'; - logo.style.width = "80px"; - logoControlDiv.appendChild(logo); - google.maps.event.addDomListener(logo, 'click', function() { - var win = window.open(ServerConnector.getLogoLink(), '_blank'); - win.focus(); - }); - logoControlDiv.index = 0; // used for ordering - this.map.controls[google.maps.ControlPosition.LEFT_BOTTOM] - .push(logoControlDiv); - - var logoControlDiv = document.createElement('DIV'); - logoControlDiv.style.padding = '5px'; - - var logo = document.createElement('IMG'); - logo.src = GuiConnector.getImgPrefix() - + GuiConnector.getLcsbLogoImg(this.bigButtons); - logo.style.cursor = 'pointer'; - logoControlDiv.appendChild(logo); - google.maps.event.addDomListener(logo, 'click', function() { - var win = window.open('http://wwwen.uni.lu/lcsb/', '_blank'); - win.focus(); - }); - - logoControlDiv.index = 1; // used for ordering - this.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM] - .push(logoControlDiv); -}; - -CustomMap.prototype.createBelt = function() { - var self = this; - - this.divBelt = document.createElement('DIV'); - this.divBelt.className = "headerBelt"; - - var hideDivButton = document.createElement('DIV'); - hideDivButton.className = "headerHideDivButton"; - - var hideButton = document.createElement('button'); - hideButton.id = "hide_button"; - hideButton.className = "headerHideButton"; - hideButton.innerHTML = "<i class='fa fa-chevron-left'></i>"; - // when there is no div to hide we should allow hiding - if (self.getHideDiv() !== undefined) { - hideButton.onclick = (function() { - var button = hideButton; - var div = self.getHideDiv(); - - var left = $(PrimeFaces.escapeClientId(self.map.getDiv().id)).offset().left; - return function() { - if (button.innerHTML.indexOf('fa-chevron-left') > 0) { - button.innerHTML = "<i class='fa fa-chevron-right'></i>"; - div.style.display = 'none'; - self.map.getDiv().style.left = "0px"; - } else { - div.style.display = 'block'; - button.innerHTML = "<i class='fa fa-chevron-left'></i>"; - self.map.getDiv().style.left = left + "px"; - } - google.maps.event.trigger(self.map, 'resize'); - return false; - }; - })(); - } else { - hideButton.disabled = true; - logger.warn("Left panel hiding disabled"); - } - hideDivButton.appendChild(hideButton); - hideDivButton.index = 1; // used for ordering - this.divBelt.appendChild(hideDivButton); - - var controlText = document.createElement('div'); - controlText.className = "headerTextBold"; - controlText.innerHTML = this.getConfiguration().MAP_NAME; - this.divBelt.appendChild(controlText); - - this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.divBelt); -}; - -CustomMap.prototype.setLegendVisible = function(vis) { - if (vis) { - document.getElementById('legend').style.display = 'block'; - } else { - document.getElementById('legend').style.display = 'none'; - } -}; - -CustomMap.prototype.clearOverlays = function() { - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName)) { - var collection = this.overlayCollections[overlayName]; - this.clearOverlayCollection(collection); - } - } -}; - -CustomMap.prototype.refreshOverlays = function() { - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName)) { - var collection = this.overlayCollections[overlayName]; - collection.refresh(); - } - } -}; - -/** - * Removes all markers from {@link OverlayCollection}. - * - * @param collection - * {@link OverlayCollection} from which all markers should be removed - */ -CustomMap.prototype.clearOverlayCollection = function(collection) { - logger.debug("Clear collection: " + collection.name); - for ( var key in collection.aliasMarkers) { - if (collection.aliasMarkers.hasOwnProperty(key) - && collection.aliasMarkers[key] != null) { - collection.aliasMarkers[key].setMap(null); - } - } - - for ( var key in collection.pointMarkers) { - if (collection.pointMarkers.hasOwnProperty(key) - && collection.pointMarkers[key] != null) { - - collection.pointMarkers[key].setMap(null); - } - } - - for ( var key in collection.reactionMarkers) { - if (collection.reactionMarkers.hasOwnProperty(key) - && collection.reactionMarkers[key] != null) { - collection.reactionMarkers[key].setMap(null); - } - } - - collection.aliasMarkers = []; - collection.pointMarkers = []; - collection.reactionMarkers = []; -}; - -/** - * Updates data about visualized markers in {@link OverlayCollection}. - * - * @param overlayCollection - * {@link OverlayCollection} with new data to visualize - * @param fitBounds - * <code>true</code> id the map should fit bounds to the new - * elements after update, <code>false</code> otherwise - */ -CustomMap.prototype.updateOverlayCollection = function(overlayCollection, - fitBounds) { - this.clearOverlayCollection(overlayCollection); - this.renderOverlayCollection(overlayCollection, fitBounds); -}; - -/** - * This method open layout by a given layout identifier (string starting with - * 'cv' prefix) in a map and all submaps. - * - * @param identifier - * identifier of the layout to present - */ -CustomMap.prototype.openLayout = function(identifier) { - logger.debug("Opening layout: " + identifier); - - this.map.setMapTypeId(identifier); - - var index = null; - for (var i = 0; i < this.getConfiguration().MAPS.length; i++) { - if ('cv' + this.getConfiguration().MAPS[i].idObject == identifier) { - index = i; - } - } - if (index == null) { - logger.warn("Invalid layout identifier: " + identifier); - } - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i].openLayout('cv' - + this.submaps[i].getConfiguration().MAPS[index].idObject); - } -}; - -/** - * This method open layout by a given database identifier. - * - * @param identifier - * identifier of the layout to present - */ -CustomMap.prototype.openLayoutById = function(identifier) { - logger.debug("Opening layout: " + identifier); - var index = null; - for (var i = 0; i < configuration.MAPS.length; i++) { - if (configuration.MAPS[i].idObject == identifier) { - index = 'cv' + identifier; - } - } - - // if layout doesn't exist print error - if (index == null) { - alert("You have no privileges for selected layout"); - } else { - this.openLayout(index); - } -}; - -CustomMap.prototype.createMapMenu = function(layoutButtons) { - var selfMap = this; - - var buttons = []; - - // create a button for overview images when the image is available - if (this.getConfiguration().TOP_OVERVIEW_IMAGE != "undefined" - && this.getConfiguration().TOP_OVERVIEW_IMAGE != null) { - var submenuButtonDiv = document.createElement('button'); - buttons.push(submenuButtonDiv); - submenuButtonDiv.id = "overview_button"; - submenuButtonDiv.innerHTML = "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i> SHOW OVERVIEW"; - submenuButtonDiv.className = "overview_button"; - submenuButtonDiv.onclick = (function() { - return function() { - selfMap.showOverview(); - return false; - }; - })(); - this.divBelt.appendChild(submenuButtonDiv); - } - - var rightHeaderMenu = document.createElement('div'); - rightHeaderMenu.className = "rightHeaderMenu"; - var submenuDiv = document.createElement('div'); - submenuDiv.className = "div4checkboxes"; - var submenuButtonDiv = document.createElement('input'); - submenuButtonDiv.type = "checkbox"; - submenuButtonDiv.name = "Comments"; - submenuButtonDiv.id = "comment_checkbox"; - submenuButtonDiv.onclick = (function() { - var selfButton = submenuButtonDiv; - return function() { - selfMap.showComments = selfButton.checked; - ServerConnector.setShowComments(selfButton.checked); - if (selfButton.checked) { - document.getElementById('refresh_comments_button').style.display = 'inline'; - } else { - document.getElementById('refresh_comments_button').style.display = 'none'; - } - selfMap.refreshComments(); - - }; - })(); - var element = document.createElement('label'); - element.innerHTML = "COMMENTS"; - element.setAttribute("for", "comment_checkbox"); - submenuDiv.appendChild(submenuButtonDiv); - submenuDiv.appendChild(element); - - var submenuButtonDiv = document.createElement('input'); - submenuButtonDiv.type = "checkbox"; - submenuButtonDiv.name = "Legend"; - submenuButtonDiv.id = "lengend_checkbox"; - submenuButtonDiv.onclick = (function() { - var selfButton = submenuButtonDiv; - return function() { - if (selfButton.checked) { - GuiConnector.showLegend(); - } else { - GuiConnector.hideLegend(); - } - }; - })(); - element = document.createElement('label'); - element.innerHTML = "LEGEND"; - element.setAttribute("for", "lengend_checkbox"); - submenuDiv.appendChild(submenuButtonDiv); - submenuDiv.appendChild(element); - - submenuButtonDiv = document.createElement('button'); - submenuButtonDiv.id = "refresh_comments_button"; - submenuButtonDiv.innerHTML = "<i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i>"; - submenuButtonDiv.className = "overview_button"; - submenuButtonDiv.style.display = 'none'; - submenuButtonDiv.onclick = (function() { - return function() { - selfMap.refreshComments(); - return false; - }; - })(); - submenuDiv.appendChild(submenuButtonDiv); - rightHeaderMenu.appendChild(submenuDiv); - - var submenuButtonDiv = document.createElement('button'); - buttons.push(submenuButtonDiv); - submenuButtonDiv.id = "clear_button"; - submenuButtonDiv.className = "overview_button"; - submenuButtonDiv.innerHTML = "<i class='fa fa-times' style='font-size:18px; font-weight:300; padding-right:10px;'></i> CLEAR"; - submenuButtonDiv.title = "Clear all queries"; - submenuButtonDiv.style.display = 'inline'; - submenuButtonDiv.onclick = (function() { - return function() { - selfMap.clearData(); - return false; - }; - })(); - rightHeaderMenu.appendChild(submenuButtonDiv); - - this.divBelt.appendChild(rightHeaderMenu); -}; - -CustomMap.prototype.registerSource = function(overlayCollection) { - this.overlayCollections[overlayCollection.name] = overlayCollection; - overlayCollection.aliasMarkers = []; - overlayCollection.pointMarkers = []; - overlayCollection.reactionMarkers = []; -}; - -CustomMap.prototype.refreshComments = function() { - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName) - && overlayName == "comment") { - var collection = this.overlayCollections[overlayName]; - collection.refresh(); - return; - } - } - throw "comment OverlayCollection not found"; -}; - -CustomMap.prototype.turnOnOffDrawing = function() { - var model = this.getSubmodelById(this.getActiveSubmapId()); - if (model != null) { - model._turnOnOffDrawing(); - } else { - throw "Cannot find submodel with id: " + this.getActiveSubmapId(); - } -}; - -CustomMap.prototype.clearData = function() { - this.clearOverlays(); - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName)) { - ServerConnector.sendClearRequest(overlayName); - } - } -}; - -CustomMap.prototype.refreshMarkers = function() { - logger.debug("Refresh Markers: "); - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName)) { - var collection = this.overlayCollections[overlayName]; - this.refreshOverlayMarkers(collection); - } - } -}; - -CustomMap.prototype.refreshOverlayMarkers = function(overlay) { - var self = this; - logger.debug("Refresh overlay: " + overlay.name); - var boundsArray = []; - boundsArray[this.getId()] = new google.maps.LatLngBounds(); - for (var i = 0; i < this.submaps.length; i++) { - boundsArray[this.submaps[i].getId()] = new google.maps.LatLngBounds(); - } - - var updated = false; - var stillMissing = false; - for ( var key in overlay.aliasMarkers) { - if (overlay.aliasMarkers.hasOwnProperty(key) - && overlay.aliasMarkers[key] != null) { - var alias = overlay.aliasMarkers[key]; - if (alias.getAliasData() == null) { - var aliasData = alias.getCustomMap().mapModel.getAliasById(alias - .getId()); - if (aliasData != null) { - alias.setAliasData(aliasData); - alias.init(); - alias.show(); - updated = true; - var bounds = alias.getBounds(); - boundsArray[alias.getCustomMap().getId()].extend(bounds - .getNorthEast()); - } else { - stillMissing = true; - logger.debug("Cannot show alias marker. Data is still not loaded..."); - } - } else { - var bounds = alias.getBounds(); - if (!this.isMarkerOptimization()) { - alias.hide(); - alias.show(); - } - boundsArray[alias.getCustomMap().getId()].extend(bounds.getNorthEast()); - boundsArray[alias.getCustomMap().getId()].extend(bounds.getSouthWest()); - } - } - } - - for ( var key in overlay.pointMarkers) { - if (overlay.pointMarkers.hasOwnProperty(key) - && overlay.pointMarkers[key] != null) { - var alias = overlay.pointMarkers[key]; - // we don't need to update this markers because thet data about - // visualization is - // already there - // alias.update(); - var bounds = alias.getBounds(); - if (!this.isMarkerOptimization()) { - alias.hide(); - alias.show(); - } - boundsArray[alias.getCustomMap().getId()].extend(bounds.getNorthEast()); - } - } - - for ( var key in overlay.reactionMarkers) { - if (overlay.reactionMarkers.hasOwnProperty(key) - && overlay.reactionMarkers[key] != null) { - var reactionOverlay = overlay.reactionMarkers[key]; - if (reactionOverlay.getReactionData() == null) { - var reactionData = reactionOverlay.getCustomMap().mapModel - .getReactionById(reactionOverlay.getId()); - if (reactionData != null) { - reactionOverlay.setReactionData(reactionData); - reactionOverlay.init(); - reactionOverlay.show(); - updated = true; - var bounds = reactionOverlay.getBounds(); - boundsArray[reactionOverlay.getCustomMap().getId()].extend(bounds - .getNorthEast()); - boundsArray[reactionOverlay.getCustomMap().getId()].extend(bounds - .getSouthWest()); - } else { - stillMissing = true; - logger - .debug("Cannot show reaction marker. Data is still not loaded..."); - } - } else { - var bounds = alias.getBounds(); - if (!this.isMarkerOptimization()) { - alias.hide(); - alias.show(); - } - boundsArray[alias.getCustomMap().getId()].extend(bounds.getNorthEast()); - boundsArray[alias.getCustomMap().getId()].extend(bounds.getSouthWest()); - } - - } - } - - if (!stillMissing && updated && overlay.fitBounds) { - for ( var mapId in boundsArray) { - if (boundsArray.hasOwnProperty(mapId)) { - var map = this.getSubmodelById(mapId).map; - var bounds = boundsArray[mapId]; - if (map != null && !bounds.isEmpty()) { - if (typeof map.fitBounds2 !== "undefined") { - map.fitBounds2(bounds); - } else { - map.fitBounds(bounds); - } - } - } - } - } -}; - -CustomMap.prototype.openSubmodel = function(id, htmlTag, jsVar) { - if (jsVar.submapControler == null) { - var submap = null; - for (var i = 0; i < this.submaps.length; i++) { - if (this.submaps[i].getId() == id) { - submap = this.submaps[i]; - } - } - if (submap == null) { - logger.error("Unknown submap for id: " + id); - } else { - submap.init(htmlTag, jsVar); - submap.openLayout(this.map.getMapTypeId()); - this.refreshOverlays(); - - // now we have to visualize layouts - var layouts = []; - - // get list of layouts - for ( var key in this.selectedLayouts) { - if (this.selectedLayouts.hasOwnProperty(key) - && this.selectedLayouts[key] == true) { - layouts.push(key); - } - } - - // show layouts that should be visualized (resize or show them) - for (var i = 0; i < layouts.length; i++) { - var layoutId = layouts[i]; - submap._showSelectedLayout(layoutId, i, layouts.length); - } - } - } - jsVar.show(); -}; - -CustomMap.prototype.customizeGoogleMapView = function() { - var mapOptions = this.creatMapOptions(); - this.map.setOptions(mapOptions); - - this.createMapMenu(false); - - this.registerMapClickEvents(); - - this.createLogo(); - // this.createMapVersion(); - google.maps.event.trigger(this.map, 'resize'); - google.maps.event.trigger(this.map, 'maptypeid_changed'); - google.maps.event.trigger(this.map, 'projection_changed'); - - // center map and zoom in to fit into browser window - if (this.getConfiguration().fitMapBounds) { - var bounds = new google.maps.LatLngBounds(); - var point = new google.maps.LatLng( - this.getConfiguration().topLeftLatLng.lat, - this.getConfiguration().topLeftLatLng.lng); - bounds.extend(point); - - point = new google.maps.LatLng( - this.getConfiguration().bottomRightLatLng.lat, - this.getConfiguration().bottomRightLatLng.lng); - bounds.extend(point); - - if (typeof this.map.fitBounds2 !== "undefined") { - this.map.fitBounds2(bounds); - } else { - this.map.fitBounds(bounds); - } - } -}; - -CustomMap.prototype.setCenter = function(mapIdentifier, coordinates) { - if (this.getConfiguration().ID_MODEL == mapIdentifier) { - this.map.setCenter(coordinates); - } else { - openDialog(mapIdentifier); - for (var i = 0; i < this.submaps.length; i++) { - if (this.submaps[i].getId() == mapIdentifier) { - this.submaps[i].map.setCenter(coordinates); - } - } - } -}; - -CustomMap.prototype.setZoom = function(mapIdentifier, zoom) { - if (this.getConfiguration().ID_MODEL == mapIdentifier) { - this.map.setZoom(zoom); - } else { - openDialog(mapIdentifier); - for (var i = 0; i < this.submaps.length; i++) { - if (this.submaps[i].getId() == mapIdentifier) { - this.submaps[i].map.setZoom(zoom); - } - } - } -}; - -/** - * Creates listeners for google.maps.Map object that will actualize the data in - * user session. - */ -CustomMap.prototype.createMapChangedCallbacks = function() { - var customMapSelf = this; - // listener for changing zoom level - google.maps.event.addListener(this.map, 'zoom_changed', function() { - ServerConnector.setZoomLevel(customMapSelf.map.getZoom()); - ServerConnector.actualizeSessionData(); - }); - - // if we have zoom level data stored in session then restore it - var level = ServerConnector.getZoomLevel(); - if (parseInt(level) > 0) { - level = parseInt(level); - this.map.setZoom(level); - } else { - ServerConnector.setZoomLevel(customMapSelf.map.getZoom()); - } - - // listener for changing location of the map (moving left/reght/top/bottom - google.maps.event.addListener(this.map, 'center_changed', function() { - var coord = customMapSelf.map.getCenter(); - var point = customMapSelf.fromLatLngToPoint(coord); - ServerConnector.setCenterCoordinateX(point.x); - ServerConnector.setCenterCoordinateY(point.y); - ServerConnector.actualizeSessionData(); - }); - - // if we have coordinate data stored in session then restore it - var x = ServerConnector.getCenterCoordinateX(); - var y = ServerConnector.getCenterCoordinateY(); - if (!isNaN(x) && !isNaN(y)) { - var point = new google.maps.Point(x, y); - var coord = customMapSelf.fromPointToLatLng(point); - customMapSelf.map.setCenter(coord); - } - - // listener for changing type of layout - google.maps.event.addListener(this.map, 'maptypeid_changed', function() { - ServerConnector.setSelectedLayout(customMapSelf.map.getMapTypeId()); - ServerConnector.actualizeParams(); - }); - - // if we have type of layout stored in the session then restore it - var mapType = ServerConnector.getSelectedLayout(); - if (mapType != "" && mapType != null) { - this.openLayout(mapType); - } -}; - -/** - * Returns submodel (or this model) by identfier of the model. - * - * @param identifier - * identifier of the submodel - * @returns submodel (or this model) with given identfier of the model - */ -CustomMap.prototype.getSubmodelById = function(identifier) { - if (this.getId() == identifier) { - return this; - } - for (var i = 0; i < this.submaps.length; i++) { - if (this.submaps[i].getId() == identifier) { - return this.submaps[i]; - } - } - return null; -}; - -CustomMap.prototype.removeSelection = function() { - var model = this.getSubmodelById(this.getActiveSubmapId()); - if (model != null) { - model._removeSelection(); - } else { - throw "Cannot find submodel with id: " + this.getActiveSubmapId(); - } -}; - -/** - * This method will hide google map view and will present single image overview - * of the data. - */ -CustomMap.prototype.showOverview = function(overviewImageId) { - overviewDialog.syncWindowResize(); - if (this.getOverviewDiv() == "undefined" || this.getOverviewDiv() == null) { - logger.warn("Cannot show overview, because overview div is undefined"); - } else { - logger.debug("Show overview"); - overviewDialog.show(); - - // resize dialog - var htmlTag = GuiConnector.getOverviewHtmlTag(); - - var width = Math.floor(window.innerWidth * 2 / 3); - var height = Math.floor(window.innerHeight * 2 / 3); - - htmlTag.style.height = (height + 50) + "px"; - htmlTag.style.width = (width + 20) + "px"; - - var self = this; - - // remove all child nodes from overview div - while (this.getOverviewDiv().hasChildNodes()) { - this.getOverviewDiv().removeChild(this.getOverviewDiv().lastChild); - } - - if (overviewImageId == "undefined" || overviewImageId == null) { - this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE; - } else { - this.overviewImage = null; - for (var i = 0; i < this.getConfiguration().OVERVIEW_IMAGES.length; i++) { - if (this.getConfiguration().OVERVIEW_IMAGES[i].idObject == overviewImageId) { - this.overviewImage = this.getConfiguration().OVERVIEW_IMAGES[i]; - } - } - - if (this.overviewImage == null) { - logger.warn("Unknown overview image with id = " + overviewImageId); - this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE; - } - } - - // add image to overview div - this.overviewImageTag = document.createElement("IMG"); - this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename; - this.getOverviewDiv().appendChild(this.overviewImageTag); - - var ratio = 1.0; - - // check how image should be resized to fit dialog and resize it manually!!! - if (width / this.overviewImage.width > height / this.overviewImage.height) { - this.overviewImageTag.style.height = height + "px"; - ratio = height / this.overviewImage.height; - width = this.overviewImage.width * ratio; - - htmlTag.style.width = (width + 20) + "px"; - } else { - this.overviewImageTag.style.width = width + "px"; - ratio = width / this.overviewImage.width; - height = this.overviewImage.height * ratio; - - htmlTag.style.height = (height + 50) + "px"; - } - - // center dialog - overviewDialog.jq.css("top", Math.max(0, - (($(window).height() - overviewDialog.jq.outerHeight()) / 2) - + $(window).scrollTop()) - + "px"); - overviewDialog.jq.css("left", Math.max(0, - (($(window).width() - overviewDialog.jq.outerWidth()) / 2) - + $(window).scrollLeft()) - + "px"); - - // on click event (what should happen when we click on the image) - var onclickevent = function getClickPosition(e) { - var parentPosition = getPosition(e.currentTarget); - var xPosition = e.clientX - parentPosition.x; - var yPosition = e.clientY - parentPosition.y; - - var imgWidth = self.overviewImageTag.offsetWidth; - - var currentRatio = imgWidth / self.overviewImage.width; - - var xNormal = xPosition / currentRatio; - var yNormal = yPosition / currentRatio; - var point = { - x : xNormal, - y : yNormal - }; - - var link = null; - for (var i = 0; i < self.overviewImage.links.length; i++) { - if (pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { - if (link == null) { - link = self.overviewImage.links[i]; - } else { - logger.warn("More than one link found. Skipping"); - } - } - } - if (link != null) { - if (link.type == "OverviewModelLink") { - logger.debug("Opening model from overview. ModelId: " - + link.modelLinkId); - logger.debug("link coordinates [" + link.idObject + "]: " - + link.latLng); - // TODO min zoom value can be different for every map, it should be - // changed in the future - self.showModel(link.modelLinkId, link.latLng, link.zoomLevel - + self.getConfiguration().MIN_ZOOM); - overviewDialog.hide(); - } else if (link.type == "OverviewImageLink") { - logger.debug("Opening image from overview. ImageId: " - + link.imageLinkId); - self.showOverview(link.imageLinkId); - } else if (link.type == "OverviewSearchLink") { - logger.debug("Sending search query. Query: " + link.query); - searchPanel.search(link.query); - overviewDialog.hide(); - } else { - logger.warn("Unknown type of link: " + link.type - + ". Don't know what to do... LinkId: " + link.idObject); - } - } - }; - - this.overviewImageTag.onclick = onclickevent; - - // resize canvas where on mouse over highligh will appear - var canvas = document.getElementById("canvasDebug"); - canvas.width = width; - canvas.height = height; - canvas.onclick = onclickevent; - - // in debug mode draw clickable shapes - if (DEBUG_ON) { - var ctx = canvas.getContext("2d"); - // clear canvas - ctx.clearRect(0, 0, canvas.width, canvas.height); - for (var i = 0; i < this.overviewImage.links.length; i++) { - ctx.beginPath(); - var polygon = this.overviewImage.links[i].polygon; - for (var j = 0; j < polygon.length; j++) { - var x = polygon[j].x * ratio; - var y = polygon[j].y * ratio; - ctx.moveTo(x, y); - x = polygon[(j + 1) % polygon.length].x * ratio; - y = polygon[(j + 1) % polygon.length].y * ratio; - ctx.lineTo(x, y); - } - ctx.stroke(); - } - } - - this.overviewImage.mousePos = { - x : 0, - y : 0 - }; - - // this listener should be called when mouse moves over image, it purpose is - // to change coursor to pointer when mouse enters clickable polygon and back - // to normal when mouse leaves such region - var onmousemove = function getMouseOverPosition(e) { - var position = getPosition(e.currentTarget); - position.x = e.clientX - position.x; - position.y = e.clientY - position.y; - - var imgWidth = self.overviewImageTag.offsetWidth; - - var currentRatio = imgWidth / self.overviewImage.width; - - var xNormal = position.x / currentRatio; - var yNormal = position.y / currentRatio; - var point = { - x : xNormal, - y : yNormal - }; - - if (self.overviewImage.mousePos.x != position.x - || self.overviewImage.mousePos.y != position.y) { - self.overviewImage.mousePos = position; - var link = null; - for (var i = 0; i < self.overviewImage.links.length; i++) { - if (pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { - link = self.overviewImage.links[i]; - } - } - if (link == null) { - e.currentTarget.style.cursor = "auto"; - } else { - e.currentTarget.style.cursor = "pointer"; - } - } - }; - - // onmousemove listener should be assigned to canvas (which is on top of the - // image) and overviewimage (just in case something went wrong with resizing - // canvas) - canvas.onmousemove = onmousemove; - this.overviewImageTag.onmousemove = onmousemove; - } -}; - -CustomMap.prototype.showModel = function(id, point, zoomLevel) { - if (point != "undefined") { - this.setCenter(id, point); - } else { - logger.warn("Center point undefined..."); - } - if (zoomLevel != "undefined") { - this.setZoom(id, zoomLevel); - } else { - logger.warn("Zoom level undefined..."); - } -}; - -/** - * Adds information about aliases visible in the specific layout. - * - * @param layoutId - * identifier of the layout - * - * @param jsonAliases - * list of aliases in json format - * - */ -CustomMap.prototype.addAliasesForLayout = function(layoutId, jsonAliases) { - logger.debug("Adding aliases for layout: " + layoutId); - - // init layout data - if (this.mapModel.getLayoutDataById(layoutId) == null) { - this.mapModel.initLayoutData(layoutId); - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i].mapModel.initLayoutData(layoutId); - } - } - - var aliases = JSON.parse(jsonAliases); - for (var i = 0; i < aliases.length; i++) { - var alias = aliases[i]; - var model = this.getSubmodelById(alias.modelId); - if (model != 'undefined' && model != null) { - model.mapModel.addAliasForLayout(layoutId, alias); - } else { - logger.warn("Unknown model: " + alias.modelId); - } - } - - this.retrieveMissingAliases(); -} - -/** - * Adds information about aliases. - * - * @param jsonAliases - * list of aliases in json format - * - */ -CustomMap.prototype.addAliases = function(aliases) { - for (var i = 0; i < aliases.length; i++) { - var alias = aliases[i]; - var model = this.getSubmodelById(alias.modelId); - if (model != 'undefined' && model != null) { - model.addAlias(alias); - } else { - logger.warn("Unknown model: " + alias.modelId); - } - } - this.callListeners("onAddAliases"); -} - -/** - * This function will ask server for aliases that should be visualized but the - * data is still missing on the client side. - */ -CustomMap.prototype.retrieveMissingAliases = function() { - var ids = []; - var missing = this.mapModel.getMissingAliasIds(); - for (var j = 0; j < missing.length; j++) { - ids.push([ this.getId(), missing[j] ]); - } - for (var i = 0; i < this.submaps.length; i++) { - missing = this.submaps[i].mapModel.getMissingAliasIds(); - for (var j = 0; j < missing.length; j++) { - ids.push([ this.submaps[i].getId(), missing[j] ]); - } - } - if (ids.length > 0) { - // load data from server about missing aliases - ServerConnector.retreiveLightAliases(ids); - } - if (!ServerConnector.isWaitingForData()) { - // if we already have everything then just refresh data to be visualized - this.refreshSelectedLayouts(); - //and close "loading" dialog - GuiConnector.closeLoadingDialog(); - } -} - -/** - * Adds layout to be visualized. - * - * @param identifier - * identifier of the layout that should be included in visualization - */ -CustomMap.prototype.addSelectedLayout = function(identifier, name) { - logger.debug("Selecting layout: " + identifier); - - if (this.selectedLayouts[identifier] == true) { - logger.warn("Layout " + identifier + " already selected"); - } else { - this.selectedLayouts[identifier] = true; - - // open dialog with info that we are loading data (it takes some time for - // bigger layouts on big maps) - GuiConnector.openLoadingDialog(); - - // if we don't have information about this layout then download it - if (this.mapModel.getLayoutDataById(identifier) == null) { - // initialize what we can on client side - this.mapModel.initLayoutData(identifier, name); - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i].mapModel.initLayoutData(identifier, name); - } - - // load data from server about this layout - ServerConnector.retreiveActiveAliasesForLayout(identifier); - - // load data from server about this layout - ServerConnector.retreiveActiveReactionsForLayout(identifier); - } - if (!ServerConnector.isWaitingForData()) { - // if we already loaded the data then just visualize it - this.refreshSelectedLayouts(); - //and close "loading" dialog (if opened) - GuiConnector.closeLoadingDialog(); - } - // if we have to load data from server then open info window should be - // opened - ServerConnector - .setVisibleLayouts(JSON.stringify(this.getSelectedLayouts())); - - } -}; - -/** - * Returns list of layouts that are selected and visualized by javascript. - * - * @return array with a list of selected layotus - * - */ -CustomMap.prototype.getSelectedLayouts = function() { - var layouts = []; - - // get list of layouts - for ( var key in this.selectedLayouts) { - if (this.selectedLayouts.hasOwnProperty(key) - && this.selectedLayouts[key] == true) { - layouts.push(key); - } - } - return layouts; -} - -/** - * Removes layout from visualization. - * - * @param identifier - * identifier of layout to remove - * - */ -CustomMap.prototype.removeSelectedLayout = function(identifier) { - logger.debug("Removing layout: " + identifier); - - if (this.selectedLayouts[identifier] != true) { - logger.warn("Layout " + identifier + " is not selected"); - } else { - this.selectedLayouts[identifier] = false; - this.refreshSelectedLayouts(); - ServerConnector - .setVisibleLayouts(JSON.stringify(this.getSelectedLayouts())); - } -}; - -/** - * Refresh visualization of selected layouts. - */ -CustomMap.prototype.refreshSelectedLayouts = function() { - logger.debug("Refreshing layouts"); - var layouts = this.getSelectedLayouts(); - - // show layouts that should be visualized (resize or show them) - for (var i = 0; i < layouts.length; i++) { - var layoutId = layouts[i]; - if (this.layoutContainsOverlays(layoutId)) { - // resize element on the map - this.resizeSelectedLayout(layoutId, i, layouts.length); - } else { - this.showSelectedLayout(layoutId, i, layouts.length); - } - } - - // remove layouts that were - for ( var key in this.selectedLayoutOverlays) { - if (!this.selectedLayouts.hasOwnProperty(key) - || this.selectedLayouts[key] == false) { - if (this.layoutContainsOverlays(key)) { - this.hideSelectedLayout(key); - } - } - } - this.refreshInfoWindows(); -}; - -/** - * Hides layout from the map and all submaps - * - * @param layoutId - * identifier of a layout to hide - */ -CustomMap.prototype.hideSelectedLayout = function(layoutId) { - this._hideSelectedLayout(layoutId); - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i]._hideSelectedLayout(layoutId); - } -} - -/** - * Resize(refresh) layout on the map and all submaps. Resizing should be called - * when number of layouts to visualize change. - * - * @param layoutId - * identifier of layout to refresh - * @param index - * position of the layout in list of layouts that we visualize - * @param length - * number of layouts that we currently visualize - */ -CustomMap.prototype.resizeSelectedLayout = function(layoutId, index, length) { - logger.debug("Resize layout: " + layoutId); - this._resizeSelectedLayout(layoutId, index, length); - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i]._resizeSelectedLayout(layoutId, index, length); - } -} - -/** - * Show layout on the map and all submaps. - * - * @param layoutId - * identifier of layout to show - * @param index - * position of the layout in list of layouts that we visualize - * @param length - * number of layouts that we currently visualize - */ -CustomMap.prototype.showSelectedLayout = function(layoutId, index, length) { - logger.debug("Resize layout: " + layoutId); - this._showSelectedLayout(layoutId, index, length); - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i]._showSelectedLayout(layoutId, index, length); - } -} - -/** - * Adds information about reactions visible in the specific layout. - * - * @param layoutId - * identifier of the layout - * - * @param jsonAliases - * list of reactions in json format - * - */ -CustomMap.prototype.addReactionsForLayout = function(layoutId, jsonReactions) { - logger.debug("Adding reactions for layout: " + layoutId); - var reactions = JSON.parse(jsonReactions); - for (var i = 0; i < reactions.length; i++) { - var reaction = reactions[i]; - var model = this.getSubmodelById(reaction.modelId); - if (model != 'undefined' && model != null) { - model.mapModel.addReactionForLayout(layoutId, reaction); - } else { - logger.warn("Unknown model: " + reaction.modelId); - } - } - this.retrieveMissingReactions(); -} - -/** - * Adds information about reactions. - * - * @param jsonAliases - * list of reactions in json format - * - */ -CustomMap.prototype.addReactions = function(jsonReactions) { - var reactions = JSON.parse(jsonReactions); - for (var i = 0; i < reactions.length; i++) { - var reaction = reactions[i]; - var model = this.getSubmodelById(reaction.modelId); - if (model != 'undefined' && model != null) { - model.addReaction(reaction); - } else { - logger.warn("Unknown model: " + reaction.modelId); - } - } - this.callListeners("onAddReactions"); -} - -/** - * This function will ask server for reactions that should be visualized but the - * data is still missing on the client side. - */ -CustomMap.prototype.retrieveMissingReactions = function() { - var ids = []; - var missing = this.mapModel.getMissingReactionIds(); - for (var j = 0; j < missing.length; j++) { - ids.push([ this.getId(), missing[j] ]); - } - for (var i = 0; i < this.submaps.length; i++) { - missing = this.submaps[i].mapModel.getMissingReactionIds(); - for (var j = 0; j < missing.length; j++) { - ids.push([ this.submaps[i].getId(), missing[j] ]); - } - } - if (ids.length > 0) { - // load data from server about missing reactions - ServerConnector.retreiveLightReactions(ids); - } - if (!ServerConnector.isWaitingForData()) { - // if we already have everything then just refresh data to be visualized - this.refreshSelectedLayouts(); - //and close "loading" dialog (if opened) - GuiConnector.closeLoadingDialog(); - } -} - -/** - * This method checks if the layout contains any overlays (like AliasOverlay or - * ReactionOverlay) that is currently visible on the map. - * - * @param layoutId - * identifier of the layout - * @returns {Boolean}: <code>true</code> if the layout contains overlays to - * visualize, <code>false</code> otherwise - */ -CustomMap.prototype.layoutContainsOverlays = function(layoutId) { - - // first, check top map - if (this.selectedLayoutOverlays.hasOwnProperty(layoutId) - && this.selectedLayoutOverlays[layoutId].length > 0) { - return true; - } - - // now check all submaps - for (var i = 0; i < this.submaps.length; i++) { - if (this.submaps[i].initialized) { - if (this.submaps[i].selectedLayoutOverlays.hasOwnProperty(layoutId) - && this.submaps[i].selectedLayoutOverlays[layoutId].length > 0) { - return true; - } - } - } - return false; -} - -/** - * Refresh content of all {@link AliasInfoWindow} in this map and all submaps. - */ -CustomMap.prototype.refreshInfoWindows = function() { - this._refreshInfoWindows(); - // now check all submaps - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i]._refreshInfoWindows(); - } -} - -/** - * Opens {@link AliasInfoWindow} for an {@link Alias} in a given model/submodel. - * - * @param aliasId - * identifier of {@link Alias} - * @param modelId - * identifier of {@link AbstractCustomMap} - */ -CustomMap.prototype.openInfoWindowForAlias = function(aliasId, modelId) { - logger.debug("Opening info window for alias: " + aliasId + ", model: " - + modelId); - var model = this.getSubmodelById(modelId); - var alias = model.mapModel.getAliasById(aliasId); - - // if we have only simple version of the data then ask server for more details - if (alias == null || alias.completness == 'SIMPLE') { - logger.debug("Accessing full alias: " + aliasId); - var ids = [ [ modelId, aliasId ] ]; - ServerConnector.retreiveFullAliases(ids); - } - // open AliasInfoWindow in a right model - model._openInfoWindowForAlias(aliasId); -}; - -/** - * Renders markers, lines, etc. for elements highlighted in OverlayCollection. - * - * @param overlayCollection - * {@link OverlayCollection} to be processed - * @param fitBounds - * <code>true</code> if the borders should fit bounds after - * creating all elements - */ -CustomMap.prototype.renderOverlayCollection = function(overlayCollection, - fitBounds) { - var elements = overlayCollection.elements; - var missingElements = false; - - var boundsArray = []; - boundsArray[this.getId()] = new google.maps.LatLngBounds(); - for (var i = 0; i < this.submaps.length; i++) { - boundsArray[this.submaps[i].getId()] = new google.maps.LatLngBounds(); - } - - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - var model = this.getSubmodelById(element.modelId); - if (element.type == "ALIAS") { - if (overlayCollection.aliasMarkers[element.getId()] != null) { - logger.warn("More than one marker in " + overlayCollection.name - + " for alias " + element.getId() + ". Skipping duplicates."); - } else { - var aliasData = model.mapModel.getAliasById(element.getId()); - if (aliasData == null) { - model.mapModel.addMissingAliasId(element.getId()); - missingElements = true; - } - var marker = new AliasMarker(element.getId(), element.icon, aliasData, - model); - overlayCollection.aliasMarkers[element.getId()] = marker; - if (!missingElements) { - var bounds = marker.getBounds(); - boundsArray[element.modelId].extend(bounds.getNorthEast()); - boundsArray[element.modelId].extend(bounds.getSouthWest()); - } - } - } else if (element.type == "REACTION") { - var reactionData = model.mapModel.getReactionById(element.getId()); - if (reactionData == null) { - model.mapModel.addMissingReactionId(element.getId()); - missingElements = true; - } - var marker = null; - var icon = element.getIcon(); - - if (icon === null || icon === undefined) { - // this should happen when we visualize search data (there is - // no marker, but only flat overlay of the reaction lines) - // - marker = new ReactionOverlay(null, reactionData, model, false, element - .getId()); - } else { - // when we have icon defined (for instance when it comes from - // comment) then we don't want to have overlayed reaction lines - // but icon marker - marker = new ReactionMarker(element.getId(), icon, reactionData, model); - } - overlayCollection.reactionMarkers[element.getId()] = marker; - if (!missingElements) { - var bounds = marker.getBounds(); - boundsArray[element.modelId].extend(bounds.getNorthEast()); - boundsArray[element.modelId].extend(bounds.getSouthWest()); - - } - } else if (element.type == "POINT") { - var pointData = model.mapModel.getPointDataByPoint(element.getPoint()); - var marker = new PointMarker(pointData, element.icon, model); - overlayCollection.pointMarkers[pointData.getId()] = marker; - if (!missingElements) { - var bounds = marker.getBounds(); - boundsArray[element.modelId].extend(bounds.getNorthEast()); - boundsArray[element.modelId].extend(bounds.getSouthWest()); - } - } else { - logger.warn("Unknown type of the element in overlay: " + element.type); - } - var infoWindow = this.getInfoWindowForIdentifiedElement(element); - if (infoWindow != null) { - this.retrieveOverlayDetailDataForElement(element, infoWindow - .getOverlayFullViewArray()); - this.updateInfoWindowForIdentifiedElement(element); - } - } - - if (missingElements) { - this.retrieveMissingReactions(); - this.retrieveMissingAliases(); - } else { - if (elements.length > 0 && fitBounds) { - for ( var mapId in boundsArray) { - if (boundsArray.hasOwnProperty(mapId)) { - var map = this.getSubmodelById(mapId).map; - var bounds = boundsArray[mapId]; - if (map != null && !bounds.isEmpty()) { - if (typeof map.fitBounds2 !== "undefined") { - map.fitBounds2(bounds); - } else { - map.fitBounds(bounds); - } - } - } - } - } - } -}; - -/** - * Creates and register listeners to be called on events: - * <ul> - * <li>onAddAliases</li> - * <li>onAddReactions</li> - * </ul> - */ -CustomMap.prototype.createClientServerListeners = function() { - this.registerListenerType("onAddAliases"); - this.registerListenerType("onAddReactions"); - - var refreshLayoutsFun = function(e) { - var self = e.object; - if (!ServerConnector.isWaitingForData()) { - self.refreshSelectedLayouts(); - //and close "loading" dialog (if opened) - GuiConnector.closeLoadingDialog(); - } - }; - - var refreshOverlaysFun = function(e) { - e.object.refreshMarkers(); - }; - - this.addListener("onAddAliases", refreshLayoutsFun); - this.addListener("onAddAliases", refreshOverlaysFun); - - this.addListener("onAddReactions", refreshLayoutsFun); - this.addListener("onAddReactions", refreshOverlaysFun); - -}; - -/** - * Opens {@link AbstractInfoWindow} for a marker. - * - * @param marker - * {@link AbstractMarker} for which info window should be opened - */ -CustomMap.prototype.openInfoWindowForMarker = function(marker) { - var modelId = marker.getCustomMap().getId(); - var markerId = marker.getId(); - var model = this.getSubmodelById(modelId); - logger.debug("Opening info window for " + marker.constructor.name + ": " - + markerId + ", model: " + modelId); - var elementType = marker.getType(); - if (marker instanceof AliasMarker) { - var alias = model.mapModel.getAliasById(markerId); - - // if we have only simple version of the data then ask server for more - // details - if (alias == null || alias.completness == 'SIMPLE') { - logger.debug("Accessing full alias: " + markerId); - var ids = [ [ modelId, markerId ] ]; - ServerConnector.retreiveFullAliases(ids); - } - } else if (marker instanceof PointMarker) { - // no special treatment for points - } else if (marker instanceof ReactionMarker) { - // no special treatment for reactions - } else { - logger.error("Unknown marker type: " + marker.constructor.name); - } - - // open AliasInfoWindow in a right model - model._openInfoWindowForMarker(marker); - - var infoWindow = model.returnInfoWindowForMarker(marker); - - var element = new IdentifiedElement({ - objectId : markerId, - modelId : modelId, - type : elementType - }); - - this.retrieveOverlayDetailDataForElement(element, infoWindow - .getOverlayFullViewArray()); - -}; - -/** - * Sends requestes to download detailed data about element in all - * {@link OverlayCollection}. - * - * @param element - * element for which we want to have detailed information - */ -CustomMap.prototype.retrieveOverlayDetailDataForElement = function(element, - general) { - if (general === undefined) { - logger.warn("general param is undefined!"); - general = []; - } - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName)) { - var overlay = this.overlayCollections[overlayName]; - - var generalRequest = general[overlayName]; - if (generalRequest === undefined) { - logger.warn( - "No information about general overlay request for overlay: ", - overlayName); - generalRequest = false; - } - generalRequest = generalRequest || !overlay.allowSearchById(); - - if (overlay.allowGeneralSearch() || overlay.allowSearchById()) { - if (overlay.isMissingDetailData(element, generalRequest)) { - ServerConnector.sendOverlayDetailDataRequest(overlayName, element, - generalRequest); - } - } - } - } -}; - -/** - * Updates info window identified by element given as a parameter. - * - * @param identifiedElement - * element for which info window should be updated - */ -CustomMap.prototype.updateInfoWindowForIdentifiedElement = function( - identifiedElement) { - var infoWindow = this.getInfoWindowForIdentifiedElement(identifiedElement); - if (infoWindow == null) { - return; - } else { - infoWindow.update(); - } -}; - -/** - * Returns data from all {@link OverlayCollection} for a given alias. - * - * @param alias - * {@link Alias} for which overlay data will be returned - * @param general - * if true then all elements will be returned, if false then only - * ones availble right now in the overlay - * @returns data from all {@link OverlayCollection} for a given alias - */ -CustomMap.prototype.getOverlayDataForAlias = function(alias, general) { - var identifiedElement = new IdentifiedElement(alias); - return this.getOverlayDataForIdentifiedElement(identifiedElement, general); -}; - -/** - * Returns data from all {@link OverlayCollection} for a given reaction. - * - * @param reaction - * {@link Reaction} for which overlay data will be returned - * @param general - * if true then all elements will be returned, if false then only - * ones availble right now in the overlay - * @returns data from all {@link OverlayCollection} for a given alias - */ -CustomMap.prototype.getOverlayDataForReaction = function(reaction, general) { - var identifiedElement = new IdentifiedElement(reaction); - return this.getOverlayDataForIdentifiedElement(identifiedElement, general); -}; - -/** - * Returns data from all {@link OverlayCollection} for a given {@link PointData} - * - * @param point - * {@link PointData} for which overlay data will be returned - * @returns data from all {@link OverlayCollection} for a given - * {@link PointData} - */ -CustomMap.prototype.getOverlayDataForPoint = function(point, general) { - var identifiedElement = new IdentifiedElement(point); - return this.getOverlayDataForIdentifiedElement(identifiedElement, general); -}; - -/** - * Returns data from all {@link OverlayCollection} for element identified by the - * parameter - * - * @param identifiedElement - * {@link IdentifiedElement} for which overlay data will be returned - * @returns data from all {@link OverlayCollection} for a given - * {@link IdentifiedElement} - */ -CustomMap.prototype.getOverlayDataForIdentifiedElement = function( - identifiedElement, general) { - if (general === undefined) { - logger.warn("general parameter must be defined"); - general = []; - } - var result = []; - for ( var overlayName in this.overlayCollections) { - if (this.overlayCollections.hasOwnProperty(overlayName)) { - var overlay = this.overlayCollections[overlayName]; - if (overlay.allowGeneralSearch() || overlay.allowSearchById()) { - var generalFlag = general[overlay.getName()]; - if (generalFlag === undefined) { - logger.warn("General flag for overlay: " + overlay.getName() - + " is not defined, assuming false"); - generalFlag = false; - } - result.push({ - overlay : overlay, - data : overlay.getDetailDataByIdentifiedElement(identifiedElement, - !overlay.allowSearchById() || generalFlag) - }); - } - } - } - return result; -}; - -/** - * Returns {@link AbstractInfoWindow} for element identified by the parameter. - * - * @param identifiedElement - * {@link IdentifiedElement} that determines for which element we - * want {@link AbstractInfoWindow} - * @returns {@link AbstractInfoWindow} for element identified by the parameter - */ -CustomMap.prototype.getInfoWindowForIdentifiedElement = function( - identifiedElement) { - var model = this.getSubmodelById(identifiedElement.modelId); - var infoWindow = null; - if (identifiedElement.type == "ALIAS") { - infoWindow = model.getAliasInfoWindowById(identifiedElement.getId()); - } else if (identifiedElement.type == "POINT") { - infoWindow = model.getPointInfoWindowById(identifiedElement.getId()); - } else if (identifiedElement.type == "REACTION") { - infoWindow = model.getReactionInfoWindowById(identifiedElement.getId()); - } else { - logger.error("Unknown type of IdentifiedElement: ", identifiedElement); - } - return infoWindow; -}; - -CustomMap.prototype.getActiveSubmapId = function() { - return this._activeSubmapId; -}; - -CustomMap.prototype.setActiveSubmapId = function(submapId) { - this._activeSubmapId = submapId; -}; - -CustomMap.prototype.updateAliasesForLayout = function(layoutId, jsonAliases) { - logger.debug("Updating aliases for layout: " + layoutId); - - // init layout data - if (this.mapModel.getLayoutDataById(layoutId) == null) { - this.mapModel.initLayoutData(layoutId); - for (var i = 0; i < this.submaps.length; i++) { - this.submaps[i].mapModel.initLayoutData(layoutId); - } - } - - var aliases = JSON.parse(jsonAliases); - for (var i = 0; i < aliases.length; i++) { - var alias = aliases[i]; - var model = this.getSubmodelById(alias.modelId); - if (model != 'undefined' && model != null) { - model.mapModel.updateAliasForLayout(layoutId, alias); - model.getAliasInfoWindowById(alias.idObject).update(); - } else { - logger.warn("Unknown model: " + alias.modelId); - } - } - - this.retrieveMissingAliases(); -}; - -CustomMap.prototype.getReferenceGenome = function(type, version) { - var result = null; - if (this._referenceGenome[type] == null) { - this._referenceGenome[type] = []; - } - if (this._referenceGenome[type][version] == null) { - ServerConnector.sendReferenceGenomeDetailRequest(type, version); - this._referenceGenome[type][version] = new ReferenceGenome(null); - return null; - } else { - return this._referenceGenome[type][version]; - } -}; - -CustomMap.prototype.updateReferenceGenome = function(type, version, jsonObj) { - if (this._referenceGenome[type] == null) { - this._referenceGenome[type] = []; - } - this._referenceGenome[type][version] = new ReferenceGenome(jsonObj); - this.refreshInfoWindows(); -} +/** + * Default constructor. + * + * @param globalMap + * google.maps.Map object representing the map + * @param configuration + * Configuration object representing our data in the map + * @param bigButtons + * boolean value determining if the buttons on the map should be big, + * and if the map is run on the touch interface + * @param hideDiv + * + */ +function CustomMap(options) { + if (!(options instanceof CustomMapOptions)) { + options = new CustomMapOptions(options); + } + AbstractCustomMap.call(this, options); + + // set config parameters + this.map = options.getMap(); + + if (options.isCustomTouchInterface()) { + this._touchInterface = new TouchMap(this); + } + + // create function that override primefaces fitBounds with default google + // implementation + var fitBounds = function(bounds) { + var tmp = this.fitBounds; + this.fitBounds = google.maps.Map.prototype.fitBounds; + this.fitBounds(bounds); + this.fitBounds = tmp; + }; + this.map.fitBounds2 = fitBounds; + + this.buttons = []; + + this.createSubmaps(); + + this.selectedLayouts = []; + + this.setupLayouts(); + + this.createBelt(); + + this.customizeGoogleMapView(); + + this.createMapChangedCallbacks(); + + this.createClientServerListeners(); + + this.overlayCollections = []; + + // which submap is active (where user made interaction for the last time) + this._activeSubmapId = null; + + this.initialized = true; + + // list of reference genomes + this._referenceGenome = []; + + ServerConnector.actualizeSessionData(); +} + +CustomMap.prototype = Object.create(AbstractCustomMap.prototype); + +CustomMap.prototype.constructor = CustomMap; + +CustomMap.prototype.createSubmaps = function() { + this.submaps = []; + for (var i = 0; i < this.getConfiguration().SUBMODELS.length; i++) { + this.submaps.push(new Submap(this, + this.getConfiguration().SUBMODELS[i].ID_MODEL)); + } +}; + +CustomMap.prototype.createLogo = function() { + + var logoControlDiv = document.createElement('DIV'); + var logo = document.createElement('IMG'); + var url = ServerConnector.getLogoImg(); + if (!/^(f|ht)tps?:\/\//i.test(url)) { + url = GuiConnector.getImgPrefix() + url; + } + logo.src = url; + logo.style.cursor = 'pointer'; + logo.style.width = "80px"; + logoControlDiv.appendChild(logo); + google.maps.event.addDomListener(logo, 'click', function() { + var win = window.open(ServerConnector.getLogoLink(), '_blank'); + win.focus(); + }); + logoControlDiv.index = 0; // used for ordering + this.map.controls[google.maps.ControlPosition.LEFT_BOTTOM] + .push(logoControlDiv); + + var logoControlDiv = document.createElement('DIV'); + logoControlDiv.style.padding = '5px'; + + var logo = document.createElement('IMG'); + logo.src = GuiConnector.getImgPrefix() + + GuiConnector.getLcsbLogoImg(this.bigButtons); + logo.style.cursor = 'pointer'; + logoControlDiv.appendChild(logo); + google.maps.event.addDomListener(logo, 'click', function() { + var win = window.open('http://wwwen.uni.lu/lcsb/', '_blank'); + win.focus(); + }); + + logoControlDiv.index = 1; // used for ordering + this.map.controls[google.maps.ControlPosition.RIGHT_BOTTOM] + .push(logoControlDiv); +}; + +CustomMap.prototype.createBelt = function() { + var self = this; + + this.divBelt = document.createElement('DIV'); + this.divBelt.className = "headerBelt"; + + var hideDivButton = document.createElement('DIV'); + hideDivButton.className = "headerHideDivButton"; + + var hideButton = document.createElement('button'); + hideButton.id = "hide_button"; + hideButton.className = "headerHideButton"; + hideButton.innerHTML = "<i class='fa fa-chevron-left'></i>"; + // when there is no div to hide we should allow hiding + if (self.getHideDiv() !== undefined) { + hideButton.onclick = (function() { + var button = hideButton; + var div = self.getHideDiv(); + + var left = $(PrimeFaces.escapeClientId(self.map.getDiv().id)).offset().left; + return function() { + if (button.innerHTML.indexOf('fa-chevron-left') > 0) { + button.innerHTML = "<i class='fa fa-chevron-right'></i>"; + div.style.display = 'none'; + self.map.getDiv().style.left = "0px"; + } else { + div.style.display = 'block'; + button.innerHTML = "<i class='fa fa-chevron-left'></i>"; + self.map.getDiv().style.left = left + "px"; + } + google.maps.event.trigger(self.map, 'resize'); + return false; + }; + })(); + } else { + hideButton.disabled = true; + logger.warn("Left panel hiding disabled"); + } + hideDivButton.appendChild(hideButton); + hideDivButton.index = 1; // used for ordering + this.divBelt.appendChild(hideDivButton); + + var controlText = document.createElement('div'); + controlText.className = "headerTextBold"; + controlText.innerHTML = this.getConfiguration().MAP_NAME; + this.divBelt.appendChild(controlText); + + this.map.controls[google.maps.ControlPosition.TOP_LEFT].push(this.divBelt); +}; + +CustomMap.prototype.setLegendVisible = function(vis) { + if (vis) { + document.getElementById('legend').style.display = 'block'; + } else { + document.getElementById('legend').style.display = 'none'; + } +}; + +CustomMap.prototype.clearOverlays = function() { + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName)) { + var collection = this.overlayCollections[overlayName]; + this.clearOverlayCollection(collection); + } + } +}; + +CustomMap.prototype.refreshOverlays = function() { + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName)) { + var collection = this.overlayCollections[overlayName]; + collection.refresh(); + } + } +}; + +/** + * Removes all markers from {@link OverlayCollection}. + * + * @param collection + * {@link OverlayCollection} from which all markers should be removed + */ +CustomMap.prototype.clearOverlayCollection = function(collection) { + logger.debug("Clear collection: " + collection.name); + for ( var key in collection.aliasMarkers) { + if (collection.aliasMarkers.hasOwnProperty(key) + && collection.aliasMarkers[key] != null) { + collection.aliasMarkers[key].setMap(null); + } + } + + for ( var key in collection.pointMarkers) { + if (collection.pointMarkers.hasOwnProperty(key) + && collection.pointMarkers[key] != null) { + + collection.pointMarkers[key].setMap(null); + } + } + + for ( var key in collection.reactionMarkers) { + if (collection.reactionMarkers.hasOwnProperty(key) + && collection.reactionMarkers[key] != null) { + collection.reactionMarkers[key].setMap(null); + } + } + + collection.aliasMarkers = []; + collection.pointMarkers = []; + collection.reactionMarkers = []; +}; + +/** + * Updates data about visualized markers in {@link OverlayCollection}. + * + * @param overlayCollection + * {@link OverlayCollection} with new data to visualize + * @param fitBounds + * <code>true</code> id the map should fit bounds to the new + * elements after update, <code>false</code> otherwise + */ +CustomMap.prototype.updateOverlayCollection = function(overlayCollection, + fitBounds) { + this.clearOverlayCollection(overlayCollection); + this.renderOverlayCollection(overlayCollection, fitBounds); +}; + +/** + * This method open layout by a given layout identifier (string starting with + * 'cv' prefix) in a map and all submaps. + * + * @param identifier + * identifier of the layout to present + */ +CustomMap.prototype.openLayout = function(identifier) { + logger.debug("Opening layout: " + identifier); + + this.map.setMapTypeId(identifier); + + var index = null; + for (var i = 0; i < this.getConfiguration().MAPS.length; i++) { + if ('cv' + this.getConfiguration().MAPS[i].idObject == identifier) { + index = i; + } + } + if (index == null) { + logger.warn("Invalid layout identifier: " + identifier); + } + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i].openLayout('cv' + + this.submaps[i].getConfiguration().MAPS[index].idObject); + } +}; + +/** + * This method open layout by a given database identifier. + * + * @param identifier + * identifier of the layout to present + */ +CustomMap.prototype.openLayoutById = function(identifier) { + logger.debug("Opening layout: " + identifier); + var index = null; + for (var i = 0; i < configuration.MAPS.length; i++) { + if (configuration.MAPS[i].idObject == identifier) { + index = 'cv' + identifier; + } + } + + // if layout doesn't exist print error + if (index == null) { + alert("You have no privileges for selected layout"); + } else { + this.openLayout(index); + } +}; + +CustomMap.prototype.createMapMenu = function(layoutButtons) { + var selfMap = this; + + var buttons = []; + + // create a button for overview images when the image is available + if (this.getConfiguration().TOP_OVERVIEW_IMAGE != "undefined" + && this.getConfiguration().TOP_OVERVIEW_IMAGE != null) { + var submenuButtonDiv = document.createElement('button'); + buttons.push(submenuButtonDiv); + submenuButtonDiv.id = "overview_button"; + submenuButtonDiv.innerHTML = "<i class='fa fa-sitemap' style='font-size:18px; font-weight:400; padding-right:10px;'></i> SHOW OVERVIEW"; + submenuButtonDiv.className = "overview_button"; + submenuButtonDiv.onclick = (function() { + return function() { + selfMap.showOverview(); + return false; + }; + })(); + this.divBelt.appendChild(submenuButtonDiv); + } + + var rightHeaderMenu = document.createElement('div'); + rightHeaderMenu.className = "rightHeaderMenu"; + var submenuDiv = document.createElement('div'); + submenuDiv.className = "div4checkboxes"; + var submenuButtonDiv = document.createElement('input'); + submenuButtonDiv.type = "checkbox"; + submenuButtonDiv.name = "Comments"; + submenuButtonDiv.id = "comment_checkbox"; + submenuButtonDiv.onclick = (function() { + var selfButton = submenuButtonDiv; + return function() { + selfMap.showComments = selfButton.checked; + ServerConnector.setShowComments(selfButton.checked); + if (selfButton.checked) { + document.getElementById('refresh_comments_button').style.display = 'inline'; + } else { + document.getElementById('refresh_comments_button').style.display = 'none'; + } + selfMap.refreshComments(); + + }; + })(); + var element = document.createElement('label'); + element.innerHTML = "COMMENTS"; + element.setAttribute("for", "comment_checkbox"); + submenuDiv.appendChild(submenuButtonDiv); + submenuDiv.appendChild(element); + + var submenuButtonDiv = document.createElement('input'); + submenuButtonDiv.type = "checkbox"; + submenuButtonDiv.name = "Legend"; + submenuButtonDiv.id = "lengend_checkbox"; + submenuButtonDiv.onclick = (function() { + var selfButton = submenuButtonDiv; + return function() { + if (selfButton.checked) { + GuiConnector.showLegend(); + } else { + GuiConnector.hideLegend(); + } + }; + })(); + element = document.createElement('label'); + element.innerHTML = "LEGEND"; + element.setAttribute("for", "lengend_checkbox"); + submenuDiv.appendChild(submenuButtonDiv); + submenuDiv.appendChild(element); + + submenuButtonDiv = document.createElement('button'); + submenuButtonDiv.id = "refresh_comments_button"; + submenuButtonDiv.innerHTML = "<i class='fa fa-refresh' style='font-size:21px; font-weight:400;'></i>"; + submenuButtonDiv.className = "overview_button"; + submenuButtonDiv.style.display = 'none'; + submenuButtonDiv.onclick = (function() { + return function() { + selfMap.refreshComments(); + return false; + }; + })(); + submenuDiv.appendChild(submenuButtonDiv); + rightHeaderMenu.appendChild(submenuDiv); + + var submenuButtonDiv = document.createElement('button'); + buttons.push(submenuButtonDiv); + submenuButtonDiv.id = "clear_button"; + submenuButtonDiv.className = "overview_button"; + submenuButtonDiv.innerHTML = "<i class='fa fa-times' style='font-size:18px; font-weight:300; padding-right:10px;'></i> CLEAR"; + submenuButtonDiv.title = "Clear all queries"; + submenuButtonDiv.style.display = 'inline'; + submenuButtonDiv.onclick = (function() { + return function() { + selfMap.clearData(); + return false; + }; + })(); + rightHeaderMenu.appendChild(submenuButtonDiv); + + this.divBelt.appendChild(rightHeaderMenu); +}; + +CustomMap.prototype.registerSource = function(overlayCollection) { + this.overlayCollections[overlayCollection.name] = overlayCollection; + overlayCollection.aliasMarkers = []; + overlayCollection.pointMarkers = []; + overlayCollection.reactionMarkers = []; +}; + +CustomMap.prototype.refreshComments = function() { + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName) + && overlayName == "comment") { + var collection = this.overlayCollections[overlayName]; + collection.refresh(); + return; + } + } + throw "comment OverlayCollection not found"; +}; + +CustomMap.prototype.turnOnOffDrawing = function() { + var model = this.getSubmodelById(this.getActiveSubmapId()); + if (model != null) { + model._turnOnOffDrawing(); + } else { + throw "Cannot find submodel with id: " + this.getActiveSubmapId(); + } +}; + +CustomMap.prototype.clearData = function() { + this.clearOverlays(); + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName)) { + ServerConnector.sendClearRequest(overlayName); + } + } +}; + +CustomMap.prototype.refreshMarkers = function() { + logger.debug("Refresh Markers: "); + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName)) { + var collection = this.overlayCollections[overlayName]; + this.refreshOverlayMarkers(collection); + } + } +}; + +CustomMap.prototype.refreshOverlayMarkers = function(overlay) { + var self = this; + logger.debug("Refresh overlay: " + overlay.name); + var boundsArray = []; + boundsArray[this.getId()] = new google.maps.LatLngBounds(); + for (var i = 0; i < this.submaps.length; i++) { + boundsArray[this.submaps[i].getId()] = new google.maps.LatLngBounds(); + } + + var updated = false; + var stillMissing = false; + for ( var key in overlay.aliasMarkers) { + if (overlay.aliasMarkers.hasOwnProperty(key) + && overlay.aliasMarkers[key] != null) { + var alias = overlay.aliasMarkers[key]; + if (alias.getAliasData() == null) { + var aliasData = alias.getCustomMap().mapModel.getAliasById(alias + .getId()); + if (aliasData != null) { + alias.setAliasData(aliasData); + alias.init(); + alias.show(); + updated = true; + var bounds = alias.getBounds(); + boundsArray[alias.getCustomMap().getId()].extend(bounds + .getNorthEast()); + } else { + stillMissing = true; + logger.debug("Cannot show alias marker. Data is still not loaded..."); + } + } else { + var bounds = alias.getBounds(); + if (!this.isMarkerOptimization()) { + alias.hide(); + alias.show(); + } + boundsArray[alias.getCustomMap().getId()].extend(bounds.getNorthEast()); + boundsArray[alias.getCustomMap().getId()].extend(bounds.getSouthWest()); + } + } + } + + for ( var key in overlay.pointMarkers) { + if (overlay.pointMarkers.hasOwnProperty(key) + && overlay.pointMarkers[key] != null) { + var alias = overlay.pointMarkers[key]; + // we don't need to update this markers because thet data about + // visualization is + // already there + // alias.update(); + var bounds = alias.getBounds(); + if (!this.isMarkerOptimization()) { + alias.hide(); + alias.show(); + } + boundsArray[alias.getCustomMap().getId()].extend(bounds.getNorthEast()); + } + } + + for ( var key in overlay.reactionMarkers) { + if (overlay.reactionMarkers.hasOwnProperty(key) + && overlay.reactionMarkers[key] != null) { + var reactionOverlay = overlay.reactionMarkers[key]; + if (reactionOverlay.getReactionData() == null) { + var reactionData = reactionOverlay.getCustomMap().mapModel + .getReactionById(reactionOverlay.getId()); + if (reactionData != null) { + reactionOverlay.setReactionData(reactionData); + reactionOverlay.init(); + reactionOverlay.show(); + updated = true; + var bounds = reactionOverlay.getBounds(); + boundsArray[reactionOverlay.getCustomMap().getId()].extend(bounds + .getNorthEast()); + boundsArray[reactionOverlay.getCustomMap().getId()].extend(bounds + .getSouthWest()); + } else { + stillMissing = true; + logger + .debug("Cannot show reaction marker. Data is still not loaded..."); + } + } else { + var bounds = alias.getBounds(); + if (!this.isMarkerOptimization()) { + alias.hide(); + alias.show(); + } + boundsArray[alias.getCustomMap().getId()].extend(bounds.getNorthEast()); + boundsArray[alias.getCustomMap().getId()].extend(bounds.getSouthWest()); + } + + } + } + + if (!stillMissing && updated && overlay.fitBounds) { + for ( var mapId in boundsArray) { + if (boundsArray.hasOwnProperty(mapId)) { + var map = this.getSubmodelById(mapId).map; + var bounds = boundsArray[mapId]; + if (map != null && !bounds.isEmpty()) { + if (typeof map.fitBounds2 !== "undefined") { + map.fitBounds2(bounds); + } else { + map.fitBounds(bounds); + } + } + } + } + } +}; + +CustomMap.prototype.openSubmodel = function(id, htmlTag, jsVar) { + if (jsVar.submapControler == null) { + var submap = null; + for (var i = 0; i < this.submaps.length; i++) { + if (this.submaps[i].getId() == id) { + submap = this.submaps[i]; + } + } + if (submap == null) { + logger.error("Unknown submap for id: " + id); + } else { + submap.init(htmlTag, jsVar); + //we have to perform it on top map, because on submaps id is different + this.openLayout(this.map.getMapTypeId()); + + this.refreshOverlays(); + + // now we have to visualize layouts + var layouts = []; + + // get list of layouts + for ( var key in this.selectedLayouts) { + if (this.selectedLayouts.hasOwnProperty(key) + && this.selectedLayouts[key] == true) { + layouts.push(key); + } + } + + // show layouts that should be visualized (resize or show them) + for (var i = 0; i < layouts.length; i++) { + var layoutId = layouts[i]; + submap._showSelectedLayout(layoutId, i, layouts.length); + } + } + } + jsVar.show(); + +}; + +CustomMap.prototype.customizeGoogleMapView = function() { + var mapOptions = this.creatMapOptions(); + this.map.setOptions(mapOptions); + + this.createMapMenu(false); + + this.registerMapClickEvents(); + + this.createLogo(); + // this.createMapVersion(); + google.maps.event.trigger(this.map, 'resize'); + google.maps.event.trigger(this.map, 'maptypeid_changed'); + google.maps.event.trigger(this.map, 'projection_changed'); + + // center map and zoom in to fit into browser window + if (this.getConfiguration().fitMapBounds) { + var bounds = new google.maps.LatLngBounds(); + var point = new google.maps.LatLng( + this.getConfiguration().topLeftLatLng.lat, + this.getConfiguration().topLeftLatLng.lng); + bounds.extend(point); + + point = new google.maps.LatLng( + this.getConfiguration().bottomRightLatLng.lat, + this.getConfiguration().bottomRightLatLng.lng); + bounds.extend(point); + + if (typeof this.map.fitBounds2 !== "undefined") { + this.map.fitBounds2(bounds); + } else { + this.map.fitBounds(bounds); + } + } +}; + +CustomMap.prototype.setCenter = function(mapIdentifier, coordinates) { + if (this.getConfiguration().ID_MODEL == mapIdentifier) { + this.map.setCenter(coordinates); + } else { + GuiConnector.openDialog(mapIdentifier); + for (var i = 0; i < this.submaps.length; i++) { + if (this.submaps[i].getId() == mapIdentifier) { + if (coordinates instanceof google.maps.Point) { + coordinates = this.submaps[i].fromPointToLatLng(coordinates); + } + this.submaps[i].map.setCenter(coordinates); + } + } + } +}; + +CustomMap.prototype.setZoom = function(mapIdentifier, zoom) { + if (this.getConfiguration().ID_MODEL == mapIdentifier) { + this.map.setZoom(zoom); + } else { + GuiConnector.openDialog(mapIdentifier); + for (var i = 0; i < this.submaps.length; i++) { + if (this.submaps[i].getId() == mapIdentifier) { + this.submaps[i].map.setZoom(zoom); + } + } + } +}; + +/** + * Creates listeners for google.maps.Map object that will actualize the data in + * user session. + */ +CustomMap.prototype.createMapChangedCallbacks = function() { + var customMapSelf = this; + // listener for changing zoom level + google.maps.event.addListener(this.map, 'zoom_changed', function() { + ServerConnector.setZoomLevel(customMapSelf.map.getZoom()); + ServerConnector.actualizeSessionData(); + }); + + // if we have zoom level data stored in session then restore it + var level = ServerConnector.getZoomLevel(); + if (parseInt(level) > 0) { + level = parseInt(level); + this.map.setZoom(level); + } else { + ServerConnector.setZoomLevel(customMapSelf.map.getZoom()); + } + + // listener for changing location of the map (moving left/reght/top/bottom + google.maps.event.addListener(this.map, 'center_changed', function() { + var coord = customMapSelf.map.getCenter(); + var point = customMapSelf.fromLatLngToPoint(coord); + ServerConnector.setCenterCoordinateX(point.x); + ServerConnector.setCenterCoordinateY(point.y); + ServerConnector.actualizeSessionData(); + }); + + // if we have coordinate data stored in session then restore it + var x = ServerConnector.getCenterCoordinateX(); + var y = ServerConnector.getCenterCoordinateY(); + if (!isNaN(x) && !isNaN(y)) { + var point = new google.maps.Point(x, y); + var coord = customMapSelf.fromPointToLatLng(point); + customMapSelf.map.setCenter(coord); + } + + // listener for changing type of layout + google.maps.event.addListener(this.map, 'maptypeid_changed', function() { + ServerConnector.setSelectedLayout(customMapSelf.map.getMapTypeId()); + ServerConnector.actualizeParams(); + }); + + // if we have type of layout stored in the session then restore it + var mapType = ServerConnector.getSelectedLayout(); + if (mapType != "" && mapType != null) { + this.openLayout(mapType); + } +}; + +/** + * Returns submodel (or this model) by identfier of the model. + * + * @param identifier + * identifier of the submodel + * @returns submodel (or this model) with given identfier of the model + */ +CustomMap.prototype.getSubmodelById = function(identifier) { + if (this.getId() == identifier) { + return this; + } + for (var i = 0; i < this.submaps.length; i++) { + if (this.submaps[i].getId() == identifier) { + return this.submaps[i]; + } + } + return null; +}; + +CustomMap.prototype.removeSelection = function() { + var model = this.getSubmodelById(this.getActiveSubmapId()); + if (model != null) { + model._removeSelection(); + } else { + throw "Cannot find submodel with id: " + this.getActiveSubmapId(); + } +}; + +/** + * This method will hide google map view and will present single image overview + * of the data. + */ +CustomMap.prototype.showOverview = function(overviewImageId) { + overviewDialog.syncWindowResize(); + if (this.getOverviewDiv() == "undefined" || this.getOverviewDiv() == null) { + logger.warn("Cannot show overview, because overview div is undefined"); + } else { + logger.debug("Show overview"); + overviewDialog.show(); + + // resize dialog + var htmlTag = GuiConnector.getOverviewHtmlTag(); + + var width = Math.floor(window.innerWidth * 2 / 3); + var height = Math.floor(window.innerHeight * 2 / 3); + + htmlTag.style.height = (height + 50) + "px"; + htmlTag.style.width = (width + 20) + "px"; + + var self = this; + + // remove all child nodes from overview div + while (this.getOverviewDiv().hasChildNodes()) { + this.getOverviewDiv().removeChild(this.getOverviewDiv().lastChild); + } + + if (overviewImageId == "undefined" || overviewImageId == null) { + this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE; + } else { + this.overviewImage = null; + for (var i = 0; i < this.getConfiguration().OVERVIEW_IMAGES.length; i++) { + if (this.getConfiguration().OVERVIEW_IMAGES[i].idObject == overviewImageId) { + this.overviewImage = this.getConfiguration().OVERVIEW_IMAGES[i]; + } + } + + if (this.overviewImage == null) { + logger.warn("Unknown overview image with id = " + overviewImageId); + this.overviewImage = this.getConfiguration().TOP_OVERVIEW_IMAGE; + } + } + + // add image to overview div + this.overviewImageTag = document.createElement("IMG"); + this.overviewImageTag.src = "../map_images/" + this.overviewImage.filename; + this.getOverviewDiv().appendChild(this.overviewImageTag); + + var ratio = 1.0; + + // check how image should be resized to fit dialog and resize it manually!!! + if (width / this.overviewImage.width > height / this.overviewImage.height) { + this.overviewImageTag.style.height = height + "px"; + ratio = height / this.overviewImage.height; + width = this.overviewImage.width * ratio; + + htmlTag.style.width = (width + 20) + "px"; + } else { + this.overviewImageTag.style.width = width + "px"; + ratio = width / this.overviewImage.width; + height = this.overviewImage.height * ratio; + + htmlTag.style.height = (height + 50) + "px"; + } + + // center dialog + overviewDialog.jq.css("top", Math.max(0, + (($(window).height() - overviewDialog.jq.outerHeight()) / 2) + + $(window).scrollTop()) + + "px"); + overviewDialog.jq.css("left", Math.max(0, + (($(window).width() - overviewDialog.jq.outerWidth()) / 2) + + $(window).scrollLeft()) + + "px"); + + // on click event (what should happen when we click on the image) + var onclickevent = function getClickPosition(e) { + var parentPosition = getPosition(e.currentTarget); + var xPosition = e.clientX - parentPosition.x; + var yPosition = e.clientY - parentPosition.y; + + var imgWidth = self.overviewImageTag.offsetWidth; + + var currentRatio = imgWidth / self.overviewImage.width; + + var xNormal = xPosition / currentRatio; + var yNormal = yPosition / currentRatio; + var point = { + x : xNormal, + y : yNormal + }; + + var link = null; + for (var i = 0; i < self.overviewImage.links.length; i++) { + if (pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { + if (link == null) { + link = self.overviewImage.links[i]; + } else { + logger.warn("More than one link found. Skipping"); + } + } + } + if (link != null) { + if (link.type == "OverviewModelLink") { + logger.debug("Opening model from overview. ModelId: " + + link.modelLinkId); + logger.debug("link coordinates [" + link.idObject + "]: " + + link.latLng); + // TODO min zoom value can be different for every map, it should be + // changed in the future + self.showModel(link.modelLinkId, link.latLng, link.zoomLevel + + self.getConfiguration().MIN_ZOOM); + overviewDialog.hide(); + } else if (link.type == "OverviewImageLink") { + logger.debug("Opening image from overview. ImageId: " + + link.imageLinkId); + self.showOverview(link.imageLinkId); + } else if (link.type == "OverviewSearchLink") { + logger.debug("Sending search query. Query: " + link.query); + searchPanel.search(link.query); + overviewDialog.hide(); + } else { + logger.warn("Unknown type of link: " + link.type + + ". Don't know what to do... LinkId: " + link.idObject); + } + } + }; + + this.overviewImageTag.onclick = onclickevent; + + // resize canvas where on mouse over highligh will appear + var canvas = document.getElementById("canvasDebug"); + canvas.width = width; + canvas.height = height; + canvas.onclick = onclickevent; + + // in debug mode draw clickable shapes + if (DEBUG_ON) { + var ctx = canvas.getContext("2d"); + // clear canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + for (var i = 0; i < this.overviewImage.links.length; i++) { + ctx.beginPath(); + var polygon = this.overviewImage.links[i].polygon; + for (var j = 0; j < polygon.length; j++) { + var x = polygon[j].x * ratio; + var y = polygon[j].y * ratio; + ctx.moveTo(x, y); + x = polygon[(j + 1) % polygon.length].x * ratio; + y = polygon[(j + 1) % polygon.length].y * ratio; + ctx.lineTo(x, y); + } + ctx.stroke(); + } + } + + this.overviewImage.mousePos = { + x : 0, + y : 0 + }; + + // this listener should be called when mouse moves over image, it purpose is + // to change coursor to pointer when mouse enters clickable polygon and back + // to normal when mouse leaves such region + var onmousemove = function getMouseOverPosition(e) { + var position = getPosition(e.currentTarget); + position.x = e.clientX - position.x; + position.y = e.clientY - position.y; + + var imgWidth = self.overviewImageTag.offsetWidth; + + var currentRatio = imgWidth / self.overviewImage.width; + + var xNormal = position.x / currentRatio; + var yNormal = position.y / currentRatio; + var point = { + x : xNormal, + y : yNormal + }; + + if (self.overviewImage.mousePos.x != position.x + || self.overviewImage.mousePos.y != position.y) { + self.overviewImage.mousePos = position; + var link = null; + for (var i = 0; i < self.overviewImage.links.length; i++) { + if (pointInsidePolygon(point, self.overviewImage.links[i].polygon)) { + link = self.overviewImage.links[i]; + } + } + if (link == null) { + e.currentTarget.style.cursor = "auto"; + } else { + e.currentTarget.style.cursor = "pointer"; + } + } + }; + + // onmousemove listener should be assigned to canvas (which is on top of the + // image) and overviewimage (just in case something went wrong with resizing + // canvas) + canvas.onmousemove = onmousemove; + this.overviewImageTag.onmousemove = onmousemove; + } +}; + +CustomMap.prototype.showModel = function(id, point, zoomLevel) { + if (point != "undefined") { + this.setCenter(id, point); + } else { + logger.warn("Center point undefined..."); + } + if (zoomLevel != "undefined") { + this.setZoom(id, zoomLevel); + } else { + logger.warn("Zoom level undefined..."); + } +}; + +/** + * Adds information about aliases visible in the specific layout. + * + * @param layoutId + * identifier of the layout + * + * @param jsonAliases + * list of aliases in json format + * + */ +CustomMap.prototype.addAliasesForLayout = function(layoutId, jsonAliases) { + logger.debug("Adding aliases for layout: " + layoutId); + + // init layout data + if (this.mapModel.getLayoutDataById(layoutId) == null) { + this.mapModel.initLayoutData(layoutId); + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i].mapModel.initLayoutData(layoutId); + } + } + + var aliases = JSON.parse(jsonAliases); + for (var i = 0; i < aliases.length; i++) { + var alias = aliases[i]; + var model = this.getSubmodelById(alias.modelId); + if (model != 'undefined' && model != null) { + model.mapModel.addAliasForLayout(layoutId, alias); + } else { + logger.warn("Unknown model: " + alias.modelId); + } + } + + this.retrieveMissingAliases(); +} + +/** + * Adds information about aliases. + * + * @param jsonAliases + * list of aliases in json format + * + */ +CustomMap.prototype.addAliases = function(aliases) { + for (var i = 0; i < aliases.length; i++) { + var alias = aliases[i]; + var model = this.getSubmodelById(alias.modelId); + if (model != 'undefined' && model != null) { + model.addAlias(alias); + } else { + logger.warn("Unknown model: " + alias.modelId); + } + } + this.callListeners("onAddAliases"); +} + +/** + * This function will ask server for aliases that should be visualized but the + * data is still missing on the client side. + */ +CustomMap.prototype.retrieveMissingAliases = function() { + var ids = []; + var missing = this.mapModel.getMissingAliasIds(); + for (var j = 0; j < missing.length; j++) { + ids.push([ this.getId(), missing[j] ]); + } + for (var i = 0; i < this.submaps.length; i++) { + missing = this.submaps[i].mapModel.getMissingAliasIds(); + for (var j = 0; j < missing.length; j++) { + ids.push([ this.submaps[i].getId(), missing[j] ]); + } + } + if (ids.length > 0) { + // load data from server about missing aliases + ServerConnector.retreiveLightAliases(ids); + } + if (!ServerConnector.isWaitingForData()) { + // if we already have everything then just refresh data to be visualized + this.refreshSelectedLayouts(); + //and close "loading" dialog + GuiConnector.closeLoadingDialog(); + } +} + +/** + * Adds layout to be visualized. + * + * @param identifier + * identifier of the layout that should be included in visualization + */ +CustomMap.prototype.addSelectedLayout = function(identifier, name) { + logger.debug("Selecting layout: " + identifier); + + if (this.selectedLayouts[identifier] == true) { + logger.warn("Layout " + identifier + " already selected"); + } else { + this.selectedLayouts[identifier] = true; + + // open dialog with info that we are loading data (it takes some time for + // bigger layouts on big maps) + GuiConnector.openLoadingDialog(); + + // if we don't have information about this layout then download it + if (this.mapModel.getLayoutDataById(identifier) == null) { + // initialize what we can on client side + this.mapModel.initLayoutData(identifier, name); + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i].mapModel.initLayoutData(identifier, name); + } + + // load data from server about this layout + ServerConnector.retreiveActiveAliasesForLayout(identifier); + + // load data from server about this layout + ServerConnector.retreiveActiveReactionsForLayout(identifier); + } + if (!ServerConnector.isWaitingForData()) { + // if we already loaded the data then just visualize it + this.refreshSelectedLayouts(); + //and close "loading" dialog (if opened) + GuiConnector.closeLoadingDialog(); + } + // if we have to load data from server then open info window should be + // opened + ServerConnector + .setVisibleLayouts(JSON.stringify(this.getSelectedLayouts())); + + } +}; + +/** + * Returns list of layouts that are selected and visualized by javascript. + * + * @return array with a list of selected layotus + * + */ +CustomMap.prototype.getSelectedLayouts = function() { + var layouts = []; + + // get list of layouts + for ( var key in this.selectedLayouts) { + if (this.selectedLayouts.hasOwnProperty(key) + && this.selectedLayouts[key] == true) { + layouts.push(key); + } + } + return layouts; +} + +/** + * Removes layout from visualization. + * + * @param identifier + * identifier of layout to remove + * + */ +CustomMap.prototype.removeSelectedLayout = function(identifier) { + logger.debug("Removing layout: " + identifier); + + if (this.selectedLayouts[identifier] != true) { + logger.warn("Layout " + identifier + " is not selected"); + } else { + this.selectedLayouts[identifier] = false; + this.refreshSelectedLayouts(); + ServerConnector + .setVisibleLayouts(JSON.stringify(this.getSelectedLayouts())); + } +}; + +/** + * Refresh visualization of selected layouts. + */ +CustomMap.prototype.refreshSelectedLayouts = function() { + logger.debug("Refreshing layouts"); + var layouts = this.getSelectedLayouts(); + + // show layouts that should be visualized (resize or show them) + for (var i = 0; i < layouts.length; i++) { + var layoutId = layouts[i]; + if (this.layoutContainsOverlays(layoutId)) { + // resize element on the map + this.resizeSelectedLayout(layoutId, i, layouts.length); + } else { + this.showSelectedLayout(layoutId, i, layouts.length); + } + } + + // remove layouts that were + for ( var key in this.selectedLayoutOverlays) { + if (!this.selectedLayouts.hasOwnProperty(key) + || this.selectedLayouts[key] == false) { + if (this.layoutContainsOverlays(key)) { + this.hideSelectedLayout(key); + } + } + } + this.refreshInfoWindows(); +}; + +/** + * Hides layout from the map and all submaps + * + * @param layoutId + * identifier of a layout to hide + */ +CustomMap.prototype.hideSelectedLayout = function(layoutId) { + this._hideSelectedLayout(layoutId); + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i]._hideSelectedLayout(layoutId); + } +} + +/** + * Resize(refresh) layout on the map and all submaps. Resizing should be called + * when number of layouts to visualize change. + * + * @param layoutId + * identifier of layout to refresh + * @param index + * position of the layout in list of layouts that we visualize + * @param length + * number of layouts that we currently visualize + */ +CustomMap.prototype.resizeSelectedLayout = function(layoutId, index, length) { + logger.debug("Resize layout: " + layoutId); + this._resizeSelectedLayout(layoutId, index, length); + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i]._resizeSelectedLayout(layoutId, index, length); + } +} + +/** + * Show layout on the map and all submaps. + * + * @param layoutId + * identifier of layout to show + * @param index + * position of the layout in list of layouts that we visualize + * @param length + * number of layouts that we currently visualize + */ +CustomMap.prototype.showSelectedLayout = function(layoutId, index, length) { + logger.debug("Resize layout: " + layoutId); + this._showSelectedLayout(layoutId, index, length); + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i]._showSelectedLayout(layoutId, index, length); + } +} + +/** + * Adds information about reactions visible in the specific layout. + * + * @param layoutId + * identifier of the layout + * + * @param jsonAliases + * list of reactions in json format + * + */ +CustomMap.prototype.addReactionsForLayout = function(layoutId, jsonReactions) { + logger.debug("Adding reactions for layout: " + layoutId); + var reactions = JSON.parse(jsonReactions); + for (var i = 0; i < reactions.length; i++) { + var reaction = reactions[i]; + var model = this.getSubmodelById(reaction.modelId); + if (model != 'undefined' && model != null) { + model.mapModel.addReactionForLayout(layoutId, reaction); + } else { + logger.warn("Unknown model: " + reaction.modelId); + } + } + this.retrieveMissingReactions(); +} + +/** + * Adds information about reactions. + * + * @param jsonAliases + * list of reactions in json format + * + */ +CustomMap.prototype.addReactions = function(jsonReactions) { + var reactions = JSON.parse(jsonReactions); + for (var i = 0; i < reactions.length; i++) { + var reaction = reactions[i]; + var model = this.getSubmodelById(reaction.modelId); + if (model != 'undefined' && model != null) { + model.addReaction(reaction); + } else { + logger.warn("Unknown model: " + reaction.modelId); + } + } + this.callListeners("onAddReactions"); +} + +/** + * This function will ask server for reactions that should be visualized but the + * data is still missing on the client side. + */ +CustomMap.prototype.retrieveMissingReactions = function() { + var ids = []; + var missing = this.mapModel.getMissingReactionIds(); + for (var j = 0; j < missing.length; j++) { + ids.push([ this.getId(), missing[j] ]); + } + for (var i = 0; i < this.submaps.length; i++) { + missing = this.submaps[i].mapModel.getMissingReactionIds(); + for (var j = 0; j < missing.length; j++) { + ids.push([ this.submaps[i].getId(), missing[j] ]); + } + } + if (ids.length > 0) { + // load data from server about missing reactions + ServerConnector.retreiveLightReactions(ids); + } + if (!ServerConnector.isWaitingForData()) { + // if we already have everything then just refresh data to be visualized + this.refreshSelectedLayouts(); + //and close "loading" dialog (if opened) + GuiConnector.closeLoadingDialog(); + } +} + +/** + * This method checks if the layout contains any overlays (like AliasOverlay or + * ReactionOverlay) that is currently visible on the map. + * + * @param layoutId + * identifier of the layout + * @returns {Boolean}: <code>true</code> if the layout contains overlays to + * visualize, <code>false</code> otherwise + */ +CustomMap.prototype.layoutContainsOverlays = function(layoutId) { + + // first, check top map + if (this.selectedLayoutOverlays.hasOwnProperty(layoutId) + && this.selectedLayoutOverlays[layoutId].length > 0) { + return true; + } + + // now check all submaps + for (var i = 0; i < this.submaps.length; i++) { + if (this.submaps[i].initialized) { + if (this.submaps[i].selectedLayoutOverlays.hasOwnProperty(layoutId) + && this.submaps[i].selectedLayoutOverlays[layoutId].length > 0) { + return true; + } + } + } + return false; +} + +/** + * Refresh content of all {@link AliasInfoWindow} in this map and all submaps. + */ +CustomMap.prototype.refreshInfoWindows = function() { + this._refreshInfoWindows(); + // now check all submaps + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i]._refreshInfoWindows(); + } +} + +/** + * Opens {@link AliasInfoWindow} for an {@link Alias} in a given model/submodel. + * + * @param aliasId + * identifier of {@link Alias} + * @param modelId + * identifier of {@link AbstractCustomMap} + */ +CustomMap.prototype.openInfoWindowForAlias = function(aliasId, modelId) { + logger.debug("Opening info window for alias: " + aliasId + ", model: " + + modelId); + var model = this.getSubmodelById(modelId); + var alias = model.mapModel.getAliasById(aliasId); + + // if we have only simple version of the data then ask server for more details + if (alias == null || alias.completness == 'SIMPLE') { + logger.debug("Accessing full alias: " + aliasId); + var ids = [ [ modelId, aliasId ] ]; + ServerConnector.retreiveFullAliases(ids); + } + // open AliasInfoWindow in a right model + model._openInfoWindowForAlias(aliasId); +}; + +/** + * Renders markers, lines, etc. for elements highlighted in OverlayCollection. + * + * @param overlayCollection + * {@link OverlayCollection} to be processed + * @param fitBounds + * <code>true</code> if the borders should fit bounds after + * creating all elements + */ +CustomMap.prototype.renderOverlayCollection = function(overlayCollection, + fitBounds) { + var elements = overlayCollection.elements; + var missingElements = false; + + var boundsArray = []; + boundsArray[this.getId()] = new google.maps.LatLngBounds(); + for (var i = 0; i < this.submaps.length; i++) { + boundsArray[this.submaps[i].getId()] = new google.maps.LatLngBounds(); + } + + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + var model = this.getSubmodelById(element.modelId); + if (element.type == "ALIAS") { + if (overlayCollection.aliasMarkers[element.getId()] != null) { + logger.warn("More than one marker in " + overlayCollection.name + + " for alias " + element.getId() + ". Skipping duplicates."); + } else { + var aliasData = model.mapModel.getAliasById(element.getId()); + if (aliasData == null) { + model.mapModel.addMissingAliasId(element.getId()); + missingElements = true; + } + var marker = new AliasMarker(element.getId(), element.icon, aliasData, + model); + overlayCollection.aliasMarkers[element.getId()] = marker; + if (!missingElements) { + var bounds = marker.getBounds(); + boundsArray[element.modelId].extend(bounds.getNorthEast()); + boundsArray[element.modelId].extend(bounds.getSouthWest()); + } + } + } else if (element.type == "REACTION") { + var reactionData = model.mapModel.getReactionById(element.getId()); + if (reactionData == null) { + model.mapModel.addMissingReactionId(element.getId()); + missingElements = true; + } + var marker = null; + var icon = element.getIcon(); + + if (icon === null || icon === undefined) { + // this should happen when we visualize search data (there is + // no marker, but only flat overlay of the reaction lines) + // + marker = new ReactionOverlay(null, reactionData, model, false, element + .getId()); + } else { + // when we have icon defined (for instance when it comes from + // comment) then we don't want to have overlayed reaction lines + // but icon marker + marker = new ReactionMarker(element.getId(), icon, reactionData, model); + } + overlayCollection.reactionMarkers[element.getId()] = marker; + if (!missingElements) { + var bounds = marker.getBounds(); + boundsArray[element.modelId].extend(bounds.getNorthEast()); + boundsArray[element.modelId].extend(bounds.getSouthWest()); + + } + } else if (element.type == "POINT") { + var pointData = model.mapModel.getPointDataByPoint(element.getPoint()); + var marker = new PointMarker(pointData, element.icon, model); + overlayCollection.pointMarkers[pointData.getId()] = marker; + if (!missingElements) { + var bounds = marker.getBounds(); + boundsArray[element.modelId].extend(bounds.getNorthEast()); + boundsArray[element.modelId].extend(bounds.getSouthWest()); + } + } else { + logger.warn("Unknown type of the element in overlay: " + element.type); + } + var infoWindow = this.getInfoWindowForIdentifiedElement(element); + if (infoWindow != null) { + this.retrieveOverlayDetailDataForElement(element, infoWindow + .getOverlayFullViewArray()); + this.updateInfoWindowForIdentifiedElement(element); + } + } + + if (missingElements) { + this.retrieveMissingReactions(); + this.retrieveMissingAliases(); + } else { + if (elements.length > 0 && fitBounds) { + for ( var mapId in boundsArray) { + if (boundsArray.hasOwnProperty(mapId)) { + var map = this.getSubmodelById(mapId).map; + var bounds = boundsArray[mapId]; + if (map != null && !bounds.isEmpty()) { + if (typeof map.fitBounds2 !== "undefined") { + map.fitBounds2(bounds); + } else { + map.fitBounds(bounds); + } + } + } + } + } + } +}; + +/** + * Creates and register listeners to be called on events: + * <ul> + * <li>onAddAliases</li> + * <li>onAddReactions</li> + * </ul> + */ +CustomMap.prototype.createClientServerListeners = function() { + this.registerListenerType("onAddAliases"); + this.registerListenerType("onAddReactions"); + + var refreshLayoutsFun = function(e) { + var self = e.object; + if (!ServerConnector.isWaitingForData()) { + self.refreshSelectedLayouts(); + //and close "loading" dialog (if opened) + GuiConnector.closeLoadingDialog(); + } + }; + + var refreshOverlaysFun = function(e) { + e.object.refreshMarkers(); + }; + + this.addListener("onAddAliases", refreshLayoutsFun); + this.addListener("onAddAliases", refreshOverlaysFun); + + this.addListener("onAddReactions", refreshLayoutsFun); + this.addListener("onAddReactions", refreshOverlaysFun); + +}; + +/** + * Opens {@link AbstractInfoWindow} for a marker. + * + * @param marker + * {@link AbstractMarker} for which info window should be opened + */ +CustomMap.prototype.openInfoWindowForMarker = function(marker) { + var modelId = marker.getCustomMap().getId(); + var markerId = marker.getId(); + var model = this.getSubmodelById(modelId); + logger.debug("Opening info window for " + marker.constructor.name + ": " + + markerId + ", model: " + modelId); + var elementType = marker.getType(); + if (marker instanceof AliasMarker) { + var alias = model.mapModel.getAliasById(markerId); + + // if we have only simple version of the data then ask server for more + // details + if (alias == null || alias.completness == 'SIMPLE') { + logger.debug("Accessing full alias: " + markerId); + var ids = [ [ modelId, markerId ] ]; + ServerConnector.retreiveFullAliases(ids); + } + } else if (marker instanceof PointMarker) { + // no special treatment for points + } else if (marker instanceof ReactionMarker) { + // no special treatment for reactions + } else { + logger.error("Unknown marker type: " + marker.constructor.name); + } + + // open AliasInfoWindow in a right model + model._openInfoWindowForMarker(marker); + + var infoWindow = model.returnInfoWindowForMarker(marker); + + var element = new IdentifiedElement({ + objectId : markerId, + modelId : modelId, + type : elementType + }); + + this.retrieveOverlayDetailDataForElement(element, infoWindow + .getOverlayFullViewArray()); + +}; + +/** + * Sends requestes to download detailed data about element in all + * {@link OverlayCollection}. + * + * @param element + * element for which we want to have detailed information + */ +CustomMap.prototype.retrieveOverlayDetailDataForElement = function(element, + general) { + if (general === undefined) { + logger.warn("general param is undefined!"); + general = []; + } + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName)) { + var overlay = this.overlayCollections[overlayName]; + + var generalRequest = general[overlayName]; + if (generalRequest === undefined) { + logger.warn( + "No information about general overlay request for overlay: ", + overlayName); + generalRequest = false; + } + generalRequest = generalRequest || !overlay.allowSearchById(); + + if (overlay.allowGeneralSearch() || overlay.allowSearchById()) { + if (overlay.isMissingDetailData(element, generalRequest)) { + ServerConnector.sendOverlayDetailDataRequest(overlayName, element, + generalRequest); + } + } + } + } +}; + +/** + * Updates info window identified by element given as a parameter. + * + * @param identifiedElement + * element for which info window should be updated + */ +CustomMap.prototype.updateInfoWindowForIdentifiedElement = function( + identifiedElement) { + var infoWindow = this.getInfoWindowForIdentifiedElement(identifiedElement); + if (infoWindow == null) { + return; + } else { + infoWindow.update(); + } +}; + +/** + * Returns data from all {@link OverlayCollection} for a given alias. + * + * @param alias + * {@link Alias} for which overlay data will be returned + * @param general + * if true then all elements will be returned, if false then only + * ones availble right now in the overlay + * @returns data from all {@link OverlayCollection} for a given alias + */ +CustomMap.prototype.getOverlayDataForAlias = function(alias, general) { + var identifiedElement = new IdentifiedElement(alias); + return this.getOverlayDataForIdentifiedElement(identifiedElement, general); +}; + +/** + * Returns data from all {@link OverlayCollection} for a given reaction. + * + * @param reaction + * {@link Reaction} for which overlay data will be returned + * @param general + * if true then all elements will be returned, if false then only + * ones availble right now in the overlay + * @returns data from all {@link OverlayCollection} for a given alias + */ +CustomMap.prototype.getOverlayDataForReaction = function(reaction, general) { + var identifiedElement = new IdentifiedElement(reaction); + return this.getOverlayDataForIdentifiedElement(identifiedElement, general); +}; + +/** + * Returns data from all {@link OverlayCollection} for a given {@link PointData} + * + * @param point + * {@link PointData} for which overlay data will be returned + * @returns data from all {@link OverlayCollection} for a given + * {@link PointData} + */ +CustomMap.prototype.getOverlayDataForPoint = function(point, general) { + var identifiedElement = new IdentifiedElement(point); + return this.getOverlayDataForIdentifiedElement(identifiedElement, general); +}; + +/** + * Returns data from all {@link OverlayCollection} for element identified by the + * parameter + * + * @param identifiedElement + * {@link IdentifiedElement} for which overlay data will be returned + * @returns data from all {@link OverlayCollection} for a given + * {@link IdentifiedElement} + */ +CustomMap.prototype.getOverlayDataForIdentifiedElement = function( + identifiedElement, general) { + if (general === undefined) { + logger.warn("general parameter must be defined"); + general = []; + } + var result = []; + for ( var overlayName in this.overlayCollections) { + if (this.overlayCollections.hasOwnProperty(overlayName)) { + var overlay = this.overlayCollections[overlayName]; + if (overlay.allowGeneralSearch() || overlay.allowSearchById()) { + var generalFlag = general[overlay.getName()]; + if (generalFlag === undefined) { + logger.warn("General flag for overlay: " + overlay.getName() + + " is not defined, assuming false"); + generalFlag = false; + } + result.push({ + overlay : overlay, + data : overlay.getDetailDataByIdentifiedElement(identifiedElement, + !overlay.allowSearchById() || generalFlag) + }); + } + } + } + return result; +}; + +/** + * Returns {@link AbstractInfoWindow} for element identified by the parameter. + * + * @param identifiedElement + * {@link IdentifiedElement} that determines for which element we + * want {@link AbstractInfoWindow} + * @returns {@link AbstractInfoWindow} for element identified by the parameter + */ +CustomMap.prototype.getInfoWindowForIdentifiedElement = function( + identifiedElement) { + var model = this.getSubmodelById(identifiedElement.modelId); + var infoWindow = null; + if (identifiedElement.type == "ALIAS") { + infoWindow = model.getAliasInfoWindowById(identifiedElement.getId()); + } else if (identifiedElement.type == "POINT") { + infoWindow = model.getPointInfoWindowById(identifiedElement.getId()); + } else if (identifiedElement.type == "REACTION") { + infoWindow = model.getReactionInfoWindowById(identifiedElement.getId()); + } else { + logger.error("Unknown type of IdentifiedElement: ", identifiedElement); + } + return infoWindow; +}; + +CustomMap.prototype.getActiveSubmapId = function() { + return this._activeSubmapId; +}; + +CustomMap.prototype.setActiveSubmapId = function(submapId) { + this._activeSubmapId = submapId; +}; + +CustomMap.prototype.updateAliasesForLayout = function(layoutId, jsonAliases) { + logger.debug("Updating aliases for layout: " + layoutId); + + // init layout data + if (this.mapModel.getLayoutDataById(layoutId) == null) { + this.mapModel.initLayoutData(layoutId); + for (var i = 0; i < this.submaps.length; i++) { + this.submaps[i].mapModel.initLayoutData(layoutId); + } + } + + var aliases = JSON.parse(jsonAliases); + for (var i = 0; i < aliases.length; i++) { + var alias = aliases[i]; + var model = this.getSubmodelById(alias.modelId); + if (model != 'undefined' && model != null) { + model.mapModel.updateAliasForLayout(layoutId, alias); + model.getAliasInfoWindowById(alias.idObject).update(); + } else { + logger.warn("Unknown model: " + alias.modelId); + } + } + + this.retrieveMissingAliases(); +}; + +CustomMap.prototype.getReferenceGenome = function(type, version) { + var result = null; + if (this._referenceGenome[type] == null) { + this._referenceGenome[type] = []; + } + if (this._referenceGenome[type][version] == null) { + ServerConnector.sendReferenceGenomeDetailRequest(type, version); + this._referenceGenome[type][version] = new ReferenceGenome(null); + return null; + } else { + return this._referenceGenome[type][version]; + } +}; + +CustomMap.prototype.updateReferenceGenome = function(type, version, jsonObj) { + if (this._referenceGenome[type] == null) { + this._referenceGenome[type] = []; + } + this._referenceGenome[type][version] = new ReferenceGenome(jsonObj); + this.refreshInfoWindows(); +} diff --git a/web/src/main/webapp/resources/js/GuiConnector.js b/web/src/main/webapp/resources/js/GuiConnector.js index e5bb74b28a6e5df625236a55eea75af9c4364e28..85503c34d5cf8985fc0827f01f23de2e297914ad 100644 --- a/web/src/main/webapp/resources/js/GuiConnector.js +++ b/web/src/main/webapp/resources/js/GuiConnector.js @@ -1,302 +1,302 @@ -/** - * This static global object contains set of functions that returns/set data in - * the Gui (html). - */ -GuiConnector = new Object(); - -/** - * Flag informing if the context menu is visible or not. - */ -GuiConnector.contextMenuVisible = false; - -/** - * Flag informing if selection menu is visible or not. Selection menu is - * available when selcting polygon on the map and right clicking on it. - */ -GuiConnector.selectionMenuVisible = false; - -/** - * X coordinate of the mouse in a browser. - */ -GuiConnector.xPos = 0; - -/** - * Y coordinate of the mouse in a browser. - */ -GuiConnector.yPos = 0; - -/** - * List of GET params passed via url. - */ -GuiConnector.getParams = []; - -// find GuiConnector.getParams -document.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function() { - function decode(s) { - return decodeURIComponent(s.split("+").join(" ")); - } - GuiConnector.getParams[decode(arguments[1])] = decode(arguments[2]); -}); - -/** - * Initialize navigation for left panel tab. - */ -$(document) - .ready( - function() { - GuiConnector.leftPanelTabNavi = new TabNavi("tabView", { - top : "17px" - }); - GuiConnector.searchTabNavi = new TabNavi("tabView:mainForm:dTable", { - hideRemaining : false, - tabSize : 1, - top : "5px" - }); - GuiConnector.drugTabNavi = new TabNavi( - "tabView:drugForm:drugResults", { - hideRemaining : false, - tabSize : 1, - top : "5px" - }); - if (document.getElementById("tabView:chemicalForm:chemicalResults") != null) { - GuiConnector.chemicalTabNavi = new TabNavi( - "tabView:chemicalForm:chemicalResults", { - hideRemaining : false, - tabSize : 1, - top : "5px" - }); - } - GuiConnector.miRnaTabNavi = new TabNavi( - "tabView:miRNAForm:miRNAResults", { - hideRemaining : false, - tabSize : 1, - top : "5px" - }); - }); - -/** - * Returns name of the file with LCSB logo. - * - * @param bigLogo - * {@link Boolean} value determining if we want to have big logo or - * small one - */ -GuiConnector.getLcsbLogoImg = function(bigLogo) { - if (bigLogo) { - return 'lcsb_logo_mid.png'; - } else { - return 'lcsb_logo.png'; - } -}; - -/** - * Returns name of the file with image that should be presented when we are - * wainting for data to be loaded. - */ -GuiConnector.getLoadingImg = function() { - return "icons/ajax-loader.gif"; -}; - -/** - * Returns home directory for images in the application. - */ -GuiConnector.getImgPrefix = function() { - return "resources/images/"; -}; - -/** - * Returns main google maps div tag placed on the webpage. - */ -GuiConnector.getGoogleMapElement = function() { - return document.getElementById(ServerConnector.formIdentifier - + ":gmapElement"); -}; - -/** - * Shows main google map (by default map is hidden, because it doesn't point to - * our data from the beginning). - */ -GuiConnector.showGoogleMap = function() { - GuiConnector.getGoogleMapElement().style.visibility = "visible"; -}; - -/** - * Shows legend. - */ -GuiConnector.showLegend = function() { - document.getElementById(ServerConnector.formIdentifier + ':legend').style.display = "block"; -}; - -/** - * Hides legend. - */ -GuiConnector.hideLegend = function() { - document.getElementById(ServerConnector.formIdentifier + ':legend').style.display = "none"; -}; - -/** - * Hides right click menu. - */ -GuiConnector.hideRightClickMenu = function() { - $(PrimeFaces.escapeClientId(ServerConnector.formIdentifier + ':contextMenu')) - .hide(); - this.contextMenuVisible = false; -}; - -/** - * Returns <code>true</code> if right click menu is visible, - * <code>false</code> otherwise. - */ -GuiConnector.isRightMenuVisible = function() { - return this.contextMenuVisible; -}; - -/** - * Shows right click menu. - */ -GuiConnector.showRightClickMenu = function(x, y) { - $(PrimeFaces.escapeClientId(ServerConnector.formIdentifier + ':contextMenu')) - .css({ - top : y + 'px', - left : x + 'px' - }).show(); - this.contextMenuVisible = true; - - if (this.isSelectionMenuVisible) { - this.hideSelectionMenu(); - } -}; - -/** - * Hides selection menu. - * - * @see selectionMenuVisible - */ -GuiConnector.hideSelectionMenu = function() { - $( - PrimeFaces.escapeClientId(ServerConnector.formIdentifier - + ':selectionContextMenu')).hide(); - this.selectionMenuVisible = false; -}; - -/** - * Returns <code>true</code> when selection menu is visible, - * <code>false</code> otherwise. - * - * @see selectionMenuVisible - */ -GuiConnector.isSelectionMenuVisible = function() { - return this.selectionMenuVisible; -}; - -/** - * Shows selection menu. - * - * @see selectionMenuVisible - */ -GuiConnector.showSelectionMenu = function(x, y) { - $( - PrimeFaces.escapeClientId(ServerConnector.formIdentifier - + ':selectionContextMenu')).css({ - top : y + 'px', - left : x + 'px' - }).show(); - this.selectionMenuVisible = true; - - if (this.isRightMenuVisible()) { - this.hideRightClickMenu(); - } -}; - -/** - * Gets html div where overview images should be visualized. - * - */ -GuiConnector.getOverviewHtmlTag = function() { - return document.getElementById(ServerConnector.formIdentifier - + ':overviewDialog'); -}; - -/** - * Updates coordinates of the mouse in the browser. - */ -GuiConnector.updateMouseCoordinates = function(x, y) { - this.xPos = x; - this.yPos = y; -}; - -// forser browser to update mouse coordinates whenever mouse move -jQuery(document).ready(function() { - $(document).mousemove(function(e) { - GuiConnector.updateMouseCoordinates(e.pageX, e.pageY); - }); -}); - -/** - * Return html tag for submap visualization. - * - * @param id - * identifier of the submodel - */ -GuiConnector.getHtmlTagForSubmodelId = function(id) { - return document.getElementById('_gmapForm:submodelDialog' + id); -}; - -/** - * Returns js Primefaces object for submap visualization. - * - * @param id - * identifier of the submodel - */ -GuiConnector.getJsPopupForSubmodelId = function(id) { - return window['submodelDialog' + id]; -}; - -/** - * Opens popup for submap visualization. - * - * @param id - * identifier of the submodel - */ -GuiConnector.openDialog = function(id) { - var jsVar = GuiConnector.getJsPopupForSubmodelId(id); - if (jsVar != null) { - var htmlTag = GuiConnector.getHtmlTagForSubmodelId(id); - customMap.openSubmodel(id, htmlTag, jsVar); - } - return false; -}; - -GuiConnector.referenceToHtml = function(reference) { - if (reference.summary != null && reference.summary != "") { - var result = '<div title="' + reference.summary + '">'; - result += '<a href="' + reference.link + '" target="_blank">' - + reference.name + "</a>"; - // + reference.name + "(" + reference.type + ")</a>"; - result += "</div>"; - return result; - } else { - var result = '<div><a href="' + reference.link + '" target="_blank">' - + reference.name + "</a></div>"; - // + reference.name + "(" + reference.type + ")</a></div>"; - return result; - } -}; - -GuiConnector.openSearchPanel = function() { - $('a[href$="#tabView:searchTab"]').click(); -}; - -/** - * Opens window that informs user data data is being loaded from server. - */ -GuiConnector.openLoadingDialog = function() { - PF('loadingDlg').show(); -}; - -/** - * Closes window that informs user data data is being loaded from server. - */ -GuiConnector.closeLoadingDialog = function() { - PF('loadingDlg').hide(); -}; +/** + * This static global object contains set of functions that returns/set data in + * the Gui (html). + */ +GuiConnector = new Object(); + +/** + * Flag informing if the context menu is visible or not. + */ +GuiConnector.contextMenuVisible = false; + +/** + * Flag informing if selection menu is visible or not. Selection menu is + * available when selcting polygon on the map and right clicking on it. + */ +GuiConnector.selectionMenuVisible = false; + +/** + * X coordinate of the mouse in a browser. + */ +GuiConnector.xPos = 0; + +/** + * Y coordinate of the mouse in a browser. + */ +GuiConnector.yPos = 0; + +/** + * List of GET params passed via url. + */ +GuiConnector.getParams = []; + +// find GuiConnector.getParams +document.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function() { + function decode(s) { + return decodeURIComponent(s.split("+").join(" ")); + } + GuiConnector.getParams[decode(arguments[1])] = decode(arguments[2]); +}); + +/** + * Initialize navigation for left panel tab. + */ +$(document) + .ready( + function() { + GuiConnector.leftPanelTabNavi = new TabNavi("tabView", { + top : "17px" + }); + GuiConnector.searchTabNavi = new TabNavi("tabView:mainForm:dTable", { + hideRemaining : false, + tabSize : 1, + top : "5px" + }); + GuiConnector.drugTabNavi = new TabNavi( + "tabView:drugForm:drugResults", { + hideRemaining : false, + tabSize : 1, + top : "5px" + }); + if (document.getElementById("tabView:chemicalForm:chemicalResults") != null) { + GuiConnector.chemicalTabNavi = new TabNavi( + "tabView:chemicalForm:chemicalResults", { + hideRemaining : false, + tabSize : 1, + top : "5px" + }); + } + GuiConnector.miRnaTabNavi = new TabNavi( + "tabView:miRNAForm:miRNAResults", { + hideRemaining : false, + tabSize : 1, + top : "5px" + }); + }); + +/** + * Returns name of the file with LCSB logo. + * + * @param bigLogo + * {@link Boolean} value determining if we want to have big logo or + * small one + */ +GuiConnector.getLcsbLogoImg = function(bigLogo) { + if (bigLogo) { + return 'lcsb_logo_mid.png'; + } else { + return 'lcsb_logo.png'; + } +}; + +/** + * Returns name of the file with image that should be presented when we are + * wainting for data to be loaded. + */ +GuiConnector.getLoadingImg = function() { + return "icons/ajax-loader.gif"; +}; + +/** + * Returns home directory for images in the application. + */ +GuiConnector.getImgPrefix = function() { + return "resources/images/"; +}; + +/** + * Returns main google maps div tag placed on the webpage. + */ +GuiConnector.getGoogleMapElement = function() { + return document.getElementById(ServerConnector.formIdentifier + + ":gmapElement"); +}; + +/** + * Shows main google map (by default map is hidden, because it doesn't point to + * our data from the beginning). + */ +GuiConnector.showGoogleMap = function() { + GuiConnector.getGoogleMapElement().style.visibility = "visible"; +}; + +/** + * Shows legend. + */ +GuiConnector.showLegend = function() { + document.getElementById(ServerConnector.formIdentifier + ':legend').style.display = "block"; +}; + +/** + * Hides legend. + */ +GuiConnector.hideLegend = function() { + document.getElementById(ServerConnector.formIdentifier + ':legend').style.display = "none"; +}; + +/** + * Hides right click menu. + */ +GuiConnector.hideRightClickMenu = function() { + $(PrimeFaces.escapeClientId(ServerConnector.formIdentifier + ':contextMenu')) + .hide(); + this.contextMenuVisible = false; +}; + +/** + * Returns <code>true</code> if right click menu is visible, + * <code>false</code> otherwise. + */ +GuiConnector.isRightMenuVisible = function() { + return this.contextMenuVisible; +}; + +/** + * Shows right click menu. + */ +GuiConnector.showRightClickMenu = function(x, y) { + $(PrimeFaces.escapeClientId(ServerConnector.formIdentifier + ':contextMenu')) + .css({ + top : y + 'px', + left : x + 'px' + }).show(); + this.contextMenuVisible = true; + + if (this.isSelectionMenuVisible) { + this.hideSelectionMenu(); + } +}; + +/** + * Hides selection menu. + * + * @see selectionMenuVisible + */ +GuiConnector.hideSelectionMenu = function() { + $( + PrimeFaces.escapeClientId(ServerConnector.formIdentifier + + ':selectionContextMenu')).hide(); + this.selectionMenuVisible = false; +}; + +/** + * Returns <code>true</code> when selection menu is visible, + * <code>false</code> otherwise. + * + * @see selectionMenuVisible + */ +GuiConnector.isSelectionMenuVisible = function() { + return this.selectionMenuVisible; +}; + +/** + * Shows selection menu. + * + * @see selectionMenuVisible + */ +GuiConnector.showSelectionMenu = function(x, y) { + $( + PrimeFaces.escapeClientId(ServerConnector.formIdentifier + + ':selectionContextMenu')).css({ + top : y + 'px', + left : x + 'px' + }).show(); + this.selectionMenuVisible = true; + + if (this.isRightMenuVisible()) { + this.hideRightClickMenu(); + } +}; + +/** + * Gets html div where overview images should be visualized. + * + */ +GuiConnector.getOverviewHtmlTag = function() { + return document.getElementById(ServerConnector.formIdentifier + + ':overviewDialog'); +}; + +/** + * Updates coordinates of the mouse in the browser. + */ +GuiConnector.updateMouseCoordinates = function(x, y) { + this.xPos = x; + this.yPos = y; +}; + +// forser browser to update mouse coordinates whenever mouse move +jQuery(document).ready(function() { + $(document).mousemove(function(e) { + GuiConnector.updateMouseCoordinates(e.pageX, e.pageY); + }); +}); + +/** + * Return html tag for submap visualization. + * + * @param id + * identifier of the submodel + */ +GuiConnector.getHtmlTagForSubmodelId = function(id) { + return document.getElementById('_gmapForm:submodelDialog' + id); +}; + +/** + * Returns js Primefaces object for submap visualization. + * + * @param id + * identifier of the submodel + */ +GuiConnector.getJsPopupForSubmodelId = function(id) { + return window['submodelDialog' + id]; +}; + +/** + * Opens popup for submap visualization. + * + * @param id + * identifier of the submodel + */ +GuiConnector.openDialog = function(id) { + var jsVar = GuiConnector.getJsPopupForSubmodelId(id); + if (jsVar != null) { + var htmlTag = GuiConnector.getHtmlTagForSubmodelId(id); + customMap.openSubmodel(id, htmlTag, jsVar); + } + return false; +}; + +GuiConnector.referenceToHtml = function(reference) { + if (reference.summary != null && reference.summary != "") { + var result = '<div title="' + reference.summary + '">'; + result += '<a href="' + reference.link + '" target="_blank">' + + reference.name + "</a>"; + // + reference.name + "(" + reference.type + ")</a>"; + result += "</div>"; + return result; + } else { + var result = '<div><a href="' + reference.link + '" target="_blank">' + + reference.name + "</a></div>"; + // + reference.name + "(" + reference.type + ")</a></div>"; + return result; + } +}; + +GuiConnector.openSearchPanel = function() { + $('a[href$="#tabView:searchTab"]').click(); +}; + +/** + * Opens window that informs user data data is being loaded from server. + */ +GuiConnector.openLoadingDialog = function() { + PF('loadingDlg').show(); +}; + +/** + * Closes window that informs user data data is being loaded from server. + */ +GuiConnector.closeLoadingDialog = function() { + PF('loadingDlg').hide(); +}; diff --git a/web/src/main/webapp/resources/js/ReactionOverlay.js b/web/src/main/webapp/resources/js/ReactionOverlay.js index d35b5c3490dd4ae572d3cbbbf83129817100ade2..c0b144caa2a6c783aed09c80bcc1d86073a29885 100644 --- a/web/src/main/webapp/resources/js/ReactionOverlay.js +++ b/web/src/main/webapp/resources/js/ReactionOverlay.js @@ -15,6 +15,9 @@ * the same time) */ function ReactionOverlay(layoutReaction, reactionData, map, customized, id) { + // call super constructor + AbstractOverlayElement.call(); + this.color = "#FF0000"; this.width = 5.0; // list of google map objects associated with the reaction (like lines) @@ -30,7 +33,7 @@ function ReactionOverlay(layoutReaction, reactionData, map, customized, id) { if (layoutReaction.width) { this.width = layoutReaction.width; } - this.color = intToColorString(layoutReaction.color.value); + this.color = this.overlayToColor(layoutReaction); } if (reactionData != null) { @@ -44,6 +47,10 @@ function ReactionOverlay(layoutReaction, reactionData, map, customized, id) { }; +ReactionOverlay.prototype = Object.create(AbstractOverlayElement.prototype); +ReactionOverlay.prototype.constructor = ReactionOverlay; + + /** * Returns {@link google.maps.Bounds bounds} of all google maps elements * included in the object. diff --git a/web/src/main/webapp/resources/js/ServerConnector.js b/web/src/main/webapp/resources/js/ServerConnector.js index ac913103206f21e64e7224318dffd645b18f0e88..bd1646dc904e5dadb5fa340f8e68f231f03603bf 100644 --- a/web/src/main/webapp/resources/js/ServerConnector.js +++ b/web/src/main/webapp/resources/js/ServerConnector.js @@ -1,1025 +1,1046 @@ -/** - * This object contains methods that will communicate with server. - */ -ServerConnector = new Object(); - -/** - * List of {@link OverlayCollection} that was added to the server connector. It - * describes list of all overlays that communicate with server. - */ -ServerConnector._overlays = []; - -/** - * Associative array with methods that should be used for comunication of the - * {@link OverlayCollection} from _overlays field. - */ -ServerConnector._overlayMethods = []; - -/** - * Form where fields passed to/from server are stored. - */ -ServerConnector.formIdentifier = "_gmapForm"; - -/** - * Variable describing when was last transmition of data (location of the map, - * zoom level, etc.) to the server session. - */ -ServerConnector.lastActualization = 0; - -ServerConnector._customMap = null; - -/** - * Number of requests send to server about AliasLayout data. - */ -ServerConnector._waitingForAliasLayoutData = 0; -ServerConnector._waitingForAliasLayoutDataByLayoutId = []; - -ServerConnector._waitingFullAliasLayoutData = 0; -ServerConnector._waitingFullAliasLayoutDataById = []; - -/** - * Number of requests send to server about AliasData data. - */ -ServerConnector._waitingForAliasData = 0; -ServerConnector._waitingForAliasDataByAliasId = []; - -/** - * Number of requests send to server about ReactionLayout data. - */ -ServerConnector._waitingForReactionLayoutData = 0; -ServerConnector._waitingForReactionLayoutDataByLayoutId = []; - -/** - * Number of requests send to server about ReactionData data. - */ -ServerConnector._waitingForReactionData = 0; -ServerConnector._waitingForReactionDataByReactionId = []; - -/** - * Get name of the file that should be used as logo. - */ -ServerConnector.getLogoImg = function() { - return document.getElementById('logoImg').value; -}; - -/** - * Get link to the website that should be accessed when clicking on - * {@link ServerConnector.getLogoImg}. - */ -ServerConnector.getLogoLink = function() { - return document.getElementById('logoLink').value; -}; - -/** - * Get zoom level of the {@link CustomMap} at which it was last browsed. - */ -ServerConnector.getZoomLevel = function() { - return document.getElementById(ServerConnector.formIdentifier + ':zoomLevel').value; -}; - -/** - * Set zoom level for {@link CustomMap} on the server side. - */ -ServerConnector.setZoomLevel = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':zoomLevel').value = "" - + value; -}; - -/** - * Set x coordinate for {@link CustomMap} on the server side. - */ -ServerConnector.setCenterCoordinateX = function(value) { - document - .getElementById(ServerConnector.formIdentifier + ':centerCoordinateX').value = "" - + value; -}; - -/** - * Get x coordinate of the {@link CustomMap} at which it was last browsed. - */ -ServerConnector.getCenterCoordinateX = function() { - var result = parseFloat(document - .getElementById(ServerConnector.formIdentifier + ':centerCoordinateX').value); - return result; -}; - -/** - * Set y coordinate for {@link CustomMap} on the server side. - */ -ServerConnector.setCenterCoordinateY = function(value) { - document - .getElementById(ServerConnector.formIdentifier + ':centerCoordinateY').value = "" - + value; -}; - -/** - * Get y coordinate of the {@link CustomMap} at which it was last browsed. - */ -ServerConnector.getCenterCoordinateY = function() { - var result = parseFloat(document - .getElementById(ServerConnector.formIdentifier + ':centerCoordinateY').value); - return result; -}; - -/** - * Set layout that is currently browsed for {@link CustomMap} on the server - * side. - */ -ServerConnector.setSelectedLayout = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':selectedLayout').value = "" - + value; -}; -/** - * Sets list of layouts visualized by javascript. - */ -ServerConnector.setVisibleLayouts = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':visibleLayouts').value = value; -} - -/** - * Get layout of the {@link CustomMap} which was last browsed. - */ -ServerConnector.getSelectedLayout = function() { - return document.getElementById(ServerConnector.formIdentifier - + ':selectedLayout').value; -}; - -/** - * Sends data about coordinates/zoom level etc. to the server. Method checks if - * the transmition is not done to often (at most once per second) - */ -ServerConnector.actualizeSessionData = function(value) { - var timestamp = new Date().getTime(); - // we send the data with at least 1 second time distance - if (timestamp > ServerConnector.lastActualization) { - ServerConnector.lastActualization = timestamp + 1000; - setTimeout(function() { - ServerConnector.actualizeParams(); - }, 1000); - } -}; - -/** - * Sends data about coordinates/zoom level etc. to the server. Sending is - * performed immediatelly. - * - * @see ServerConnector.actualizeSessionData - */ -ServerConnector.actualizeParams = function() { - actualizeParams(); -}; - -/** - * Sets search query that will be handled by server. - */ -ServerConnector.setSearchQuery = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':mapParam').value = "" - + value; -}; - -/** - * Sets data mining query that will be handled by server. - */ -ServerConnector.setDataMiningQuery = function(value) { - document.getElementById(ServerConnector.formIdentifier - + ':missingConnectionParam').value = "" + value; -}; - -/** - * Sets drug search query that will be handled by server. - */ -ServerConnector.setDrugQuery = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':drugParam').value = "" - + value; -}; - -/** - * Sets comment query that will be handled by server. - */ -ServerConnector.setCommentQuery = function(value) { - logger.error("ServerConnector.setCommentQuery: Not implemented"); - document.getElementById(ServerConnector.formIdentifier + ':commentParam').value = "" - + value; -}; - -/** - * Sets selected polygon. This might be in futer used oto extract/analyze data - * in the polygon by the server side. - */ -ServerConnector.setSelectedPolygon = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':selectedPolygon').value = "" - + value; - document.getElementById(ServerConnector.formIdentifier - + ':selectedDrugPolygon').value = "" + value; -}; - -/** - * Sets identifier of the model where selected polygon (@see - * ServerConnector.setSelectedPolygon) was selected. - */ -ServerConnector.setExportModelId = function(value) { - document.getElementById(ServerConnector.formIdentifier + ':exportModelId').value = "" - + value; -}; - -/** - * Sets flag marking if the comments are visible or not. - */ -ServerConnector.setShowComments = function(value) { - _setShowComments([ { - name : 'showComments', - value : value - } ]); -}; - -/** - * Search for similar data mining entries on the map. - */ -ServerConnector.showSimilarDataMining = function(param) { - document.getElementById(ServerConnector.formIdentifier + ':geneName').value = "" - + param; - searchMissingConnections(); -}; - -/** - * Ask server to send list of aliases that were highlighted in the layout with a - * given identifier. - * - * @param identifier - * of the layout - */ -ServerConnector.retreiveActiveAliasesForLayout = function(identifier) { - this.setWaitingForAliasLayoutData(parseInt(identifier), true); - _retreiveActiveAliasesForLayout([ { - name : 'layoutId', - value : identifier - } ]); -}; - -ServerConnector.retreiveFullAliasesForLayout = function(layoutId, aliasId, modelId) { - this.setWaitingForFullAliasLayoutData(parseInt(layoutId),parseInt(aliasId), true); - _retreiveFullAliasesForLayout([ { - name : 'layoutId', - value : layoutId, - }, { - name : 'ids', - value : JSON.stringify([[modelId, aliasId]]), - }, - ]); -}; - -/** - * Ask server to send list of reactions that were highlighted in the layout with - * a given identifier. - * - * @param identifier - * of the layout - */ -ServerConnector.retreiveActiveReactionsForLayout = function(identifier) { - this.setWaitingForReactionLayoutData(parseInt(identifier), true); - _retreiveActiveReactionsForLayout([ { - name : 'layoutId', - value : identifier - } ]); -}; - -/** - * Ask server to send list of light information about aliases. - * - * @param ids - * list of alias identifiers, every identifier is an array with two - * values: modelId, aliasId - */ -ServerConnector.retreiveLightAliases = function(ids) { - for (var i = 0; i < ids.length; i++) { - this.setWaitingForAliasData(parseInt(ids[i][1]), true); - } - _retreiveLightAliases([ { - name : 'ids', - value : JSON.stringify(ids) - } ]); -}; - -/** - * Ask server to send list of full information about aliases. - * - * @param ids - * list of alias identifiers, every identifier is an array with two - * values: modelId, aliasId - */ -ServerConnector.retreiveFullAliases = function(ids) { - _retreiveFullAliases([ { - name : 'ids', - value : JSON.stringify(ids) - } ]); -}; - -/** - * Ask server to send list of light information about reactions. - * - * @param ids - * list of reaction identifiers, every identifier is an array with - * two values: modelId, reactionId - */ -ServerConnector.retreiveLightReactions = function(ids) { - for (var i = 0; i < ids.length; i++) { - this.setWaitingForReactionData(parseInt(ids[i][1]), true); - } - _retreiveLightReactions([ { - name : 'ids', - value : JSON.stringify(ids) - } ]); -}; - -/** - * Sends request to server to refresh data for overlay with a given name. - * - * @param overlayName - * name of the overlay - */ -ServerConnector.sendRefreshRequest = function(overlayName) { - var functions = ServerConnector._overlayMethods[overlayName]; - if (functions != null) { - var refreshFunction = functions.refreshFunction; - if (refreshFunction != null) { - refreshFunction(); - } else { - logger.warn("Refresh function for " + overlayName + " doesn't exist"); - } - } else { - logger.warn("[Refresh function] Unknown overlay: ", overlayName); - } -}; - -/** - * Adds {@link OverlayCollection} to ServerConnector. - */ -ServerConnector.addOverlayCollection = function(overlay) { - if (ServerConnector._overlayMethods[overlay.name] != null) { - if (ServerConnector._overlays[overlay.name] != null) { - logger.warn("Overlay with name " + overlay.name + " already added"); - return; - } - ServerConnector._overlays[overlay.name] = overlay; - if (ServerConnector._overlayMethods[overlay.name].initFunction != null) { - ServerConnector._overlayMethods[overlay.name].initFunction(); - } else { - logger.warn("Cannot initialize overlay: " + overlay); - } - } else { - logger.warn("Unknown overlay: ", overlay); - } -}; - -/** - * Method that should be called by server to update data in overlay. - * - * @param overlayName - * name of overlay for which the data is sent - * @param data - * new data for overlay - * @param fitBounds - * should the map call fitBounds after update - */ -ServerConnector.updateOverlayCollection = function(overlayName, data, fitBounds) { - logger.debug("Updating: " + overlayName); - var overlay = ServerConnector._overlays[overlayName]; - if (overlay != null) { - overlay.updateOverlays(data, fitBounds); - } else { - logger.warn("Overlay " + overlayName - + " cannot be updated. It doesn't exist"); - } -} - -/** - * Name of the overlay for 'search' overlay. - */ -ServerConnector.SEARCH_OVERLAY_NAME = 'search'; - -/** - * Name of the overlay for 'data mining' overlay. - */ -ServerConnector.DATA_MINING_OVERLAY_NAME = 'missingConnection'; - -/** - * Name of the overlay for 'drug' overlay. - */ -ServerConnector.DRUG_OVERLAY_NAME = 'drug'; - -/** - * Name of the overlay for 'chemical' overlay. - */ -ServerConnector.CHEMICAL_OVERLAY_NAME = 'chemical'; - -/** - * Name of the overlay for 'comment' overlay. - */ -ServerConnector.COMMENT_OVERLAY_NAME = 'comment'; - -/** - * Name of the overlay for 'mirna' overlay. - */ -ServerConnector.MI_RNA_OVERLAY_NAME = 'mirna'; - -/** - * Register 'search' overlay on the server. - */ -ServerConnector.registerSearchOverlay = function() { - _registerSearchOverlayCollection([ { - name : "overlayName", - value : ServerConnector.SEARCH_OVERLAY_NAME, - } ]); -}; - -/** - * Sends request to the server to refresh data in 'search' overlay. - */ -ServerConnector.refreshSearchOverlay = function() { - _refreshSearchOverlayCollection(); -}; - -/** - * Clear data related to 'search' overlay.. - */ -ServerConnector.clearSearchOverlay = function() { - _clearSearchOverlayCollection(); -}; - -/** - * Register 'data mining' overlay on the server. - */ -ServerConnector.registerDataMiningOverlay = function() { - _registerMissingConnectionOverlayCollection([ { - name : "overlayName", - value : ServerConnector.DATA_MINING_OVERLAY_NAME, - } ]); -}; - -/** - * Sends request to the server to refresh data in 'data mining' overlay. - */ -ServerConnector.refreshDataMiningOverlay = function() { - _refreshMissingConnectionOverlayCollection(); -}; - -/** - * Clear data related to 'data mining' overlay. - */ -ServerConnector.clearDataMiningOverlay = function() { - _clearMissingConnectionOverlayCollection(); -}; - -/** - * Register 'drug' overlay on the server. - */ -ServerConnector.registerDrugOverlay = function() { - _registerDrugOverlayCollection([ { - name : "overlayName", - value : ServerConnector.DRUG_OVERLAY_NAME, - } ]); -}; - -ServerConnector.requestDrugDetailDataFunction = function(identfiedElement, id) { - logger.debug("Requesting drug details: ", identfiedElement, id); - _requestDrugDetailDataFunction([ { - name : "searchResultIdentifier", - value : id, - }, { - name : "objectIdentifier", - value : identfiedElement.getId(), - }, { - name : "modelIdentifier", - value : identfiedElement.getModelId(), - }, { - name : "type", - value : identfiedElement.getType(), - } ]); -}; -ServerConnector.requestCommentDetailDataFunction = function(identfiedElement, - id) { - _requestCommentDetailDataFunction([ { - name : "searchResultIdentifier", - value : id, - }, { - name : "objectIdentifier", - value : identfiedElement.getId(), - }, { - name : "modelIdentifier", - value : identfiedElement.getModelId(), - }, { - name : "type", - value : identfiedElement.getType(), - } ]); -}; - -/** - * Sends request to the server to refresh data in 'drug' overlay. - */ -ServerConnector.refreshDrugOverlay = function() { - _refreshDrugOverlayCollection(); -}; - -/** - * Clear data related to 'drug' overlay. - */ -ServerConnector.clearDrugOverlay = function() { - _clearDrugOverlayCollection(); -}; - -ServerConnector.registerChemicalOverlay = function() { - _registerChemicalOverlayCollection([ { - name : "overlayName", - value : ServerConnector.CHEMICAL_OVERLAY_NAME, - } ]); -}; - -ServerConnector.requestChemicalDetailDataFunction = function(identfiedElement, - id) { - _requestChemicalDetailDataFunction([ { - name : "searchResultIdentifier", - value : id, - }, { - name : "objectIdentifier", - value : identfiedElement.getId(), - }, { - name : "modelIdentifier", - value : identfiedElement.getModelId(), - }, { - name : "type", - value : identfiedElement.getType(), - } ]); -}; - -/** - * Sends request to the server to refresh data in 'drug' overlay. - */ -ServerConnector.refreshChemicalOverlay = function() { - _refreshChemicalOverlayCollection(); -}; - -/** - * Clear data related to 'chemical' overlay. - */ -ServerConnector.clearChemicalOverlay = function() { - _clearChemicalOverlayCollection(); -}; - -/** - * Register 'comment' overlay on the server. - */ -ServerConnector.registerCommentOverlay = function() { - _registerCommentOverlayCollection([ { - name : "overlayName", - value : ServerConnector.COMMENT_OVERLAY_NAME, - } ]); -}; - -/** - * Sends request to the server to refresh data in 'comment' overlay. - */ -ServerConnector.refreshCommentOverlay = function() { - _refreshCommentOverlayCollection(); -}; - -/** - * Clear data related to 'comment' overlay. - */ -ServerConnector.clearCommentOverlay = function() { - _clearCommentOverlayCollection(); -}; - -/** - * Clear data related to 'data mining' overlay. - */ -ServerConnector.clearDataMiningOverlay = function() { - _clearMissingConnectionOverlayCollection(); -}; - -/** - * Register 'drug' overlay on the server. - */ -ServerConnector.registerMiRnaOverlay = function() { - _registerMiRnaOverlayCollection([ { - name : "overlayName", - value : ServerConnector.MI_RNA_OVERLAY_NAME, - } ]); -}; - -ServerConnector.requestMiRnaDetailDataFunction = function(identfiedElement, id) { - _requestMiRnaDetailDataFunction([ { - name : "searchResultIdentifier", - value : id, - }, { - name : "objectIdentifier", - value : identfiedElement.getId(), - }, { - name : "modelIdentifier", - value : identfiedElement.getModelId(), - }, { - name : "type", - value : identfiedElement.getType(), - } ]); -}; - -/** - * Sends request to the server to refresh data in 'drug' overlay. - */ -ServerConnector.refreshMiRnaOverlay = function() { - _refreshMiRnaOverlayCollection(); -}; - -/** - * Clear data related to 'mirna' overlay. - */ -ServerConnector.clearMiRnaOverlay = function() { - _clearMiRnaOverlayCollection(); -}; - -/** - * Define pack of methods for 'search' overlay. - */ -ServerConnector._overlayMethods[ServerConnector.SEARCH_OVERLAY_NAME] = { - initFunction : ServerConnector.registerSearchOverlay, - refreshFunction : ServerConnector.refreshSearchOverlay, - clearFunction : ServerConnector.clearSearchOverlay, -}; - -/** - * Define pack of methods for 'data minig' overlay. - */ -ServerConnector._overlayMethods[ServerConnector.DATA_MINING_OVERLAY_NAME] = { - initFunction : ServerConnector.registerDataMiningOverlay, - refreshFunction : ServerConnector.refreshDataMiningOverlay, - clearFunction : ServerConnector.clearDataMiningOverlay, -}; - -/** - * Define pack of methods for 'drug' overlay. - */ -ServerConnector._overlayMethods[ServerConnector.DRUG_OVERLAY_NAME] = { - initFunction : ServerConnector.registerDrugOverlay, - refreshFunction : ServerConnector.refreshDrugOverlay, - clearFunction : ServerConnector.clearDrugOverlay, - requestDetailDataFunction : ServerConnector.requestDrugDetailDataFunction, -}; - -/** - * Define pack of methods for 'chemical' overlay. - */ -ServerConnector._overlayMethods[ServerConnector.CHEMICAL_OVERLAY_NAME] = { - initFunction : ServerConnector.registerChemicalOverlay, - refreshFunction : ServerConnector.refreshChemicalOverlay, - clearFunction : ServerConnector.clearChemicalOverlay, - requestDetailDataFunction : ServerConnector.requestChemicalDetailDataFunction, -}; - -/** - * Define pack of methods for 'comment' overlay. - */ -ServerConnector._overlayMethods[ServerConnector.COMMENT_OVERLAY_NAME] = { - initFunction : ServerConnector.registerCommentOverlay, - refreshFunction : ServerConnector.refreshCommentOverlay, - clearFunction : ServerConnector.clearCommentOverlay, - requestDetailDataFunction : ServerConnector.requestCommentDetailDataFunction, -}; - -ServerConnector._overlayMethods[ServerConnector.MI_RNA_OVERLAY_NAME] = { - initFunction : ServerConnector.registerMiRnaOverlay, - refreshFunction : ServerConnector.refreshMiRnaOverlay, - clearFunction : ServerConnector.clearMiRnaOverlay, - requestDetailDataFunction : ServerConnector.requestMiRnaDetailDataFunction, -}; - -ServerConnector.sendClearRequest = function(overlayName) { - var functions = ServerConnector._overlayMethods[overlayName]; - if (functions != null) { - var clearFunction = functions.clearFunction; - if (clearFunction != null) { - clearFunction(); - } else { - logger.warn("Clear function for " + overlayName + " doesn't exist"); - } - } else { - logger.warn("[Clear function] Unknown overlay: ", overlayName); - } -}; - -ServerConnector.setOverlayResultIds = function(overlayName, ids) { - var overlay = this._overlays[overlayName]; - if (overlay != null) { - overlay.setResultsIds(ids); - } else { - logger.warn("Overlay '" + overlayName + "' doesn't exist"); - } -}; - -ServerConnector.sendOverlayDetailDataRequest = function(overlayName, - identifiedElement, general) { - var overlay = ServerConnector._overlays[overlayName]; - if (overlay == null) { - logger.warn("Unknown overlay: " + overlayName); - return; - } - var functions = ServerConnector._overlayMethods[overlayName]; - if (functions != null) { - var requestDetailDataFunction = functions.requestDetailDataFunction; - if (requestDetailDataFunction != null) { - var missingData = overlay.getMissingDetailDataIds(identifiedElement, - general); - if (missingData.length == 0) { - logger - .warn( - "request of missing data called for empty data set... overlay name = ", - overlayName, "general: ", general); - } - for (var i = 0; i < missingData.length; i++) { - requestDetailDataFunction(identifiedElement, missingData[i]); - } - } else { - logger.warn("Request detail data function for " + overlayName - + " doesn't exist"); - } - } else { - logger.warn("[Clear function] Unknown overlay: ", overlayName); - } - -}; - -ServerConnector.updateOverviewElementDetailData = function(overlayName, - searchResultIdentifier, identifiedElement, data) { - var overlay = this._overlays[overlayName]; - if (overlay != null) { - overlay.updateOverviewElementDetailData(identifiedElement, - searchResultIdentifier, data); - } else { - logger.warn("Overlay '" + overlayName + "' doesn't exist"); - } -}; - -/** - * Returns <code>true</code> if we are waiting for any kind of data from - * server, <code>false</code> otherwise. - * - * @returns {Boolean}: <code>true</code> if we are waiting for any kind of - * data from server, <code>false</code> otherwise. - */ -ServerConnector.isWaitingForData = function() { - var result = (this._waitingForAliasLayoutData != 0) || // - (this._waitingForAliasData != 0) || // - (this._waitingForReactionLayoutData != 0) || // - (this._waitingForReactionData != 0); - return result; -}; - -/** - * Sets waitingForAliasLayoutData flag that monitors if we are waiting for the - * data about aliases in a layout from server. - * - * @param value - * new value of the waitingForAliasLayoutData field - */ -ServerConnector.setWaitingForAliasLayoutData = function(layoutId, value) { - if (isInt(layoutId)) { - var oldVal = this._waitingForAliasLayoutDataByLayoutId[layoutId]; - this._waitingForAliasLayoutDataByLayoutId[layoutId] = value; - if (value === true) { - if (oldVal !== true) { - this._waitingForAliasLayoutData++; - } - } else if (value === false) { - if (oldVal === true) { - this._waitingForAliasLayoutData--; - } - } else { - logger - .error( - "WaitingForAliasLayoutData value must be boolean, but found: ", - value); - } - } else { - logger.error( - "WaitingForAliasLayoutData layoutId must be integer, but found: ", - layoutId); - } -} - -ServerConnector.setWaitingForFullAliasLayoutData = function(layoutId, aliasId, value) { - if (!isInt(layoutId)) { - logger.error( - "setWaitingForFullAliasLayoutData layoutId must be integer, but found: ", - layoutId); - } - if (!isInt(aliasId)) { - logger.error( - "setWaitingForFullAliasLayoutData aliasId must be integer, but found: ", - aliasId); - } - - var oldVal = this._waitingFullAliasLayoutDataById[layoutId+"-"+aliasId]; - this._waitingFullAliasLayoutDataById[layoutId+"-"+aliasId] = value; - if (value === true) { - if (oldVal !== true) { - this._waitingFullAliasLayoutData++; - } - } else if (value === false) { - if (oldVal === true) { - this._waitingFullAliasLayoutData--; - } - } else { - logger - .error( - "setWaitingForFullAliasLayoutData value must be boolean, but found: ", - value); - } -} - -ServerConnector.isWaitingForFullAliasLayoutData = function(layoutId, aliasId) { - if (!isInt(layoutId)) { - logger.error( - "isWaitingForFullAliasLayoutData layoutId must be integer, but found: ", - layoutId); - } - if (!isInt(aliasId)) { - logger.error( - "isWaitingForFullAliasLayoutData aliasId must be integer, but found: ", - aliasId); - } - - var val = this._waitingFullAliasLayoutDataById[layoutId+"-"+aliasId]; - if (val==null) { - return false; - } - return val; -} - -/** - * Sets waitingForAliasData flag that monitors if we are waiting for the data - * about aliases from server. - * - * @param value - * new value of the waitingForAliasData field - */ -ServerConnector.setWaitingForAliasData = function(aliasId, value) { - if (isInt(aliasId)) { - var oldVal = this._waitingForAliasDataByAliasId[aliasId]; - this._waitingForAliasDataByAliasId[aliasId] = value; - if (value === true) { - if (oldVal !== true) { - this._waitingForAliasData++; - } - } else if (value === false) { - if (oldVal === true) { - this._waitingForAliasData--; - } - } else { - logger.error("WaitingForAliasData value must be boolean, but found: ", - value); - } - } else { - logger.error("WaitingForAliasData aliasId must be integer, but found: ", - aliasId); - } -}; - -/** - * Sets waitingForReactionLayoutData flag that monitors if we are waiting for - * the data about reactions in a layout from server. - * - * @param value - * new value of the waitingForReactionLayoutData field - */ -ServerConnector.setWaitingForReactionLayoutData = function(layoutId, value) { - if (isInt(layoutId)) { - var oldVal = this._waitingForReactionLayoutDataByLayoutId[layoutId]; - this._waitingForReactionLayoutDataByLayoutId[layoutId] = value; - if (value === true) { - if (oldVal !== true) { - this._waitingForReactionLayoutData++; - } - } else if (value === false) { - if (oldVal === true) { - this._waitingForReactionLayoutData--; - } - } else { - logger.error( - "WaitingForReactionLayoutData value must be boolean, but found: ", - value); - } - } else { - logger.error( - "WaitingForReactionLayoutData layoutId must be integer, but found: ", - layoutId); - } -}; -/** - * Sets waitingForReactionData flag that monitors if we are waiting for the data - * about reactions from server. - * - * @param value - * new value of the waitingForReactionData field - */ -ServerConnector.setWaitingForReactionData = function(reactionId, value) { - if (isInt(reactionId)) { - var oldVal = this._waitingForReactionDataByReactionId[reactionId]; - this._waitingForReactionDataByReactionId[reactionId] = value; - if (value === true) { - if (oldVal !== true) { - this._waitingForReactionData++; - } - } else if (value === false) { - if (oldVal === true) { - this._waitingForReactionData--; - } - } else { - logger.error("WaitingForReactionData value must be boolean, but found: ", - value); - } - } else { - logger.error( - "WaitingForReactionData reactionId must be integer, but found: ", - reactionId); - } -}; - -ServerConnector.setCustomMap = function(customMap) { - this._customMap = customMap; -}; - -ServerConnector.getCustomMap = function() { - return this._customMap; -}; - -ServerConnector.addAliasesForLayout = function(layoutId, jsonAliases) { - this.setWaitingForAliasLayoutData(parseInt(layoutId), false); - this.getCustomMap().addAliasesForLayout(layoutId, jsonAliases); -}; - -ServerConnector.updateAliasesForLayout = function(layoutId, jsonAliases) { - var arr = JSON.parse(jsonAliases); - for (var i=0;i<arr.length;i++) { - this.setWaitingForFullAliasLayoutData(parseInt(layoutId), parseInt(arr[i].idObject), false); - } - this.getCustomMap().updateAliasesForLayout(layoutId, jsonAliases); -}; - -ServerConnector.addAliases = function(aliases) { - for (var i = 0; i < aliases.length; i++) { - this.setWaitingForAliasData(parseInt(aliases[i].idObject), false); - } - this.getCustomMap().addAliases(aliases); -}; - -ServerConnector.addReactionsForLayout = function(layoutId, jsonReactions) { - this.setWaitingForReactionLayoutData(parseInt(layoutId), false); - this.getCustomMap().addReactionsForLayout(layoutId, jsonReactions); -}; - -ServerConnector.addReactions = function(jsonReactions) { - var arr = JSON.parse(jsonReactions); - for (var i = 0; i < arr.length; i++) { - this.setWaitingForReactionData(parseInt(arr[i].idObject), false); - } - this.getCustomMap().addReactions(jsonReactions); -}; - -ServerConnector.searchByCoord = function(modelId, latLngCoordinates) { - _searchByCoord([ { - name : 'submodelId', - value : modelId - }, { - name : 'latCoord', - value : latLngCoordinates.lat() - }, { - name : 'lngCoord', - value : latLngCoordinates.lng() - } ]); -}; - -ServerConnector.requestUpdateCommentList = function(modelId, latLngCoordinates) { - _updateCommentList([ { - name : 'submodelId', - value : modelId - }, { - name : 'latCoord', - value : latLngCoordinates.lat() - }, { - name : 'lngCoord', - value : latLngCoordinates.lng() - } ]); -}; - -ServerConnector.sendReferenceGenomeDetailRequest = function(type, version) { - logger.debug("Send request", type, version); - _sendReferenceGenomeDetailRequest([ { - name : 'type', - value : type - }, { - name : 'version', - value : version - }]); -}; -ServerConnector.updateReferenceGenomeData = function(organismId, type, version, jsonObj) { - this.getCustomMap().updateReferenceGenome(type, version, jsonObj); -}; - +/** + * This object contains methods that will communicate with server. + */ +ServerConnector = new Object(); + +/** + * List of {@link OverlayCollection} that was added to the server connector. It + * describes list of all overlays that communicate with server. + */ +ServerConnector._overlays = []; + +/** + * Associative array with methods that should be used for comunication of the + * {@link OverlayCollection} from _overlays field. + */ +ServerConnector._overlayMethods = []; + +/** + * Form where fields passed to/from server are stored. + */ +ServerConnector.formIdentifier = "_gmapForm"; + +/** + * Variable describing when was last transmition of data (location of the map, + * zoom level, etc.) to the server session. + */ +ServerConnector.lastActualization = 0; + +ServerConnector._customMap = null; + +/** + * Number of requests send to server about AliasLayout data. + */ +ServerConnector._waitingForAliasLayoutData = 0; +ServerConnector._waitingForAliasLayoutDataByLayoutId = []; + +ServerConnector._waitingFullAliasLayoutData = 0; +ServerConnector._waitingFullAliasLayoutDataById = []; + +/** + * Number of requests send to server about AliasData data. + */ +ServerConnector._waitingForAliasData = 0; +ServerConnector._waitingForAliasDataByAliasId = []; + +/** + * Number of requests send to server about ReactionLayout data. + */ +ServerConnector._waitingForReactionLayoutData = 0; +ServerConnector._waitingForReactionLayoutDataByLayoutId = []; + +/** + * Number of requests send to server about ReactionData data. + */ +ServerConnector._waitingForReactionData = 0; +ServerConnector._waitingForReactionDataByReactionId = []; + +/** + * Get name of the file that should be used as logo. + */ +ServerConnector.getLogoImg = function() { + return document.getElementById('logoImg').value; +}; + +/** + * Get link to the website that should be accessed when clicking on + * {@link ServerConnector.getLogoImg}. + */ +ServerConnector.getLogoLink = function() { + return document.getElementById('logoLink').value; +}; + +/** + * Get zoom level of the {@link CustomMap} at which it was last browsed. + */ +ServerConnector.getZoomLevel = function() { + return document.getElementById(ServerConnector.formIdentifier + ':zoomLevel').value; +}; + +/** + * Set zoom level for {@link CustomMap} on the server side. + */ +ServerConnector.setZoomLevel = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':zoomLevel').value = "" + + value; +}; + +/** + * Set x coordinate for {@link CustomMap} on the server side. + */ +ServerConnector.setCenterCoordinateX = function(value) { + document + .getElementById(ServerConnector.formIdentifier + ':centerCoordinateX').value = "" + + value; +}; + +/** + * Get x coordinate of the {@link CustomMap} at which it was last browsed. + */ +ServerConnector.getCenterCoordinateX = function() { + var result = parseFloat(document + .getElementById(ServerConnector.formIdentifier + ':centerCoordinateX').value); + return result; +}; + +/** + * Set y coordinate for {@link CustomMap} on the server side. + */ +ServerConnector.setCenterCoordinateY = function(value) { + document + .getElementById(ServerConnector.formIdentifier + ':centerCoordinateY').value = "" + + value; +}; + +/** + * Get y coordinate of the {@link CustomMap} at which it was last browsed. + */ +ServerConnector.getCenterCoordinateY = function() { + var result = parseFloat(document + .getElementById(ServerConnector.formIdentifier + ':centerCoordinateY').value); + return result; +}; + +/** + * Set layout that is currently browsed for {@link CustomMap} on the server + * side. + */ +ServerConnector.setSelectedLayout = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':selectedLayout').value = "" + + value; +}; +/** + * Sets list of layouts visualized by javascript. + */ +ServerConnector.setVisibleLayouts = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':visibleLayouts').value = value; +} + +/** + * Get layout of the {@link CustomMap} which was last browsed. + */ +ServerConnector.getSelectedLayout = function() { + return document.getElementById(ServerConnector.formIdentifier + + ':selectedLayout').value; +}; + +/** + * Sends data about coordinates/zoom level etc. to the server. Method checks if + * the transmition is not done to often (at most once per second) + */ +ServerConnector.actualizeSessionData = function(value) { + var timestamp = new Date().getTime(); + // we send the data with at least 1 second time distance + if (timestamp > ServerConnector.lastActualization) { + ServerConnector.lastActualization = timestamp + 1000; + setTimeout(function() { + ServerConnector.actualizeParams(); + }, 1000); + } +}; + +/** + * Sends data about coordinates/zoom level etc. to the server. Sending is + * performed immediatelly. + * + * @see ServerConnector.actualizeSessionData + */ +ServerConnector.actualizeParams = function() { + actualizeParams(); +}; + +/** + * Sets search query that will be handled by server. + */ +ServerConnector.setSearchQuery = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':mapParam').value = "" + + value; +}; + +/** + * Sets data mining query that will be handled by server. + */ +ServerConnector.setDataMiningQuery = function(value) { + document.getElementById(ServerConnector.formIdentifier + + ':missingConnectionParam').value = "" + value; +}; + +/** + * Sets drug search query that will be handled by server. + */ +ServerConnector.setDrugQuery = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':drugParam').value = "" + + value; +}; + +/** + * Sets comment query that will be handled by server. + */ +ServerConnector.setCommentQuery = function(value) { + logger.error("ServerConnector.setCommentQuery: Not implemented"); + document.getElementById(ServerConnector.formIdentifier + ':commentParam').value = "" + + value; +}; + +/** + * Sets selected polygon. This might be in futer used oto extract/analyze data + * in the polygon by the server side. + */ +ServerConnector.setSelectedPolygon = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':selectedPolygon').value = "" + + value; + document.getElementById(ServerConnector.formIdentifier + + ':selectedDrugPolygon').value = "" + value; +}; + +/** + * Sets identifier of the model where selected polygon (@see + * ServerConnector.setSelectedPolygon) was selected. + */ +ServerConnector.setExportModelId = function(value) { + document.getElementById(ServerConnector.formIdentifier + ':exportModelId').value = "" + + value; +}; + +/** + * Sets flag marking if the comments are visible or not. + */ +ServerConnector.setShowComments = function(value) { + _setShowComments([ { + name : 'showComments', + value : value + } ]); +}; + +/** + * Search for similar data mining entries on the map. + */ +ServerConnector.showSimilarDataMining = function(param) { + document.getElementById(ServerConnector.formIdentifier + ':geneName').value = "" + + param; + searchMissingConnections(); +}; + +/** + * Ask server to send list of aliases that were highlighted in the layout with a + * given identifier. + * + * @param identifier + * of the layout + */ +ServerConnector.retreiveActiveAliasesForLayout = function(identifier) { + this.setWaitingForAliasLayoutData(parseInt(identifier), true); + _retreiveActiveAliasesForLayout([ { + name : 'layoutId', + value : identifier + } ]); +}; + +ServerConnector.retreiveFullAliasesForLayout = function(layoutId, aliasId, modelId) { + this.setWaitingForFullAliasLayoutData(parseInt(layoutId),parseInt(aliasId), true); + _retreiveFullAliasesForLayout([ { + name : 'layoutId', + value : layoutId, + }, { + name : 'ids', + value : JSON.stringify([[modelId, aliasId]]), + }, + ]); +}; + +/** + * Ask server to send list of reactions that were highlighted in the layout with + * a given identifier. + * + * @param identifier + * of the layout + */ +ServerConnector.retreiveActiveReactionsForLayout = function(identifier) { + this.setWaitingForReactionLayoutData(parseInt(identifier), true); + _retreiveActiveReactionsForLayout([ { + name : 'layoutId', + value : identifier + } ]); +}; + +/** + * Ask server to send list of light information about aliases. + * + * @param ids + * list of alias identifiers, every identifier is an array with two + * values: modelId, aliasId + */ +ServerConnector.retreiveLightAliases = function(ids) { + for (var i = 0; i < ids.length; i++) { + this.setWaitingForAliasData(parseInt(ids[i][1]), true); + } + _retreiveLightAliases([ { + name : 'ids', + value : JSON.stringify(ids) + } ]); +}; + +/** + * Ask server to send list of full information about aliases. + * + * @param ids + * list of alias identifiers, every identifier is an array with two + * values: modelId, aliasId + */ +ServerConnector.retreiveFullAliases = function(ids) { + _retreiveFullAliases([ { + name : 'ids', + value : JSON.stringify(ids) + } ]); +}; + +/** + * Ask server to send list of light information about reactions. + * + * @param ids + * list of reaction identifiers, every identifier is an array with + * two values: modelId, reactionId + */ +ServerConnector.retreiveLightReactions = function(ids) { + for (var i = 0; i < ids.length; i++) { + this.setWaitingForReactionData(parseInt(ids[i][1]), true); + } + _retreiveLightReactions([ { + name : 'ids', + value : JSON.stringify(ids) + } ]); +}; + +/** + * Sends request to server to refresh data for overlay with a given name. + * + * @param overlayName + * name of the overlay + */ +ServerConnector.sendRefreshRequest = function(overlayName) { + var functions = ServerConnector._overlayMethods[overlayName]; + if (functions != null) { + var refreshFunction = functions.refreshFunction; + if (refreshFunction != null) { + refreshFunction(); + } else { + logger.warn("Refresh function for " + overlayName + " doesn't exist"); + } + } else { + logger.warn("[Refresh function] Unknown overlay: ", overlayName); + } +}; + +/** + * Adds {@link OverlayCollection} to ServerConnector. + */ +ServerConnector.addOverlayCollection = function(overlay) { + if (ServerConnector._overlayMethods[overlay.name] != null) { + if (ServerConnector._overlays[overlay.name] != null) { + logger.warn("Overlay with name " + overlay.name + " already added"); + return; + } + ServerConnector._overlays[overlay.name] = overlay; + if (ServerConnector._overlayMethods[overlay.name].initFunction != null) { + ServerConnector._overlayMethods[overlay.name].initFunction(); + } else { + logger.warn("Cannot initialize overlay: " + overlay); + } + } else { + logger.warn("Unknown overlay: ", overlay); + } +}; + +/** + * Method that should be called by server to update data in overlay. + * + * @param overlayName + * name of overlay for which the data is sent + * @param data + * new data for overlay + * @param fitBounds + * should the map call fitBounds after update + */ +ServerConnector.updateOverlayCollection = function(overlayName, data, fitBounds) { + logger.debug("Updating: " + overlayName); + var overlay = ServerConnector._overlays[overlayName]; + if (overlay != null) { + overlay.updateOverlays(data, fitBounds); + } else { + logger.warn("Overlay " + overlayName + + " cannot be updated. It doesn't exist"); + } +} + +/** + * Name of the overlay for 'search' overlay. + */ +ServerConnector.SEARCH_OVERLAY_NAME = 'search'; + +/** + * Name of the overlay for 'data mining' overlay. + */ +ServerConnector.DATA_MINING_OVERLAY_NAME = 'missingConnection'; + +/** + * Name of the overlay for 'drug' overlay. + */ +ServerConnector.DRUG_OVERLAY_NAME = 'drug'; + +/** + * Name of the overlay for 'chemical' overlay. + */ +ServerConnector.CHEMICAL_OVERLAY_NAME = 'chemical'; + +/** + * Name of the overlay for 'comment' overlay. + */ +ServerConnector.COMMENT_OVERLAY_NAME = 'comment'; + +/** + * Name of the overlay for 'mirna' overlay. + */ +ServerConnector.MI_RNA_OVERLAY_NAME = 'mirna'; + +/** + * Register 'search' overlay on the server. + */ +ServerConnector.registerSearchOverlay = function() { + _registerSearchOverlayCollection([ { + name : "overlayName", + value : ServerConnector.SEARCH_OVERLAY_NAME, + } ]); +}; + +/** + * Sends request to the server to refresh data in 'search' overlay. + */ +ServerConnector.refreshSearchOverlay = function() { + _refreshSearchOverlayCollection(); +}; + +/** + * Clear data related to 'search' overlay.. + */ +ServerConnector.clearSearchOverlay = function() { + _clearSearchOverlayCollection(); +}; + +/** + * Register 'data mining' overlay on the server. + */ +ServerConnector.registerDataMiningOverlay = function() { + _registerMissingConnectionOverlayCollection([ { + name : "overlayName", + value : ServerConnector.DATA_MINING_OVERLAY_NAME, + } ]); +}; + +/** + * Sends request to the server to refresh data in 'data mining' overlay. + */ +ServerConnector.refreshDataMiningOverlay = function() { + _refreshMissingConnectionOverlayCollection(); +}; + +/** + * Clear data related to 'data mining' overlay. + */ +ServerConnector.clearDataMiningOverlay = function() { + _clearMissingConnectionOverlayCollection(); +}; + +/** + * Register 'drug' overlay on the server. + */ +ServerConnector.registerDrugOverlay = function() { + _registerDrugOverlayCollection([ { + name : "overlayName", + value : ServerConnector.DRUG_OVERLAY_NAME, + } ]); +}; + +ServerConnector.requestDrugDetailDataFunction = function(identfiedElement, id) { + logger.debug("Requesting drug details: ", identfiedElement, id); + _requestDrugDetailDataFunction([ { + name : "searchResultIdentifier", + value : id, + }, { + name : "objectIdentifier", + value : identfiedElement.getId(), + }, { + name : "modelIdentifier", + value : identfiedElement.getModelId(), + }, { + name : "type", + value : identfiedElement.getType(), + } ]); +}; +ServerConnector.requestCommentDetailDataFunction = function(identfiedElement, + id) { + _requestCommentDetailDataFunction([ { + name : "searchResultIdentifier", + value : id, + }, { + name : "objectIdentifier", + value : identfiedElement.getId(), + }, { + name : "modelIdentifier", + value : identfiedElement.getModelId(), + }, { + name : "type", + value : identfiedElement.getType(), + } ]); +}; + +/** + * Sends request to the server to refresh data in 'drug' overlay. + */ +ServerConnector.refreshDrugOverlay = function() { + _refreshDrugOverlayCollection(); +}; + +/** + * Clear data related to 'drug' overlay. + */ +ServerConnector.clearDrugOverlay = function() { + _clearDrugOverlayCollection(); +}; + +ServerConnector.registerChemicalOverlay = function() { + _registerChemicalOverlayCollection([ { + name : "overlayName", + value : ServerConnector.CHEMICAL_OVERLAY_NAME, + } ]); +}; + +ServerConnector.requestChemicalDetailDataFunction = function(identfiedElement, + id) { + _requestChemicalDetailDataFunction([ { + name : "searchResultIdentifier", + value : id, + }, { + name : "objectIdentifier", + value : identfiedElement.getId(), + }, { + name : "modelIdentifier", + value : identfiedElement.getModelId(), + }, { + name : "type", + value : identfiedElement.getType(), + } ]); +}; + +/** + * Sends request to the server to refresh data in 'drug' overlay. + */ +ServerConnector.refreshChemicalOverlay = function() { + _refreshChemicalOverlayCollection(); +}; + +/** + * Clear data related to 'chemical' overlay. + */ +ServerConnector.clearChemicalOverlay = function() { + _clearChemicalOverlayCollection(); +}; + +/** + * Register 'comment' overlay on the server. + */ +ServerConnector.registerCommentOverlay = function() { + _registerCommentOverlayCollection([ { + name : "overlayName", + value : ServerConnector.COMMENT_OVERLAY_NAME, + } ]); +}; + +/** + * Sends request to the server to refresh data in 'comment' overlay. + */ +ServerConnector.refreshCommentOverlay = function() { + _refreshCommentOverlayCollection(); +}; + +/** + * Clear data related to 'comment' overlay. + */ +ServerConnector.clearCommentOverlay = function() { + _clearCommentOverlayCollection(); +}; + +/** + * Clear data related to 'data mining' overlay. + */ +ServerConnector.clearDataMiningOverlay = function() { + _clearMissingConnectionOverlayCollection(); +}; + +/** + * Register 'drug' overlay on the server. + */ +ServerConnector.registerMiRnaOverlay = function() { + _registerMiRnaOverlayCollection([ { + name : "overlayName", + value : ServerConnector.MI_RNA_OVERLAY_NAME, + } ]); +}; + +ServerConnector.requestMiRnaDetailDataFunction = function(identfiedElement, id) { + _requestMiRnaDetailDataFunction([ { + name : "searchResultIdentifier", + value : id, + }, { + name : "objectIdentifier", + value : identfiedElement.getId(), + }, { + name : "modelIdentifier", + value : identfiedElement.getModelId(), + }, { + name : "type", + value : identfiedElement.getType(), + } ]); +}; + +/** + * Sends request to the server to refresh data in 'drug' overlay. + */ +ServerConnector.refreshMiRnaOverlay = function() { + _refreshMiRnaOverlayCollection(); +}; + +/** + * Clear data related to 'mirna' overlay. + */ +ServerConnector.clearMiRnaOverlay = function() { + _clearMiRnaOverlayCollection(); +}; + +/** + * Define pack of methods for 'search' overlay. + */ +ServerConnector._overlayMethods[ServerConnector.SEARCH_OVERLAY_NAME] = { + initFunction : ServerConnector.registerSearchOverlay, + refreshFunction : ServerConnector.refreshSearchOverlay, + clearFunction : ServerConnector.clearSearchOverlay, +}; + +/** + * Define pack of methods for 'data minig' overlay. + */ +ServerConnector._overlayMethods[ServerConnector.DATA_MINING_OVERLAY_NAME] = { + initFunction : ServerConnector.registerDataMiningOverlay, + refreshFunction : ServerConnector.refreshDataMiningOverlay, + clearFunction : ServerConnector.clearDataMiningOverlay, +}; + +/** + * Define pack of methods for 'drug' overlay. + */ +ServerConnector._overlayMethods[ServerConnector.DRUG_OVERLAY_NAME] = { + initFunction : ServerConnector.registerDrugOverlay, + refreshFunction : ServerConnector.refreshDrugOverlay, + clearFunction : ServerConnector.clearDrugOverlay, + requestDetailDataFunction : ServerConnector.requestDrugDetailDataFunction, +}; + +/** + * Define pack of methods for 'chemical' overlay. + */ +ServerConnector._overlayMethods[ServerConnector.CHEMICAL_OVERLAY_NAME] = { + initFunction : ServerConnector.registerChemicalOverlay, + refreshFunction : ServerConnector.refreshChemicalOverlay, + clearFunction : ServerConnector.clearChemicalOverlay, + requestDetailDataFunction : ServerConnector.requestChemicalDetailDataFunction, +}; + +/** + * Define pack of methods for 'comment' overlay. + */ +ServerConnector._overlayMethods[ServerConnector.COMMENT_OVERLAY_NAME] = { + initFunction : ServerConnector.registerCommentOverlay, + refreshFunction : ServerConnector.refreshCommentOverlay, + clearFunction : ServerConnector.clearCommentOverlay, + requestDetailDataFunction : ServerConnector.requestCommentDetailDataFunction, +}; + +ServerConnector._overlayMethods[ServerConnector.MI_RNA_OVERLAY_NAME] = { + initFunction : ServerConnector.registerMiRnaOverlay, + refreshFunction : ServerConnector.refreshMiRnaOverlay, + clearFunction : ServerConnector.clearMiRnaOverlay, + requestDetailDataFunction : ServerConnector.requestMiRnaDetailDataFunction, +}; + +ServerConnector.sendClearRequest = function(overlayName) { + var functions = ServerConnector._overlayMethods[overlayName]; + if (functions != null) { + var clearFunction = functions.clearFunction; + if (clearFunction != null) { + clearFunction(); + } else { + logger.warn("Clear function for " + overlayName + " doesn't exist"); + } + } else { + logger.warn("[Clear function] Unknown overlay: ", overlayName); + } +}; + +ServerConnector.setOverlayResultIds = function(overlayName, ids) { + var overlay = this._overlays[overlayName]; + if (overlay != null) { + overlay.setResultsIds(ids); + } else { + logger.warn("Overlay '" + overlayName + "' doesn't exist"); + } +}; + +ServerConnector.sendOverlayDetailDataRequest = function(overlayName, + identifiedElement, general) { + var overlay = ServerConnector._overlays[overlayName]; + if (overlay == null) { + logger.warn("Unknown overlay: " + overlayName); + return; + } + var functions = ServerConnector._overlayMethods[overlayName]; + if (functions != null) { + var requestDetailDataFunction = functions.requestDetailDataFunction; + if (requestDetailDataFunction != null) { + var missingData = overlay.getMissingDetailDataIds(identifiedElement, + general); + if (missingData.length == 0) { + logger + .warn( + "request of missing data called for empty data set... overlay name = ", + overlayName, "general: ", general); + } + for (var i = 0; i < missingData.length; i++) { + requestDetailDataFunction(identifiedElement, missingData[i]); + } + } else { + logger.warn("Request detail data function for " + overlayName + + " doesn't exist"); + } + } else { + logger.warn("[Clear function] Unknown overlay: ", overlayName); + } + +}; + +ServerConnector.updateOverviewElementDetailData = function(overlayName, + searchResultIdentifier, identifiedElement, data) { + var overlay = this._overlays[overlayName]; + if (overlay != null) { + overlay.updateOverviewElementDetailData(identifiedElement, + searchResultIdentifier, data); + } else { + logger.warn("Overlay '" + overlayName + "' doesn't exist"); + } +}; + +/** + * Returns <code>true</code> if we are waiting for any kind of data from + * server, <code>false</code> otherwise. + * + * @returns {Boolean}: <code>true</code> if we are waiting for any kind of + * data from server, <code>false</code> otherwise. + */ +ServerConnector.isWaitingForData = function() { + var result = (this._waitingForAliasLayoutData != 0) || // + (this._waitingForAliasData != 0) || // + (this._waitingForReactionLayoutData != 0) || // + (this._waitingForReactionData != 0); + return result; +}; + +/** + * Sets waitingForAliasLayoutData flag that monitors if we are waiting for the + * data about aliases in a layout from server. + * + * @param value + * new value of the waitingForAliasLayoutData field + */ +ServerConnector.setWaitingForAliasLayoutData = function(layoutId, value) { + if (isInt(layoutId)) { + var oldVal = this._waitingForAliasLayoutDataByLayoutId[layoutId]; + this._waitingForAliasLayoutDataByLayoutId[layoutId] = value; + if (value === true) { + if (oldVal !== true) { + this._waitingForAliasLayoutData++; + } + } else if (value === false) { + if (oldVal === true) { + this._waitingForAliasLayoutData--; + } + } else { + logger + .error( + "WaitingForAliasLayoutData value must be boolean, but found: ", + value); + } + } else { + logger.error( + "WaitingForAliasLayoutData layoutId must be integer, but found: ", + layoutId); + } +} + +ServerConnector.setWaitingForFullAliasLayoutData = function(layoutId, aliasId, value) { + if (!isInt(layoutId)) { + logger.error( + "setWaitingForFullAliasLayoutData layoutId must be integer, but found: ", + layoutId); + } + if (!isInt(aliasId)) { + logger.error( + "setWaitingForFullAliasLayoutData aliasId must be integer, but found: ", + aliasId); + } + + var oldVal = this._waitingFullAliasLayoutDataById[layoutId+"-"+aliasId]; + this._waitingFullAliasLayoutDataById[layoutId+"-"+aliasId] = value; + if (value === true) { + if (oldVal !== true) { + this._waitingFullAliasLayoutData++; + } + } else if (value === false) { + if (oldVal === true) { + this._waitingFullAliasLayoutData--; + } + } else { + logger + .error( + "setWaitingForFullAliasLayoutData value must be boolean, but found: ", + value); + } +} + +ServerConnector.isWaitingForFullAliasLayoutData = function(layoutId, aliasId) { + if (!isInt(layoutId)) { + logger.error( + "isWaitingForFullAliasLayoutData layoutId must be integer, but found: ", + layoutId); + } + if (!isInt(aliasId)) { + logger.error( + "isWaitingForFullAliasLayoutData aliasId must be integer, but found: ", + aliasId); + } + + var val = this._waitingFullAliasLayoutDataById[layoutId+"-"+aliasId]; + if (val==null) { + return false; + } + return val; +} + +/** + * Sets waitingForAliasData flag that monitors if we are waiting for the data + * about aliases from server. + * + * @param value + * new value of the waitingForAliasData field + */ +ServerConnector.setWaitingForAliasData = function(aliasId, value) { + if (isInt(aliasId)) { + var oldVal = this._waitingForAliasDataByAliasId[aliasId]; + this._waitingForAliasDataByAliasId[aliasId] = value; + if (value === true) { + if (oldVal !== true) { + this._waitingForAliasData++; + } + } else if (value === false) { + if (oldVal === true) { + this._waitingForAliasData--; + } + } else { + logger.error("WaitingForAliasData value must be boolean, but found: ", + value); + } + } else { + logger.error("WaitingForAliasData aliasId must be integer, but found: ", + aliasId); + } +}; + +/** + * Sets waitingForReactionLayoutData flag that monitors if we are waiting for + * the data about reactions in a layout from server. + * + * @param value + * new value of the waitingForReactionLayoutData field + */ +ServerConnector.setWaitingForReactionLayoutData = function(layoutId, value) { + if (isInt(layoutId)) { + var oldVal = this._waitingForReactionLayoutDataByLayoutId[layoutId]; + this._waitingForReactionLayoutDataByLayoutId[layoutId] = value; + if (value === true) { + if (oldVal !== true) { + this._waitingForReactionLayoutData++; + } + } else if (value === false) { + if (oldVal === true) { + this._waitingForReactionLayoutData--; + } + } else { + logger.error( + "WaitingForReactionLayoutData value must be boolean, but found: ", + value); + } + } else { + logger.error( + "WaitingForReactionLayoutData layoutId must be integer, but found: ", + layoutId); + } +}; +/** + * Sets waitingForReactionData flag that monitors if we are waiting for the data + * about reactions from server. + * + * @param value + * new value of the waitingForReactionData field + */ +ServerConnector.setWaitingForReactionData = function(reactionId, value) { + if (isInt(reactionId)) { + var oldVal = this._waitingForReactionDataByReactionId[reactionId]; + this._waitingForReactionDataByReactionId[reactionId] = value; + if (value === true) { + if (oldVal !== true) { + this._waitingForReactionData++; + } + } else if (value === false) { + if (oldVal === true) { + this._waitingForReactionData--; + } + } else { + logger.error("WaitingForReactionData value must be boolean, but found: ", + value); + } + } else { + logger.error( + "WaitingForReactionData reactionId must be integer, but found: ", + reactionId); + } +}; + +ServerConnector.setCustomMap = function(customMap) { + this._customMap = customMap; +}; + +ServerConnector.getCustomMap = function() { + return this._customMap; +}; + +ServerConnector.addAliasesForLayout = function(layoutId, jsonAliases) { + this.setWaitingForAliasLayoutData(parseInt(layoutId), false); + this.getCustomMap().addAliasesForLayout(layoutId, jsonAliases); +}; + +ServerConnector.updateAliasesForLayout = function(layoutId, jsonAliases) { + var arr = JSON.parse(jsonAliases); + for (var i=0;i<arr.length;i++) { + this.setWaitingForFullAliasLayoutData(parseInt(layoutId), parseInt(arr[i].idObject), false); + } + this.getCustomMap().updateAliasesForLayout(layoutId, jsonAliases); +}; + +ServerConnector.addAliases = function(aliases) { + for (var i = 0; i < aliases.length; i++) { + this.setWaitingForAliasData(parseInt(aliases[i].idObject), false); + } + this.getCustomMap().addAliases(aliases); +}; + +ServerConnector.addReactionsForLayout = function(layoutId, jsonReactions) { + this.setWaitingForReactionLayoutData(parseInt(layoutId), false); + this.getCustomMap().addReactionsForLayout(layoutId, jsonReactions); +}; + +ServerConnector.addReactions = function(jsonReactions) { + var arr = JSON.parse(jsonReactions); + for (var i = 0; i < arr.length; i++) { + this.setWaitingForReactionData(parseInt(arr[i].idObject), false); + } + this.getCustomMap().addReactions(jsonReactions); +}; + +ServerConnector.searchByCoord = function(modelId, latLngCoordinates) { + _searchByCoord([ { + name : 'submodelId', + value : modelId + }, { + name : 'latCoord', + value : latLngCoordinates.lat() + }, { + name : 'lngCoord', + value : latLngCoordinates.lng() + } ]); +}; + +ServerConnector.requestUpdateCommentList = function(modelId, latLngCoordinates) { + _updateCommentList([ { + name : 'submodelId', + value : modelId + }, { + name : 'latCoord', + value : latLngCoordinates.lat() + }, { + name : 'lngCoord', + value : latLngCoordinates.lng() + } ]); +}; + +ServerConnector.sendReferenceGenomeDetailRequest = function(type, version) { + logger.debug("Send request", type, version); + _sendReferenceGenomeDetailRequest([ { + name : 'type', + value : type + }, { + name : 'version', + value : version + }]); +}; +ServerConnector.updateReferenceGenomeData = function(organismId, type, version, jsonObj) { + this.getCustomMap().updateReferenceGenome(type, version, jsonObj); +}; + +ServerConnector.getMinOverlayColorInt = function() { + var color = document.getElementById("overlayConfigForm:userMinColor").value; + if (color=="") { + color = document.getElementById("overlayConfigForm:systemMinColor").value; + } + color = parseInt(color, 16); + var color = (color & 0xFFFFFF); + return color; +}; + +ServerConnector.getMaxOverlayColorInt = function() { + var color = document.getElementById("overlayConfigForm:userMaxColor").value; + if (color=="") { + color = document.getElementById("overlayConfigForm:systemMaxColor").value; + } + color = parseInt(color, 16); + var color = (color & 0xFFFFFF); + return color; +}; + + diff --git a/web/src/test/java/lcsb/mapviewer/AllWebTests.java b/web/src/test/java/lcsb/mapviewer/AllWebTests.java new file mode 100644 index 0000000000000000000000000000000000000000..c394dd619eb3f3fa9c10ec0ff7695787e7accc97 --- /dev/null +++ b/web/src/test/java/lcsb/mapviewer/AllWebTests.java @@ -0,0 +1,16 @@ +package lcsb.mapviewer; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +import lcsb.mapviewer.bean.AllBeanTests; +import lcsb.mapviewer.validator.AllValidatorTests; + +@RunWith(Suite.class) +@SuiteClasses({ AllBeanTests.class, // + AllValidatorTests.class,// +}) +public class AllWebTests { + +} diff --git a/web/src/test/java/lcsb/mapviewer/bean/AbstractManagedBeanTest.java b/web/src/test/java/lcsb/mapviewer/bean/AbstractManagedBeanTest.java index 2c2d3e525f8fd134aaca919705beb986b23dfa87..48b0cf4118c75e2f37da185a05f18776b994ac9e 100644 --- a/web/src/test/java/lcsb/mapviewer/bean/AbstractManagedBeanTest.java +++ b/web/src/test/java/lcsb/mapviewer/bean/AbstractManagedBeanTest.java @@ -1,117 +1,120 @@ -package lcsb.mapviewer.bean; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.events.Event; -import lcsb.mapviewer.events.Listener; - -import org.apache.commons.lang3.mutable.MutableInt; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class AbstractManagedBeanTest { - - class AbstractManagedBeanMock extends AbstractManagedBean { - - /** - * - */ - private static final long serialVersionUID = 1L; - - @Override - public void clear() { - } - - public void callMockEvent(String data) { - callListeners(new EventMock(data)); - } - - @Override - public void init() { - // TODO Auto-generated method stub - - } - - }; - - class EventMock extends Event { - String data = ""; - - public EventMock(String d) { - data = d; - } - } - - AbstractManagedBeanMock mockBean; - - @Before - public void setUp() throws Exception { - mockBean = new AbstractManagedBeanMock(); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public void testListeners() throws Exception { - final MutableInt called = new MutableInt(0); - try { - Listener<EventMock> listener = new Listener<EventMock>(EventMock.class) { - /** - * - */ - private static final long serialVersionUID = 1L; - - @Override - protected void handle(EventMock event) { - called.add(1); - } - }; - - mockBean.registerListener(listener); - assertEquals(new MutableInt(0), called); - mockBean.callMockEvent("hi"); - assertEquals(new MutableInt(1), called); - mockBean.callMockEvent("hi2"); - assertEquals(new MutableInt(2), called); - mockBean.unregisterListener(listener); - mockBean.callMockEvent("hi3"); - assertEquals(new MutableInt(2), called); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } - - @Test - public void testRemoveListeners() throws Exception { - final MutableInt called = new MutableInt(0); - try { - Listener<EventMock> listener = new Listener<EventMock>(EventMock.class) { - - /** - * - */ - private static final long serialVersionUID = 1L; - - @Override - protected void handle(EventMock event) { - called.add(1); - } - }; - - try { - mockBean.unregisterListener(listener); - fail("Exception expected"); - } catch (InvalidArgumentException e) { - - } - } catch (Exception e) { - e.printStackTrace(); - throw e; - } - } -} +package lcsb.mapviewer.bean; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import org.apache.commons.lang3.mutable.MutableInt; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.events.Event; +import lcsb.mapviewer.events.Listener; + +public class AbstractManagedBeanTest { + Logger logger = Logger.getLogger(AbstractManagedBeanTest.class); + + class AbstractManagedBeanMock extends AbstractManagedBean { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + public void clear() { + } + + public void callMockEvent(String data) { + callListeners(new EventMock(data)); + } + + @Override + public void init() { + // TODO Auto-generated method stub + + } + + }; + + class EventMock extends Event { + String data = ""; + + public EventMock(String d) { + data = d; + } + } + + AbstractManagedBeanMock mockBean; + + @Before + public void setUp() throws Exception { + mockBean = new AbstractManagedBeanMock(); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testListeners() throws Exception { + final MutableInt called = new MutableInt(0); + try { + Listener<EventMock> listener = new Listener<EventMock>(EventMock.class) { + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + protected void handle(EventMock event) { + called.add(1); + } + }; + + mockBean.registerListener(listener); + assertEquals(new MutableInt(0), called); + mockBean.callMockEvent("hi"); + assertEquals(new MutableInt(1), called); + mockBean.callMockEvent("hi2"); + assertEquals(new MutableInt(2), called); + mockBean.unregisterListener(listener); + mockBean.callMockEvent("hi3"); + assertEquals(new MutableInt(2), called); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + @Test + public void testRemoveListeners() throws Exception { + final MutableInt called = new MutableInt(0); + try { + Listener<EventMock> listener = new Listener<EventMock>(EventMock.class) { + + /** + * + */ + private static final long serialVersionUID = 1L; + + @Override + protected void handle(EventMock event) { + called.add(1); + } + }; + + try { + mockBean.unregisterListener(listener); + fail("Exception expected"); + } catch (InvalidArgumentException e) { + + } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } +} diff --git a/web/src/test/java/lcsb/mapviewer/bean/DrugBeanTest.java b/web/src/test/java/lcsb/mapviewer/bean/DrugBeanTest.java index 21fbb10b623650d7cacc6e7394d19c2b69f2c5b3..f19ae4abf42f0a2f3953d7bb1460b78802ca4547 100644 --- a/web/src/test/java/lcsb/mapviewer/bean/DrugBeanTest.java +++ b/web/src/test/java/lcsb/mapviewer/bean/DrugBeanTest.java @@ -1,5 +1,6 @@ package lcsb.mapviewer.bean; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.Serializable; @@ -96,4 +97,15 @@ public class DrugBeanTest extends WebTestFunctions { } } + @Test + public void testFindDrug() throws Exception { + try { + drugBean.findDrug("levadopa; carbidopa"); + assertEquals(2, drugBean.getResults().size()); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + } diff --git a/web/src/test/java/lcsb/mapviewer/validator/AllValidatorTests.java b/web/src/test/java/lcsb/mapviewer/validator/AllValidatorTests.java new file mode 100644 index 0000000000000000000000000000000000000000..dd6e48a1eb63b7d82bfea487a32eea40b9d6162f --- /dev/null +++ b/web/src/test/java/lcsb/mapviewer/validator/AllValidatorTests.java @@ -0,0 +1,11 @@ +package lcsb.mapviewer.validator; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +@RunWith(Suite.class) +@SuiteClasses({ LoginValidatorTest.class }) +public class AllValidatorTests { + +} diff --git a/web/src/test/java/lcsb/mapviewer/validator/LoginValidatorTest.java b/web/src/test/java/lcsb/mapviewer/validator/LoginValidatorTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a216753326f54d1d72112c0d1691ca7cedcc03ca --- /dev/null +++ b/web/src/test/java/lcsb/mapviewer/validator/LoginValidatorTest.java @@ -0,0 +1,42 @@ +package lcsb.mapviewer.validator; + +import static org.junit.Assert.fail; + +import javax.faces.validator.ValidatorException; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.Test; + +public class LoginValidatorTest { + LoginValidator validator = new LoginValidator(); + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testCorrect() { + validator.validate(null, null, "piotr.gawron"); + } + + @Test + public void testIncorrect() { + try { + validator.validate(null, null, "piotr gawron"); + fail("Exception expected"); + } catch (ValidatorException e) { + + } + } + +}