Skip to content

Commit

Permalink
Extract native functions to OS package
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-kolb committed Mar 14, 2016
1 parent 9f897ca commit b40092c
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 150 deletions.
167 changes: 17 additions & 150 deletions src/main/java/net/sf/jabref/gui/desktop/JabRefDesktop.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import net.sf.jabref.external.ExternalFileTypes;
import net.sf.jabref.external.UnknownExternalFileType;
import net.sf.jabref.gui.*;
import net.sf.jabref.gui.desktop.os.Linux;
import net.sf.jabref.gui.desktop.os.OSX;
import net.sf.jabref.gui.desktop.os.Windows;
import net.sf.jabref.gui.undo.UndoableFieldChange;
import net.sf.jabref.logic.l10n.Localization;
import net.sf.jabref.logic.net.URLDownload;
import net.sf.jabref.logic.util.DOI;
import net.sf.jabref.logic.util.OS;
import net.sf.jabref.logic.util.io.FileUtil;
Expand All @@ -21,11 +23,8 @@
import org.apache.commons.logging.LogFactory;

import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -37,12 +36,10 @@
* http://stackoverflow.com/questions/18004150/desktop-api-is-not-supported-on-the-current-platform
*/
public class JabRefDesktop {

private static final Log LOGGER = LogFactory.getLog(JabRefDesktop.class);

private static final Pattern REMOTE_LINK_PATTERN = Pattern.compile("[a-z]+://.*");


/**
* Open a http/pdf/ps viewer for the given link string.
*/
Expand Down Expand Up @@ -72,7 +69,6 @@ public static void openExternalViewer(MetaData metaData, String initialLink, Str
fieldName = "ps";
}
}

} else if ("doi".equals(fieldName)) {
Optional<DOI> doiUrl = DOI.build(link);
if(doiUrl.isPresent()) {
Expand Down Expand Up @@ -101,17 +97,9 @@ public static void openExternalViewer(MetaData metaData, String initialLink, Str
} else if ("ps".equals(fieldName)) {
try {
if (OS.OS_X) {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt("ps");
String viewer = type == null ? Globals.prefs.get(JabRefPreferences.PSVIEWER) : type.getOpenWith();
String[] cmd = {"/usr/bin/open", "-a", viewer, link};
Runtime.getRuntime().exec(cmd);
OSX.openFile(link);
} else if (OS.WINDOWS) {
openFileOnWindows(link);
/*
* cmdArray[0] = Globals.prefs.get(JabRefPreferences.PSVIEWER); cmdArray[1] =
* link; Process child = Runtime.getRuntime().exec(
* cmdArray[0] + " " + cmdArray[1]);
*/
Windows.openFile(link);
} else {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt("ps");
String viewer = type == null ? "xdg-open" : type.getOpenWith();
Expand All @@ -127,12 +115,9 @@ public static void openExternalViewer(MetaData metaData, String initialLink, Str
} else if ("pdf".equals(fieldName)) {
try {
if (OS.OS_X) {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt("pdf");
String viewer = type == null ? Globals.prefs.get(JabRefPreferences.PSVIEWER) : type.getOpenWith();
String[] cmd = {"/usr/bin/open", "-a", viewer, link};
Runtime.getRuntime().exec(cmd);
OSX.openFile(link, "pdf");
} else if (OS.WINDOWS) {
openFileOnWindows(link);
Windows.openFile(link);
/*
* String[] spl = link.split("\\\\"); StringBuffer sb = new
* StringBuffer(); for (int i = 0; i < spl.length; i++) { if
Expand All @@ -145,14 +130,7 @@ public static void openExternalViewer(MetaData metaData, String initialLink, Str
* Process child = Runtime.getRuntime().exec(cmd);
*/
} else {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt("pdf");
String viewer = type == null ? Globals.prefs.get(JabRefPreferences.PSVIEWER) : type.getOpenWith();
String[] cmdArray = new String[2];
cmdArray[0] = viewer;
cmdArray[1] = link;
// Process child = Runtime.getRuntime().exec(cmdArray[0]+"
// "+cmdArray[1]);
Runtime.getRuntime().exec(cmdArray);
Linux.openFile(link, "pdf");
}
} catch (IOException e) {
LOGGER.error("An error occured on the command: " + Globals.prefs.get(JabRefPreferences.PDFVIEWER) + " #"
Expand All @@ -163,31 +141,6 @@ public static void openExternalViewer(MetaData metaData, String initialLink, Str
}
}

/**
* Opens a file on a Windows system, using its default viewer.
*
* @param link
* The filename.
* @throws IOException
*/
private static void openFileOnWindows(String link) throws IOException {
// escape & and spaces
Runtime.getRuntime().exec("cmd.exe /c start " + link.replaceAll("&", "\"&\"").replaceAll(" ", "\" \""));
}

/**
* Opens a file on a Windows system, using the given application.
*
* @param link The filename.
* @param application Link to the app that opens the file.
* @throws IOException
*/
private static void openFileWithApplicationOnWindows(String link, String application) throws IOException {
String escapedLink = link.replaceAll("&", "\"&\"").replaceAll(" ", "\" \"");

Runtime.getRuntime().exec(application + " " + escapedLink);
}

/**
* Open an external file, attempting to use the correct viewer for it.
*
Expand All @@ -204,22 +157,6 @@ public static boolean openExternalFileAnyFormat(final MetaData metaData, String
if (REMOTE_LINK_PATTERN.matcher(link.toLowerCase()).matches()) {
httpLink = true;
}
/*if (link.toLowerCase().startsWith("file://")) {
link = link.substring(7);
}
final String ln = link;
if (REMOTE_LINK_PATTERN.matcher(link.toLowerCase()).matches()) {
(new Thread(new Runnable() {
public void run() {
openRemoteExternalFile(metaData, ln, fileType);
}
})).start();
return true;
}*/

//boolean httpLink = link.toLowerCase().startsWith("http:")
// || link.toLowerCase().startsWith("ftp:");

// For other platforms we'll try to find the file type:
File file = new File(link);
Expand Down Expand Up @@ -261,9 +198,9 @@ private static void openExternalFilePlatformIndependent(ExternalFileType fileTyp
} else if (OS.WINDOWS) {
if ((fileType.getOpenWith() != null) && !fileType.getOpenWith().isEmpty()) {
// Application is specified. Use it:
openFileWithApplicationOnWindows(filePath, fileType.getOpenWith());
Windows.openFileWithApplication(filePath, fileType.getOpenWith());
} else {
openFileOnWindows(filePath);
Windows.openFile(filePath);
}
} else {
// Use the given app if specified, and the universal "xdg-open" otherwise:
Expand All @@ -281,30 +218,6 @@ private static void openExternalFilePlatformIndependent(ExternalFileType fileTyp
}
}

public static void openRemoteExternalFile(final MetaData metaData,
final String link, final ExternalFileType fileType) {
File temp = null;
try {
temp = File.createTempFile("jabref-link", "." + fileType.getExtension());
temp.deleteOnExit();
LOGGER.info("Downloading to '" + temp.getPath() + "'");
new URLDownload(new URL(link)).downloadToFile(temp);
LOGGER.info("Done");
} catch (IOException ex) {
LOGGER.warn("Problem downloading", ex);
}
if (temp != null) {
final String ln = temp.getPath();
SwingUtilities.invokeLater(() -> {
try {
openExternalFileAnyFormat(metaData, ln, fileType);
} catch (IOException ex) {
LOGGER.error("Cannot open external file", ex);
}
});
}
}

public static boolean openExternalFileUnknown(JabRefFrame frame, BibEntry entry, MetaData metaData,
String link, UnknownExternalFileType fileType) throws IOException {

Expand Down Expand Up @@ -387,43 +300,15 @@ else if (answer == JOptionPane.YES_OPTION) {
*/
public static void openFolderAndSelectFile(String fileLink) throws IOException {
if (OS.WINDOWS) {
openFolderAndSelectFileOnWindows(fileLink);
Windows.openFolderAndSelectFile(fileLink);
} else if (OS.LINUX) {
openFolderAndSelectFileOnLinux(fileLink);
Linux.openFolderAndSelectFile(fileLink);
} else {
openFolderAndSelectFileGeneric(fileLink);
File f = new File(fileLink);
Desktop.getDesktop().open(f.getParentFile());
}
}

private static void openFolderAndSelectFileOnLinux(String fileLink) throws IOException {
String desktopSession = System.getenv("DESKTOP_SESSION").toLowerCase();

String cmd;

if (desktopSession.contains("gnome")) {
cmd = "nautilus " + fileLink;
} else if (desktopSession.contains("kde")) {
cmd = "dolphin --select " + fileLink;
} else {
cmd = "xdg-open " + fileLink.substring(0, fileLink.lastIndexOf(File.separator));
}

Runtime.getRuntime().exec(cmd);
}

private static void openFolderAndSelectFileGeneric(String fileLink) throws IOException {
File f = new File(fileLink);
Desktop.getDesktop().open(f.getParentFile());
}

private static void openFolderAndSelectFileOnWindows(String link) throws IOException {
String escapedLink = link.replace("&", "\"&\"");

String cmd = "explorer.exe /select,\"" + escapedLink + "\"";

Runtime.getRuntime().exec(cmd);
}

/**
* Opens the given URL using the system browser
*
Expand All @@ -440,33 +325,15 @@ public static void openConsole(File file) throws IOException {
return;
}

Runtime runtime = Runtime.getRuntime();
String absolutePath = file.getAbsolutePath();
absolutePath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator) + 1);

if (OS.LINUX) {
Process p = runtime.exec("readlink /etc/alternatives/x-terminal-emulator");
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

String emulatorName = reader.readLine();

if (emulatorName != null) {
emulatorName = emulatorName.substring(emulatorName.lastIndexOf(File.separator) + 1);

if (emulatorName.contains("gnome")) {
runtime.exec("gnome-terminal --working-directory=" + absolutePath);
} else if (emulatorName.contains("xfce4")) {
runtime.exec("xfce4-terminal --working-directory=" + absolutePath);
} else if (emulatorName.contains("konsole")) {
runtime.exec("konsole --workdir=" + absolutePath);
} else {
runtime.exec(emulatorName, null, new File(absolutePath));
}
}
Linux.openConsole(absolutePath);
} else if (OS.WINDOWS) {
runtime.exec("cmd.exe /c start", null, new File(absolutePath));
Windows.openConsole(absolutePath);
} else if (OS.OS_X) {
runtime.exec("open -a Terminal " + absolutePath, null, new File(absolutePath));
OSX.openConsole(absolutePath);
} else {
LOGGER.info("Operating system is not supported by this feature.");
}
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/net/sf/jabref/gui/desktop/os/Linux.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package net.sf.jabref.gui.desktop.os;

import net.sf.jabref.Globals;
import net.sf.jabref.JabRefPreferences;
import net.sf.jabref.external.ExternalFileType;
import net.sf.jabref.external.ExternalFileTypes;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class Linux {
public static void openFolderAndSelectFile(String fileLink) throws IOException {
String desktopSession = System.getenv("DESKTOP_SESSION").toLowerCase();

String cmd;

if (desktopSession.contains("gnome")) {
cmd = "nautilus " + fileLink;
} else if (desktopSession.contains("kde")) {
cmd = "dolphin --select " + fileLink;
} else {
cmd = "xdg-open " + fileLink.substring(0, fileLink.lastIndexOf(File.separator));
}

Runtime.getRuntime().exec(cmd);
}

public static void openConsole(String absolutePath) throws IOException {
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec("readlink /etc/alternatives/x-terminal-emulator");
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

String emulatorName = reader.readLine();

if (emulatorName != null) {
emulatorName = emulatorName.substring(emulatorName.lastIndexOf(File.separator) + 1);

if (emulatorName.contains("gnome")) {
runtime.exec("gnome-terminal --working-directory=" + absolutePath);
} else if (emulatorName.contains("xfce4")) {
runtime.exec("xfce4-terminal --working-directory=" + absolutePath);
} else if (emulatorName.contains("konsole")) {
runtime.exec("konsole --workdir=" + absolutePath);
} else {
runtime.exec(emulatorName, null, new File(absolutePath));
}
}
}

public static void openFile(String link, String fileType) throws IOException {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt(fileType);
String viewer = type == null ? Globals.prefs.get(JabRefPreferences.PSVIEWER) : type.getOpenWith();
String[] cmdArray = new String[2];
cmdArray[0] = viewer;
cmdArray[1] = link;
Runtime.getRuntime().exec(cmdArray);
}
}
30 changes: 30 additions & 0 deletions src/main/java/net/sf/jabref/gui/desktop/os/OSX.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package net.sf.jabref.gui.desktop.os;

import net.sf.jabref.Globals;
import net.sf.jabref.JabRefPreferences;
import net.sf.jabref.external.ExternalFileType;
import net.sf.jabref.external.ExternalFileTypes;

import java.io.File;
import java.io.IOException;

public class OSX {

This comment has been minimized.

Copy link
@koppor

koppor Mar 15, 2016

Member

Would it be worth to create an interface, which all three classes have to implement? Then, it would be easier to see which method is available in one OS only and may trigger some documentation why some methods are needed only on Windows etc.

public static void openFile(String link, String fileType) throws IOException {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt(fileType);
String viewer = type == null ? Globals.prefs.get(JabRefPreferences.PSVIEWER) : type.getOpenWith();
String[] cmd = {"/usr/bin/open", "-a", viewer, link};
Runtime.getRuntime().exec(cmd);
}

public static void openFile(String link) throws IOException {
ExternalFileType type = ExternalFileTypes.getInstance().getExternalFileTypeByExt("ps");
String viewer = type == null ? Globals.prefs.get(JabRefPreferences.PSVIEWER) : type.getOpenWith();
String[] cmd = {"/usr/bin/open", "-a", viewer, link};
Runtime.getRuntime().exec(cmd);
}

public static void openConsole(String absolutePath) throws IOException {
Runtime runtime = Runtime.getRuntime();
runtime.exec("open -a Terminal " + absolutePath, null, new File(absolutePath));
}
}
Loading

0 comments on commit b40092c

Please sign in to comment.