Browse Source

Refactoring of to-PRISM language translations: addition of PrismLanguageTranslator abstract class (preliminary version of) and connection with SBML/reactions/PEPA translators. Also, add support for SBML import to Prism class (but not used elsewhere yet).

git-svn-id: https://www.prismmodelchecker.org/svn/prism/prism/trunk@10687 bbc10eb1-c90d-0410-af57-cb519fbb1720
master
Dave Parker 10 years ago
parent
commit
f8e4f427bc
  1. 91
      prism/src/prism/PEPA2Prism.java
  2. 94
      prism/src/prism/Prism.java
  3. 94
      prism/src/prism/PrismLanguageTranslator.java
  4. 5
      prism/src/prism/Reactions2Prism.java
  5. 118
      prism/src/prism/ReactionsText2Prism.java
  6. 126
      prism/src/prism/SBML2Prism.java

91
prism/src/prism/PEPA2Prism.java

@ -0,0 +1,91 @@
package prism;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
public class PEPA2Prism extends PrismLanguageTranslator
{
private File modelFile;
@Override
public String getName()
{
return "pepa";
}
@Override
public void load(File file) throws PrismException
{
modelFile = file;
}
@Override
public void load(String s) throws PrismException
{
try {
// Create temporary file containing pepa model
modelFile = File.createTempFile("tempPepa" + System.currentTimeMillis(), ".pepa");
FileWriter write = new FileWriter(modelFile);
write.write(s);
write.close();
} catch (IOException e) {
if (modelFile != null) {
modelFile.delete();
modelFile = null;
}
throw new PrismException("Couldn't create temporary file for PEPA conversion");
}
}
@Override
public void load(InputStream in) throws PrismException
{
try {
// Create temporary file containing pepa model
modelFile = File.createTempFile("tempPepa" + System.currentTimeMillis(), ".pepa");
FileWriter write = new FileWriter(modelFile);
int byteIn = in.read();
while (byteIn != -1) {
write.write(byteIn);
byteIn = in.read();
}
write.close();
} catch (IOException e) {
if (modelFile != null) {
modelFile.delete();
modelFile = null;
}
throw new PrismException("Couldn't create temporary file for PEPA conversion");
}
}
@Override
public String translateToString() throws PrismException
{
// Translate PEPA model to PRISM model string
String prismModelString = null;
try {
prismModelString = pepa.compiler.Main.compile("" + modelFile);
} catch (pepa.compiler.InternalError e) {
if (modelFile != null) {
modelFile.delete();
modelFile = null;
}
throw new PrismException("Could not import PEPA model:\n" + e.getMessage());
}
if (modelFile != null) {
modelFile.delete();
modelFile = null;
}
return prismModelString;
}
@Override
public void translate(PrintStream out) throws PrismException
{
out.print(translateToString());
}
}

94
prism/src/prism/Prism.java

