All Downloads are FREE. Search and download functionalities are using the official Maven repository.

tuwien.auto.calimero.gui.SwtChecker Maven / Gradle / Ivy

There is a newer version: 2.6-rc1
Show newest version
/*
    Calimero GUI - A graphical user interface for the Calimero 2 tools
    Copyright (c) 2016, 2018 B. Malinowsky

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Linking this library statically or dynamically with other modules is
    making a combined work based on this library. Thus, the terms and
    conditions of the GNU General Public License cover the whole
    combination.

    As a special exception, the copyright holders of this library give you
    permission to link this library with independent modules to produce an
    executable, regardless of the license terms of these independent
    modules, and to copy and distribute the resulting executable under terms
    of your choice, provided that you also meet, for each linked independent
    module, the terms and conditions of the license of that module. An
    independent module is a module which is not derived from or based on
    this library. If you modify this library, you may extend this exception
    to your version of the library, but you are not obligated to do so. If
    you do not wish to do so, delete this exception statement from your
    version.
*/

package tuwien.auto.calimero.gui;

import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Checks for correct SWT library on classpath, if missing/mismatch try to download library.
 */
public class SwtChecker
{
	private static final String swtArtifactId = "org.eclipse.swt.";
	private static final String swtVersion = "3.109.0";
	private static final String baseDownloadUrl = "http://central.maven.org/maven2/org/eclipse/platform";

	private final Logger logger;

	public static void main(final String[] args)
	{
		if (isSwtOnClasspath())
			Main.main(new String[0]);
		else {
			final SwtChecker checker = new SwtChecker();
			try {
				checker.downloadToLibDir();
			}
			catch (IOException | URISyntaxException | RuntimeException e) {
				checker.logger.error("Failed to add SWT library", e);
			}
		}
	}

	public SwtChecker()
	{
		logger = LoggerFactory.getLogger("swt-checker");
	}

	private enum Platform {
		Unknown,
		Linux_x86,
		Linux_x86_64,
		MacOS,
		Win_x86,
		Win_x86_64,
	}

	public static boolean isSwtOnClasspath()
	{
		try {
			// this already fails if swt is not available
			final Class swt = Class.forName("org.eclipse.swt.SWT");

			final Object instance = swt.getConstructor().newInstance();
			final Boolean loadable = invoke(swt, instance, "isLoadable");
			final Integer v = invoke(swt, instance, "getVersion");
			final String platform = invoke(swt, instance, "getPlatform");
			if (!loadable)
				System.err.println("SWT library mismatch, version " + v + ", platform " + platform);
			return loadable;
		}
		catch (final Exception e) {
			return false;
		}
	}

	public void downloadToLibDir() throws IOException, URISyntaxException
	{
		logger.warn("No loadable SWT library on classpath (maybe first start?), trying to download SWT ...");
		final Platform platform = platform();
		logger.info("Detected OS: {}", platform);

		final String folder = swtArtifactId + swtPlatformId(platform);
		final String jarName = jarName(platform);
		final String path = String.join("/", baseDownloadUrl, folder, swtVersion, jarName);
		final URI link = new URI(path);
		logger.info("Download {}", link);

		final Path dest = Paths.get(libDir(), "swt.jar");
		download(link, dest);
		logger.info("Saved to {}", dest.normalize().toAbsolutePath());
		logger.info("Success, please restart the application!");
	}

	private Platform platform()
	{
		final String os = System.getProperty("os.name", "unknown").toLowerCase(Locale.ENGLISH);
		// at first try to find out jvm bitness, fallback to OS bitness
		String arch = System.getProperty("sun.arch.data.model");
		if (arch == null)
			arch = System.getProperty("os.arch");

		final boolean is64bit = "64".equals(arch) || "amd64".equals(arch) || "x86_64".equals(arch);
		logger.info("Architecture {}", arch);
		if (os.indexOf("win") >= 0)
			return is64bit ? Platform.Win_x86_64 : Platform.Win_x86;
		if (os.indexOf("mac") >= 0)
			return Platform.MacOS;
		if (os.indexOf("linux") >= 0)
			return is64bit ? Platform.Linux_x86_64 : Platform.Linux_x86;
		return Platform.Unknown;
	}

	private static String swtPlatformId(final Platform p)
	{
		switch (p) {
		case Linux_x86:
			return "gtk.linux.x86";
		case Linux_x86_64:
			return "gtk.linux.x86_64";
		case MacOS:
			return "cocoa.macosx.x86_64";
		case Win_x86:
			return "win32.win32.x86";
		case Win_x86_64:
			return "win32.win32.x86_64";
		case Unknown:
			return "";
		}
		return "";
	}

	private static String jarName(final Platform p)
	{
		return swtArtifactId + swtPlatformId(p) + "-" + swtVersion + ".jar";
	}

	private static String libDir() throws URISyntaxException
	{
		final URL url = SwtChecker.class.getResource("SwtChecker.class");
		URI uri = url.toURI();
		if (url.getProtocol().equals("jar")) {
			// remove the jar parts manually, otherwise we have to create a zip file system
			final String p = url.getPath();
			uri = new URI(p.substring(0, p.indexOf('!')));
		}
		final Path path = Paths.get(uri);
		// remove the file name with extension
		final Path dir = Optional.ofNullable(path.getRoot())
				.map(root -> root.resolve(path.subpath(0, path.getNameCount() - 1))).orElse(Paths.get(""));
		return dir.toString();
	}

	private static void download(final URI link, final Path to) throws IOException
	{
		final URL url = link.toURL();
		try (ReadableByteChannel rbc = Channels.newChannel(url.openStream());
				FileOutputStream os = new FileOutputStream(to.toFile())) {
			os.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
		}
	}

	private static  T invoke(final Class swt, final Object instance, final String method)
		throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
		InvocationTargetException
	{
		final Method m = swt.getMethod(method);
		@SuppressWarnings("unchecked")
		final T result = (T) m.invoke(instance);
		return result;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy