--- /dev/null
+/*******************************************************************************\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