-/*******************************************************************************\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.db.procore.server.environment.windows;\r
-\r
-import java.io.Closeable;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.net.URL;\r
-import java.net.URLDecoder;\r
-import java.security.MessageDigest;\r
-import java.security.NoSuchAlgorithmException;\r
-import java.util.Arrays;\r
-\r
-import org.simantics.db.procore.server.environment.ExecutionEnvironment;\r
-import org.simantics.db.procore.server.environment.ExecutionEnvironmentException;\r
-\r
-/**\r
- * Provides Java access to Windows Msi API functions:\r
- * <ul>\r
- * <li>{@link #MsiQueryProductState(String)} (see <a\r
- * href="http://msdn.microsoft.com/en-us/library/aa370363(VS.85).aspx">MSDN</a>)</li>\r
- * </ul>\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class Msi {\r
-\r
- public static void checkOneOfProductsInstalled(Product... products) throws ExecutionEnvironmentException {\r
- StringBuilder sb = new StringBuilder();\r
- sb.append("None of the following products are installed properly:\n");\r
- for (Product product : products) {\r
- ProductState state = Msi.MsiQueryProductState(product.getCode());\r
- switch (state) {\r
- case DEFAULT:\r
- // One of the listed products is installed OK.\r
- return;\r
- default:\r
- sb.append("\t" + product);\r
- sb.append(" - MsiQueryProductState returned ");\r
- sb.append(state);\r
- sb.append("\n");\r
- }\r
- }\r
- throw new ExecutionEnvironmentException("Cannot run ProCore database server in this environment due to the following problems:\n" + sb.toString(), Arrays.asList(products));\r
- }\r
-\r
- public static void checkProductsInstalled(Product... products) throws ExecutionEnvironmentException {\r
- StringBuilder sb = new StringBuilder();\r
- for (Product product : products) {\r
- ProductState state = Msi.MsiQueryProductState(product.getCode());\r
- switch (state) {\r
- case DEFAULT:\r
- // Installed OK\r
- continue;\r
- default:\r
- sb.append("\tProduct " + product + " is not installed properly, MsiQueryProductState returned " + state);\r
- sb.append("\n");\r
- }\r
- }\r
- if (sb.length() > 0) {\r
- // Something is not installed right, throw exception\r
- throw new ExecutionEnvironmentException("Cannot run ProCore database server in this environment due to the following problems:\n" + sb.toString(), Arrays.asList(products));\r
- }\r
- }\r
-\r
- // -------------------------------------------------------------------------\r
-\r
- public static ProductState MsiQueryProductState(String productCode) {\r
- int result = MsiQueryProductState0(productCode);\r
- return ProductState.of(result);\r
- }\r
-\r
- private static native int MsiQueryProductState0(String productCode);\r
-\r
- // -------------------------------------------------------------------------\r
-\r
- private static final String DLL_NAME = "msijni.dll";\r
- private static final String DLL_NAME_64 = "msijni64.dll";\r
-\r
- static {\r
- initialize();\r
- }\r
-\r
- private static void initialize() {\r
- ExecutionEnvironment env = ExecutionEnvironment.calculate();\r
- String libName = null;\r
- switch (env.arch) {\r
- case X86:\r
- libName = DLL_NAME;\r
- break;\r
- case X86_64:\r
- libName = DLL_NAME_64;\r
- break;\r
- default:\r
- return;\r
- }\r
-\r
- URL libURL = Msi.class.getResource("/" + libName);\r
- if (libURL != null) {\r
- try {\r
- if ("file".equals(libURL.getProtocol())) {\r
- File path = new File(URLDecoder.decode(libURL.getPath(), "UTF-8"));\r
- initialize(path);\r
- } else {\r
- File libFile = extractLib(libURL, libName);\r
- initialize(libFile);\r
- }\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
- }\r
-\r
- private static void initialize(File path) {\r
- //System.out.println("load msijni: " + path);\r
- System.load(path.toString());\r
- }\r
-\r
- /**\r
- * Extracts the specified source file in the specified bundle into the\r
- * specified local directory.\r
- * \r
- * @param url the source URL to stream the resource from\r
- * @param targetFile the target file to write the resource to\r
- * @param deleteOnExit <code>true</code> to use {@link File#deleteOnExit()}\r
- * on the resulting file. Note that this does not guarantee that the\r
- * file is deleted when the JVM exits\r
- * @return the resulting file\r
- * @throws FileNotFoundException\r
- */\r
- private static File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {\r
- FileOutputStream os = null;\r
- InputStream is = null;\r
- try {\r
- if (targetFile.exists())\r
- targetFile.delete();\r
-\r
- is = url.openStream();\r
- int read;\r
- byte [] buffer = new byte [16384];\r
- os = new FileOutputStream (targetFile);\r
- while ((read = is.read (buffer)) != -1) {\r
- os.write(buffer, 0, read);\r
- }\r
- os.close ();\r
- is.close ();\r
-\r
- return targetFile;\r
- } finally {\r
- uncheckedClose(os);\r
- uncheckedClose(is);\r
- }\r
- }\r
-\r
-\r
- private static void uncheckedClose(Closeable closeable) {\r
- try {\r
- if (closeable != null)\r
- closeable.close();\r
- } catch (IOException e) {\r
- //ignore\r
- }\r
- }\r
-\r
- private static File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException {\r
- String tmpDirStr = System.getProperty("java.io.tmpdir");\r
- if (tmpDirStr == null)\r
- throw new NullPointerException("java.io.tmpdir property is null");\r
- File tmpDir = new File(tmpDirStr);\r
- File libFile = new File(tmpDir, libName);\r
-\r
- if (libFile.exists()) {\r
- if (libFile.isFile()) {\r
- try {\r
- byte[] origSum = computeSum(libURL);\r
- byte[] targetSum = computeSum(libFile);\r
- if (Arrays.equals(origSum, targetSum))\r
- return libFile;\r
- } catch (NoSuchAlgorithmException e) {\r
- // TODO Auto-generated catch block\r
- e.printStackTrace();\r
- }\r
- }\r
- }\r
-\r
- return copyResource(libURL, libFile);\r
- }\r
-\r
- public static byte[] computeSum(InputStream in) throws IOException {\r
- if (in == null)\r
- throw new IllegalArgumentException("Input cannot be null!");\r
-\r
- try {\r
- MessageDigest md = MessageDigest.getInstance("MD5");\r
- byte[] data = new byte[64 * 1024];\r
-\r
- while (true) {\r
- int read = in.read(data);\r
- if (read == -1) {\r
- return md.digest();\r
- }\r
- md.update(data, 0, read);\r
- }\r
- } catch (NoSuchAlgorithmException e) {\r
- // Should not be possible for MD5\r
- throw new IOException(e);\r
- }\r
- }\r
-\r
- public static byte[] computeSum(File f) throws IOException, NoSuchAlgorithmException {\r
- InputStream in = null;\r
- try {\r
- in = new FileInputStream(f);\r
- return computeSum(in);\r
- } finally {\r
- if (in != null)\r
- in.close();\r
- }\r
- }\r
-\r
- public static byte[] computeSum(URL url) throws IOException, NoSuchAlgorithmException {\r
- InputStream in = null;\r
- try {\r
- in = url.openStream();\r
- return computeSum(in);\r
- } finally {\r
- if (in != null)\r
- in.close();\r
- }\r
- }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procore.server.environment.windows;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+import org.simantics.db.procore.server.environment.ExecutionEnvironment;
+import org.simantics.db.procore.server.environment.ExecutionEnvironmentException;
+
+/**
+ * Provides Java access to Windows Msi API functions:
+ * <ul>
+ * <li>{@link #MsiQueryProductState(String)} (see <a
+ * href="http://msdn.microsoft.com/en-us/library/aa370363(VS.85).aspx">MSDN</a>)</li>
+ * </ul>
+ *
+ * @author Tuukka Lehtonen
+ */
+public class Msi {
+
+ public static void checkOneOfProductsInstalled(Product... products) throws ExecutionEnvironmentException {
+ StringBuilder sb = new StringBuilder();
+ sb.append("None of the following products are installed properly:\n");
+ for (Product product : products) {
+ ProductState state = Msi.MsiQueryProductState(product.getCode());
+ switch (state) {
+ case DEFAULT:
+ // One of the listed products is installed OK.
+ return;
+ default:
+ sb.append("\t" + product);
+ sb.append(" - MsiQueryProductState returned ");
+ sb.append(state);
+ sb.append("\n");
+ }
+ }
+ throw new ExecutionEnvironmentException("Cannot run ProCore database server in this environment due to the following problems:\n" + sb.toString(), Arrays.asList(products));
+ }
+
+ public static void checkProductsInstalled(Product... products) throws ExecutionEnvironmentException {
+ StringBuilder sb = new StringBuilder();
+ for (Product product : products) {
+ ProductState state = Msi.MsiQueryProductState(product.getCode());
+ switch (state) {
+ case DEFAULT:
+ // Installed OK
+ continue;
+ default:
+ sb.append("\tProduct " + product + " is not installed properly, MsiQueryProductState returned " + state);
+ sb.append("\n");
+ }
+ }
+ if (sb.length() > 0) {
+ // Something is not installed right, throw exception
+ throw new ExecutionEnvironmentException("Cannot run ProCore database server in this environment due to the following problems:\n" + sb.toString(), Arrays.asList(products));
+ }
+ }
+
+ // -------------------------------------------------------------------------
+
+ public static ProductState MsiQueryProductState(String productCode) {
+ int result = MsiQueryProductState0(productCode);
+ return ProductState.of(result);
+ }
+
+ private static native int MsiQueryProductState0(String productCode);
+
+ // -------------------------------------------------------------------------
+
+ private static final String DLL_NAME = "msijni.dll";
+ private static final String DLL_NAME_64 = "msijni64.dll";
+
+ static {
+ initialize();
+ }
+
+ private static void initialize() {
+ ExecutionEnvironment env = ExecutionEnvironment.calculate();
+ String libName = null;
+ switch (env.arch) {
+ case X86:
+ libName = DLL_NAME;
+ break;
+ case X86_64:
+ libName = DLL_NAME_64;
+ break;
+ default:
+ return;
+ }
+
+ URL libURL = Msi.class.getResource("/" + libName);
+ if (libURL != null) {
+ try {
+ if ("file".equals(libURL.getProtocol())) {
+ File path = new File(URLDecoder.decode(libURL.getPath(), "UTF-8"));
+ initialize(path);
+ } else {
+ File libFile = extractLib(libURL, libName);
+ initialize(libFile);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private static void initialize(File path) {
+ //System.out.println("load msijni: " + path);
+ System.load(path.toString());
+ }
+
+ /**
+ * Extracts the specified source file in the specified bundle into the
+ * specified local directory.
+ *
+ * @param url the source URL to stream the resource from
+ * @param targetFile the target file to write the resource to
+ * @param deleteOnExit <code>true</code> to use {@link File#deleteOnExit()}
+ * on the resulting file. Note that this does not guarantee that the
+ * file is deleted when the JVM exits
+ * @return the resulting file
+ * @throws FileNotFoundException
+ */
+ private static File copyResource(URL url, File targetFile) throws IOException, FileNotFoundException {
+ FileOutputStream os = null;
+ InputStream is = null;
+ try {
+ if (targetFile.exists())
+ targetFile.delete();
+
+ is = url.openStream();
+ int read;
+ byte [] buffer = new byte [16384];
+ os = new FileOutputStream (targetFile);
+ while ((read = is.read (buffer)) != -1) {
+ os.write(buffer, 0, read);
+ }
+ os.close ();
+ is.close ();
+
+ return targetFile;
+ } finally {
+ uncheckedClose(os);
+ uncheckedClose(is);
+ }
+ }
+
+
+ private static void uncheckedClose(Closeable closeable) {
+ try {
+ if (closeable != null)
+ closeable.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+
+ private static File extractLib(URL libURL, String libName) throws FileNotFoundException, IOException {
+ String tmpDirStr = System.getProperty("java.io.tmpdir");
+ if (tmpDirStr == null)
+ throw new NullPointerException("java.io.tmpdir property is null");
+ File tmpDir = new File(tmpDirStr);
+ File libFile = new File(tmpDir, libName);
+
+ if (libFile.exists()) {
+ if (libFile.isFile()) {
+ try {
+ byte[] origSum = computeSum(libURL);
+ byte[] targetSum = computeSum(libFile);
+ if (Arrays.equals(origSum, targetSum))
+ return libFile;
+ } catch (NoSuchAlgorithmException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ return copyResource(libURL, libFile);
+ }
+
+ public static byte[] computeSum(InputStream in) throws IOException {
+ if (in == null)
+ throw new IllegalArgumentException("Input cannot be null!");
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] data = new byte[64 * 1024];
+
+ while (true) {
+ int read = in.read(data);
+ if (read == -1) {
+ return md.digest();
+ }
+ md.update(data, 0, read);
+ }
+ } catch (NoSuchAlgorithmException e) {
+ // Should not be possible for MD5
+ throw new IOException(e);
+ }
+ }
+
+ public static byte[] computeSum(File f) throws IOException, NoSuchAlgorithmException {
+ InputStream in = null;
+ try {
+ in = new FileInputStream(f);
+ return computeSum(in);
+ } finally {
+ if (in != null)
+ in.close();
+ }
+ }
+
+ public static byte[] computeSum(URL url) throws IOException, NoSuchAlgorithmException {
+ InputStream in = null;
+ try {
+ in = url.openStream();
+ return computeSum(in);
+ } finally {
+ if (in != null)
+ in.close();
+ }
+ }
+