Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/main/java/org/scijava/desktop/links/DefaultLinkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
package org.scijava.desktop.links;

import java.awt.Desktop;
import java.awt.GraphicsEnvironment;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -46,6 +47,8 @@
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
import org.scijava.service.Service;
import org.scijava.ui.DialogPrompt;
import org.scijava.ui.UIService;

/**
* Default implementation of {@link LinkService}.
Expand All @@ -61,6 +64,12 @@ public class DefaultLinkService extends AbstractHandlerService<URI, LinkHandler>
@Parameter(required = false)
private PlatformService platformService;

@Parameter(required = false)
private UIService uiService;

/** Maximum number of characters of an unsupported URI shown to the user. */
private static final int MAX_URI_DISPLAY_LENGTH = 120;

@EventHandler
private void onEvent(final ContextCreatedEvent evt) {
// Register URI handler with the desktop system, if possible.
Expand All @@ -75,6 +84,26 @@ private void onEvent(final ContextCreatedEvent evt) {
installSchemes();
}

@Override
public void handleUnsupported(final URI uri) {
final String appName = System.getProperty("scijava.app.name", "This application");
final String appDir = System.getProperty("scijava.app.directory");
String shown = String.valueOf(uri);
if (shown.length() > MAX_URI_DISPLAY_LENGTH) {
shown = shown.substring(0, MAX_URI_DISPLAY_LENGTH) + "...";
}
final String msg = appName + " cannot handle this link:\n\n" + shown +
"\n\nThe component that supports it may be missing or outdated. " +
"Please make sure it is installed and up to date." +
(appDir == null ? "" : "\n\nIf several installations exist in your system, " +
"the one that received this link may not include the component it " +
"needs. This link has been opened by:\n" + appDir);
if (log != null) log.warn(msg.replace("\n\n", " ").replace("\n", " "));
if (uiService != null && !GraphicsEnvironment.isHeadless()) {
uiService.showDialog(msg, "Unsupported Link", DialogPrompt.MessageType.ERROR_MESSAGE);
}
}

/**
* Installs URI schemes with the operating system.
* <p>
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/org/scijava/desktop/links/LinkService.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,30 @@ default void handle(final URI uri) {
.findFirst();
if (match.isEmpty()) {
// No appropriate link handler plugin was found.
final Logger log = log();
if (log != null) log.debug("No handler for URI: " + uri);
handleUnsupported(uri);
return; // no handler for this URI
}
// Handle the URI using the matching link handler.
match.get().handle(uri);
}

/**
* Called by {@link #handle(URI)} when no {@link LinkHandler} supports the
* given URI. This typically happens when a link is opened by an installation
* that lacks (or has an outdated version of) the component that implements
* it, since the operating system routes links by scheme only.
* <p>
* The default implementation only logs a debug message. Implementations
* with access to a user interface should override it to notify the user.
* </p>
*
* @param uri The URI that no handler supports.
*/
default void handleUnsupported(final URI uri) {
final Logger log = log();
if (log != null) log.debug("No handler for URI: " + uri);
}

default Set<String> getSchemes() {
var schemes = new HashSet<String>();
for (final LinkHandler handler : getInstances()) {
Expand Down