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 Main.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) { 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 Main.warn("Desktop class failed. Platform dependent fall back for open url in browser."); 062 displayUrlFallback(uri); 063 } 064 } 065 } catch (IOException e) { 066 Main.warn(e); 067 return e.getMessage(); 068 } 069 } else { 070 try { 071 Main.warn("Desktop class is not supported. Platform dependent fall back for open url in browser."); 072 displayUrlFallback(uri); 073 } catch (IOException e) { 074 return e.getMessage(); 075 } 076 } 077 return null; 078 } 079 080 /** 081 * Displays an external URL using platform associated software. 082 * A web resource will launch platform's browser, an audio file URL will launch audio player, etc. 083 * @param url The URL to display 084 * @return <code>null</code> for success or a string in case of an error. 085 * @throws IllegalStateException if no platform is set to which opening the URL can be dispatched, 086 * {@link Main#platform} 087 */ 088 public static String displayUrl(String url) { 089 try { 090 return displayUrl(new URI(url)); 091 } catch (URISyntaxException e) { 092 return e.getMessage(); 093 } 094 } 095}