-/*******************************************************************************
- * 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();
- }
- }
-
-}
\ No newline at end of file