]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.excel/src/org/simantics/excel/Excel.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.excel / src / org / simantics / excel / Excel.java
diff --git a/bundles/org.simantics.excel/src/org/simantics/excel/Excel.java b/bundles/org.simantics.excel/src/org/simantics/excel/Excel.java
new file mode 100644 (file)
index 0000000..2cc7bc0
--- /dev/null
@@ -0,0 +1,468 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.excel;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.PrintStream;\r
+import java.net.URL;\r
+import java.net.URLDecoder;\r
+import java.nio.charset.Charset;\r
+import java.util.ArrayList;\r
+import java.util.Enumeration;\r
+import java.util.UUID;\r
+import java.util.concurrent.Callable;\r
+import java.util.concurrent.ExecutionException;\r
+import java.util.concurrent.Executors;\r
+import java.util.concurrent.Future;\r
+import java.util.concurrent.ScheduledExecutorService;\r
+import java.util.concurrent.TimeUnit;\r
+import java.util.concurrent.TimeoutException;\r
+\r
+import org.eclipse.core.resources.IWorkspace;\r
+import org.eclipse.core.resources.IWorkspaceRoot;\r
+import org.eclipse.core.resources.ResourcesPlugin;\r
+import org.eclipse.core.runtime.FileLocator;\r
+import org.eclipse.core.runtime.IPath;\r
+import org.eclipse.core.runtime.Path;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.osgi.framework.Bundle;\r
+import org.osgi.framework.BundleContext;\r
+import org.simantics.excel.ExecEnvironment.ARCHType;\r
+import org.simantics.excel.ExecEnvironment.OSType;\r
+import org.simantics.utils.FileUtils;\r
+\r
+public class Excel {\r
+\r
+    private static Excel instance;\r
+\r
+    public static Excel getInstance(PrintStream out) throws ExcelException {\r
+\r
+        if(instance == null) {\r
+               if (Platform.inDevelopmentMode()) {\r
+                Bundle b = Activator.getDefault().getBundle();\r
+                URL url = FileLocator.find(b, new Path(""), null);\r
+                try {\r
+                    extractDir = new File(URLDecoder.decode(FileLocator.toFileURL(url).getPath(), "UTF-8"));\r
+                } catch (IOException e) {\r
+                    e.printStackTrace(out);\r
+                    throw new ExcelException(e);\r
+                }\r
+            } else {\r
+                try {\r
+                    start(out);\r
+                } catch (IOException e) {\r
+                    e.printStackTrace(out);\r
+                    throw new ExcelException(e);\r
+                } catch (Throwable t) {\r
+                    t.printStackTrace(out);\r
+                    throw new ExcelException(t);\r
+                }\r
+            }\r
+\r
+               instance = new Excel(out);\r
+            \r
+        }\r
+\r
+        return instance;\r
+\r
+    }\r
+\r
+    public File getDirectory() throws IOException {\r
+\r
+        Bundle b = Platform.getBundle(Activator.PLUGIN_ID);\r
+        if (b == null)\r
+            throw new AssertionError("Could not resolve bundle '" + Activator.PLUGIN_ID + "' although were running in its fragment. Should not happen.");\r
+\r
+        BundleContext context = b.getBundleContext();\r
+        if (context == null)\r
+            throw new AssertionError("Could not get bundle context for bundle '" + Activator.PLUGIN_ID + "'. Bundle state is " + b.getState() + ".");\r
+\r
+        File extractDir = context.getDataFile("");\r
+        if (extractDir == null)\r
+            throw new IOException("Bundle '" + Activator.PLUGIN_ID + " context has no file system support. Cannot extract server executables.");\r
+\r
+        if (!extractDir.exists())\r
+            if (!extractDir.mkdir())\r
+                throw new IOException("Could not create directory '" + extractDir.getCanonicalPath() + "' for storing Balas solver data.");\r
+        \r
+        return extractDir;\r
+        \r
+    }\r
+    \r
+    public String getContainer() {\r
+       return UUID.randomUUID().toString();\r
+    }\r
+    \r
+    public String getFile(String name) {\r
+        try {\r
+            return getDirectory().getAbsolutePath() + "\\" + name;\r
+        } catch (IOException e) {\r
+            e.printStackTrace();\r
+            return null;\r
+        }\r
+    }\r
+    \r
+    private Excel(PrintStream out) throws ExcelException {\r
+\r
+       try {\r
+               Future<?> future = init_(extractDir + File.separator);\r
+                       future.get(10, TimeUnit.SECONDS);\r
+               } catch (InterruptedException e) {\r
+                       throw new ExcelException(e);\r
+               } catch (ExecutionException e) {\r
+                       throw new ExcelException(e);\r
+               } catch (TimeoutException e) {\r
+                       throw new ExcelException(e);\r
+               }\r
+\r
+    }\r
+\r
+    public static IPath getAbsolutePath(String inBundle, String fullpath) {\r
+        Bundle b = Platform.getBundle(inBundle);\r
+        if (b == null)\r
+            return null;\r
+        return getAbsolutePath(b, fullpath);\r
+    }\r
+\r
+    public static IPath getAbsolutePath(Bundle inBundle, String fullpath) {\r
+//      System.out.println("getAbsolutePath: " + inBundle + ", " + fullpath);\r
+        IPath path = new Path(fullpath);\r
+        URL u = FileLocator.find(inBundle, path, null);\r
+        if (u != null) {\r
+            try {\r
+                u = FileLocator.resolve(u);\r
+//              System.out.println("  PROTOCOL: " + u.getProtocol());\r
+//              System.out.println("  FILE: " + u.getFile());\r
+                // an absolute path is only available for the file protocol.\r
+                if ("file".equals(u.getProtocol())) {\r
+                    IPath p = new Path(new File(u.getFile()).getAbsolutePath());\r
+                    return p;\r
+                }\r
+            } catch (Exception e) {\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private static final Charset  ascii             = Charset.forName("US-ASCII");\r
+\r
+    private static final String   REQUIRED_FILES_DESCRIPTOR_FILE = "required_files.txt";\r
+\r
+    /**\r
+     * List here all the files that are required from this bundle to be able to\r
+     * run the ProCoreServer executable. This is necessary for the starter core\r
+     * below to be able to extract all the needed files incase the bundle\r
+     * happens to be deployed as a JAR.\r
+     */\r
+    private static final String[] DEFAULT_REQUIRED_FILES    = {\r
+        "SimanticsExcel.dll", "SimanticsExcel_64.dll"\r
+    };\r
+\r
+    /**\r
+     * The extraction directory is stored as a static field so that it can be\r
+     * used to check whether the files have already been extracted.\r
+     */\r
+    static private  File           extractDir        = null;\r
+\r
+    static private String[]              requiredFiles     = null;\r
+\r
+    static private boolean               needExtraction    = false;\r
+\r
+    private static IPath getAbsolutePath(String fullpath) {\r
+        Bundle b = Platform.getBundle(Activator.PLUGIN_ID);\r
+        if (b == null)\r
+            return null;\r
+//      System.out.println("getAbsolutePath: " + inBundle + ", " + fullpath);\r
+        IPath path = new Path(fullpath);\r
+        URL u = FileLocator.find(b, path, null);\r
+        if (u != null) {\r
+            try {\r
+                u = FileLocator.resolve(u);\r
+//              System.out.println("  PROTOCOL: " + u.getProtocol());\r
+//              System.out.println("  FILE: " + u.getFile());\r
+                // an absolute path is only available for the file protocol.\r
+                if ("file".equals(u.getProtocol())) {\r
+                    IPath p = new Path(new File(u.getFile()).getAbsolutePath());\r
+                    return p;\r
+                }\r
+            } catch (Exception e) {\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    static String[] getRequiredFiles() {\r
+\r
+        if (requiredFiles != null)\r
+            return requiredFiles;\r
+\r
+        Bundle b = Platform.getBundle(Activator.PLUGIN_ID);\r
+        if (b == null)\r
+            return null;\r
+\r
+        ArrayList<Enumeration<?>> enu = new ArrayList<Enumeration<?>>();\r
+\r
+        enu.add(b.findEntries("/", "*.dll", true));\r
+        //enu.add(b.findEntries("/", "*.manifest", true));\r
+\r
+        ArrayList<String> filez = new ArrayList<String>();\r
+\r
+        for(Enumeration<?> e : enu) {\r
+            while(e.hasMoreElements()) {\r
+                URL url = (URL)e.nextElement();\r
+                filez.add(url.getFile());\r
+//                     System.out.println(url.getFile());\r
+            }\r
+        }\r
+\r
+        requiredFiles = filez.toArray(new String[filez.size()]);\r
+\r
+        return requiredFiles;\r
+\r
+    }\r
+\r
+    private static File extractFiles() throws IOException {\r
+        Bundle b = Platform.getBundle(Activator.PLUGIN_ID);\r
+        if (b == null)\r
+            throw new AssertionError("Could not resolve bundle '" + Activator.PLUGIN_ID + "' although were running in it. Should not happen.");\r
+\r
+        //System.out.println("bundle dir: " + baseDir);\r
+        for (String file : getRequiredFiles()) {\r
+            // FileLocator find files in fragments also, Bundle.getEntry won't do that.\r
+            URL url = FileLocator.find(b, new Path(file), null);\r
+            File fzz = new File(extractDir, file);\r
+            Path path = new Path(fzz.getAbsolutePath());\r
+            path.removeLastSegments(1).toFile().mkdirs();\r
+            FileUtils.copyResource(url, fzz, false);\r
+        }\r
+        return extractDir;\r
+    }\r
+\r
+    public static final String EXCEL_FOLDER = "Excel"; //$NON-NLS-1$\r
+    \r
+    public static void start(PrintStream out) throws IOException {\r
+\r
+        Bundle b = Platform.getBundle(Activator.PLUGIN_ID);\r
+        if (b == null)\r
+            throw new AssertionError("Could not resolve bundle '" + Activator.PLUGIN_ID + "' although were running in its fragment. Should not happen.");\r
+\r
+        BundleContext context = b.getBundleContext();\r
+        if (context == null)\r
+            throw new AssertionError("Could not get bundle context for bundle '" + Activator.PLUGIN_ID + "'. Bundle state is " + b.getState() + ".");\r
+\r
+        IWorkspace workspace = ResourcesPlugin.getWorkspace();\r
+        IWorkspaceRoot workspaceRoot = workspace.getRoot();\r
+        extractDir = new File(workspaceRoot.getLocation().toFile(), EXCEL_FOLDER);\r
+        \r
+        if (!extractDir.exists())\r
+            if (!extractDir.mkdir())\r
+                throw new IOException("Could not create directory '" + extractDir.getCanonicalPath() + "' for storing Balas solver data.");\r
+\r
+        String asd = "";\r
+        ExecEnvironment env = ExecEnvironment.calculate();\r
+        if (env.os == OSType.WINDOWS) {\r
+            if (env.arch == ARCHType.X86) {\r
+                asd = extractDir + "\\SimanticsExcel.dll";\r
+            } else if (env.arch == ARCHType.X86_64) {\r
+                asd = extractDir + "\\SimanticsExcel_64.dll";\r
+            }\r
+        }\r
+\r
+        \r
+        File test = new File(asd);\r
+        if(test.exists()) {\r
+            needExtraction = false;\r
+            return;\r
+        } else {\r
+            needExtraction = true;\r
+        }\r
+\r
+        // Resolve executable location\r
+        if (needExtraction) {\r
+            extractDir = extractFiles();\r
+        } else {\r
+            out.println("needExtraction=false");\r
+        }\r
+\r
+    }\r
+\r
+    // Initialization\r
+    private native int init();\r
+    private native String open(String fileName, String sheetName);\r
+    private native String getModifications(int handle);\r
+    private native int setDouble(int handle, int row, int column, double value);\r
+    private native int setString(int handle, int row, int column, String value);\r
+    private native int setName(int handle, int row, int column, String value);\r
+    private native int setVisible(int handle, boolean value);\r
+    private native int close(int handle);\r
+    \r
+//    private native double getDouble(int handle, int row, int column);\r
+//    private native String getString(int handle, int row, int column);\r
+\r
+    final ScheduledExecutorService  scheduler = Executors.newSingleThreadScheduledExecutor();\r
+\r
+    public Future<?> init_(final String path) {\r
+       return scheduler.submit(new Runnable() {\r
+               @Override\r
+               public void run() {\r
+\r
+                   String asd = "";\r
+               ExecEnvironment env = ExecEnvironment.calculate();\r
+               if (env.os == OSType.WINDOWS) {\r
+                   if (env.arch == ARCHType.X86) {\r
+                       asd = extractDir + "\\SimanticsExcel.dll";\r
+                   } else if (env.arch == ARCHType.X86_64) {\r
+                       asd = extractDir + "\\SimanticsExcel_64.dll";\r
+                   }\r
+               }\r
+                System.load(asd);\r
+                init();\r
+               }\r
+       });\r
+    }\r
+\r
+    public String open_(final String fileName, final String sheetName) {\r
+        try {\r
+            return scheduler.submit(new Callable<String>() {\r
+                @Override\r
+                public String call() throws Exception {\r
+                    return open(fileName, sheetName);\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return "";\r
+        }\r
+    }\r
+\r
+    public int setDouble_(final int handle, final int row, final int column, final double value) {\r
+        try {\r
+            return scheduler.submit(new Callable<Integer>() {\r
+                @Override\r
+                public Integer call() throws Exception {\r
+//                    System.out.println("Excel: setDouble at " + row + "-" + column); \r
+                    return setDouble(handle, row, column, value);\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return -1;\r
+        }\r
+    }\r
+\r
+    public int setString_(final int handle, final int row, final int column, final String value) {\r
+        try {\r
+            return scheduler.submit(new Callable<Integer>() {\r
+                @Override\r
+                public Integer call() throws Exception {\r
+//                    System.out.println("Excel: setString at " + row + "-" + column); \r
+                    return setString(handle, row, column, value);\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return -1;\r
+        }\r
+    }\r
+\r
+    public String getModifications_(final int handle) {\r
+        try {\r
+            return scheduler.submit(new Callable<String>() {\r
+                @Override\r
+                public String call() throws Exception {\r
+//                    System.out.println("Excel: setString at " + row + "-" + column); \r
+                    return getModifications(handle);\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return "";\r
+        }\r
+    }\r
+\r
+    public int setName_(final int handle, final int row, final int column, final String value) {\r
+        try {\r
+            return scheduler.submit(new Callable<Integer>() {\r
+                @Override\r
+                public Integer call() throws Exception {\r
+//                    System.out.println("Excel: setString at " + row + "-" + column); \r
+                    return setName(handle, row, column, value);\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return -1;\r
+        }\r
+    }\r
+\r
+    public int setVisible_(final int handle, final Boolean value) {\r
+        try {\r
+            return scheduler.submit(new Callable<Integer>() {\r
+                @Override\r
+                public Integer call() throws Exception {\r
+//                    System.out.println("Excel: setString at " + row + "-" + column); \r
+                    return setVisible(handle, value);\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return -1;\r
+        }\r
+    }\r
+\r
+    public int close_(final int handle) {\r
+        try {\r
+            return scheduler.submit(new Callable<Integer>() {\r
+                @Override\r
+                public Integer call() throws Exception {\r
+//                    System.out.println("Excel: close " + handle);\r
+                    int ret = close(handle); \r
+//                    System.out.println("Excel: close = " + ret);\r
+                    return ret;\r
+                }\r
+            }).get();\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            return -1;\r
+        }\r
+    }\r
+    \r
+//    public double getDouble_(final int handle, final int row, final int column) {\r
+//        try {\r
+//            return scheduler.submit(new Callable<Double>() {\r
+//                @Override\r
+//                public Double call() throws Exception {\r
+//                    return getDouble(handle, row, column);\r
+//                }\r
+//            }).get();\r
+//        } catch (Exception e) {\r
+//            e.printStackTrace();\r
+//            return Double.NaN;\r
+//        }\r
+//    }\r
+//    \r
+//    public String getString_(final int handle, final int row, final int column) {\r
+//        try {\r
+//            return scheduler.submit(new Callable<String>() {\r
+//                @Override\r
+//                public String call() throws Exception {\r
+//                    return getString(handle, row, column);\r
+//                }\r
+//            }).get();\r
+//        } catch (Exception e) {\r
+//            e.printStackTrace();\r
+//            return null;\r
+//        }\r
+//    }\r
+\r
+}\r