import java.io.Reader;\r
import java.util.ArrayList;\r
import java.util.HashMap;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
\r
import org.simantics.sysdyn.mdlImport.mdlElements.Auxiliary;\r
import org.simantics.sysdyn.mdlImport.mdlElements.Cloud;\r
import org.simantics.sysdyn.mdlImport.mdlElements.Variable;\r
import org.simantics.sysdyn.mdlImport.mdlElements.View;\r
\r
+/*\r
+ * THINGS TO FIX:\r
+ * - vensim apparently supports infix operators (:AND: instead of AND()), these must be handled\r
+ * - "public" seems to be a keyboard of some sort which causes a problem in certain variable names\r
+ * - something is seriously wrong with the sketch import\r
+ * - how should models with multiple sketches be handled (this might already work)\r
+ * - instead of splitting the file into blocks, the parser could already process the data further which would greatly simplify later methods\r
+ */\r
+\r
public class MdlParser {\r
- \r
+\r
+ private enum State {\r
+ VARIABLE, CONTROL, SKETCH, OTHER\r
+ }\r
+\r
public static Model parse(File file) {\r
- \r
+\r
Model model = new Model();\r
- \r
+\r
String[] name = file.getName().split("\\.mdl");\r
model.setName(name[0]);\r
+\r
+ MdlFile mdlFile = getMdlFile(file);\r
+\r
+ for (String variable : mdlFile.getVariableData()) {\r
+ parseElement(variable);\r
+ }\r
+\r
+ for (ArrayList<String> sketch : mdlFile.getSketchData()) {\r
+ parseSketch(sketch);\r
+ }\r
+\r
+ //MdlFile test = getMdlContents(file);\r
+\r
+ //getVariableData(model, test.getVariableData());\r
+\r
+ //getSketchData(model, mdlFile.getSketchData());\r
+\r
+ //getControlData(model, mdlFile.getControlData());\r
+\r
+ //getOthertData(model, mdlFile.getOtherData());\r
+\r
+ //setAllSubscripts(model);\r
+\r
+ return null;\r
+ }\r
+\r
+ private static final String UTF_8 = "{UTF-8}";\r
+ private static final String CONTROL_STR = ".Control";\r
+ private static final String SKETCH_START = "\\\\\\---///";\r
+ private static final String SKETCH_END = "///---\\\\\\";\r
+\r
+ private static MdlFile getMdlFile(File file) {\r
+ MdlFile mdl = new MdlFile();\r
+\r
+ try {\r
+ BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));\r
+ String line = reader.readLine();\r
+\r
+ if (line != null && line.startsWith(UTF_8)) {\r
+ reader.close();\r
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));\r
+ // skip the "{UTF-8}" line\r
+ reader.readLine();\r
+ line = reader.readLine();\r
+ }\r
+\r
+ State state = State.VARIABLE;\r
+\r
+ while (line != null) {\r
+ line = line.trim();\r
+\r
+ if (line.isEmpty()) {\r
+ line = reader.readLine();\r
+ continue;\r
+ }\r
+\r
+ switch (state) {\r
+ case VARIABLE:\r
+ if (line.startsWith(SKETCH_START)) {\r
+ state = State.SKETCH;\r
+ continue; \r
+ }\r
+\r
+ String variable = readElement(reader, line);\r
+\r
+ if (variable.contains(CONTROL_STR)) {\r
+ state = State.CONTROL;\r
+ break;\r
+ }\r
+\r
+ mdl.addVariableData(variable);\r
+ break;\r
+\r
+ case CONTROL:\r
+ if (line.startsWith(SKETCH_START)) {\r
+ state = State.SKETCH;\r
+ continue; \r
+ }\r
+\r
+ String control = readElement(reader, line);\r
+ mdl.addControlData(control);\r
+ break;\r
+\r
+\r
+ case SKETCH:\r
+ if (line.startsWith(SKETCH_END)) {\r
+ state = State.OTHER;\r
+ break;\r
+ }\r
+\r
+ if (line.startsWith(SKETCH_START)) {\r
+ mdl.startSketch();\r
+ break;\r
+ }\r
+\r
+ mdl.addSketchData(line);\r
+ break;\r
+\r
+ case OTHER:\r
+ mdl.addOtherData(line);\r
+ break;\r
+\r
+ default: break; // should not get this far\r
+ }\r
+\r
+ line = reader.readLine();\r
+ }\r
+\r
+ reader.close();\r
+ }\r
+ catch (IOException e) {\r
+ e.printStackTrace();\r
+ }\r
+\r
+ return mdl;\r
+ }\r
+\r
+ private static String readElement(BufferedReader reader, String current) \r
+ throws IOException {\r
+ // TODO: does not support subscript stuff at all currently\r
+ StringBuilder element = new StringBuilder();\r
+\r
+ while (current != null) {\r
+ current = current.trim().replace('\t', ' ');\r
+\r
+ if (current.endsWith("|")) {\r
+ element.append(current.substring(0, current.length() - 1));\r
+ break;\r
+ }\r
+ else if (current.endsWith("\\")) {\r
+ element.append(current.substring(0, current.length() - 1));\r
+ }\r
+ else {\r
+ element.append(current);\r
+ }\r
+\r
+ current = reader.readLine();\r
+ }\r
+\r
+ return element.toString();\r
+ }\r
+\r
+ private static void parseElement(String element) {\r
+ String left, right, unit, desc;\r
+\r
+ String[] data = element.split("~");\r
+\r
+ if (data.length != 3) {\r
+ System.err.println("INVALID ELEMENT DATA "+element);\r
+ return;\r
+ }\r
+\r
+ String equation = sanitize(data[0]);\r
+\r
+ left = equation.substring(0, equation.indexOf('=')).trim();\r
+ right = equation.substring(equation.indexOf('=') + 1).trim();\r
+ unit = data[1].trim();\r
+ desc = data[2].trim();\r
+\r
+ //System.err.println("FOUND VARIABLE "+left);\r
+ //System.err.println(" EQUATION "+right);\r
+ //System.err.println(" UNIT "+unit);\r
+ //System.err.println(" DESC "+desc);\r
+\r
+ }\r
+\r
+ // matches a quoted string that may contain escaped special characters \r
+ // (which includes other quotation marks)\r
+ private static final String QUOTED_PATTERN = "\"([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\"";\r
+ // matches (possibly escaped) unsupported characters\r
+ private static final String BADCHARS_PATTERN = "\\\\?[-+*/()=<>\"]";\r
+ // matches a substring that should be capitalized (see below for details)\r
+ private static final String NAMEPART_PATTERN = "([A-Za-z])[A-Za-z]*";\r
+\r
+ private static String sanitize(String str) {\r
+ //TODO: fix this to produce quoted modelica strings instead\r
+ StringBuilder result = new StringBuilder(str);\r
+\r
+ Matcher matcher;\r
+\r
+ matcher = Pattern.compile(QUOTED_PATTERN).matcher(str);\r
+ while (matcher.find()) {\r
+ // TODO: could do something more clever than just an underscore\r
+ String replacement = Pattern.compile(BADCHARS_PATTERN).matcher(matcher.group(1)).replaceAll("_");\r
+ result.replace(matcher.start(), matcher.end(), replacement);\r
+ }\r
+\r
+ // also capitalize all variable names to remove certain openmodelica \r
+ // keywords such as "public" or "private", this might not seem like\r
+ // the most sane variable name handling scheme possible, but it is\r
+ // nevertheless the one we are forced to use \r
+ matcher = Pattern.compile(NAMEPART_PATTERN).matcher(result.toString());\r
+ while (matcher.find()) {\r
+ // replace the first character of the match with the same \r
+ // character in upper case\r
+ result.replace(matcher.start(1), matcher.end(1), matcher.group(1).toUpperCase());\r
+ }\r
+\r
+ return result.toString();\r
+ }\r
+\r
+ private static void parseSketch(ArrayList<String> sketch) {\r
+ // the sketch should have at least three lines, version, name and font\r
+ if (sketch.size() < 3 || \r
+ !sketch.get(0).startsWith("V300") || \r
+ !sketch.get(1).startsWith("*") || \r
+ !sketch.get(2).startsWith("$")) {\r
+ System.err.println("INVALID SKETCH DATA");\r
+ return;\r
+ }\r
+\r
+ // parse name\r
+ String name = sketch.get(1).substring(1);\r
+ // parse font\r
+ String font = sketch.get(2).substring(2);\r
+\r
+ for (int i = 3; i < sketch.size(); i++) {\r
+ String line = sketch.get(i);\r
+ if (line.startsWith(CONNECTION_PREFIX)) {\r
+ parseConnection(line.substring(2));\r
+ }\r
+ else if (line.startsWith(VARIABLE_PREFIX)) {\r
+ parseVariable(line.substring(3));\r
+ }\r
+ else if (line.startsWith(VALVE_PREFIX)) {\r
+ //parseValve(line.substring(3));\r
+ }\r
+ else if (line.startsWith(COMMENT_PREFIX)) {\r
+ //parseComment(line.substring(3));\r
+ }\r
+ else {\r
+ //System.err.println("UNSUPPORTED SKETCH OBJECT "+line);\r
+ }\r
+ }\r
+ }\r
+\r
+ // these methods are implemented according to the documentation on the .mdl\r
+ // file format available in http://www.vensim.com/documentation/24305.htm\r
+\r
+ // (1,)id,from,to,shape,hid,pol,thick,hasf,dtype,res,color,font,np|plist\r
+ private static final String CONNECTION_PREFIX = "1,";\r
+ private static final String CONNECTION_PATTERN = \r
+ "(\\d+),(\\d+),(\\d+).*";\r
+ // (n,)id,name,x,y,w,h,sh,bits,hid,hasf,tpos,bw,nav1,nav2(,box,fill,font)\r
+ private static final String VARIABLE_PREFIX = "10,";\r
+ private static final String VALVE_PREFIX = "11,";\r
+ private static final String COMMENT_PREFIX = "12,";\r
+ private static final String ELEMENT_PATTERN = \r
+ "(\\d+),(\".*\"|[^\",]*),(-?\\d+),(-?\\d+),(\\d+),(\\d+).*";\r
+\r
+ private static void parseConnection(String line) {\r
+ Matcher matcher = Pattern.compile(CONNECTION_PATTERN).matcher(line);\r
+ if (!matcher.matches()) {\r
+ System.err.println("MALFORMED CONNECTION");\r
+ return;\r
+ }\r
+\r
+ // the fields of interest are: id, from, to, ... (TODO)\r
+ int id = Integer.parseInt(matcher.group(1));\r
+ int from = Integer.parseInt(matcher.group(2));\r
+ int to = Integer.parseInt(matcher.group(3));\r
+\r
+ System.err.println("connection "+id+": "+from+" -> "+to);\r
+ }\r
+\r
+ private static void parseVariable(String line) {\r
+ Matcher matcher = Pattern.compile(ELEMENT_PATTERN).matcher(line);\r
+ if (!matcher.matches()) {\r
+ System.err.println("MALFORMED VARIABLE "+line);\r
+ return;\r
+ }\r
\r
- MdlFile mdlFile = getMdlContents(file);\r
- \r
- getVariableData(model, mdlFile.getVariables());\r
- \r
- getSketchData(model, mdlFile.getSketchData());\r
- \r
- getControlData(model, mdlFile.getControls());\r
+ int id = Integer.parseInt(matcher.group(1));\r
+ String name = sanitize(matcher.group(2));\r
+ int x = Integer.parseInt(matcher.group(3));\r
+ int y = Integer.parseInt(matcher.group(4));\r
+ int width = Integer.parseInt(matcher.group(5));\r
+ int height = Integer.parseInt(matcher.group(6));\r
\r
-// getOthertData(model, mdlFile.getOtherData());\r
+ System.err.println("variable "+id+": "+name+" ("+x+","+y+")");\r
+ }\r
+\r
+ private static void parseValve(String line) {\r
\r
- setAllSubscripts(model);\r
+ }\r
+\r
+ private static void parseComment(String line) { \r
\r
- return model;\r
}\r
- \r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
\r
private static MdlFile getMdlContents(File aFile) {\r
MdlFile mdlFile = new MdlFile();\r
- \r
+\r
try {\r
BufferedReader input = new BufferedReader(new FileReader(aFile));\r
- \r
+\r
try {\r
- String line = null; //not declared within while loop\r
+ String line = null; // not declared within while loop\r
\r
+ mdlFile.startSketch();\r
+\r
// See if the document is encoded with UTF-8. It will be marked with {UTF-8} on the first line\r
input.mark(30);\r
- if (( line = input.readLine()) != null &&\r
- line.contains("{UTF-8}")){\r
+ if ((line = input.readLine()) != null && line.contains("{UTF-8}")){\r
Reader in = new InputStreamReader(new FileInputStream(aFile), "UTF-8");\r
input = new BufferedReader(in);\r
line = input.readLine();\r
} else {\r
input.reset();\r
}\r
- \r
- \r
+\r
+\r
boolean isControl = false;\r
- \r
- while (( line = input.readLine()) != null){\r
+\r
+ while ((line = input.readLine()) != null) {\r
// Build an element (combine the lines to one string)\r
StringBuilder elementBuilder = new StringBuilder();\r
- while(line != null && !line.contains("\\\\\\---///")) {\r
+ while (line != null && !line.contains("\\\\\\---///")) {\r
// Add a new line for the element\r
elementBuilder.append(line);\r
if(line.endsWith("|") && !line.endsWith("~~|")) {\r
}\r
line = input.readLine();\r
}\r
- \r
- if(line.contains("\\\\\\---///"))\r
+\r
+ if (line.contains("\\\\\\---///"))\r
break;\r
- \r
+\r
String variable = elementBuilder.toString();\r
\r
- if(variable.trim().matches("[\\*]{46}.+[\\*]{46}.+")) {\r
+ if (variable.trim().matches("[\\*]{46}.+[\\*]{46}.+")) {\r
if(variable.contains(".Control")) {\r
isControl = true;\r
} else {\r
\r
// Add element string to model\r
if(isControl) {\r
- mdlFile.addControl(variable);\r
+ mdlFile.addControlData(variable);\r
} else {\r
- mdlFile.addVariable(variable);\r
+ mdlFile.addVariableData(variable);\r
}\r
}\r
- \r
- while (( line = input.readLine()) != null && !line.contains("///---\\\\\\")){\r
+\r
+ while ((line = input.readLine()) != null && !line.contains("///---\\\\\\")) {\r
mdlFile.addSketchData(line);\r
}\r
- \r
- while (( line = input.readLine()) != null){\r
+\r
+ while ((line = input.readLine()) != null){\r
mdlFile.addOtherData(line);\r
}\r
}\r
catch (IOException ex){\r
ex.printStackTrace();\r
}\r
- \r
+\r
return mdlFile;\r
}\r
- \r
+\r
private static void getVariableData(Model model, ArrayList<String> elements) {\r
ArrayList<EquivalenceSubscript> equivalenceSubscripts = new ArrayList<EquivalenceSubscript>();\r
for(String elementString : elements) {\r
equivalenceSubscripts.add((EquivalenceSubscript) v);\r
}\r
}\r
- \r
+\r
// All variables are ready, determine subscript equivalences\r
for(EquivalenceSubscript es : equivalenceSubscripts) {\r
Element e = model.getElement(es.getEquivalentToName());\r
}\r
}\r
}\r
- \r
- \r
+\r
+\r
private static void getControlData(Model model, ArrayList<String> controls) {\r
for(String controlString : controls) {\r
String[] nameAndData = controlString.split("="); \r
String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]");\r
- \r
+\r
if(nameAndData[0].trim().equals("FINAL TIME")) {\r
model.setEndTime(Double.parseDouble(expressionUnitsAndComments[0]));\r
} else if(nameAndData[0].trim().equals("INITIAL TIME")) {\r
model.setTimeUnit(expressionUnitsAndComments[1]);\r
}\r
}\r
- \r
+\r
}\r
- \r
+\r
private static Variable getVariable(Model model, String name) {\r
Element e = model.getElement(name);\r
Variable variable = null;\r
variable = (Variable)e;\r
return variable;\r
}\r
- \r
+\r
private static String[] getNormalVariableNameDataAndRange(String element) {\r
String[] nameAndData = element.split("=", 2);\r
String[] nameAndRange = nameAndData[0].trim().split("[\\[|\\]]");\r
return new String[] {nameAndRange[0], nameAndData[1], nameAndRange.length == 2 ? nameAndRange[1] : null};\r
return null;\r
}\r
- \r
+\r
private static String[] getSubscriptNameAndData(String element) {\r
String[] nameAndData = element.split(":");\r
if(nameAndData.length == 2)\r
return nameAndData;\r
return null;\r
} \r
- \r
+\r
private static String[] getEquivalenceSubscriptNameAndData(String element) {\r
String[] nameAndData = element.split("\\<\\-\\>");\r
if(nameAndData.length == 2)\r
return nameAndData;\r
return null;\r
}\r
- \r
+\r
private static String[] getTableNameDataAndRange(String element) {\r
String[] parts = element.split("\\~"); \r
if(!parts[0].contains("(") || !parts[0].contains(")"))\r
return new String[] {nameAndRange[0], nameAndData[1], nameAndRange.length == 2 ? nameAndRange[1] : null};\r
return nameAndData;\r
}\r
- \r
+\r
private static String[] getDataVariableNameAndData(String element) {\r
String[] nameAndData = {\r
element.substring(0, element.indexOf("~")),\r
" " + element.substring(element.indexOf("~"))};\r
return nameAndData;\r
}\r
- \r
+\r
private static Variable createVariable(Model model, String elementString) {\r
\r
String[] elementExpressions = elementString.split("\\~\\~\\|");\r
- \r
+\r
Variable variable = null;\r
\r
+ System.err.println("CREATE VARIABLE "+elementString);\r
+\r
for(String s : elementExpressions) {\r
+ System.err.println(" INSIDE FOR");\r
+ \r
// Skip these definitions at least for now\r
if(elementExpressions.length > 1 && s.contains("A FUNCTION OF"))\r
continue;\r
- \r
+\r
Expression expression = new Expression();\r
\r
String[] nameAndData = null;\r
String name;\r
- \r
+\r
// Create the expression based on the expression string\r
if((nameAndData = getNormalVariableNameDataAndRange(s)) != null) {\r
- \r
+\r
name = nameAndData[0].replace("\"", "");\r
variable = getVariable(model, name);\r
if(variable == null) {\r
variable.setName(name);\r
model.addElement(variable);\r
}\r
- \r
+\r
if(!nameAndData[1].trim().endsWith("|")) {\r
// Multiple expressions\r
expression.setExpression(nameAndData[1].trim());\r
String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]");\r
expression.setExpression(expressionUnitsAndComments[0].trim());\r
}\r
- \r
+\r
} else if((nameAndData = getSubscriptNameAndData(s)) != null) {\r
- \r
+\r
name = nameAndData[0].replace("\"", "");\r
variable = getVariable(model, name);\r
if(variable == null) {\r
variable.setName(name);\r
model.addElement(variable);\r
}\r
- \r
+\r
// No support for multidimensional variables. Don't know what that would mean\r
String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]");\r
expression.setExpression(expressionUnitsAndComments[0].trim());\r
variable.setUnits(expressionUnitsAndComments[1].trim());\r
variable.setComments(expressionUnitsAndComments[2].trim());\r
- \r
+\r
} else if((nameAndData = getEquivalenceSubscriptNameAndData(s)) != null) {\r
- \r
+\r
name = nameAndData[0].replace("\"", "");\r
variable = getVariable(model, name);\r
if(variable == null) {\r
variable.setName(name);\r
model.addElement(variable);\r
}\r
- \r
+\r
// No support for multidimensional variables. Don't know what that would mean\r
String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]");\r
expression.setExpression(expressionUnitsAndComments[0].trim());\r
variable.setUnits(expressionUnitsAndComments[1].trim());\r
variable.setComments(expressionUnitsAndComments[2].trim());\r
- \r
+\r
} else if((nameAndData = getTableNameDataAndRange(s)) != null) {\r
- \r
+\r
name =(nameAndData[0].replace("\"", ""));\r
variable = getVariable(model, name);\r
if(variable == null) {\r
variable.setName(name);\r
model.addElement(variable);\r
}\r
- \r
+\r
String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]");\r
// ([(0,0)-(2,5)],(0,5),(0.5,3),(1,0.5),(2,0.5) => ( ; (0,0)-(2,5) ; ,(0,5),(0.5,3),(1,0.5),(2,0.5)\r
String table = expressionUnitsAndComments[0].trim().split("[\\[|\\]]")[2];\r
table = table.replace("(", "{");\r
table = table.replace(")", "}");\r
expression.setExpression(table); \r
- \r
- \r
+\r
+\r
} else if((nameAndData = getDataVariableNameAndData(s)) != null) {\r
- \r
+\r
name = nameAndData[0].replace("\"", "");\r
variable = getVariable(model, name);\r
if(variable == null) {\r
variable.setName(name);\r
model.addElement(variable);\r
}\r
- \r
+\r
expression.setExpression("");\r
} \r
- \r
+\r
if(nameAndData == null || variable == null)\r
continue;\r
- \r
+\r
// Set possible range for the expression\r
if(nameAndData.length == 3)\r
expression.setRange(nameAndData[2]);\r
- \r
+\r
// Set units and comments for the variable \r
if(nameAndData[1].trim().endsWith("|")) {\r
String[] expressionUnitsAndComments = nameAndData[1].split("[\\~|\\|]");\r
units.lastIndexOf("[") + 1, \r
units.length() - 1);\r
String[] rangeParts = range.split(",");\r
- \r
+\r
try {\r
variable.setRangeStart(Double.parseDouble(rangeParts[0]));\r
if(rangeParts.length >= 2)\r
variable.setUnits(expressionUnitsAndComments[1].trim());\r
variable.setComments(expressionUnitsAndComments[2].trim());\r
}\r
- \r
+\r
// Finally add the expression to element\r
variable.getExpressions().add(expression);\r
}\r
return variable;\r
}\r
- \r
+\r
private static int SCALE = 4;\r
- private static void getSketchData(Model model, ArrayList<String> sketchData) {\r
\r
+ private static void getSketchData(Model model, ArrayList<String> sketchData) {\r
String line = null;\r
View view = null;\r
+\r
int i = 0;\r
+\r
while(i < sketchData.size()) {\r
line = sketchData.get(i);\r
if(line.startsWith("*")) {\r
view = new View();\r
model.addView(view);\r
- \r
+\r
view.setName(line.substring(1));\r
\r
// STARTED A NEW VIEW\r
ArrayList<String> ghostNumbers = new ArrayList<String>();\r
ArrayList<String[]> connections = new ArrayList<String[]>();\r
HashMap<String, String[]> emptyValves = new HashMap<String, String[]>(); // map for valves that don't have an element \r
- \r
- \r
+\r
+\r
i++;\r
line = sketchData.get(i);\r
while(i < sketchData.size() && !sketchData.get(i).startsWith("*")) {\r
line = sketchData.get(i);\r
- \r
+\r
if(line.startsWith("$")) {\r
view.setFontParameters(line);\r
i++;\r
continue;\r
}\r
- \r
+\r
String[] data = line.split(",");\r
- if(data[0].equals("1")) {\r
+ if (data[0].equals("1")) {\r
// Connections are handled after all elements\r
String[] connectionData = line.split(",");\r
connections.add(connectionData);\r
- \r
- } else if(data[0].equals("11")){\r
+\r
+ } else if (data[0].equals("11")){\r
// Valve\r
i = i + 1;\r
String elementLine = sketchData.get(i);\r
// FIXME: Assumes that element is always attached to the valve\r
Element element = model.getElement(elementData[2].replace("\"", ""));\r
Valve valve = new Valve();\r
- if(element != null && element instanceof Variable) {\r
+ if (element != null && element instanceof Variable) {\r
Variable v = (Variable) element;\r
valve.setName(v.getName());\r
valve.setExpressions(v.getExpressions());\r
valve.setComments(v.getComments());\r
valve.setX(Integer.parseInt(data[3]) / SCALE);\r
valve.setY(Integer.parseInt(data[4]) / SCALE);\r
- \r
+\r
model.removeElement(element);\r
model.addElement(view, valve);\r
- \r
+\r
// Add valve to the element list with both valve and variable symbol numbers\r
elementNumbers.put(elementData[1], valve);\r
elementNumbers.put(data[1], valve);\r
i = i - 1;\r
emptyValves.put(data[1], data);\r
}\r
- } else if(data[0].equals("12")){\r
+ } else if (data[0].equals("12")){\r
// Cloud\r
Cloud cloud = new Cloud();\r
cloud.setX(Integer.parseInt(data[3]) / SCALE); \r
cloud.setY(Integer.parseInt(data[4]) / SCALE); \r
elementNumbers.put(data[1], cloud);\r
model.addElement(view, cloud);\r
- } else if(data[0].equals("10") && data.length <= 15){\r
+ } else if (data[0].equals("10") && data.length <= 15){\r
// Some variable\r
Element e = model.getElement(data[2].replace("\"", "").trim());\r
- if(e != null && e instanceof Variable) {\r
+\r
+ if (e != null && e instanceof Variable) {\r
Variable v = (Variable) e;\r
- if(v.getExpressions().get(0).getExpression().startsWith("INTEG (") && !(e instanceof Stock)) {\r
+ if (v.getExpressions().get(0).getExpression().startsWith("INTEG (") && !(e instanceof Stock)) {\r
// Stock\r
Stock s = new Stock();\r
s.setName(v.getName());\r
e.setY(Integer.parseInt(data[4]) / SCALE); \r
elementNumbers.put(data[1], e);\r
model.relocateElement(view, e);\r
- } else if(data[0].equals("10") && data.length > 15){\r
+ } else if (data[0].equals("10") && data.length > 15){\r
// TODO: Ghost\r
// for now, direct back to the original element\r
Element originalElement = model.getElement(data[2].replace("\"", ""));\r
ghostNumbers.add(data[1]);\r
}\r
}\r
- \r
+\r
i++;\r
}\r
+\r
i--;\r
- \r
+\r
// Find the first variable that is connected to an empty valve\r
for(String[] connectionData : connections) {\r
if(!connectionData[9].equals("64"))\r
continue; // not dependency\r
String[] end = emptyValves.get(connectionData[3]);\r
- if(end != null && elementNumbers.get(connectionData[3]) == null) {\r
+ if (end != null && elementNumbers.get(connectionData[3]) == null) {\r
// Use the connected element to create a valve and give it a name \r
Element start = elementNumbers.get(connectionData[2]);\r
- if(start == null)\r
+ if (start == null)\r
continue;\r
- \r
+\r
Valve valve = new Valve();\r
valve.setName(start.getName() + " Rate");\r
valve.setX(Integer.parseInt(end[3]) / SCALE); \r
valve.setY(Integer.parseInt(end[4]) / SCALE);\r
- \r
+\r
model.addElement(view, valve);\r
elementNumbers.put(connectionData[3], valve);\r
valve.setUnits("");\r
valve.setComments("");\r
}\r
}\r
- \r
- \r
- \r
+\r
+\r
+\r
for(String[] connectionData : connections) {\r
- \r
+\r
Element start = elementNumbers.get(connectionData[2]);\r
Element end = elementNumbers.get(connectionData[3]);\r
// Discard connection if one of the ends is null\r
if(start == null || end == null)\r
continue;\r
- \r
- \r
+\r
+\r
Connection connection; \r
if(connectionData[9].equals("64")) {\r
// Dependency\r
String controlX = connectionData[13].substring(connectionData[13].indexOf("(") + 1);\r
String controlY = connectionData[14].substring(0, connectionData[14].indexOf(")"));\r
Point2D controlPoint = new Point2D.Double(Double.parseDouble(controlX) / SCALE, Double.parseDouble(controlY) / SCALE);\r
- \r
+\r
if(ghostNumbers.contains(connectionData[2]) ||\r
ghostNumbers.contains(connectionData[3])) {\r
connection = new Dependency();\r
\r
connection = new Dependency(angle);\r
}\r
- \r
+\r
} else {\r
// Flow\r
connection = new Flow();\r
connection.setEnd(end);\r
model.addConnection(connection);\r
}\r
- \r
- \r
+\r
+\r
// Generate expressions for empty valves \r
for(String key : emptyValves.keySet()) {\r
Element e = elementNumbers.get(key);\r
break;\r
}\r
}\r
- \r
+\r
// Create the expression. Use the expression of the stock, and undo the effect of other valves\r
if(stock != null && stock instanceof Stock) {\r
Expression expression = new Expression();\r
- \r
+\r
StringBuilder sb = new StringBuilder();\r
sb.append(((Stock)stock).getIntegralParts(stock.getExpressions().get(0))[0]);\r
- \r
+\r
for(Connection c : stock.getConnections()) {\r
if(c instanceof Flow) {\r
if(c.getStart().equals(stock) && !c.getEnd().equals(valve)) {\r
}\r
}\r
}\r
+\r
i++;\r
}\r
\r
}\r
- \r
+\r
private static void getOthertData(Model model, String otherData) {\r
- \r
+\r
}\r
- \r
+\r
private static void setAllSubscripts(Model model) {\r
- \r
+\r
// Set subscripts for all elements\r
ArrayList<Element> elements = new ArrayList<Element>();\r
elements.addAll(model.getUnlocatedElements());\r
for(View view : model.getViews()) {\r
elements.addAll(view.getElements());\r
}\r
- \r
+\r
for(Element e : elements) { \r
if(!(e instanceof Variable))\r
continue;\r
v.initializeSubscripts(model);\r
}\r
}\r
- \r
+\r
}\r