From f49f6cc3355d7166914fd5ded743ca26b8c04b63 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <p.gawron@atcomp.pl>
Date: Mon, 17 Mar 2025 17:09:22 +0100
Subject: [PATCH] export pathway

---
 .../celldesigner/CellDesignerXmlParser.java   |   2 +-
 .../model/celldesigner/LayerXmlParser.java    |  61 +++-
 .../CellDesignerTestFunctions.java            |  15 +
 .../celldesigner/LayerXmlParserTest.java      |   5 +-
 .../model/celldesigner/ProjectExportTest.java |  15 +
 .../graphics/AbstractImageGenerator.java      | 333 ++++++------------
 .../converter/model/sbml/SbmlLayerParser.java |   3 +-
 .../mapviewer/converter/ProjectFactory.java   |   4 +-
 .../model/map/model/ModelComparator.java      |  12 +-
 .../wikipathway/xml/ModelContructor.java      |  14 +-
 .../services/impl/ProjectService.java         |  12 -
 11 files changed, 219 insertions(+), 257 deletions(-)

diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java
index a732c0d83e..6f6a521c4d 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParser.java
@@ -734,7 +734,7 @@ public class CellDesignerXmlParser extends Converter {
     result.append(speciesCollectionXmlParser.geneCollectionToXmlString(genes));
     result.append(speciesCollectionXmlParser.rnaCollectionToXmlString(rnas));
     result.append(speciesCollectionXmlParser.antisenseRnaCollectionToXmlString(antisenseRnas));
-    result.append(layerParser.layerCollectionToXml(model.getLayers()));
+    result.append(layerParser.layerCollectionToXml(model.getLayers(), model.getCompartments()));
 
     result.append("</celldesigner:extension>\n");
 
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParser.java
index 592a89b005..affddd6eaa 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParser.java
@@ -1,5 +1,6 @@
 package lcsb.mapviewer.converter.model.celldesigner;
 
+import lcsb.mapviewer.commands.CreateHierarchyCommand;
 import lcsb.mapviewer.common.XmlParser;
 import lcsb.mapviewer.common.exception.InvalidXmlSchemaException;
 import lcsb.mapviewer.common.geometry.ColorParser;
@@ -7,6 +8,8 @@ import lcsb.mapviewer.converter.ComplexZipConverter;
 import lcsb.mapviewer.model.graphics.ArrowType;
 import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.graphics.PolylineData;
+import lcsb.mapviewer.model.map.compartment.Compartment;
+import lcsb.mapviewer.model.map.compartment.PathwayCompartment;
 import lcsb.mapviewer.model.map.layout.BlockDiagram;
 import lcsb.mapviewer.model.map.layout.ElementGroup;
 import lcsb.mapviewer.model.map.layout.graphics.Layer;
@@ -28,7 +31,9 @@ import java.awt.geom.Point2D;
 import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Parser used for parsing CellDesigner xml to get {@link Layer} object.
@@ -81,7 +86,7 @@ public class LayerXmlParser {
    * @param layers collection of layers
    * @return xml node representing layers collection
    */
-  public String layerCollectionToXml(final Collection<Layer> layers) {
+  public String layerCollectionToXml(final Collection<Layer> layers, final Collection<Compartment> compartments) {
     for (final Layer layer : layers) {
       if (NumberUtils.isParsable(layer.getLayerId())) {
         problematicIdCounter = Math.max(problematicIdCounter, Integer.parseInt(layer.getLayerId()));
@@ -89,8 +94,25 @@ public class LayerXmlParser {
     }
     StringBuilder result = new StringBuilder();
     result.append("<celldesigner:listOfLayers>");
+    boolean compartmentsAdded = false;
+    Set<PathwayCompartment> pathways = new HashSet<>();
+    for (Compartment compartment : compartments) {
+      if (compartment instanceof PathwayCompartment) {
+        pathways.add((PathwayCompartment) compartment);
+      }
+    }
     for (final Layer layer : layers) {
-      result.append(layerToXml(layer));
+      if (layer.getName().equals(CreateHierarchyCommand.PATHWAY_LAYER_NAME)) {
+        compartmentsAdded = true;
+        result.append(layerToXml(layer, pathways));
+      } else {
+        result.append(layerToXml(layer, new HashSet<>()));
+      }
+    }
+    if (!compartmentsAdded) {
+      Layer layer = new Layer();
+      layer.setName(CreateHierarchyCommand.PATHWAY_LAYER_NAME);
+      result.append(layerToXml(layer, pathways));
     }
     result.append("</celldesigner:listOfLayers>\n");
     return result.toString();
@@ -275,7 +297,7 @@ public class LayerXmlParser {
    * @param layer object to be transformed into xml
    * @return CellDesigner xml representation for the layer
    */
-  String layerToXml(final Layer layer) {
+  String layerToXml(final Layer layer, final Set<PathwayCompartment> pathways) {
     StringBuilder result = new StringBuilder();
     String id = layer.getLayerId();
     if (!NumberUtils.isParsable(id)) {
@@ -293,6 +315,9 @@ public class LayerXmlParser {
     for (final LayerImage layerImage : layer.getImages()) {
       result.append(layerImageToXml(layerImage));
     }
+    for (final PathwayCompartment pathway : pathways) {
+      result.append(pathwayToXml(pathway));
+    }
     result.append("</celldesigner:listOfTexts>\n");
 
     result.append("<celldesigner:listOfSquares>\n");
@@ -579,4 +604,34 @@ public class LayerXmlParser {
     return result.toString();
   }
 
+  String pathwayToXml(final PathwayCompartment pathway) {
+    StringBuilder result = new StringBuilder();
+    result.append("<celldesigner:layerSpeciesAlias>");
+    result.append("<celldesigner:layerNotes>\n");
+    String notes = pathway.getName();
+    if (notes == null) {
+      notes = "";
+    }
+    if (commonParser.getNotesXmlContent(pathway.getNotes()) != null) {
+      notes += "\n" + commonParser.getNotesXmlContent(pathway.getNotes());
+    }
+    if (pathway.getFillColor() != null && !pathway.getFillColor().equals(Color.WHITE)) {
+      notes += "\nBackgroundColor:" + new ColorParser().colorToHtml(pathway.getFillColor());
+    }
+    if (!pathway.getBorderColor().equals(Color.LIGHT_GRAY)) {
+      notes += "\nBorderColor:" + new ColorParser().colorToHtml(pathway.getBorderColor());
+    }
+    result.append(notes);
+    result.append("\n</celldesigner:layerNotes>");
+    result.append("<celldesigner:paint color=\"" + XmlParser.colorToString(pathway.getFontColor()) + "\"/>");
+    result.append("<celldesigner:bounds x=\"" + pathway.getX() + "\" ");
+    result.append(" y=\"" + pathway.getY() + "\" ");
+    result.append(" w=\"" + pathway.getWidth() + "\" ");
+    result.append(" h=\"" + pathway.getHeight() + "\"/>");
+    result.append("<celldesigner:font size=\"" + pathway.getFontSize().intValue() + "\"/>");
+    result.append("</celldesigner:layerSpeciesAlias>\n");
+    return result.toString();
+  }
+
+
 }
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerTestFunctions.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerTestFunctions.java
index 379d507b56..9140a5181f 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerTestFunctions.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerTestFunctions.java
@@ -16,6 +16,7 @@ import lcsb.mapviewer.model.map.InconsistentModelException;
 import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.LeftSquareCompartment;
+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;
@@ -169,6 +170,20 @@ public abstract class CellDesignerTestFunctions extends TestUtils {
     return compartment;
   }
 
+  protected PathwayCompartment createPathway() {
+    final PathwayCompartment pathwayCompartment = new PathwayCompartment("art0");
+    pathwayCompartment.setName(faker.science().element());
+    assignCoordinates(13, 14, 100, 120, pathwayCompartment);
+    pathwayCompartment.setNameVerticalAlign(VerticalAlign.TOP);
+    pathwayCompartment.setNameHorizontalAlign(HorizontalAlign.LEFT);
+    pathwayCompartment.setNameX(pathwayCompartment.getX() + 10);
+    pathwayCompartment.setNameY(pathwayCompartment.getY() + 10);
+    pathwayCompartment.setNameWidth(pathwayCompartment.getWidth() - 20);
+    pathwayCompartment.setNameHeight(pathwayCompartment.getHeight() - 20);
+
+    return pathwayCompartment;
+  }
+
   protected static LayerText createText() {
     final LayerText layerText = new LayerText();
     layerText.setX(256.0);
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParserTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParserTest.java
index e6fcbd17d9..ad1b8ef7b2 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParserTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/LayerXmlParserTest.java
@@ -25,6 +25,7 @@ import org.w3c.dom.Node;
 import java.awt.Color;
 import java.awt.geom.Rectangle2D;
 import java.util.Collection;
+import java.util.HashSet;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -53,7 +54,7 @@ public class LayerXmlParserTest extends CellDesignerTestFunctions {
     assertNotNull(layers);
     assertEquals(1, layers.size());
 
-    xmlString = parser.layerCollectionToXml(layers);
+    xmlString = parser.layerCollectionToXml(layers, new HashSet<>());
     node = getNodeFromXmlString(xmlString);
     Collection<Layer> layers2 = parser.parseLayers(node);
     assertNotNull(layers2);
@@ -119,7 +120,7 @@ public class LayerXmlParserTest extends CellDesignerTestFunctions {
     Layer layer = parser.getLayer(node);
     assertNotNull(layer);
 
-    xmlString = parser.layerToXml(layer);
+    xmlString = parser.layerToXml(layer, new HashSet<>());
     node = getNodeFromXmlString(xmlString);
     Layer layers2 = parser.getLayer(node);
     assertNotNull(layers2);
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/ProjectExportTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/ProjectExportTest.java
index fb3eb9eaab..adbeeabe2a 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/ProjectExportTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/ProjectExportTest.java
@@ -8,6 +8,7 @@ import lcsb.mapviewer.converter.zip.ZipEntryFile;
 import lcsb.mapviewer.converter.zip.ZipEntryFileFactory;
 import lcsb.mapviewer.model.Project;
 import lcsb.mapviewer.model.ProjectComparator;
+import lcsb.mapviewer.model.map.compartment.PathwayCompartment;
 import lcsb.mapviewer.model.map.layout.graphics.Glyph;
 import lcsb.mapviewer.model.map.layout.graphics.Layer;
 import lcsb.mapviewer.model.map.layout.graphics.LayerImage;
@@ -239,4 +240,18 @@ public class ProjectExportTest extends CellDesignerTestFunctions {
     testSerializationOverZip(project);
   }
 
+  @Test
+  public void testWithPathway() throws Exception {
+    Project project = createProject();
+    Model model = createEmptyModel();
+    model.setWidth(126);
+    model.setHeight(148);
+    PathwayCompartment pathway = createPathway();
+    model.addElement(pathway);
+
+    project.addModel(model);
+
+    testSerializationOverZip(project);
+  }
+
 }
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 df9a04f21c..3a08e727ca 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
@@ -1,24 +1,6 @@
 package lcsb.mapviewer.converter.graphics;
 
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.RenderingHints;
-import java.awt.geom.Line2D;
-import java.awt.geom.Rectangle2D;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.file.FileStore;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.commands.CreateHierarchyCommand;
 import lcsb.mapviewer.commands.SemanticZoomLevelMatcher;
 import lcsb.mapviewer.common.Configuration;
 import lcsb.mapviewer.common.MimeType;
@@ -35,7 +17,6 @@ import lcsb.mapviewer.model.map.BioEntity;
 import lcsb.mapviewer.model.map.Drawable;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.PathwayCompartment;
-import lcsb.mapviewer.model.map.layout.graphics.Layer;
 import lcsb.mapviewer.model.map.layout.graphics.LayerOval;
 import lcsb.mapviewer.model.map.layout.graphics.LayerRect;
 import lcsb.mapviewer.model.map.layout.graphics.LayerText;
@@ -46,6 +27,21 @@ import lcsb.mapviewer.model.map.species.Element;
 import lcsb.mapviewer.model.map.species.Species;
 import lcsb.mapviewer.model.map.species.field.ModificationResidue;
 import lcsb.mapviewer.model.overlay.DataOverlayEntry;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * This class is responsible for creation of the image from the model. It's an
@@ -78,9 +74,8 @@ import lcsb.mapviewer.model.overlay.DataOverlayEntry;
  * from graphics2D and save it into separate files</li>
  * </ul>
  * </p>
- * 
+ *
  * @author Piotr Gawron
- * 
  */
 public abstract class AbstractImageGenerator {
 
@@ -99,13 +94,13 @@ public abstract class AbstractImageGenerator {
   /**
    * Default class logger.
    */
-  private static Logger logger = LogManager.getLogger();
+  private static final Logger logger = LogManager.getLogger();
   /**
    * Class that allows to check if element is visible (or transparent) when
    * drawing. It's used to filter out invisible elements when drawing
    * semantic/hierarchy view.
    */
-  private SemanticZoomLevelMatcher zoomLevelMatcher = new SemanticZoomLevelMatcher();
+  private final SemanticZoomLevelMatcher zoomLevelMatcher = new SemanticZoomLevelMatcher();
   /**
    * On which level in hierarchical view we should visualize map.
    */
@@ -145,11 +140,8 @@ public abstract class AbstractImageGenerator {
    * {@link lcsb.mapviewer.converter.graphics.AbstractImageGenerator.Params
    * params}.
    *
-   * @param params
-   *          list of all params to create appropriate image
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing a map
-   *
+   * @param params list of all params to create appropriate image
+   * @throws DrawingException thrown when there was a problem with drawing a map
    */
   protected AbstractImageGenerator(final Params params) {
     this.params = params;
@@ -167,18 +159,15 @@ public abstract class AbstractImageGenerator {
    * This method creates a graphics object for different implementations of
    * canvas with fixed width and height.
    *
-   * @param width
-   *          width of the canvas (graphics2d) to be created
-   * @param height
-   *          height of the canvas (graphics2d) to be created
+   * @param width  width of the canvas (graphics2d) to be created
+   * @param height height of the canvas (graphics2d) to be created
    */
   protected abstract void createImageObject(final double width, final double height);
 
   /**
    * Draw a model into {@link #getGraphics()} object.
-   * 
-   * @throws DrawingException
-   *           thrown when there is a problem with drawing
+   *
+   * @throws DrawingException thrown when there is a problem with drawing
    */
   protected void draw() throws DrawingException {
     if (isDrawn()) {
@@ -248,21 +237,8 @@ public abstract class AbstractImageGenerator {
   }
 
   private List<Drawable> getDrawables() {
-    boolean isOriginallyVisible = false;
-    for (Layer layer : params.getModel().getLayers()) {
-      if (Objects.deepEquals(layer.getName(), CreateHierarchyCommand.TEXT_LAYER_NAME)) {
-        isOriginallyVisible = layer.isVisible();
-        layer.setVisible(true);
-      }
-    }
     List<Drawable> drawables = new ArrayList<>(params.getModel().getDrawables(true));
     drawables.sort(BioEntity.Z_INDEX_COMPARATOR);
-    for (Layer layer : params.getModel().getLayers()) {
-      if (Objects.deepEquals(layer.getName(), CreateHierarchyCommand.TEXT_LAYER_NAME)) {
-        // revert change that was required to obtain drawables with text layer
-        layer.setVisible(isOriginallyVisible);
-      }
-    }
     return drawables;
   }
 
@@ -300,10 +276,8 @@ public abstract class AbstractImageGenerator {
   /**
    * This method draw a {@link Compartment} on a graphics.
    *
-   * @param compartment
-   *          object that we want to draw
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing {@link Compartment}
+   * @param compartment object that we want to draw
+   * @throws DrawingException thrown when there was a problem with drawing {@link Compartment}
    */
   protected void drawCompartment(final Compartment compartment) throws DrawingException {
     // get a converter for this compartment
@@ -328,10 +302,8 @@ public abstract class AbstractImageGenerator {
   /**
    * This method draw a {@link Species} on a graphics.
    *
-   * @param species
-   *          object to be drawn
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing a {@link Species}
+   * @param species object to be drawn
+   * @throws DrawingException thrown when there was a problem with drawing a {@link Species}
    */
   protected void drawSpecies(final Species species) throws DrawingException {
     if (!cross(species.getBorder())) {
@@ -368,10 +340,8 @@ public abstract class AbstractImageGenerator {
   /**
    * This method draw a reaction on a graphics.
    *
-   * @param reaction
-   *          object to be drawn
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing a {@link Reaction}
+   * @param reaction object to be drawn
+   * @throws DrawingException thrown when there was a problem with drawing a {@link Reaction}
    */
   protected void drawReaction(final Reaction reaction) throws DrawingException {
     if (!cross(reaction.getLines())) {
@@ -385,8 +355,7 @@ public abstract class AbstractImageGenerator {
   /**
    * Checks if one of the lines in parameter cross the frame.
    *
-   * @param lines
-   *          list of lines to check
+   * @param lines list of lines to check
    * @return true if the cross point exist, false otherwise
    */
   private boolean cross(final List<Line2D> lines) {
@@ -402,8 +371,7 @@ public abstract class AbstractImageGenerator {
    * Checks if the rectangle in the parameters cross the fram in which we are
    * currently draw image.
    *
-   * @param rect
-   *          rectangle to check
+   * @param rect rectangle to check
    * @return true if rectangle check the frame, false otherwise
    */
   protected boolean cross(final Rectangle2D rect) {
@@ -418,8 +386,7 @@ public abstract class AbstractImageGenerator {
   }
 
   /**
-   * @param graphics
-   *          the graphics to set
+   * @param graphics the graphics to set
    */
   protected void setGraphics(final Graphics2D graphics) {
     this.graphics = graphics;
@@ -428,12 +395,9 @@ public abstract class AbstractImageGenerator {
   /**
    * Saves generated image into file.
    *
-   * @param fileName
-   *          file where the images should be saved
-   * @throws IOException
-   *           thrown when there is problem with output file
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param fileName file where the images should be saved
+   * @throws IOException      thrown when there is problem with output file
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   public final void saveToFile(final String fileName) throws IOException, DrawingException {
     if (!isDrawn()) {
@@ -446,24 +410,18 @@ public abstract class AbstractImageGenerator {
   /**
    * Saves generated image from {@link #getGraphics()} into file.
    *
-   * @param fileName
-   *          file where the images should be saved
-   * @throws IOException
-   *           thrown when there is problem with output file
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param fileName file where the images should be saved
+   * @throws IOException      thrown when there is problem with output file
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   protected abstract void saveToFileImplementation(final String fileName) throws IOException;
 
   /**
    * Saves generated image into {@link OutputStream}.
    *
-   * @param os
-   *          stream where the images should be saved
-   * @throws IOException
-   *           thrown when there is problem with output stream
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param os stream where the images should be saved
+   * @throws IOException      thrown when there is problem with output stream
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   public final void saveToOutputStream(final OutputStream os) throws IOException, DrawingException {
     if (!isDrawn()) {
@@ -476,32 +434,22 @@ public abstract class AbstractImageGenerator {
    * Saves generated image from {@link #getGraphics()} into {@link OutputStream}
    * .
    *
-   * @param os
-   *          stream where the images should be saved
-   * @throws IOException
-   *           thrown when there is problem with output stream
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param os stream where the images should be saved
+   * @throws IOException      thrown when there is problem with output stream
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   protected abstract void saveToOutputStreamImplementation(final OutputStream os) throws IOException;
 
   /**
    * Saves part of the generated image file.
    *
-   * @param fileName
-   *          file where the images should be saved
-   * @param x
-   *          x left margin of the image part
-   * @param y
-   *          y top margin of the image part
-   * @param width
-   *          width of the image part
-   * @param height
-   *          height of the image part
-   * @throws IOException
-   *           thrown when there is problem with output file
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param fileName file where the images should be saved
+   * @param x        x left margin of the image part
+   * @param y        y top margin of the image part
+   * @param width    width of the image part
+   * @param height   height of the image part
+   * @throws IOException      thrown when there is problem with output file
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   public final void savePartToFile(final int x, final int y, final int width, final int height, final String fileName)
       throws IOException, DrawingException {
@@ -525,42 +473,29 @@ public abstract class AbstractImageGenerator {
   /**
    * Saves part of the generated image from {@link #getGraphics()} into file.
    *
-   * @param fileName
-   *          file where the images should be saved
-   * @param x
-   *          x left margin of the image part
-   * @param y
-   *          y top margin of the image part
-   * @param width
-   *          width of the image part
-   * @param height
-   *          height of the image part
-   * @throws IOException
-   *           thrown when there is problem with output file
+   * @param fileName file where the images should be saved
+   * @param x        x left margin of the image part
+   * @param y        y top margin of the image part
+   * @param width    width of the image part
+   * @param height   height of the image part
+   * @throws IOException thrown when there is problem with output file
    */
   protected abstract void savePartToFileImplementation(final int x, final int y, final int width, final int height,
-      final String fileName) throws IOException;
+                                                       final String fileName) throws IOException;
 
   /**
    * Saves part of the generated image into {@link OutputStream}.
    *
-   * @param os
-   *          stream where the images should be saved
-   * @param x
-   *          x left margin of the image part
-   * @param y
-   *          y top margin of the image part
-   * @param width
-   *          width of the image part
-   * @param height
-   *          height of the image part
-   * @throws IOException
-   *           thrown when there is problem with output file
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param os     stream where the images should be saved
+   * @param x      x left margin of the image part
+   * @param y      y top margin of the image part
+   * @param width  width of the image part
+   * @param height height of the image part
+   * @throws IOException      thrown when there is problem with output file
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   public final void savePartToOutputStream(final int x, final int y, final int width, final int height,
-      final OutputStream os) throws IOException, DrawingException {
+                                           final OutputStream os) throws IOException, DrawingException {
     if (!isDrawn()) {
       draw();
     }
@@ -571,23 +506,16 @@ public abstract class AbstractImageGenerator {
    * Saves part of the generated image from {@link #getGraphics()} into
    * {@link OutputStream}.
    *
-   * @param os
-   *          stream where the images should be saved
-   * @param x
-   *          x left margin of the image part
-   * @param y
-   *          y top margin of the image part
-   * @param width
-   *          width of the image part
-   * @param height
-   *          height of the image part
-   * @throws IOException
-   *           thrown when there is problem with output file
-   * @throws DrawingException
-   *           thrown when there was a problem with drawing map
+   * @param os     stream where the images should be saved
+   * @param x      x left margin of the image part
+   * @param y      y top margin of the image part
+   * @param width  width of the image part
+   * @param height height of the image part
+   * @throws IOException      thrown when there is problem with output file
+   * @throws DrawingException thrown when there was a problem with drawing map
    */
   protected abstract void savePartToOutputStreamImplementation(final int x, final int y, final int width,
-      final int height, final OutputStream os) throws IOException;
+                                                               final int height, final OutputStream os) throws IOException;
 
   /**
    * Returns name of the format to which this graphic converter will transform.
@@ -600,8 +528,7 @@ public abstract class AbstractImageGenerator {
    * Returns {@link MimeType} that should be used for files generated by this
    * image generator.
    *
-   * @return {@link MimeType} that should be used for files generated by this
-   *         image generator
+   * @return {@link MimeType} that should be used for files generated by this image generator
    */
   public abstract MimeType getMimeType();
 
@@ -620,8 +547,7 @@ public abstract class AbstractImageGenerator {
   }
 
   /**
-   * @param sbgnFormat
-   *          the sbgnFormat to set
+   * @param sbgnFormat the sbgnFormat to set
    */
   protected void sbgnFormat(final boolean sbgnFormat) {
     this.sbgnFormat = sbgnFormat;
@@ -636,8 +562,7 @@ public abstract class AbstractImageGenerator {
   }
 
   /**
-   * @param drawn
-   *          the drawn to set
+   * @param drawn the drawn to set
    * @see #drawn
    */
   private void setDrawn(final boolean drawn) {
@@ -653,8 +578,7 @@ public abstract class AbstractImageGenerator {
   }
 
   /**
-   * @param params
-   *          the params to set
+   * @param params the params to set
    * @see #params
    */
   protected void setParams(final Params params) {
@@ -665,7 +589,6 @@ public abstract class AbstractImageGenerator {
    * This class contains a list of params that are used for drawing.
    *
    * @author Piotr Gawron
-   *
    */
   public static class Params {
 
@@ -740,9 +663,8 @@ public abstract class AbstractImageGenerator {
      * single layout. In this map we have pairs between {@link Element}/
      * {@link Reaction} and {@link DataOverlayEntry} used to visualize the
      * element.
-     *
      */
-    private List<List<Pair<? extends BioEntity, DataOverlayEntry>>> visibleDataOverlays = new ArrayList<>();
+    private final List<List<Pair<? extends BioEntity, DataOverlayEntry>>> visibleDataOverlays = new ArrayList<>();
 
     /**
      * Color that should be used for drawing overlays with minimum value.
@@ -759,8 +681,7 @@ public abstract class AbstractImageGenerator {
     private Color neutralColor = Color.WHITE;
 
     /**
-     * @param scale
-     *          scale to set
+     * @param scale scale to set
      * @return object with all parameters
      * @see #scale
      */
@@ -770,8 +691,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param scale
-     *          scale to set
+     * @param scale scale to set
      * @return object with all parameters
      * @see #scale
      */
@@ -781,9 +701,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
-     * @param x
-     *          x coordinate to be set
+     * @param x x coordinate to be set
      * @return object with all parameters
      * @see #x
      */
@@ -793,8 +711,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param x
-     *          x coordinate to be set
+     * @param x x coordinate to be set
      * @return object with all parameters
      * @see #x
      */
@@ -804,8 +721,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param y
-     *          y coordinate to be set
+     * @param y y coordinate to be set
      * @return object with all parameters
      * @see #y
      */
@@ -815,8 +731,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param y
-     *          y coordinate to be set
+     * @param y y coordinate to be set
      * @return object with all parameters
      * @see #y
      */
@@ -826,8 +741,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param width
-     *          width to set
+     * @param width width to set
      * @return object with all parameters
      * @see #width
      */
@@ -837,8 +751,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param width
-     *          width to set
+     * @param width width to set
      * @return object with all parameters
      * @see #width
      */
@@ -848,9 +761,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
-     * @param height
-     *          height to set
+     * @param height height to set
      * @return object with all parameters
      * @see #height
      */
@@ -860,8 +771,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param height
-     *          height to set
+     * @param height height to set
      * @return object with all parameters
      * @see #height
      */
@@ -871,9 +781,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
-     * @param background
-     *          background flag to set
+     * @param background background flag to set
      * @return object with all parameters
      * @see #background
      */
@@ -883,9 +791,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
-     * @param nested
-     *          nested flag to set
+     * @param nested nested flag to set
      * @return object with all parameters
      * @see #nested
      */
@@ -895,9 +801,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
-     * @param model
-     *          model to set
+     * @param model model to set
      * @return object with all parameters
      * @see #model
      */
@@ -913,9 +817,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
-     * @param level
-     *          level to set
+     * @param level level to set
      * @return object with all parameters
      * @see #level
      */
@@ -927,8 +829,7 @@ public abstract class AbstractImageGenerator {
     /**
      * Sets {@link #level} parameter from {@link String}.
      *
-     * @param zoomLevel
-     *          new {@link #level} value
+     * @param zoomLevel new {@link #level} value
      * @return object with all parameters
      */
     public Params level(final String zoomLevel) {
@@ -941,7 +842,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return scale value
      * @see #scale
      */
@@ -950,7 +850,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return x coordinate value
      * @see #x
      */
@@ -959,7 +858,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return y coordinate value
      * @see #y
      */
@@ -968,7 +866,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return width value
      * @see #width
      */
@@ -977,7 +874,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return height value
      * @see #height
      */
@@ -986,7 +882,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return model object
      * @see #model
      */
@@ -995,7 +890,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return background value
      * @see #background
      */
@@ -1004,7 +898,6 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     *
      * @return nested value
      * @see #nested
      */
@@ -1033,10 +926,9 @@ public abstract class AbstractImageGenerator {
      * contains mapping between {@link Element}/{@link Reaction} and
      * {@link DataOverlayEntry} used for coloring specific element.
      *
-     * @param map
-     *          layout data containing mapping between {@link Element}/
-     *          {@link Reaction} and {@link DataOverlayEntry} used for coloring
-     *          specific element
+     * @param map layout data containing mapping between {@link Element}/
+     *            {@link Reaction} and {@link DataOverlayEntry} used for coloring
+     *            specific element
      */
     public void addVisibleDataOverlay(final List<Pair<? extends BioEntity, DataOverlayEntry>> map) {
       visibleDataOverlays.add(map);
@@ -1050,12 +942,9 @@ public abstract class AbstractImageGenerator {
      * Returns list with {@link DataOverlayEntry} used to visualize the specific
      * object in data overlays visualized in the JavaScript.
      *
-     * @param object
-     *          object ({@link Element} or {@link Reaction}) for which we return
-     *          list of {@link DataOverlayEntry} in different layouts
-     * @return list with {@link DataOverlayEntry} used to visualize the specific
-     *         object in data overlays visualized in the JavaScript
-     * @see #visibleDataOverlays
+     * @param object object ({@link Element} or {@link Reaction}) for which we return
+     *               list of {@link DataOverlayEntry} in different layouts
+     * @return list with {@link DataOverlayEntry} used to visualize the specific object in data overlays visualized in the JavaScript
      */
     public List<List<DataOverlayEntry>> getVisibleDataOverlaysForElement(final BioEntity object) {
       List<List<DataOverlayEntry>> result = new ArrayList<>();
@@ -1075,8 +964,7 @@ public abstract class AbstractImageGenerator {
      * 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
+     * @return {@link Color} that should be used for drawing overlays with maximum value
      */
     public Color getMaxColor() {
       return maxColor;
@@ -1090,16 +978,14 @@ public abstract class AbstractImageGenerator {
      * 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
+     * @return {@link Color} that should be used for drawing overlays with minimum value
      */
     public Color getMinColor() {
       return minColor;
     }
 
     /**
-     * @param minColor
-     *          minColor to set
+     * @param minColor minColor to set
      * @return object with all parameters
      * @see #minColor
      */
@@ -1109,8 +995,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param maxColor
-     *          maxColor to set
+     * @param maxColor maxColor to set
      * @return object with all parameters
      * @see #maxColor
      */
@@ -1120,8 +1005,7 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param simpleColor
-     *          simpleColor to set
+     * @param simpleColor simpleColor to set
      * @return object with all parameters
      * @see #simpleColor
      */
@@ -1139,10 +1023,9 @@ public abstract class AbstractImageGenerator {
     }
 
     /**
-     * @param sbgn
-     *          the sbgn to set
-     * @see #sbgn
+     * @param sbgn the sbgn to set
      * @return object with all parameters
+     * @see #sbgn
      */
     public Params sbgn(final boolean sbgn) {
       this.sbgn = sbgn;
diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlLayerParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlLayerParser.java
index 82e31e6801..894be0c3f4 100644
--- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlLayerParser.java
+++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlLayerParser.java
@@ -1,6 +1,5 @@
 package lcsb.mapviewer.converter.model.sbml;
 
-import lcsb.mapviewer.commands.CreateHierarchyCommand;
 import lcsb.mapviewer.converter.InvalidInputDataExecption;
 import lcsb.mapviewer.model.map.layout.graphics.Layer;
 import lcsb.mapviewer.model.map.layout.graphics.LayerText;
@@ -22,7 +21,7 @@ public class SbmlLayerParser extends SbmlBioEntityParser {
     Layer layer = new Layer();
     layer.setLayerId(1);
     layer.setZ(1);
-    layer.setName(CreateHierarchyCommand.TEXT_LAYER_NAME);
+    layer.setName("text");
     SbmlModelUtils sbmlModelUtils = new SbmlModelUtils(sbmlModel);
     Layout layout = sbmlModelUtils.getLayout();
     if (layout != null) {
diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java
index 6a4939e969..fd05cbb417 100644
--- a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java
+++ b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java
@@ -178,7 +178,9 @@ public class ProjectFactory {
       addModelFileToZip(project.getTopModel(), project.getTopModel().getName() + "." + converter.getFileExtensions().get(0), converter, zos);
       for (ModelData model : project.getModels()) {
         if (model != project.getTopModelData()) {
-          addModelFileToZip(model.getModel(), ZipEntryFileFactory.SUBMODEL_DIRECTORY + model.getName() + "." + converter.getFileExtensions().get(0), converter, zos);
+          addModelFileToZip(model.getModel(),
+              ZipEntryFileFactory.SUBMODEL_DIRECTORY + model.getName() + "." + converter.getFileExtensions().get(0), converter,
+              zos);
         }
       }
       Model mapping = createMappingModel(project.getModels());
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java
index 3b56cb0799..f31d8915ff 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelComparator.java
@@ -27,6 +27,7 @@ import lcsb.mapviewer.modelutils.map.ElementUtils;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
@@ -112,7 +113,16 @@ public class ModelComparator extends Comparator<Model> {
 
     int status = compareElements(arg0.getElements(), arg1.getElements());
     if (status != 0) {
-      logger.debug("Set of elements different");
+      Set<String> model0ids = new HashSet<>();
+      Set<String> model1ids = new HashSet<>();
+
+      for (Element element : arg0.getElements()) {
+        model0ids.add(element.getElementId());
+      }
+      for (Element element : arg1.getElements()) {
+        model1ids.add(element.getElementId());
+      }
+      logger.debug("Set of elements different: {}, {}", model1ids, model0ids);
       return status;
     }
 
diff --git a/pathvisio/src/main/java/lcsb/mapviewer/wikipathway/xml/ModelContructor.java b/pathvisio/src/main/java/lcsb/mapviewer/wikipathway/xml/ModelContructor.java
index f20dc52948..f6bf6a4c3d 100644
--- a/pathvisio/src/main/java/lcsb/mapviewer/wikipathway/xml/ModelContructor.java
+++ b/pathvisio/src/main/java/lcsb/mapviewer/wikipathway/xml/ModelContructor.java
@@ -106,7 +106,7 @@ public class ModelContructor {
    */
   private static final double EPSILON = 1e-6;
   /**
-   * List of {@link Shape#shape shapes} that are not supported to be part of a
+   * List of shapes that are not supported to be part of a
    * {@link Complex complex}.
    */
   private static final Set<GpmlShape> INALID_COMPLEX_SHAPE_CHILDREN = new HashSet<>();
@@ -1252,7 +1252,7 @@ public class ModelContructor {
           }
           if (complex.getName() == null || (complex.getName().isEmpty())) {
             for (final Layer layer : model.getLayers()) {
-              if (layer.getName().equals(CreateHierarchyCommand.TEXT_LAYER_NAME)) {
+              if (!layer.getName().equals(CreateHierarchyCommand.PATHWAY_LAYER_NAME)) {
                 LayerText toRemove = null;
                 for (final LayerText lt : layer.getTexts()) {
                   if (complex.contains(lt)) {
@@ -1297,7 +1297,7 @@ public class ModelContructor {
     for (final Compartment compartment : model.getCompartments()) {
       if (compartment.getName() == null || compartment.getName().isEmpty()) {
         for (final Layer layer : model.getLayers()) {
-          if (layer.getName().equals(CreateHierarchyCommand.TEXT_LAYER_NAME)) {
+          if (!layer.getName().equals(CreateHierarchyCommand.PATHWAY_LAYER_NAME)) {
             LayerText toRemove = null;
             for (final LayerText lt : layer.getTexts()) {
               if (compartment.contains(lt)) {
@@ -1322,12 +1322,6 @@ public class ModelContructor {
     }
   }
 
-  /**
-   * Creates list of {@link LayerLine} in the model from gpml model.
-   *
-   * @param graph gpml model
-   * @return list of {@link LayerLine}
-   */
   private Collection<PolylineData> createLines(final Graph graph) {
     final List<PolylineData> result = new ArrayList<PolylineData>();
     for (final PolylineData pd : graph.getLines()) {
@@ -1398,7 +1392,7 @@ public class ModelContructor {
       layer.setVisible(true);
       layer.setLayerId(1);
       layer.setZ(1);
-      layer.setName(CreateHierarchyCommand.TEXT_LAYER_NAME);
+      layer.setName("text");
     }
   }
 }
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 11e01fb110..51c76d2285 100644
--- a/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java
+++ b/service/src/main/java/lcsb/mapviewer/services/impl/ProjectService.java
@@ -41,7 +41,6 @@ import lcsb.mapviewer.model.map.MiriamType;
 import lcsb.mapviewer.model.map.layout.ProjectBackground;
 import lcsb.mapviewer.model.map.layout.ProjectBackgroundImageLayer;
 import lcsb.mapviewer.model.map.layout.ProjectBackgroundStatus;
-import lcsb.mapviewer.model.map.layout.graphics.Layer;
 import lcsb.mapviewer.model.map.model.Model;
 import lcsb.mapviewer.model.map.model.ModelData;
 import lcsb.mapviewer.model.map.model.ModelSubmodelConnection;
@@ -58,7 +57,6 @@ import lcsb.mapviewer.persist.dao.ProjectDao;
 import lcsb.mapviewer.persist.dao.ProjectLogEntryDao;
 import lcsb.mapviewer.persist.dao.ProjectLogEntryProperty;
 import lcsb.mapviewer.persist.dao.ProjectProperty;
-import lcsb.mapviewer.persist.dao.graphics.LayerProperty;
 import lcsb.mapviewer.persist.dao.map.ModelProperty;
 import lcsb.mapviewer.persist.dao.user.UserAnnotationSchemaDao;
 import lcsb.mapviewer.services.interfaces.ICommentService;
@@ -602,16 +600,6 @@ public class ProjectService implements IProjectService {
       self.createSimpleProject(params);
     }
 
-    Map<LayerProperty, Object> layerFilter = new HashMap<>();
-    layerFilter.put(LayerProperty.PROJECT_ID, params.getProjectId());
-    List<Layer> layers = layerService.getAll(layerFilter, Pageable.unpaged()).getContent();
-    for (final Layer layer : layers) {
-      if (!layer.getName().equals(CreateHierarchyCommand.TEXT_LAYER_NAME)) {
-        layer.setVisible(false);
-        layerService.update(layer);
-      }
-    }
-
     self.updateProjectStatus(params.getProjectId(), ProjectStatus.UPLOADING_TO_DB, 0.0);
 
     self.addBuiltInBackgrounds(params);
-- 
GitLab