Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement native messaging #3246

Merged
merged 28 commits into from
Apr 26, 2018
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
ce94601
First working prototype
tobiasdiez Oct 1, 2017
2b8c252
Don't remember completed requests
tobiasdiez Oct 1, 2017
4b4ae53
Improve native messaging interface and add import functionality
tobiasdiez Oct 2, 2017
0d120f5
Add native messaging manifest
tobiasdiez Oct 2, 2017
30e174c
Add default handler
tobiasdiez Oct 2, 2017
7064df8
Add todo: timeout
tobiasdiez Oct 5, 2017
9bc7e24
Don't wait for response from debug messages
tobiasdiez Oct 5, 2017
04fe0bd
handle IOException
tobiasdiez Oct 5, 2017
90b80ca
Update JabRefMain.java
tobiasdiez Oct 5, 2017
dc4317c
Update log4j2.xml
tobiasdiez Oct 5, 2017
fbd5260
Fix NPE
tobiasdiez Oct 5, 2017
35be5de
Merge branch 'master' of /~https://github.com/JabRef/jabref into native…
tobiasdiez Mar 3, 2018
9ac9d20
Merge branch 'nativeMessaging' of /~https://github.com/JabRef/jabref in…
tobiasdiez Mar 3, 2018
6b50302
Fix build
tobiasdiez Mar 3, 2018
b24b599
Make it work in principle
tobiasdiez Mar 4, 2018
6c2c8f8
Give up on native messaging with Java
tobiasdiez Mar 4, 2018
5dc0fc1
Give up on native messaging with Java
tobiasdiez Mar 4, 2018
c3a18ca
Native messaging via powershell script
tobiasdiez Mar 4, 2018
b55a0e4
Small code cleanup
tobiasdiez Mar 4, 2018
3bd7436
Remove silent ApplicationInsights hack since it is no longer needed
tobiasdiez Mar 31, 2018
ef25f09
Specify correct add-on identifier
tobiasdiez Mar 31, 2018
8d5a872
Fix remote passing of arguments with line breaks
tobiasdiez Mar 31, 2018
091ca23
Include into Install4J (and update that from 7.0.3 to 7.0.4)
koppor Apr 3, 2018
c51b9a4
Add exception in architecture tests for javafx.util.Pair
tobiasdiez Apr 3, 2018
2c47830
Fix powershell script
tobiasdiez Apr 3, 2018
242309d
Fix regkey for install4j
koppor Apr 16, 2018
223bd46
Merge branch 'master' of /~https://github.com/JabRef/jabref into native…
tobiasdiez Apr 18, 2018
159874f
Disable remote tests on travis
tobiasdiez Apr 18, 2018
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
14 changes: 11 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ buildscript {

plugins {
id 'com.gradle.build-scan' version '1.11'
id 'com.install4j.gradle' version '7.0.3'
id 'com.install4j.gradle' version '7.0.4'
id 'com.github.johnrengelman.shadow' version '2.0.2'
id "de.sebastianboegl.shadow.transformer.log4j" version "2.1.1"
id "com.simonharrer.modernizer" version '1.5.0-1'
Expand Down Expand Up @@ -50,7 +50,7 @@ apply from: 'xjc.gradle'
group = "org.jabref"
version = "4.2-dev"
project.ext.threeDotVersion = "4.1.0.1"
project.ext.install4jDir = hasProperty("install4jDir") ? getProperty("install4jDir") : (OperatingSystem.current().isWindows() ? 'C:/Program Files/install4j6' : 'install4j6')
project.ext.install4jDir = hasProperty("install4jDir") ? getProperty("install4jDir") : (OperatingSystem.current().isWindows() ? 'C:/Program Files/install4j7' : 'install4j7')
sourceCompatibility = 1.8
targetCompatibility = 1.8
mainClassName = "org.jabref.JabRefMain"
Expand Down Expand Up @@ -468,8 +468,16 @@ install4j {
installDir = file(project.ext.install4jDir)
}

task generateFinalJabRefPS1File(type: Copy) {
from('buildres') {
include 'JabRef.ps1'
}
into 'build'
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [jabRefJarFileName: jar.archiveName])
}

// has to be defined AFTER 'dev' things to have the correct project.version
task media(type: com.install4j.gradle.Install4jTask, dependsOn: "releaseJar") {
task media(type: com.install4j.gradle.Install4jTask, dependsOn: ["releaseJar", "generateFinalJabRefPS1File"]) {
projectFile = file('jabref.install4j')
release = project.version
winKeystorePassword = System.getenv('CERTIFICATE_PW')
Expand Down
3 changes: 3 additions & 0 deletions buildres/JabRef.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@echo off
pushd %~dp0
@powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File ".\JabRef.ps1"
48 changes: 48 additions & 0 deletions buildres/JabRef.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
function Respond($response) {
$jsonResponse = $response | ConvertTo-Json

try {
$writer = New-Object System.IO.BinaryWriter([System.Console]::OpenStandardOutput())
$writer.Write([int]$jsonResponse.Length)
$writer.Write([System.Text.Encoding]::UTF8.GetBytes($jsonResponse))
$writer.Close()
} finally {
$writer.Dispose()
}
}

$jabRefJarFileName = "@jabRefJarFileName@"
$jabRefJar = [System.IO.Path]::Combine($PSScriptRoot, $jabRefJarFileName)

try {
$reader = New-Object System.IO.BinaryReader([System.Console]::OpenStandardInput())
$length = $reader.ReadInt32()
$messageRaw = [System.Text.Encoding]::UTF8.GetString($reader.ReadBytes($length))
$message = $messageRaw | ConvertFrom-Json

if ($message.Status -eq "validate") {
if (-not (Test-Path $jabRefJar)) {
return Respond @{message="jarNotFound";path=$jabRefJar}
} else {
return Respond @{message="jarFound"}
}
}

if (-not (Test-Path $jabRefJar)) {
$wshell = New-Object -ComObject Wscript.Shell
$popup = "Unable to locate '$jabRefJarFileName' in '$([System.IO.Path]::GetDirectoryName($jabRefJar))'."
$wshell.Popup($popup,0,"JabRef", 0x0 + 0x30)
return
}

#$wshell = New-Object -ComObject Wscript.Shell
#$wshell.Popup($message.Text,0,"JabRef", 0x0 + 0x30)

$messageText = $message.Text
$output = & java -jar $jabRefJar -importBibtex "$messageText" 2>&1
#$output = & echoargs -importBibtex $messageText 2>&1
#$wshell.Popup($output,0,"JabRef", 0x0 + 0x30)
return Respond @{message="ok";output="$output"}
} finally {
$reader.Dispose()
}
9 changes: 9 additions & 0 deletions buildres/jabref.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "org.jabref.jabref",
"description": "JabRef",
"path": "JabRef.bat",
"type": "stdio",
"allowed_extensions": [
"@jabfox"
]
}
57 changes: 54 additions & 3 deletions jabref.install4j
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<install4j version="7.0.3" transformSequenceNumber="7">
<directoryPresets config="build/releases/${compiler:buildFileName}" />
<install4j version="7.0.4" transformSequenceNumber="7">
<directoryPresets config="./buildres/jabref.json" />
<application name="JabRef" distributionSourceDir="" applicationId="0034-7691-1464-4754" mediaDir="build/install4j" mediaFilePattern="${compiler:sys.shortName}_${compiler:sys.platform}_${compiler:sys.version}" compression="6" lzmaCompression="false" pack200Compression="false" excludeSignedFromPacking="true" commonExternalFiles="false" createMd5Sums="true" shrinkRuntime="true" shortName="JabRef" publisher="JabRef Community" publisherWeb="https://www.jabref.org/" version="DEV" allPathsRelative="true" backupOnSave="false" autoSave="true" convertDotsToUnderscores="true" macSignature="????" macVolumeId="780dfea2d33a0244" javaMinVersion="1.8" javaMaxVersion="1.8" allowBetaVM="false" jdkMode="runtimeJre" jdkName="">
<languages skipLanguageSelection="true" languageSelectionInPrincipalLanguage="false">
<principalLanguage id="en" customLocalizationFile="" />
Expand Down Expand Up @@ -51,10 +51,13 @@
<mountPoint id="22" root="" location="" mode="755" />
</mountPoints>
<entries>
<fileEntry mountPoint="22" file="build/releases/${compiler:buildFileName}" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="./LICENSE.md" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="./AUTHORS" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="build/releases/${compiler:buildFileName}" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="./build/JabRef.ps1" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="./buildres/JabRef.VisualElementsManifest.xml" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="./buildres/JabRef.bat" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
<fileEntry mountPoint="22" file="./buildres/jabref.json" overwriteMode="4" shared="false" fileMode="644" uninstallMode="0" overrideFileMode="false" overrideOverwriteMode="false" overrideUninstallMode="false" />
</entries>
<components />
</files>
Expand Down Expand Up @@ -561,6 +564,30 @@ return console.askOkCancel(message, true);
</serializedBean>
<condition>!(Util.hasFullAdminRights() || Util.isAdminGroup())</condition>
</action>
<action name="" id="352" customizedId="" beanClass="com.install4j.runtime.beans.actions.registry.SetRegistryValueAction" enabled="true" commentSet="false" comment="" actionElevationType="elevated" rollbackBarrier="false" rollbackBarrierExitCode="0" multiExec="false" failureStrategy="1" errorMessage="">
<serializedBean>
<java class="java.beans.XMLDecoder">
<object class="com.install4j.runtime.beans.actions.registry.SetRegistryValueAction">
<void property="keyName">
<string>SOFTWARE\Mozilla\NativeMessagingHosts</string>
</void>
<void property="registryRoot">
<object class="java.lang.Enum" method="valueOf">
<class>com.install4j.api.windows.RegistryRoot</class>
<string>HKEY_LOCAL_MACHINE</string>
</object>
</void>
<void property="value">
<string>/ve /d "${installer:sys.installationDir}\jabref.json" /f</string>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@koppor This generates a key with a value /ve /d "C:\Program Files\JabRef\jabref.json" /f. However, there actually should be a folder org.jabref.jabref with key Default and only the path as value.
image

It would be nice if you could fix this since this is the last issue that currently prevents merging this PR. Thanks!
See JabRef/JabRef-Browser-Extension#50.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I was in a hurry when copy'n'pasting your requirements.

</void>
<void property="valueName">
<string>org.jabref.jabref</string>
</void>
</object>
</java>
</serializedBean>
<condition />
</action>
</beans>
</group>
</actions>
Expand Down Expand Up @@ -896,6 +923,30 @@ return console.askYesNo(message, true);
</serializedBean>
<condition>!(Util.hasFullAdminRights() || Util.isAdminGroup())</condition>
</action>
<action name="" id="353" customizedId="" beanClass="com.install4j.runtime.beans.actions.registry.DeleteRegistryItemAction" enabled="true" commentSet="false" comment="" actionElevationType="elevated" rollbackBarrier="false" rollbackBarrierExitCode="0" multiExec="false" failureStrategy="1" errorMessage="">
<serializedBean>
<java class="java.beans.XMLDecoder">
<object class="com.install4j.runtime.beans.actions.registry.DeleteRegistryItemAction">
<void property="keyName">
<string>SOFTWARE\Mozilla\NativeMessagingHosts</string>
</void>
<void property="onlyIfEmpty">
<boolean>false</boolean>
</void>
<void property="registryRoot">
<object class="java.lang.Enum" method="valueOf">
<class>com.install4j.api.windows.RegistryRoot</class>
<string>HKEY_LOCAL_MACHINE</string>
</object>
</void>
<void property="valueName">
<string>org.jabref.jabref</string>
</void>
</object>
</java>
</serializedBean>
<condition />
</action>
</beans>
</group>
</actions>
Expand Down
1 change: 0 additions & 1 deletion src/main/java/org/jabref/Globals.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public class Globals {
public static final BuildInfo BUILD_INFO = new BuildInfo();
// Remote listener
public static final RemoteListenerServerLifecycle REMOTE_LISTENER = new RemoteListenerServerLifecycle();

public static final ImportFormatReader IMPORT_FORMAT_READER = new ImportFormatReader();
public static final TaskExecutor TASK_EXECUTOR = new DefaultTaskExecutor();
// In the main program, this field is initialized in JabRef.java
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/JabRefGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void openWindow() {
for (Iterator<ParserResult> parserResultIterator = bibDatabases.iterator(); parserResultIterator.hasNext();) {
ParserResult pr = parserResultIterator.next();
// Define focused tab
if (pr.getFile().get().getAbsolutePath().equals(focusedFile)) {
if (pr.getFile().filter(path -> path.getAbsolutePath().equals(focusedFile)).isPresent()) {
first = true;
}

Expand Down
54 changes: 26 additions & 28 deletions src/main/java/org/jabref/JabRefMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.jabref.logic.net.ProxyRegisterer;
import org.jabref.logic.protectedterms.ProtectedTermsLoader;
import org.jabref.logic.remote.RemotePreferences;
import org.jabref.logic.remote.client.RemoteListenerClient;
import org.jabref.logic.remote.client.RemoteClient;
import org.jabref.logic.util.BuildInfo;
import org.jabref.logic.util.JavaVersion;
import org.jabref.logic.util.OS;
Expand All @@ -43,13 +43,8 @@ public class JabRefMain extends Application {

public static void main(String[] args) {
arguments = args;
launch(arguments);
}

@Override
public void start(Stage mainStage) throws Exception {
Platform.setImplicitExit(false);
SwingUtilities.invokeLater(() -> start(arguments));
launch(arguments);
}

/**
Expand Down Expand Up @@ -99,25 +94,9 @@ private static void ensureCorrectJavaVersion() {
}

private static void start(String[] args) {
FallbackExceptionHandler.installExceptionHandler();

// Init preferences
JabRefPreferences preferences = JabRefPreferences.getInstance();

ensureCorrectJavaVersion();

ProxyPreferences proxyPreferences = preferences.getProxyPreferences();
ProxyRegisterer.register(proxyPreferences);
if (proxyPreferences.isUseProxy() && proxyPreferences.isUseAuthentication()) {
Authenticator.setDefault(new ProxyAuthenticator());
}

Globals.prefs = preferences;
Globals.startBackgroundTasks();

// Note that the language was already set during the initialization of the preferences and it is safe to
// call the next function.
Globals.prefs.setLanguageDependentDefaultValues();

// Perform Migrations
// Perform checks and changes for users with a preference set from an older JabRef version.
PreferencesMigrations.upgradePrefsToOrgJabRef();
Expand All @@ -130,6 +109,21 @@ private static void start(String[] args) {
PreferencesMigrations.addCrossRefRelatedFieldsForAutoComplete();
PreferencesMigrations.upgradeObsoleteLookAndFeels();

// Process arguments
ArgumentProcessor argumentProcessor = new ArgumentProcessor(args, ArgumentProcessor.Mode.INITIAL_START);

FallbackExceptionHandler.installExceptionHandler();

ensureCorrectJavaVersion();

ProxyPreferences proxyPreferences = preferences.getProxyPreferences();
ProxyRegisterer.register(proxyPreferences);
if (proxyPreferences.isUseProxy() && proxyPreferences.isUseAuthentication()) {
Authenticator.setDefault(new ProxyAuthenticator());
}

Globals.startBackgroundTasks();

// Update handling of special fields based on preferences
InternalBibtexFields
.updateSpecialFields(Globals.prefs.getBoolean(JabRefPreferences.SERIALIZESPECIALFIELDS));
Expand Down Expand Up @@ -158,7 +152,7 @@ private static void start(String[] args) {

if (!Globals.REMOTE_LISTENER.isOpen()) {
// we are not alone, there is already a server out there, try to contact already running JabRef:
if (RemoteListenerClient.sendToActiveJabRefInstance(args, remotePreferences.getPort())) {
if (new RemoteClient(remotePreferences.getPort()).sendCommandLineArguments(args)) {
// We have successfully sent our command line options through the socket to another JabRef instance.
// So we assume it's all taken care of, and quit.
LOGGER.info(Localization.lang("Arguments passed on to running JabRef instance. Shutting down."));
Expand All @@ -176,9 +170,6 @@ private static void start(String[] args) {
// The preferences return the system newline character sequence as default
OS.NEWLINE = Globals.prefs.get(JabRefPreferences.NEWLINE);

// Process arguments
ArgumentProcessor argumentProcessor = new ArgumentProcessor(args, ArgumentProcessor.Mode.INITIAL_START);

// See if we should shut down now
if (argumentProcessor.shouldShutDown()) {
Globals.shutdownThreadPools();
Expand All @@ -191,4 +182,11 @@ private static void start(String[] args) {
.invokeLater(() -> new JabRefGUI(argumentProcessor.getParserResults(),
argumentProcessor.isBlank()));
}

@Override
public void start(Stage mainStage) throws Exception {
Platform.setImplicitExit(false);
SwingUtilities.invokeLater(() -> start(arguments)
);
}
}
19 changes: 19 additions & 0 deletions src/main/java/org/jabref/cli/ArgumentProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
import org.jabref.logic.importer.ImportFormatReader;
import org.jabref.logic.importer.OpenDatabase;
import org.jabref.logic.importer.OutputPrinter;
import org.jabref.logic.importer.ParseException;
import org.jabref.logic.importer.ParserResult;
import org.jabref.logic.importer.fileformat.BibtexParser;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.layout.LayoutFormatterPreferences;
import org.jabref.logic.logging.JabRefLogger;
Expand Down Expand Up @@ -82,6 +84,19 @@ private static Optional<ParserResult> importToOpenBase(String argument) {
return result;
}

private static Optional<ParserResult> importBibtexToOpenBase(String argument) {
BibtexParser parser = new BibtexParser(Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor());
try {
List<BibEntry> entries = parser.parseEntries(argument);
ParserResult result = new ParserResult(entries);
result.setToOpenTab();
return Optional.of(result);
} catch (ParseException e) {
System.err.println(Localization.lang("Error occurred when parsing entry") + ": " + e.getLocalizedMessage());
return Optional.empty();
}
}

private static Optional<ParserResult> importFile(String argument) {
String[] data = argument.split(",");

Expand Down Expand Up @@ -346,6 +361,10 @@ private List<ParserResult> importAndOpenFiles() {
importToOpenBase(cli.getImportToOpenBase()).ifPresent(loaded::add);
}

if (!cli.isBlank() && cli.isBibtexImport()) {
importBibtexToOpenBase(cli.getBibtexImport()).ifPresent(loaded::add);
}

return loaded;
}

Expand Down
20 changes: 17 additions & 3 deletions src/main/java/org/jabref/cli/JabRefCLI.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.jabref.cli;

import java.util.Arrays;
import java.util.List;

import org.jabref.Globals;
Expand All @@ -21,14 +20,13 @@ public class JabRefCLI {
private final CommandLine cl;
private List<String> leftOver;


public JabRefCLI(String[] args) {

Options options = getOptions();

try {
this.cl = new DefaultParser().parse(options, args);
this.leftOver = Arrays.asList(cl.getArgs());
this.leftOver = cl.getArgList();
} catch (ParseException e) {
LOGGER.warn("Problem parsing arguments", e);

Expand Down Expand Up @@ -96,6 +94,14 @@ public String getFileExport() {
return cl.getOptionValue("output");
}

public boolean isBibtexImport() {
return cl.hasOption("importBibtex");
}

public String getBibtexImport() {
return cl.getOptionValue("importBibtex");
}

public boolean isFileImport() {
return cl.hasOption("import");
}
Expand Down Expand Up @@ -168,6 +174,14 @@ private Options getOptions() {
hasArg().
argName("FILE").build());

options.addOption(
Option.builder("ib")
.longOpt("importBibtex")
.desc(String.format("%s: %s[,importBibtex bibtexString]", Localization.lang("Import") + " " + Localization.BIBTEX, Localization.lang("filename")))
.hasArg()
.argName("FILE")
.build());

options.addOption(Option.builder("o").
longOpt("output").
desc(String.format("%s: %s[,export format]", Localization.lang("Output or export file"),
Expand Down
Loading