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

WIP Restapi #628

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b29aaea
Add jaxrs copy over code
Siedlerchr Sep 21, 2022
c951839
try with jetty
Siedlerchr Sep 21, 2022
96d917a
fcking inject (
Siedlerchr Sep 21, 2022
4b38bd1
Update afterburner to jakarta
Siedlerchr Sep 21, 2022
8f8dff9
Merge remote-tracking branch 'upstream/afterburner' into restApi
Siedlerchr Sep 21, 2022
03bcdd3
add another fcking injection stuff
Siedlerchr Sep 21, 2022
7ce929b
test again
Siedlerchr Sep 22, 2022
809a579
fix afterburner
Siedlerchr Sep 22, 2022
607cb2a
Merge remote-tracking branch 'upstream/main' into restapi
Siedlerchr Oct 13, 2022
9293da1
Fix conflicts
Siedlerchr Oct 13, 2022
698e88f
cleanup
Siedlerchr Oct 14, 2022
4638d77
Merge remote-tracking branch 'upstream/main' into restapi
Siedlerchr Jan 5, 2023
bcca5cc
fix compile errors
Siedlerchr Jan 5, 2023
dd77dce
Switch to JBOSS RestEasy (and Jackson instead of Glassfish)
koppor Jan 5, 2023
4640087
Switch back to Glassfish for JAXB (instead of Jackson)
koppor Jan 6, 2023
a6ee546
Switch from Glassfish to Jackson2 for JSON (but keep it for XML)
koppor Jan 6, 2023
1b4c30d
Remove one dependency
koppor Jan 6, 2023
67280b0
Merge remote-tracking branch 'origin/main' into restapi
koppor Mar 17, 2023
1bbb1db
Remove two "nice-to-have" Markdown plugins (strikethrough, tasklist)
koppor Mar 17, 2023
5c448de
Fix checkstyle
koppor Mar 17, 2023
6095223
Remove duoble dependency entry
koppor Mar 17, 2023
82492fd
Really remove Markdown extension
koppor Mar 17, 2023
bf659ea
Endless startup...
koppor Mar 17, 2023
636873d
Get server to run
koppor Mar 17, 2023
2f8302b
Make use of JabRefDesktop for default directory
koppor Mar 17, 2023
1b1fa9d
Streamline code of ServerPropertyService
koppor Mar 17, 2023
cf14659
Fix checkstyle
koppor Mar 18, 2023
ba80857
Merge remote-tracking branch 'upstream/main' into restapi
Siedlerchr Mar 18, 2023
0c2c30c
fix starting error
Siedlerchr Mar 18, 2023
306d731
fix jlink dupliate module
Siedlerchr Mar 18, 2023
a0799b0
run in background thread
Siedlerchr Mar 18, 2023
21b20f1
Merge remote-tracking branch 'upstream/main' into restapi
Siedlerchr Mar 20, 2023
3b14255
remove tika
Siedlerchr Mar 20, 2023
e734892
Fix checkstyle
koppor Mar 20, 2023
1aacc96
Merge branch 'main' into restapi
koppor Apr 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 23 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ version = project.findProperty('projVersion') ?: '100.0.0'
java {
sourceCompatibility = JavaVersion.VERSION_19
targetCompatibility = JavaVersion.VERSION_19

// Workaround needed for Eclipse, probably because of https://github.com/gradle/gradle/issues/16922
// Should be removed as soon as Gradle 7.0.1 is released ( https://github.com/gradle/gradle/issues/16922#issuecomment-828217060 )
modularity.inferModulePath.set(false)
Expand Down Expand Up @@ -124,8 +125,6 @@ dependencies {
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
implementation 'com.h2database:h2-mvstore:2.1.214'

implementation group: 'org.apache.tika', name: 'tika-core', version: '2.7.0'

// required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635
implementation 'org.bouncycastle:bcprov-jdk18on:1.71.1'

Expand All @@ -142,9 +141,6 @@ dependencies {

implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.5.0.202303070854-r'

implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.2'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.2'

implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.7'

implementation 'org.postgresql:postgresql:42.5.4'
Expand All @@ -161,7 +157,7 @@ dependencies {

implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1'
implementation 'jakarta.inject:jakarta.inject-api:2.0.1'

implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.1'

implementation 'com.github.JabRef:afterburner.fx:testmoduleinfo-SNAPSHOT'
implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1'
Expand All @@ -184,9 +180,27 @@ dependencies {

implementation 'de.undercouch:citeproc-java:3.0.0-beta.2'

// jakarta.activation is already dependency of glassfish
implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2'
// Data mapping
implementation 'jakarta.xml.bind:jakarta.xml.bind-api:4.0.0'
// Data mapping provider for JAXB annotated classes (e.g., MedlineImporter)
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '4.0.2'

// JSON mapping
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.2'
// YML mapping
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.2'

// JAX-WS
implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'

// http sever
// "Starting a Grizzly server to run a JAX-RS or Jersey application is one of the most lightweight and easy ways how to expose a functional RESTful services application."
implementation ('org.glassfish.jersey.containers:jersey-container-grizzly2-http:3.1.1') {
exclude module: "jakarta.activation"
}

implementation group: 'org.glassfish.jersey.media', name: 'jersey-media-jaxb', version: '3.1.1'
implementation group: 'org.glassfish.jersey.media', name: 'jersey-media-json-jackson', version: '3.1.1'

implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') {
exclude module: 'fastparse_2.13'
Expand Down
31 changes: 23 additions & 8 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,32 @@
with org.jabref.gui.logging.GuiWriter,
org.jabref.gui.logging.ApplicationInsightsWriter;

// Preferences and XML
requires java.prefs;

// XML, YAML, JSON
requires jdk.xml.dom;
// Enable JAXB annotations
requires jakarta.xml.bind;
// needs to be loaded here as it's otherwise not found at runtime

// Enable YAML and JSON parsing by Jackson
requires com.fasterxml.jackson.databind;
requires com.fasterxml.jackson.dataformat.yaml;
requires com.fasterxml.jackson.datatype.jsr310;
// Enable JSON mapping at the REST server using Jackson2
// requires resteasy.jackson2.provider;
// Enable JAXB using the standard implementation by Glassfish
requires org.glassfish.jaxb.runtime;
requires jdk.xml.dom;

requires jersey.common;
requires jersey.server;
requires jersey.media.jaxb;
requires jersey.media.json.jackson;
requires jersey.container.grizzly2.http;
requires jersey.hk2;

// Annotations (@PostConstruct)
requires jakarta.annotation;
requires jakarta.validation;

// Microsoft application insights
requires applicationinsights.core;
Expand Down Expand Up @@ -87,15 +104,15 @@
requires org.apache.commons.lang3;
requires org.antlr.antlr4.runtime;
requires org.fxmisc.flowless;
requires org.apache.tika.core;
uses org.apache.tika.detect.AutoDetectReader;

requires pdfbox;
requires xmpbox;
requires com.ibm.icu;

requires flexmark;
requires flexmark.util.ast;
requires flexmark.util.data;

requires com.h2database.mvstore;

// fulltext search
Expand All @@ -108,14 +125,12 @@
requires org.apache.lucene.analysis.common;
requires org.apache.lucene.highlighter;

requires com.fasterxml.jackson.databind;
requires com.fasterxml.jackson.dataformat.yaml;
requires com.fasterxml.jackson.datatype.jsr310;
requires net.harawata.appdirs;
requires com.sun.jna;
requires com.sun.jna.platform;

requires org.eclipse.jgit;
requires jakarta.ws.rs;
uses org.eclipse.jgit.transport.SshSessionFactory;
uses org.eclipse.jgit.lib.GpgSigner;
}
38 changes: 34 additions & 4 deletions src/main/java/org/jabref/cli/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import java.io.File;
import java.io.IOException;
import java.net.Authenticator;
import java.net.URI;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.Map;

import org.jabref.gui.Globals;
import org.jabref.gui.JabRefExecutorService;
import org.jabref.gui.MainApplication;
import org.jabref.logic.journals.JournalAbbreviationLoader;
import org.jabref.logic.l10n.Localization;
Expand All @@ -21,6 +23,7 @@
import org.jabref.logic.protectedterms.ProtectedTermsLoader;
import org.jabref.logic.remote.RemotePreferences;
import org.jabref.logic.remote.client.RemoteClient;
import org.jabref.logic.shared.restserver.rest.Root;
import org.jabref.logic.util.BuildInfo;
import org.jabref.logic.util.OS;
import org.jabref.migrations.PreferencesMigrations;
Expand All @@ -29,6 +32,7 @@
import org.jabref.preferences.JabRefPreferences;
import org.jabref.preferences.PreferencesService;

import jakarta.ws.rs.SeBootstrap;
import net.harawata.appdirs.AppDirsFactory;
import org.apache.commons.cli.ParseException;
import org.slf4j.Logger;
Expand All @@ -43,13 +47,15 @@
* - Start the JavaFX application (if not in cli mode)
*/
public class Launcher {
private static Logger LOGGER;
private static String[] ARGUMENTS;
// initialized after reading the preferences (which configure log directory, ...)
static Logger LOGGER;

public static void main(String[] args) {
ARGUMENTS = args;
addLogToDisk();
try {
// we need a copy of the original arguments
String[] arguments = args;

// Init preferences
final JabRefPreferences preferences = JabRefPreferences.getInstance();
Globals.prefs = preferences;
Expand All @@ -75,7 +81,9 @@ public static void main(String[] args) {
return;
}

MainApplication.main(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences, ARGUMENTS);
JabRefExecutorService.INSTANCE.execute(Launcher::startServer);

MainApplication.main(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences, arguments);
} catch (ParseException e) {
LOGGER.error("Problem parsing arguments", e);
JabRefCLI.printUsage(preferences);
Expand All @@ -85,6 +93,28 @@ public static void main(String[] args) {
}
}

static void startServer() {
SeBootstrap.Configuration.Builder configBuilder = SeBootstrap.Configuration.builder();
configBuilder.property(SeBootstrap.Configuration.PROTOCOL, "HTTP")
.property(SeBootstrap.Configuration.HOST, "localhost")
.property(SeBootstrap.Configuration.PORT, 2005);
SeBootstrap.start(new Root(), configBuilder.build()).thenAccept(instance -> {
instance.stopOnShutdown(stopResult ->
System.out.printf("JabRef REST server stop result: %s [Native stop result: %s].%n", stopResult, stopResult.unwrap(Object.class)));
URI uri = instance.configuration().baseUri();
System.out.printf("JabRef REST server %s running at %s [Native handle: %s].%n", instance, uri, instance.unwrap(Object.class));
}).exceptionally(ex -> {
LOGGER.error("Error starting server", ex);
return null;
});

try {
Thread.currentThread().join();
} catch (InterruptedException e) {
LOGGER.error("could not join on current thread", e);
}
}

/**
* This needs to be called as early as possible. After the first log write, it
* is not possible to alter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.data.MutableDataSet;

public class MarkdownFormatter implements LayoutFormatter {

private final Parser parser;
private final HtmlRenderer renderer;

public MarkdownFormatter() {
MutableDataSet options = new MutableDataSet();
parser = Parser.builder(options).build();
renderer = HtmlRenderer.builder(options).build();
parser = Parser.builder().build();
renderer = HtmlRenderer.builder().build();
}

@Override
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/jabref/logic/net/URLDownload.java
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,11 @@ public String getMimeType() {
*/
public boolean canBeReached() throws UnirestException {

// Set a custom Apache Client Builder to be able to allow circular redirects, otherwise downloads from springer might not work
// Set a custom Apache Client Builder to be able to allow circular redirects, otherwise downloads from springer might not work
Unirest.config().httpClient(new ApacheClient.Builder()
.withRequestConfig((c, r) -> RequestConfig.custom()
.setCircularRedirectsAllowed(true)
.build()));
.withRequestConfig((c, r) -> RequestConfig.custom()
.setCircularRedirectsAllowed(true)
.build()));

Unirest.config().setDefaultHeader("User-Agent", USER_AGENT);

Expand Down Expand Up @@ -391,8 +391,8 @@ public URLConnection openConnection() throws IOException {
int status = ((HttpURLConnection) connection).getResponseCode();

if ((status == HttpURLConnection.HTTP_MOVED_TEMP)
|| (status == HttpURLConnection.HTTP_MOVED_PERM)
|| (status == HttpURLConnection.HTTP_SEE_OTHER)) {
|| (status == HttpURLConnection.HTTP_MOVED_PERM)
|| (status == HttpURLConnection.HTTP_SEE_OTHER)) {
// get redirect url from "location" header field
String newUrl = connection.getHeaderField("location");
// open the new connection again
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.jabref.logic.shared.restserver.core.properties;

import java.nio.file.Path;

import org.jabref.gui.desktop.JabRefDesktop;
import org.jabref.gui.desktop.os.NativeDesktop;
import org.jabref.model.strings.StringUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ServerPropertyService {
private static final Logger LOGGER = LoggerFactory.getLogger(ServerPropertyService.class);
private static ServerPropertyService instance;
private Path workingDirectory;

private ServerPropertyService() {
workingDirectory = determineWorkingDirectory();
}

public static ServerPropertyService getInstance() {
if (instance == null) {
instance = new ServerPropertyService();
}
return instance;
}

/**
* Tries to determine the working directory of the library.
* Uses the first path it finds when resolving in this order:
* 1. Environment variable LIBRARY_WORKSPACE
* 2. Default User home (via {@link NativeDesktop#getDefaultFileChooserDirectory()}) with a new directory for the library
*/
private Path determineWorkingDirectory() {
String libraryWorkspaceEnvironmentVariable = System.getenv("LIBRARY_WORKSPACE");
if (!StringUtil.isNullOrEmpty(libraryWorkspaceEnvironmentVariable)) {
LOGGER.info("Environment Variable found, using defined directory: {}", libraryWorkspaceEnvironmentVariable);
return Path.of(libraryWorkspaceEnvironmentVariable);
} else {
Path fallbackDirectory = JabRefDesktop.getNativeDesktop().getDefaultFileChooserDirectory().resolve("planqk-library");
LOGGER.info("Working directory was not found in either the properties or the environment variables, falling back to default location: {}", fallbackDirectory);
return fallbackDirectory;
}
}

public Path getWorkingDirectory() {
return workingDirectory;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.jabref.logic.shared.restserver.core.repository;

import java.io.IOException;

import org.jabref.logic.crawler.Crawler;
import org.jabref.logic.exporter.SaveException;

import org.eclipse.jgit.api.errors.GitAPIException;

public class CrawlTask implements Runnable {
private final Crawler crawler;
private TaskStatus status;

public CrawlTask(Crawler crawler) {
this.crawler = crawler;
}

public TaskStatus getStatus() {
return status;
}

@Override
public void run() {
status = TaskStatus.RUNNING;
try {
crawler.performCrawl();
} catch (IOException | GitAPIException | SaveException e) {
status = TaskStatus.FAILED;
throw new RuntimeException(e);
}
status = TaskStatus.DONE;
}
}