From d48279802404b84683856b3052aba39ee3a535b4 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 19 Nov 2014 17:04:19 +0100 Subject: [PATCH] Change open URI support --- .../gui/components/AddressTextField.java | 3 +- .../java/io/bitsquare/util/Utilities.java | 24 +- .../mightypork/rpack/utils/DesktopApi.java | 261 ++++++++++++++++++ 3 files changed, 275 insertions(+), 13 deletions(-) create mode 100644 src/main/java/net/mightypork/rpack/utils/DesktopApi.java diff --git a/src/main/java/io/bitsquare/gui/components/AddressTextField.java b/src/main/java/io/bitsquare/gui/components/AddressTextField.java index 9ec8402835..2cd8fb3674 100644 --- a/src/main/java/io/bitsquare/gui/components/AddressTextField.java +++ b/src/main/java/io/bitsquare/gui/components/AddressTextField.java @@ -24,7 +24,6 @@ import org.bitcoinj.core.Coin; import org.bitcoinj.uri.BitcoinURI; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.net.URI; @@ -71,7 +70,7 @@ public class AddressTextField extends AnchorPane { textField.setOnMouseClicked(mouseEvent -> { try { Utilities.openURI(URI.create(getBitcoinURI())); - } catch (IOException e) { + } catch (Exception e) { log.warn(e.getMessage()); Popups.openWarningPopup("Warning", "Opening a system Bitcoin wallet application has failed. " + "Perhaps you don't have one installed?"); diff --git a/src/main/java/io/bitsquare/util/Utilities.java b/src/main/java/io/bitsquare/util/Utilities.java index 3f8c5a9f75..71cef2cd77 100644 --- a/src/main/java/io/bitsquare/util/Utilities.java +++ b/src/main/java/io/bitsquare/util/Utilities.java @@ -17,12 +17,12 @@ package io.bitsquare.util; +import io.bitsquare.BitsquareException; + import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import java.awt.*; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -32,7 +32,6 @@ import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.util.function.Function; @@ -42,6 +41,8 @@ import javafx.scene.input.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import net.mightypork.rpack.utils.DesktopApi; + /** * General utilities */ @@ -140,23 +141,24 @@ public class Utilities { printElapsedTime(""); } - public static void openURI(URI uri) throws IOException { - Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; + public static void openURI(URI uri) throws BitsquareException { + // On Linux Desktop is poorly implemented. + // See https://stackoverflow.com/questions/18004150/desktop-api-is-not-supported-on-the-current-platform + boolean succeeded = DesktopApi.browse(uri); + if (!succeeded) + throw new BitsquareException("Failed to open URI: " + uri.toString()); + /* Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null; if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) desktop.browse(uri); - else + else { new ProcessBuilder("x-www-browser", uri.toURL().toString()).start(); + }*/ } public static void openWebPage(String target) throws URISyntaxException, IOException { openURI(new URI(target)); } - public static void openURL(URL url) throws URISyntaxException, IOException { - openURI(url.toURI()); - } - - public static Object copy(Serializable orig) { Object obj = null; try { diff --git a/src/main/java/net/mightypork/rpack/utils/DesktopApi.java b/src/main/java/net/mightypork/rpack/utils/DesktopApi.java new file mode 100644 index 0000000000..c654a32d59 --- /dev/null +++ b/src/main/java/net/mightypork/rpack/utils/DesktopApi.java @@ -0,0 +1,261 @@ +package net.mightypork.rpack.utils; + +import java.awt.*; + +import java.io.File; +import java.io.IOException; + +import java.net.URI; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class DesktopApi { + private static final Logger log = LoggerFactory.getLogger(DesktopApi.class); + + public static boolean browse(URI uri) { + + if (openSystemSpecific(uri.toString())) return true; + + if (browseDESKTOP(uri)) return true; + + return false; + } + + + public static boolean open(File file) { + + if (openSystemSpecific(file.getPath())) return true; + + if (openDESKTOP(file)) return true; + + return false; + } + + + public static boolean edit(File file) { + + // you can try something like + // runCommand("gimp", "%s", file.getPath()) + // based on user preferences. + + if (openSystemSpecific(file.getPath())) return true; + + if (editDESKTOP(file)) return true; + + return false; + } + + + private static boolean openSystemSpecific(String what) { + + EnumOS os = getOs(); + + if (os.isLinux()) { + if (runCommand("kde-open", "%s", what)) return true; + if (runCommand("gnome-open", "%s", what)) return true; + if (runCommand("xdg-open", "%s", what)) return true; + } + + if (os.isMac()) { + if (runCommand("open", "%s", what)) return true; + } + + if (os.isWindows()) { + if (runCommand("explorer", "%s", what)) return true; + } + + return false; + } + + + private static boolean browseDESKTOP(URI uri) { + + logOut("Trying to use Desktop.getDesktop().browse() with " + uri.toString()); + try { + if (!Desktop.isDesktopSupported()) { + logErr("Platform is not supported."); + return false; + } + + if (!Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) { + logErr("BORWSE is not supported."); + return false; + } + + Desktop.getDesktop().browse(uri); + + return true; + } catch (Throwable t) { + logErr("Error using desktop browse.", t); + return false; + } + } + + + private static boolean openDESKTOP(File file) { + + logOut("Trying to use Desktop.getDesktop().open() with " + file.toString()); + try { + if (!Desktop.isDesktopSupported()) { + logErr("Platform is not supported."); + return false; + } + + if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) { + logErr("OPEN is not supported."); + return false; + } + + Desktop.getDesktop().open(file); + + return true; + } catch (Throwable t) { + logErr("Error using desktop open.", t); + return false; + } + } + + + private static boolean editDESKTOP(File file) { + + logOut("Trying to use Desktop.getDesktop().edit() with " + file); + try { + if (!Desktop.isDesktopSupported()) { + logErr("Platform is not supported."); + return false; + } + + if (!Desktop.getDesktop().isSupported(Desktop.Action.EDIT)) { + logErr("EDIT is not supported."); + return false; + } + + Desktop.getDesktop().edit(file); + + return true; + } catch (Throwable t) { + logErr("Error using desktop edit.", t); + return false; + } + } + + + private static boolean runCommand(String command, String args, String file) { + + logOut("Trying to exec:\n cmd = " + command + "\n args = " + args + "\n %s = " + file); + + String[] parts = prepareCommand(command, args, file); + + try { + Process p = Runtime.getRuntime().exec(parts); + if (p == null) return false; + + try { + int retval = p.exitValue(); + if (retval == 0) { + logErr("Process ended immediately."); + return false; + } + else { + logErr("Process crashed."); + return false; + } + } catch (IllegalThreadStateException itse) { + logErr("Process is running."); + return true; + } + } catch (IOException e) { + logErr("Error running command.", e); + return false; + } + } + + + private static String[] prepareCommand(String command, String args, String file) { + + List parts = new ArrayList(); + parts.add(command); + + if (args != null) { + for (String s : args.split(" ")) { + s = String.format(s, file); // put in the filename thing + + parts.add(s.trim()); + } + } + + return parts.toArray(new String[parts.size()]); + } + + private static void logErr(String msg, Throwable t) { + System.err.println(msg); + t.printStackTrace(); + } + + private static void logErr(String msg) { + System.err.println(msg); + } + + private static void logOut(String msg) { + System.out.println(msg); + } + + public static enum EnumOS { + linux, macos, solaris, unknown, windows; + + public boolean isLinux() { + + return this == linux || this == solaris; + } + + + public boolean isMac() { + + return this == macos; + } + + + public boolean isWindows() { + + return this == windows; + } + } + + + public static EnumOS getOs() { + + String s = System.getProperty("os.name").toLowerCase(); + + if (s.contains("win")) { + return EnumOS.windows; + } + + if (s.contains("mac")) { + return EnumOS.macos; + } + + if (s.contains("solaris")) { + return EnumOS.solaris; + } + + if (s.contains("sunos")) { + return EnumOS.solaris; + } + + if (s.contains("linux")) { + return EnumOS.linux; + } + + if (s.contains("unix")) { + return EnumOS.linux; + } + else { + return EnumOS.unknown; + } + } +} \ No newline at end of file