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 aa357bbda2901b9a4604fae54b30fe7e599a5f4c..24e3bebbcaeec0d8b6de0588da9b9c522b123152 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 @@ -7,6 +7,7 @@ import lcsb.mapviewer.converter.ConverterParams; import lcsb.mapviewer.converter.InvalidInputDataExecption; import lcsb.mapviewer.converter.model.celldesigner.structure.CellDesignerSpecies; import lcsb.mapviewer.model.Project; +import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.graphics.HorizontalAlign; import lcsb.mapviewer.model.graphics.VerticalAlign; import lcsb.mapviewer.model.map.Drawable; @@ -20,6 +21,7 @@ import lcsb.mapviewer.model.map.compartment.TopSquareCompartment; import lcsb.mapviewer.model.map.kinetics.SbmlFunction; import lcsb.mapviewer.model.map.kinetics.SbmlParameter; import lcsb.mapviewer.model.map.kinetics.SbmlUnit; +import lcsb.mapviewer.model.map.layout.graphics.Glyph; import lcsb.mapviewer.model.map.layout.graphics.Layer; import lcsb.mapviewer.model.map.layout.graphics.LayerText; import lcsb.mapviewer.model.map.model.Model; @@ -46,9 +48,13 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.geom.Point2D; import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import static org.junit.Assert.assertEquals; @@ -299,4 +305,22 @@ public abstract class CellDesignerTestFunctions extends TestUtils { return project; } + protected Glyph createGlyph() throws IOException { + Glyph glyph = new Glyph(); + glyph.setFile(createFile("testFiles/glyphs/uni.png")); + + return glyph; + } + + private UploadedFileEntry createFile(final String filePath) throws IOException { + UploadedFileEntry uploadedFileEntry = new UploadedFileEntry(); + byte[] byteArray = Files.readAllBytes(Paths.get(filePath)); + uploadedFileEntry.setFileContent(byteArray); + uploadedFileEntry.setOriginalFileName("glyphs/" + new File(filePath).getName()); + uploadedFileEntry.setLength(byteArray.length); + uploadedFileEntry.setLocalPath(null); + return uploadedFileEntry; + + } + } 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 57001079c87ca067e121c547b66889480533695f..1f5034282ddf0a0f27cbec29170abcb28c820063 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 @@ -7,6 +7,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.layout.graphics.Glyph; import lcsb.mapviewer.model.map.model.ElementSubmodelConnection; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelData; @@ -99,6 +100,22 @@ public class ProjectExportTest extends CellDesignerTestFunctions { testSerializationOverZip(project); } + @Test + public void testGlyph() throws Exception { + Glyph glyph = createGlyph(); + Project project = createProject(); + Model model = createEmptyModel(); + model.setWidth(260); + Protein protein = createProtein(); + protein.setGlyph(glyph); + model.addElement(protein); + project.addModel(model); + project.addGlyph(glyph); + + testSerializationOverZip(project); + } + + private void testSerializationOverZip(final Project project) throws Exception { File tempFile = File.createTempFile("CD-", ".zip"); try (FileOutputStream outputStream = new FileOutputStream(tempFile)) { diff --git a/converter-CellDesigner/testFiles/glyphs/uni.png b/converter-CellDesigner/testFiles/glyphs/uni.png new file mode 100644 index 0000000000000000000000000000000000000000..fd325269723c196ab52460e32a904db0e3bdc46f Binary files /dev/null and b/converter-CellDesigner/testFiles/glyphs/uni.png differ diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java index 5d6bc2741c2dc10b2f18223f019874358c771f2b..c00117499d594f9ca6dbf8395de7f63544cf679c 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java @@ -10,9 +10,11 @@ import lcsb.mapviewer.converter.zip.LayoutZipEntryFile; import lcsb.mapviewer.converter.zip.ModelZipEntryFile; import lcsb.mapviewer.converter.zip.ZipEntryFile; import lcsb.mapviewer.converter.zip.ZipEntryFileFactory; +import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.map.compartment.Compartment; import lcsb.mapviewer.model.map.layout.ReferenceGenomeType; +import lcsb.mapviewer.model.map.layout.graphics.Glyph; import lcsb.mapviewer.model.map.model.ElementSubmodelConnection; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; @@ -40,6 +42,7 @@ import java.lang.reflect.Modifier; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -65,6 +68,7 @@ public class ComplexZipConverter { */ private static final Logger logger = LogManager.getLogger(); protected static final String IMMEDIATE_LINK_PREFIX = "IMMEDIATE_LINK:"; + protected static final String GLYPH_PREFIX = "Glyph:"; /** * Class used to create single submap from a file. @@ -97,7 +101,7 @@ public class ComplexZipConverter { * @return complex {@link Model} created from input data * @throws InvalidInputDataExecption thrown when there is a problem with accessing input data */ - public Model createModel(final ComplexZipConverterParams params) throws InvalidInputDataExecption, ConverterException { + public Model createModel(final ComplexZipConverterParams params, final Project project) throws InvalidInputDataExecption, ConverterException { try { ZipFile zipFile = params.getZipFile(); Enumeration<? extends ZipEntry> entries; @@ -154,16 +158,22 @@ public class ComplexZipConverter { processReaction(mapping, nameModelMap, result, reaction); } for (final Species species : mappingModel.getSpeciesList()) { - processSpecies(species, nameModelMap); + processSpecies(species, nameModelMap, project.getGlyphs()); } } + + project.addModel(result); + for (final Model model : result.getSubmodels()) { + project.addModel(model); + } + return result; } catch (final IOException e) { throw new InvalidArgumentException(e); } } - private void processSpecies(final Species species, final Map<String, Model> nameModelMap) { + private void processSpecies(final Species species, final Map<String, Model> nameModelMap, final List<Glyph> glyphs) { String notes = species.getNotes(); if (notes != null) { String[] lines = notes.split("\n"); @@ -172,28 +182,49 @@ public class ComplexZipConverter { if (line.startsWith(IMMEDIATE_LINK_PREFIX)) { String link = line.replace(IMMEDIATE_LINK_PREFIX, "").trim(); - Compartment compartment = species.getCompartment(); - if (compartment == null) { - logger.warn("[SUBMODEL MAPPING] Species {} in mapping file doesn't start inside compartment. Skipped. Link skipped", - species.getElementId()); - } else { - String modelName = compartment.getName().toLowerCase(); - Model model = nameModelMap.get(modelName); - if (model == null) { - throw new InvalidArgumentException("Mapping file references to " + modelName + " submodel. But such model doesn't exist"); - } - Element elementToChange = model.getElementByElementId(species.getName()); - if (elementToChange == null) { - throw new InvalidArgumentException("Mapping file references to element with alias: " + species.getName() - + ". But such element doesn't exist"); - } + Element elementToChange = getElementToChange(species, nameModelMap); + if (elementToChange != null) { elementToChange.setImmediateLink(link); } + } else if (line.startsWith(GLYPH_PREFIX)) { + String filename = line.replace(GLYPH_PREFIX, "").trim(); + + Element elementToChange = getElementToChange(species, nameModelMap); + if (elementToChange != null) { + for (Glyph glyph : glyphs) { + if (glyph.getFile().getOriginalFileName().equalsIgnoreCase(filename)) { + elementToChange.setGlyph(glyph); + } + } + } } } } } + private static Element getElementToChange( + final Species species, + final Map<String, Model> nameModelMap) { + Compartment compartment = species.getCompartment(); + if (compartment == null) { + logger.warn("[SUBMODEL MAPPING] Species {} in mapping file doesn't start inside compartment. Skipped. Link skipped", + species.getElementId()); + } else { + String modelName = compartment.getName().toLowerCase(); + Model model = nameModelMap.get(modelName); + if (model == null) { + throw new InvalidArgumentException("Mapping file references to " + modelName + " submodel. But such model doesn't exist"); + } + Element result = model.getElementByElementId(species.getName()); + if (result == null) { + throw new InvalidArgumentException("Mapping file references to element with alias: " + species.getName() + + ". But such element doesn't exist"); + } + return result; + } + return null; + } + protected boolean isIgnoredFile(final String name) { if (name == null) { return true; diff --git a/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java b/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java index 6be2c0667115a0e7bf148fd87bd26656a9bb4d01..00f51f01df6db6f3144fdfd0f4b9191b7fc1bec4 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/OverviewParser.java @@ -1,5 +1,23 @@ package lcsb.mapviewer.converter; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.converter.zip.ImageZipEntryFile; +import lcsb.mapviewer.converter.zip.OverviewLinkDeserializer; +import lcsb.mapviewer.model.map.OverviewImage; +import lcsb.mapviewer.model.map.OverviewImageLink; +import lcsb.mapviewer.model.map.OverviewLink; +import lcsb.mapviewer.model.map.OverviewModelLink; +import lcsb.mapviewer.model.map.OverviewSearchLink; +import lcsb.mapviewer.model.map.model.ModelData; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import javax.imageio.ImageIO; import java.awt.Polygon; import java.awt.geom.Area; import java.awt.geom.Point2D; @@ -20,33 +38,11 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import javax.imageio.ImageIO; - -import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.module.SimpleModule; - -import lcsb.mapviewer.common.exception.InvalidArgumentException; -import lcsb.mapviewer.converter.zip.ImageZipEntryFile; -import lcsb.mapviewer.converter.zip.OverviewLinkDeserializer; -import lcsb.mapviewer.model.map.OverviewImage; -import lcsb.mapviewer.model.map.OverviewImageLink; -import lcsb.mapviewer.model.map.OverviewLink; -import lcsb.mapviewer.model.map.OverviewModelLink; -import lcsb.mapviewer.model.map.OverviewSearchLink; -import lcsb.mapviewer.model.map.model.Model; - /** * Parser used to extract data about {@link OverviewImage overview images} from * zip file. - * + * * @author Piotr Gawron - * */ public class OverviewParser { /** @@ -58,37 +54,17 @@ public class OverviewParser { private static final String JSON_COORDINATES_FILENAME = "coords.json"; - /** - * Name of the column in {@link #COORDINATES_FILENAME} where information about - * {@link OverviewModelLink#zoomLevel} is stored. - */ private static final String ZOOM_LEVEL_COORDINATES_COLUMN = "MODEL_ZOOM_LEVEL"; - /** - * Name of the column in {@link #COORDINATES_FILENAME} where information about - * {@link OverviewModelLink#xCoord},{@link OverviewModelLink#yCoord} is stored. - */ + private static final String REDIRECTION_COORDINATES_COORDINATE_COLUMN = "MODEL_COORDINATES"; - /** - * Name of the column in {@link #COORDINATES_FILENAME} where information about - * {@link OverviewModelLink#linkedModel} or - * {@link OverviewImageLink#linkedOverviewImage} is stored. - */ + private static final String TARGET_FILENAME_COORDINATE_COLUMN = "LINK_TARGET"; - /** - * Name of the column in {@link #COORDINATES_FILENAME} where information about - * {@link OverviewLink#polygon} is stored. - */ + private static final String POLYGON_COORDINATE_COLUMN = "POLYGON"; - /** - * Name of the column in {@link #COORDINATES_FILENAME} where information about - * {@link OverviewLink#overviewImage source of the image} is stored. - */ + private static final String FILENAME_COORDINATE_COLUMN = "FILE"; - /** - * Name of the column in {@link #COORDINATES_FILENAME} where information about - * type of the link (implementation of {@link OverviewLink} class) is stored. - */ + private static final String TARGET_TYPE_COORDINATE_COLUMN = "LINK_TYPE"; /** @@ -126,20 +102,16 @@ public class OverviewParser { * Method that parse zip file and creates list of {@link OverviewImage images} * from it. * - * @param models - * map with models where the key is name of the file and value is model - * that was parsed from the file - * @param files - * list with files to parse - * @param outputDirectory - * directory where images should be stored, directory path should be - * absolute + * @param models map with models where the key is name of the file and value is model + * that was parsed from the file + * @param files list with files to parse + * @param outputDirectory directory where images should be stored, directory path should be + * absolute * @return list of {@link OverviewImage images} - * @throws InvalidOverviewFile - * thrown when the zip file contains invalid data + * @throws InvalidOverviewFile thrown when the zip file contains invalid data */ - public List<OverviewImage> parseOverviewLinks(final Set<Model> models, final List<ImageZipEntryFile> files, - final String outputDirectory, final ZipFile zipFile) throws InvalidOverviewFile { + public List<OverviewImage> parseOverviewLinks(final Set<ModelData> models, final List<ImageZipEntryFile> files, + final String outputDirectory, final ZipFile zipFile) throws InvalidOverviewFile { if (outputDirectory != null) { File f = new File(outputDirectory); if (!f.exists()) { @@ -220,9 +192,9 @@ public class OverviewParser { } } - private Map<String, Model> createMapping(final Set<Model> models) { - Map<String, Model> result = new HashMap<>(); - for (final Model model : models) { + private Map<String, ModelData> createMapping(final Set<ModelData> models) { + Map<String, ModelData> result = new HashMap<>(); + for (final ModelData model : models) { result.put(model.getName().toLowerCase(), model); } return result; @@ -232,20 +204,16 @@ public class OverviewParser { * This method process data from {@link #COORDINATES_FILENAME} in zip archive. * This method adds connections between images and between images and models. * - * @param models - * map with models where the key is name of the file and value is model - * that was parsed from the file - * @param images - * list of {@link OverviewImage images} that should be connected - * @param coordinatesData - * {@link String} with the data taken from - * {@link #COORDINATES_FILENAME} file - * @throws InvalidOverviewFile - * thrown when the data are invalid + * @param models map with models where the key is name of the file and value is model + * that was parsed from the file + * @param images list of {@link OverviewImage images} that should be connected + * @param coordinatesData {@link String} with the data taken from + * {@link #COORDINATES_FILENAME} file + * @throws InvalidOverviewFile thrown when the data are invalid */ - protected List<OverviewImage> processCoordinates(final Set<Model> models, final List<OverviewImage> images, final String coordinatesData) + protected List<OverviewImage> processCoordinates(final Set<ModelData> models, final List<OverviewImage> images, final String coordinatesData) throws InvalidOverviewFile { - Map<String, Model> modelMapping = createMapping(models); + Map<String, ModelData> modelMapping = createMapping(models); String[] rows = coordinatesData.replaceAll("\r", "\n").split("\n"); Integer filenameColumn = null; Integer polygonColumn = null; @@ -399,9 +367,9 @@ public class OverviewParser { return images; } - protected List<OverviewImage> processJsonCoordinates(final Set<Model> models, final List<OverviewImage> images, final String json) + protected List<OverviewImage> processJsonCoordinates(final Set<ModelData> models, final List<OverviewImage> images, final String json) throws InvalidOverviewFile { - Map<String, Model> modelMapping = createMapping(models); + Map<String, ModelData> modelMapping = createMapping(models); ObjectMapper mapper = new ObjectMapper(); final SimpleModule module = new SimpleModule(); module.addDeserializer(OverviewLink.class, new OverviewLinkDeserializer()); @@ -429,7 +397,7 @@ public class OverviewParser { ((OverviewImageLink) link).setLinkedOverviewImage(linkImage); } if (link instanceof OverviewModelLink) { - Model model = modelMapping.get(((OverviewModelLink) link).getLinkedModel().getName().toLowerCase()); + ModelData model = modelMapping.get(((OverviewModelLink) link).getLinkedModel().getName().toLowerCase()); if (model == null) { throw new InvalidOverviewFile(((OverviewModelLink) link).getLinkedModel().getName() + " is missing"); @@ -454,35 +422,32 @@ public class OverviewParser { * Creates a link from parameters and place it in appropriate * {@link OverviewImage}. * - * @param filename - * {@link OverviewImage#filename name of the image} - * @param polygon - * {@link OverviewImage#polygon polygon} describing link - * @param linkTarget - * defines target that should be invoked when the link is activated. - * This target is either a file name (in case of - * {@link #MODEL_LINK_TYPE} or {@link #IMAGE_LINK_TYPE}) or a search - * string (in case of {@link #SEARCH_LINK_TYPE}). - * @param coord - * coordinates on the model where redirection should be placed in case - * of {@link #MODEL_LINK_TYPE} connection - * @param zoomLevel - * zoom level on the model where redirection should be placed in case - * of {@link #MODEL_LINK_TYPE} connection - * @param linkType - * type of the connection. This will define implementation of - * {@link OverviewImage} that will be used. For now three values are - * acceptable: {@link #MODEL_LINK_TYPE}, {@link #IMAGE_LINK_TYPE}, - * {@link #SEARCH_LINK_TYPE}. - * @param images - * list of images that are available - * @param models - * list of models that are available - * @throws InvalidCoordinatesFile - * thrown when one of the input parameters is invalid + * @param filename filename name of the image + * @param polygon polygon polygon describing link + * @param linkTarget defines target that should be invoked when the link is activated. + * This target is either a file name (in case of + * {@link #MODEL_LINK_TYPE} or {@link #IMAGE_LINK_TYPE}) or a search + * string (in case of {@link #SEARCH_LINK_TYPE}). + * @param coord coordinates on the model where redirection should be placed in case + * of {@link #MODEL_LINK_TYPE} connection + * @param zoomLevel zoom level on the model where redirection should be placed in case + * of {@link #MODEL_LINK_TYPE} connection + * @param linkType type of the connection. This will define implementation of + * {@link OverviewImage} that will be used. For now three values are + * acceptable: {@link #MODEL_LINK_TYPE}, {@link #IMAGE_LINK_TYPE}, + * {@link #SEARCH_LINK_TYPE}. + * @param images list of images that are available + * @param models list of models that are available + * @throws InvalidCoordinatesFile thrown when one of the input parameters is invalid */ - private void createOverviewLink(final String filename, final String polygon, final String linkTarget, final String coord, final String zoomLevel, - final String linkType, final List<OverviewImage> images, final Map<String, Model> models) throws InvalidCoordinatesFile { + private void createOverviewLink(final String filename, + final String polygon, + final String linkTarget, + final String coord, + final String zoomLevel, + final String linkType, + final List<OverviewImage> images, + final Map<String, ModelData> models) throws InvalidCoordinatesFile { OverviewImage image = null; for (final OverviewImage oi : images) { if (oi.getFilename().equalsIgnoreCase(filename)) { @@ -494,7 +459,7 @@ public class OverviewParser { } OverviewLink ol = null; if (linkType.equals(MODEL_LINK_TYPE)) { - Model model = models.get(linkTarget.toLowerCase()); + ModelData model = models.get(linkTarget.toLowerCase()); if (model == null) { throw new InvalidCoordinatesFile("Unknown model in \"" + COORDINATES_FILENAME + "\" file: " + linkTarget); } diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java index b5f450031f4f9d21313458eba8b0fdb377bc8c4e..51e60b8766d5525509f02858b723c69d49cb5145 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java @@ -7,6 +7,7 @@ import lcsb.mapviewer.converter.zip.ImageZipEntryFile; import lcsb.mapviewer.converter.zip.LayoutZipEntryFile; import lcsb.mapviewer.converter.zip.ZipEntryFile; import lcsb.mapviewer.model.Project; +import lcsb.mapviewer.model.cache.UploadedFileEntry; import lcsb.mapviewer.model.map.InconsistentModelException; import lcsb.mapviewer.model.map.compartment.Compartment; import lcsb.mapviewer.model.map.compartment.SquareCompartment; @@ -30,6 +31,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; @@ -72,17 +74,6 @@ public class ProjectFactory { public Project create(final ComplexZipConverterParams params, final Project project) throws InvalidInputDataExecption, ConverterException { try { - Model model = converter.createModel(params); - - Set<Model> models = new HashSet<>(); - models.add(model); - models.addAll(model.getSubmodels()); - - project.addModel(model); - for (final Model m : model.getSubmodels()) { - project.addModel(m); - } - ZipFile zipFile = params.getZipFile(); Enumeration<? extends ZipEntry> entries; @@ -103,10 +94,12 @@ public class ProjectFactory { } } } + converter.createModel(params, project); + + if (!imageEntries.isEmpty()) { OverviewParser parser = new OverviewParser(); - project - .addOverviewImages(parser.parseOverviewLinks(models, imageEntries, params.getVisualizationDir(), zipFile)); + project.addOverviewImages(parser.parseOverviewLinks(project.getModels(), imageEntries, params.getVisualizationDir(), zipFile)); } if (!project.getGlyphs().isEmpty()) { assignGlyphsToElements(project); @@ -151,7 +144,7 @@ public class ProjectFactory { String[] lines = notes.split("[\n\r]+"); StringBuilder result = new StringBuilder(); for (final String line : lines) { - if (!line.startsWith("Glyph:")) { + if (!line.startsWith(ComplexZipConverter.GLYPH_PREFIX)) { result.append(line).append("\n"); } } @@ -161,8 +154,8 @@ public class ProjectFactory { Glyph extractGlyph(final Project project, final String notes) throws InvalidGlyphFile { String[] lines = notes.split("[\n\r]+"); for (final String line : lines) { - if (line.startsWith("Glyph:")) { - String glyphString = line.replace("Glyph:", "").trim().toLowerCase(); + if (line.startsWith(ComplexZipConverter.GLYPH_PREFIX)) { + String glyphString = line.replace(ComplexZipConverter.GLYPH_PREFIX, "").trim().toLowerCase(); for (final Glyph glyph : project.getGlyphs()) { if (glyph.getFile().getOriginalFileName().toLowerCase().equalsIgnoreCase(glyphString)) { return glyph; @@ -189,12 +182,28 @@ public class ProjectFactory { addModelFileToZip(mapping, "submaps/mapping." + converter.getFileExtensions().get(0), converter, zos); + for (ModelData model : project.getModels()) { + addGlyphsToZip(model.getModel(), zos); + } + } catch (IOException ioe) { throw new ConverterException(ioe); } return byteArrayOutputStream.toByteArray(); } + private void addGlyphsToZip(final Model model, final ZipOutputStream zos) throws IOException { + for (Element element : model.getElements()) { + if (element.getGlyph() != null) { + UploadedFileEntry uploadedFileEntry = element.getGlyph().getFile(); + ZipEntry entry = new ZipEntry("glyphs/" + new File(uploadedFileEntry.getOriginalFileName()).getName()); + zos.putNextEntry(entry); + zos.write(uploadedFileEntry.getFileContent()); + zos.closeEntry(); + } + } + } + private int idCounter = 0; private Model createMappingModel(final Set<ModelData> models) { @@ -228,7 +237,16 @@ public class ProjectFactory { Species sourceElement = getCompartmentChildForConnection(parentElement.getElementId(), mappingParentCompartment); String notes = sourceElement.getNotes(); - notes += ComplexZipConverter.IMMEDIATE_LINK_PREFIX + parentElement.getImmediateLink() + "\n"; + notes += "\n" + ComplexZipConverter.IMMEDIATE_LINK_PREFIX + parentElement.getImmediateLink(); + sourceElement.setNotes(notes); + } + if (parentElement.getGlyph() != null) { + UploadedFileEntry uploadedFileEntry = parentElement.getGlyph().getFile(); + Compartment mappingParentCompartment = getCompartmentForConnection(parentModel.getName(), mapping); + + Species sourceElement = getCompartmentChildForConnection(parentElement.getElementId(), mappingParentCompartment); + String notes = sourceElement.getNotes(); + notes += "\n" + ComplexZipConverter.GLYPH_PREFIX + "glyphs/" + new File(uploadedFileEntry.getOriginalFileName()).getName(); sourceElement.setNotes(notes); } } diff --git a/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java b/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java index 5850f0dad1bc7462da0d3249e7b4de1a83f6f784..bea7c1a8885b1d67c9bc966c546ece254a9cb132 100644 --- a/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java +++ b/converter/src/test/java/lcsb/mapviewer/converter/ComplexZipConverterTest.java @@ -4,6 +4,7 @@ import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.InvalidClassException; import lcsb.mapviewer.converter.zip.LayoutZipEntryFile; import lcsb.mapviewer.converter.zip.ModelZipEntryFile; +import lcsb.mapviewer.model.Project; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; import lcsb.mapviewer.model.map.model.SubmodelType; @@ -40,7 +41,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { } @Test - public void testConstructor3() throws Exception { + public void testConstructor3() { new ComplexZipConverter(MockConverter.class); } @@ -54,7 +55,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - Model model = converter.createModel(params); + Model model = converter.createModel(params, new Project()); assertNotNull(model); assertEquals("main", model.getName()); assertEquals(3, model.getSubmodelConnections().size()); @@ -108,7 +109,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - Model model = converter.createModel(params); + Model model = converter.createModel(params, new Project()); assertNotNull(model); assertEquals("main", model.getName()); assertEquals(3, model.getSubmodelConnections().size()); @@ -160,7 +161,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s1.xml", "s1", false, false, SubmodelType.DOWNSTREAM_TARGETS)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - converter.createModel(params); + converter.createModel(params, new Project()); } @Test(expected = InvalidArgumentException.class) @@ -174,7 +175,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - converter.createModel(params); + converter.createModel(params, new Project()); } @Test(expected = InvalidArgumentException.class) @@ -188,7 +189,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - converter.createModel(params); + converter.createModel(params, new Project()); } @Test(expected = InvalidArgumentException.class) @@ -202,7 +203,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - converter.createModel(params); + converter.createModel(params, new Project()); } @Test @@ -216,7 +217,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s2.xml", "s2", false, false, SubmodelType.PATHWAY)); params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", "", false, false, null)); - Model model = converter.createModel(params); + Model model = converter.createModel(params, new Project()); assertNotNull(model); @@ -247,7 +248,7 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.entry(new ModelZipEntryFile("s3.xml", "s3", false, false, SubmodelType.UNKNOWN)); params.entry(new ModelZipEntryFile("mapping.xml", "", false, false, null)); params.entry(new ModelZipEntryFile("blabla.xml", "s3", false, false, SubmodelType.UNKNOWN)); - converter.createModel(params); + converter.createModel(params, new Project()); } @Test(expected = InvalidArgumentException.class) @@ -258,11 +259,11 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { params.zipFile(new ZipFile("testFiles/invalid_mapping.zip")); params.entry(new ModelZipEntryFile("main.xml", "main", true, false, null)); params.entry(new ModelZipEntryFile("mapping.xml", null, false, true, null)); - converter.createModel(params); + converter.createModel(params, new Project()); } @Test - public void testIsIgnoredFileForMac() throws Exception { + public void testIsIgnoredFileForMac() { ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class); assertTrue(converter.isIgnoredFile("__MACOSX/.desc")); assertTrue(converter.isIgnoredFile(".DS_Store")); @@ -272,13 +273,13 @@ public class ComplexZipConverterTest extends ConverterTestFunctions { } @Test - public void testIsIgnoredFileForOldMacEntries() throws Exception { + public void testIsIgnoredFileForOldMacEntries() { ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class); assertTrue(converter.isIgnoredFile(".DS_Store/.desc")); } @Test - public void testIsIgnoredFileForValidFiles() throws Exception { + public void testIsIgnoredFileForValidFiles() { ComplexZipConverter converter = new ComplexZipConverter(MockConverter.class); assertFalse(converter.isIgnoredFile("mapping.xml")); } diff --git a/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java b/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java index 02ddc58b20808b342eaa3c85d701483c48e696fe..1485ed962095df0b1426cb10c0d77fa66a1479c4 100644 --- a/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java +++ b/converter/src/test/java/lcsb/mapviewer/converter/OverviewParserTest.java @@ -1,8 +1,16 @@ package lcsb.mapviewer.converter; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import lcsb.mapviewer.converter.zip.ImageZipEntryFile; +import lcsb.mapviewer.model.map.OverviewImage; +import lcsb.mapviewer.model.map.OverviewLink; +import lcsb.mapviewer.model.map.OverviewModelLink; +import lcsb.mapviewer.model.map.model.Model; +import lcsb.mapviewer.model.map.model.ModelData; +import lcsb.mapviewer.model.map.model.ModelFullIndexed; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import java.awt.geom.Point2D; import java.io.File; @@ -16,23 +24,15 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import org.apache.commons.io.FileUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import lcsb.mapviewer.converter.zip.ImageZipEntryFile; -import lcsb.mapviewer.model.map.OverviewImage; -import lcsb.mapviewer.model.map.OverviewLink; -import lcsb.mapviewer.model.map.OverviewModelLink; -import lcsb.mapviewer.model.map.model.Model; -import lcsb.mapviewer.model.map.model.ModelFullIndexed; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; public class OverviewParserTest extends ConverterTestFunctions { private static final String TEST_FILES_VALID_OVERVIEW_ZIP = "testFiles/valid_overview.zip"; private static final String TEST_FILES_VALID_OVERVIEW_CASE_SENSITIVE_ZIP = "testFiles/valid_overview_case_sensitive.zip"; - private OverviewParser parser = new OverviewParser(); + private final OverviewParser parser = new OverviewParser(); @Before public void setUp() throws Exception { @@ -44,7 +44,7 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test public void testParsingValidFile() throws Exception { - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); List<ImageZipEntryFile> imageEntries = createImageEntries(TEST_FILES_VALID_OVERVIEW_ZIP); List<OverviewImage> result = parser.parseOverviewLinks(models, imageEntries, null, new ZipFile(TEST_FILES_VALID_OVERVIEW_ZIP)); @@ -66,8 +66,8 @@ public class OverviewParserTest extends ConverterTestFunctions { assertTrue(link instanceof OverviewModelLink); OverviewModelLink modelLink = (OverviewModelLink) link; - Model mainModel = models.iterator().next(); - assertEquals(mainModel.getModelData(), modelLink.getLinkedModel()); + ModelData mainModel = models.iterator().next(); + assertEquals(mainModel, modelLink.getLinkedModel()); assertEquals((Integer) 10, modelLink.getxCoord()); assertEquals((Integer) 10, modelLink.getyCoord()); assertEquals((Integer) 3, modelLink.getZoomLevel()); @@ -75,7 +75,7 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test public void testParsingValidCaseSensitiveFile() throws Exception { - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); List<ImageZipEntryFile> imageEntries = createImageEntries(TEST_FILES_VALID_OVERVIEW_CASE_SENSITIVE_ZIP); for (final ImageZipEntryFile imageZipEntryFile : imageEntries) { imageZipEntryFile.setFilename(imageZipEntryFile.getFilename().toLowerCase()); @@ -99,8 +99,8 @@ public class OverviewParserTest extends ConverterTestFunctions { assertTrue(link instanceof OverviewModelLink); OverviewModelLink modelLink = (OverviewModelLink) link; - Model mainModel = models.iterator().next(); - assertEquals(mainModel.getModelData(), modelLink.getLinkedModel()); + ModelData mainModel = models.iterator().next(); + assertEquals(mainModel, modelLink.getLinkedModel()); assertEquals((Integer) 10, modelLink.getxCoord()); assertEquals((Integer) 10, modelLink.getyCoord()); assertEquals((Integer) 3, modelLink.getZoomLevel()); @@ -109,8 +109,7 @@ public class OverviewParserTest extends ConverterTestFunctions { private List<ImageZipEntryFile> createImageEntries(final String string) throws IOException { List<ImageZipEntryFile> result = new ArrayList<>(); - ZipFile zipFile = new ZipFile(string); - try { + try (ZipFile zipFile = new ZipFile(string)) { Enumeration<? extends ZipEntry> entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); @@ -119,14 +118,12 @@ public class OverviewParserTest extends ConverterTestFunctions { } } return result; - } finally { - zipFile.close(); } } @Test public void testParsingValidFile2() throws Exception { - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); String tmpDir = Files.createTempDirectory("tmp").toFile().getAbsolutePath(); @@ -145,7 +142,7 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test(expected = InvalidOverviewFile.class) public void testParsingInvalidFile1() throws Exception { List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_1.zip"); - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/invalid_overview_1.zip")); } @@ -153,7 +150,7 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test(expected = InvalidOverviewFile.class) public void testParsingInvalidFile2() throws Exception { List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_2.zip"); - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/invalid_overview_2.zip")); } @@ -161,16 +158,16 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test(expected = InvalidOverviewFile.class) public void testParsingInvalidFile3() throws Exception { List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/invalid_overview_3.zip"); - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/invalid_overview_3.zip")); } - private Set<Model> createValidTestMapModel() { - Set<Model> result = new HashSet<>(); + private Set<ModelData> createValidTestMapModel() { + Set<ModelData> result = new HashSet<>(); Model model = new ModelFullIndexed(null); model.setName("main"); - result.add(model); + result.add(model.getModelData()); return result; } @@ -181,9 +178,9 @@ public class OverviewParserTest extends ConverterTestFunctions { public void testParseInvalidCoordinates() throws Exception { String invalidCoordinates = "test.png\t10,10 100,10 100,100 10,10\tmain.xml\t10,10\t3\n" + "test.png\t10,10 10,400 400,400 400,10\tmain.xml\t10,10\t4"; - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); - List<OverviewImage> images = new ArrayList<OverviewImage>(); + List<OverviewImage> images = new ArrayList<>(); OverviewImage oi = new OverviewImage(); oi.setFilename("test.png"); oi.setWidth(1000); @@ -198,9 +195,9 @@ public class OverviewParserTest extends ConverterTestFunctions { String invalidCoordinates = "FILE\tPOLYGON\tLINK_TARGET\tMODEL_COORDINATES\tMODEL_ZOOM_LEVEL\tLINK_TYPE\n" + "test.png\t10,10 100,10 100,100 10,10\tmain.xml\t10,10\t3\tMODEL\n" + "test.png\t200,200 200,400 400,400 400,200\tmain.xml\t10,10\t4\tMODEL"; - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); - List<OverviewImage> images = new ArrayList<OverviewImage>(); + List<OverviewImage> images = new ArrayList<>(); OverviewImage oi = new OverviewImage(); oi.setFilename("test.png"); oi.setWidth(1000); @@ -215,7 +212,7 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test public void testParseValidComplexCoordinates() throws Exception { String invalidCoordinates = FileUtils.readFileToString(new File("testFiles/coordinates.txt"), "UTF-8"); - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); List<OverviewImage> images = new ArrayList<>(); OverviewImage oi = new OverviewImage(); @@ -239,7 +236,7 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test public void testParseValidComplexCoordinatesWithExtraImages() throws Exception { String invalidCoordinates = FileUtils.readFileToString(new File("testFiles/coordinates.txt"), "UTF-8"); - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); List<OverviewImage> images = new ArrayList<>(); OverviewImage oi = new OverviewImage(); @@ -267,10 +264,10 @@ public class OverviewParserTest extends ConverterTestFunctions { @Test public void testJsonCoordinates() throws Exception { - Set<Model> models = createValidTestMapModel(); + Set<ModelData> models = createValidTestMapModel(); Model child = new ModelFullIndexed(null); child.setName("child"); - models.add(child); + models.add(child.getModelData()); List<ImageZipEntryFile> imageEntries = createImageEntries("testFiles/valid_overview_with_json.zip"); List<OverviewImage> result = parser.parseOverviewLinks(models, imageEntries, null, new ZipFile("testFiles/valid_overview_with_json.zip")); diff --git a/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java b/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java index 327f984bdc2ab4ec4d4574fdf6c1e679b6800550..ea88c764532c884c45bd397a0572489ff5e9fe9c 100644 --- a/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java +++ b/converter/src/test/java/lcsb/mapviewer/converter/ProjectFactoryTest.java @@ -149,7 +149,7 @@ public class ProjectFactoryTest extends ConverterTestFunctions { public void testParseGlyphsAndPutThemAsElementGlyphs() throws Exception { Model model = new ModelFullIndexed(null); final GenericProtein protein = createProtein(); - protein.setNotes("Glyph: glyphs/g1.png"); + protein.setNotes(ComplexZipConverter.GLYPH_PREFIX + "glyphs/g1.png"); model.addElement(protein); MockConverter.modelToBeReturned = model; @@ -188,7 +188,7 @@ public class ProjectFactoryTest extends ConverterTestFunctions { final Layer layer = new Layer(); final LayerText text = new LayerText(); - text.setNotes("Glyph: glyphs/g1.png"); + text.setNotes(ComplexZipConverter.GLYPH_PREFIX + " glyphs/g1.png"); layer.addLayerText(text); model.addLayer(layer); 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 5d2fdaadc98bb325e3952ee48b079112c7847e80..2a3b2cebfcfe2ca83126c712023003ee6afd0418 100644 --- a/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java +++ b/model-command/src/test/java/lcsb/mapviewer/commands/ColorModelCommandTest.java @@ -45,7 +45,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testAliasMatchWithInvalidElementId() throws Exception { + public void testAliasMatchWithInvalidElementId() { GenericDataOverlayEntry colorSchema = new GenericDataOverlayEntry(); colorSchema.setName(null); colorSchema.setElementId("1"); @@ -65,7 +65,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testSpeciesMatchWithProteinType() throws Exception { + public void testSpeciesMatchWithProteinType() { GenericDataOverlayEntry colorSchema = new GenericDataOverlayEntry(); colorSchema.setName("s1"); colorSchema.addType(Protein.class); @@ -82,7 +82,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testSpeciesMatchWithMiriamData() throws Exception { + public void testSpeciesMatchWithMiriamData() { GenericDataOverlayEntry colorSchema = new GenericDataOverlayEntry(); colorSchema.setName("s1"); colorSchema.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA")); @@ -105,7 +105,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testSpeciesMatchWithMiriamDataDifferentAnnotator() throws Exception { + public void testSpeciesMatchWithMiriamDataDifferentAnnotator() { GenericDataOverlayEntry colorSchema = new GenericDataOverlayEntry(); colorSchema.setName("s1"); colorSchema.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA")); @@ -123,7 +123,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionMatchWithProteinMiriamData() throws Exception { + public void testReactionMatchWithProteinMiriamData() { GenericDataOverlayEntry colorSchema = new GenericDataOverlayEntry(); colorSchema.addMiriamData(new MiriamData(MiriamType.HGNC_SYMBOL, "SNCA")); @@ -138,7 +138,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionMatchWithMiriamData() throws Exception { + public void testReactionMatchWithMiriamData() { GenericDataOverlayEntry colorSchema = new GenericDataOverlayEntry(); colorSchema.addMiriamData(new MiriamData(MiriamType.PUBMED, "1234")); @@ -155,7 +155,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { @Test - public void testGetModifiedElements() throws Exception { + public void testGetModifiedElements() { Reaction reaction = new Reaction("re"); reaction.addMiriamData(new MiriamData(MiriamType.PUBMED, "1234")); @@ -174,7 +174,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testApplyColorToReaction() throws Exception { + public void testApplyColorToReaction() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -249,7 +249,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testColoring2() throws Exception { + public void testColoring2() { Model model = createSimpleModel(); GenericProtein protein = createProteinWithLayout(); protein.addMiriamData(new MiriamData(MiriamType.HGNC, "11138")); @@ -280,7 +280,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testColorTheSameElementTwiceUsingDifferentSelector() throws Exception { + public void testColorTheSameElementTwiceUsingDifferentSelector() { Model model = createSimpleModel(); GenericProtein protein = createProteinWithLayout(); protein.setName("SNCA"); @@ -304,7 +304,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionColoring1() throws Exception { + public void testReactionColoring1() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -326,7 +326,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionColoring2() throws Exception { + public void testReactionColoring2() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -335,7 +335,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { Reaction reaction = createReactionWithLayout(protein1, protein1); model.addReaction(reaction); - Collection<DataOverlayEntry> schemas = new ArrayList<DataOverlayEntry>(); + Collection<DataOverlayEntry> schemas = new ArrayList<>(); DataOverlayEntry schema = new GenericDataOverlayEntry(); schema.setElementId(reaction.getIdReaction()); schema.setColor(Color.RED); @@ -351,7 +351,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionColoring3() throws Exception { + public void testReactionColoring3() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -360,7 +360,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { Reaction reaction = createReactionWithLayout(protein1, protein1); model.addReaction(reaction); - Collection<DataOverlayEntry> schemas = new ArrayList<DataOverlayEntry>(); + Collection<DataOverlayEntry> schemas = new ArrayList<>(); DataOverlayEntry schema = new GenericDataOverlayEntry(); schema.setElementId(reaction.getIdReaction()); schema.setValue(-1.0); @@ -376,7 +376,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionColoring4() throws Exception { + public void testReactionColoring4() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -386,7 +386,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { reaction.addMiriamData(new MiriamData(MiriamType.PUBMED, "12345")); model.addReaction(reaction); - Collection<DataOverlayEntry> schemas = new ArrayList<DataOverlayEntry>(); + Collection<DataOverlayEntry> schemas = new ArrayList<>(); DataOverlayEntry schema = new GenericDataOverlayEntry(); schema.addMiriamData(new MiriamData(MiriamType.PUBMED, "12345")); schema.setValue(-1.0); @@ -403,7 +403,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testColoringComplexModel() throws Exception { + public void testColoringComplexModel() { Model model = createSimpleModel(); Model model2 = createSimpleModel(); @@ -420,8 +420,10 @@ public class ColorModelCommandTest extends CommandTestFunctions { Model coloredModel2 = coloredModel.getSubmodelConnections().iterator().next().getSubmodel().getModel(); Model coloredModel3 = coloredModel.getSubmodelByConnectionName("BLA"); - assertNotEquals(coloredModel2.getElementByElementId(protein1.getElementId()).getFillColor(), model2.getElementByElementId(protein1.getElementId()).getFillColor()); - assertNotEquals(coloredModel3.getElementByElementId(protein1.getElementId()).getFillColor(), model2.getElementByElementId(protein1.getElementId()).getFillColor()); + assertNotEquals(coloredModel2.getElementByElementId(protein1.getElementId()).getFillColor(), + model2.getElementByElementId(protein1.getElementId()).getFillColor()); + assertNotEquals(coloredModel3.getElementByElementId(protein1.getElementId()).getFillColor(), + model2.getElementByElementId(protein1.getElementId()).getFillColor()); } @Test @@ -453,7 +455,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testColoredReactions() throws Exception { + public void testColoredReactions() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -477,7 +479,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testColoredReactions2() throws Exception { + public void testColoredReactions2() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -506,7 +508,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionColoringWithModelNotMatching() throws Exception { + public void testReactionColoringWithModelNotMatching() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -529,7 +531,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testReactionColoringWithModelMatch() throws Exception { + public void testReactionColoringWithModelMatch() { Model model = createSimpleModel(); Protein protein1 = createProteinWithLayout(); Protein protein2 = createProteinWithLayout(); @@ -552,7 +554,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testAliasColoringWithModelNotMatching() throws Exception { + public void testAliasColoringWithModelNotMatching() { Model model = createSimpleModel(); Protein p1 = createProtein(); p1.setName("CNC"); @@ -571,7 +573,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testAliasColoringWithModelMatch() throws Exception { + public void testAliasColoringWithModelMatch() { Model model = createSimpleModel(); Protein p1 = createProtein(); p1.setName("CNC"); @@ -606,7 +608,7 @@ public class ColorModelCommandTest extends CommandTestFunctions { } @Test - public void testAliasColoringWithElementIdMatch() throws Exception { + public void testAliasColoringWithElementIdMatch() { Model model = createSimpleModel(); model.addElement(createProtein()); diff --git a/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java b/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java index b1862ab7964b2350d3a4aa87e535e0f713b22ec8..776c2556b7f86616cadf9afc6834cc3d0595d3fe 100644 --- a/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java +++ b/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java @@ -3,23 +3,29 @@ package lcsb.mapviewer.model; import lcsb.mapviewer.common.Comparator; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.comparator.SetComparator; +import lcsb.mapviewer.model.map.layout.graphics.Glyph; +import lcsb.mapviewer.model.map.layout.graphics.GlyphComparator; import lcsb.mapviewer.model.map.model.ModelComparator; import lcsb.mapviewer.model.map.model.ModelData; import lcsb.mapviewer.model.map.model.ModelDataComparator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.HashSet; + public class ProjectComparator extends Comparator<Project> { private static final Logger logger = LogManager.getLogger(); private final ModelComparator modelComparator; private final SetComparator<ModelData> modelDataSetComparator; + private final SetComparator<Glyph> glyphSetComparator; public ProjectComparator(final double epsilon) { super(Project.class); modelComparator = new ModelComparator(epsilon); modelDataSetComparator = new SetComparator<>(new ModelDataComparator(epsilon)); + glyphSetComparator = new SetComparator<>(new GlyphComparator()); } public ProjectComparator() { @@ -28,7 +34,13 @@ public class ProjectComparator extends Comparator<Project> { @Override protected int internalCompare(final Project arg0, final Project arg1) { - int compareResult = modelComparator.compare(arg0.getTopModel(), arg1.getTopModel()); + int compareResult = glyphSetComparator.compare(new HashSet<>(arg0.getGlyphs()), new HashSet<>(arg1.getGlyphs())); + if (compareResult != 0) { + logger.debug("Glyphs different"); + return compareResult; + } + + compareResult = modelComparator.compare(arg0.getTopModel(), arg1.getTopModel()); if (compareResult != 0) { logger.debug("Top model different: {}, {}", arg0.getTopModel(), arg1.getTopModel()); return compareResult; @@ -38,6 +50,7 @@ public class ProjectComparator extends Comparator<Project> { logger.debug("Models different"); return modelDataSetComparator.compare(arg0.getModels(), arg1.getModels()); } + return 0; } diff --git a/model/src/main/java/lcsb/mapviewer/model/cache/UploadedFileEntryComparator.java b/model/src/main/java/lcsb/mapviewer/model/cache/UploadedFileEntryComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..2dda81abcb2ae007c29ca5aaba6f5ad1e1f87e4c --- /dev/null +++ b/model/src/main/java/lcsb/mapviewer/model/cache/UploadedFileEntryComparator.java @@ -0,0 +1,32 @@ +package lcsb.mapviewer.model.cache; + +import lcsb.mapviewer.common.Comparator; +import lcsb.mapviewer.common.comparator.StringComparator; + +import java.util.Arrays; + +public class UploadedFileEntryComparator extends Comparator<UploadedFileEntry> { + + public UploadedFileEntryComparator() { + super(UploadedFileEntry.class, true); + } + + + @Override + protected int internalCompare(final UploadedFileEntry arg0, final UploadedFileEntry arg1) { + StringComparator stringComparator = new StringComparator(); + + if (stringComparator.compare(arg0.getOriginalFileName(), arg1.getOriginalFileName()) != 0) { + logger.debug("Original file name is different: {} != {}", arg0.getOriginalFileName(), arg1.getOriginalFileName()); + return stringComparator.compare(arg0.getOriginalFileName(), arg1.getOriginalFileName()); + } + + if (!Arrays.equals(arg0.getFileContent(), arg1.getFileContent())) { + logger.debug("Glyph content different for file {}.", arg0.getOriginalFileName()); + return -1; + } + + return 0; + } + +} diff --git a/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/GlyphComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/GlyphComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..e217a4bc5d86d30bfb5e4fe12435bf3c95fea74e --- /dev/null +++ b/model/src/main/java/lcsb/mapviewer/model/map/layout/graphics/GlyphComparator.java @@ -0,0 +1,24 @@ +package lcsb.mapviewer.model.map.layout.graphics; + +import lcsb.mapviewer.common.Comparator; +import lcsb.mapviewer.model.cache.UploadedFileEntryComparator; + +public class GlyphComparator extends Comparator<Glyph> { + + + public GlyphComparator() { + super(Glyph.class, true); + } + + @Override + protected int internalCompare(final Glyph arg0, final Glyph arg1) { + UploadedFileEntryComparator fileComparator = new UploadedFileEntryComparator(); + + if (fileComparator.compare(arg0.getFile(), arg1.getFile()) != 0) { + return fileComparator.compare(arg0.getFile(), arg1.getFile()); + } + + return 0; + } + +} diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java index 72997425c9a9cc13cb463d4658542bdd5af140d1..e4cd56e75133735ca72d43f0461967a92b483846 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/species/ElementComparator.java @@ -14,6 +14,7 @@ import lcsb.mapviewer.model.graphics.VerticalAlign; import lcsb.mapviewer.model.map.MiriamData; import lcsb.mapviewer.model.map.MiriamDataComparator; import lcsb.mapviewer.model.map.compartment.CompartmentComparator; +import lcsb.mapviewer.model.map.layout.graphics.GlyphComparator; import lcsb.mapviewer.model.map.model.ElementSubmodelConnectionComparator; /** @@ -63,6 +64,7 @@ public class ElementComparator extends Comparator<Element> { StringComparator stringComparator = new StringComparator(); ColorComparator colorComparator = new ColorComparator(); DoubleComparator doubleComparator = new DoubleComparator(epsilon); + GlyphComparator glyphComparator = new GlyphComparator(); if (stringComparator.compare(arg0.getElementId(), arg1.getElementId()) != 0) { logger.debug("ElementId different: {}, {}", arg0.getElementId(), arg1.getElementId()); @@ -216,6 +218,11 @@ public class ElementComparator extends Comparator<Element> { return stringComparator.compare(arg0.getImmediateLink(), arg1.getImmediateLink()); } + if (glyphComparator.compare(arg0.getGlyph(), arg1.getGlyph()) != 0) { + logger.debug("Glyph different: {}, {}", arg0.getGlyph(), arg1.getGlyph()); + return glyphComparator.compare(arg0.getGlyph(), arg1.getGlyph()); + } + return 0; }