@ -34,6 +34,8 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@ -1405,17 +1407,7 @@ public class Prism extends PrismComponent implements PrismSettingsListener
*/
public ModulesFile importPepaFile(File file) throws PrismException, PrismLangException
{
String modelString;
// compile pepa file to string
try {
modelString = pepa.compiler.Main.compile("" + file);
} catch (pepa.compiler.InternalError e) {
throw new PrismException("Could not import PEPA file:\n" + e.getMessage());
}
// parse string as prism model and return
return parseModelString(modelString);
return importModelFile("pepa", file);
}
/**
@ -1424,34 +1416,68 @@ public class Prism extends PrismComponent implements PrismSettingsListener
*/
public ModulesFile importPepaString(String s) throws PrismException, PrismLangException
{
File pepaFile = null;
String modelString;
return importModelString("pepa", s);
}
// create temporary file containing pepa model
try {
pepaFile = File.createTempFile("tempPepa" + System.currentTimeMillis(), ".pepa");
FileWriter write = new FileWriter(pepaFile);
write.write(s);
write.close();
} catch (IOException e) {
if (pepaFile != null)
pepaFile.delete();
throw new PrismException("Couldn't create temporary file for PEPA conversion");
}
/**
* Import a PRISM model from an SBML model in a file
* @param file File to read in
*/
public ModulesFile importSBMLFile(File file) throws PrismException, PrismLangException
{
return importModelFile("sbml", file);
}
// compile pepa file to string
try {
modelString = pepa.compiler.Main.compile("" + pepaFile);
} catch (pepa.compiler.InternalError e) {
if (pepaFile != null)
pepaFile.delete();
throw new PrismException("Could not import PEPA file:\n" + e.getMessage());
}
/**
* Import a PRISM model from an SBML model in a string
* @param file File to read in
*/
public ModulesFile importSBMLString(String s) throws PrismException, PrismLangException
{
return importModelString("sbml", s);
}
// parse string as prism model and return
return parseModelString(modelString);
/**
* Import a PRISM model by translating from another language
*/
public ModulesFile importModelFile(String lang, File file) throws PrismException, PrismLangException
{
PrismLanguageTranslator importer = createPrismLanguageTranslator(lang);
importer.load(file);
String prismModelString = importer.translateToString();
return parseModelString(prismModelString);
}
/**
* Import a PRISM model by translating from another language
*/
public ModulesFile importModelString(String lang, String s) throws PrismException, PrismLangException
{
PrismLanguageTranslator importer = createPrismLanguageTranslator(lang);
importer.load(s);
String prismModelString = importer.translateToString();
return parseModelString(prismModelString);
}
/**
* Create a translator to the PRISM language.
*/
private PrismLanguageTranslator createPrismLanguageTranslator(String lang) throws PrismException
{
PrismLanguageTranslator importer = null;
switch (lang) {
case "pepa":
importer = new PEPA2Prism();
break;
case "sbml":
importer = new SBML2Prism();
break;
default:
throw new PrismException("Unknown import language \"" + lang + "\"");
}
return importer;
}
/**
* Import a PRISM model from a PRISM preprocessor file
* @param file File to read in

94
prism/src/prism/PrismLanguageTranslator.java

@ -0,0 +1,94 @@
//==============================================================================
//
// Copyright (c) 2015-
// Authors:
// * Dave Parker <d.a.parker@cs.bham.ac.uk> (University of Birmingham)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================
package prism;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
/**
* Base class for classes that convert to PRISM language models from other languages.
*/
public abstract class PrismLanguageTranslator
{
/**
* Get a name associated with the language to be translated from.
*/
public abstract String getName();
/**
* Load a model to be translated from an input stream.
*/
public abstract void load(InputStream in) throws PrismException;
/**
* Load a model to be translated from a string.
*/
public void load(String modelString) throws PrismException
{
load(new ByteArrayInputStream(modelString.getBytes()));
}
/**
* Load a model to be translated from a file.
*/
public void load(File file) throws PrismException
{
FileInputStream in;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e) {
throw new PrismException("File \"" + file.getPath() + "\" not found");
}
load(in);
}
/**
* Translate the loaded model to a PRISM language model and write it to an output stream.
*/
public abstract void translate(PrintStream out) throws PrismException;
/**
* Translate the loaded model to a PRISM language model and return it as a string.
*/
public String translateToString() throws PrismException
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
PrintStream out = new PrintStream(os);
translate(out);
try {
return os.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new PrismException("Error translating output stream to string: " + e.getMessage());
}
}
}

5
prism/src/prism/Reactions2Prism.java

