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
* Bug fix: API didn't allow to upload pluins with local url (#1084,
regression 14.0.7)
......
package lcsb.mapviewer.converter.model.sbml;
import java.util.Collection;
import javax.xml.stream.XMLStreamException;
import org.apache.commons.text.StringEscapeUtils;
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.annotation.XmlAnnotationParser;
import lcsb.mapviewer.model.map.MiriamData;
/**
* This utility class parses notes from SBML node and prepares escaped string
......@@ -60,4 +67,14 @@ public class NotesUtility {
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;
import org.sbml.jsbml.ext.layout.*;
import org.sbml.jsbml.ext.multi.MultiModelPlugin;
import org.sbml.jsbml.ext.render.*;
import org.sbml.jsbml.xml.XMLNode;
import lcsb.mapviewer.common.XmlParser;
import lcsb.mapviewer.common.exception.InvalidStateException;
import lcsb.mapviewer.converter.annotation.XmlAnnotationParser;
import lcsb.mapviewer.model.graphics.ArrowType;
import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.InconsistentModelException;
......@@ -117,10 +117,9 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s
String mapKey = getSbmlIdKey(element);
if (sbmlElementByElementNameAndCompartmentName.get(mapKey) == null) {
S sbmlElement = createSbmlElement(element);
XmlAnnotationParser parser = new XmlAnnotationParser();
String rdf = parser.dataSetToXmlString(element.getMiriamData(), sbmlElement.getId());
try {
sbmlElement.setAnnotation(rdf);
XMLNode rdfNode = NotesUtility.getRdfNode(element.getMiriamData(), sbmlElement.getId());
sbmlElement.setAnnotation(rdfNode);
} catch (XMLStreamException e1) {
throw new InconsistentModelException(e1);
}
......
......@@ -104,7 +104,7 @@ public class SbmlExporter {
String rdf = parser.dataSetToXmlString(model.getMiriamData(), model.getAuthors(), model.getCreationDate(),
model.getModificationDates(), model.getIdModel());
try {
result.setAnnotation(rdf);
result.setAnnotation(NotesUtility.getRdfNode(rdf));
} catch (XMLStreamException e1) {
throw new InconsistentModelException(e1);
}
......
......@@ -8,6 +8,7 @@ import java.io.File;
import java.lang.reflect.Modifier;
import java.util.*;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
......@@ -21,6 +22,7 @@ import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.graphics.PolylineData;
import lcsb.mapviewer.model.graphics.PolylineDataComparator;
import lcsb.mapviewer.model.map.InconsistentModelException;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.model.*;
import lcsb.mapviewer.model.map.reaction.*;
......@@ -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