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.MalformedURLException; 009import java.net.URI; 010 011import javax.swing.JApplet; 012 013import org.openstreetmap.josm.Main; 014 015/** 016 * Helper to open platform web browser on different platforms 017 * 018 * This now delegates the real work to a platform specific class. 019 * 020 * @author Imi 021 */ 022public final class OpenBrowser { 023 024 private OpenBrowser() { 025 // Hide default constructor for utils classes 026 } 027 028 private static void displayUrlFallback(URI uri) throws IOException { 029 if (Main.platform == null) 030 throw new IllegalStateException(tr("Failed to open URL. There is currently no platform set. Please set a platform first.")); 031 Main.platform.openUrl(uri.toString()); 032 } 033 034 /** 035 * Displays an external URI using platform associated software. 036 * A web resource will launch platform's browser, an audio file URI will launch audio player, etc. 037 * @param uri The URI to display 038 * @return <code>null</code> for success or a string in case of an error. 039 * @throws IllegalStateException thrown if no platform is set to which opening the URL can be dispatched, 040 * {@link Main#platform} 041 */ 042 public static String displayUrl(URI uri) { 043 CheckParameterUtil.ensureParameterNotNull(uri, "uri"); 044 if (Main.applet) { 045 try { 046 JApplet applet = (JApplet) Main.parent; 047 applet.getAppletContext().showDocument(uri.toURL()); 048 return null; 049 } catch (MalformedURLException mue) { 050 return mue.getMessage(); 051 } 052 } 053 054 Main.info(tr("Opening URL: {0}", uri)); 055 056 if (Desktop.isDesktopSupported()) { 057 try { 058 if (Main.platform instanceof PlatformHookWindows) { 059 // 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 060 Desktop.getDesktop().browse(uri); 061 } else { 062 // This is not the case with some Linux environments (see below), and not sure about Mac OS X, so we need to handle API failure 063 try { 064 Desktop.getDesktop().browse(uri); 065 } catch (IOException e) { 066 // Workaround for KDE (Desktop API is severely flawed) 067 // see https://bugs.openjdk.java.net/browse/JDK-6486393 068 Main.warn("Desktop class failed. Platform dependent fall back for open url in browser."); 069 displayUrlFallback(uri); 070 } 071 } 072 } catch (Exception e) { 073 Main.warn(e); 074 return e.getMessage(); 075 } 076 } else { 077 try { 078 Main.warn("Desktop class is not supported. Platform dependent fall back for open url in browser."); 079 displayUrlFallback(uri); 080 } catch (IOException e) { 081 return e.getMessage(); 082 } 083 } 084 return null; 085 } 086 087 /** 088 * Displays an external URL using platform associated software. 089 * A web resource will launch platform's browser, an audio file URL will launch audio player, etc. 090 * @param url The URL to display 091 * @return <code>null</code> for success or a string in case of an error. 092 * @throws IllegalStateException thrown if no platform is set to which opening the URL can be dispatched, 093 * {@link Main#platform} 094 */ 095 public static String displayUrl(String url) { 096 try { 097 return displayUrl(new URI(url)); 098 } catch (Exception e) { 099 return e.getMessage(); 100 } 101 } 102}