Commit c387e93b authored by lcottret's avatar lcottret
Browse files

[in progress] Refactoring and tests JsbmlReader

parent b11d2508
......@@ -39,12 +39,10 @@ package fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import javax.xml.stream.XMLStreamException;
import fr.inrae.toulouse.metexplore.met4j_io.jsbml.errors.JSBMLPackageReaderException;
import org.sbml.jsbml.Model;
import org.sbml.jsbml.SBMLDocument;
import org.sbml.jsbml.SBMLError;
......@@ -66,8 +64,8 @@ import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.PackageParser;
* depending on the SBML level defined in the file
*
* @author Benjamin Merlet
* @since 3.0
* @version $Id: $Id
* @since 3.0
*/
public class JsbmlReader {
......@@ -80,7 +78,7 @@ public class JsbmlReader {
* The list of errors and/or warnings found by jsbml while parsing the SBML
* File
*/
public ArrayList<String> errorsAndWarnings = new ArrayList<String>();
public ArrayList<String> errorsAndWarnings = new ArrayList<>();
/**
* The SBML filename
*/
......@@ -96,9 +94,9 @@ public class JsbmlReader {
/**
* Set to true to use SBML online validator
*/
private boolean useValidator = true;
private boolean useValidator;
private String xml = null;
private String xmlString = null;
/**
* Constructor
......@@ -130,7 +128,7 @@ public class JsbmlReader {
* @throws java.io.IOException if any.
*/
public JsbmlReader(InputStream inputStream) throws IOException {
this.xml = this.inputStreamToString(inputStream);
this.xmlString = this.inputStreamToString(inputStream);
this.useValidator = false;
}
......@@ -143,7 +141,7 @@ public class JsbmlReader {
* @throws java.io.IOException if any.
*/
public JsbmlReader(InputStream inputStream, boolean useValidator) throws IOException {
this.xml = this.inputStreamToString(inputStream);
this.xmlString = this.inputStreamToString(inputStream);
this.useValidator = useValidator;
}
......@@ -152,21 +150,21 @@ public class JsbmlReader {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + System.lineSeparator());
sb.append(line).append(System.lineSeparator());
}
return sb.toString();
}
/**
/*
* A test main method
*
* @param args the arguments
* @throws fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException if any.
* @throws java.io.IOException if any.
*/
public static void main(String[] args) throws Met4jSbmlReaderException, IOException, JSBMLPackageReaderException {
/* public static void main(String[] args) throws Met4jSbmlReaderException, IOException, JSBMLPackageReaderException {
// String
String inputFile = args[0];
......@@ -205,7 +203,7 @@ public class JsbmlReader {
System.err.println("End :" + new Date());
}
}*/
/**
* <p>read.</p>
......@@ -218,6 +216,7 @@ public class JsbmlReader {
* @throws fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException if any.
*/
public BioNetwork read(ArrayList<PackageParser> userEnabledPackages) throws Met4jSbmlReaderException {
try {
this.initiateModel();
} catch (IOException | XMLStreamException e) {
......@@ -228,8 +227,7 @@ public class JsbmlReader {
if (this.isValidSBML()) {
System.err.println("Verifying enabled Plugins...");
ArrayList<PackageParser> verifiedPkgs = this
.verifyPackages(userEnabledPackages);
ArrayList<PackageParser> verifiedPkgs = this.verifyPackages(userEnabledPackages);
JsbmlToBioNetwork converter = new JsbmlToBioNetwork(this.getModel());
......@@ -239,9 +237,17 @@ public class JsbmlReader {
converter.setPackages(verifiedPkgs);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
throw new Met4jSbmlReaderException("Problem while setting the JSBML packages");
}
return parseModel();
} else {
return null;
}
}
protected BioNetwork parseModel() throws Met4jSbmlReaderException {
System.err.println("Parsing model " + this.getModel().getId());
this.getConverter().parseModel();
......@@ -251,10 +257,6 @@ public class JsbmlReader {
this.errorsAndWarnings.addAll(PackageParser.errorsAndWarnings);
return this.getConverter().getNetwork();
} else {
return null;
}
}
/**
......@@ -264,9 +266,7 @@ public class JsbmlReader {
* @throws fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException if any.
*/
public BioNetwork read() throws Met4jSbmlReaderException {
ArrayList<PackageParser> pkgs = new ArrayList<PackageParser>(Arrays.asList(
new NotesParser(true), new FBCParser(), new GroupPathwayParser(), new AnnotationParser(
true)));
ArrayList<PackageParser> pkgs = new ArrayList<>(Arrays.asList(new NotesParser(true), new FBCParser(), new GroupPathwayParser(), new AnnotationParser(true)));
return this.read(pkgs);
}
......@@ -278,25 +278,22 @@ public class JsbmlReader {
* @throws fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException if any.
*/
public BioNetwork readWithoutNotes() throws Met4jSbmlReaderException {
ArrayList<PackageParser> pkgs = new ArrayList<PackageParser>(Arrays.asList( new FBCParser(), new GroupPathwayParser(), new AnnotationParser(
true)));
ArrayList<PackageParser> pkgs = new ArrayList<>(Arrays.asList(new FBCParser(), new GroupPathwayParser(), new AnnotationParser(true)));
return this.read(pkgs);
}
/**
* Verifies the Set of user defined packages and orders them
*
* @param userEnabledPackages the packages enabled by the user
* @return the ordered list of packages
*/
private ArrayList<PackageParser> verifyPackages(
ArrayList<PackageParser> userEnabledPackages) {
private ArrayList<PackageParser> verifyPackages(ArrayList<PackageParser> userEnabledPackages) {
ArrayList<PackageParser> start = new ArrayList<PackageParser>();
ArrayList<PackageParser> end = new ArrayList<PackageParser>();
ArrayList<PackageParser> start = new ArrayList<>();
ArrayList<PackageParser> end = new ArrayList<>();
if (userEnabledPackages == null) {
System.err.println("No user package defined");
......@@ -330,15 +327,7 @@ public class JsbmlReader {
*/
private void initiateModel() throws IOException, XMLStreamException {
SBMLDocument doc;
if(this.xml == null) {
File sbmlFile = new File(this.getFilename());
doc = SBMLReader.read(sbmlFile);
}
else {
doc = SBMLReader.read(xml);
}
SBMLDocument doc = sbmlRead();
if (this.useValidator) {
System.err.println("Validating Input SBML..");
......@@ -350,6 +339,19 @@ public class JsbmlReader {
}
protected SBMLDocument sbmlRead() throws XMLStreamException, IOException {
SBMLDocument doc;
if (this.xmlString == null) {
File sbmlFile = new File(this.getFilename());
doc = SBMLReader.read(sbmlFile);
} else {
doc = SBMLReader.read(xmlString);
}
return doc;
}
/**
* Validates the SBML document using the online validator
*
......@@ -362,46 +364,35 @@ public class JsbmlReader {
// TODO test if the validator is working properly before checking
// consistency.
doc.setConsistencyChecks(
SBMLValidator.CHECK_CATEGORY.GENERAL_CONSISTENCY, true);
doc.setConsistencyChecks(
SBMLValidator.CHECK_CATEGORY.IDENTIFIER_CONSISTENCY, true);
doc.setConsistencyChecks(
SBMLValidator.CHECK_CATEGORY.UNITS_CONSISTENCY, false);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.SBO_CONSISTENCY,
false);
doc.setConsistencyChecks(
SBMLValidator.CHECK_CATEGORY.MATHML_CONSISTENCY, true);
doc.setConsistencyChecks(
SBMLValidator.CHECK_CATEGORY.OVERDETERMINED_MODEL, true);
doc.setConsistencyChecks(
SBMLValidator.CHECK_CATEGORY.MODELING_PRACTICE, false);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.GENERAL_CONSISTENCY, true);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.IDENTIFIER_CONSISTENCY, true);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.UNITS_CONSISTENCY, true);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.SBO_CONSISTENCY, true);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.MATHML_CONSISTENCY, false);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.OVERDETERMINED_MODEL, false);
doc.setConsistencyChecks(SBMLValidator.CHECK_CATEGORY.MODELING_PRACTICE, false);
// Online validator
Integer code = doc.checkConsistency();
int code = doc.checkConsistencyOffline();
if (code > 0) {
HashMap<Integer, String> parsedErrors = new HashMap<Integer, String>();
HashMap<Integer, String> parsedErrors = new HashMap<>();
for (SBMLError err : doc.getErrorLog().getValidationErrors()) {
StringBuilder sb = new StringBuilder();
if (parsedErrors.containsKey(err.getCode())) {
sb.append(parsedErrors.get(err.getCode())).append(", ")
.append(err.getLine()).toString();
if (!parsedErrors.containsKey(err.getCode())) {
parsedErrors.put(err.getCode(), "");
} else {
sb.append(parsedErrors.get(err.getCode())).append("\n");
}
sb.append("SBML ").append(err.getSeverity()).append(" #")
.append(err.getCode()).append(" on ");
sb.append(err.getCategory()).append(":");
sb.append(err.getShortMessage().getMessage()).append("\n")
.append("Line(s): ").append(err.getLine());
}
sb.append(err.getSeverity()).append(" line ").append(err.getLine())
.append(" : ").append(err.getCategory())
.append(" : ").append(err.getShortMessage().getMessage());
String newMessage = sb.toString();
parsedErrors.put(err.getCode(), newMessage);
......@@ -409,9 +400,7 @@ public class JsbmlReader {
errorsAndWarnings.addAll(parsedErrors.values());
if (doc.getErrorLog().getNumFailsWithSeverity(SEVERITY.ERROR) != 0) {
return false;
}
return doc.getErrorLog().getNumFailsWithSeverity(SEVERITY.ERROR) == 0;
}
return true;
}
......
/*
* Copyright INRAE (2022)
*
* contact-metexplore@inrae.fr
*
* This software is a computer program whose purpose is to [describe
* functionalities and technical features of your software].
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*
*/
package fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader;
import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork;
import fr.inrae.toulouse.metexplore.met4j_io.kegg.KeggApiMock;
import org.junit.Test;
import org.sbml.jsbml.SBMLDocument;
import org.w3c.dom.Document;
import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
public class JsbmlReaderTest {
@Test
public void read() throws IOException, XMLStreamException, Met4jSbmlReaderException {
JsbmlReader reader = spy(new JsbmlReader("test"));
SbmlDocMock docMockGenerator = new SbmlDocMock();
SBMLDocument doc = docMockGenerator.doc;
doReturn(doc).when(reader).sbmlRead();
BioNetwork network = reader.read();
assertNotNull(network);
assertEquals(3, network.getReactionsView().size());
// Other tests are done on JsbmlToBioNetwork
}
@Test
public void validateSbml() throws IOException, XMLStreamException, Met4jSbmlReaderException {
JsbmlReader reader = spy(new JsbmlReader("test"));
SbmlDocMock docMockGenerator = new SbmlDocMock();
SBMLDocument doc = docMockGenerator.doc;
Boolean check = reader.validateSBML(doc);
System.err.println(reader.errorsAndWarnings);
assertTrue(check);
SbmlDocInvalidMock invalidDocMockGenerator = new SbmlDocInvalidMock();
SBMLDocument invalidDoc = invalidDocMockGenerator.doc;
assertFalse(reader.validateSBML(invalidDoc));
}
@Test
public void readWithoutNotes() {
fail();
}
@Test
public void validateSBML() {
fail();
}
}
\ No newline at end of file
/*
* Copyright INRAE (2022)
*
* contact-metexplore@inrae.fr
*
* This software is a computer program whose purpose is to [describe
* functionalities and technical features of your software].
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
*
*/
package fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader;
import org.sbml.jsbml.*;
import javax.xml.stream.XMLStreamException;
public class SbmlDocInvalidMock {
public SBMLDocument doc;
Model model;
JsbmlToBioNetwork parser;
Compartment c1, c2, c3;
Species m1, m2, m3, m4;
Reaction r1, r2, r3;
SpeciesType type1, type2, type3;
public SbmlDocInvalidMock() {
doc = new SBMLDocument(3, 1);
model = doc.createModel();
model.setId("modelId");
model.setName("modelName");
c1 = model.createCompartment("c1");
c1.setName("compartment1");
c2 = model.createCompartment("c2");
c2.setName("compartment2");
c3 = model.createCompartment("c3");
CompartmentType compartmentType = new CompartmentType("cType");
model.addCompartmentType(compartmentType);
c1.setCompartmentType(compartmentType);
c1.setOutside(c2);
c2.setOutside(c1);
c1.setSize(2.0);
c1.setSpatialDimensions(4.0);
c1.setName("test");
m1 = model.createSpecies("m1", "name1", c1);
m2 = model.createSpecies("m2", "name2", c2);
m4 = model.createSpecies("m4", "m4", c1);
m3 = model.createSpecies("m3");
m3.setCompartment(c1);
m1.setConstant(true);
m2.setConstant(false);
m1.setInitialAmount(2.0);
m2.setInitialAmount(3.0);
if (model.getLevel() < 3) {
m1.setCharge(3);
m2.setCharge(4);
type1 = model.createSpeciesType("type1");
type1.setSBOTerm(12345);
type2 = model.createSpeciesType("type2");
Annotation annotation = new Annotation();
CVTerm cvterm = new CVTerm();
cvterm.addResource("urn.miriam.obo.go#GO%3A1234567");
cvterm.setQualifierType(CVTerm.Type.BIOLOGICAL_QUALIFIER);
cvterm.setBiologicalQualifierType(CVTerm.Qualifier.BQB_IS);
annotation.addCVTerm(cvterm);
type2.setAnnotation(annotation);
type3 = model.createSpeciesType("type3");
try {
type3.setNotes(
"<notes>\n" + "<body xmlns=\"http://www.w3.org/1999/xhtml\"><p>Attr:val</p></body></notes>");
} catch (XMLStreamException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
m1.setSpeciesType(type1);
m2.setSpeciesType(type2);
m3.setSpeciesType(type3);
}
r1 = model.createReaction("r1");
r1.setName("name1");
r1.setReversible(false);
if (model.getLevel() > 2) {
r1.setSBOTerm("SBO:0000167");
}
r1.setFast(true);
r2 = model.createReaction("r2");
SpeciesReference m1Ref = new SpeciesReference(m1);
m1Ref.setStoichiometry(2.0);
SpeciesReference m1RefBis = new SpeciesReference(m1);
m1RefBis.setStoichiometry(3.0);
SpeciesReference m2Ref = new SpeciesReference(m2);
if (model.getLevel() > 2) {
m1Ref.setConstant(true);
m2Ref.setConstant(false);
}
// This metabolite must not be taken into account
SpeciesReference m4Ref = new SpeciesReference(m4);
m4Ref.setStoichiometry(0.0);
r1.addReactant(m1Ref);
r1.addReactant(m4Ref);
r1.addProduct(m2Ref);
r1.addProduct(m1RefBis);
r3 = model.createReaction("r3");
}
}
/*
* Copyright INRAE (2022)
*
* contact-metexplore@inrae.fr
*
* This software is a computer program whose purpose is to [describe
* functionalities and technical features of your software].
*
* This software is governed by the CeCILL license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL
* license as circulated by CEA, CNRS and INRIA at the following URL
* "https://cecill.info/licences/Licence_CeCILL_V2.1-en.html".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited