]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.gnuplot/src/org/simantics/gnuplot/Gnuplot.java
Added missing plug-ins from old SVN repository trunk
[simantics/platform.git] / bundles / org.simantics.gnuplot / src / org / simantics / gnuplot / Gnuplot.java
diff --git a/bundles/org.simantics.gnuplot/src/org/simantics/gnuplot/Gnuplot.java b/bundles/org.simantics.gnuplot/src/org/simantics/gnuplot/Gnuplot.java
new file mode 100644 (file)
index 0000000..f132179
--- /dev/null
@@ -0,0 +1,167 @@
+package org.simantics.gnuplot;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * @author Tuukka Lehtonen
+ * @since 1.24
+ */
+public class Gnuplot {
+
+    private static final String GNUPLOT_VERSION_STRING_STARTS_WITH = "gnuplot ";
+    private static final String GNUPLOT_ENV = "GNUPLOT";
+    private static final String PATH_ENV = "PATH";
+
+    private Path executable;
+
+    public Gnuplot(Path executable) {
+        this.executable = executable;
+    }
+
+    public static Gnuplot detect() throws IOException {
+        try {
+            return new Gnuplot(findGnuplotPath());
+        } catch (InterruptedException e) {
+            throw new IOException(e);
+        }
+    }
+
+    private static String readInput(InputStream in) throws IOException {
+        StringWriter sw = new StringWriter();
+        for (int l = 0; l < GNUPLOT_VERSION_STRING_STARTS_WITH.length(); ++l) {
+            int c;
+            c = in.read();
+            if(c <= 0)
+                break;
+            sw.write(c);
+        }
+        return sw.toString();
+    }
+
+    private static boolean testExecutable(Path exe) throws IOException, InterruptedException {
+        Process process = new ProcessBuilder(exe.toString(), "-V").start();
+        try {
+            if (GNUPLOT_VERSION_STRING_STARTS_WITH.startsWith( readInput(process.getInputStream()) ))
+                return true;
+            return false;
+        } finally {
+            process.getInputStream().close();
+            process.getErrorStream().close();
+            process.waitFor();
+        }
+    }
+
+    private static Path findExecutable(String[] paths, String executableName, boolean fail) throws IOException, InterruptedException {
+        for (String p : paths) {
+            Path exe = Paths.get(p);
+            if (executableName != null)
+                exe = exe.resolve(executableName);
+            if (Files.exists(exe) && Files.isExecutable(exe) && testExecutable(exe)) {
+                return exe;
+            }
+        }
+        if (fail)
+            throw new UnsupportedOperationException("Couldn't find executable '" + executableName + "' on the system path.");
+        return null;
+    }
+
+    private static Path findExecutable(String path, boolean splitPath, boolean fail) throws IOException, InterruptedException {
+        switch (OSType.calculate()) {
+        case APPLE:
+        case SUN:
+        case LINUX:
+            return findExecutable(splitPath ? path.split(":") : new String[] { path }, "gnuplot", fail);
+        case WINDOWS:
+            return findExecutable(splitPath ? path.split(";") : new String[] { path }, "gnuplot.exe", fail);
+        default:
+            throw new UnsupportedOperationException("unsupported platform");
+        }
+    }
+
+    private static Path findGnuplotPath() throws IOException, InterruptedException {
+        String path = System.getenv(GNUPLOT_ENV);
+        if (path != null) {
+            // Does GNUPLOT point directly to the executable?
+            Path p = findExecutable(new String[] { path }, null, false);
+            if (p != null)
+                return p;
+            // Does GNUPLOT point to the gnuplot installation bin directory?
+            p = findExecutable(path, false, false);
+            if (p != null)
+                return p;
+            // Does GNUPLOT point to the gnuplot installation root directory?
+            p = findExecutable(path + "/bin", false, false);
+            if (p != null)
+                return p;
+        }
+        path = System.getenv(PATH_ENV);
+        return findExecutable(path, true, true);
+    }
+
+    private void execute0(Path workingDirectory, Path stdout, Path stderr, String... cmdline) throws IOException {
+        Process process = new ProcessBuilder(cmdline)
+                .directory(workingDirectory.toFile())
+                .start();
+        process.getOutputStream().close();
+        Thread stdoutDumper = new Thread(new InputStreamToFileCopier(process.getInputStream(), stdout));
+        Thread stderrDumper = new Thread(new InputStreamToFileCopier(process.getErrorStream(), stderr));
+        stdoutDumper.start();
+        stderrDumper.start();
+        try {
+            stdoutDumper.join();
+            stderrDumper.join();
+            process.waitFor();
+        } catch (InterruptedException e) {
+            throw new IOException(e);
+        }
+    }
+
+    public void execute(Path workingDirectory, Path stdout, Path stderr, Path script) throws IOException {
+        execute0(workingDirectory, stdout, stderr, executable.toString(), "-c", script.toString());
+    }
+
+    public void execute(Path workingDirectory, Path stdout, Path stderr, String... commands) throws IOException {
+        StringBuilder e = new StringBuilder().append('"');
+        boolean first = true;
+        for (String cmd : commands) {
+            if (!first)
+                e.append("; ");
+            first = false;
+            e.append(cmd);
+        }
+        e.append('"');
+        execute0(workingDirectory, stdout, stderr, executable.toString(), "-e", e.toString());
+    }
+
+    public GnuplotSession newSession(Path workingDirectory, Path stdout, Path stderr) throws IOException {
+        Process process = new ProcessBuilder(executable.toString())
+                .directory(workingDirectory.toFile())
+                .start();
+        return new GnuplotSession(workingDirectory, stdout, stderr, process);
+    }
+
+    static enum OSType {
+        APPLE, LINUX, SUN, WINDOWS, UNKNOWN;
+
+        public static OSType calculate() {
+            String osName = System.getProperty("os.name");
+            assert osName != null;
+            osName = osName.toLowerCase();
+            if (osName.startsWith("mac os x"))
+                return APPLE;
+            if (osName.startsWith("windows"))
+                return WINDOWS;
+            if (osName.startsWith("linux"))
+                return LINUX;
+            if (osName.startsWith("sun"))
+                return SUN;
+            return UNKNOWN;
+        }
+    }
+
+}