001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.tools; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Desktop; 007import java.io.IOException; 008import java.net.URI; 009import java.net.URISyntaxException; 010 011import org.openstreetmap.josm.Main; 012 013/** 014 * Helper to open platform web browser on different platforms 015 * 016 * This now delegates the real work to a platform specific class. 017 * 018 * @author Imi 019 */ 020public final class OpenBrowser { 021 022 private OpenBrowser() { 023 // Hide default constructor for utils classes 024 } 025 026 private static void displayUrlFallback(URI uri) throws IOException { 027 if (Main.platform == null) 028 throw new IllegalStateException(tr("Failed to open URL. There is currently no platform set. Please set a platform first.")); 029 Main.platform.openUrl(uri.toString()); 030 } 031 032 /** 033 * Displays an external URI using platform associated software. 034 * A web resource will launch platform's browser, an audio file URI will launch audio player, etc. 035 * @param uri The URI to display 036 * @return <code>null</code> for success or a string in case of an error. 037 * @throws IllegalStateException if no platform is set to which opening the URL can be dispatched, 038 * {@link Main#platform} 039 */ 040 public static String displayUrl(URI uri) { 041 CheckParameterUtil.ensureParameterNotNull(uri, "uri"); 042 043 Logging.info(tr("Opening URL: {0}", uri)); 044 045 if (Desktop.isDesktopSupported()) { 046 try { 047 if (Main.isPlatformWindows()) { 048 // Desktop API works fine under Windows, so we don't try any fallback in case of I/O exceptions because it's not API's fault 049 Desktop.getDesktop().browse(uri); 050 } else if (Main.platform instanceof PlatformHookUnixoid || Main.platform instanceof PlatformHookOsx) { 051 // see #5629 #5108 #9568 052 Main.platform.openUrl(uri.toString()); 053 } else { 054 // This is not the case with some Linux environments (see below), 055 // and not sure about Mac OS X, so we need to handle API failure 056 try { 057 Desktop.getDesktop().browse(uri); 058 } catch (IOException e) { 059 // Workaround for KDE (Desktop API is severely flawed) 060 // see https://bugs.openjdk.java.net/browse/JDK-6486393 061 Logging.log(Logging.LEVEL_WARN, "Desktop class failed. Platform dependent fall back for open url in browser.", e); 062 displayUrlFallback(uri); 063 } 064 } 065 } catch (IOException e) { 066 Logging.warn(e); 067 return e.getMessage(); 068 } 069 } else { 070 try { 071 Logging.warn("Desktop class is not supported. Platform dependent fall back for open url in browser."); 072 displayUrlFallback(uri); 073 } catch (IOException e) { 074 Logging.debug(e); 075 return e.getMessage(); 076 } 077 } 078 return null; 079 } 080 081 /** 082 * Displays an external URL using platform associated software. 083 * A web resource will launch platform's browser, an audio file URL will launch audio player, etc. 084 * @param url The URL to display 085 * @return <code>null</code> for success or a string in case of an error. 086 * @throws IllegalStateException if no platform is set to which opening the URL can be dispatched, 087 * {@link Main#platform} 088 */ 089 public static String displayUrl(String url) { 090 try { 091 return displayUrl(new URI(url)); 092 } catch (URISyntaxException e) { 093 Logging.debug(e); 094 return e.getMessage(); 095 } 096 } 097}