]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Support both .txt and .xml init file formats
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 1 Sep 2011 09:33:42 +0000 (09:33 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Thu, 1 Sep 2011 09:33:42 +0000 (09:33 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@22020 ac1ea38d-2e2b-0410-8846-a27921b304fc

org.simantics.modelica/src/org/simantics/modelica/InitWriter.java [new file with mode: 0644]
org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java
org.simantics.modelica/src/org/simantics/modelica/data/SimulationResult.java

diff --git a/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java b/org.simantics.modelica/src/org/simantics/modelica/InitWriter.java
new file mode 100644 (file)
index 0000000..6b90a2f
--- /dev/null
@@ -0,0 +1,182 @@
+package org.simantics.modelica;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.PrintStream;\r
+import java.util.HashMap;\r
+\r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.transform.Transformer;\r
+import javax.xml.transform.TransformerConfigurationException;\r
+import javax.xml.transform.TransformerException;\r
+import javax.xml.transform.TransformerFactory;\r
+import javax.xml.transform.TransformerFactoryConfigurationError;\r
+import javax.xml.transform.dom.DOMSource;\r
+import javax.xml.transform.stream.StreamResult;\r
+import javax.xml.xpath.XPath;\r
+import javax.xml.xpath.XPathConstants;\r
+import javax.xml.xpath.XPathExpressionException;\r
+import javax.xml.xpath.XPathFactory;\r
+\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Node;\r
+import org.w3c.dom.NodeList;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+\r
+/**\r
+ * Class to change values of parameters in modelica init.xml files\r
+ * @author tlteemu\r
+ *\r
+ */\r
+public class InitWriter {\r
+\r
+    /**\r
+     * Change the given init parameter values for XML init file\r
+     * @param file path to the init.xml file\r
+     * @param inits name-value map\r
+     * @return\r
+     */\r
+    public static boolean writeXML(String file, HashMap<String, String> inits) {\r
+        Document doc;\r
+        try {\r
+            doc = DocumentBuilderFactory.newInstance()\r
+                    .newDocumentBuilder().parse(new InputSource(file));\r
+\r
+\r
+            // Locate the node(s)\r
+            XPath xpath = XPathFactory.newInstance().newXPath();\r
+\r
+            for(String name : inits.keySet()) {\r
+                NodeList nodes = null;\r
+                try {\r
+                    // First try normal variables\r
+                    nodes = (NodeList)xpath.evaluate\r
+                            ("//fmiModelDescription/ModelVariables/ScalarVariable[@name='" + name + "']/Real/@start",\r
+                                    doc, \r
+                                    XPathConstants.NODESET);\r
+                    if(nodes.getLength() == 0) {\r
+                        // If normal variables were not found, try if it is an experiment attribute\r
+                        nodes = (NodeList)xpath.evaluate\r
+                                ("//fmiModelDescription/DefaultExperiment/@" + name,\r
+                                        doc, \r
+                                        XPathConstants.NODESET);\r
+                    }\r
+                } catch (XPathExpressionException e) {\r
+\r
+                }\r
+                if (nodes != null) {\r
+                    // make the change. There should be only one node.\r
+                    for (int idx = 0; idx < nodes.getLength(); idx++) {\r
+                        Node n = nodes.item(idx);\r
+                        n.setNodeValue(inits.get(name).replaceAll("\"", ""));\r
+                    }\r
+                }\r
+            }\r
+\r
+            // Save the result\r
+            Transformer xformer = TransformerFactory.newInstance().newTransformer();\r
+            xformer.transform\r
+            (new DOMSource(doc), new StreamResult(new File(file)));\r
+\r
+            return true;\r
+        } catch (SAXException e) {\r
+            e.printStackTrace();\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+        } catch (ParserConfigurationException e) {\r
+            e.printStackTrace();\r
+        } catch (TransformerConfigurationException e) {\r
+            e.printStackTrace();\r
+        } catch (TransformerFactoryConfigurationError e) {\r
+            e.printStackTrace();\r
+        } catch (TransformerException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+        return false;\r
+\r
+    }\r
+\r
+    /**\r
+     * Change the given init parameter values for TXT init file\r
+     * @param file path to the init.xml file\r
+     * @param inits name-value map\r
+     * @return\r
+     */\r
+    public static boolean writeTXT(String file, HashMap<String, String> inits) {\r
+        HashMap<String, String> initials = new HashMap<String, String>();\r
+        HashMap<Integer, String> order = new HashMap<Integer, String>();\r
+\r
+        InputStream is;\r
+        try {\r
+            is = new FileInputStream(file);\r
+            int orderNumber = 0;\r
+            while(true) {\r
+                String line = getLine(is);\r
+                if(line == null)\r
+                    return false;\r
+                if(line.isEmpty())\r
+                    break;\r
+                if(line.contains("//")) {\r
+                    String[] nn = line.split("//", 2);\r
+                    String key = nn[1].trim();\r
+                    String value = nn[0].trim();\r
+                    if(inits.containsKey(key)) {\r
+                        value = inits.get(key);\r
+                    }\r
+                    initials.put(key, value);\r
+                    order.put(orderNumber, key);\r
+                }\r
+                orderNumber++;\r
+            }\r
+            is.close();\r
+\r
+            PrintStream s = new PrintStream(file);\r
+            for(int j = 0; j < orderNumber ; j++) {\r
+                String key = order.get(j);\r
+                if (key != null) {\r
+                    s.println(initials.get(key) + " // " + key);\r
+                } else {\r
+                    s.println("0.0");\r
+                }\r
+            }\r
+            s.close();\r
+\r
+            return true;\r
+        } catch (FileNotFoundException e) {\r
+            e.printStackTrace();\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    private static String getLine(InputStream stream) {\r
+        if(stream == null)\r
+            return null;\r
+        StringBuilder b = new StringBuilder();\r
+        try {\r
+            while(true) {\r
+                int c = stream.read();\r
+                if(c == -1) {\r
+                    stream = null;\r
+                    return b.toString();\r
+                }\r
+                else if(c == '\n') \r
+                    return b.toString();\r
+                else if(c == '\r')\r
+                    ;\r
+                else\r
+                    b.append((char)c);\r
+            }\r
+        } catch (IOException e) {\r
+            return null;\r
+        }           \r
+\r
+    }\r
+}
\ No newline at end of file
index ee9e4738f5894f1d34854dbf97e1194e8a0823c3..e9b448e546698c30f8c8d98fc0f5cd9e8ae97ef0 100644 (file)
@@ -14,7 +14,6 @@ package org.simantics.modelica;
 import java.io.BufferedWriter;\r
 import java.io.File;\r
 import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
 import java.io.FileWriter;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
@@ -29,375 +28,349 @@ import org.osgi.framework.Bundle;
 \r
 public class ModelicaManager {\r
 \r
-       public enum OSType {\r
-               APPLE, LINUX, SUN, WINDOWS, UNKNOWN\r
-       }\r
-\r
-       public static OSType calculateOS() {\r
-               String osName = System.getProperty("os.name");\r
-               assert osName != null;\r
-               osName = osName.toLowerCase();\r
-               if (osName.startsWith("mac os x"))\r
-                       return OSType.APPLE;\r
-               if (osName.startsWith("windows"))\r
-                       return OSType.WINDOWS;\r
-               if (osName.startsWith("linux"))\r
-                       return OSType.LINUX;\r
-               if (osName.startsWith("sun"))\r
-                       return OSType.SUN;\r
-               return OSType.UNKNOWN;\r
-       }\r
-       \r
-       public static File getModelicaHome() {\r
-\r
-               String dir = System.getenv("OPENMODELICAHOME");\r
-               File omhome = null;\r
-\r
-               String osName = System.getProperty("os.name");\r
-               OSType os = calculateOS();\r
-\r
-               if (os == OSType.UNKNOWN)\r
-                       throw new UnsatisfiedLinkError("unknown OS '" + osName + "' for running OpenModelica");\r
-               \r
-               // If OPENMODELICAHOME is found, try to return the folder.\r
-               if(dir != null) {\r
-                       switch (os) {\r
-                       case APPLE:\r
-                       case LINUX:\r
-                       case SUN:\r
-                               omhome = new File(dir);\r
-                               if(omhome.isDirectory())\r
-                                       return  omhome;\r
-                               else\r
-                                       break;\r
-                       case WINDOWS:\r
-                               omhome = new File(dir);\r
-                               if(omhome.isDirectory())\r
-                                       return  omhome;\r
-                               else\r
-                                       break;\r
-                       }\r
-               }\r
-\r
-               // OPENMODELICAHOMe was not found or the folder does not exist. Try built-in OpenModelica for windows\r
-               if(os.equals(OSType.WINDOWS)) {\r
-\r
-                       Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32");\r
-                       if (bundle != null) {\r
-                               try{\r
-                                       URL entry = bundle.getEntry("/");\r
-                                       if(entry != null) {\r
-                                               URL fileURL = FileLocator.toFileURL(entry);\r
-                                               File root = new File( URLDecoder.decode(fileURL.getPath(), "UTF-8") );\r
-                                               File f = new File(root, "OpenModelica1.7.0");\r
-                                               return f;\r
-                                       }\r
-                               }\r
-                               catch (Exception e) {\r
-                                       e.printStackTrace();\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // OS was not windows or built-in OpenModelica did not work\r
-               switch (os) {\r
-               case APPLE:\r
-               case LINUX:\r
-               case SUN:\r
-                       return new File("/usr/bin/omc");\r
-               case WINDOWS:\r
-                       return new File("c:/OpenModelica1.7.0");\r
-               default:\r
-                       throw new UnsatisfiedLinkError("Unsupported operating system: " + os);\r
-               }\r
-       }\r
-\r
-       public static File getModelicaExecutable(File simulationDir) {\r
-\r
-               File modelicaHome = getModelicaHome();\r
-               \r
-               if(!modelicaHome.isDirectory())\r
-                       throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath());\r
-               \r
-               try {\r
-                       File omBat = new File(simulationDir, "om.bat");\r
-                       FileWriter fw = new FileWriter(omBat);\r
-                       BufferedWriter out = new BufferedWriter(fw);\r
-                       out.write("@echo off");\r
-                       out.newLine();\r
-                       out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath());\r
-                       out.newLine();\r
-                       out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31");\r
-                       out.newLine();\r
-                       out.write("%OPENMODELICAHOME%\\bin\\omc.exe %*");\r
-                       out.newLine();\r
-                       out.close();\r
-                       fw.close();\r
-                       \r
-                       return omBat;\r
-               } catch (IOException e) {\r
-                       e.printStackTrace();\r
-                       throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath());\r
-               }\r
-       }\r
-       \r
-       public static File getSimulationExecutableBat(File exeFile) {\r
-               \r
-               File modelicaHome = getModelicaHome();\r
-               \r
-               File folder = new File(exeFile.getParent());\r
-\r
-               try {\r
-                       File exeBat = new File(folder, exeFile.getName() + ".bat");\r
-                       FileWriter fw = new FileWriter(exeBat);\r
-                       BufferedWriter out = new BufferedWriter(fw);\r
-                       \r
-                       out.write("@echo off");\r
-                       out.newLine();\r
-                       out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath());\r
-                       out.newLine();\r
-                       out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31");\r
-                       out.newLine();\r
-                       out.write("set OMPATH=%OPENMODELICAHOME%\\bin");\r
-                       out.newLine();\r
-                       out.write("echo %PATH%|findstr /i %OMPATH% >nul:");\r
-                       out.newLine();\r
-                       out.write("if %errorlevel%==1 set PATH=%PATH%;%OMPATH%");\r
-                       out.newLine();\r
-                       out.write(exeFile.getAbsolutePath() + " %*");\r
-                       out.newLine();\r
-                       \r
-                       out.close();\r
-                       fw.close();\r
-                       return exeBat;\r
-               }\r
-               catch (IOException e) {\r
-                       e.printStackTrace();\r
-                       throw new UnsatisfiedLinkError("Creating bat for the exe failed");\r
-               }\r
-       }\r
-\r
-       protected static File createTempDirectory() throws IOException {\r
-               final File temp = File.createTempFile("temp", Long.toString(System.nanoTime()));\r
-               if(!(temp.delete()))\r
-                       throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());\r
-               if(!(temp.mkdir()))\r
-                       throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());\r
-               return (temp);\r
-       }\r
-\r
-       protected static boolean recursiveDelete(File fileOrDir) {\r
-               if(fileOrDir.isDirectory())\r
-                       for(File innerFile: fileOrDir.listFiles())\r
-                               if(!recursiveDelete(innerFile))\r
-                                       return false;\r
-               return fileOrDir.delete();\r
-       }\r
-\r
-       protected static String readFile(File file) throws IOException {\r
-               InputStream stream = new FileInputStream(file);\r
-               byte[] buffer = new byte[(int)file.length()];\r
-               stream.read(buffer);\r
-               stream.close();\r
-               return new String(buffer);\r
-       }\r
-\r
-       public static void printProcessOutput(final Process process, final IModelicaMonitor monitor) {\r
-               Thread thread = new Thread() {\r
-                       @Override\r
-                       public void run() {\r
-                               InputStream stream = process.getInputStream();\r
-                               StringBuilder b = new StringBuilder();\r
-                               while(true) {\r
-                                       try {\r
-                                               int c;\r
-\r
-                                               c = stream.read();\r
-\r
-                                               if(c <= 0)\r
-                                                       break;\r
-                                               if((char)c != '\n')\r
-                                                       b.append((char)c);\r
-                                               else {\r
-                                                       System.out.println("OMC output: " + b.toString());\r
-                                                       String message = b.toString();\r
-                                                       message = message.trim();\r
-                                                       if(message.startsWith("\""))\r
-                                                               message = message.substring(1);\r
-                                                       monitor.message(message);\r
-                                                       b.delete(0, b.length());\r
-                                               }\r
-                                       } catch (IOException e) {\r
-                                               System.err.println("Not able to read simulation output");\r
-                                               e.printStackTrace();\r
-                                       }\r
-                               }\r
-                       } \r
-               };\r
-               thread.run();\r
-\r
-       }\r
-\r
-       public static SimulationLocation createInputFiles(File simulationDir, String modelName, String modelText, HashMap<String, String> inits, String additionalScript) throws IOException {\r
-               System.out.println(simulationDir.getAbsolutePath());\r
-               modelName = modelName.replace(" ", "");\r
-               File modelFile = new File(simulationDir, modelName + ".mo");\r
-               File scriptFile = new File(simulationDir, modelName + ".mos");\r
-               String outputFormat = inits.containsKey("outputFormat") ? inits.get("outputFormat") : "\"plt\"";\r
-               {\r
-                       PrintStream s = new PrintStream(modelFile);\r
-                       s.print(modelText);\r
-                       s.close();\r
-               }\r
-\r
-               {\r
-                       PrintStream s = new PrintStream(scriptFile);\r
-                       if(additionalScript != null)\r
-                               s.println(additionalScript);\r
-                       s.println("loadFile(\"" + modelName + ".mo\");");\r
-                       s.print("buildModel("+modelName+\r
-                                       ",startTime="+inits.get("start value")+\r
-                                       ",stopTime="+inits.get("stop value")+\r
-                                       ",method="+inits.get("method")+\r
-                                       ",outputFormat="+ outputFormat\r
-                       );\r
-                       if(inits.containsKey("tolerance")) {\r
-                               s.print(",tolerance="+inits.get("tolerance"));\r
-                       }\r
-                       s.print(");\n");\r
-                       s.println("getErrorString();");\r
-                       s.close();\r
-               }\r
-\r
-               OSType os = calculateOS();\r
-               String suffix = OSType.WINDOWS.equals(os) ? ".exe" : "";\r
-\r
-               return new SimulationLocation(\r
-                               simulationDir,\r
-                               new File(simulationDir, modelName + ".mos"),\r
-                               new File(simulationDir, modelName + "_res." + outputFormat.substring(1, outputFormat.length()-1)),\r
-                               new File(simulationDir, modelName + "_init.txt"),\r
-                               new File(simulationDir, modelName + suffix)\r
-               );\r
-       }\r
-\r
-       public static void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) throws ModelicaException {\r
-               try {\r
-                       File omc = getModelicaExecutable(simulationLocation.simulationDir);\r
-                       \r
-                       if(omc == null) {\r
-                               monitor.message("OpenModelica not found! Install it from www.openmodelica.org");\r
-                               throw new ModelicaException("OpenModelica not found");  \r
-                       }\r
-\r
-                       Process process = new ProcessBuilder(\r
-                                       omc.getAbsolutePath(),\r
-                                       simulationLocation.inputFile.getAbsolutePath()\r
-                       )\r
-                       .directory(simulationLocation.simulationDir.getAbsoluteFile())\r
-                       .redirectErrorStream(true)\r
-                       .start();\r
-                       printProcessOutput(process, monitor);\r
-\r
-                       if(!simulationLocation.exeFile.isFile())\r
-                               throw new ModelicaException(".exe file not created\nSee log at " + simulationLocation.simulationDir.getAbsolutePath());            \r
-\r
-               } catch(IOException e) {\r
-                       e.printStackTrace();\r
-               }\r
-\r
-       }\r
-\r
-       public static Process runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, HashMap<String, String> inits) throws IOException {\r
-\r
-               try {\r
-\r
-                       writeInits(simulationLocation, inits);\r
-\r
-                       Process process = new ProcessBuilder(\r
-                                       getSimulationExecutableBat(simulationLocation.exeFile).getAbsolutePath()\r
-                       )\r
-                       .directory(simulationLocation.simulationDir.getAbsoluteFile())\r
-                       .redirectErrorStream(true)\r
-                       .start();\r
-\r
-                       return process;\r
-               } catch(IOException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               return null;\r
-       }\r
-\r
-       private static void writeInits(SimulationLocation simulationLocation, HashMap<String, String> inits) {\r
-\r
-               HashMap<String, String> initials = new HashMap<String, String>();\r
-               HashMap<Integer, String> order = new HashMap<Integer, String>();\r
-\r
-               InputStream is;\r
-               try {\r
-                       is = new FileInputStream(simulationLocation.initFile);\r
-                       int orderNumber = 0;\r
-                       while(true) {\r
-                               String line = getLine(is);\r
-                               if(line == null)\r
-                                       return;\r
-                               if(line.isEmpty())\r
-                                       break;\r
-                               if(line.contains("//")) {\r
-                                       String[] nn = line.split("//", 2);\r
-                                       String key = nn[1].trim();\r
-                                       String value = nn[0].trim();\r
-                                       if(inits.containsKey(key)) {\r
-                                               value = inits.get(key);\r
-                                       }\r
-                                       initials.put(key, value);\r
-                                       order.put(orderNumber, key);\r
-                               }\r
-                               orderNumber++;\r
-                       }\r
-                       is.close();\r
-\r
-                       PrintStream s = new PrintStream(simulationLocation.initFile);\r
-                       for(int j = 0; j < orderNumber ; j++) {\r
-                               String key = order.get(j);\r
-                               if (key != null) {\r
-                                       s.println(initials.get(key) + " // " + key);\r
-                               } else {\r
-                                       s.println("0.0");\r
-                               }\r
-                       }\r
-                       s.close();\r
-\r
-               } catch (FileNotFoundException e) {\r
-                       e.printStackTrace();\r
-               } catch (IOException e) {\r
-                       e.printStackTrace();\r
-               }\r
-       }\r
-\r
-\r
-       private static String getLine(InputStream stream) {\r
-               if(stream == null)\r
-                       return null;\r
-               StringBuilder b = new StringBuilder();\r
-               try {\r
-                       while(true) {\r
-                               int c = stream.read();\r
-                               if(c == -1) {\r
-                                       stream = null;\r
-                                       return b.toString();\r
-                               }\r
-                               else if(c == '\n') \r
-                                       return b.toString();\r
-                               else if(c == '\r')\r
-                                       ;\r
-                               else\r
-                                       b.append((char)c);\r
-                       }\r
-               } catch (IOException e) {\r
-                       return null;\r
-               }           \r
-\r
-       }\r
-\r
+    public enum OSType {\r
+        APPLE, LINUX, SUN, WINDOWS, UNKNOWN\r
+    }\r
+\r
+    public static OSType calculateOS() {\r
+        String osName = System.getProperty("os.name");\r
+        assert osName != null;\r
+        osName = osName.toLowerCase();\r
+        if (osName.startsWith("mac os x"))\r
+            return OSType.APPLE;\r
+        if (osName.startsWith("windows"))\r
+            return OSType.WINDOWS;\r
+        if (osName.startsWith("linux"))\r
+            return OSType.LINUX;\r
+        if (osName.startsWith("sun"))\r
+            return OSType.SUN;\r
+        return OSType.UNKNOWN;\r
+    }\r
+\r
+    public static File getModelicaHome() {\r
+\r
+        String dir = System.getenv("OPENMODELICAHOME");\r
+        File omhome = null;\r
+\r
+        String osName = System.getProperty("os.name");\r
+        OSType os = calculateOS();\r
+\r
+        if (os == OSType.UNKNOWN)\r
+            throw new UnsatisfiedLinkError("unknown OS '" + osName + "' for running OpenModelica");\r
+\r
+        // If OPENMODELICAHOME is found, try to return the folder.\r
+        if(dir != null) {\r
+            switch (os) {\r
+                case APPLE:\r
+                case LINUX:\r
+                case SUN:\r
+                    omhome = new File(dir);\r
+                    if(omhome.isDirectory())\r
+                        return  omhome;\r
+                    else\r
+                        break;\r
+                case WINDOWS:\r
+                    omhome = new File(dir);\r
+                    if(omhome.isDirectory())\r
+                        return  omhome;\r
+                    else\r
+                        break;\r
+            }\r
+        }\r
+\r
+        // OPENMODELICAHOMe was not found or the folder does not exist. Try built-in OpenModelica for windows\r
+        if(os.equals(OSType.WINDOWS)) {\r
+\r
+            Bundle bundle = Platform.getBundle("org.simantics.openmodelica.win32");\r
+            if (bundle != null) {\r
+                try{\r
+                    URL entry = bundle.getEntry("/");\r
+                    if(entry != null) {\r
+                        URL fileURL = FileLocator.toFileURL(entry);\r
+                        File root = new File( URLDecoder.decode(fileURL.getPath(), "UTF-8") );\r
+                        File f = new File(root, "OpenModelica1.7.0");\r
+                        return f;\r
+                    }\r
+                }\r
+                catch (Exception e) {\r
+                    e.printStackTrace();\r
+                }\r
+            }\r
+        }\r
+\r
+        // OS was not windows or built-in OpenModelica did not work\r
+        switch (os) {\r
+            case APPLE:\r
+            case LINUX:\r
+            case SUN:\r
+                return new File("/usr/bin/omc");\r
+            case WINDOWS:\r
+                return new File("c:/OpenModelica1.7.0");\r
+            default:\r
+                throw new UnsatisfiedLinkError("Unsupported operating system: " + os);\r
+        }\r
+    }\r
+\r
+    public static File getModelicaExecutable(File simulationDir) {\r
+\r
+        File modelicaHome = getModelicaHome();\r
+\r
+        if(!modelicaHome.isDirectory())\r
+            throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath());\r
+\r
+        try {\r
+            File omBat = new File(simulationDir, "om.bat");\r
+            FileWriter fw = new FileWriter(omBat);\r
+            BufferedWriter out = new BufferedWriter(fw);\r
+            out.write("@echo off");\r
+            out.newLine();\r
+            out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath());\r
+            out.newLine();\r
+            out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31");\r
+            out.newLine();\r
+            out.write("%OPENMODELICAHOME%\\bin\\omc.exe %*");\r
+            out.newLine();\r
+            out.close();\r
+            fw.close();\r
+\r
+            return omBat;\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+            throw new UnsatisfiedLinkError("OpenModelica probably not installed. Tried to find it from: " + modelicaHome.getAbsolutePath());\r
+        }\r
+    }\r
+\r
+    public static File getSimulationExecutableBat(File exeFile) {\r
+\r
+        File modelicaHome = getModelicaHome();\r
+\r
+        File folder = new File(exeFile.getParent());\r
+\r
+        try {\r
+            File exeBat = new File(folder, exeFile.getName() + ".bat");\r
+            FileWriter fw = new FileWriter(exeBat);\r
+            BufferedWriter out = new BufferedWriter(fw);\r
+\r
+            out.write("@echo off");\r
+            out.newLine();\r
+            out.write("set OPENMODELICAHOME=" + modelicaHome.getAbsolutePath());\r
+            out.newLine();\r
+            out.write("set OPENMODELICALIBRARY=%OPENMODELICAHOME%\\lib\\omlibrary\\msl31");\r
+            out.newLine();\r
+            out.write("set OMPATH=%OPENMODELICAHOME%\\bin");\r
+            out.newLine();\r
+            out.write("echo %PATH%|findstr /i %OMPATH% >nul:");\r
+            out.newLine();\r
+            out.write("if %errorlevel%==1 set PATH=%PATH%;%OMPATH%");\r
+            out.newLine();\r
+            out.write(exeFile.getAbsolutePath() + " %*");\r
+            out.newLine();\r
+\r
+            out.close();\r
+            fw.close();\r
+            return exeBat;\r
+        }\r
+        catch (IOException e) {\r
+            e.printStackTrace();\r
+            throw new UnsatisfiedLinkError("Creating bat for the exe failed");\r
+        }\r
+    }\r
+\r
+    protected static File createTempDirectory() throws IOException {\r
+        final File temp = File.createTempFile("temp", Long.toString(System.nanoTime()));\r
+        if(!(temp.delete()))\r
+            throw new IOException("Could not delete temp file: " + temp.getAbsolutePath());\r
+        if(!(temp.mkdir()))\r
+            throw new IOException("Could not create temp directory: " + temp.getAbsolutePath());\r
+        return (temp);\r
+    }\r
+\r
+    protected static boolean recursiveDelete(File fileOrDir) {\r
+        if(fileOrDir.isDirectory())\r
+            for(File innerFile: fileOrDir.listFiles())\r
+                if(!recursiveDelete(innerFile))\r
+                    return false;\r
+                    return fileOrDir.delete();\r
+    }\r
+\r
+    protected static String readFile(File file) throws IOException {\r
+        InputStream stream = new FileInputStream(file);\r
+        byte[] buffer = new byte[(int)file.length()];\r
+        stream.read(buffer);\r
+        stream.close();\r
+        return new String(buffer);\r
+    }\r
+\r
+    public static void printProcessOutput(final Process process, final IModelicaMonitor monitor) {\r
+        Thread thread = new Thread() {\r
+            @Override\r
+            public void run() {\r
+                InputStream stream = process.getInputStream();\r
+                StringBuilder b = new StringBuilder();\r
+                while(true) {\r
+                    try {\r
+                        int c;\r
+\r
+                        c = stream.read();\r
+\r
+                        if(c <= 0)\r
+                            break;\r
+                        if((char)c != '\n')\r
+                            b.append((char)c);\r
+                        else {\r
+                            System.out.println("OMC output: " + b.toString());\r
+                            String message = b.toString();\r
+                            message = message.trim();\r
+                            if(message.startsWith("\""))\r
+                                message = message.substring(1);\r
+                            monitor.message(message);\r
+                            b.delete(0, b.length());\r
+                        }\r
+                    } catch (IOException e) {\r
+                        System.err.println("Not able to read simulation output");\r
+                        e.printStackTrace();\r
+                    }\r
+                }\r
+            } \r
+        };\r
+        thread.run();\r
+\r
+    }\r
+\r
+    public static SimulationLocation createInputFiles(File simulationDir, String modelName, String modelText, HashMap<String, String> inits, String additionalScript) throws IOException {\r
+        System.out.println(simulationDir.getAbsolutePath());\r
+        modelName = modelName.replace(" ", "");\r
+        File modelFile = new File(simulationDir, modelName + ".mo");\r
+        File scriptFile = new File(simulationDir, modelName + ".mos");\r
+        String outputFormat = inits.containsKey("outputFormat") ? inits.get("outputFormat") : "\"plt\"";\r
+        {\r
+            PrintStream s = new PrintStream(modelFile);\r
+            s.print(modelText);\r
+            s.close();\r
+        }\r
+\r
+        {\r
+            PrintStream s = new PrintStream(scriptFile);\r
+            if(additionalScript != null)\r
+                s.println(additionalScript);\r
+            s.println("loadFile(\"" + modelName + ".mo\");");\r
+            s.print("buildModel("+modelName+\r
+                    ",startTime="+inits.get("start value")+\r
+                    ",stopTime="+inits.get("stop value")+\r
+                    ",method="+inits.get("method")+\r
+                    ",outputFormat="+ outputFormat\r
+                    );\r
+            if(inits.containsKey("tolerance")) {\r
+                s.print(",tolerance="+inits.get("tolerance"));\r
+            }\r
+            s.print(");\n");\r
+            s.println("getErrorString();");\r
+            s.close();\r
+        }\r
+\r
+        OSType os = calculateOS();\r
+        String suffix = OSType.WINDOWS.equals(os) ? ".exe" : "";\r
+\r
+        return new SimulationLocation(\r
+                simulationDir,\r
+                new File(simulationDir, modelName + ".mos"),\r
+                new File(simulationDir, modelName + "_res." + outputFormat.substring(1, outputFormat.length()-1)),\r
+                new File(simulationDir, modelName + "_init.txt"),\r
+                new File(simulationDir, modelName + suffix)\r
+                );\r
+    }\r
+\r
+    public static void buildModel(SimulationLocation simulationLocation, IModelicaMonitor monitor) throws ModelicaException {\r
+        try {\r
+            File omc = getModelicaExecutable(simulationLocation.simulationDir);\r
+\r
+            if(omc == null) {\r
+                monitor.message("OpenModelica not found! Install it from www.openmodelica.org");\r
+                throw new ModelicaException("OpenModelica not found");  \r
+            }\r
+\r
+            Process process = new ProcessBuilder(\r
+                    omc.getAbsolutePath(),\r
+                    simulationLocation.inputFile.getAbsolutePath()\r
+                    )\r
+            .directory(simulationLocation.simulationDir.getAbsoluteFile())\r
+            .redirectErrorStream(true)\r
+            .start();\r
+            printProcessOutput(process, monitor);\r
+\r
+            if(!simulationLocation.exeFile.isFile())\r
+                throw new ModelicaException(".exe file not created\nSee log at " + simulationLocation.simulationDir.getAbsolutePath());            \r
+\r
+        } catch(IOException e) {\r
+            e.printStackTrace();\r
+        }\r
+\r
+    }\r
+\r
+    public static Process runModelica(SimulationLocation simulationLocation, IModelicaMonitor monitor, HashMap<String, String> inits) throws IOException {\r
+\r
+        try {\r
+\r
+            writeInits(simulationLocation, inits);\r
+\r
+            Process process = new ProcessBuilder(\r
+                    getSimulationExecutableBat(simulationLocation.exeFile).getAbsolutePath()\r
+                    )\r
+            .directory(simulationLocation.simulationDir.getAbsoluteFile())\r
+            .redirectErrorStream(true)\r
+            .start();\r
+\r
+            return process;\r
+        } catch(IOException e) {\r
+            e.printStackTrace();\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private static void writeInits(SimulationLocation simulationLocation, HashMap<String, String> inits) {\r
+        /* How the correct input file format should be investigated:\r
+        try {\r
+\r
+            List<String> command = new ArrayList<String>();\r
+            command.add(getModelicaHome().getAbsolutePath() + "\\bin\\omc.exe");\r
+            command.add("+version");\r
+\r
+            ProcessBuilder builder = new ProcessBuilder(command);\r
+            Map<String, String> environ = builder.environment();\r
+            environ.put("OPENMODELICAHOME", getModelicaHome().getAbsolutePath());\r
+\r
+            builder.directory(new File(System.getenv("temp")));\r
+\r
+            Process process;\r
+            process = builder.start();\r
+\r
+            InputStream is = process.getInputStream();\r
+            InputStreamReader isr = new InputStreamReader(is);\r
+            BufferedReader br = new BufferedReader(isr);\r
+            String line;\r
+            while ((line = br.readLine()) != null) {\r
+                System.out.println("OpenModelica Version: " + line);\r
+            }\r
+\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+        }\r
+        */\r
+\r
+        // OpenModelica version number has stayed the same after changing the \r
+        // init format to nightly builds.\r
+        if(simulationLocation.initFile.getAbsolutePath().endsWith(".txt")) {\r
+            File xmlTest = new File(simulationLocation.initFile.getAbsolutePath().replace(".txt", ".xml"));\r
+            if(xmlTest.exists()) {\r
+                simulationLocation.initFile = xmlTest;\r
+            }\r
+        }\r
+        \r
+        if(simulationLocation.initFile.getAbsolutePath().endsWith(".txt")) {\r
+            InitWriter.writeTXT(simulationLocation.initFile.getAbsolutePath(), inits);\r
+        } else {\r
+            InitWriter.writeXML(simulationLocation.initFile.getAbsolutePath(), inits);\r
+\r
+        }\r
+    }\r
 }\r
index 2e104443932087c541d0624b633376aba5e7cdab..a7068a38548511e63ab543c8f205fb7fafcacb88 100644 (file)
@@ -22,6 +22,20 @@ import java.util.List;
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
 \r
+import javax.xml.parsers.DocumentBuilderFactory;\r
+import javax.xml.parsers.ParserConfigurationException;\r
+import javax.xml.transform.TransformerFactoryConfigurationError;\r
+import javax.xml.xpath.XPath;\r
+import javax.xml.xpath.XPathConstants;\r
+import javax.xml.xpath.XPathExpressionException;\r
+import javax.xml.xpath.XPathFactory;\r
+\r
+import org.w3c.dom.Document;\r
+import org.w3c.dom.Node;\r
+import org.w3c.dom.NodeList;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+\r
 /**\r
  * Class that reads OpenModelica result files.\r
  * @author Hannu Niemistö\r
@@ -30,18 +44,18 @@ public class SimulationResult {
 \r
     List<DataSet> variables = new ArrayList<DataSet>();\r
     List<DataSet> initials = new ArrayList<DataSet>();\r
-    \r
-       class TimeValuePair {\r
-               public String time;\r
-               public String value;\r
-               \r
-               public TimeValuePair(String time, String value) {\r
-                       this.time = time;\r
-                       this.value = value;\r
-               }\r
-       }\r
-       \r
-       HashMap<String, ArrayList<TimeValuePair>> errors = new HashMap<String, ArrayList<TimeValuePair>>();\r
+\r
+    class TimeValuePair {\r
+        public String time;\r
+        public String value;\r
+\r
+        public TimeValuePair(String time, String value) {\r
+            this.time = time;\r
+            this.value = value;\r
+        }\r
+    }\r
+\r
+    HashMap<String, ArrayList<TimeValuePair>> errors = new HashMap<String, ArrayList<TimeValuePair>>();\r
 \r
     static String getLine(InputStream stream) {\r
         if(stream == null)\r
@@ -69,12 +83,81 @@ public class SimulationResult {
 \r
 \r
     public void readInits(File file) throws FileNotFoundException, IOException {\r
-        InputStream is = new FileInputStream(file);\r
-        readInits(is);\r
-        is.close();\r
+\r
+        if(file.getName().endsWith("txt")) {\r
+            InputStream is = new FileInputStream(file);\r
+            readInitsTXT(is);\r
+            is.close();\r
+        } else if(file.getName().endsWith("xml")) {\r
+            readInitsXML(file.getAbsolutePath());\r
+        }\r
     }\r
 \r
-    public void readInits(InputStream stream) {\r
+    public void readInitsXML(String file) {\r
+        Document doc;\r
+        try {\r
+            doc = DocumentBuilderFactory.newInstance()\r
+                    .newDocumentBuilder().parse(new InputSource(file));\r
+\r
+            XPath xpath = XPathFactory.newInstance().newXPath();\r
+\r
+            List<Double> times = new ArrayList<Double>(2);\r
+            Node node;\r
+            // Find start time\r
+            node = (Node)xpath.evaluate\r
+                    ("//fmiModelDescription/DefaultExperiment/@startTime",\r
+                            doc, \r
+                            XPathConstants.NODE);\r
+            times.add(Double.parseDouble(node.getNodeValue()));\r
+            // Find end time\r
+            node = (Node)xpath.evaluate\r
+                    ("//fmiModelDescription/DefaultExperiment/@stopTime",\r
+                            doc, \r
+                            XPathConstants.NODE);\r
+            times.add(Double.parseDouble(node.getNodeValue()));\r
+            \r
+            NodeList nodes;\r
+            // Find parameters and constants\r
+            nodes = (NodeList)xpath.evaluate\r
+                    ("//fmiModelDescription/ModelVariables/ScalarVariable[@variability='parameter']",\r
+                            doc, \r
+                            XPathConstants.NODESET);\r
+\r
+            // make the change. There should be only one node.\r
+            List<Double> values;\r
+            NodeList children;\r
+            for (int idx = 0; idx < nodes.getLength(); idx++) {\r
+                Node n = nodes.item(idx);\r
+                children = n.getChildNodes();\r
+                for(int i = 0; i < children.getLength(); i++) {\r
+                    Node child = children.item(i);\r
+                    if(child.getNodeName().equals("Real")) {\r
+                        Double d = Double.parseDouble(child.getAttributes().getNamedItem("start").getNodeValue());\r
+                        values = new ArrayList<Double>(2);\r
+                        values.add(d);\r
+                        values.add(d);\r
+                        initials.add(\r
+                                new DataSet(n.getAttributes().getNamedItem("name").getNodeValue(), \r
+                                        times , \r
+                                        values));\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+        } catch (SAXException e) {\r
+            e.printStackTrace();\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+        } catch (ParserConfigurationException e) {\r
+            e.printStackTrace();\r
+        } catch (TransformerFactoryConfigurationError e) {\r
+            e.printStackTrace();\r
+        } catch (XPathExpressionException e) {\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    public void readInitsTXT(InputStream stream) {\r
         HashMap<String, Double> mappedInitials = new HashMap<String, Double>();\r
         while(true) {\r
             String line = getLine(stream);\r
@@ -92,17 +175,17 @@ public class SimulationResult {
                 } catch (NumberFormatException nfe) {\r
                     continue; // Not a valid double\r
                 }\r
-                \r
+\r
             }\r
 \r
         }\r
-        \r
+\r
         double startTime = mappedInitials.get("start value");\r
         double stopTime = mappedInitials.get("stop value");\r
         List<Double> times = new ArrayList<Double>(2);\r
         times.add(startTime);\r
         times.add(stopTime);\r
-        \r
+\r
         for(String key : mappedInitials.keySet()) {\r
             List<Double> values = new ArrayList<Double>(2);\r
             values.add(mappedInitials.get(key));\r
@@ -169,7 +252,7 @@ public class SimulationResult {
     public List<DataSet> getInitialValueDataSets() {\r
         return initials;\r
     }\r
-    \r
+\r
     /**\r
      * Gets DataSet for variable. Loops first the variables and then initials.  \r
      * @param name the name of the variable\r
@@ -179,28 +262,28 @@ public class SimulationResult {
         for(DataSet set : variables)\r
             if(set.name.equals(name))\r
                 return set;\r
-        for(DataSet set : initials)\r
-            if(set.name.equals(name))\r
-                return set;\r
-        return null;\r
+                for(DataSet set : initials)\r
+                    if(set.name.equals(name))\r
+                        return set;\r
+                        return null;\r
     }\r
-    \r
-    \r
+\r
+\r
     /**\r
      * Return errors encountered during reading of the results.\r
      * \r
      * @return\r
      */\r
     public String getResultReadErrors() {\r
-       StringBuilder errorString = new StringBuilder();\r
+        StringBuilder errorString = new StringBuilder();\r
         if(!errors.isEmpty()) {\r
-               errorString.append("Number format errors (Time, Value):\n");\r
-               for(String key : errors.keySet()) {\r
-                       errorString.append("\n" + key + ":\n");\r
-                       for(TimeValuePair tv : errors.get(key)) {\r
-                               errorString.append("    " + tv.time + ", " + tv.value + "\n");\r
-                       }\r
-               }\r
+            errorString.append("Number format errors (Time, Value):\n");\r
+            for(String key : errors.keySet()) {\r
+                errorString.append("\n" + key + ":\n");\r
+                for(TimeValuePair tv : errors.get(key)) {\r
+                    errorString.append("    " + tv.time + ", " + tv.value + "\n");\r
+                }\r
+            }\r
         }\r
         return errorString.toString();\r
     }\r