@ -31,7 +31,6 @@ import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.util.ArrayList;
@ -44,7 +43,7 @@ import parser.PrismParser;
/**
* Base class for classes that build/store a set of biological reactions and then convert to PRISM.
*/
public class Reactions2Prism
public abstract class Reactions2Prism extends PrismLanguageTranslator
{
// Log for output of warnings, messages
protected PrismLog mainLog = null;
@ -104,7 +103,7 @@ public class Reactions2Prism
/**
* Process the currently loaded reaction set model, convert to PRISM code, export to an OutputStream.
*/
protected void convertToPRISMCode(OutputStream out) throws PrismException
protected void convertToPRISMCode(PrintStream out) throws PrismException
{
StringBuilder sb = convertToPRISMCode();
try {

118
prism/src/prism/ReactionsText2Prism.java

@ -28,8 +28,10 @@ package prism;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
/**
@ -37,32 +39,9 @@ import java.util.ArrayList;
*/
public class ReactionsText2Prism extends Reactions2Prism
{
/**
* Calling point for command-line script:
* e.g. java -cp classes prism.ReactionsText2Prism myfile.txt 100
* (100 denotes (integer) maximum for species population sizes, default is 100)
*/
public static void main(String args[])
{
PrismLog errLog = new PrismPrintStreamLog(System.err);
try {
if (args.length < 1) {
System.err.println("Usage: java -cp classes prism.ReactionsText2Prism <file> [max_amount]");
System.exit(1);
}
ReactionsText2Prism rt2prism = new ReactionsText2Prism(errLog);
try {
if (args.length > 1)
rt2prism.setMaxAmount(Integer.parseInt(args[1]));
} catch (NumberFormatException e) {
throw new PrismException("Invalid max amount \"" + args[1] + "\"");
}
rt2prism.translate(new File(args[0]));
} catch (PrismException e) {
errLog.println("Error: " + e.getMessage() + ".");
}
}
/** Name of the original file */
protected String parsedFileName;
// Enums
private enum SectionType {
@ -81,25 +60,24 @@ public class ReactionsText2Prism extends Reactions2Prism
super(mainLog);
}
/**
* Main method: load reactions file, process and send resulting PRISM file to stdout
*/
public void translate(File file) throws PrismException
@Override
public String getName()
{
// Read in file
extractModelFromFile(file);
// Generate PRISM code
prismCodeHeader = "// File generated by reactions-to-PRISM conversion\n";
prismCodeHeader += "// Original file: " + file.getPath() + "\n\n";
convertToPRISMCode(System.out);
return "reactions";
}
/**
* Build the reaction set model from a parsed SBML file.
*/
private void extractModelFromFile(File file) throws PrismException
@Override
public void load(File file) throws PrismException
{
// Store filename for later use before parsing
parsedFileName = file.getPath();
super.load(file);
}
@Override
public void load(InputStream in) throws PrismException
{
BufferedReader in;
BufferedReader buf;
SectionType secType = null;
String s, s2, ss[], ss2[];
int i, lineNum = 0;
@ -115,9 +93,9 @@ public class ReactionsText2Prism extends Reactions2Prism
try {
// Open file for reading
in = new BufferedReader(new FileReader(file));
buf = new BufferedReader(new InputStreamReader(in));
// Read remaining lines
s = in.readLine();
s = buf.readLine();
lineNum++;
while (s != null) {
// Strip comments
@ -213,7 +191,7 @@ public class ReactionsText2Prism extends Reactions2Prism
reaction.addProduct(product, 1);
}
// Next line
s = in.readLine();
s = buf.readLine();
lineNum++;
if (s == null)
throw new PrismException("missing line in reaction definition");
@ -244,18 +222,58 @@ public class ReactionsText2Prism extends Reactions2Prism
}
}
// read next line
s = in.readLine();
s = buf.readLine();
lineNum++;
}
// close file
in.close();
buf.close();
} catch (IOException e) {
throw new PrismException("File I/O error reading from \"" + file + "\"");
throw new PrismException("I/O error reading reactions: " + e.getMessage());
} catch (NumberFormatException e) {
throw new PrismException("Error detected at line " + lineNum + " of file \"" + file + "\"");
throw new PrismException("Error detected at line " + lineNum + " of reactions file");
} catch (PrismException e) {
throw new PrismException("Error detected (" + e.getMessage() + ") at line " + lineNum + " of reactions file");
}
}
@Override
public void translate(PrintStream out) throws PrismException
{
// Generate PRISM code
prismCodeHeader = "// File generated by reactions-to-PRISM conversion\n";
if (parsedFileName != null) {
prismCodeHeader += "// Original file: " + parsedFileName + "\n\n";
}
convertToPRISMCode(out);
// Reset filename storage
parsedFileName = null;
}
/**
* Calling point for command-line script:
* e.g. java -cp classes prism.ReactionsText2Prism myfile.txt 100
* (100 denotes (integer) maximum for species population sizes, default is 100)
*/
public static void main(String args[])
{
PrismLog errLog = new PrismPrintStreamLog(System.err);
try {
if (args.length < 1) {
System.err.println("Usage: java -cp classes prism.ReactionsText2Prism <file> [max_amount]");
System.exit(1);
}
ReactionsText2Prism rt2prism = new ReactionsText2Prism(errLog);
try {
if (args.length > 1)
rt2prism.setMaxAmount(Integer.parseInt(args[1]));
} catch (NumberFormatException e) {
throw new PrismException("Invalid max amount \"" + args[1] + "\"");
}
rt2prism.load(new File(args[0]));
rt2prism.translate(System.out);
} catch (PrismException e) {
throw new PrismException("Error detected (" + e.getMessage() + ") at line " + lineNum + " of file \"" + file + "\"");
errLog.println("Error: " + e.getMessage() + ".");
}
}
}

126
prism/src/prism/SBML2Prism.java

