Commit 8dd088f0 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge remote-tracking branch 'origin/devel_15.0.x' into merge-15.0.3

parents 8491b9b4 1559bd9d
Pipeline #31174 passed with stage
in 13 minutes and 37 seconds
...@@ -42,6 +42,31 @@ minerva (15.1.0~beta.0) unstable; urgency=medium ...@@ -42,6 +42,31 @@ minerva (15.1.0~beta.0) unstable; urgency=medium
-- Piotr Gawron <piotr.gawron@uni.lu> Mon, 13 Jul 2020 16:00:00 +0200 -- Piotr Gawron <piotr.gawron@uni.lu> Mon, 13 Jul 2020 16:00:00 +0200
minerva (15.0.3) stable; urgency=medium
* Bug fix: caching chemicals/drug data on big map could cause Out of Memory
issues (#1315)
* Bug fix: when there is a problem with minerva deployment on tomcat proper
warning message is presented in admin panel (#1332)
* Bug fix: API call updating user preferences did not handle properly
conflicts on new gui properties (#1326)
* Bug fix: "bqbiol:hasTaxon" relation type is not supported by CellDedigner
and is now transformed during export into something readable by
CellDesigner (#1281)
* Bug fix: concurrency issue that could happen rarely on first search of the
map and put the project into "unsearchable" state is fixed (#1333)
* Bug fix: when edit project buton was clicked on project that was removed in
another tab there was an error thrown (#1343)
* Bug fix: chebi and entrez annotations were incorrectly exported to GPML
(#1349)
* Bug fix: exporting to GPML sometimes resulted in invalid modification point
end for catalysis (#1350)
* Bug fix: elements name were not escaped properly when exporting to GPML
(#1351)
* Bug fix: reaction with description and pubmed reference was incorrectly
exported to GPML (#1352)
-- Piotr Gawron <piotr.gawron@uni.lu> Thu, 13 Aug 2020 15:00:00 +0200
minerva (15.0.2) stable; urgency=medium minerva (15.0.2) stable; urgency=medium
* Bug fix: annotations using identifiers.org urls sometimes required http and * Bug fix: annotations using identifiers.org urls sometimes required http and
sometimes required https url (#1297) sometimes required https url (#1297)
...@@ -61,9 +86,9 @@ minerva (15.0.2) stable; urgency=medium ...@@ -61,9 +86,9 @@ minerva (15.0.2) stable; urgency=medium
* Bug fix: bqmodel:isInstanceOf and bqmodel:hasInstance relation types were * Bug fix: bqmodel:isInstanceOf and bqmodel:hasInstance relation types were
not handled properly (#1281) not handled properly (#1281)
* Bug fix: "bqmodel:isInstanceOf", "bqmodel:hasInstance", * Bug fix: "bqmodel:isInstanceOf", "bqmodel:hasInstance",
"bqbiol:hasProperty", "bqbiol:isPropertyOf" and "bqbiol:hasTaxon" relation "bqbiol:hasProperty", "bqbiol:isPropertyOf" relation types are not
types are not supported by CellDedigner and are now transformed during supported by CellDedigner and are now transformed during export into
export into something readable by CellDesigner (#1281) something readable by CellDesigner (#1281)
* Bug fix: at random time points there was an issue with cached data (#1323) * Bug fix: at random time points there was an issue with cached data (#1323)
* Bug fix: connection to DAPI timeouted sometimes which resulted in error * Bug fix: connection to DAPI timeouted sometimes which resulted in error
when checking for all chemicals for specfific protein (#1324) when checking for all chemicals for specfific protein (#1324)
......
...@@ -37,12 +37,12 @@ public final class ApplicationLevelCache implements QueryCacheInterface { ...@@ -37,12 +37,12 @@ public final class ApplicationLevelCache implements QueryCacheInterface {
/** /**
* Cached nodes stored locally and identified by string. * Cached nodes stored locally and identified by string.
*/ */
private static Map<String, Node> cachedQueryNodes = new HashMap<String, Node>(); private static Map<String, Node> cachedQueryNodes = new HashMap<>();
/** /**
* Cached strings stored locally and identified by string. * Cached strings stored locally and identified by string.
*/ */
private static Map<String, String> cachedQueryString = new HashMap<String, String>(); private static Map<String, String> cachedQueryString = new HashMap<>();
/** /**
* Global instance of cache. * Global instance of cache.
...@@ -109,8 +109,8 @@ public final class ApplicationLevelCache implements QueryCacheInterface { ...@@ -109,8 +109,8 @@ public final class ApplicationLevelCache implements QueryCacheInterface {
@Override @Override
public synchronized void clearCache() { public synchronized void clearCache() {
logger.info("Clearing application cache"); logger.info("Clearing application cache");
cachedQueryNodes.clear(); cachedQueryNodes = new HashMap<>();
cachedQueryString.clear(); cachedQueryString= new HashMap<>();
} }
@Override @Override
...@@ -144,6 +144,16 @@ public final class ApplicationLevelCache implements QueryCacheInterface { ...@@ -144,6 +144,16 @@ public final class ApplicationLevelCache implements QueryCacheInterface {
logger.info("Elements in cache: " + cacheCount); logger.info("Elements in cache: " + cacheCount);
clearCache(); clearCache();
System.gc(); System.gc();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
maxMem = runtime.maxMemory();
useMem = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
logger.info("Memory usage after cache is cleared: " + useMem + " out of " + maxMem + " is used. Exceeded: "
+ maxMem * Configuration.getMemorySaturationRatioTriggerClean());
} }
} }
} }
......
...@@ -128,6 +128,8 @@ public class WebPageDownloader { ...@@ -128,6 +128,8 @@ public class WebPageDownloader {
BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
result = IOUtils.toString(in); result = IOUtils.toString(in);
} catch (IOException e) { } catch (IOException e) {
logger.error(
"Problem with fetching url (" + (HTTP_INTERNAL_ERROR_RECONNECT_TIMES + 1) + " tries): " + accessUrl);
if (e.getClass().equals(IOException.class) || e.getClass().equals(FileNotFoundException.class)) { if (e.getClass().equals(IOException.class) || e.getClass().equals(FileNotFoundException.class)) {
throw new WrongResponseCodeIOException(e, code); throw new WrongResponseCodeIOException(e, code);
} else { } else {
......
...@@ -274,7 +274,6 @@ public abstract class DrugAnnotation extends CachableInterface { ...@@ -274,7 +274,6 @@ public abstract class DrugAnnotation extends CachableInterface {
private List<String> getSuggestedQueryListWithoutCache(Project project, MiriamData organism) private List<String> getSuggestedQueryListWithoutCache(Project project, MiriamData organism)
throws DrugSearchException { throws DrugSearchException {
Set<String> resultSet = new HashSet<>();
Set<MiriamData> targets = new HashSet<>(); Set<MiriamData> targets = new HashSet<>();
for (ModelData model : project.getModels()) { for (ModelData model : project.getModels()) {
for (Element element : model.getElements()) { for (Element element : model.getElements()) {
...@@ -315,11 +314,15 @@ public abstract class DrugAnnotation extends CachableInterface { ...@@ -315,11 +314,15 @@ public abstract class DrugAnnotation extends CachableInterface {
if (organism != null) { if (organism != null) {
organisms.add(organism); organisms.add(organism);
} }
List<Drug> drugs = getDrugListByTargets(targets, organisms);
for (Drug chemical : drugs) {
resultSet.add(chemical.getName());
}
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
Set<String> resultSet = new HashSet<>();
for (MiriamData target: targets) {
List<Drug> drugs = getDrugListByTarget(target, organisms);
for (Drug chemical : drugs) {
resultSet.add(chemical.getName());
}
}
result.addAll(resultSet); result.addAll(resultSet);
Collections.sort(result); Collections.sort(result);
return result; return result;
......
...@@ -43,7 +43,7 @@ public class PubmedParser extends CachableInterface implements IExternalService ...@@ -43,7 +43,7 @@ public class PubmedParser extends CachableInterface implements IExternalService
/** /**
* Version of the remote API that is supported by this connecting class. * Version of the remote API that is supported by this connecting class.
*/ */
static final String SUPPORTED_VERSION = "6.3"; static final String SUPPORTED_VERSION = "6.4";
static final String API_URL = "https://www.ebi.ac.uk/europepmc/webservices/rest/"; static final String API_URL = "https://www.ebi.ac.uk/europepmc/webservices/rest/";
/** /**
* Length of {@link #PUBMED_PREFIX} string. * Length of {@link #PUBMED_PREFIX} string.
......
...@@ -87,7 +87,7 @@ public class ChemicalParser { ...@@ -87,7 +87,7 @@ public class ChemicalParser {
* @throws ChemicalSearchException * @throws ChemicalSearchException
* thrown when there is a problem with accessing ctd database * thrown when there is a problem with accessing ctd database
*/ */
public List<Chemical> getChemicalListByTarget(Collection<MiriamData> targets, MiriamData disease) public List<Chemical> getChemicalListByTargets(Collection<MiriamData> targets, MiriamData disease)
throws ChemicalSearchException { throws ChemicalSearchException {
Map<MiriamData, Chemical> chemicals = new HashMap<>(); Map<MiriamData, Chemical> chemicals = new HashMap<>();
...@@ -182,10 +182,14 @@ public class ChemicalParser { ...@@ -182,10 +182,14 @@ public class ChemicalParser {
} }
} }
Set<String> names = new HashSet<>(); Set<String> names = new HashSet<>();
List<Chemical> chemicals = getChemicalListByTarget(hgncSymbols, diseaseMiriam); for (MiriamData hgncSymbol : hgncSymbols) {
for (Chemical chemical : chemicals) { // fetching all chemicals for big map is very memory exhaustive, therefore do it
names.add(chemical.getChemicalName()); // step by step to prevent storing everything in the memory at single point
names.addAll(chemical.getSynonyms()); List<Chemical> chemicals = getChemicalListByTarget(hgncSymbol, diseaseMiriam);
for (Chemical chemical : chemicals) {
names.add(chemical.getChemicalName());
names.addAll(chemical.getSynonyms());
}
} }
List<String> result = new ArrayList<>(names); List<String> result = new ArrayList<>(names);
Collections.sort(result); Collections.sort(result);
......
package lcsb.mapviewer.annotation.cache; package lcsb.mapviewer.annotation.cache;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import java.io.IOException; import java.io.IOException;
import java.net.HttpURLConnection; import java.net.*;
import java.net.UnknownHostException;
import org.junit.*; import org.junit.*;
import org.mockito.Mockito; import org.mockito.Mockito;
public class WebPageDownloaderTest { import lcsb.mapviewer.annotation.AnnotationTestFunctions;
public class WebPageDownloaderTest extends AnnotationTestFunctions {
@AfterClass @AfterClass
public static void tearDownAfterClass() throws Exception { public static void tearDownAfterClass() throws Exception {
...@@ -80,4 +82,24 @@ public class WebPageDownloaderTest { ...@@ -80,4 +82,24 @@ public class WebPageDownloaderTest {
} }
@Test
public void testErrorLogResetConnection() throws IOException {
String accessUrl = "https://www.google.pl/?gws_rd=ssl";
HttpURLConnection invalidConnection = Mockito.mock(HttpURLConnection.class);
Mockito.doThrow(new SocketException()).when(invalidConnection).getResponseCode();
Mockito.doThrow(new SocketException()).when(invalidConnection).getInputStream();
WebPageDownloader downloader = Mockito.spy(new WebPageDownloader());
Mockito.when(downloader.openConnection(accessUrl))
.thenReturn(invalidConnection);
try {
downloader.getFromNetwork(accessUrl);
} catch (SocketException e) {
}
assertEquals(1, super.getErrors().size());
}
} }
...@@ -113,7 +113,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions { ...@@ -113,7 +113,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions {
List<MiriamData> targets = new ArrayList<>(); List<MiriamData> targets = new ArrayList<>();
targets.add(target); targets.add(target);
List<Chemical> list = chemicalParser.getChemicalListByTarget(targets, bloodLossDisease); List<Chemical> list = chemicalParser.getChemicalListByTargets(targets, bloodLossDisease);
assertNotNull(list); assertNotNull(list);
assertFalse(list.isEmpty()); assertFalse(list.isEmpty());
} }
...@@ -124,7 +124,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions { ...@@ -124,7 +124,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions {
List<MiriamData> targets = new ArrayList<>(); List<MiriamData> targets = new ArrayList<>();
targets.add(target); targets.add(target);
List<Chemical> list = chemicalParser.getChemicalListByTarget(targets, bloodLossDisease); List<Chemical> list = chemicalParser.getChemicalListByTargets(targets, bloodLossDisease);
assertNotNull(list); assertNotNull(list);
assertFalse(list.isEmpty()); assertFalse(list.isEmpty());
} }
...@@ -134,7 +134,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions { ...@@ -134,7 +134,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions {
MiriamData target = new MiriamData(MiriamType.WIKIPEDIA, "TNF"); MiriamData target = new MiriamData(MiriamType.WIKIPEDIA, "TNF");
List<MiriamData> targets = new ArrayList<>(); List<MiriamData> targets = new ArrayList<>();
targets.add(target); targets.add(target);
chemicalParser.getChemicalListByTarget(targets, parkinsonDiseaseId); chemicalParser.getChemicalListByTargets(targets, parkinsonDiseaseId);
} }
@Test @Test
...@@ -150,7 +150,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions { ...@@ -150,7 +150,7 @@ public class ChemicalParserTest extends AnnotationTestFunctions {
MiriamData target = new MiriamData(MiriamType.HGNC_SYMBOL, "GALM"); MiriamData target = new MiriamData(MiriamType.HGNC_SYMBOL, "GALM");
List<MiriamData> targets = new ArrayList<>(); List<MiriamData> targets = new ArrayList<>();
targets.add(target); targets.add(target);
List<Chemical> list = chemicalParser.getChemicalListByTarget(targets, parkinsonDiseaseId); List<Chemical> list = chemicalParser.getChemicalListByTargets(targets, parkinsonDiseaseId);
assertNotNull(list); assertNotNull(list);
assertTrue(list.isEmpty()); assertTrue(list.isEmpty());
} }
......
...@@ -58,6 +58,7 @@ public class CommonXmlParser { ...@@ -58,6 +58,7 @@ public class CommonXmlParser {
RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_BIOL_IS_PROPERTY_OF); RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_BIOL_IS_PROPERTY_OF);
RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_MODEL_IS_INSTANCE_OF); RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_MODEL_IS_INSTANCE_OF);
RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_MODEL_HAS_INSTANCE); RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_MODEL_HAS_INSTANCE);
RELATION_TYPES_SUPPORTED_BY_CELL_DESIGNER.remove(MiriamRelationType.BQ_BIOL_HAS_TAXON);
} }
private DocumentBuilderFactory dbFactory; private DocumentBuilderFactory dbFactory;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
"deploy": "node scripts/deploy.js", "deploy": "node scripts/deploy.js",
"refresh-mock-requests": "node scripts/refresh_mock_requests.js", "refresh-mock-requests": "node scripts/refresh_mock_requests.js",
"lint": "jshint src/.", "lint": "jshint src/.",
"test": "istanbul cover node_modules/mocha/bin/_mocha -- --recursive src/test/js --retries 4 --timeout 4000" "test": "istanbul cover node_modules/mocha/bin/_mocha -- --recursive src/test/js --retries 4 --timeout 10000"
}, },
"author": "Piotr Gawron", "author": "Piotr Gawron",
"devDependencies": { "devDependencies": {
......
...@@ -163,11 +163,15 @@ Admin.prototype.checkAvailableVersion = function () { ...@@ -163,11 +163,15 @@ Admin.prototype.checkAvailableVersion = function () {
var self = this; var self = this;
var localVersion = semver.coerce(self.getConfiguration().getVersion()); var localVersion = semver.coerce(self.getConfiguration().getVersion());
return self.getLatestPublishedVersion().then(function (publishedVersion) { if (localVersion === null) {
if (semver.gt(publishedVersion, localVersion) > 0) { GuiConnector.warn("Minerva was not deployed properly. Please contact system administrator.");
GuiConnector.warn("New minerva version (" + publishedVersion + ") was released. Please upgrade your minerva instance or contact system administrator to do so."); } else {
} return self.getLatestPublishedVersion().then(function (publishedVersion) {
}); if (semver.gt(publishedVersion, localVersion) > 0) {
GuiConnector.warn("New minerva version (" + publishedVersion + ") was released. Please upgrade your minerva instance or contact system administrator to do so.");
}
});
}
}; };
/** /**
......
...@@ -538,9 +538,13 @@ MapsAdminPanel.prototype.showEditDialog = function (id) { ...@@ -538,9 +538,13 @@ MapsAdminPanel.prototype.showEditDialog = function (id) {
var self = this; var self = this;
GuiConnector.showProcessing(); GuiConnector.showProcessing();
return self.getServerConnector().getProject(id).then(function (project) { return self.getServerConnector().getProject(id).then(function (project) {
return self.getDialog(project); if (project === null) {
}).then(function (dialog) { GuiConnector.warn("Project \"" + id + "\" does not exist");
dialog.open(); } else {
return self.getDialog(project).then(function (dialog) {
dialog.open();
});
}
}).finally(function () { }).finally(function () {
GuiConnector.hideProcessing(); GuiConnector.hideProcessing();
}); });
......
...@@ -43,7 +43,7 @@ public class ModelContructor { ...@@ -43,7 +43,7 @@ public class ModelContructor {
/** /**
* Default color used by complexes. * Default color used by complexes.
*/ */
private static final Color DEFAULT_COMPLEX_ALIAS_COLOR = new Color(248, 247, 240); static final Color DEFAULT_COMPLEX_ALIAS_COLOR = new Color(248, 247, 240);
/** /**
* Epsilon used for double comparison. * Epsilon used for double comparison.
......
...@@ -11,6 +11,7 @@ import org.apache.commons.text.StringEscapeUtils; ...@@ -11,6 +11,7 @@ import org.apache.commons.text.StringEscapeUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import lcsb.mapviewer.common.XmlParser;
import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.geometry.ColorParser; import lcsb.mapviewer.common.geometry.ColorParser;
import lcsb.mapviewer.common.geometry.PointTransformation; import lcsb.mapviewer.common.geometry.PointTransformation;
...@@ -338,7 +339,7 @@ public class ModelToGPML { ...@@ -338,7 +339,7 @@ public class ModelToGPML {
double x = ca.getCenterX(), y = ca.getCenterY(), h = ca.getHeight(), w = ca.getWidth(); double x = ca.getCenterX(), y = ca.getCenterY(), h = ca.getHeight(), w = ca.getWidth();
String shape = ShapeMapping.getShape(ca.getClass()).getStringRepresentation(); String shape = ShapeMapping.getShape(ca.getClass()).getStringRepresentation();
comparments.append(" <Shape TextLabel=\"" + ca.getName() + "\" GraphId=\"" + ca.getElementId() + "\">\n"); comparments.append(" <Shape TextLabel=\"" + XmlParser.escapeXml(ca.getName()) + "\" GraphId=\"" + ca.getElementId() + "\">\n");
comparments.append(" <Comment>" + StringEscapeUtils.escapeXml11(getAllNames(ca)) + "</Comment>\n"); comparments.append(" <Comment>" + StringEscapeUtils.escapeXml11(getAllNames(ca)) + "</Comment>\n");
comparments.append(" <Attribute Key=\"org.pathvisio.CellularComponentProperty\" Value=\"Cell\" />\n"); comparments.append(" <Attribute Key=\"org.pathvisio.CellularComponentProperty\" Value=\"Cell\" />\n");
comparments.append(" <Attribute Key=\"org.pathvisio.DoubleLineProperty\" Value=\"Double\" />\n"); comparments.append(" <Attribute Key=\"org.pathvisio.DoubleLineProperty\" Value=\"Double\" />\n");
...@@ -499,7 +500,7 @@ public class ModelToGPML { ...@@ -499,7 +500,7 @@ public class ModelToGPML {
for (Complex ca : model.getComplexList()) { for (Complex ca : model.getComplexList()) {
if (ca.getElements().size() == 0) { if (ca.getElements().size() == 0) {
dataNodes.append( dataNodes.append(
" <DataNode TextLabel=\"" + ca.getName() + "\" GraphId=\"" + ca.getElementId() + "\" Type=\"Complex\""); " <DataNode TextLabel=\"" + XmlParser.escapeXml(ca.getName()) + "\" GraphId=\"" + ca.getElementId() + "\" Type=\"Complex\"");
if (ca.getComplex() != null) { if (ca.getComplex() != null) {
dataNodes.append(" GroupRef=\"" + ca.getComplex().getElementId() + "\""); dataNodes.append(" GroupRef=\"" + ca.getComplex().getElementId() + "\"");
} }
...@@ -530,38 +531,6 @@ public class ModelToGPML { ...@@ -530,38 +531,6 @@ public class ModelToGPML {
return dataNodes.toString(); return dataNodes.toString();
} }
String speciesToLabel(Species species) throws ConverterException {
StringBuilder result = new StringBuilder();
result.append(
" <Label TextLabel=\"" + species.getName() + "\" GraphId=\"" + species.getElementId() + "\"");
if (species.getComplex() != null) {
result.append(" GroupRef=\"" + species.getComplex().getElementId() + "\"");
}
result.append(">\n");
result.append(" <Comment>" + StringEscapeUtils.escapeXml11(species.getNotes().trim()) + "</Comment>\n");
result.append(biopaxParser.toReferenceXml(species.getMiriamData()));
Rectangle2D rec = species.getBorder();
result.append(
" <Graphics CenterX=\"" + rec.getCenterX() + "\" " +
"CenterY=\"" + rec.getCenterY() + "\" " +
"Width=\"" + rec.getWidth() + "\" " +
"Height=\"" + rec.getHeight() + "\" " +
"ZOrder=\"" + species.getZ() + "\" " +
"FontSize=\"" + species.getFontSize().intValue() + "\" " +
"Valign=\"Middle\" " +
"Color=\"" + colorToString(species.getFontColor()) + "\" " +
"FillColor=\"" + colorToString(species.getFillColor()) + "\"/>\n");
if (species.getMiriamData().size() > 0) {
logger.warn(new LogMarker(ProjectLogEntryType.EXPORT_ISSUE, species), "Annotations cannot be exported to gpml");
}
result.append(" </Label>\n");
return result.toString();
}
String speciesToShape(Species species) throws ConverterException { String speciesToShape(Species species) throws ConverterException {
String shape = ShapeMapping.getShape(species.getClass()).getStringRepresentation(); String shape = ShapeMapping.getShape(species.getClass()).getStringRepresentation();
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
...@@ -605,7 +574,7 @@ public class ModelToGPML { ...@@ -605,7 +574,7 @@ public class ModelToGPML {
String nodeType = getType(species); String nodeType = getType(species);
result.append( result.append(
" <DataNode TextLabel=\"" + species.getName() + "\" " " <DataNode TextLabel=\"" + XmlParser.escapeXml(species.getName()) + "\" "
+ "GraphId=\"" + species.getElementId() + "\""); + "GraphId=\"" + species.getElementId() + "\"");
if (nodeType != null) { if (nodeType != null) {
result.append(" Type=\"" + nodeType + "\""); result.append(" Type=\"" + nodeType + "\"");
...@@ -659,7 +628,7 @@ public class ModelToGPML { ...@@ -659,7 +628,7 @@ public class ModelToGPML {
stateString = mr.getName(); stateString = mr.getName();
} }
} }
result.append("TextLabel=\"" + stateString + "\" "); result.append("TextLabel=\"" + XmlParser.escapeXml(stateString) + "\" ");
result.append(">"); result.append(">");
double relX = ((mr.getPosition().getX() - mr.getSpecies().getX()) / mr.getSpecies().getWidth() - 0.5) * 2; double relX = ((mr.getPosition().getX() - mr.getSpecies().getX()) / mr.getSpecies().getWidth() - 0.5) * 2;
double relY = ((mr.getPosition().getY() - mr.getSpecies().getY()) / mr.getSpecies().getHeight() - 0.5) * 2; double relY = ((mr.getPosition().getY() - mr.getSpecies().getY()) / mr.getSpecies().getHeight() - 0.5) * 2;
...@@ -693,7 +662,7 @@ public class ModelToGPML { ...@@ -693,7 +662,7 @@ public class ModelToGPML {
groups.append(" <Group" groups.append(" <Group"
+ " GroupId=\"" + complex.getElementId() + "\"" + " GroupId=\"" + complex.getElementId() + "\""
+ " GraphId=\"" + complex.getElementId() + "\"" + " GraphId=\"" + complex.getElementId() + "\""
+ " TextLabel=\"" + complex.getName() + "\""); + " TextLabel=\"" + XmlParser.escapeXml(complex.getName()) + "\"");
if (complex.getComplex() != null) { if (complex.getComplex() != null) {
groups.append(" GroupRef=\"" + complex.getComplex().getElementId() + "\""); groups.append(" GroupRef=\"" + complex.getComplex().getElementId() + "\"");
} }
...@@ -728,10 +697,10 @@ public class ModelToGPML { ...@@ -728,10 +697,10 @@ public class ModelToGPML {
StringBuilder tmp = new StringBuilder(""); StringBuilder tmp = new StringBuilder("");
interactions.append(" <Interaction GraphId=\"" + reaction.getIdReaction() + "\">\n"); interactions.append(" <Interaction GraphId=\"" + reaction.getIdReaction() + "\">\n");
interactions.append(biopaxParser.toReferenceXml(reaction.getMiriamData()));
if (reaction.getNotes() != null) { if (reaction.getNotes() != null) {