Commit 1a3037c1 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '985-celldesigner-parser-crashes' into 'master'

Resolve "celldesigner parser crashes"

Closes #985

See merge request minerva/core!960
parents a477f51f 6798ba79
Pipeline #15120 passed with stage
in 14 minutes and 11 seconds
minerva (14.0.3) stable; urgency=medium
* Bug fix: parsing of CellDesigner files that contained substanceUnits could
crash the upload (#985)
-- Piotr Gawron <piotr.gawron@uni.lu> Wed, 16 Oct 2019 9:00:00 +0200
minerva (14.0.2) stable; urgency=medium
* Bug fix: Genetic data overlay uploaded prior to 14.0.0 crashed maps (#988)
......
......@@ -98,7 +98,7 @@ public class CellDesignerXmlParser extends Converter {
if (params.getFilename() != null) {
model.setName(FilenameUtils.getBaseName(params.getFilename()));
}
speciesSbmlParser = new SpeciesCollectionXmlParser(elements);
speciesSbmlParser = new SpeciesCollectionXmlParser(elements, model.getUnits());
aliasCollectionParser = new AliasCollectionXmlParser(elements, model);
compartmentCollectionXmlParser = new CompartmentCollectionXmlParser(elements);
......@@ -133,21 +133,6 @@ public class CellDesignerXmlParser extends Converter {
model.setIdModel(modelId);
}
Node compartmentNode = XmlParser.getNode("listOfCompartments", modelNode.getChildNodes());
if (compartmentNode != null) {
List<CellDesignerCompartment> compartments = compartmentCollectionXmlParser
.parseXmlCompartmentCollection(compartmentNode);
elements.addElements(compartments);
}
InternalModelSpeciesData modelData = new InternalModelSpeciesData();
Node speciesNode = XmlParser.getNode("listOfSpecies", modelNode.getChildNodes());
if (speciesNode != null) {
List<Pair<String, ? extends CellDesignerSpecies<?>>> species = speciesSbmlParser
.parseSbmlSpeciesCollection(speciesNode);
modelData.updateSpecies(species);
}
Node reactionsNode = null;
Node functionsNode = null;
Node unitsNode = null;
......@@ -192,6 +177,22 @@ public class CellDesignerXmlParser extends Converter {
model.addParameters(parameterParser.parseXmlParameterCollection(parametersNode));
}
Node compartmentNode = XmlParser.getNode("listOfCompartments", modelNode.getChildNodes());
if (compartmentNode != null) {
List<CellDesignerCompartment> compartments = compartmentCollectionXmlParser
.parseXmlCompartmentCollection(compartmentNode);
elements.addElements(compartments);
}
InternalModelSpeciesData modelData = new InternalModelSpeciesData();
Node speciesNode = XmlParser.getNode("listOfSpecies", modelNode.getChildNodes());
if (speciesNode != null) {
List<Pair<String, ? extends CellDesignerSpecies<?>>> species = speciesSbmlParser
.parseSbmlSpeciesCollection(speciesNode);
modelData.updateSpecies(species);
}
Node annotationNode = XmlParser.getNode("annotation", modelNode.getChildNodes());
if (annotationNode == null) {
throw new InvalidInputDataExecption("No annotation node in SBML/model");
......@@ -388,7 +389,7 @@ public class CellDesignerXmlParser extends Converter {
private void parseAnnotationExtension(Model model, InternalModelSpeciesData modelData,
CellDesignerElementCollection elements, Node extensionNode) throws InvalidXmlSchemaException {
SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements);
SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements, model.getUnits());
NodeList nodes = extensionNode.getChildNodes();
Node includedSpecies = null;
......@@ -598,7 +599,7 @@ public class CellDesignerXmlParser extends Converter {
try {
CellDesignerElementCollection elements = new CellDesignerElementCollection();
SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements);
SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements, model.getUnits());
ReactionCollectionXmlParser reactionCollectionXmlParser = new ReactionCollectionXmlParser(model, elements, false);
UnitCollectionXmlParser unitCollectionXmlParser = new UnitCollectionXmlParser();
FunctionCollectionXmlParser functionCollectionXmlParser = new FunctionCollectionXmlParser();
......@@ -667,7 +668,7 @@ public class CellDesignerXmlParser extends Converter {
* @return annotation xml string for the model
*/
private String annotationToXml(Model model, CellDesignerElementCollection elements) {
SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements);
SpeciesCollectionXmlParser speciesCollectionXmlParser = new SpeciesCollectionXmlParser(elements, model.getUnits());
StringBuilder result = new StringBuilder();
result.append("<annotation>\n");
......
......@@ -16,6 +16,7 @@ import lcsb.mapviewer.converter.model.celldesigner.CellDesignerElementCollection
import lcsb.mapviewer.converter.model.celldesigner.annotation.RestAnnotationParser;
import lcsb.mapviewer.converter.model.celldesigner.structure.*;
import lcsb.mapviewer.model.map.InconsistentModelException;
import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
import lcsb.mapviewer.model.map.species.*;
/**
......@@ -95,6 +96,8 @@ public class SpeciesCollectionXmlParser {
*/
private CellDesignerElementCollection elements;
private Collection<SbmlUnit> units;
/**
* Default constructor. Model is required because some CellDesigner nodes
* require access to other parts of the model.
......@@ -103,9 +106,10 @@ public class SpeciesCollectionXmlParser {
* collection of {@link CellDesignerElement cell designer elements}
* parsed from xml
*/
public SpeciesCollectionXmlParser(CellDesignerElementCollection elements) {
sbmlSpeciesParser = new SpeciesSbmlParser(elements);
public SpeciesCollectionXmlParser(CellDesignerElementCollection elements, Collection<SbmlUnit> units) {
sbmlSpeciesParser = new SpeciesSbmlParser(elements, units);
this.elements = elements;
this.units = units;
rnaParser = new RnaXmlParser(elements);
geneParser = new GeneXmlParser(elements);
proteinParser = new ProteinXmlParser(elements);
......@@ -390,7 +394,7 @@ public class SpeciesCollectionXmlParser {
// Probably this should be improved, this part of a CD model is really
// messy.
NodeList nodes = spieciesNode.getChildNodes();
SpeciesSbmlParser parser = new SpeciesSbmlParser(elements);
SpeciesSbmlParser parser = new SpeciesSbmlParser(elements, units);
for (int x = 0; x < nodes.getLength(); x++) {
Node node = nodes.item(x);
if (node.getNodeType() == Node.ELEMENT_NODE) {
......
package lcsb.mapviewer.converter.model.celldesigner.species;
import java.util.Collection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.w3c.dom.Node;
......@@ -16,6 +18,7 @@ import lcsb.mapviewer.converter.model.celldesigner.structure.fields.CellDesigner
import lcsb.mapviewer.converter.model.celldesigner.structure.fields.SpeciesState;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.compartment.PathwayCompartment;
import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
import lcsb.mapviewer.model.map.model.ModelData;
import lcsb.mapviewer.model.map.species.*;
......@@ -43,6 +46,8 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
*/
private CellDesignerElementCollection elements;
private Collection<SbmlUnit> units;
/**
* Default constructor. Model is required because some nodes require access to
* other parts of the model.
......@@ -51,8 +56,9 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
* collection of {@link CellDesignerElement cell designer elements}
* parsed from xml
*/
public SpeciesSbmlParser(CellDesignerElementCollection elements) {
public SpeciesSbmlParser(CellDesignerElementCollection elements, Collection<SbmlUnit> units) {
this.elements = elements;
this.units = units;
}
@Override
......@@ -146,7 +152,17 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
species.setInitialAmount(XmlParser.getNodeAttr("initialAmount", spieciesNode));
String substanceUnits = XmlParser.getNodeAttr("substanceUnits", spieciesNode);
if (substanceUnits != null && !substanceUnits.isEmpty()) {
species.setSubstanceUnits(SbmlUnitType.valueOf(substanceUnits.toUpperCase()));
SbmlUnit sbmlUnit = null;
for (SbmlUnit unit : units) {
if (unit.getUnitId().equals(substanceUnits)) {
sbmlUnit = unit;
}
}
if (sbmlUnit != null) {
species.setSubstanceUnits(sbmlUnit);
} else {
species.setSubstanceUnits(SbmlUnitType.valueOf(substanceUnits.toUpperCase()));
}
}
species.setInitialAmount(XmlParser.getNodeAttr("initialAmount", spieciesNode));
species.setInitialConcentration(XmlParser.getNodeAttr("initialConcentration", spieciesNode));
......@@ -196,7 +212,11 @@ public class SpeciesSbmlParser extends AbstractElementXmlParser<CellDesignerSpec
attributesBuilder.append(" hasOnlySubstanceUnits=\"" + species.hasOnlySubstanceUnits() + "\"");
}
if (species.getSubstanceUnits() != null) {
attributesBuilder.append(" substanceUnits=\"" + species.getSubstanceUnits().toString().toLowerCase() + "\"");
if (species.getSubstanceUnits() instanceof SbmlUnit) {
attributesBuilder.append(" substanceUnits=\"" + ((SbmlUnit)species.getSubstanceUnits()).getUnitId().toLowerCase() + "\"");
} else {
attributesBuilder.append(" substanceUnits=\"" + species.getSubstanceUnits().toString().toLowerCase() + "\"");
}
}
if (species.getConstant() != null) {
attributesBuilder.append(" constant=\"" + species.getConstant().toString().toLowerCase() + "\"");
......
......@@ -6,6 +6,7 @@ import org.apache.logging.log4j.Logger;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.model.map.MiriamData;
import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
import lcsb.mapviewer.model.map.species.Species;
import lcsb.mapviewer.model.map.species.field.PositionToCompartment;
......@@ -70,7 +71,20 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
*/
private Boolean hypothetical = null;
private SbmlUnitType substanceUnits;
/**
* SBML allows to store substanceUnit as either basic SI unit type or complex
* unit definition. To map it properly to database we need to separate the type
* into two properties. This property is responsible for basic SI unit type.
*/
private SbmlUnitType substanceUnitRawType;
/**
* SBML allows to store substanceUnit as either basic SI unit type or complex
* unit definition. To map it properly to database we need to separate the type
* into two properties. This property is responsible for complex unit
* definition.
*/
private SbmlUnit substanceUnitComlexType;
private Boolean boundaryCondition;
......@@ -93,7 +107,8 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
this.onlySubstanceUnits = species.onlySubstanceUnits;
this.homodimer = species.homodimer;
this.constant = species.constant;
this.substanceUnits = species.substanceUnits;
this.substanceUnitComlexType = species.substanceUnitComlexType;
this.substanceUnitRawType = species.substanceUnitRawType;
this.boundaryCondition = species.boundaryCondition;
}
......@@ -287,7 +302,11 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
if (boundaryCondition != null) {
result.setBoundaryCondition(boundaryCondition);
}
result.setSubstanceUnits(substanceUnits);
if (substanceUnitComlexType != null) {
result.setSubstanceUnits(substanceUnitComlexType);
} else {
result.setSubstanceUnits(substanceUnitRawType);
}
result.setHomodimer(homodimer);
result.setPositionToCompartment(positionToCompartment);
result.setHypothetical(hypothetical);
......@@ -503,11 +522,21 @@ public class CellDesignerSpecies<T extends Species> extends CellDesignerElement<
}
public void setSubstanceUnits(SbmlUnitType substanceUnits) {
this.substanceUnits = substanceUnits;
this.substanceUnitRawType = substanceUnits;
}
public void setSubstanceUnits(SbmlUnit substanceUnits) {
this.substanceUnitComlexType = substanceUnits;
}
public SbmlUnitType getSubstanceUnit() {
return this.substanceUnits;
public Object getSubstanceUnit() {
if (substanceUnitComlexType != null) {
return substanceUnitComlexType;
} else if (substanceUnitRawType != null) {
return substanceUnitRawType;
} else {
return null;
}
}
public Boolean isBoundaryCondition() {
......
......@@ -67,6 +67,16 @@ public class CellDesignerXmlParserTest extends CellDesignerTestFunctions {
assertEquals("sample", model.getName());
}
@Test
public void testSubstanceUnitAsType() throws Exception {
CellDesignerXmlParser parser = new CellDesignerXmlParser();
Model model = parser
.createModel(new ConverterParams().filename("testFiles/problematic/substance_defined_as_type.xml").sizeAutoAdjust(false));
assertNotNull(model);
assertNotNull(model.getSpeciesList().get(0).getSubstanceUnits());
super.testXmlSerialization(model);
}
@Test
public void testParseTransparency() throws Exception {
CellDesignerXmlParser parser = new CellDesignerXmlParser();
......
......@@ -3,8 +3,7 @@ package lcsb.mapviewer.converter.model.celldesigner.species;
import static org.junit.Assert.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
......@@ -41,7 +40,7 @@ public class SpeciesCollectionXmlParserTest extends CellDesignerTestFunctions {
@Before
public void setUp() throws Exception {
elements = new CellDesignerElementCollection();
parser = new SpeciesCollectionXmlParser(elements);
parser = new SpeciesCollectionXmlParser(elements, new HashSet<>());
}
@After
......@@ -292,7 +291,7 @@ public class SpeciesCollectionXmlParserTest extends CellDesignerTestFunctions {
// this is only for test coverage purpose
SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements);
SpeciesCollectionXmlParser parser = new SpeciesCollectionXmlParser(elements, new HashSet<>());
Field field = SpeciesCollectionXmlParser.class.getDeclaredField("helpParser");
field.setAccessible(true);
try {
......
......@@ -3,6 +3,7 @@ package lcsb.mapviewer.converter.model.celldesigner.species;
import static org.junit.Assert.*;
import java.io.StringReader;
import java.util.HashSet;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
......@@ -45,7 +46,7 @@ public class SpeciesSbmlParserTest extends CellDesignerTestFunctions {
@Before
public void setUp() throws Exception {
elements = new CellDesignerElementCollection();
parser = new SpeciesSbmlParser(elements);
parser = new SpeciesSbmlParser(elements, new HashSet<>());
}
@After
......@@ -269,7 +270,7 @@ public class SpeciesSbmlParserTest extends CellDesignerTestFunctions {
InternalModelSpeciesData modelData = new InternalModelSpeciesData();
modelData.updateSpecies(gene, "");
SpeciesSbmlParser complexParser = new SpeciesSbmlParser(elements);
SpeciesSbmlParser complexParser = new SpeciesSbmlParser(elements, new HashSet<>());
CellDesignerGene oldGene = new CellDesignerGene();
oldGene.setElementId("s5916");
oldGene.setName("Ptgr1");
......
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level2/version4" xmlns:celldesigner="http://www.sbml.org/2001/ns/celldesigner" level="2" version="4">
<model metaid="CellDesigner_Ver_42_Components" id="CellDesigner_Ver_42_Components" sboTerm="SBO:0000231">
<notes>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title/>
</head>
<body>This is a sample file for CellDesigner 4.2, describing the graphical notation.
http://celldesigner.org
</body>
</html>
</notes>
<annotation>
<celldesigner:extension>
<celldesigner:modelVersion>4.0</celldesigner:modelVersion>
<celldesigner:modelDisplay sizeX="1700" sizeY="1200"/>
<celldesigner:listOfCompartmentAliases/>
<celldesigner:listOfComplexSpeciesAliases/>
<celldesigner:listOfSpeciesAliases>
<celldesigner:speciesAlias id="a1" species="s198">
<celldesigner:activity>inactive</celldesigner:activity>
<celldesigner:bounds x="123.25" y="47.20381061236179" w="80.0" h="40.0"/>
<celldesigner:font size="12"/>
<celldesigner:view state="usual"/>
<celldesigner:usualView>
<celldesigner:boxSize width="80.0" height="40.0"/>
<celldesigner:singleLine width="1.0"/>
<celldesigner:paint color="ffccffcc" scheme="Color"/>
</celldesigner:usualView>
<celldesigner:briefView>
<celldesigner:innerPosition x="0.0" y="0.0"/>
<celldesigner:boxSize width="80.0" height="60.0"/>
<celldesigner:singleLine width="1.0"/>
<celldesigner:paint color="3fff0000" scheme="Color"/>
</celldesigner:briefView>
<celldesigner:info state="empty" angle="-1.5707963267948966"/>
</celldesigner:speciesAlias>
</celldesigner:listOfSpeciesAliases>
<celldesigner:listOfGroups/>
<celldesigner:listOfProteins>
<celldesigner:protein id="p1" name="Protein" type="GENERIC"/>
</celldesigner:listOfProteins>
<celldesigner:listOfGenes/>
<celldesigner:listOfRNAs/>
<celldesigner:listOfAntisenseRNAs/>
<celldesigner:listOfLayers>
<celldesigner:layer id="1" name="comment" locked="false" visible="true"/>
</celldesigner:listOfLayers>
<celldesigner:listOfBlockDiagrams/>
</celldesigner:extension>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
<rdf:Description rdf:about="#CellDesigner_Ver_42_Components">
<dc:creator>
<rdf:Bag>
<rdf:li rdf:parseType="Resource">
<vCard:EMAIL>info@celldesigner.org</vCard:EMAIL>
<vCard:ORG rdf:parseType="Resource">
<vCard:Orgname>The Systems Biology Institute</vCard:Orgname>
</vCard:ORG>
</rdf:li>
</rdf:Bag>
</dc:creator>
<dcterms:created rdf:parseType="Resource">
<dcterms:W3CDTF>2009-07-13T20:39:30Z</dcterms:W3CDTF>
</dcterms:created>
<dcterms:modified rdf:parseType="Resource">
<dcterms:W3CDTF>2011-03-09T19:11:39Z</dcterms:W3CDTF>
</dcterms:modified>
</rdf:Description>
</rdf:RDF>
</annotation>
<listOfUnitDefinitions>
<unitDefinition metaid="substance" id="substance" name="substance">
<listOfUnits>
<unit metaid="CDMT00121" kind="mole"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="volume" id="volume" name="volume">
<listOfUnits>
<unit metaid="CDMT00122" kind="litre"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="area" id="area" name="area">
<listOfUnits>
<unit metaid="CDMT00123" kind="metre" exponent="2"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="length" id="length" name="length">
<listOfUnits>
<unit metaid="CDMT00124" kind="metre"/>
</listOfUnits>
</unitDefinition>
<unitDefinition metaid="time" id="time" name="time">
<listOfUnits>
<unit metaid="CDMT00125" kind="second"/>
</listOfUnits>
</unitDefinition>
</listOfUnitDefinitions>
<listOfCompartments>
<compartment metaid="default" id="default" size="1" units="volume" sboTerm="SBO:0000240"/>
</listOfCompartments>
<listOfSpecies>
<species metaid="s198" id="s198" name="Protein" compartment="default" initialAmount="0" substanceUnits="substance" sboTerm="SBO:0000252">
<notes>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title/>
</head>
<body>You can input the Protein Notes here.
</body>
</html>
</notes>
<annotation>
<celldesigner:extension>
<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
<celldesigner:speciesIdentity>
<celldesigner:class>PROTEIN</celldesigner:class>
<celldesigner:proteinReference>p1</celldesigner:proteinReference>
</celldesigner:speciesIdentity>
</celldesigner:extension>
</annotation>
</species>
</listOfSpecies>
</model>
</sbml>
......@@ -320,8 +320,12 @@ public class XmlAnnotationParser {
result.append("<rdf:Bag>\n");
result.append("<rdf:li rdf:parseType=\"Resource\">\n");
result.append("<vCard:N rdf:parseType=\"Resource\">\n");
result.append("<vCard:Family>" + XmlParser.escapeXml(author.getLastName()) + "</vCard:Family>\n");
result.append("<vCard:Given>" + XmlParser.escapeXml(author.getFirstName()) + "</vCard:Given>\n");
if (author.getLastName() != null) {
result.append("<vCard:Family>" + XmlParser.escapeXml(author.getLastName()) + "</vCard:Family>\n");
}
if (author.getFirstName() != null) {
result.append("<vCard:Given>" + XmlParser.escapeXml(author.getFirstName()) + "</vCard:Given>\n");
}
result.append("</vCard:N>\n");
if (author.getEmail() != null && !author.getEmail().trim().isEmpty()) {
......
......@@ -10,6 +10,7 @@ import org.apache.logging.log4j.Logger;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import lcsb.mapviewer.model.map.kinetics.SbmlUnit;
import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
import lcsb.mapviewer.model.map.species.field.PositionToCompartment;
import lcsb.mapviewer.model.map.species.field.UniprotRecord;
......@@ -120,8 +121,23 @@ public abstract class Species extends Element {
private Boolean constant = false;
/**
* SBML allows to store substanceUnit as either basic SI unit type or complex
* unit definition. To map it properly to database we need to separate the type
* into two properties. This property is responsible for basic SI unit type.
*/
@Enumerated(EnumType.STRING)
private SbmlUnitType substanceUnits;
private SbmlUnitType substanceUnitRawType;
/**
* SBML allows to store substanceUnit as either basic SI unit type or complex
* unit definition. To map it properly to database we need to separate the type
* into two properties. This property is responsible for complex unit
* definition.
*/
@ManyToOne
@Cascade({ CascadeType.ALL })
private SbmlUnit substanceUnitComlexType;
/**
* Constructor that set element identifier.
......@@ -171,7 +187,8 @@ public abstract class Species extends Element {
hypothetical = original.getHypothetical();
boundaryCondition = original.getBoundaryCondition();
constant = original.getConstant();
substanceUnits = original.getSubstanceUnits();
substanceUnitComlexType = original.substanceUnitComlexType;
substanceUnitRawType = original.substanceUnitRawType;
uniprots = original.getUniprots();
......@@ -476,12 +493,22 @@ public abstract class Species extends Element {
this.constant = constant;
}
public SbmlUnitType getSubstanceUnits() {
return substanceUnits;
public Object getSubstanceUnits() {
if (this.substanceUnitRawType != null) {
return this.substanceUnitRawType;
} else {
return this.substanceUnitComlexType;
}
}
public void setSubstanceUnits(SbmlUnitType substanceUnits) {
this.substanceUnits = substanceUnits;
this.substanceUnitRawType = substanceUnits;
this.substanceUnitComlexType = null;
}
public void setSubstanceUnits(SbmlUnit substanceUnits) {
this.substanceUnitComlexType = substanceUnits;
this.substanceUnitRawType = null;
}
}
......@@ -6,7 +6,7 @@ import org.apache.logging.log4j.Logger;
import lcsb.mapviewer.common.Comparator;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.common.comparator.*;
import lcsb.mapviewer.model.map.kinetics.SbmlUnitType;
import lcsb.mapviewer.model.map.kinetics.*;
/**
* Comparator class used for comparing {@link Species} objects.