Commit 0adda777 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

workaround for bug in JSBML library...

workaround for bug in JSBML library (https://github.com/sbmlteam/jsbml/issues/195) XMLNode.convertStringToXMLNode is not thread safe
parent 85db0ad2
Pipeline #20455 passed with stage
in 14 minutes and 24 seconds
minerva (14.0.9) stable; urgency=medium
* Bug fix: simultanous export to SBML of more than one file could result in
500 Internal Server Error (#1110)
-- Piotr Gawron <piotr.gawron@uni.lu> Mon, 3 Feb 2020 15:00:00 +0200
minerva (14.0.8) stable; urgency=medium minerva (14.0.8) stable; urgency=medium
* Bug fix: API didn't allow to upload pluins with local url (#1084, * Bug fix: API didn't allow to upload pluins with local url (#1084,
regression 14.0.7) regression 14.0.7)
......
package lcsb.mapviewer.converter.model.sbml; package lcsb.mapviewer.converter.model.sbml;
import java.util.Collection;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import org.apache.commons.text.StringEscapeUtils; import org.apache.commons.text.StringEscapeUtils;
import org.sbml.jsbml.AbstractNamedSBase; import org.sbml.jsbml.AbstractNamedSBase;
import org.sbml.jsbml.util.StringTools;
import org.sbml.jsbml.xml.XMLNode;
import org.sbml.jsbml.xml.stax.SBMLReader;
import lcsb.mapviewer.converter.InvalidInputDataExecption; import lcsb.mapviewer.converter.InvalidInputDataExecption;
import lcsb.mapviewer.converter.annotation.XmlAnnotationParser;
import lcsb.mapviewer.model.map.MiriamData;
/** /**
* This utility class parses notes from SBML node and prepares escaped string * This utility class parses notes from SBML node and prepares escaped string
...@@ -60,4 +67,14 @@ public class NotesUtility { ...@@ -60,4 +67,14 @@ public class NotesUtility {
return StringEscapeUtils.escapeXml10(notes); return StringEscapeUtils.escapeXml10(notes);
} }
public static XMLNode getRdfNode(Collection<MiriamData> data, String metaid) throws XMLStreamException {
XmlAnnotationParser parser = new XmlAnnotationParser();
String rdf = parser.dataSetToXmlString(data, metaid);
return getRdfNode(rdf);
}
public static XMLNode getRdfNode(String rdf) throws XMLStreamException {
return new SBMLReader().readNotes(StringTools.toXMLAnnotationString(rdf));
}
} }
...@@ -13,10 +13,10 @@ import org.sbml.jsbml.ext.SBasePlugin; ...@@ -13,10 +13,10 @@ import org.sbml.jsbml.ext.SBasePlugin;
import org.sbml.jsbml.ext.layout.*; import org.sbml.jsbml.ext.layout.*;
import org.sbml.jsbml.ext.multi.MultiModelPlugin; import org.sbml.jsbml.ext.multi.MultiModelPlugin;
import org.sbml.jsbml.ext.render.*; import org.sbml.jsbml.ext.render.*;
import org.sbml.jsbml.xml.XMLNode;
import lcsb.mapviewer.common.XmlParser; import lcsb.mapviewer.common.XmlParser;
import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.converter.annotation.XmlAnnotationParser;
import lcsb.mapviewer.model.graphics.ArrowType; import lcsb.mapviewer.model.graphics.ArrowType;
import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.InconsistentModelException; import lcsb.mapviewer.model.map.InconsistentModelException;
...@@ -117,10 +117,9 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s ...@@ -117,10 +117,9 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s
String mapKey = getSbmlIdKey(element); String mapKey = getSbmlIdKey(element);
if (sbmlElementByElementNameAndCompartmentName.get(mapKey) == null) { if (sbmlElementByElementNameAndCompartmentName.get(mapKey) == null) {
S sbmlElement = createSbmlElement(element); S sbmlElement = createSbmlElement(element);
XmlAnnotationParser parser = new XmlAnnotationParser();
String rdf = parser.dataSetToXmlString(element.getMiriamData(), sbmlElement.getId());
try { try {
sbmlElement.setAnnotation(rdf); XMLNode rdfNode = NotesUtility.getRdfNode(element.getMiriamData(), sbmlElement.getId());
sbmlElement.setAnnotation(rdfNode);
} catch (XMLStreamException e1) { } catch (XMLStreamException e1) {
throw new InconsistentModelException(e1); throw new InconsistentModelException(e1);
} }
......
...@@ -104,7 +104,7 @@ public class SbmlExporter { ...@@ -104,7 +104,7 @@ public class SbmlExporter {
String rdf = parser.dataSetToXmlString(model.getMiriamData(), model.getAuthors(), model.getCreationDate(), String rdf = parser.dataSetToXmlString(model.getMiriamData(), model.getAuthors(), model.getCreationDate(),
model.getModificationDates(), model.getIdModel()); model.getModificationDates(), model.getIdModel());
try { try {
result.setAnnotation(rdf); result.setAnnotation(NotesUtility.getRdfNode(rdf));
} catch (XMLStreamException e1) { } catch (XMLStreamException e1) {
throw new InconsistentModelException(e1); throw new InconsistentModelException(e1);
} }
......
...@@ -8,6 +8,7 @@ import java.io.File; ...@@ -8,6 +8,7 @@ import java.io.File;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
import org.apache.commons.lang3.mutable.MutableBoolean;
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 org.junit.Test; import org.junit.Test;
...@@ -21,6 +22,7 @@ import lcsb.mapviewer.converter.ConverterParams; ...@@ -21,6 +22,7 @@ import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.graphics.PolylineData; import lcsb.mapviewer.model.graphics.PolylineData;
import lcsb.mapviewer.model.graphics.PolylineDataComparator; import lcsb.mapviewer.model.graphics.PolylineDataComparator;
import lcsb.mapviewer.model.map.InconsistentModelException;
import lcsb.mapviewer.model.map.compartment.Compartment; import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.model.*; import lcsb.mapviewer.model.map.model.*;
import lcsb.mapviewer.model.map.reaction.*; import lcsb.mapviewer.model.map.reaction.*;
...@@ -678,5 +680,31 @@ public class SbmlExporterTest extends SbmlTestFunctions { ...@@ -678,5 +680,31 @@ public class SbmlExporterTest extends SbmlTestFunctions {
} }
@Test
public void testExportMultiTthreaded() throws Exception {
final Model originalModel = getModelAfterSerializing("testFiles/small/small_molecule.xml");
Set<Thread> threads = new HashSet<>();
MutableBoolean exceptionHappened = new MutableBoolean(false);
for (int i = 0; i < 20; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
new SbmlExporter().toXml(originalModel);
} catch (Exception e) {
exceptionHappened.setTrue();
e.printStackTrace();
}
}
});
thread.start();
threads.add(thread);
}
for (Thread thread : threads) {
thread.join();
}
assertFalse(exceptionHappened.booleanValue());
}
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment