Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
metexplore
met4j
Commits
c387e93b
Commit
c387e93b
authored
Mar 25, 2022
by
lcottret
Browse files
[in progress] Refactoring and tests JsbmlReader
parent
b11d2508
Changes
4
Hide whitespace changes
Inline
Side-by-side
met4j-io/src/main/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/JsbmlReader.java
View file @
c387e93b
...
...
@@ -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
xml
String
=
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
.
xml
String
=
this
.
inputStreamToString
(
inputStream
);
this
.
useValidator
=
false
;
}
...
...
@@ -138,12 +136,12 @@ public class JsbmlReader {
/**
* <p>Constructor for JsbmlReader.</p>
*
* @param inputStream a {@link java.io.InputStream} object.
* @param inputStream
a {@link java.io.InputStream} object.
* @param useValidator a boolean.
* @throws java.io.IOException if any.
*/
public
JsbmlReader
(
InputStream
inputStream
,
boolean
useValidator
)
throws
IOException
{
this
.
xml
=
this
.
inputStreamToString
(
inputStream
);
this
.
xml
String
=
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,22 +237,26 @@ public class JsbmlReader {
converter
.
setPackages
(
verifiedPkgs
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
System
.
exit
(
1
);
throw
new
Met4jSbmlReaderException
(
"Problem while setting the JSBML packages"
);
}
System
.
err
.
println
(
"Parsing model "
+
this
.
getModel
().
getId
());
return
parseModel
();
}
else
{
this
.
getConverter
().
parseModel
();
return
null
;
}
}
System
.
err
.
println
(
"End Parsing model "
+
this
.
getModel
().
getId
());
protected
BioNetwork
parseModel
()
throws
Met4jSbmlReaderException
{
System
.
err
.
println
(
"Parsing model "
+
this
.
getModel
().
getId
());
this
.
errorsAndWarnings
.
addAll
(
PackageParser
.
errorsAndWarnings
);
this
.
getConverter
().
parseModel
(
);
return
this
.
getConverter
().
getNetwork
();
}
else
{
System
.
err
.
println
(
"End Parsing model "
+
this
.
getModel
().
getId
());
return
null
;
}
this
.
errorsAndWarnings
.
addAll
(
PackageParser
.
errorsAndWarnings
);
return
this
.
getConverter
().
getNetwork
();
}
/**
...
...
@@ -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
I
nt
eger
code
=
doc
.
checkConsistency
();
i
nt
code
=
doc
.
checkConsistency
Offline
();
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
;
}
...
...
met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/JsbmlReaderTest.java
0 → 100644
View file @
c387e93b
/*
* 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
met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/SbmlDocInvalidMock.java
0 → 100644
View file @
c387e93b
/*
* 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"
);
}
}
met4j-io/src/test/java/fr/inrae/toulouse/metexplore/met4j_io/jsbml/reader/SbmlDocMock.java
0 → 100644
View file @
c387e93b
/*
* Copyright INRAE (2022)
*
* contact-metexplore@inrae.fr
<