From 79d6cecbd7a3c5dbaedd44a803210dded3466ee2 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <p.gawron@atcomp.pl> Date: Thu, 13 Mar 2025 14:34:29 +0100 Subject: [PATCH] basic export of project with single file --- .../lcsb/mapviewer/common/Comparator.java | 23 +++--- .../CellDesignerTestFunctions.java | 8 ++ .../model/celldesigner/ProjectExportTest.java | 79 +++++++++++++++++++ .../converter/ComplexZipConverter.java | 1 + .../mapviewer/converter/ProjectFactory.java | 59 +++++++++----- .../mapviewer/model/ProjectComparator.java | 43 ++++++++++ .../model/map/model/ModelComparator.java | 58 ++++++-------- .../model/map/model/ModelDataComparator.java | 26 ++++++ .../map/reaction/AbstractNodeComparator.java | 19 ++--- 9 files changed, 232 insertions(+), 84 deletions(-) create mode 100644 converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/ProjectExportTest.java create mode 100644 model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java create mode 100644 model/src/main/java/lcsb/mapviewer/model/map/model/ModelDataComparator.java diff --git a/commons/src/main/java/lcsb/mapviewer/common/Comparator.java b/commons/src/main/java/lcsb/mapviewer/common/Comparator.java index b096d920c8..772b161ba7 100644 --- a/commons/src/main/java/lcsb/mapviewer/common/Comparator.java +++ b/commons/src/main/java/lcsb/mapviewer/common/Comparator.java @@ -1,21 +1,18 @@ package lcsb.mapviewer.common; -import java.util.ArrayList; -import java.util.List; - +import lcsb.mapviewer.common.exception.NotImplementedException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import lcsb.mapviewer.common.exception.NotImplementedException; +import java.util.ArrayList; +import java.util.List; public abstract class Comparator<T extends Object> implements java.util.Comparator<T> { - /** - * Default class logger. - */ - private static Logger logger = LogManager.getLogger(); - private Class<T> comparatorClazz; - private boolean exactClassMatch; - private List<Comparator<? extends T>> subClassComparatorList = new ArrayList<>(); + protected static Logger logger = LogManager.getLogger(); + + private final Class<T> comparatorClazz; + private final boolean exactClassMatch; + private final List<Comparator<? extends T>> subClassComparatorList = new ArrayList<>(); protected Comparator(final Class<T> clazz) { this(clazz, false); @@ -26,7 +23,7 @@ public abstract class Comparator<T extends Object> implements java.util.Comparat this.exactClassMatch = exactClassMatch; } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) @Override public final int compare(final T arg0, final T arg1) { if (arg0 == null) { @@ -68,7 +65,7 @@ public abstract class Comparator<T extends Object> implements java.util.Comparat return null; } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) private int compareParents(final T arg0, final T arg1) { Comparator parentComparator = getParentComparator(); while (parentComparator != null) { 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 615388da09..ca10f5af92 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 @@ -6,6 +6,7 @@ import lcsb.mapviewer.common.tests.UnitTestFailedWatcher; 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.graphics.HorizontalAlign; import lcsb.mapviewer.model.graphics.VerticalAlign; import lcsb.mapviewer.model.map.Drawable; @@ -283,4 +284,11 @@ public abstract class CellDesignerTestFunctions extends TestUtils { result.setZ(faker.number().numberBetween(1, 100)); return result; } + + protected Project createProject() { + Project project = new Project(); + project.setProjectId(faker.numerify("P########")); + return project; + } + } 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 new file mode 100644 index 0000000000..e2a0795446 --- /dev/null +++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/ProjectExportTest.java @@ -0,0 +1,79 @@ +package lcsb.mapviewer.converter.model.celldesigner; + +import lcsb.mapviewer.converter.ComplexZipConverter; +import lcsb.mapviewer.converter.ComplexZipConverterParams; +import lcsb.mapviewer.converter.ProjectFactory; +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.model.Model; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import static org.junit.Assert.assertEquals; + +public class ProjectExportTest extends CellDesignerTestFunctions { + + private final ProjectComparator projectComparator = new ProjectComparator(); + + private final ZipEntryFileFactory zefFactory = new ZipEntryFileFactory(); + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testBasic() throws Exception { + Project project = createProject(); + Model model = createEmptyModel(); + project.addModel(model); + + final ComplexZipConverter parser = new ComplexZipConverter(CellDesignerXmlParser.class); + final ProjectFactory projectFactory = new ProjectFactory(parser); + + byte[] data = projectFactory.project2zip(project); + + File tempFile = File.createTempFile("CD-", ".zip"); + + try (FileOutputStream outputStream = new FileOutputStream(tempFile)) { + outputStream.write(data); + } + logger.debug(tempFile.getAbsolutePath()); + + final ComplexZipConverterParams complexParams = createDefaultParams(tempFile); + + Project project2 = projectFactory.create(complexParams); + + assertEquals(0, projectComparator.compare(project, project2)); + } + + private ComplexZipConverterParams createDefaultParams(final File tempFile) throws IOException { + final ComplexZipConverterParams complexParams; + complexParams = new ComplexZipConverterParams().zipFile(new ZipFile(tempFile)); + complexParams.visualizationDir(faker.name().username()); + + ZipFile zipFile = new ZipFile(tempFile.getAbsolutePath()); + Enumeration<? extends ZipEntry> entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + ZipEntryFile e = zefFactory.createZipEntryFile(entry, zipFile); + complexParams.entry(e); + } + zipFile.close(); + return complexParams; + } + +} diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java index 3c320b72e1..bea7b0376e 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/ComplexZipConverter.java @@ -427,4 +427,5 @@ public class ComplexZipConverter { } return converter; } + } diff --git a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java index e8af1d4bac..fe2b69e772 100644 --- a/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java +++ b/converter/src/main/java/lcsb/mapviewer/converter/ProjectFactory.java @@ -1,23 +1,12 @@ package lcsb.mapviewer.converter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.converter.zip.GlyphZipEntryFile; 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.map.InconsistentModelException; import lcsb.mapviewer.model.map.layout.graphics.Glyph; import lcsb.mapviewer.model.map.layout.graphics.Layer; import lcsb.mapviewer.model.map.layout.graphics.LayerText; @@ -25,6 +14,19 @@ import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelData; import lcsb.mapviewer.model.map.model.ModelSubmodelConnection; import lcsb.mapviewer.model.map.species.Element; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; public class ProjectFactory { @@ -32,11 +34,11 @@ public class ProjectFactory { * Default class logger. */ @SuppressWarnings("unused") - private Logger logger = LogManager.getLogger(); + private final Logger logger = LogManager.getLogger(); - private ComplexZipConverter converter; + private final ComplexZipConverter converter; - private GlyphParser glyphParser = new GlyphParser(); + private final GlyphParser glyphParser = new GlyphParser(); public ProjectFactory(final ComplexZipConverter converter) { this.converter = converter; @@ -80,12 +82,12 @@ public class ProjectFactory { } } } - if (imageEntries.size() > 0) { + if (!imageEntries.isEmpty()) { OverviewParser parser = new OverviewParser(); project .addOverviewImages(parser.parseOverviewLinks(models, imageEntries, params.getVisualizationDir(), zipFile)); } - if (project.getGlyphs().size() > 0) { + if (!project.getGlyphs().isEmpty()) { assignGlyphsToElements(project); } return project; @@ -97,8 +99,7 @@ public class ProjectFactory { } private void assignGlyphsToElements(final Project project) throws InvalidGlyphFile { - Set<ModelData> models = new HashSet<>(); - models.addAll(project.getModels()); + Set<ModelData> models = new HashSet<>(project.getModels()); for (final ModelData model : project.getModels()) { for (final ModelSubmodelConnection connection : model.getSubmodels()) { @@ -127,10 +128,10 @@ public class ProjectFactory { String removeGlyph(final String notes) { String[] lines = notes.split("[\n\r]+"); - StringBuilder result = new StringBuilder(""); + StringBuilder result = new StringBuilder(); for (final String line : lines) { if (!line.startsWith("Glyph:")) { - result.append(line + "\n"); + result.append(line).append("\n"); } } return result.toString(); @@ -152,4 +153,20 @@ public class ProjectFactory { return null; } + public byte[] project2zip(final Project project) throws ConverterException, InconsistentModelException { + Converter converter = this.converter.createConverterInstance(); + String topModelContent = converter.model2String(project.getTopModel()); + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + try (ZipOutputStream zos = new ZipOutputStream(byteArrayOutputStream)) { + ZipEntry entry = new ZipEntry(project.getTopModel().getName() + "." + converter.getFileExtensions().get(0)); + + zos.putNextEntry(entry); + zos.write(topModelContent.getBytes()); + zos.closeEntry(); + } catch (IOException ioe) { + throw new ConverterException(ioe); + } + return byteArrayOutputStream.toByteArray(); + } } diff --git a/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java b/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java new file mode 100644 index 0000000000..0aa6694500 --- /dev/null +++ b/model/src/main/java/lcsb/mapviewer/model/ProjectComparator.java @@ -0,0 +1,43 @@ +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.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; + +public class ProjectComparator extends Comparator<Project> { + + private static final Logger logger = LogManager.getLogger(); + + private final ModelComparator modelComparator; + private final SetComparator<ModelData> modelDataSetComparator; + + public ProjectComparator(final double epsilon) { + super(Project.class); + modelComparator = new ModelComparator(epsilon); + modelDataSetComparator = new SetComparator<>(new ModelDataComparator(epsilon)); + } + + public ProjectComparator() { + this(Configuration.EPSILON); + } + + @Override + protected int internalCompare(final Project arg0, final Project arg1) { + if (modelComparator.compare(arg0.getTopModel(), arg1.getTopModel()) != 0) { + logger.debug("Top model different: {}, {}", arg0.getTopModel(), arg1.getTopModel()); + return modelComparator.compare(arg0.getTopModel(), arg1.getTopModel()); + } + + if (modelDataSetComparator.compare(arg0.getModels(), arg1.getModels()) != 0) { + logger.debug("Models different"); + return modelDataSetComparator.compare(arg0.getModels(), arg1.getModels()); + } + return 0; + } + +} 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 16f6065ca4..3b56cb0799 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 @@ -1,14 +1,5 @@ package lcsb.mapviewer.model.map.model; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import lcsb.mapviewer.common.Comparator; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.comparator.CalendarComparator; @@ -33,22 +24,23 @@ import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.ElementComparator; import lcsb.mapviewer.modelutils.map.ElementUtils; +import java.util.Calendar; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + /** * Comparator for {@link Model} class. - * + * * @author Piotr Gawron - * */ public class ModelComparator extends Comparator<Model> { - /** - * Default class logger. - */ - private static Logger logger = LogManager.getLogger(); /** * Epsilon value used for comparison of doubles. */ - private double epsilon; + private final double epsilon; private SetComparator<SbmlUnit> unitSetComparator = new SetComparator<>(new SbmlUnitComparator()); @@ -56,13 +48,12 @@ public class ModelComparator extends Comparator<Model> { private ElementComparator elementComparator; - private ElementUtils eu = new ElementUtils(); + private final ElementUtils eu = new ElementUtils(); /** * Constructor that requires {@link #epsilon} parameter. - * - * @param epsilon - * {@link #epsilon} + * + * @param epsilon {@link #epsilon} */ public ModelComparator(final double epsilon) { super(Model.class); @@ -125,7 +116,7 @@ public class ModelComparator extends Comparator<Model> { return status; } - SetComparator<Layer> layerSetComparator = new SetComparator<Layer>(new LayerComparator(epsilon)); + SetComparator<Layer> layerSetComparator = new SetComparator<Layer>(new LayerComparator(epsilon)); status = layerSetComparator.compare(arg0.getLayers(), arg1.getLayers()); if (status != 0) { @@ -202,13 +193,10 @@ public class ModelComparator extends Comparator<Model> { /** * Compares two sets of elements. - * - * @param elements - * first set of elements - * @param elements2 - * second set of elements - * @return if sets are equal then returns 0. If they are different then -1/1 - * is returned. + * + * @param elements first set of elements + * @param elements2 second set of elements + * @return if sets are equal then returns 0. If they are different then -1/1 is returned. */ private int compareElements(final Set<Element> elements, final Set<Element> elements2) { @@ -216,8 +204,8 @@ public class ModelComparator extends Comparator<Model> { Map<String, Element> map2 = new HashMap<>(); if (elements.size() != elements2.size()) { - logger.debug("Number of elements different: " + elements.size() + ", " + elements2.size()); - return ((Integer) elements.size()).compareTo(elements2.size()); + logger.debug("Number of elements different: {}, {}", elements.size(), elements2.size()); + return Integer.compare(elements.size(), elements2.size()); } for (final Element element : elements) { @@ -248,15 +236,13 @@ public class ModelComparator extends Comparator<Model> { /** * Compares two collection of models. - * - * @param collection1 - * first collection to compare - * @param collection2 - * second collection to compare + * + * @param collection1 first collection to compare + * @param collection2 second collection to compare * @return 0 if the collections are identical, -1/1 otherwise */ private int compareSubmodels(final Collection<ModelSubmodelConnection> collection1, - final Collection<ModelSubmodelConnection> collection2) { + final Collection<ModelSubmodelConnection> collection2) { IntegerComparator integerComparator = new IntegerComparator(); if (integerComparator.compare(collection1.size(), collection2.size()) != 0) { logger.debug("collection of submodels doesn't match: " + collection1.size() + ", " + collection2.size()); diff --git a/model/src/main/java/lcsb/mapviewer/model/map/model/ModelDataComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelDataComparator.java new file mode 100644 index 0000000000..21ca1415b9 --- /dev/null +++ b/model/src/main/java/lcsb/mapviewer/model/map/model/ModelDataComparator.java @@ -0,0 +1,26 @@ +package lcsb.mapviewer.model.map.model; + +import lcsb.mapviewer.common.Comparator; +import lcsb.mapviewer.common.Configuration; + +public class ModelDataComparator extends Comparator<ModelData> { + + private final ModelComparator modelComparator; + + public ModelDataComparator(final double epsilon) { + super(ModelData.class); + modelComparator = new ModelComparator(epsilon); + } + + /** + * Default constructor. + */ + public ModelDataComparator() { + this(Configuration.EPSILON); + } + + @Override + protected int internalCompare(final ModelData arg0, final ModelData arg1) { + return modelComparator.compare(new ModelFullIndexed(arg0), new ModelFullIndexed(arg1)); + } +} diff --git a/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java b/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java index c84733e90a..68a975713f 100644 --- a/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java +++ b/model/src/main/java/lcsb/mapviewer/model/map/reaction/AbstractNodeComparator.java @@ -1,8 +1,5 @@ package lcsb.mapviewer.model.map.reaction; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - import lcsb.mapviewer.common.Comparator; import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.model.graphics.PolylineDataComparator; @@ -10,28 +7,22 @@ import lcsb.mapviewer.model.graphics.PolylineDataComparator; /** * This class implements comparator interface for AbstractNode. It also handles * comparison of subclasses of AbstractNode class. - * + * * @author Piotr Gawron - * */ public class AbstractNodeComparator extends Comparator<AbstractNode> { - /** - * Default class logger. - */ - private static Logger logger = LogManager.getLogger(); /** * Epsilon value used for comparison of doubles. */ - private double epsilon; + private final double epsilon; - private boolean ignoreLayout; + private final boolean ignoreLayout; /** * Constructor that requires {@link #epsilon} parameter. - * - * @param epsilon - * {@link #epsilon} + * + * @param epsilon {@link #epsilon} */ public AbstractNodeComparator(final double epsilon, final boolean ignoreLayout) { super(AbstractNode.class, true); -- GitLab