1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.excel;
15 import java.io.IOException;
16 import java.io.PrintStream;
18 import java.net.URLDecoder;
19 import java.nio.charset.Charset;
20 import java.util.ArrayList;
21 import java.util.Enumeration;
22 import java.util.UUID;
23 import java.util.concurrent.Callable;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.TimeUnit;
29 import java.util.concurrent.TimeoutException;
31 import org.eclipse.core.resources.IWorkspace;
32 import org.eclipse.core.resources.IWorkspaceRoot;
33 import org.eclipse.core.resources.ResourcesPlugin;
34 import org.eclipse.core.runtime.FileLocator;
35 import org.eclipse.core.runtime.IPath;
36 import org.eclipse.core.runtime.Path;
37 import org.eclipse.core.runtime.Platform;
38 import org.osgi.framework.Bundle;
39 import org.osgi.framework.BundleContext;
40 import org.simantics.excel.ExecEnvironment.ARCHType;
41 import org.simantics.excel.ExecEnvironment.OSType;
42 import org.simantics.utils.FileUtils;
46 private static Excel instance;
48 public static Excel getInstance() throws ExcelException {
49 return getInstance(System.out);
52 public static Excel getInstance(PrintStream out) throws ExcelException {
54 if(instance == null) {
55 if (Platform.inDevelopmentMode()) {
56 Bundle b = Activator.getDefault().getBundle();
57 URL url = FileLocator.find(b, new Path(""), null);
59 extractDir = new File(URLDecoder.decode(FileLocator.toFileURL(url).getPath(), "UTF-8"));
60 } catch (IOException e) {
61 e.printStackTrace(out);
62 throw new ExcelException(e);
67 } catch (IOException e) {
68 e.printStackTrace(out);
69 throw new ExcelException(e);
70 } catch (Throwable t) {
71 t.printStackTrace(out);
72 throw new ExcelException(t);
76 instance = new Excel(out);
84 public File getDirectory() throws IOException {
86 Bundle b = Platform.getBundle(Activator.PLUGIN_ID);
88 throw new AssertionError("Could not resolve bundle '" + Activator.PLUGIN_ID + "' although were running in its fragment. Should not happen.");
90 BundleContext context = b.getBundleContext();
92 throw new AssertionError("Could not get bundle context for bundle '" + Activator.PLUGIN_ID + "'. Bundle state is " + b.getState() + ".");
94 File extractDir = context.getDataFile("");
95 if (extractDir == null)
96 throw new IOException("Bundle '" + Activator.PLUGIN_ID + " context has no file system support. Cannot extract DLLs.");
98 if (!extractDir.exists())
99 if (!extractDir.mkdir())
100 throw new IOException("Could not create directory '" + extractDir.getCanonicalPath() + "' for communicating with Excel.");
106 public String getContainer() {
107 return UUID.randomUUID().toString();
110 public String getFile(String name) {
112 return getDirectory().getAbsolutePath() + "\\" + name;
113 } catch (IOException e) {
119 private Excel(PrintStream out) throws ExcelException {
122 Future<?> future = init_(extractDir + File.separator);
123 future.get(10, TimeUnit.SECONDS);
124 } catch (InterruptedException e) {
125 throw new ExcelException(e);
126 } catch (ExecutionException e) {
127 throw new ExcelException(e);
128 } catch (TimeoutException e) {
129 throw new ExcelException(e);
134 public static IPath getAbsolutePath(String inBundle, String fullpath) {
135 Bundle b = Platform.getBundle(inBundle);
138 return getAbsolutePath(b, fullpath);
141 public static IPath getAbsolutePath(Bundle inBundle, String fullpath) {
142 // System.out.println("getAbsolutePath: " + inBundle + ", " + fullpath);
143 IPath path = new Path(fullpath);
144 URL u = FileLocator.find(inBundle, path, null);
147 u = FileLocator.resolve(u);
148 // System.out.println(" PROTOCOL: " + u.getProtocol());
149 // System.out.println(" FILE: " + u.getFile());
150 // an absolute path is only available for the file protocol.
151 if ("file".equals(u.getProtocol())) {
152 IPath p = new Path(new File(u.getFile()).getAbsolutePath());
155 } catch (Exception e) {
161 private static final Charset ascii = Charset.forName("US-ASCII");
163 private static final String REQUIRED_FILES_DESCRIPTOR_FILE = "required_files.txt";
166 * List here all the files that are required from this bundle to be able to
167 * run the ProCoreServer executable. This is necessary for the starter core
168 * below to be able to extract all the needed files incase the bundle
169 * happens to be deployed as a JAR.
171 private static final String[] DEFAULT_REQUIRED_FILES = {
172 "SimanticsExcel.dll", "SimanticsExcel_64.dll"
176 * The extraction directory is stored as a static field so that it can be
177 * used to check whether the files have already been extracted.
179 static private File extractDir = null;
181 static private String[] requiredFiles = null;
183 static private boolean needExtraction = false;
185 private static IPath getAbsolutePath(String fullpath) {
186 Bundle b = Platform.getBundle(Activator.PLUGIN_ID);
189 // System.out.println("getAbsolutePath: " + inBundle + ", " + fullpath);
190 IPath path = new Path(fullpath);
191 URL u = FileLocator.find(b, path, null);
194 u = FileLocator.resolve(u);
195 // System.out.println(" PROTOCOL: " + u.getProtocol());
196 // System.out.println(" FILE: " + u.getFile());
197 // an absolute path is only available for the file protocol.
198 if ("file".equals(u.getProtocol())) {
199 IPath p = new Path(new File(u.getFile()).getAbsolutePath());
202 } catch (Exception e) {
208 static String[] getRequiredFiles() {
210 if (requiredFiles != null)
211 return requiredFiles;
213 Bundle b = Platform.getBundle(Activator.PLUGIN_ID);
217 ArrayList<Enumeration<?>> enu = new ArrayList<Enumeration<?>>();
219 enu.add(b.findEntries("/", "*.dll", true));
220 //enu.add(b.findEntries("/", "*.manifest", true));
222 ArrayList<String> filez = new ArrayList<String>();
224 for(Enumeration<?> e : enu) {
225 while(e.hasMoreElements()) {
226 URL url = (URL)e.nextElement();
227 filez.add(url.getFile());
228 // System.out.println(url.getFile());
232 requiredFiles = filez.toArray(new String[filez.size()]);
234 return requiredFiles;
238 private static File extractFiles() throws IOException {
239 Bundle b = Platform.getBundle(Activator.PLUGIN_ID);
241 throw new AssertionError("Could not resolve bundle '" + Activator.PLUGIN_ID + "' although were running in it. Should not happen.");
243 //System.out.println("bundle dir: " + baseDir);
244 for (String file : getRequiredFiles()) {
245 // FileLocator find files in fragments also, Bundle.getEntry won't do that.
246 URL url = FileLocator.find(b, new Path(file), null);
247 File fzz = new File(extractDir, file);
248 Path path = new Path(fzz.getAbsolutePath());
249 path.removeLastSegments(1).toFile().mkdirs();
250 FileUtils.copyResource(url, fzz, false);
255 public static final String EXCEL_FOLDER = "Excel"; //$NON-NLS-1$
257 public static void start(PrintStream out) throws IOException {
259 Bundle b = Platform.getBundle(Activator.PLUGIN_ID);
261 throw new AssertionError("Could not resolve bundle '" + Activator.PLUGIN_ID + "' although were running in its fragment. Should not happen.");
263 BundleContext context = b.getBundleContext();
265 throw new AssertionError("Could not get bundle context for bundle '" + Activator.PLUGIN_ID + "'. Bundle state is " + b.getState() + ".");
267 IWorkspace workspace = ResourcesPlugin.getWorkspace();
268 IWorkspaceRoot workspaceRoot = workspace.getRoot();
269 extractDir = new File(workspaceRoot.getLocation().toFile(), EXCEL_FOLDER);
271 if (!extractDir.exists())
272 if (!extractDir.mkdir())
273 throw new IOException("Could not create directory '" + extractDir.getCanonicalPath() + "' for communicating with Excel.");
276 ExecEnvironment env = ExecEnvironment.calculate();
277 if (env.os == OSType.WINDOWS) {
278 if (env.arch == ARCHType.X86) {
279 asd = extractDir + "\\SimanticsExcel.dll";
280 } else if (env.arch == ARCHType.X86_64) {
281 asd = extractDir + "\\SimanticsExcel_64.dll";
286 File test = new File(asd);
288 needExtraction = false;
291 needExtraction = true;
294 // Resolve executable location
295 if (needExtraction) {
296 extractDir = extractFiles();
298 out.println("needExtraction=false");
304 private native int init();
305 private native String open(String fileName, String sheetName);
306 private native String getModifications(int handle);
307 private native int setDouble(int handle, int row, int column, double value);
308 private native int setString(int handle, int row, int column, String value);
309 private native int setName(int handle, int row, int column, String value);
310 private native int setVisible(int handle, boolean value);
311 private native int close(int handle);
313 private native double getDouble(int handle, int row, int column);
314 private native String getString(int handle, int row, int column);
316 final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
318 public Future<?> init_(final String path) {
319 return scheduler.submit(new Runnable() {
324 ExecEnvironment env = ExecEnvironment.calculate();
325 if (env.os == OSType.WINDOWS) {
326 if (env.arch == ARCHType.X86) {
327 asd = extractDir + "\\SimanticsExcel.dll";
328 } else if (env.arch == ARCHType.X86_64) {
329 asd = extractDir + "\\SimanticsExcel_64.dll";
338 public int open2_(final String fileName, final String sheetName) {
340 return scheduler.submit(new Callable<Integer>() {
342 public Integer call() throws Exception {
343 return Integer.parseInt(open(fileName, sheetName));
346 } catch (Exception e) {
352 public String open_(final String fileName, final String sheetName) {
354 return scheduler.submit(new Callable<String>() {
356 public String call() throws Exception {
357 return open(fileName, sheetName);
360 } catch (Exception e) {
366 public int setDouble_(final int handle, final int row, final int column, final double value) {
368 return scheduler.submit(new Callable<Integer>() {
370 public Integer call() throws Exception {
371 // System.out.println("Excel: setDouble at " + row + "-" + column);
372 return setDouble(handle, row, column, value);
375 } catch (Exception e) {
381 public int setString_(final int handle, final int row, final int column, final String value) {
383 return scheduler.submit(new Callable<Integer>() {
385 public Integer call() throws Exception {
386 // System.out.println("Excel: setString at " + row + "-" + column);
387 return setString(handle, row, column, value);
390 } catch (Exception e) {
396 public String getModifications_(final int handle) {
398 return scheduler.submit(new Callable<String>() {
400 public String call() throws Exception {
401 // System.out.println("Excel: setString at " + row + "-" + column);
402 return getModifications(handle);
405 } catch (Exception e) {
411 public int setName_(final int handle, final int row, final int column, final String value) {
413 return scheduler.submit(new Callable<Integer>() {
415 public Integer call() throws Exception {
416 // System.out.println("Excel: setString at " + row + "-" + column);
417 return setName(handle, row, column, value);
420 } catch (Exception e) {
426 public int setVisible_(final int handle, final Boolean value) {
428 return scheduler.submit(new Callable<Integer>() {
430 public Integer call() throws Exception {
431 // System.out.println("Excel: setString at " + row + "-" + column);
432 return setVisible(handle, value);
435 } catch (Exception e) {
441 public int close_(final int handle) {
443 return scheduler.submit(new Callable<Integer>() {
445 public Integer call() throws Exception {
446 // System.out.println("Excel: close " + handle);
447 int ret = close(handle);
448 // System.out.println("Excel: close = " + ret);
452 } catch (Exception e) {
458 public double getDouble_(final int handle, final int row, final int column) {
460 return scheduler.submit(new Callable<Double>() {
462 public Double call() throws Exception {
463 return getDouble(handle, row, column);
466 } catch (Exception e) {
472 public String getString_(final int handle, final int row, final int column) {
474 return scheduler.submit(new Callable<String>() {
476 public String call() throws Exception {
477 return getString(handle, row, column);
480 } catch (Exception e) {