From b29aaea384f04312b03d510092b3305c5d5caa50 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 21 Sep 2022 21:04:58 +0200 Subject: [PATCH 01/28] Add jaxrs copy over code --- build.gradle | 2 +- src/main/java/module-info.java | 1 + .../indexing/IndexingTaskManager.java.orig | 133 + .../properties/ServerPropertyService.java | 47 + .../restserver/core/repository/CrawlTask.java | 33 + .../core/repository/LibraryService.java | 200 ++ .../core/repository/StudyService.java | 154 ++ .../core/repository/TaskStatus.java | 7 + .../core/representation/CSLStyleAdapter.java | 91 + .../core/serialization/BibEntryAdapter.java | 113 + .../BibEntryJacksonDeserializer.java | 78 + .../BibEntryJacksonSerializer.java | 63 + .../core/serialization/BibEntryMapper.java | 141 ++ .../logic/shared/restserver/rest/Root.java | 16 + .../restserver/rest/base/Accumulation.java | 40 + .../restserver/rest/base/Libraries.java | 58 + .../shared/restserver/rest/base/Library.java | 120 + .../restserver/rest/model/BibEntryDTO.java | 120 + .../restserver/rest/model/CrawlStatus.java | 9 + .../shared/restserver/rest/model/Library.java | 11 + .../restserver/rest/model/NewLibraryDTO.java | 13 + .../restserver/rest/model/StudyDTO.java | 15 + .../ObjectMapperContextResolver.java | 30 + .../shared/restserver/rest/slr/Studies.java | 115 + .../xjc/medline/dtd/htmlmathml-f.ent | 2164 +++++++++++++++++ .../resources/xjc/medline/dtd/isoamsa.ent | 201 ++ .../resources/xjc/medline/dtd/isoamsb.ent | 177 ++ .../resources/xjc/medline/dtd/isoamsc.ent | 77 + .../resources/xjc/medline/dtd/isoamsn.ent | 148 ++ .../resources/xjc/medline/dtd/isoamso.ent | 107 + .../resources/xjc/medline/dtd/isoamsr.ent | 238 ++ src/main/resources/xjc/medline/dtd/isobox.ent | 95 + .../resources/xjc/medline/dtd/isocyr1.ent | 122 + .../resources/xjc/medline/dtd/isocyr2.ent | 81 + src/main/resources/xjc/medline/dtd/isodia.ent | 69 + .../resources/xjc/medline/dtd/isogrk3.ent | 98 + .../resources/xjc/medline/dtd/isolat1.ent | 117 + .../resources/xjc/medline/dtd/isolat2.ent | 176 ++ .../resources/xjc/medline/dtd/isomfrk.ent | 107 + .../resources/xjc/medline/dtd/isomopf.ent | 81 + .../resources/xjc/medline/dtd/isomscr.ent | 107 + src/main/resources/xjc/medline/dtd/isonum.ent | 131 + src/main/resources/xjc/medline/dtd/isopub.ent | 140 ++ .../resources/xjc/medline/dtd/isotech.ent | 216 ++ src/main/resources/xjc/medline/dtd/math.ent | 329 +++ .../xjc/medline/dtd/mathml-in-pubmed.mod | 151 ++ .../resources/xjc/medline/dtd/mathml2-3.dtd | 19 + .../xjc/medline/dtd/mathml2-qname-1.mod | 1 + .../resources/xjc/medline/dtd/mathml2.dtd | 17 + .../xjc/medline/dtd/mathml3-qname.mod | 295 +++ .../xjc/medline/dtd/mathml3-qname1.mod | 294 +++ .../resources/xjc/medline/dtd/mathml3.dtd | 1632 +++++++++++++ .../resources/xjc/medline/dtd/mathmlsetup.ent | 191 ++ .../resources/xjc/medline/dtd/mmlalias.ent | 564 +++++ .../resources/xjc/medline/dtd/mmlextra.ent | 122 + .../resources/xjc/medline/dtd/modules.ent | 417 ++++ .../resources/xjc/medline/dtd/predefined.ent | 43 + .../xjc/medline/dtd/pubmed_190101.dtd | 478 ++++ 58 files changed, 10814 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/repository/CrawlTask.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/repository/TaskStatus.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/representation/CSLStyleAdapter.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryAdapter.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonSerializer.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/Root.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/base/Accumulation.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/base/Libraries.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/model/BibEntryDTO.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/model/CrawlStatus.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/model/Library.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/model/NewLibraryDTO.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java create mode 100644 src/main/java/org/jabref/logic/shared/restserver/rest/slr/Studies.java create mode 100755 src/main/resources/xjc/medline/dtd/htmlmathml-f.ent create mode 100755 src/main/resources/xjc/medline/dtd/isoamsa.ent create mode 100755 src/main/resources/xjc/medline/dtd/isoamsb.ent create mode 100755 src/main/resources/xjc/medline/dtd/isoamsc.ent create mode 100755 src/main/resources/xjc/medline/dtd/isoamsn.ent create mode 100755 src/main/resources/xjc/medline/dtd/isoamso.ent create mode 100755 src/main/resources/xjc/medline/dtd/isoamsr.ent create mode 100755 src/main/resources/xjc/medline/dtd/isobox.ent create mode 100755 src/main/resources/xjc/medline/dtd/isocyr1.ent create mode 100755 src/main/resources/xjc/medline/dtd/isocyr2.ent create mode 100755 src/main/resources/xjc/medline/dtd/isodia.ent create mode 100755 src/main/resources/xjc/medline/dtd/isogrk3.ent create mode 100755 src/main/resources/xjc/medline/dtd/isolat1.ent create mode 100755 src/main/resources/xjc/medline/dtd/isolat2.ent create mode 100755 src/main/resources/xjc/medline/dtd/isomfrk.ent create mode 100755 src/main/resources/xjc/medline/dtd/isomopf.ent create mode 100755 src/main/resources/xjc/medline/dtd/isomscr.ent create mode 100755 src/main/resources/xjc/medline/dtd/isonum.ent create mode 100755 src/main/resources/xjc/medline/dtd/isopub.ent create mode 100755 src/main/resources/xjc/medline/dtd/isotech.ent create mode 100644 src/main/resources/xjc/medline/dtd/math.ent create mode 100644 src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod create mode 100755 src/main/resources/xjc/medline/dtd/mathml2-3.dtd create mode 100644 src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod create mode 100755 src/main/resources/xjc/medline/dtd/mathml2.dtd create mode 100755 src/main/resources/xjc/medline/dtd/mathml3-qname.mod create mode 100644 src/main/resources/xjc/medline/dtd/mathml3-qname1.mod create mode 100755 src/main/resources/xjc/medline/dtd/mathml3.dtd create mode 100644 src/main/resources/xjc/medline/dtd/mathmlsetup.ent create mode 100644 src/main/resources/xjc/medline/dtd/mmlalias.ent create mode 100644 src/main/resources/xjc/medline/dtd/mmlextra.ent create mode 100644 src/main/resources/xjc/medline/dtd/modules.ent create mode 100755 src/main/resources/xjc/medline/dtd/predefined.ent create mode 100644 src/main/resources/xjc/medline/dtd/pubmed_190101.dtd diff --git a/build.gradle b/build.gradle index 3510a5e6fa5..a2f8a2c3cba 100644 --- a/build.gradle +++ b/build.gradle @@ -181,12 +181,12 @@ dependencies { implementation "org.tinylog:tinylog-api:2.5.0" implementation "org.tinylog:slf4j-tinylog:2.5.0" implementation "org.tinylog:tinylog-impl:2.5.0" - implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' // 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' + implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.0.0' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index c05e10bda2b..a9ccf1ffedf 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -116,6 +116,7 @@ requires net.harawata.appdirs; requires org.eclipse.jgit; + requires jakarta.ws.rs; uses org.eclipse.jgit.transport.SshSessionFactory; uses org.eclipse.jgit.lib.GpgSigner; } diff --git a/src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig b/src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig new file mode 100644 index 00000000000..ec227d3957a --- /dev/null +++ b/src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig @@ -0,0 +1,133 @@ +package org.jabref.logic.pdf.search.indexing; + +import java.util.List; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.jabref.gui.util.BackgroundTask; +import org.jabref.gui.util.DefaultTaskExecutor; +import org.jabref.gui.util.TaskExecutor; +import org.jabref.logic.l10n.Localization; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.LinkedFile; + +/** + * Wrapper around {@link PdfIndexer} to execute all operations in the background. + */ +public class IndexingTaskManager extends BackgroundTask { + + private final Queue taskQueue = new ConcurrentLinkedQueue<>(); + private TaskExecutor taskExecutor; + private int numOfIndexedFiles = 0; + + private final Object lock = new Object(); + private boolean isRunning = false; + private boolean isBlockingNewTasks = false; + + public IndexingTaskManager(TaskExecutor taskExecutor) { + this.taskExecutor = taskExecutor; + showToUser(true); + willBeRecoveredAutomatically(true); + DefaultTaskExecutor.runInJavaFXThread(() -> { + this.updateProgress(1, 1); + this.titleProperty().set(Localization.lang("Indexing pdf files")); + }); + } + + @Override + protected Void call() throws Exception { + synchronized (lock) { + isRunning = true; + } + updateProgress(); + while (!taskQueue.isEmpty() && !isCanceled()) { + taskQueue.poll().run(); + numOfIndexedFiles++; + updateProgress(); + } + synchronized (lock) { + isRunning = false; + } + return null; + } + + private void updateProgress() { + DefaultTaskExecutor.runInJavaFXThread(() -> { + updateMessage(Localization.lang("%0 of %1 linked files added to the index", numOfIndexedFiles, numOfIndexedFiles + taskQueue.size())); + updateProgress(numOfIndexedFiles, numOfIndexedFiles + taskQueue.size()); + }); + } + + private void enqueueTask(Runnable indexingTask) { + if (!isBlockingNewTasks) { + taskQueue.add(indexingTask); + // What if already running? + synchronized (lock) { + if (!isRunning) { + isRunning = true; + this.executeWith(taskExecutor); + showToUser(false); + } + } + } + } + + public AutoCloseable blockNewTasks() { + synchronized (lock) { + isBlockingNewTasks = true; + } + return () -> { + synchronized (lock) { + isBlockingNewTasks = false; + } + }; + } + + public void createIndex(PdfIndexer indexer) { + enqueueTask(() -> indexer.createIndex()); + } + + public void updateIndex(PdfIndexer indexer, BibDatabaseContext databaseContext) { + Set pathsToRemove = indexer.getListOfFilePaths(); + for (BibEntry entry : databaseContext.getEntries()) { + for (LinkedFile file : entry.getFiles()) { + System.out.println("Adding file " + file.getLink()); + enqueueTask(() -> indexer.addToIndex(entry, file, databaseContext)); + pathsToRemove.remove(file.getLink()); + } + } + for (String pathToRemove : pathsToRemove) { +<<<<<<< HEAD +======= + System.out.println("Removing file " + pathToRemove); +>>>>>>> 972bac7252 (Cleanup index when opening a library) + enqueueTask(() -> indexer.removeFromIndex(pathToRemove)); + } + } + + public void addToIndex(PdfIndexer indexer, BibEntry entry, BibDatabaseContext databaseContext) { + enqueueTask(() -> addToIndex(indexer, entry, entry.getFiles(), databaseContext)); + } + + public void addToIndex(PdfIndexer indexer, BibEntry entry, List linkedFiles, BibDatabaseContext databaseContext) { + for (LinkedFile file : linkedFiles) { + enqueueTask(() -> indexer.addToIndex(entry, file, databaseContext)); + } + } + + public void removeFromIndex(PdfIndexer indexer, BibEntry entry, List linkedFiles) { + for (LinkedFile file : linkedFiles) { + enqueueTask(() -> indexer.removeFromIndex(file.getLink())); + } + } + + public void removeFromIndex(PdfIndexer indexer, BibEntry entry) { + enqueueTask(() -> removeFromIndex(indexer, entry, entry.getFiles())); + } + + public void updateDatabaseName(String name) { + DefaultTaskExecutor.runInJavaFXThread(() -> this.titleProperty().set(Localization.lang("Indexing for %0", name))); + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java b/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java new file mode 100644 index 00000000000..98d768ae50f --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java @@ -0,0 +1,47 @@ +package org.jabref.logic.shared.restserver.core.properties; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Properties; + +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 final Properties serverProperties; + + private ServerPropertyService() { + serverProperties = loadProperties(); + } + + 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 with a new directory for the library + */ + private Properties loadProperties() { + Properties properties = new Properties(); + if (!((System.getenv("LIBRARY_WORKSPACE") == null) || System.getenv("LIBRARY_WORKSPACE").isBlank())) { + LOGGER.info("Environment Variable found, using defined directory: {}", System.getenv("LIBRARY_WORKSPACE")); + properties.setProperty("workingDirectory", System.getenv("LIBRARY_WORKSPACE")); + } else { + LOGGER.info("Working directory was not found in either the properties or the environment variables, falling back to default location: {}", System.getProperty("user.home") + "/planqk-library"); + properties.setProperty("workingDirectory", System.getProperty("user.home") + "/planqk-library"); + } + return properties; + } + + public Path getWorkingDirectory() { + return Paths.get(serverProperties.getProperty("workingDirectory")); + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/CrawlTask.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/CrawlTask.java new file mode 100644 index 00000000000..6aafd545b37 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/CrawlTask.java @@ -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; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java new file mode 100644 index 00000000000..4e3a90c3a79 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java @@ -0,0 +1,200 @@ +package org.jabref.logic.shared.restserver.core.repository; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.jabref.gui.Globals; +import org.jabref.logic.database.DatabaseMerger; +import org.jabref.logic.exporter.AtomicFileWriter; +import org.jabref.logic.exporter.BibWriter; +import org.jabref.logic.exporter.BibtexDatabaseWriter; +import org.jabref.logic.exporter.SavePreferences; +import org.jabref.logic.importer.OpenDatabase; +import org.jabref.logic.shared.restserver.rest.model.NewLibraryDTO; +import org.jabref.logic.util.OS; +import org.jabref.model.database.BibDatabase; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.util.DummyFileUpdateMonitor; +import org.jabref.model.util.FileUpdateMonitor; +import org.jabref.preferences.GeneralPreferences; +import org.jabref.preferences.JabRefPreferences; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LibraryService { + + private static final Map instances = new HashMap<>(); + private static final Logger LOGGER = LoggerFactory.getLogger(LibraryService.class); + private final Path workingDirectory; + + private LibraryService(Path workingDirectory) { + this.workingDirectory = workingDirectory; + if (Files.notExists(workingDirectory)) { + try { + Files.createDirectories(workingDirectory); + } catch (IOException e) { + LOGGER.error("Could not create working directory.", e); + System.exit(1); + } + } + } + + public static LibraryService getInstance(Path workingDirectory) { + return instances.computeIfAbsent(workingDirectory, LibraryService::new); + } + + public List getLibraryNames() throws IOException { + return Files.list(workingDirectory) // Alternatively walk(Path start, int depth) for recursive aggregation + .filter(file -> !Files.isDirectory(file)) + .map(Path::getFileName) + .map(Path::toString) + .filter(file -> file.endsWith(".bib")) + .collect(Collectors.toList()); + } + + public void createLibrary(NewLibraryDTO newLibraryConfiguration) throws IOException { + Files.createFile(getLibraryPath(newLibraryConfiguration.getLibraryName())); + } + + public Boolean deleteLibrary(String libraryName) throws IOException { + return Files.deleteIfExists(getLibraryPath(libraryName)); + } + + public boolean libraryExists(String libraryName) { + return Files.exists(getLibraryPath(libraryName)); + } + + public List getLibraryEntries(String libraryName) throws IOException { + Path libraryPath = getLibraryPath(libraryName); + if (!Files.exists(libraryPath)) { + throw new FileNotFoundException(); + } + // We do not need any update monitoring + return new ArrayList<>(OpenDatabase.loadDatabase(libraryPath, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) + .getDatabase() + .getEntries()); + } + + public Optional getLibraryEntryMatchingCiteKey(String libraryName, String citeKey) throws IOException { + Path libraryPath = getLibraryPath(libraryName); + if (!Files.exists(libraryPath)) { + throw new FileNotFoundException(); + } + + // Note that this might lead to issues if multiple entries have the same cite key! + return OpenDatabase.loadDatabase(libraryPath, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) + .getDatabase() + .getEntryByCitationKey(citeKey); + } + + public synchronized void addEntryToLibrary(String libraryName, BibEntry newEntry) throws IOException { + // Enforce that a citation key is provided and that is is not part of the library already. + if (newEntry.getCitationKey().isEmpty()) { + throw new IllegalArgumentException("Entry does not contain a citation key"); + } + Path libraryPath = getLibraryPath(libraryName); + BibDatabaseContext context; + if (!Files.exists(libraryPath)) { + throw new FileNotFoundException(); + } else { + context = OpenDatabase.loadDatabase(libraryPath, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) + .getDatabaseContext(); + } + // Required to get serialized + newEntry.setChanged(true); + if (this.citationKeyAlreadyExists(libraryName, newEntry.getCitationKey().get())) { + throw new IllegalArgumentException("Library already contains an entry with that citation key."); + } + context.getDatabase().insertEntry(newEntry); + GeneralPreferences generalPreferences = JabRefPreferences.getInstance().getGeneralPreferences(); + SavePreferences savePreferences = JabRefPreferences.getInstance().getSavePreferences(); + + try (AtomicFileWriter fileWriter = new AtomicFileWriter(libraryPath, context.getMetaData().getEncoding().orElse(StandardCharsets.UTF_8), savePreferences.shouldMakeBackup())) { + BibWriter writer = new BibWriter(fileWriter, OS.NEWLINE); + BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(writer, JabRefPreferences.getInstance().getGeneralPreferences(), savePreferences, new BibEntryTypesManager()); + databaseWriter.saveDatabase(context); + } + } + + public synchronized void updateEntry(String libraryName, String citeKey, BibEntry updatedEntry) throws IOException { + // Enforce that a citation key is provided and that is is not part of the library already. + if (updatedEntry.getCitationKey().isEmpty()) { + throw new IllegalArgumentException("Entry does not contain a citation key"); + } + this.deleteEntryByCiteKey(libraryName, citeKey); + updatedEntry.setChanged(true); + this.addEntryToLibrary(libraryName, updatedEntry); + } + + public synchronized boolean deleteEntryByCiteKey(String libraryName, String citeKey) throws IOException { + Path libraryPath = getLibraryPath(libraryName); + BibDatabaseContext context; + if (!Files.exists(libraryPath)) { + return false; + } else { + context = OpenDatabase.loadDatabase(libraryPath, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) + .getDatabaseContext(); + } + Optional entry = context.getDatabase().getEntryByCitationKey(citeKey); + if (entry.isEmpty()) { + return false; + } + + context.getDatabase().removeEntry(entry.get()); + GeneralPreferences generalPreferences = JabRefPreferences.getInstance().getGeneralPreferences(); + SavePreferences savePreferences = JabRefPreferences.getInstance().getSavePreferences(); + + try (AtomicFileWriter fileWriter = new AtomicFileWriter(libraryPath, context.getMetaData().getEncoding().orElse(StandardCharsets.UTF_8), savePreferences.shouldMakeBackup())) { + BibWriter writer = new BibWriter(fileWriter, OS.NEWLINE); + BibtexDatabaseWriter databaseWriter = new BibtexDatabaseWriter(writer, generalPreferences, savePreferences, new BibEntryTypesManager()); + databaseWriter.saveDatabase(context); + return true; + } + } + + public List getAllEntries() throws IOException { + List libraryNames = getLibraryNames(); + BibDatabase result = new BibDatabase(); + DatabaseMerger merger = new DatabaseMerger(JabRefPreferences.getInstance().getImportFormatPreferences().getKeywordSeparator()); + FileUpdateMonitor dummy = new DummyFileUpdateMonitor(); + libraryNames.stream() + .map(this::getLibraryPath) + .map(path -> { + try { + return OpenDatabase.loadDatabase(path, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()).getDatabase(); + } catch (IOException e) { + // Just return an empty database, a.k.a if opening fails, ignore it + return new BibDatabase(); + } + }) + .forEach(database -> merger.merge(result, database)); + return new ArrayList<>(result.getEntries()); + } + + private boolean citationKeyAlreadyExists(String libraryName, String citationKey) throws IOException { + return this.getLibraryEntryMatchingCiteKey(libraryName, citationKey).isPresent(); + } + + private Path getLibraryPath(String libraryName) { + libraryName = addBibExtensionIfMissing(libraryName); + LOGGER.info("Resolved path: {}", workingDirectory.resolve(libraryName)); + // For now make assumption that the directory is flat: + return workingDirectory.resolve(libraryName); + } + + private String addBibExtensionIfMissing(String libraryName) { + return libraryName.endsWith(".bib") ? libraryName : libraryName + ".bib"; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java new file mode 100644 index 00000000000..bed077969c4 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java @@ -0,0 +1,154 @@ +package org.jabref.logic.shared.restserver.core.repository; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.FileSystemAlreadyExistsException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.jabref.gui.Globals; +import org.jabref.logic.crawler.Crawler; +import org.jabref.logic.crawler.StudyYamlParser; +import org.jabref.logic.git.GitHandler; +import org.jabref.logic.git.SlrGitHandler; +import org.jabref.logic.importer.ParseException; +import org.jabref.model.entry.BibEntryTypesManager; +import org.jabref.model.study.Study; +import org.jabref.model.util.DummyFileUpdateMonitor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StudyService { + private static final Map instances = new HashMap<>(); + private static final Logger LOGGER = LoggerFactory.getLogger(StudyService.class); + // Contains all running tasks, + private final Map runningCrawls = new HashMap<>(); + private final Path studiesDirectory; + + /** + * Returns a study service instance for the selected working directory + * + * @param workingDirectory the path under which the studies can be found in the studies directory + */ + private StudyService(Path workingDirectory) { + this.studiesDirectory = workingDirectory.resolve("studies"); + if (Files.notExists(studiesDirectory)) { + try { + LOGGER.info(studiesDirectory.toString()); + Files.createDirectories(studiesDirectory); + Map env = new HashMap<>(); + env.put("create", "true"); + try { + FileSystems.newFileSystem(GitHandler.class.getResource("git.gitignore").toURI(), env); + } catch (IOException | URISyntaxException e) { + LOGGER.error("Setting up filesystem failed", e); + } catch (FileSystemAlreadyExistsException e) { + LOGGER.info("Filesystem already exists"); + } + } catch (IOException e) { + LOGGER.error("Could not create working directory.", e); + System.exit(1); + } + } + } + + public static synchronized StudyService getInstance(Path workingDirectory) { + return instances.computeIfAbsent(workingDirectory, StudyService::new); + } + + /** + * Each study is managed as a directory within the study directory + * + * @return A list of the currently existing studies + */ + public List getStudyNames() throws IOException { + return Files.list(studiesDirectory) // Alternatively walk(Path start, int depth) for recursive aggregation + .filter(Files::isDirectory) + .map(Path::getFileName) + .map(Path::toString) + .collect(Collectors.toList()); + } + + public synchronized void createStudy(Study study) throws IOException { + Files.createDirectories(studiesDirectory.resolve(Paths.get(study.getTitle()))); + StudyYamlParser parser = new StudyYamlParser(); + parser.writeStudyYamlFile(study, studiesDirectory.resolve(Paths.get(study.getTitle(), "study.yml"))); + } + + public boolean deleteStudy(String studyName) throws IOException { + Path study = studiesDirectory.resolve(Paths.get(studyName)); + if (Files.notExists(study)) { + return false; + } + + Files.walk(study) + .sorted(Comparator.reverseOrder()) + .forEach(t -> { + try { + Files.delete(t); + } catch (IOException e) { + LOGGER.error("Error deleting dir", e); + } + }); + return true; + } + + public boolean studyExists(String studyName) { + return Files.exists(getStudyPath(studyName)); + } + + /** + * Starts a crawl for a specific study + * + * @throws ParseException Occurs if the study definition file is malformed + */ + public synchronized void startCrawl(String studyName) throws IOException, ParseException { + if (runningCrawls.containsKey(studyName)) { + return; + } + Path studyDirectory = studiesDirectory.resolve(Paths.get(studyName)); + + + CrawlTask crawl = new CrawlTask(new Crawler(studyDirectory, + new SlrGitHandler(studyDirectory), + Globals.prefs.getGeneralPreferences(), + Globals.prefs.getImportFormatPreferences(), + Globals.prefs.getImporterPreferences(), + Globals.prefs.getSavePreferences(), + new BibEntryTypesManager(), + new DummyFileUpdateMonitor())); + runningCrawls.put(studyName, crawl); + new Thread(crawl).start(); + } + + /** + * Checks whether there is a crawl running for the specified study. + * Removes crawls that are finished or failed. + */ + public Boolean isCrawlRunning(String studyName) { + if (!runningCrawls.containsKey(studyName)) { + return false; + } + if (runningCrawls.get(studyName).getStatus() == TaskStatus.RUNNING) { + return true; + } + runningCrawls.remove(studyName); + return false; + } + + public Path getStudyPath(String studyName) { + return studiesDirectory.resolve(Paths.get(studyName)); + } + + public Study getStudyDefinition(String studyName) throws IOException { + StudyYamlParser parser = new StudyYamlParser(); + return parser.parseStudyYamlFile(studiesDirectory.resolve(Paths.get(studyName, "study.yml"))); + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/TaskStatus.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/TaskStatus.java new file mode 100644 index 00000000000..e2fc52f94a1 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/TaskStatus.java @@ -0,0 +1,7 @@ +package org.jabref.logic.shared.restserver.core.repository; + +public enum TaskStatus { + RUNNING, + DONE, + FAILED +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/representation/CSLStyleAdapter.java b/src/main/java/org/jabref/logic/shared/restserver/core/representation/CSLStyleAdapter.java new file mode 100644 index 00000000000..09702de0a5c --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/representation/CSLStyleAdapter.java @@ -0,0 +1,91 @@ +package org.jabref.logic.shared.restserver.core.representation; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.FileSystemAlreadyExistsException; +import java.nio.file.FileSystems; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.jabref.logic.citationstyle.CitationStyle; +import org.jabref.logic.citationstyle.CitationStyleGenerator; +import org.jabref.logic.citationstyle.CitationStyleOutputFormat; +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.BibEntryTypesManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CSLStyleAdapter { + private static final Logger LOGGER = LoggerFactory.getLogger(CSLStyleAdapter.class); + private static final String STYLES_ROOT = "/csl-styles"; + private static CSLStyleAdapter instance; + + private final Map namesToStyles = new HashMap<>(); + + static { + // Setup file system + Map env = new HashMap<>(); + env.put("create", "true"); + try { + FileSystems.newFileSystem(CitationStyle.class.getResource(STYLES_ROOT).toURI(), env); + } catch (IOException | URISyntaxException e) { + LOGGER.error("Setting up filesystem failed", e); + } catch (FileSystemAlreadyExistsException e) { + LOGGER.info("Filesystem already exists"); + } + } + + private CSLStyleAdapter() throws URISyntaxException, IOException { + registerAvailableCitationStyles(); + } + + public static CSLStyleAdapter getInstance() throws URISyntaxException, IOException { + if (instance == null) { + instance = new CSLStyleAdapter(); + } + return instance; + } + + protected static void resetStyles() { + instance = null; + } + + /** + * @param entry Entry to be returned in the expected style + * @param style Expects a style from the list of styles returned by getRegisteredStyles() + * @return A styled Entry in HTML, if the style is not available use default style + */ + public String generateCitation(BibEntry entry, String style) { + return CitationStyleGenerator.generateCitation(entry, namesToStyles.getOrDefault(style, CitationStyle.getDefault()).getSource(), CitationStyleOutputFormat.HTML, new BibDatabaseContext(), new BibEntryTypesManager()); + } + + /** + * @param entry Entry to be returned in the expected style + * @param style Expects a style from the list of styles returned by getRegisteredStyles() + * @return A styled Entry in HTML, if the style is not available use default style + */ + public String generatePlainCitation(BibEntry entry, String style) { + return CitationStyleGenerator.generateCitation(entry, namesToStyles.getOrDefault(style, CitationStyle.getDefault()).getSource(), CitationStyleOutputFormat.TEXT, new BibDatabaseContext(), new BibEntryTypesManager()); + } + + public List getRegisteredStyles() { + return new ArrayList<>(namesToStyles.keySet()); + } + + private void registerAvailableCitationStyles() { + List styles = CitationStyle.discoverCitationStyles(); + namesToStyles.putAll(styles.stream().collect(Collectors.toMap(CitationStyle::getTitle, citationStyle -> citationStyle))); + } + + public CitationStyle registerCitationStyleFromFile(String citationStyleFile) throws IOException { + CitationStyle style = CitationStyle.createCitationStyleFromFile(citationStyleFile).orElseThrow(FileNotFoundException::new); + namesToStyles.putIfAbsent(style.getTitle(), style); + return style; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryAdapter.java b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryAdapter.java new file mode 100644 index 00000000000..c263bb56dea --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryAdapter.java @@ -0,0 +1,113 @@ +package org.jabref.logic.shared.restserver.core.serialization; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.jabref.logic.TypedBibEntry; +import org.jabref.model.database.BibDatabaseMode; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.Field; +import org.jabref.model.entry.field.IEEEField; +import org.jabref.model.entry.field.InternalField; +import org.jabref.model.entry.field.SpecialField; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.field.UnknownField; +import org.jabref.model.entry.types.StandardEntryType; + +import com.google.gson.TypeAdapter; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +/** + * Used to convert a bibentry object between POJO and JSON + */ +public class BibEntryAdapter extends TypeAdapter { + + private static final String JSON_TYPE = "entrytype"; + private static final String JSON_KEY = "citekey"; + + @Override + public void write(JsonWriter writer, BibEntry entry) throws IOException { + if (entry == null) { + writer.nullValue(); + return; + } + writer.beginObject(); + writer.name(JSON_TYPE).value(new TypedBibEntry(entry, BibDatabaseMode.BIBTEX).getTypeForDisplay()); + writer.name(JSON_KEY).value(entry.getCitationKey().orElse("")); + + // Grab field entries and place in map + Map mapFieldToValue = new HashMap<>(); + // determine sorted fields -- all fields lower case + SortedSet sortedFields = new TreeSet<>(); + for (Map.Entry field : entry.getFieldMap().entrySet()) { + Field fieldName = field.getKey(); + String fieldValue = field.getValue(); + // JabRef stores the key in the field KEY_FIELD, which must not be serialized + if (!fieldName.equals(InternalField.KEY_FIELD)) { + String lowerCaseFieldName = fieldName.getName().toLowerCase(Locale.US); + sortedFields.add(lowerCaseFieldName); + mapFieldToValue.put(lowerCaseFieldName, fieldValue); + } + } + + // Add to writer + for (String fieldName : sortedFields) { + writer.name(fieldName).value(String.valueOf(mapFieldToValue.get(fieldName)).replaceAll("\\r\\n", "\n")); + } + writer.endObject(); + } + + @Override + public BibEntry read(JsonReader in) throws IOException { + // Create new entry + BibEntry deserializedEntry = new BibEntry(); + in.beginObject(); + while (in.hasNext()) { + String field = in.nextName(); + switch (field) { + case "citekey": + deserializedEntry.withCitationKey(in.nextString()); + break; + case "entrytype": + deserializedEntry.setType(StandardEntryType.valueOf(in.nextString())); + break; + default: + // We cannot apply an optional of Field here as e.g. Optional cannot be assigned to Optional + Optional parsedField = Arrays.stream(StandardField.values()) + .filter(e -> e.name().equalsIgnoreCase(field)) + .findAny(); + if (parsedField.isPresent()) { + deserializedEntry.withField(parsedField.get(), in.nextString()); + break; + } + + Optional parsedIEEEField = Arrays.stream(IEEEField.values()) + .filter(e -> e.name().equalsIgnoreCase(field)) + .findAny(); + if (parsedIEEEField.isPresent()) { + deserializedEntry.withField(parsedIEEEField.get(), in.nextString()); + break; + } + Optional parsedSpecialField = Arrays.stream(SpecialField.values()) + .filter(e -> e.name().equalsIgnoreCase(field)) + .findAny(); + if (parsedSpecialField.isPresent()) { + deserializedEntry.withField(parsedSpecialField.get(), in.nextString()); + break; + } + UnknownField unknownField = new UnknownField(field); + deserializedEntry.withField(unknownField, in.nextString()); + } + } + deserializedEntry.setChanged(true); + in.endObject(); + return deserializedEntry; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java new file mode 100644 index 00000000000..a693e839ccd --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java @@ -0,0 +1,78 @@ +package org.jabref.logic.shared.restserver.core.serialization; + + +import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Optional; + +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.IEEEField; +import org.jabref.model.entry.field.SpecialField; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.field.UnknownField; +import org.jabref.model.entry.types.StandardEntryType; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BibEntryJacksonDeserializer extends JsonDeserializer { + private final Logger LOGGER = LoggerFactory.getLogger(BibEntryJacksonDeserializer.class); + + @Override + public BibEntry deserialize(JsonParser in, DeserializationContext ctxt) throws IOException { + BibEntry deserializedEntry = new BibEntry(); + ObjectMapper mapper = new ObjectMapper(); + try { + JsonNode node = mapper.readTree(in); + assert node.isObject(); + for (Iterator it = node.fieldNames(); it.hasNext(); ) { + String field = it.next(); + switch (field) { + case "citekey": + deserializedEntry.withCitationKey(node.get(field).asText()); + break; + case "entrytype": + deserializedEntry.setType(StandardEntryType.valueOf(node.get(field).asText())); + break; + default: + // We cannot apply an optional of Field here as e.g. Optional cannot be assigned to Optional + Optional parsedField = Arrays.stream(StandardField.values()) + .filter(e -> e.name().equalsIgnoreCase(field)) + .findAny(); + if (parsedField.isPresent()) { + deserializedEntry.withField(parsedField.get(), node.get(field).asText()); + break; + } + + Optional parsedIEEEField = Arrays.stream(IEEEField.values()) + .filter(e -> e.name().equalsIgnoreCase(field)) + .findAny(); + if (parsedIEEEField.isPresent()) { + deserializedEntry.withField(parsedIEEEField.get(), node.get(field).asText()); + break; + } + Optional parsedSpecialField = Arrays.stream(SpecialField.values()) + .filter(e -> e.name().equalsIgnoreCase(field)) + .findAny(); + if (parsedSpecialField.isPresent()) { + deserializedEntry.withField(parsedSpecialField.get(), node.get(field).asText()); + break; + } + UnknownField unknownField = new UnknownField(field); + deserializedEntry.withField(unknownField, node.get(field).asText()); + } + } + deserializedEntry.setChanged(true); + return deserializedEntry; + } catch (IOException ex) { + LOGGER.error("Deserialization failed", ex); + throw ex; + } + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonSerializer.java b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonSerializer.java new file mode 100644 index 00000000000..642148d0fb7 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonSerializer.java @@ -0,0 +1,63 @@ +package org.jabref.logic.shared.restserver.core.serialization; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import org.jabref.logic.TypedBibEntry; +import org.jabref.model.database.BibDatabaseMode; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.Field; +import org.jabref.model.entry.field.InternalField; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BibEntryJacksonSerializer extends StdSerializer { + + private static final String JSON_TYPE = "entrytype"; + private static final String JSON_KEY = "citekey"; + private final Logger LOGGER = LoggerFactory.getLogger(BibEntryJacksonSerializer.class); + + public BibEntryJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize(BibEntry entry, JsonGenerator writer, SerializerProvider provider) throws IOException { + if (entry == null) { + writer.writeNull(); + return; + } + writer.writeStartObject(); + writer.writeStringField(JSON_TYPE, new TypedBibEntry(entry, BibDatabaseMode.BIBTEX).getTypeForDisplay()); + writer.writeStringField(JSON_KEY, entry.getCitationKey().orElse("")); + + // Grab field entries and place in map + Map mapFieldToValue = new HashMap<>(); + // determine sorted fields -- all fields lower case + SortedSet sortedFields = new TreeSet<>(); + for (Map.Entry field : entry.getFieldMap().entrySet()) { + Field fieldName = field.getKey(); + String fieldValue = field.getValue(); + // JabRef stores the key in the field KEY_FIELD, which must not be serialized + if (!fieldName.equals(InternalField.KEY_FIELD)) { + String lowerCaseFieldName = fieldName.getName().toLowerCase(Locale.US); + sortedFields.add(lowerCaseFieldName); + mapFieldToValue.put(lowerCaseFieldName, fieldValue); + } + } + + // Add to writer + for (String fieldName : sortedFields) { + writer.writeStringField(fieldName, String.valueOf(mapFieldToValue.get(fieldName)).replaceAll("\\r\\n", "\n")); + } + writer.writeEndObject(); + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java new file mode 100644 index 00000000000..cea87c2e40c --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java @@ -0,0 +1,141 @@ +package org.jabref.logic.shared.restserver.core.serialization; + +import java.util.Arrays; +import java.util.Optional; + +import org.jabref.logic.shared.restserver.rest.model.BibEntryDTO; +import org.jabref.model.entry.BibEntry; +import org.jabref.model.entry.field.StandardField; +import org.jabref.model.entry.types.EntryType; +import org.jabref.model.entry.types.IEEETranEntryType; +import org.jabref.model.entry.types.StandardEntryType; +import org.jabref.model.entry.types.UnknownEntryType; + + + +public class BibEntryMapper { + + /** + * Maps the relevant standard fields of the complete entry into a DTO + * Note: This step is lossy. The BibEntryDTO contains way less information than the BibEntry. + */ + public static BibEntryDTO map(BibEntry entry) { + BibEntryDTO mappedEntry = new BibEntryDTO(); + mappedEntry.entryType = entry.getType().getName(); + entry.getCitationKey().ifPresent(s -> mappedEntry.citationKey = s); + entry.getField(StandardField.ADDRESS).ifPresent(s -> mappedEntry.address = s); + entry.getField(StandardField.AUTHOR).ifPresent(s -> mappedEntry.author = s); + entry.getField(StandardField.BOOKTITLE).ifPresent(s -> mappedEntry.booktitle = s); + entry.getField(StandardField.CHAPTER).ifPresent(s -> mappedEntry.chapter = s); + entry.getField(StandardField.EDITION).ifPresent(s -> mappedEntry.edition = s); + entry.getField(StandardField.EDITOR).ifPresent(s -> mappedEntry.editor = s); + entry.getField(StandardField.HOWPUBLISHED).ifPresent(s -> mappedEntry.howpublished = s); + entry.getField(StandardField.INSTITUTION).ifPresent(s -> mappedEntry.institution = s); + entry.getField(StandardField.JOURNAL).ifPresent(s -> mappedEntry.journal = s); + entry.getField(StandardField.MONTH).ifPresent(s -> mappedEntry.month = s); + entry.getField(StandardField.NOTE).ifPresent(s -> mappedEntry.note = s); + entry.getField(StandardField.NUMBER).ifPresent(s -> mappedEntry.number = s); + entry.getField(StandardField.ORGANIZATION).ifPresent(s -> mappedEntry.organization = s); + entry.getField(StandardField.PAGES).ifPresent(s -> mappedEntry.pages = s); + entry.getField(StandardField.PUBLISHER).ifPresent(s -> mappedEntry.publisher = s); + entry.getField(StandardField.SCHOOL).ifPresent(s -> mappedEntry.school = s); + entry.getField(StandardField.SERIES).ifPresent(s -> mappedEntry.series = s); + entry.getField(StandardField.TITLE).ifPresent(s -> mappedEntry.title = s); + entry.getField(StandardField.VOLUME).ifPresent(s -> mappedEntry.volume = s); + entry.getField(StandardField.YEAR).ifPresent(s -> mappedEntry.year = s); + entry.getField(StandardField.DATE).ifPresent(s -> mappedEntry.date = s); + return mappedEntry; + } + + /** + * Maps the BibEntryDTO into a BibEntry with the fields provided by the DTO mapped into the BibEntry + * Note that the Information provided by the DTO cannot be used to reconstruct + * a BibEntry that was previously mapped using the map method above. + */ + public static BibEntry map(BibEntryDTO entry) { + if((entry.entryType == null) || entry.entryType.isBlank()) { + throw new IllegalArgumentException("Entry has to have an entry type"); + } + if ((entry.citationKey == null) || entry.citationKey.isBlank()) { + throw new IllegalArgumentException("Entry has to have a citation key"); + } + BibEntry mappedEntry = new BibEntry(getEntryType(entry.entryType)); + mappedEntry.withCitationKey(entry.citationKey); + if ((entry.address != null) && !entry.address.isBlank()) { + mappedEntry.withField(StandardField.ADDRESS, entry.address); + } + if ((entry.author != null) && !entry.author.isBlank()) { + mappedEntry.withField(StandardField.AUTHOR, entry.author); + } + if ((entry.booktitle != null) && !entry.booktitle.isBlank()) { + mappedEntry.withField(StandardField.BOOKTITLE, entry.booktitle); + } + if ((entry.chapter != null) && !entry.chapter.isBlank()) { + mappedEntry.withField(StandardField.CHAPTER, entry.chapter); + } + if ((entry.edition != null) && !entry.edition.isBlank()) { + mappedEntry.withField(StandardField.EDITION, entry.edition); + } + if ((entry.editor != null) && !entry.editor.isBlank()) { + mappedEntry.withField(StandardField.EDITOR, entry.editor); + } + if ((entry.howpublished != null) && !entry.howpublished.isBlank()) { + mappedEntry.withField(StandardField.HOWPUBLISHED, entry.howpublished); + } + if ((entry.institution != null) && !entry.institution.isBlank()) { + mappedEntry.withField(StandardField.INSTITUTION, entry.institution); + } + if ((entry.journal != null) && !entry.journal.isBlank()) { + mappedEntry.withField(StandardField.JOURNAL, entry.journal); + } + if ((entry.month != null) && !entry.month.isBlank()) { + mappedEntry.withField(StandardField.MONTH, entry.month); + } + if ((entry.note != null) && !entry.note.isBlank()) { + mappedEntry.withField(StandardField.NOTE, entry.note); + } + if ((entry.number != null) && !entry.number.isBlank()) { + mappedEntry.withField(StandardField.NUMBER, entry.number); + } + if ((entry.organization != null) && !entry.organization.isBlank()) { + mappedEntry .withField(StandardField.ORGANIZATION, entry.organization); + } + if ((entry.pages != null) && !entry.pages.isBlank()) { + mappedEntry.withField(StandardField.PAGES, entry.pages); + } + if ((entry.publisher != null) && !entry.publisher.isBlank()) { + mappedEntry.withField(StandardField.PUBLISHER, entry.publisher); + } + if ((entry.school != null) && !entry.school.isBlank()) { + mappedEntry.withField(StandardField.SCHOOL, entry.school); + } + if ((entry.series != null) && !entry.series.isBlank()) { + mappedEntry.withField(StandardField.SERIES, entry.series); + } + if ((entry.title != null) && !entry.title.isBlank()) { + mappedEntry.withField(StandardField.TITLE, entry.title); + } + if ((entry.volume != null) && !entry.volume.isBlank()) { + mappedEntry.withField(StandardField.VOLUME, entry.volume); + } + if ((entry.year != null) && !entry.year.isBlank()) { + mappedEntry.withField(StandardField.YEAR, entry.year); + } + if ((entry.date != null) && !entry.date.isBlank()) { + mappedEntry.withField(StandardField.DATE, entry.date); + } + return mappedEntry; + } + + private static EntryType getEntryType(String entryTypeAsString) { + Optional standardEntryType = Arrays.stream(StandardEntryType.values()).filter(entryType -> entryType.getName().equals(entryTypeAsString)).findFirst(); + if (standardEntryType.isPresent()) { + return standardEntryType.get(); + } + Optional ieeeEntryType = Arrays.stream(IEEETranEntryType.values()).filter(entryType ->entryType.getName().equals(entryTypeAsString)).findFirst(); + if (ieeeEntryType.isPresent()) { + return ieeeEntryType.get(); + } + return new UnknownEntryType(entryTypeAsString); + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java new file mode 100644 index 00000000000..3e0e8d97c8e --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java @@ -0,0 +1,16 @@ +package org.jabref.logic.shared.restserver.rest; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +@Path("/") +public class Root { + + @GET + @Produces(MediaType.TEXT_HTML) + public String getText() { + return "

Server runs

"; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/base/Accumulation.java b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Accumulation.java new file mode 100644 index 00000000000..9ef9821af2b --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Accumulation.java @@ -0,0 +1,40 @@ +package org.jabref.logic.shared.restserver.rest.base; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; + +import org.jabref.logic.shared.restserver.core.properties.ServerPropertyService; +import org.jabref.logic.shared.restserver.core.repository.LibraryService; +import org.jabref.logic.shared.restserver.core.serialization.BibEntryMapper; +import org.jabref.logic.shared.restserver.rest.model.Library; +import org.jabref.model.entry.BibEntry; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("all") +public class Accumulation { + private static final Logger LOGGER = LoggerFactory.getLogger(Accumulation.class); + private final LibraryService libraryService; + + public Accumulation() { + libraryService = LibraryService.getInstance(ServerPropertyService.getInstance().getWorkingDirectory()); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Library getAllEntries() throws IOException { + try { + List entries = libraryService.getAllEntries(); + return new Library(entries.parallelStream().map(BibEntryMapper::map).collect(Collectors.toList())); + } catch (IOException e) { + LOGGER.error("Error accumulating all entries.", e); + throw e; + } + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/base/Libraries.java b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Libraries.java new file mode 100644 index 00000000000..e67e007cca9 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Libraries.java @@ -0,0 +1,58 @@ +package org.jabref.logic.shared.restserver.rest.base; + +import java.io.IOException; +import java.util.List; + +import org.jabref.logic.shared.restserver.core.properties.ServerPropertyService; +import org.jabref.logic.shared.restserver.core.repository.LibraryService; +import org.jabref.logic.shared.restserver.rest.model.NewLibraryDTO; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("libraries") +public class Libraries { + private final LibraryService libraryService; + private final Logger LOGGER = LoggerFactory.getLogger(Libraries.class); + + public Libraries() { + libraryService = LibraryService.getInstance(ServerPropertyService.getInstance().getWorkingDirectory()); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getLibraryNames() throws IOException { + try { + return libraryService.getLibraryNames(); + } catch (IOException e) { + LOGGER.error("Error retrieving library names.", e); + throw e; + } + } + + @POST + @Consumes({MediaType.APPLICATION_JSON}) + public Response createNewLibrary(NewLibraryDTO newLibraryConfiguration) throws IOException { + if (libraryService.libraryExists(newLibraryConfiguration.getLibraryName())) { + return Response.status(Response.Status.CONFLICT) + .entity("The given library name is taken.") + .build(); + } + libraryService.createLibrary(newLibraryConfiguration); + return Response.ok() + .build(); + } + + @Path("{libraryName}") + public Library getLibraryResource(@PathParam("libraryName") String libraryName) { + return new Library(libraryName); + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java new file mode 100644 index 00000000000..029dbddc810 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java @@ -0,0 +1,120 @@ +package org.jabref.logic.shared.restserver.rest.base; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.jabref.logic.shared.restserver.core.properties.ServerPropertyService; +import org.jabref.logic.shared.restserver.core.repository.LibraryService; +import org.jabref.logic.shared.restserver.core.representation.CSLStyleAdapter; +import org.jabref.logic.shared.restserver.core.serialization.BibEntryMapper; +import org.jabref.logic.shared.restserver.rest.model.BibEntryDTO; +import org.jabref.model.entry.BibEntry; +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.NotFoundException; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Library { + + private static final Logger LOGGER = LoggerFactory.getLogger(Library.class); + private final LibraryService libraryService; + private final String libraryName; + + public Library(String libraryName) { + this.libraryName = libraryName; + libraryService = LibraryService.getInstance(ServerPropertyService.getInstance().getWorkingDirectory()); + } + + public Library(java.nio.file.Path directory, String libraryName) { + this.libraryName = libraryName; + libraryService = LibraryService.getInstance(directory); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public org.jabref.logic.shared.restserver.rest.model.Library getLibraryEntries() throws IOException { + List entries = libraryService.getLibraryEntries(libraryName); + return new org.jabref.logic.shared.restserver.rest.model.Library(entries.parallelStream().map(BibEntryMapper::map).collect(Collectors.toList())); + } + + @GET + @Path("styles") + @Produces(MediaType.APPLICATION_JSON) + public List getCSLStyles() throws IOException, URISyntaxException { + return CSLStyleAdapter.getInstance().getRegisteredStyles(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + public void addEntryToLibrary(BibEntryDTO bibEntry) throws IOException { + libraryService.addEntryToLibrary(libraryName, BibEntryMapper.map(bibEntry)); + } + + @DELETE + public Response deleteLibrary() throws IOException { + if (libraryService.deleteLibrary(libraryName)) { + return Response.ok().build(); + } else { + return Response.status(Response.Status.NOT_FOUND) + .build(); + } + } + + @GET + @Path("{citeKey}") + @Produces(MediaType.APPLICATION_JSON) + public BibEntryDTO getBibEntryMatchingCiteKey(@PathParam("citeKey") String citeKey) throws IOException { + Optional entry = libraryService.getLibraryEntryMatchingCiteKey(libraryName, citeKey); + if (entry.isPresent()) { + return BibEntryMapper.map(entry.get()); + } else { + throw new NotFoundException(); + } + } + + @GET + @Path("{citeKey}/{cslStyle}") + @Produces(MediaType.TEXT_HTML) + public String getBibEntryMatchingCiteKey(@PathParam("citeKey") String citeKey, @PathParam("cslStyle") String cslStyle) throws IOException, URISyntaxException { + Optional entry = libraryService.getLibraryEntryMatchingCiteKey(libraryName, citeKey); + if (entry.isPresent()) { + return CSLStyleAdapter.getInstance().generateCitation(entry.get(), cslStyle); + } else { + throw new NotFoundException(); + } + } + + @PUT + @Path("{citeKey}") + @Consumes(MediaType.APPLICATION_JSON) + public void updateEntry(@PathParam("citeKey") String citeKey, BibEntryDTO bibEntry) throws IOException { + BibEntry updatedEntry = BibEntryMapper.map(bibEntry); + libraryService.updateEntry(libraryName, citeKey, updatedEntry); + } + + @DELETE + @Path("{citeKey}") + @Produces(MediaType.APPLICATION_JSON) + public Response deleteEntryFromLibrary(@PathParam("citeKey") String citeKey) throws IOException { + boolean foundAndDeleted = libraryService.deleteEntryByCiteKey(libraryName, citeKey); + if (foundAndDeleted) { + return Response.ok() + .build(); + } else { + return Response.status(Response.Status.NOT_FOUND) + .build(); + } + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/model/BibEntryDTO.java b/src/main/java/org/jabref/logic/shared/restserver/rest/model/BibEntryDTO.java new file mode 100644 index 00000000000..d24568a4461 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/model/BibEntryDTO.java @@ -0,0 +1,120 @@ +package org.jabref.logic.shared.restserver.rest.model; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class BibEntryDTO { + public String entryType; + public String citationKey; + + public String address; + public String author; + public String booktitle; + public String chapter; + public String edition; + public String editor; + public String howpublished; + public String institution; + public String journal; + public String month; + public String note; + public String number; + public String organization; + public String pages; + public String publisher; + public String school; + public String series; + public String title; + public String volume; + public String year; + public String date; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if ((o == null) || (getClass() != o.getClass())) { + return false; + } + + BibEntryDTO that = (BibEntryDTO) o; + + if (!entryType.equals(that.entryType)) { + return false; + } + if (!citationKey.equals(that.citationKey)) { + return false; + } + if (address != null ? !address.equals(that.address) : that.address != null) { + return false; + } + if (author != null ? !author.equals(that.author) : that.author != null) { + return false; + } + if (booktitle != null ? !booktitle.equals(that.booktitle) : that.booktitle != null) { + return false; + } + if (chapter != null ? !chapter.equals(that.chapter) : that.chapter != null) { + return false; + } + if (edition != null ? !edition.equals(that.edition) : that.edition != null) { + return false; + } + if (editor != null ? !editor.equals(that.editor) : that.editor != null) { + return false; + } + if (howpublished != null ? !howpublished.equals(that.howpublished) : that.howpublished != null) { + return false; + } + if (institution != null ? !institution.equals(that.institution) : that.institution != null) { + return false; + } + if (journal != null ? !journal.equals(that.journal) : that.journal != null) { + return false; + } + if (month != null ? !month.equals(that.month) : that.month != null) { + return false; + } + if (note != null ? !note.equals(that.note) : that.note != null) { + return false; + } + if (number != null ? !number.equals(that.number) : that.number != null) { + return false; + } + if (organization != null ? !organization.equals(that.organization) : that.organization != null) { + return false; + } + if (pages != null ? !pages.equals(that.pages) : that.pages != null) { + return false; + } + if (publisher != null ? !publisher.equals(that.publisher) : that.publisher != null) { + return false; + } + if (school != null ? !school.equals(that.school) : that.school != null) { + return false; + } + if (series != null ? !series.equals(that.series) : that.series != null) { + return false; + } + if (title != null ? !title.equals(that.title) : that.title != null) { + return false; + } + if (volume != null ? !volume.equals(that.volume) : that.volume != null) { + return false; + } + if (year != null ? !year.equals(that.year) : that.year != null) { + return false; + } + return date != null ? date.equals(that.date) : that.date == null; + } + + @Override + public int hashCode() { + int result = entryType.hashCode(); + result = (31 * result) + citationKey.hashCode(); + return result; + } +} + + diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/model/CrawlStatus.java b/src/main/java/org/jabref/logic/shared/restserver/rest/model/CrawlStatus.java new file mode 100644 index 00000000000..bf94f39c139 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/model/CrawlStatus.java @@ -0,0 +1,9 @@ +package org.jabref.logic.shared.restserver.rest.model; + +public class CrawlStatus { + public boolean currentlyCrawling; + + public CrawlStatus(boolean currentlyCrawling) { + this.currentlyCrawling = currentlyCrawling; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/model/Library.java b/src/main/java/org/jabref/logic/shared/restserver/rest/model/Library.java new file mode 100644 index 00000000000..475c298c79f --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/model/Library.java @@ -0,0 +1,11 @@ +package org.jabref.logic.shared.restserver.rest.model; + +import java.util.List; + +public class Library { + public List bibEntries; + + public Library(List bibEntries) { + this.bibEntries = bibEntries; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/model/NewLibraryDTO.java b/src/main/java/org/jabref/logic/shared/restserver/rest/model/NewLibraryDTO.java new file mode 100644 index 00000000000..b9265ed317c --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/model/NewLibraryDTO.java @@ -0,0 +1,13 @@ +package org.jabref.logic.shared.restserver.rest.model; + +public class NewLibraryDTO { + public String libraryName; + + public String getLibraryName() { + return libraryName; + } + + public void setLibraryName(String libraryName) { + this.libraryName = libraryName; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java b/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java new file mode 100644 index 00000000000..6e60c1ccf66 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java @@ -0,0 +1,15 @@ +package org.jabref.logic.shared.restserver.rest.model; + +import org.jabref.model.study.Study; + +public class StudyDTO { + public Study studyDefinition; + + public StudyDTO() { + + } + + public StudyDTO(Study studyDefinition) { + this.studyDefinition = studyDefinition; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java b/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java new file mode 100644 index 00000000000..2c8a1cd4532 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java @@ -0,0 +1,30 @@ +package org.jabref.logic.shared.restserver.rest.serialization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import jakarta.ws.rs.ext.ContextResolver; +import jakarta.ws.rs.ext.Provider; + +@Provider +public class ObjectMapperContextResolver implements ContextResolver { + + private final ObjectMapper mapper; + + public ObjectMapperContextResolver() { + this.mapper = createObjectMapper(); + } + + @Override + public ObjectMapper getContext(Class type) { + return mapper; + } + + private ObjectMapper createObjectMapper() { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new JavaTimeModule()); + mapper.enable(SerializationFeature.INDENT_OUTPUT); + mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + return mapper; + } +} diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/slr/Studies.java b/src/main/java/org/jabref/logic/shared/restserver/rest/slr/Studies.java new file mode 100644 index 00000000000..99c219fe6d8 --- /dev/null +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/slr/Studies.java @@ -0,0 +1,115 @@ +package org.jabref.logic.shared.restserver.rest.slr; + +import java.io.IOException; +import java.util.List; + +import org.jabref.logic.importer.ParseException; +import org.jabref.logic.shared.restserver.core.properties.ServerPropertyService; +import org.jabref.logic.shared.restserver.core.repository.StudyService; +import org.jabref.logic.shared.restserver.rest.base.Library; +import org.jabref.logic.shared.restserver.rest.model.CrawlStatus; +import org.jabref.logic.shared.restserver.rest.model.StudyDTO; + +import jakarta.ws.rs.Consumes; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.Response; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Path("studies") +public class Studies { + private static final Logger LOGGER = LoggerFactory.getLogger(Studies.class); + private final StudyService studyService; + + public Studies() { + studyService = StudyService.getInstance(ServerPropertyService.getInstance().getWorkingDirectory()); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + public List getStudyNames() throws IOException { + try { + return studyService.getStudyNames(); + } catch (IOException e) { + LOGGER.error("Error retrieving study names.", e); + throw e; + } + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response createStudy(StudyDTO study) throws IOException { + try { + if (studyService.studyExists(study.studyDefinition.getTitle())) { + return Response.status(Response.Status.CONFLICT).entity("The given study name is already in use.").build(); + } + studyService.createStudy(study.studyDefinition); + return Response.ok() + .build(); + } catch (IOException e) { + LOGGER.error("Error retrieving study names.", e); + throw e; + } + } + + // TODO: How can we remove the /results + @Path("{studyName}/results") + public Library getStudyResults(@PathParam("studyName") String studyName) { + return new Library(studyService.getStudyPath(studyName), "studyResult"); + } + + @DELETE + @Path("{studyName}") + public Response deleteStudy(@PathParam("studyName") String studyName) throws IOException { + try { + if (studyService.deleteStudy(studyName)) { + return Response.ok() + .build(); + } + return Response.status(Response.Status.NOT_FOUND) + .build(); + } catch (IOException e) { + LOGGER.error("Error deleting study.", e); + throw e; + } + } + + @POST + // Workaround to fix Tomcat CORS Filter issue with missing media type header: https://stackoverflow.com/questions/59204624/cors-failing-when-post-request-has-no-body-and-server-response-is-a-403-forbidde + @Consumes(MediaType.TEXT_PLAIN) + @Path("{studyName}/crawl") + public void crawlStudy(@PathParam("studyName") String studyName, String unused) throws IOException, ParseException { + try { + // Note: This only starts a new crawl if no other crawl is currently running for this study + studyService.startCrawl(studyName); + } catch (IOException | ParseException e) { + LOGGER.error("Error during crawling", e); + throw e; + } + } + + @GET + @Path("{studyName}/crawl") + @Produces(MediaType.APPLICATION_JSON) + public CrawlStatus getCrawlStatus(@PathParam("studyName") String studyName) { + return new CrawlStatus(studyService.isCrawlRunning(studyName)); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("{studyName}/studyDefinition") + public StudyDTO getStudyDefinition(@PathParam("studyName") String studyName) throws IOException { + try { + return new StudyDTO(studyService.getStudyDefinition(studyName)); + } catch (IOException e) { + LOGGER.error("Error retrieving study definition.", e); + throw e; + } + } +} diff --git a/src/main/resources/xjc/medline/dtd/htmlmathml-f.ent b/src/main/resources/xjc/medline/dtd/htmlmathml-f.ent new file mode 100755 index 00000000000..299a6bb6cba --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/htmlmathml-f.ent @@ -0,0 +1,2164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isoamsa.ent b/src/main/resources/xjc/medline/dtd/isoamsa.ent new file mode 100755 index 00000000000..73c43409222 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isoamsa.ent @@ -0,0 +1,201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isoamsb.ent b/src/main/resources/xjc/medline/dtd/isoamsb.ent new file mode 100755 index 00000000000..0ed2f1d454c --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isoamsb.ent @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isoamsc.ent b/src/main/resources/xjc/medline/dtd/isoamsc.ent new file mode 100755 index 00000000000..2f22ffb98e5 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isoamsc.ent @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isoamsn.ent b/src/main/resources/xjc/medline/dtd/isoamsn.ent new file mode 100755 index 00000000000..7bb9059295c --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isoamsn.ent @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isoamso.ent b/src/main/resources/xjc/medline/dtd/isoamso.ent new file mode 100755 index 00000000000..6c7765f1a23 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isoamso.ent @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isoamsr.ent b/src/main/resources/xjc/medline/dtd/isoamsr.ent new file mode 100755 index 00000000000..80a3ea546d7 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isoamsr.ent @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isobox.ent b/src/main/resources/xjc/medline/dtd/isobox.ent new file mode 100755 index 00000000000..4dd69436c84 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isobox.ent @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isocyr1.ent b/src/main/resources/xjc/medline/dtd/isocyr1.ent new file mode 100755 index 00000000000..6c631e3a9a8 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isocyr1.ent @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isocyr2.ent b/src/main/resources/xjc/medline/dtd/isocyr2.ent new file mode 100755 index 00000000000..c4632cb90b4 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isocyr2.ent @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isodia.ent b/src/main/resources/xjc/medline/dtd/isodia.ent new file mode 100755 index 00000000000..f977c204ae4 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isodia.ent @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isogrk3.ent b/src/main/resources/xjc/medline/dtd/isogrk3.ent new file mode 100755 index 00000000000..cdd734b3403 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isogrk3.ent @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isolat1.ent b/src/main/resources/xjc/medline/dtd/isolat1.ent new file mode 100755 index 00000000000..7ccf900945d --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isolat1.ent @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isolat2.ent b/src/main/resources/xjc/medline/dtd/isolat2.ent new file mode 100755 index 00000000000..786bdc497f2 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isolat2.ent @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isomfrk.ent b/src/main/resources/xjc/medline/dtd/isomfrk.ent new file mode 100755 index 00000000000..97257a91617 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isomfrk.ent @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isomopf.ent b/src/main/resources/xjc/medline/dtd/isomopf.ent new file mode 100755 index 00000000000..2682710fd6b --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isomopf.ent @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isomscr.ent b/src/main/resources/xjc/medline/dtd/isomscr.ent new file mode 100755 index 00000000000..dac95895e23 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isomscr.ent @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isonum.ent b/src/main/resources/xjc/medline/dtd/isonum.ent new file mode 100755 index 00000000000..d0c8043e5f9 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isonum.ent @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isopub.ent b/src/main/resources/xjc/medline/dtd/isopub.ent new file mode 100755 index 00000000000..cca1520e3a1 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isopub.ent @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/isotech.ent b/src/main/resources/xjc/medline/dtd/isotech.ent new file mode 100755 index 00000000000..ac642f8fa42 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/isotech.ent @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/math.ent b/src/main/resources/xjc/medline/dtd/math.ent new file mode 100644 index 00000000000..a501866f0d1 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/math.ent @@ -0,0 +1,329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod b/src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod new file mode 100644 index 00000000000..0eb047c1edd --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + +%ent-mmlextra; + + + +%ent-mmlalias; + + +%isobox; +%isocyr1; +%isocyr2; +%isodia; +%isolat1; +%isolat2; +%isonum; +%isopub; +%isoamsa; +%isoamsb; +%isoamsc; +%isoamsn; +%isoamso; +%isoamsr; +%isogrk3; +%isomfrk; +%isomopf; +%isomscr; +%isotech; + + + + + + + + + + + + + + +%mathml.dtd; diff --git a/src/main/resources/xjc/medline/dtd/mathml2-3.dtd b/src/main/resources/xjc/medline/dtd/mathml2-3.dtd new file mode 100755 index 00000000000..075c34132c3 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml2-3.dtd @@ -0,0 +1,19 @@ + + + + + + + + +%mml3; + + diff --git a/src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod b/src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod new file mode 100644 index 00000000000..92a7621c521 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod @@ -0,0 +1 @@ + ]]> ]]> ]]> \ No newline at end of file diff --git a/src/main/resources/xjc/medline/dtd/mathml2.dtd b/src/main/resources/xjc/medline/dtd/mathml2.dtd new file mode 100755 index 00000000000..e86cf93126c --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml2.dtd @@ -0,0 +1,17 @@ + + + + + + +%mml3; + + diff --git a/src/main/resources/xjc/medline/dtd/mathml3-qname.mod b/src/main/resources/xjc/medline/dtd/mathml3-qname.mod new file mode 100755 index 00000000000..e33a403fa2a --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml3-qname.mod @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + +]]> + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/mathml3-qname1.mod b/src/main/resources/xjc/medline/dtd/mathml3-qname1.mod new file mode 100644 index 00000000000..254bdb24f43 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml3-qname1.mod @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + +]]> + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/mathml3.dtd b/src/main/resources/xjc/medline/dtd/mathml3.dtd new file mode 100755 index 00000000000..4b616dfa130 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathml3.dtd @@ -0,0 +1,1632 @@ + + + + + + + + + +%mathml-qname.mod;]]> + + + +]]> + + + + + + +%htmlmathmlent; + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/mathmlsetup.ent b/src/main/resources/xjc/medline/dtd/mathmlsetup.ent new file mode 100644 index 00000000000..034be16e153 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mathmlsetup.ent @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + +%mathml.dtd; + + + diff --git a/src/main/resources/xjc/medline/dtd/mmlalias.ent b/src/main/resources/xjc/medline/dtd/mmlalias.ent new file mode 100644 index 00000000000..1371af3224c --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mmlalias.ent @@ -0,0 +1,564 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/mmlextra.ent b/src/main/resources/xjc/medline/dtd/mmlextra.ent new file mode 100644 index 00000000000..850c7e7a758 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/mmlextra.ent @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/modules.ent b/src/main/resources/xjc/medline/dtd/modules.ent new file mode 100644 index 00000000000..8458753c470 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/modules.ent @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/predefined.ent b/src/main/resources/xjc/medline/dtd/predefined.ent new file mode 100755 index 00000000000..212dd20aa25 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/predefined.ent @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/src/main/resources/xjc/medline/dtd/pubmed_190101.dtd b/src/main/resources/xjc/medline/dtd/pubmed_190101.dtd new file mode 100644 index 00000000000..a1cd16776c0 --- /dev/null +++ b/src/main/resources/xjc/medline/dtd/pubmed_190101.dtd @@ -0,0 +1,478 @@ + + + + + + + +%mathml-in-pubmed; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From c9518399628ee879a8032dcdbd5c02d9cbd3c66b Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 21 Sep 2022 21:48:42 +0200 Subject: [PATCH 02/28] try with jetty TODO fix javafx inject errors --- build.gradle | 5 ++++- src/main/java/module-info.java | 4 ++++ src/main/java/org/jabref/gui/EntryTypeView.java | 2 +- src/main/java/org/jabref/gui/JabRefMain.java | 13 +++++++++++++ .../jabref/gui/slr/ManageStudyDefinitionView.java | 1 - 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index a2f8a2c3cba..29baa372a8b 100644 --- a/build.gradle +++ b/build.gradle @@ -170,7 +170,6 @@ dependencies { implementation 'com.tobiasdiez:easybind:2.2.1-SNAPSHOT' implementation 'org.fxmisc.flowless:flowless:0.6.10' implementation 'org.fxmisc.richtext:richtextfx:0.10.9' - implementation group: 'org.glassfish.hk2.external', name: 'jakarta.inject', version: '2.6.1' implementation 'com.jfoenix:jfoenix:9.0.10' implementation 'org.controlsfx:controlsfx:11.1.1' @@ -187,6 +186,10 @@ dependencies { 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' implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.0.0' + implementation (group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.0.8') { + exclude module: 'javax.inject' + } + implementation group: 'org.glassfish.hk2.external', name: 'jakarta.inject', version: '2.6.1' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index a9ccf1ffedf..9740458f18c 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -117,6 +117,10 @@ requires org.eclipse.jgit; requires jakarta.ws.rs; + requires jersey.container.jdk.http; + requires jersey.server; + requires jersey.container.jetty.http; + requires org.eclipse.jetty.server; uses org.eclipse.jgit.transport.SshSessionFactory; uses org.eclipse.jgit.lib.GpgSigner; } diff --git a/src/main/java/org/jabref/gui/EntryTypeView.java b/src/main/java/org/jabref/gui/EntryTypeView.java index 7db73467529..5c27930de7a 100644 --- a/src/main/java/org/jabref/gui/EntryTypeView.java +++ b/src/main/java/org/jabref/gui/EntryTypeView.java @@ -5,7 +5,7 @@ import java.util.Optional; import java.util.stream.Collectors; -import javax.inject.Inject; +import jakarta.inject.*; import javafx.application.Platform; import javafx.event.Event; diff --git a/src/main/java/org/jabref/gui/JabRefMain.java b/src/main/java/org/jabref/gui/JabRefMain.java index a9812e591ec..2acf12cf852 100644 --- a/src/main/java/org/jabref/gui/JabRefMain.java +++ b/src/main/java/org/jabref/gui/JabRefMain.java @@ -3,6 +3,7 @@ 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; @@ -28,6 +29,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.migrations.PreferencesMigrations; import org.jabref.model.database.BibDatabaseContext; @@ -35,8 +37,12 @@ import org.jabref.preferences.JabRefPreferences; import org.jabref.preferences.PreferencesService; +import jakarta.ws.rs.core.UriBuilder; import net.harawata.appdirs.AppDirsFactory; import org.apache.commons.cli.ParseException; +import org.eclipse.jetty.server.Server; +import org.glassfish.jersey.jetty.JettyHttpContainerFactory; +import org.glassfish.jersey.server.ResourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tinylog.configuration.Configuration; @@ -51,10 +57,17 @@ public class JabRefMain extends Application { public static void main(String[] args) { addLogToDisk(); + startServer(); arguments = args; launch(arguments); } + private static void startServer() { + URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); + ResourceConfig config = new ResourceConfig(Root.class); + Server server = JettyHttpContainerFactory.createServer(baseUri, config); + } + private static void initializeLogger() { LOGGER = LoggerFactory.getLogger(JabRefMain.class); } diff --git a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java index 5040015fa3d..271dff14eec 100644 --- a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java +++ b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java @@ -5,7 +5,6 @@ import java.util.StringJoiner; import java.util.function.Consumer; -import javax.inject.Inject; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; From 96d917a84d40a95730886273e4f06f8ad64f691a Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 21 Sep 2022 22:10:28 +0200 Subject: [PATCH 03/28] fcking inject ( --- build.gradle | 7 +++++-- src/main/java/module-info.java | 3 +-- src/main/java/org/jabref/gui/EntryTypeView.java | 2 +- .../java/org/jabref/gui/slr/ManageStudyDefinitionView.java | 1 + 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 29baa372a8b..e7801e48ebf 100644 --- a/build.gradle +++ b/build.gradle @@ -161,6 +161,7 @@ dependencies { } implementation group: 'jakarta.annotation', name: 'jakarta.annotation-api', version: '1.3.5' + implementation group: 'org.glassfish.hk2.external', name: 'jakarta.inject', version: '2.6.1' // JavaFX stuff implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1' @@ -187,9 +188,11 @@ dependencies { implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.0.0' implementation (group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.0.8') { - exclude module: 'javax.inject' + exclude group: "jakarta.inject", module: 'jakarta.inject' + } + implementation( group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '11.0.12') { + exclude group: "jakarta.inject", module: 'jakarta.inject' } - implementation group: 'org.glassfish.hk2.external', name: 'jakarta.inject', version: '2.6.1' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 9740458f18c..554d3aca616 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -54,7 +54,7 @@ requires jdk.xml.dom; // Annotations (@PostConstruct) - requires java.annotation; + requires jakarta.annotation; // Microsoft application insights requires applicationinsights.core; @@ -117,7 +117,6 @@ requires org.eclipse.jgit; requires jakarta.ws.rs; - requires jersey.container.jdk.http; requires jersey.server; requires jersey.container.jetty.http; requires org.eclipse.jetty.server; diff --git a/src/main/java/org/jabref/gui/EntryTypeView.java b/src/main/java/org/jabref/gui/EntryTypeView.java index 5c27930de7a..7db73467529 100644 --- a/src/main/java/org/jabref/gui/EntryTypeView.java +++ b/src/main/java/org/jabref/gui/EntryTypeView.java @@ -5,7 +5,7 @@ import java.util.Optional; import java.util.stream.Collectors; -import jakarta.inject.*; +import javax.inject.Inject; import javafx.application.Platform; import javafx.event.Event; diff --git a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java index 271dff14eec..5040015fa3d 100644 --- a/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java +++ b/src/main/java/org/jabref/gui/slr/ManageStudyDefinitionView.java @@ -5,6 +5,7 @@ import java.util.StringJoiner; import java.util.function.Consumer; +import javax.inject.Inject; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleStringProperty; From 4b38bd1fd443139f0e3fb084b4decbdb22674113 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Wed, 21 Sep 2022 23:01:30 +0200 Subject: [PATCH 04/28] Update afterburner to jakarta --- build.gradle | 2 +- lib/afterburner.fx.jar | Bin 18245 -> 17998 bytes .../java/org/jabref/gui/EntryTypeView.java | 2 +- .../jabref/gui/auximport/FromAuxDialog.java | 2 +- .../bibtexextractor/ExtractBibtexDialog.java | 2 +- .../collab/ExternalChangesResolverDialog.java | 2 +- .../CitationKeyPatternPanel.java | 2 +- .../ContentSelectorDialogView.java | 2 +- .../CustomizeEntryTypeDialogView.java | 2 +- .../documentviewer/DocumentViewerView.java | 2 +- .../jabref/gui/edit/ManageKeywordsDialog.java | 2 +- .../jabref/gui/entryeditor/EntryEditor.java | 2 +- .../FileAnnotationTabView.java | 2 +- .../gui/errorconsole/ErrorConsoleView.java | 2 +- .../CreateModifyExporterDialogView.java | 2 +- .../UnlinkedFilesDialogView.java | 2 +- .../org/jabref/gui/help/AboutDialogView.java | 2 +- .../ImportCustomEntryTypesDialog.java | 2 +- .../gui/importer/ImportEntriesDialog.java | 2 +- .../gui/integrity/IntegrityCheckDialog.java | 2 +- .../AbstractPropertiesTabView.java | 2 +- .../LibraryPropertiesView.java | 2 +- .../constants/ConstantsPropertiesView.java | 2 +- .../general/GeneralPropertiesView.java | 2 +- .../keypattern/KeyPatternPropertiesView.java | 2 +- .../saving/SavingPropertiesView.java | 2 +- .../linkedfile/LinkedFileEditDialogView.java | 2 +- .../openoffice/ManageCitationsDialogView.java | 2 +- .../gui/openoffice/StyleSelectDialogView.java | 2 +- .../AbstractPreferenceTabView.java | 2 +- .../preferences/PreferencesDialogView.java | 2 +- .../customexporter/CustomExporterTab.java | 2 +- .../EditExternalFileTypeEntryDialog.java | 2 +- .../journals/JournalAbbreviationsTab.java | 2 +- .../keybindings/KeyBindingsTab.java | 2 +- .../gui/preferences/preview/PreviewTab.java | 2 +- .../protectedterms/ProtectedTermsTab.java | 2 +- .../gui/search/GlobalSearchResultDialog.java | 2 +- .../shared/SharedDatabaseLoginDialogView.java | 2 +- .../gui/slr/ManageStudyDefinitionView.java | 2 +- .../gui/texparser/ParseLatexDialogView.java | 2 +- .../gui/texparser/ParseLatexResultView.java | 2 +- 42 files changed, 41 insertions(+), 41 deletions(-) diff --git a/build.gradle b/build.gradle index 3510a5e6fa5..0add72e5b36 100644 --- a/build.gradle +++ b/build.gradle @@ -161,6 +161,7 @@ dependencies { } implementation group: 'jakarta.annotation', name: 'jakarta.annotation-api', version: '1.3.5' + implementation 'jakarta.inject:jakarta.inject-api:2.0.1' // JavaFX stuff implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1' @@ -170,7 +171,6 @@ dependencies { implementation 'com.tobiasdiez:easybind:2.2.1-SNAPSHOT' implementation 'org.fxmisc.flowless:flowless:0.6.10' implementation 'org.fxmisc.richtext:richtextfx:0.10.9' - implementation group: 'org.glassfish.hk2.external', name: 'jakarta.inject', version: '2.6.1' implementation 'com.jfoenix:jfoenix:9.0.10' implementation 'org.controlsfx:controlsfx:11.1.1' diff --git a/lib/afterburner.fx.jar b/lib/afterburner.fx.jar index 816b3e27f5d649d6b0c44d69c7a2578d0136a473..2e7f8e43e63f143b45d46da8b2d6b46c4680b632 100644 GIT binary patch literal 17998 zcma)k19W83vUV`Z#5O0k?TKyMww+9D+qNclCbn&KY)?4JpZV{*ns?v5x7Iq{r`Ou` z)$Y@$zg@ddRmn+$eu4r5f`9-@Xk<|a`Vf%cFCPN=aYzd*@zaRQh|qxo$^C6$V78}x zoiE4*_QwFsj|1f&2TJqHh>Hj-D$z=d+)9s+NlDVs&cI62P)?3d)hp1?Gi~n!_Cfvu z>`$woKEMoZt^dj3pJQPEXN zMMGN~6LV8%2Yn}VTbus{Lj^ygRsHczNI$MD$A1qa_%~2n2UCLoWegr{ zRx1c-ia>$6WJ&`HcR#T_VR0ezKq!ISK!aM1wm`5Z*p=~%VkqBIUHd@=U6VWP$w&NG z0?w?H)(iyJePaw#CeN+x7w$ujsn&;sn&uyGaC$hh0atnaewDp3B9JNB=5!54{8Toi zhfCSV?xF&QtK?XdErG#rM-B+U%oGsiX2BY!*=x19-kJhq#TV3SCgROFg3Tma$1#&_ zD#k1YLgC;ApIDOQl zOpS5oh~LhG@4?Twd9*^p$Bq)Gv+35NTeUCC*XnHxw8qRWo~eU(6K;T z29-`@;gY#YH(K(xc~CD4LRT`!#Jd7(VW+)HQl{?CpnU<<3`QiD?@aL7{fEl zDAR(|GHH`XWd@j0h3I&d>=cD_N(~-AVMD%o^)xsGH|q+cFhDx=%r6Ru$v9zYtHiQ9 z9T=#s){S2_HiBgJGn5jB#i-d?d-JH$CQ)xRIma|V<5oAX>6qOn@a^5l>q&gYlDGft zO2NoTkT-Q&K-k|m-l;h8h>=5%p%{ncS(7FIwYVlpA}H&N@l~1J27J0}Yd*T~53Jpq1V(z%(isXA4nGo&Yk3;Hsa_#v}O)D#i(x`y-Rea8%f?H!ea$(>NYD}&V(ut zBbOWWH9qmllZ!zdtXJ5MBEU4bSJ0EY%{vLh~+1i!kH;~&Gb!yCC7*@)h`fN0z(vlL>f{us^|JpiWP~J zVen$_5@-`h1X9Eg0rsZDUL+g;3#V}Xx$20?aP@_tBkz5I%&Jy&rZlW04xbF|QW&D5 zWmX519X6+`4iO{TO&@3crFu}`d}*wN&v3agXS)HR9VvRA5xY7JK4GU91}%(oL$8P& zfUTjgLT|eydsYT9j{^M+{Zt(xQ$c2;VIG;*Ky0A~p|?ynRPF8?q#ChzK;rO-mZ_;+ zX*;k@JPk*NzM+;(8a-@@5-4BtF)XNET7cuJnd z5MHTpXKF)vJpDrNatFJ9H#=6HF3)|jqks#`>E^rIPz)`SI1+4AA6!~!`!%sR#ftj^ zNfYJ`V=A8Ds~6LE1<*jmSr(k?LiMH0;4${-O<1ab#a zT%CYmYnv2r7cG0*1hvmCoT0KcFj5JyWG1F+j?gK(ep=A1f1yjD9iX&ts6gadD(+bd znYR=5__BBE5#TZ_C;g;J>#LgZOHBD^6hoK-50aN~8Fpa(F`}oT^qH*I*up#T-kl93%ZByiZ9C;(qRm|o??eEX66 zJ^6WUzy1-tZJkNn(H5Olohq&Vq1kq8^Kks>cB|wEaB8nClmJW$jJlNlociHlaR$I$ zmfg~L2u)_Rfh}++ZB}N(IgrX~cHE&aVKM;1qgIw*Ey({Dj40b9nrsr!oP=>uy)l+R z3O5-}uucRX#vlvNH??)zLPj*#4JU=I0did7Px4^p;h^lp2sN6Mir`)oNHFrvMrm*1 zb@~{y=^YEo#}EeWgoMv_)y12dJ242SJ= zx26jj307HGzvaqQu?yeP+ZdFk4%d$?Wsg!FZakhuk=z6g#-nL1|7w_eWMCmeD`W>= zKsiV+^GPbb=~x;=^X@^~ zgE5yN|Hy_72L_B2{f;sKXK~nMhm%Q5?PToqPi6^P3b%+IqdvG?TC|p=`xY{jiNE$Iw;tppUvO*dpn)Qrc={>2XSj}F1j(JYsDhkZy-YMJBA30^Xe5V)%SoPH&~m6w&+;w_}%8hUKZ$zUhO2*g~fp(tmfr zBXmMEv4fxJqR_I?vtgtkh98X1kEsd8t89;-I9bL?RNP6zCM*G8 z`UP5Nj6=gp>(|0^NVz;oH%_x-vYn_C1>0EBUG^&*<}+6lmodrSX48m^b+D#NvJLhz z2CpSYRz*OZ7GYD@mFy9nvQ=;Rj%9F##u9Sw36WtLmo}`J)*UuT_IsXwbvzLplfbKfu_Ti{ib-kgO~j4#?QD# zYb5j$^fuEQcF{Jfw@xFiVfBdOzv5=!S(X=iV#L#gIj3a!+PxbR^aqeW0B%91yd6;>ZGii>LIKr%`JCw&qD0r^Jvm z?|$;-52OX@HX&D*KzEXm$S{eE5-h+V;O2yGl)a?hbVlFkb`rjUh_KOmC}|hGC#sw za&ptWVD8snVJgDbz^$bW#7#RrgCbH9gRD{4Bj?T(5kuLnYec=eB(hleub{65k@c>P zdJ&((;5)N2vMygt4vKGg51TK67HiW7Fp$iNX(EXR=sWu!TFxC7>UEu60t+w|P|FH+ zOvO+n(x#fU6-K&XR_ht?Wf@0we03BEriqxq2CC0$vU!Dx7lZiZ4%nWiRCPHUNu zG`gKfd?gPzbyKOtFH_OR`?SA|XmPx%nHTPE;a#9r4o{}eYOdWtA7mapqSi*>!qp3p zfrl!(D|={L5@+b<5WEVmJl{fL?|ZF}

iq1#B#)(pjySS}sY#DwyCM;i`4Bcaq(= z!TM0-e#w>Kp{d|(dGA=HZi3;etYtw)Zx)6?PEv zL{+8Yo`tY5he0(YCw(rtKo#R7(#JTH$TQ%4l#p26ke!Xd!l-Kx{?6YeBm|=#lD_9z zZCT90hBb8c6W{cz^2Qp;)+6sSG@ZFK8~<�$iBsUW=m|9YI#`$hyW-A94&Ptr`Z$ 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 literal 18245 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 Date: Wed, 21 Sep 2022 23:17:08 +0200 Subject: [PATCH 05/28] add another fcking injection stuff --- build.gradle | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 26fcedd6d0d..3d85afadcda 100644 --- a/build.gradle +++ b/build.gradle @@ -187,12 +187,9 @@ dependencies { 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' implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.0.0' - implementation (group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.0.8') { - exclude group: "jakarta.inject", module: 'jakarta.inject' - } - implementation( group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '11.0.12') { - exclude group: "jakarta.inject", module: 'jakarta.inject' - } + implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.0.8' + implementation 'org.glassfish.jersey.inject:jersey-hk2:3.0.8' + implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '11.0.12' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' From 7ce929b7228453204c8112adbcd0724ae4943ca7 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 22 Sep 2022 20:23:41 +0200 Subject: [PATCH 06/28] test again --- build.gradle | 7 ++++--- src/main/java/module-info.java | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 3d85afadcda..7bb1779fe52 100644 --- a/build.gradle +++ b/build.gradle @@ -186,9 +186,10 @@ dependencies { // 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' - implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.0.0' - implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.0.8' - implementation 'org.glassfish.jersey.inject:jersey-hk2:3.0.8' + implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' + implementation 'jakarta.validation:jakarta.validation-api:3.0.2' + implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.1.0-M8' + implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.0-M8' implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '11.0.12' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 554d3aca616..62659bb52d2 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -117,6 +117,7 @@ requires org.eclipse.jgit; requires jakarta.ws.rs; + requires jakarta.validation; requires jersey.server; requires jersey.container.jetty.http; requires org.eclipse.jetty.server; From 809a57979190ed6e03813f65fe30ea3d3e7812fd Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 22 Sep 2022 21:03:04 +0200 Subject: [PATCH 07/28] fix afterburner --- lib/afterburner.fx.jar | Bin 17998 -> 17998 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/afterburner.fx.jar b/lib/afterburner.fx.jar index 2e7f8e43e63f143b45d46da8b2d6b46c4680b632..16e780b695b4a45ad34cf214fb8d58373ce63803 100644 GIT binary patch delta 5120 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 delta 5120 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 Date: Thu, 13 Oct 2022 22:42:16 +0200 Subject: [PATCH 08/28] Fix conflicts --- src/main/java/org/jabref/cli/Launcher.java | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 97cece913d5..2e5739e8494 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -54,17 +54,6 @@ public class Launcher { public static void main(String[] args) { addLogToDisk(); - startServer(); - } - - private static void startServer() { - URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); - ResourceConfig config = new ResourceConfig(Root.class); - Server server = JettyHttpContainerFactory.createServer(baseUri, config); - } - - private static void initializeLogger() { - LOGGER = LoggerFactory.getLogger(JabRefMain.class); try { // Init preferences final JabRefPreferences preferences = JabRefPreferences.getInstance(); @@ -99,7 +88,14 @@ private static void initializeLogger() { } catch (Exception ex) { LOGGER.error("Unexpected exception", ex); } ->>>>>>> upstream/main:src/main/java/org/jabref/cli/Launcher.java + + startServer(); + } + + private static void startServer() { + URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); + ResourceConfig config = new ResourceConfig(Root.class); + Server server = JettyHttpContainerFactory.createServer(baseUri, config); } /** From 698e88f5f8e737f3ab45285fcef5fc64a2c949cd Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Fri, 14 Oct 2022 22:17:19 +0200 Subject: [PATCH 09/28] cleanup --- .../indexing/IndexingTaskManager.java.orig | 133 - .../xjc/medline/dtd/htmlmathml-f.ent | 2164 ----------------- .../resources/xjc/medline/dtd/isoamsa.ent | 201 -- .../resources/xjc/medline/dtd/isoamsb.ent | 177 -- .../resources/xjc/medline/dtd/isoamsc.ent | 77 - .../resources/xjc/medline/dtd/isoamsn.ent | 148 -- .../resources/xjc/medline/dtd/isoamso.ent | 107 - .../resources/xjc/medline/dtd/isoamsr.ent | 238 -- src/main/resources/xjc/medline/dtd/isobox.ent | 95 - .../resources/xjc/medline/dtd/isocyr1.ent | 122 - .../resources/xjc/medline/dtd/isocyr2.ent | 81 - src/main/resources/xjc/medline/dtd/isodia.ent | 69 - .../resources/xjc/medline/dtd/isogrk3.ent | 98 - .../resources/xjc/medline/dtd/isolat1.ent | 117 - .../resources/xjc/medline/dtd/isolat2.ent | 176 -- .../resources/xjc/medline/dtd/isomfrk.ent | 107 - .../resources/xjc/medline/dtd/isomopf.ent | 81 - .../resources/xjc/medline/dtd/isomscr.ent | 107 - src/main/resources/xjc/medline/dtd/isonum.ent | 131 - src/main/resources/xjc/medline/dtd/isopub.ent | 140 -- .../resources/xjc/medline/dtd/isotech.ent | 216 -- src/main/resources/xjc/medline/dtd/math.ent | 329 --- .../xjc/medline/dtd/mathml-in-pubmed.mod | 151 -- .../resources/xjc/medline/dtd/mathml2-3.dtd | 19 - .../xjc/medline/dtd/mathml2-qname-1.mod | 1 - .../resources/xjc/medline/dtd/mathml2.dtd | 17 - .../xjc/medline/dtd/mathml3-qname.mod | 295 --- .../xjc/medline/dtd/mathml3-qname1.mod | 294 --- .../resources/xjc/medline/dtd/mathml3.dtd | 1632 ------------- .../resources/xjc/medline/dtd/mathmlsetup.ent | 191 -- .../resources/xjc/medline/dtd/mmlalias.ent | 564 ----- .../resources/xjc/medline/dtd/mmlextra.ent | 122 - .../resources/xjc/medline/dtd/modules.ent | 417 ---- .../resources/xjc/medline/dtd/predefined.ent | 43 - .../xjc/medline/dtd/pubmed_190101.dtd | 478 ---- 35 files changed, 9338 deletions(-) delete mode 100644 src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig delete mode 100755 src/main/resources/xjc/medline/dtd/htmlmathml-f.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isoamsa.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isoamsb.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isoamsc.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isoamsn.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isoamso.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isoamsr.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isobox.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isocyr1.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isocyr2.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isodia.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isogrk3.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isolat1.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isolat2.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isomfrk.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isomopf.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isomscr.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isonum.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isopub.ent delete mode 100755 src/main/resources/xjc/medline/dtd/isotech.ent delete mode 100644 src/main/resources/xjc/medline/dtd/math.ent delete mode 100644 src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod delete mode 100755 src/main/resources/xjc/medline/dtd/mathml2-3.dtd delete mode 100644 src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod delete mode 100755 src/main/resources/xjc/medline/dtd/mathml2.dtd delete mode 100755 src/main/resources/xjc/medline/dtd/mathml3-qname.mod delete mode 100644 src/main/resources/xjc/medline/dtd/mathml3-qname1.mod delete mode 100755 src/main/resources/xjc/medline/dtd/mathml3.dtd delete mode 100644 src/main/resources/xjc/medline/dtd/mathmlsetup.ent delete mode 100644 src/main/resources/xjc/medline/dtd/mmlalias.ent delete mode 100644 src/main/resources/xjc/medline/dtd/mmlextra.ent delete mode 100644 src/main/resources/xjc/medline/dtd/modules.ent delete mode 100755 src/main/resources/xjc/medline/dtd/predefined.ent delete mode 100644 src/main/resources/xjc/medline/dtd/pubmed_190101.dtd diff --git a/src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig b/src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig deleted file mode 100644 index ec227d3957a..00000000000 --- a/src/main/java/org/jabref/logic/pdf/search/indexing/IndexingTaskManager.java.orig +++ /dev/null @@ -1,133 +0,0 @@ -package org.jabref.logic.pdf.search.indexing; - -import java.util.List; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.ConcurrentLinkedQueue; - -import org.jabref.gui.util.BackgroundTask; -import org.jabref.gui.util.DefaultTaskExecutor; -import org.jabref.gui.util.TaskExecutor; -import org.jabref.logic.l10n.Localization; -import org.jabref.model.database.BibDatabaseContext; -import org.jabref.model.entry.BibEntry; -import org.jabref.model.entry.LinkedFile; - -/** - * Wrapper around {@link PdfIndexer} to execute all operations in the background. - */ -public class IndexingTaskManager extends BackgroundTask { - - private final Queue taskQueue = new ConcurrentLinkedQueue<>(); - private TaskExecutor taskExecutor; - private int numOfIndexedFiles = 0; - - private final Object lock = new Object(); - private boolean isRunning = false; - private boolean isBlockingNewTasks = false; - - public IndexingTaskManager(TaskExecutor taskExecutor) { - this.taskExecutor = taskExecutor; - showToUser(true); - willBeRecoveredAutomatically(true); - DefaultTaskExecutor.runInJavaFXThread(() -> { - this.updateProgress(1, 1); - this.titleProperty().set(Localization.lang("Indexing pdf files")); - }); - } - - @Override - protected Void call() throws Exception { - synchronized (lock) { - isRunning = true; - } - updateProgress(); - while (!taskQueue.isEmpty() && !isCanceled()) { - taskQueue.poll().run(); - numOfIndexedFiles++; - updateProgress(); - } - synchronized (lock) { - isRunning = false; - } - return null; - } - - private void updateProgress() { - DefaultTaskExecutor.runInJavaFXThread(() -> { - updateMessage(Localization.lang("%0 of %1 linked files added to the index", numOfIndexedFiles, numOfIndexedFiles + taskQueue.size())); - updateProgress(numOfIndexedFiles, numOfIndexedFiles + taskQueue.size()); - }); - } - - private void enqueueTask(Runnable indexingTask) { - if (!isBlockingNewTasks) { - taskQueue.add(indexingTask); - // What if already running? - synchronized (lock) { - if (!isRunning) { - isRunning = true; - this.executeWith(taskExecutor); - showToUser(false); - } - } - } - } - - public AutoCloseable blockNewTasks() { - synchronized (lock) { - isBlockingNewTasks = true; - } - return () -> { - synchronized (lock) { - isBlockingNewTasks = false; - } - }; - } - - public void createIndex(PdfIndexer indexer) { - enqueueTask(() -> indexer.createIndex()); - } - - public void updateIndex(PdfIndexer indexer, BibDatabaseContext databaseContext) { - Set pathsToRemove = indexer.getListOfFilePaths(); - for (BibEntry entry : databaseContext.getEntries()) { - for (LinkedFile file : entry.getFiles()) { - System.out.println("Adding file " + file.getLink()); - enqueueTask(() -> indexer.addToIndex(entry, file, databaseContext)); - pathsToRemove.remove(file.getLink()); - } - } - for (String pathToRemove : pathsToRemove) { -<<<<<<< HEAD -======= - System.out.println("Removing file " + pathToRemove); ->>>>>>> 972bac7252 (Cleanup index when opening a library) - enqueueTask(() -> indexer.removeFromIndex(pathToRemove)); - } - } - - public void addToIndex(PdfIndexer indexer, BibEntry entry, BibDatabaseContext databaseContext) { - enqueueTask(() -> addToIndex(indexer, entry, entry.getFiles(), databaseContext)); - } - - public void addToIndex(PdfIndexer indexer, BibEntry entry, List linkedFiles, BibDatabaseContext databaseContext) { - for (LinkedFile file : linkedFiles) { - enqueueTask(() -> indexer.addToIndex(entry, file, databaseContext)); - } - } - - public void removeFromIndex(PdfIndexer indexer, BibEntry entry, List linkedFiles) { - for (LinkedFile file : linkedFiles) { - enqueueTask(() -> indexer.removeFromIndex(file.getLink())); - } - } - - public void removeFromIndex(PdfIndexer indexer, BibEntry entry) { - enqueueTask(() -> removeFromIndex(indexer, entry, entry.getFiles())); - } - - public void updateDatabaseName(String name) { - DefaultTaskExecutor.runInJavaFXThread(() -> this.titleProperty().set(Localization.lang("Indexing for %0", name))); - } -} diff --git a/src/main/resources/xjc/medline/dtd/htmlmathml-f.ent b/src/main/resources/xjc/medline/dtd/htmlmathml-f.ent deleted file mode 100755 index 299a6bb6cba..00000000000 --- a/src/main/resources/xjc/medline/dtd/htmlmathml-f.ent +++ /dev/null @@ -1,2164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isoamsa.ent b/src/main/resources/xjc/medline/dtd/isoamsa.ent deleted file mode 100755 index 73c43409222..00000000000 --- a/src/main/resources/xjc/medline/dtd/isoamsa.ent +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isoamsb.ent b/src/main/resources/xjc/medline/dtd/isoamsb.ent deleted file mode 100755 index 0ed2f1d454c..00000000000 --- a/src/main/resources/xjc/medline/dtd/isoamsb.ent +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isoamsc.ent b/src/main/resources/xjc/medline/dtd/isoamsc.ent deleted file mode 100755 index 2f22ffb98e5..00000000000 --- a/src/main/resources/xjc/medline/dtd/isoamsc.ent +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isoamsn.ent b/src/main/resources/xjc/medline/dtd/isoamsn.ent deleted file mode 100755 index 7bb9059295c..00000000000 --- a/src/main/resources/xjc/medline/dtd/isoamsn.ent +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isoamso.ent b/src/main/resources/xjc/medline/dtd/isoamso.ent deleted file mode 100755 index 6c7765f1a23..00000000000 --- a/src/main/resources/xjc/medline/dtd/isoamso.ent +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isoamsr.ent b/src/main/resources/xjc/medline/dtd/isoamsr.ent deleted file mode 100755 index 80a3ea546d7..00000000000 --- a/src/main/resources/xjc/medline/dtd/isoamsr.ent +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isobox.ent b/src/main/resources/xjc/medline/dtd/isobox.ent deleted file mode 100755 index 4dd69436c84..00000000000 --- a/src/main/resources/xjc/medline/dtd/isobox.ent +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isocyr1.ent b/src/main/resources/xjc/medline/dtd/isocyr1.ent deleted file mode 100755 index 6c631e3a9a8..00000000000 --- a/src/main/resources/xjc/medline/dtd/isocyr1.ent +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isocyr2.ent b/src/main/resources/xjc/medline/dtd/isocyr2.ent deleted file mode 100755 index c4632cb90b4..00000000000 --- a/src/main/resources/xjc/medline/dtd/isocyr2.ent +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isodia.ent b/src/main/resources/xjc/medline/dtd/isodia.ent deleted file mode 100755 index f977c204ae4..00000000000 --- a/src/main/resources/xjc/medline/dtd/isodia.ent +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isogrk3.ent b/src/main/resources/xjc/medline/dtd/isogrk3.ent deleted file mode 100755 index cdd734b3403..00000000000 --- a/src/main/resources/xjc/medline/dtd/isogrk3.ent +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isolat1.ent b/src/main/resources/xjc/medline/dtd/isolat1.ent deleted file mode 100755 index 7ccf900945d..00000000000 --- a/src/main/resources/xjc/medline/dtd/isolat1.ent +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isolat2.ent b/src/main/resources/xjc/medline/dtd/isolat2.ent deleted file mode 100755 index 786bdc497f2..00000000000 --- a/src/main/resources/xjc/medline/dtd/isolat2.ent +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isomfrk.ent b/src/main/resources/xjc/medline/dtd/isomfrk.ent deleted file mode 100755 index 97257a91617..00000000000 --- a/src/main/resources/xjc/medline/dtd/isomfrk.ent +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isomopf.ent b/src/main/resources/xjc/medline/dtd/isomopf.ent deleted file mode 100755 index 2682710fd6b..00000000000 --- a/src/main/resources/xjc/medline/dtd/isomopf.ent +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isomscr.ent b/src/main/resources/xjc/medline/dtd/isomscr.ent deleted file mode 100755 index dac95895e23..00000000000 --- a/src/main/resources/xjc/medline/dtd/isomscr.ent +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isonum.ent b/src/main/resources/xjc/medline/dtd/isonum.ent deleted file mode 100755 index d0c8043e5f9..00000000000 --- a/src/main/resources/xjc/medline/dtd/isonum.ent +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isopub.ent b/src/main/resources/xjc/medline/dtd/isopub.ent deleted file mode 100755 index cca1520e3a1..00000000000 --- a/src/main/resources/xjc/medline/dtd/isopub.ent +++ /dev/null @@ -1,140 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/isotech.ent b/src/main/resources/xjc/medline/dtd/isotech.ent deleted file mode 100755 index ac642f8fa42..00000000000 --- a/src/main/resources/xjc/medline/dtd/isotech.ent +++ /dev/null @@ -1,216 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/math.ent b/src/main/resources/xjc/medline/dtd/math.ent deleted file mode 100644 index a501866f0d1..00000000000 --- a/src/main/resources/xjc/medline/dtd/math.ent +++ /dev/null @@ -1,329 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod b/src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod deleted file mode 100644 index 0eb047c1edd..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml-in-pubmed.mod +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - - - - - - - - - - - - - - - - - - -%ent-mmlextra; - - - -%ent-mmlalias; - - -%isobox; -%isocyr1; -%isocyr2; -%isodia; -%isolat1; -%isolat2; -%isonum; -%isopub; -%isoamsa; -%isoamsb; -%isoamsc; -%isoamsn; -%isoamso; -%isoamsr; -%isogrk3; -%isomfrk; -%isomopf; -%isomscr; -%isotech; - - - - - - - - - - - - - - -%mathml.dtd; diff --git a/src/main/resources/xjc/medline/dtd/mathml2-3.dtd b/src/main/resources/xjc/medline/dtd/mathml2-3.dtd deleted file mode 100755 index 075c34132c3..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml2-3.dtd +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - -%mml3; - - diff --git a/src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod b/src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod deleted file mode 100644 index 92a7621c521..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml2-qname-1.mod +++ /dev/null @@ -1 +0,0 @@ - ]]> ]]> ]]> \ No newline at end of file diff --git a/src/main/resources/xjc/medline/dtd/mathml2.dtd b/src/main/resources/xjc/medline/dtd/mathml2.dtd deleted file mode 100755 index e86cf93126c..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml2.dtd +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - -%mml3; - - diff --git a/src/main/resources/xjc/medline/dtd/mathml3-qname.mod b/src/main/resources/xjc/medline/dtd/mathml3-qname.mod deleted file mode 100755 index e33a403fa2a..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml3-qname.mod +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - -]]> - - - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/mathml3-qname1.mod b/src/main/resources/xjc/medline/dtd/mathml3-qname1.mod deleted file mode 100644 index 254bdb24f43..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml3-qname1.mod +++ /dev/null @@ -1,294 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - -]]> - - - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/mathml3.dtd b/src/main/resources/xjc/medline/dtd/mathml3.dtd deleted file mode 100755 index 4b616dfa130..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathml3.dtd +++ /dev/null @@ -1,1632 +0,0 @@ - - - - - - - - - -%mathml-qname.mod;]]> - - - -]]> - - - - - - -%htmlmathmlent; - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/mathmlsetup.ent b/src/main/resources/xjc/medline/dtd/mathmlsetup.ent deleted file mode 100644 index 034be16e153..00000000000 --- a/src/main/resources/xjc/medline/dtd/mathmlsetup.ent +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - - - - - - - - - - -%mathml.dtd; - - - diff --git a/src/main/resources/xjc/medline/dtd/mmlalias.ent b/src/main/resources/xjc/medline/dtd/mmlalias.ent deleted file mode 100644 index 1371af3224c..00000000000 --- a/src/main/resources/xjc/medline/dtd/mmlalias.ent +++ /dev/null @@ -1,564 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/mmlextra.ent b/src/main/resources/xjc/medline/dtd/mmlextra.ent deleted file mode 100644 index 850c7e7a758..00000000000 --- a/src/main/resources/xjc/medline/dtd/mmlextra.ent +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/modules.ent b/src/main/resources/xjc/medline/dtd/modules.ent deleted file mode 100644 index 8458753c470..00000000000 --- a/src/main/resources/xjc/medline/dtd/modules.ent +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/predefined.ent b/src/main/resources/xjc/medline/dtd/predefined.ent deleted file mode 100755 index 212dd20aa25..00000000000 --- a/src/main/resources/xjc/medline/dtd/predefined.ent +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - diff --git a/src/main/resources/xjc/medline/dtd/pubmed_190101.dtd b/src/main/resources/xjc/medline/dtd/pubmed_190101.dtd deleted file mode 100644 index a1cd16776c0..00000000000 --- a/src/main/resources/xjc/medline/dtd/pubmed_190101.dtd +++ /dev/null @@ -1,478 +0,0 @@ - - - - - - - -%mathml-in-pubmed; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From bcca5cca0ed5dfbb2ce20768770096ec0225e619 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Thu, 5 Jan 2023 15:42:53 +0100 Subject: [PATCH 10/28] fix compile errors --- build.gradle | 4 --- src/main/java/module-info.java | 4 --- src/main/java/org/jabref/cli/Launcher.java | 27 +++++++++++++------ .../core/repository/LibraryService.java | 2 +- .../logic/shared/restserver/rest/Root.java | 3 ++- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/build.gradle b/build.gradle index e504924334e..ded11d00c8c 100644 --- a/build.gradle +++ b/build.gradle @@ -188,10 +188,6 @@ dependencies { 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' implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' - implementation 'jakarta.validation:jakarta.validation-api:3.0.2' - implementation group: 'org.glassfish.jersey.containers', name: 'jersey-container-jetty-http', version: '3.1.0-M8' - implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.0-M8' - implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '11.0.12' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 2d9770a0905..48807b1b87b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -119,10 +119,6 @@ requires org.eclipse.jgit; requires jakarta.ws.rs; - requires jakarta.validation; - requires jersey.server; - requires jersey.container.jetty.http; - requires org.eclipse.jetty.server; uses org.eclipse.jgit.transport.SshSessionFactory; uses org.eclipse.jgit.lib.GpgSigner; } diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 95854a0ad3b..94769ad416e 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -30,12 +30,9 @@ import org.jabref.preferences.JabRefPreferences; import org.jabref.preferences.PreferencesService; -import jakarta.ws.rs.core.UriBuilder; +import jakarta.ws.rs.SeBootstrap; import net.harawata.appdirs.AppDirsFactory; import org.apache.commons.cli.ParseException; -import org.eclipse.jetty.server.Server; -import org.glassfish.jersey.jetty.JettyHttpContainerFactory; -import org.glassfish.jersey.server.ResourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tinylog.configuration.Configuration; @@ -79,6 +76,8 @@ public static void main(String[] args) { LOGGER.debug("JabRef shut down after processing command line arguments"); return; } + startServer(); + MainApplication.main(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences, ARGUMENTS); } catch (ParseException e) { @@ -89,13 +88,25 @@ public static void main(String[] args) { LOGGER.error("Unexpected exception", ex); } - startServer(); } private static void startServer() { - URI baseUri = UriBuilder.fromUri("http://localhost/").port(9998).build(); - ResourceConfig config = new ResourceConfig(Root.class); - Server server = JettyHttpContainerFactory.createServer(baseUri, config); + SeBootstrap.start(Root.class).thenAccept(instance -> { + instance.stopOnShutdown(stopResult -> + System.out.printf("Stop result: %s [Native stop result: %s].%n", stopResult, + stopResult.unwrap(Object.class))); + final URI uri = instance.configuration().baseUri(); + System.out.printf("Instance %s running at %s [Native handle: %s].%n", instance, uri, + instance.unwrap(Object.class)); + System.out.println("Send SIGKILL to shutdown."); + }); + + try { + Thread.currentThread().join(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } /** diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java index 4e3a90c3a79..5abd74bb41c 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java @@ -167,7 +167,7 @@ public synchronized boolean deleteEntryByCiteKey(String libraryName, String cite public List getAllEntries() throws IOException { List libraryNames = getLibraryNames(); BibDatabase result = new BibDatabase(); - DatabaseMerger merger = new DatabaseMerger(JabRefPreferences.getInstance().getImportFormatPreferences().getKeywordSeparator()); + DatabaseMerger merger = new DatabaseMerger(JabRefPreferences.getInstance().getBibEntryPreferences().getKeywordSeparator()); FileUpdateMonitor dummy = new DummyFileUpdateMonitor(); libraryNames.stream() .map(this::getLibraryPath) diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java index 3e0e8d97c8e..3691fb63f01 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java @@ -3,10 +3,11 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.MediaType; @Path("/") -public class Root { +public class Root extends Application { @GET @Produces(MediaType.TEXT_HTML) From dd77dce5cf9eb2a22e62ed257c1424bda3647427 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Thu, 5 Jan 2023 20:51:44 +0100 Subject: [PATCH 11/28] Switch to JBOSS RestEasy (and Jackson instead of Glassfish) --- build.gradle | 19 ++++++++++----- src/main/java/module-info.java | 15 ++++++------ src/main/java/org/jabref/cli/Launcher.java | 23 ++++++++----------- .../restserver/rest/model/StudyDTO.java | 1 - .../ObjectMapperContextResolver.java | 2 ++ .../java/org/jabref/cli/LauncherTest.java | 13 +++++++++++ 6 files changed, 46 insertions(+), 27 deletions(-) create mode 100644 src/test/java/org/jabref/cli/LauncherTest.java diff --git a/build.gradle b/build.gradle index ded11d00c8c..18abd997ab5 100644 --- a/build.gradle +++ b/build.gradle @@ -143,9 +143,6 @@ dependencies { implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.4.0.202211300538-r' - implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.1' - implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1' - implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.7' implementation 'org.postgresql:postgresql:42.5.1' @@ -185,9 +182,18 @@ dependencies { implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' // 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' implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' + implementation 'org.jboss.resteasy:resteasy-core:6.2.2.Final' + implementation 'org.jboss.resteasy:resteasy-undertow-cdi:6.2.2.Final' + + // Data mapping + implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1' + implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-jakarta-xmlbind-annotations', version: '2.14.1' + implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1' + // XML mapping, e.g., org.jabref.logic.importer.fileformat.mods + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.14.1' + // JSON mapping + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.1' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' @@ -218,7 +224,8 @@ dependencies { testImplementation "org.hamcrest:hamcrest-library:2.2" checkstyle 'com.puppycrawl.tools:checkstyle:10.6.0' - // xjc needs the runtime as well for the ant task, otherwise it fails + + // xjc needs the runtime for the ant task, otherwise it fails xjc group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '3.0.2' xjc group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 48807b1b87b..e67b3a457c6 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -46,12 +46,16 @@ with org.jabref.gui.logging.GuiWriter, org.jabref.gui.logging.ApplicationInsightsWriter; - // Preferences and XML requires java.prefs; - requires jakarta.xml.bind; - // needs to be loaded here as it's otherwise not found at runtime - requires org.glassfish.jaxb.runtime; + + // XML, YAML, JSON requires jdk.xml.dom; + requires jakarta.xml.bind; + requires com.fasterxml.jackson.databind; + requires com.fasterxml.jackson.dataformat.xml; + requires com.fasterxml.jackson.module.jakarta.xmlbind; + requires com.fasterxml.jackson.dataformat.yaml; + requires com.fasterxml.jackson.datatype.jsr310; // Annotations (@PostConstruct) requires jakarta.annotation; @@ -110,9 +114,6 @@ 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; diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 94769ad416e..e0d9f3336a7 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -45,13 +45,15 @@ * - Start the JavaFX application (if not in cli mode) */ public class Launcher { + // initialized after reading the preferences (which configure log directory, ...) private static Logger LOGGER; - private static String[] ARGUMENTS; 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; @@ -78,8 +80,7 @@ public static void main(String[] args) { } startServer(); - - MainApplication.main(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences, ARGUMENTS); + MainApplication.main(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences, arguments); } catch (ParseException e) { LOGGER.error("Problem parsing arguments", e); JabRefCLI.printUsage(preferences); @@ -90,22 +91,18 @@ public static void main(String[] args) { } - private static void startServer() { + static void startServer() { SeBootstrap.start(Root.class).thenAccept(instance -> { instance.stopOnShutdown(stopResult -> - System.out.printf("Stop result: %s [Native stop result: %s].%n", stopResult, - stopResult.unwrap(Object.class))); - final URI uri = instance.configuration().baseUri(); - System.out.printf("Instance %s running at %s [Native handle: %s].%n", instance, uri, - instance.unwrap(Object.class)); - System.out.println("Send SIGKILL to shutdown."); + 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)); }); try { Thread.currentThread().join(); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + LOGGER.error("could not join on current thread", e); } } diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java b/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java index 6e60c1ccf66..e70fe43ec93 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/model/StudyDTO.java @@ -6,7 +6,6 @@ public class StudyDTO { public Study studyDefinition; public StudyDTO() { - } public StudyDTO(Study studyDefinition) { diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java b/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java index 2c8a1cd4532..809f889ad1f 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule; import jakarta.ws.rs.ext.ContextResolver; import jakarta.ws.rs.ext.Provider; @@ -23,6 +24,7 @@ public ObjectMapper getContext(Class type) { private ObjectMapper createObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); + mapper.registerModule(new JakartaXmlBindAnnotationModule()); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; diff --git a/src/test/java/org/jabref/cli/LauncherTest.java b/src/test/java/org/jabref/cli/LauncherTest.java new file mode 100644 index 00000000000..8803d0f33f3 --- /dev/null +++ b/src/test/java/org/jabref/cli/LauncherTest.java @@ -0,0 +1,13 @@ +package org.jabref.cli; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +class LauncherTest { + + @Test + @Disabled + void startServer() { + Launcher.startServer(); + } +} From 464008794c337b6d13dab575cd81efe86f32679b Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 6 Jan 2023 14:25:46 +0100 Subject: [PATCH 12/28] Switch back to Glassfish for JAXB (instead of Jackson) --- build.gradle | 9 ++++----- src/main/java/module-info.java | 7 +++++-- .../rest/serialization/ObjectMapperContextResolver.java | 2 -- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 18abd997ab5..d6f741f290f 100644 --- a/build.gradle +++ b/build.gradle @@ -181,18 +181,17 @@ dependencies { implementation "org.tinylog:tinylog-impl:2.5.0" implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' - // jakarta.activation is already dependency of glassfish implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' implementation 'org.jboss.resteasy:resteasy-core:6.2.2.Final' implementation 'org.jboss.resteasy:resteasy-undertow-cdi:6.2.2.Final' // Data mapping implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1' - implementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-jakarta-xmlbind-annotations', version: '2.14.1' - implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1' - // XML mapping, e.g., org.jabref.logic.importer.fileformat.mods - implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.14.1' + implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' + // JSON mapping + implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1' + // YML mapping implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.1' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index e67b3a457c6..1830f06047a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -50,10 +50,13 @@ // XML, YAML, JSON requires jdk.xml.dom; + // Enable JAXB using the standard implementation by Glassfish + requires org.glassfish.jaxb.runtime; + // Enable JAXB annotations requires jakarta.xml.bind; + + // Enable YAML and JSON parsing by Jackson requires com.fasterxml.jackson.databind; - requires com.fasterxml.jackson.dataformat.xml; - requires com.fasterxml.jackson.module.jakarta.xmlbind; requires com.fasterxml.jackson.dataformat.yaml; requires com.fasterxml.jackson.datatype.jsr310; diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java b/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java index 809f889ad1f..2c8a1cd4532 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/serialization/ObjectMapperContextResolver.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationModule; import jakarta.ws.rs.ext.ContextResolver; import jakarta.ws.rs.ext.Provider; @@ -24,7 +23,6 @@ public ObjectMapper getContext(Class type) { private ObjectMapper createObjectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); - mapper.registerModule(new JakartaXmlBindAnnotationModule()); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); return mapper; From a6ee546f4d0bb14551323efafa2abc543fcdcea2 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 6 Jan 2023 14:34:49 +0100 Subject: [PATCH 13/28] Switch from Glassfish to Jackson2 for JSON (but keep it for XML) --- build.gradle | 3 +++ src/main/java/module-info.java | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d6f741f290f..cfc2664ff6e 100644 --- a/build.gradle +++ b/build.gradle @@ -187,7 +187,10 @@ dependencies { // Data mapping implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1' + // Data mapping provider for JAXB annotated classes (e.g., MedlineImporter) implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' + // Data mapping provider for POJOs + implementation 'org.jboss.resteasy:resteasy-jackson2-provider:6.2.2.Final' // JSON mapping implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 1830f06047a..ae254e3b1f4 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -50,8 +50,6 @@ // XML, YAML, JSON requires jdk.xml.dom; - // Enable JAXB using the standard implementation by Glassfish - requires org.glassfish.jaxb.runtime; // Enable JAXB annotations requires jakarta.xml.bind; @@ -59,6 +57,10 @@ 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; // Annotations (@PostConstruct) requires jakarta.annotation; From 1b4c30dda019f61040b1a9262a6cea8069892309 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 6 Jan 2023 15:42:08 +0100 Subject: [PATCH 14/28] Remove one dependency --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index cfc2664ff6e..43ff77fbb09 100644 --- a/build.gradle +++ b/build.gradle @@ -182,7 +182,6 @@ dependencies { implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' - implementation 'org.jboss.resteasy:resteasy-core:6.2.2.Final' implementation 'org.jboss.resteasy:resteasy-undertow-cdi:6.2.2.Final' // Data mapping From 1bbb1db9d4ab0d141e2109a1c6c7f06f77aad92f Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 17 Mar 2023 18:07:39 +0100 Subject: [PATCH 15/28] Remove two "nice-to-have" Markdown plugins (strikethrough, tasklist) --- build.gradle | 2 -- src/main/java/module-info.java | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index b161da3cd38..de0a2009e82 100644 --- a/build.gradle +++ b/build.gradle @@ -210,8 +210,6 @@ dependencies { } implementation 'com.vladsch.flexmark:flexmark:0.64.0' - implementation 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.64.0' - implementation 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.64.0' implementation group: 'net.harawata', name: 'appdirs', version: '1.2.1' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 21255fcd29d..7d4c2337436 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -103,10 +103,9 @@ requires com.ibm.icu; requires flexmark; - requires flexmark.ext.gfm.strikethrough; - requires flexmark.ext.gfm.tasklist; requires flexmark.util.ast; requires flexmark.util.data; + requires com.h2database.mvstore; // fulltext search From 5c448de1c24bcfb38993f777f31f58273012ea2c Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 17 Mar 2023 19:29:01 +0100 Subject: [PATCH 16/28] Fix checkstyle --- src/main/java/org/jabref/cli/Launcher.java | 1 - .../shared/restserver/core/repository/LibraryService.java | 6 +++--- .../shared/restserver/core/repository/StudyService.java | 7 +++---- .../core/serialization/BibEntryJacksonDeserializer.java | 1 - .../restserver/core/serialization/BibEntryMapper.java | 6 ++---- .../jabref/logic/shared/restserver/rest/base/Library.java | 1 + 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index e0d9f3336a7..8f690cc0e1c 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -88,7 +88,6 @@ public static void main(String[] args) { } catch (Exception ex) { LOGGER.error("Unexpected exception", ex); } - } static void startServer() { diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java index 5abd74bb41c..f678cf19a1f 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/LibraryService.java @@ -35,7 +35,7 @@ public class LibraryService { - private static final Map instances = new HashMap<>(); + private static final Map INSTANCES = new HashMap<>(); private static final Logger LOGGER = LoggerFactory.getLogger(LibraryService.class); private final Path workingDirectory; @@ -52,7 +52,7 @@ private LibraryService(Path workingDirectory) { } public static LibraryService getInstance(Path workingDirectory) { - return instances.computeIfAbsent(workingDirectory, LibraryService::new); + return INSTANCES.computeIfAbsent(workingDirectory, LibraryService::new); } public List getLibraryNames() throws IOException { @@ -109,7 +109,7 @@ public synchronized void addEntryToLibrary(String libraryName, BibEntry newEntry if (!Files.exists(libraryPath)) { throw new FileNotFoundException(); } else { - context = OpenDatabase.loadDatabase(libraryPath, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) + context = OpenDatabase.loadDatabase(libraryPath, Globals.prefs.getImportFormatPreferences(), Globals.getFileUpdateMonitor()) .getDatabaseContext(); } // Required to get serialized diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java b/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java index bed077969c4..36ec08019b3 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/repository/StudyService.java @@ -22,11 +22,12 @@ import org.jabref.model.entry.BibEntryTypesManager; import org.jabref.model.study.Study; import org.jabref.model.util.DummyFileUpdateMonitor; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class StudyService { - private static final Map instances = new HashMap<>(); + private static final Map INSTANCES = new HashMap<>(); private static final Logger LOGGER = LoggerFactory.getLogger(StudyService.class); // Contains all running tasks, private final Map runningCrawls = new HashMap<>(); @@ -60,7 +61,7 @@ private StudyService(Path workingDirectory) { } public static synchronized StudyService getInstance(Path workingDirectory) { - return instances.computeIfAbsent(workingDirectory, StudyService::new); + return INSTANCES.computeIfAbsent(workingDirectory, StudyService::new); } /** @@ -114,8 +115,6 @@ public synchronized void startCrawl(String studyName) throws IOException, ParseE return; } Path studyDirectory = studiesDirectory.resolve(Paths.get(studyName)); - - CrawlTask crawl = new CrawlTask(new Crawler(studyDirectory, new SlrGitHandler(studyDirectory), Globals.prefs.getGeneralPreferences(), diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java index a693e839ccd..f913c1343ed 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryJacksonDeserializer.java @@ -1,6 +1,5 @@ package org.jabref.logic.shared.restserver.core.serialization; - import java.io.IOException; import java.util.Arrays; import java.util.Iterator; diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java index cea87c2e40c..8478c2c5022 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/serialization/BibEntryMapper.java @@ -11,8 +11,6 @@ import org.jabref.model.entry.types.StandardEntryType; import org.jabref.model.entry.types.UnknownEntryType; - - public class BibEntryMapper { /** @@ -53,7 +51,7 @@ public static BibEntryDTO map(BibEntry entry) { * a BibEntry that was previously mapped using the map method above. */ public static BibEntry map(BibEntryDTO entry) { - if((entry.entryType == null) || entry.entryType.isBlank()) { + if ((entry.entryType == null) || entry.entryType.isBlank()) { throw new IllegalArgumentException("Entry has to have an entry type"); } if ((entry.citationKey == null) || entry.citationKey.isBlank()) { @@ -132,7 +130,7 @@ private static EntryType getEntryType(String entryTypeAsString) { if (standardEntryType.isPresent()) { return standardEntryType.get(); } - Optional ieeeEntryType = Arrays.stream(IEEETranEntryType.values()).filter(entryType ->entryType.getName().equals(entryTypeAsString)).findFirst(); + Optional ieeeEntryType = Arrays.stream(IEEETranEntryType.values()).filter(entryType -> entryType.getName().equals(entryTypeAsString)).findFirst(); if (ieeeEntryType.isPresent()) { return ieeeEntryType.get(); } diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java index 029dbddc810..feabca78770 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/base/Library.java @@ -12,6 +12,7 @@ import org.jabref.logic.shared.restserver.core.serialization.BibEntryMapper; import org.jabref.logic.shared.restserver.rest.model.BibEntryDTO; import org.jabref.model.entry.BibEntry; + import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; import jakarta.ws.rs.GET; From 60952238f98c6f6671a4038b29a20d4a830d3d15 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 17 Mar 2023 19:32:41 +0100 Subject: [PATCH 17/28] Remove duoble dependency entry --- build.gradle | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index de0a2009e82..2667ab47da7 100644 --- a/build.gradle +++ b/build.gradle @@ -143,9 +143,6 @@ dependencies { implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.4.0.202211300538-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' @@ -196,9 +193,9 @@ dependencies { implementation 'org.jboss.resteasy:resteasy-jackson2-provider:6.2.2.Final' // JSON mapping - implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1' + 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.1' + implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.14.2' implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') { exclude module: 'fastparse_2.13' From 82492fda6f90ada38bf6d068d7d6cabd864c39b9 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 17 Mar 2023 20:39:33 +0100 Subject: [PATCH 18/28] Really remove Markdown extension --- .../logic/layout/format/MarkdownFormatter.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/jabref/logic/layout/format/MarkdownFormatter.java b/src/main/java/org/jabref/logic/layout/format/MarkdownFormatter.java index f387dc40224..5aa733c880f 100644 --- a/src/main/java/org/jabref/logic/layout/format/MarkdownFormatter.java +++ b/src/main/java/org/jabref/logic/layout/format/MarkdownFormatter.java @@ -1,16 +1,12 @@ package org.jabref.logic.layout.format; -import java.util.List; import java.util.Objects; import org.jabref.logic.layout.LayoutFormatter; -import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension; -import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension; 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 { @@ -18,15 +14,8 @@ public class MarkdownFormatter implements LayoutFormatter { private final HtmlRenderer renderer; public MarkdownFormatter() { - MutableDataSet options = new MutableDataSet(); - // in case a new extension is added here, the depedency has to be added to build.gradle, too. - options.set(Parser.EXTENSIONS, List.of( - StrikethroughExtension.create(), - TaskListExtension.create() - )); - - parser = Parser.builder(options).build(); - renderer = HtmlRenderer.builder(options).build(); + parser = Parser.builder().build(); + renderer = HtmlRenderer.builder().build(); } @Override From bf659ea861ae0d0b53cf80e1e5d9e22b5977f102 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Fri, 17 Mar 2023 21:03:06 +0100 Subject: [PATCH 19/28] Endless startup... --- build.gradle | 7 ++++--- src/main/java/module-info.java | 5 ++++- src/main/java/org/jabref/cli/Launcher.java | 10 +++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 2667ab47da7..715d17c0f31 100644 --- a/build.gradle +++ b/build.gradle @@ -182,15 +182,16 @@ dependencies { implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' + // JAX-WS implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' - implementation 'org.jboss.resteasy:resteasy-undertow-cdi:6.2.2.Final' + + // http sever + implementation 'org.glassfish.jersey.core:jersey-server:3.1.1' // Data mapping implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1' // Data mapping provider for JAXB annotated classes (e.g., MedlineImporter) implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2' - // Data mapping provider for POJOs - implementation 'org.jboss.resteasy:resteasy-jackson2-provider:6.2.2.Final' // JSON mapping implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.2' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 7d4c2337436..18c6a2ad41f 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -58,10 +58,13 @@ 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; + // requires resteasy.jackson2.provider; // Enable JAXB using the standard implementation by Glassfish requires org.glassfish.jaxb.runtime; + requires jersey.common; + requires jersey.server; + // Annotations (@PostConstruct) requires jakarta.annotation; diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 8f690cc0e1c..6a4c6959ffc 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -33,6 +33,7 @@ import jakarta.ws.rs.SeBootstrap; import net.harawata.appdirs.AppDirsFactory; import org.apache.commons.cli.ParseException; +import org.glassfish.jersey.server.ResourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tinylog.configuration.Configuration; @@ -91,7 +92,14 @@ public static void main(String[] args) { } static void startServer() { - SeBootstrap.start(Root.class).thenAccept(instance -> { + SeBootstrap.Configuration.Builder configBuilder = SeBootstrap.Configuration.builder(); + configBuilder.property(SeBootstrap.Configuration.PROTOCOL, "HTTP") + .property(SeBootstrap.Configuration.HOST, "localhost") + .property(SeBootstrap.Configuration.PORT, 2005); + ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfig.packages(Root.class.getPackageName()); + SeBootstrap.start(resourceConfig, configBuilder.build()).thenAccept(instance -> { +// SeBootstrap.start(Root.class, 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(); From 636873dd064d3e6ecceb85517d25ac5d688ec114 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 18 Mar 2023 00:48:02 +0100 Subject: [PATCH 20/28] Get server to run - Add log if server cannot start - Refine root page --- build.gradle | 18 +++++++---- src/main/java/module-info.java | 4 +++ src/main/java/org/jabref/cli/Launcher.java | 13 ++++---- .../logic/shared/restserver/rest/Root.java | 32 +++++++++++++++++-- .../java/org/jabref/cli/LauncherTest.java | 2 ++ 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 715d17c0f31..4ff7932d690 100644 --- a/build.gradle +++ b/build.gradle @@ -159,7 +159,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' @@ -182,12 +182,6 @@ dependencies { implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' - // JAX-WS - implementation 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' - - // http sever - implementation 'org.glassfish.jersey.core:jersey-server:3.1.1' - // Data mapping implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1' // Data mapping provider for JAXB annotated classes (e.g., MedlineImporter) @@ -198,6 +192,16 @@ dependencies { // 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' + + 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' } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 18c6a2ad41f..26fe5153e83 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -64,6 +64,10 @@ 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; diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 6a4c6959ffc..8e8b4e956ad 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -33,7 +33,6 @@ import jakarta.ws.rs.SeBootstrap; import net.harawata.appdirs.AppDirsFactory; import org.apache.commons.cli.ParseException; -import org.glassfish.jersey.server.ResourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tinylog.configuration.Configuration; @@ -47,7 +46,7 @@ */ public class Launcher { // initialized after reading the preferences (which configure log directory, ...) - private static Logger LOGGER; + static Logger LOGGER; public static void main(String[] args) { addLogToDisk(); @@ -96,15 +95,15 @@ static void startServer() { configBuilder.property(SeBootstrap.Configuration.PROTOCOL, "HTTP") .property(SeBootstrap.Configuration.HOST, "localhost") .property(SeBootstrap.Configuration.PORT, 2005); - ResourceConfig resourceConfig = new ResourceConfig(); - resourceConfig.packages(Root.class.getPackageName()); - SeBootstrap.start(resourceConfig, configBuilder.build()).thenAccept(instance -> { -// SeBootstrap.start(Root.class, configBuilder.build()).thenAccept(instance -> { + 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(); diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java index 3691fb63f01..ff24c9c185b 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java @@ -1,17 +1,45 @@ package org.jabref.logic.shared.restserver.rest; +import java.util.Collections; +import java.util.Set; + +import org.jabref.logic.shared.restserver.rest.base.Accumulation; +import org.jabref.logic.shared.restserver.rest.base.Libraries; +import org.jabref.logic.shared.restserver.rest.base.Library; +import org.jabref.logic.shared.restserver.rest.slr.Studies; + +import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.Application; import jakarta.ws.rs.core.MediaType; -@Path("/") +@ApplicationPath("/") +@Path("") public class Root extends Application { + @Override + public Set> getClasses() { + return Set.of(Root.class, Libraries.class, Library.class, Studies.class, Accumulation.class); + } + @GET @Produces(MediaType.TEXT_HTML) public String getText() { - return "

Server runs

"; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(""" + + + + + """); + stringBuilder.append("

JabRef REST-ful http API

"); + stringBuilder.append("Use a JSON client and navigate to libraries."); + stringBuilder.append(""" + + + """); + return stringBuilder.toString(); } } diff --git a/src/test/java/org/jabref/cli/LauncherTest.java b/src/test/java/org/jabref/cli/LauncherTest.java index 8803d0f33f3..af1c649a511 100644 --- a/src/test/java/org/jabref/cli/LauncherTest.java +++ b/src/test/java/org/jabref/cli/LauncherTest.java @@ -2,12 +2,14 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; class LauncherTest { @Test @Disabled void startServer() { + Launcher.LOGGER = LoggerFactory.getLogger(Launcher.class); Launcher.startServer(); } } From 2f8302b455b54d74fe1b17ce0478af7568efe8a1 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 18 Mar 2023 00:48:24 +0100 Subject: [PATCH 21/28] Make use of JabRefDesktop for default directory --- .../core/properties/ServerPropertyService.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java b/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java index 98d768ae50f..d323e556d64 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java @@ -4,6 +4,9 @@ import java.nio.file.Paths; import java.util.Properties; +import org.jabref.gui.desktop.JabRefDesktop; +import org.jabref.model.strings.StringUtil; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,12 +34,14 @@ public static ServerPropertyService getInstance() { */ private Properties loadProperties() { Properties properties = new Properties(); - if (!((System.getenv("LIBRARY_WORKSPACE") == null) || System.getenv("LIBRARY_WORKSPACE").isBlank())) { - LOGGER.info("Environment Variable found, using defined directory: {}", System.getenv("LIBRARY_WORKSPACE")); - properties.setProperty("workingDirectory", System.getenv("LIBRARY_WORKSPACE")); + String libraryWorkspaceEnvironmentVariable = System.getenv("LIBRARY_WORKSPACE"); + if (!StringUtil.isNullOrEmpty(libraryWorkspaceEnvironmentVariable)) { + LOGGER.info("Environment Variable found, using defined directory: {}", libraryWorkspaceEnvironmentVariable); + properties.setProperty("workingDirectory", libraryWorkspaceEnvironmentVariable); } else { - LOGGER.info("Working directory was not found in either the properties or the environment variables, falling back to default location: {}", System.getProperty("user.home") + "/planqk-library"); - properties.setProperty("workingDirectory", System.getProperty("user.home") + "/planqk-library"); + 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); + properties.setProperty("workingDirectory", fallbackDirectory.toString()); } return properties; } From 1b1fa9dabc7d8fc940f22e7eb69b17d4070241cb Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 18 Mar 2023 00:56:28 +0100 Subject: [PATCH 22/28] Streamline code of ServerPropertyService --- .../properties/ServerPropertyService.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java b/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java index d323e556d64..1bb83195a8f 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java +++ b/src/main/java/org/jabref/logic/shared/restserver/core/properties/ServerPropertyService.java @@ -1,10 +1,9 @@ package org.jabref.logic.shared.restserver.core.properties; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Properties; import org.jabref.gui.desktop.JabRefDesktop; +import org.jabref.gui.desktop.os.NativeDesktop; import org.jabref.model.strings.StringUtil; import org.slf4j.Logger; @@ -13,10 +12,10 @@ public class ServerPropertyService { private static final Logger LOGGER = LoggerFactory.getLogger(ServerPropertyService.class); private static ServerPropertyService instance; - private final Properties serverProperties; + private Path workingDirectory; private ServerPropertyService() { - serverProperties = loadProperties(); + workingDirectory = determineWorkingDirectory(); } public static ServerPropertyService getInstance() { @@ -30,23 +29,21 @@ public static ServerPropertyService getInstance() { * 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 with a new directory for the library + * 2. Default User home (via {@link NativeDesktop#getDefaultFileChooserDirectory()}) with a new directory for the library */ - private Properties loadProperties() { - Properties properties = new Properties(); + private Path determineWorkingDirectory() { String libraryWorkspaceEnvironmentVariable = System.getenv("LIBRARY_WORKSPACE"); if (!StringUtil.isNullOrEmpty(libraryWorkspaceEnvironmentVariable)) { LOGGER.info("Environment Variable found, using defined directory: {}", libraryWorkspaceEnvironmentVariable); - properties.setProperty("workingDirectory", 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); - properties.setProperty("workingDirectory", fallbackDirectory.toString()); + return fallbackDirectory; } - return properties; } public Path getWorkingDirectory() { - return Paths.get(serverProperties.getProperty("workingDirectory")); + return workingDirectory; } } From cf14659363e9fed058a28992bf00a2bf4b349402 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Sat, 18 Mar 2023 01:12:25 +0100 Subject: [PATCH 23/28] Fix checkstyle --- src/main/java/org/jabref/logic/shared/restserver/rest/Root.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java index ff24c9c185b..90d23533bb5 100644 --- a/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java +++ b/src/main/java/org/jabref/logic/shared/restserver/rest/Root.java @@ -1,6 +1,5 @@ package org.jabref.logic.shared.restserver.rest; -import java.util.Collections; import java.util.Set; import org.jabref.logic.shared.restserver.rest.base.Accumulation; From 0c2c30cf7aa7c351d19030116792c85a05982f3d Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 18 Mar 2023 20:03:58 +0100 Subject: [PATCH 24/28] fix starting error --- src/main/java/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 26fe5153e83..14048e0f98a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -71,6 +71,7 @@ // Annotations (@PostConstruct) requires jakarta.annotation; + requires jakarta.validation; // Microsoft application insights requires applicationinsights.core; From 306d7314f83bd6bb487e461ccda793deb165fbc8 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 18 Mar 2023 20:41:16 +0100 Subject: [PATCH 25/28] fix jlink dupliate module --- build.gradle | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 719814fdb0f..6b7b2a1d56a 100644 --- a/build.gradle +++ b/build.gradle @@ -183,9 +183,9 @@ dependencies { implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6' // Data mapping - implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1' + 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: '3.0.2' + 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' @@ -197,7 +197,9 @@ dependencies { // 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' + 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' From a0799b03ebfd1dbc9fc49a36e848a8d4a092e476 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Sat, 18 Mar 2023 20:45:55 +0100 Subject: [PATCH 26/28] run in background thread --- src/main/java/org/jabref/cli/Launcher.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/jabref/cli/Launcher.java b/src/main/java/org/jabref/cli/Launcher.java index 8a95d5e299e..81879e0ffbc 100644 --- a/src/main/java/org/jabref/cli/Launcher.java +++ b/src/main/java/org/jabref/cli/Launcher.java @@ -11,6 +11,7 @@ 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; @@ -79,7 +80,8 @@ public static void main(String[] args) { LOGGER.debug("JabRef shut down after processing command line arguments"); return; } - startServer(); + + JabRefExecutorService.INSTANCE.execute(Launcher::startServer); MainApplication.main(argumentProcessor.getParserResults(), argumentProcessor.isBlank(), preferences, arguments); } catch (ParseException e) { From 3b14255d0fb6d897501ad36a8af5a430d97ac932 Mon Sep 17 00:00:00 2001 From: Siedlerchr Date: Mon, 20 Mar 2023 17:47:32 +0100 Subject: [PATCH 27/28] remove tika --- build.gradle | 2 -- src/main/java/module-info.java | 3 +- .../org/jabref/logic/net/URLDownload.java | 13 +++---- .../org/jabref/logic/util/io/FileUtil.java | 16 ++++----- .../org/jabref/model/util/FileHelper.java | 35 +++---------------- 5 files changed, 21 insertions(+), 48 deletions(-) diff --git a/build.gradle b/build.gradle index ea14e004eed..795c361c5ec 100644 --- a/build.gradle +++ b/build.gradle @@ -125,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' diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 14048e0f98a..cf1e2682e57 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -104,8 +104,7 @@ 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; diff --git a/src/main/java/org/jabref/logic/net/URLDownload.java b/src/main/java/org/jabref/logic/net/URLDownload.java index 08cd53b0c28..275e631b5bf 100644 --- a/src/main/java/org/jabref/logic/net/URLDownload.java +++ b/src/main/java/org/jabref/logic/net/URLDownload.java @@ -111,6 +111,7 @@ public static void bypassSSLVerification() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = {new X509TrustManager() { + @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @@ -204,11 +205,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); @@ -391,8 +392,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 diff --git a/src/main/java/org/jabref/logic/util/io/FileUtil.java b/src/main/java/org/jabref/logic/util/io/FileUtil.java index d670db1dd54..bb804a8cb62 100644 --- a/src/main/java/org/jabref/logic/util/io/FileUtil.java +++ b/src/main/java/org/jabref/logic/util/io/FileUtil.java @@ -132,7 +132,7 @@ public static Optional getUniquePathDirectory(List paths, Path c List uniquePathParts = uniquePathSubstrings(paths); return uniquePathParts.stream() .filter(part -> comparePath.toString().contains(part) - && !part.equals(fileName) && part.contains(File.separator)) + && !part.equals(fileName) && part.contains(File.separator)) .findFirst() .map(part -> part.substring(0, part.lastIndexOf(File.separator))); } @@ -145,9 +145,9 @@ public static Optional getUniquePathDirectory(List paths, Path c */ public static Optional getUniquePathFragment(List paths, Path comparePath) { return uniquePathSubstrings(paths).stream() - .filter(part -> comparePath.toString().contains(part)) - .sorted(Comparator.comparingInt(String::length).reversed()) - .findFirst(); + .filter(part -> comparePath.toString().contains(part)) + .sorted(Comparator.comparingInt(String::length).reversed()) + .findFirst(); } /** @@ -212,7 +212,7 @@ public static boolean copyFile(Path pathToSourceFile, Path pathToDestinationFile try { // Preserve Hard Links with OpenOption defaults included for clarity Files.write(pathToDestinationFile, Files.readAllBytes(pathToSourceFile), - StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); + StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); return true; } catch (IOException e) { LOGGER.error("Copying Files failed.", e); @@ -311,9 +311,9 @@ public static String createDirNameFromPattern(BibDatabase database, BibEntry ent public static Optional find(String filename, Path rootDirectory) { try (Stream pathStream = Files.walk(rootDirectory)) { return pathStream - .filter(Files::isRegularFile) - .filter(f -> f.getFileName().toString().equals(filename)) - .findFirst(); + .filter(Files::isRegularFile) + .filter(f -> f.getFileName().toString().equals(filename)) + .findFirst(); } catch (UncheckedIOException | IOException ex) { LOGGER.error("Error trying to locate the file " + filename + " inside the directory " + rootDirectory); } diff --git a/src/main/java/org/jabref/model/util/FileHelper.java b/src/main/java/org/jabref/model/util/FileHelper.java index fcfe0ce9499..754f898c5ee 100644 --- a/src/main/java/org/jabref/model/util/FileHelper.java +++ b/src/main/java/org/jabref/model/util/FileHelper.java @@ -1,8 +1,6 @@ package org.jabref.model.util; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.nio.file.InvalidPathException; @@ -13,18 +11,11 @@ import java.util.Objects; import java.util.Optional; +import org.jabref.logic.net.URLDownload; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabaseContext; import org.jabref.preferences.FilePreferences; -import org.apache.tika.config.TikaConfig; -import org.apache.tika.detect.Detector; -import org.apache.tika.metadata.Metadata; -import org.apache.tika.metadata.TikaCoreProperties; -import org.apache.tika.mime.MediaType; -import org.apache.tika.mime.MimeType; -import org.apache.tika.mime.MimeTypeException; -import org.apache.tika.parser.AutoDetectParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -68,13 +59,10 @@ public static Optional getFileExtension(Path file) { * @return The extension (without leading dot), trimmed and in lowercase. */ public static Optional getFileExtension(String fileName) { - Metadata metadata = new Metadata(); - metadata.add(TikaCoreProperties.RESOURCE_NAME_KEY, fileName); - if (isUrl(fileName)) { - try (InputStream is = new URL(fileName).openStream()) { - return detectExtension(is, metadata); - } catch (IOException | MimeTypeException e) { + try { + return Optional.of(new URLDownload(fileName).getMimeType()); + } catch (MalformedURLException e) { return Optional.empty(); } } @@ -86,20 +74,7 @@ public static Optional getFileExtension(String fileName) { return Optional.empty(); } - private static Optional detectExtension(InputStream is, Metadata metaData) throws IOException, MimeTypeException { - BufferedInputStream bis = new BufferedInputStream(is); - AutoDetectParser parser = new AutoDetectParser(); - Detector detector = parser.getDetector(); - MediaType mediaType = detector.detect(bis, metaData); - MimeType mimeType = TikaConfig.getDefaultConfig().getMimeRepository().forName(mediaType.toString()); - String extension = mimeType.getExtension(); - if (extension.isEmpty()) { - return Optional.empty(); - } - - return Optional.of(extension.substring(1)); - } /** * Converts a relative filename to an absolute one, if necessary. Returns an empty optional if the file does not From e734892a2783657f0e79384735a297861db5f641 Mon Sep 17 00:00:00 2001 From: Oliver Kopp Date: Mon, 20 Mar 2023 23:46:25 +0100 Subject: [PATCH 28/28] Fix checkstyle --- src/main/java/org/jabref/logic/net/URLDownload.java | 1 - src/main/java/org/jabref/model/util/FileHelper.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/main/java/org/jabref/logic/net/URLDownload.java b/src/main/java/org/jabref/logic/net/URLDownload.java index 275e631b5bf..7a75abd398e 100644 --- a/src/main/java/org/jabref/logic/net/URLDownload.java +++ b/src/main/java/org/jabref/logic/net/URLDownload.java @@ -111,7 +111,6 @@ public static void bypassSSLVerification() { // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = {new X509TrustManager() { - @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } diff --git a/src/main/java/org/jabref/model/util/FileHelper.java b/src/main/java/org/jabref/model/util/FileHelper.java index 754f898c5ee..c1f94e361a9 100644 --- a/src/main/java/org/jabref/model/util/FileHelper.java +++ b/src/main/java/org/jabref/model/util/FileHelper.java @@ -74,8 +74,6 @@ public static Optional getFileExtension(String fileName) { return Optional.empty(); } - - /** * Converts a relative filename to an absolute one, if necessary. Returns an empty optional if the file does not * exist.