@ -29,6 +29,7 @@ package prism;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
@ -47,33 +48,10 @@ import org.xml.sax.SAXParseException;
public class SBML2Prism extends Reactions2Prism implements EntityResolver
{
/**
* Calling point for command-line script:
* This is probably the sbml2prism (found in etc/scripts)
* But it can also be called as, e.g.: java -cp classes prism.SBML2Prism myfile.sbml 100
* (100 denotes (integer) maximum for species population sizes, default is 100)
* (also used to compute amounts from (real-valued) concentrations)
*/
public static void main(String args[])
{
PrismLog errLog = new PrismPrintStreamLog(System.err);
try {
if (args.length < 1) {
System.err.println("Usage: sbml2prism <sbml_file> [max_amount]");
System.exit(1);
}
SBML2Prism sbml2prism = new SBML2Prism(errLog);
try {
if (args.length > 1)
sbml2prism.setMaxAmount(Integer.parseInt(args[1]));
} catch (NumberFormatException e) {
throw new PrismException("Invalid max amount \"" + args[1] + "\"");
}
sbml2prism.translate(new File(args[0]));
} catch (PrismException e) {
errLog.println("Error: " + e.getMessage() + ".");
}
}
/** Name of the original SBML file */
protected String parsedFileName;
/** Temporary storage of the parsed XML */
protected Document parsedSBML;
// Constructors
@ -87,29 +65,26 @@ public class SBML2Prism extends Reactions2Prism implements EntityResolver
super(mainLog);
}
/**
* Main method: load SBML file, process and send resulting PRISM file to stdout
*/
public void translate(File file) throws PrismException
@Override
public String getName()
{
// Read in SBML
Document doc = parseSBML(file);
checkSBMLVersion(doc);
extractModelFromSBML(doc);
// Generate PRISM code
prismCodeHeader = "// File generated by automatic SBML-to-PRISM conversion\n";
prismCodeHeader += "// Original SBML file: " + file.getPath() + "\n\n";
convertToPRISMCode(System.out);
return "sbml";
}
/**
* Parse SBML file {@code file} and return as an XML Document object.
*/
private Document parseSBML(File file) throws PrismException
@Override
public void load(File file) throws PrismException
{
// Store filename for later use before parsing
parsedFileName = file.getPath();
super.load(file);
}
@Override
public void load(InputStream in) throws PrismException
{
DocumentBuilderFactory factory;
DocumentBuilder builder;
Document doc = null;
parsedSBML = null;
// Create XML parser
factory = DocumentBuilderFactory.newInstance();
@ -138,23 +113,22 @@ public class SBML2Prism extends Reactions2Prism implements EntityResolver
throw new PrismException("Couldn't create XML parser");
}
// Parse
// Parse XML
try {
doc = builder.parse(file);
parsedSBML = builder.parse(in);
} catch (IOException e) {
throw new PrismException("Couldn't load file \"" + file.getPath() + "\": " + e.getMessage());
throw new PrismException("Error reading SBML: " + e.getMessage());
} catch (SAXException e) {
throw new PrismException("Invalid XML file:\n" + e.getMessage());
}
return doc;
}
// Function used by parseSBML() above to find the SBML DTD
// (this currently unused since we do not validate the SBML file when reading)
// (and since the DTD specified in the SBML files is not local)
// (if validation is enabled, put the DTD file "sbml.dtd" in PRISM's "dtds" directory)
/**
* Function used by parseSBML() above to find the SBML DTD
* (this currently unused since we do not validate the SBML file when reading)
* (and since the DTD specified in the SBML files is not local)
* (if validation is enabled, put the DTD file "sbml.dtd" in PRISM's "dtds" directory)
*/
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
{
InputSource inputSource = null;
@ -170,6 +144,21 @@ public class SBML2Prism extends Reactions2Prism implements EntityResolver
return inputSource;
}
@Override
public void translate(PrintStream out) throws PrismException
{
checkSBMLVersion(parsedSBML);
extractModelFromSBML(parsedSBML);
// Generate PRISM code
prismCodeHeader = "// File generated by automatic SBML-to-PRISM conversion\n";
if (parsedFileName != null) {
prismCodeHeader += "// Original SBML file: " + parsedFileName + "\n\n";
}
convertToPRISMCode(out);
// Reset filename storage
parsedFileName = null;
}
/**
* Check that we can handle whatever level/version this file is.
*/
@ -348,4 +337,33 @@ public class SBML2Prism extends Reactions2Prism implements EntityResolver
reactionList.add(reaction);
}
}
/**
* Calling point for command-line script:
* This is probably the sbml2prism (found in etc/scripts)
* But it can also be called as, e.g.: java -cp classes prism.SBML2Prism myfile.sbml 100
* (100 denotes (integer) maximum for species population sizes, default is 100)
* (also used to compute amounts from (real-valued) concentrations)
*/
public static void main(String args[])
{
PrismLog errLog = new PrismPrintStreamLog(System.err);
try {
if (args.length < 1) {
System.err.println("Usage: sbml2prism <sbml_file> [max_amount]");
System.exit(1);
}
SBML2Prism sbml2prism = new SBML2Prism(errLog);
try {
if (args.length > 1)
sbml2prism.setMaxAmount(Integer.parseInt(args[1]));
} catch (NumberFormatException e) {
throw new PrismException("Invalid max amount \"" + args[1] + "\"");
}
sbml2prism.load(new File(args[0]));
sbml2prism.translate(System.out);
} catch (PrismException e) {
errLog.println("Error: " + e.getMessage() + ".");
}
}
}
Loading…
Cancel
Save