123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- /*
- * Copyright (c) 2006-2014 DMDirc Developers
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
- package com.dmdirc.ui.core.util;
-
- import com.dmdirc.ServerManager;
- import com.dmdirc.events.UnknownURLEvent;
- import com.dmdirc.events.UserErrorEvent;
- import com.dmdirc.interfaces.config.AggregateConfigProvider;
- import com.dmdirc.logger.ErrorLevel;
- import com.dmdirc.ui.StatusMessage;
- import com.dmdirc.ui.core.components.StatusBarManager;
- import com.dmdirc.util.CommandUtils;
-
- import java.awt.Desktop;
- import java.io.IOException;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.net.URL;
- import java.util.Date;
-
- import javax.inject.Inject;
-
- import net.engio.mbassy.bus.MBassador;
-
- /** Handles URLs. */
- public class URLHandler {
-
- /** The time a browser was last launched. */
- private static Date lastLaunch;
- /** Event bus to fire unknown protocol errors on. */
- private final MBassador eventBus;
- /** Config manager. */
- private final AggregateConfigProvider config;
- /** Server manager to use to connect to servers. */
- private final ServerManager serverManager;
- /** Status bar manager to use to show messages. */
- private final StatusBarManager statusBarManager;
- /** Desktop handler. */
- private final Desktop desktop;
-
- /**
- * Instantiates a new URL Handler.
- *
- * @param eventBus Event bus to fire unknown protocol errors on.
- * @param globalConfig Config to retrieve settings from
- * @param serverManager Server manager to connect to servers
- * @param statusBarManager Status bar manager used to show messages
- */
- @Inject
- public URLHandler(
- final MBassador eventBus,
- final AggregateConfigProvider globalConfig,
- final ServerManager serverManager,
- final StatusBarManager statusBarManager) {
- this.eventBus = eventBus;
- this.config = globalConfig;
- this.serverManager = serverManager;
- this.statusBarManager = statusBarManager;
- this.desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
- }
-
- /**
- * Launches an application for a given url.
- *
- * @param urlString URL to parse
- */
- public void launchApp(final String urlString) {
- final String sanitisedString = getSanitisedString(urlString);
-
- URI uri;
- try {
- uri = new URI(sanitisedString);
- if (uri.getScheme() == null) {
- uri = new URI("http://" + sanitisedString);
- }
- } catch (URISyntaxException ex) {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, ex,
- "Invalid URL: " + ex.getMessage(), ""));
- return;
- }
-
- launchApp(uri);
- }
-
- /**
- * Sanitises the specified string so that it may be used as a {@link URI}. Sanitisation consists
- * of:
- * <ul>
- * <li>replacing any pipe character with its hex escape</li>
- * <li>replacing any hash character in the fragment with its hex escape</li>
- * </ul>
- *
- * @since 0.6.5
- * @param urlString The string to be sanitised
- *
- * @return A sanitised version of the specified string.
- */
- protected static String getSanitisedString(final String urlString) {
- String sanitisedString = urlString.replace("|", "%7C");
-
- final int index = sanitisedString.indexOf('#');
- if (sanitisedString.lastIndexOf('#') > index) {
- sanitisedString = sanitisedString.substring(0, index + 1)
- + sanitisedString.substring(index + 1).replace("#", "%23");
- }
-
- return sanitisedString;
- }
-
- /**
- * Launches an application for a given url.
- *
- * @param url URL to parse
- */
- public void launchApp(final URL url) {
- URI uri;
- try {
- uri = url.toURI();
- if (uri.getScheme() == null) {
- uri = new URI("http://" + url.toString());
- }
- } catch (URISyntaxException ex) {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, ex,
- "Invalid URL: " + ex.getMessage(), ""));
- return;
- }
-
- launchApp(uri);
- }
-
- /**
- * Launches an application for a given url.
- *
- * @param uri URL to parse
- */
- public void launchApp(final URI uri) {
- final Date oldLaunch = lastLaunch;
- lastLaunch = new Date();
-
- if (config.getOptionBool("browser", "uselaunchdelay") && oldLaunch != null) {
- final Long diff = lastLaunch.getTime() - oldLaunch.getTime();
-
- if (diff < config.getOptionInt("browser", "launchdelay")) {
- return;
- }
- }
-
- if (!config.hasOptionString("protocol", uri.getScheme().toLowerCase())) {
- eventBus.publish(new UnknownURLEvent(uri));
- return;
- }
-
- final String command = config.getOption("protocol", uri.getScheme().toLowerCase());
- switch (command) {
- case "DMDIRC":
- statusBarManager.setMessage(
- new StatusMessage("Connecting to: " + uri.toString(),
- config));
- serverManager.connectToAddress(uri);
- break;
- case "BROWSER":
- statusBarManager.setMessage(
- new StatusMessage("Opening: " + uri.toString(),
- config));
- execBrowser(uri);
- break;
- case "MAIL":
- execMail(uri);
- break;
- default:
- statusBarManager.setMessage(
- new StatusMessage("Opening: " + uri.toString(),
- config));
- execApp(substituteParams(uri, command));
- break;
- }
- }
-
- /**
- * Substitutes variables into a command.
- *
- * @param url data url
- * @param command command to be substituted
- *
- * @return Substituted command
- */
- public static String substituteParams(final URI url, final String command) {
- final String userInfo = url.getUserInfo();
- String fragment = "";
- String host = "";
- String path = "";
- String protocol = "";
- String query = "";
- String username = "";
- String password = "";
- String port = "";
- String newCommand = command;
-
- if (url.getFragment() != null) {
- fragment = url.getFragment();
- }
-
- if (url.getHost() != null) {
- host = url.getHost();
- }
-
- if (url.getPath() != null) {
- path = url.getPath();
- }
-
- if (url.getScheme() != null) {
- protocol = url.getScheme();
- }
-
- if (url.getQuery() != null) {
- query = url.getQuery();
- }
-
- if (url.getPort() > 0) {
- port = String.valueOf(url.getPort());
- }
-
- if (userInfo != null && !userInfo.isEmpty()) {
- if (userInfo.indexOf(':') == -1) {
- username = userInfo;
- } else {
- final int pos = userInfo.indexOf(':');
- username = userInfo.substring(0, pos);
- password = userInfo.substring(pos + 1);
- }
- }
-
- newCommand = newCommand.replace("$url", url.toString());
- newCommand = newCommand.replace("$fragment", fragment);
- newCommand = newCommand.replace("$host", host);
- newCommand = newCommand.replace("$path", path);
- newCommand = newCommand.replace("$port", port);
- newCommand = newCommand.replace("$query", query);
- newCommand = newCommand.replace("$protocol", protocol);
- newCommand = newCommand.replace("$username", username);
- newCommand = newCommand.replace("$password", password);
-
- return newCommand;
- }
-
- /**
- * Launches an application.
- *
- * @param command Application and arguments
- */
- private void execApp(final String command) {
- try {
- Runtime.getRuntime().exec(CommandUtils.parseArguments(command));
- } catch (IOException ex) {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, ex,
- "Unable to run application: " + ex.getMessage(), ""));
- }
- }
-
- /**
- * Opens the specified URL in the users browser.
- *
- * @param url URL to open
- */
- private void execBrowser(final URI url) {
- if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
- try {
- desktop.browse(url);
- } catch (IOException ex) {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, ex,
- "Unable to open URL: " + ex.getMessage(), ""));
- }
- } else {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, null,
- "Unable to open your browser: Your desktop enviroment is "
- + "not supported, please go to the URL Handlers section of "
- + "the preferences dialog and set the path to your browser "
- + "manually", ""));
- }
- }
-
- /**
- * Opens the specified URL in the users mail client.
- *
- * @param url URL to open
- */
- private void execMail(final URI url) {
- if (desktop != null && desktop.isSupported(Desktop.Action.MAIL)) {
- try {
- desktop.mail(url);
- } catch (IOException ex) {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, ex,
- "Unable to open URL: " + ex.getMessage(), ""));
- }
- } else {
- eventBus.publish(new UserErrorEvent(ErrorLevel.LOW, null,
- "Unable to open your mail client: Your desktop enviroment is "
- + "not supported, please go to the URL Handlers section of "
- + "the preferences dialog and set the path to your browser "
- + "manually", ""));
- }
- }
-
- }
|