Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[WIP] Rhar768/feature/23 rest interface #59

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4b56ca3
Add mindmap node data model
rmoradc Sep 2, 2020
b9dac8b
Add parser class
rmoradc Sep 2, 2020
01c9232
Add mind map edge data model
rmoradc Sep 2, 2020
fea430f
Add model for full mind map
rmoradc Sep 3, 2020
ff565ec
Merge branch 'rmoradc/feature/mindmap-model' into rmoradc/feature/bib…
rmoradc Sep 3, 2020
aab8687
Rename class
rmoradc Sep 3, 2020
2127930
Add logic to parse BibtexString objects to MindMap objects
rmoradc Sep 4, 2020
d809f59
Added entry point for JabMap
rowanh22 Sep 7, 2020
6e1aedf
Initial (non-working) Root Resource
koppor Sep 7, 2020
216f6db
Refactored server creation (working)
rowanh22 Sep 7, 2020
c766fcd
Merge
rowanh22 Sep 10, 2020
243f02c
Basic getting bib entry
rowanh22 Sep 10, 2020
06968d8
Merge branch 'rhar768/feature/23-REST-interface' into rmoradc/feature…
rmoradc Sep 11, 2020
6ef3d1f
Refactor to fit REST setup
rmoradc Sep 11, 2020
5ee4d9a
Updated entries endpoint to return list of bib entries
rowanh22 Sep 11, 2020
30f300a
Update data object models
rmoradc Sep 11, 2020
47400f1
Fix formatting
rmoradc Sep 11, 2020
5809eb0
Remove obselete MindMap class
rmoradc Sep 14, 2020
083b48d
Add GET method for maps
rmoradc Sep 14, 2020
41e161a
Add bibtex to mindmap adpater
rmoradc Sep 14, 2020
fba01af
Add enums for node and edge fields
rmoradc Sep 15, 2020
2cb7481
Refactor data models with enums
rmoradc Sep 15, 2020
1ab1b7a
Add separate methods for bib to node and edge
rmoradc Sep 15, 2020
f065885
Refactored bib entry serializer format & formatting
rowanh22 Sep 15, 2020
6260c64
Converted node id to type Long rather than String
rowanh22 Sep 15, 2020
232095b
Merge branch 'rmoradc/feature/bibtext-mindmap-parser' into rhar768/fe…
rowanh22 Sep 15, 2020
b98e702
Merged branch rmoradc/feature/bibtext-mindmap-parser and added basic …
rowanh22 Sep 15, 2020
876a40f
Added reading mindmap from bibtex file and endpoint to get the curren…
rowanh22 Sep 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Documentation
about: Create a report to help us improve
title: ''
labels: documentation
assignees: ''

---
### User Story:

As a \<type of user\>, I want \<some feature\> so that \<some reason\>


### Acceptance Criteria:

1)
2)
26 changes: 26 additions & 0 deletions .github/ISSUE_TEMPLATE/epic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: UoA Epic
about: Create an epic
title: ''
labels: epic
assignees: ''

---

**Epic**
<!--As a [user role], I'd like to [do something], so that [some goal].-->

**Acceptance Criteria**

-
-

**User Stories**

-
-

**Notes**

---

28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request-uoa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: UoA Feature Request
about: Create a feature request
title: ''
labels: user story
assignees: ''

---

<!--Please start the issue title with [Xpt] where X is the number of story points estimated for the issue.-->

**User Story**
<!--As a [user role], I'd like to [do something], so that [some goal].-->

**Acceptance Criteria**

-
-

**Notes**

---

**Why is this feature needed? Please describe the problem your requested feature wants to solve**
<!-- Describe what the problem is. Ex. I'm always frustrated when ... -->

**Describe the solution you'd like**
<!--Describe what you want to happen -->
17 changes: 16 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ dependencies {

implementation group: 'jakarta.activation', name: 'jakarta.activation-api', version: '1.2.1'
implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '2.3.2'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.2'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '2.3.3'

implementation ('com.github.tomtung:latex2unicode_2.12:0.2.6') {
exclude module: 'fastparse_2.12'
Expand All @@ -199,6 +199,21 @@ dependencies {
implementation 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.62.2'
implementation 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.62.2'

// Required for the standalone server
implementation 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'org.eclipse.jetty:jetty-servlet:9.4.31.v20200723'
implementation 'org.eclipse.jetty:jetty-servlets:9.4.31.v20200723'
implementation 'org.glassfish.jersey.containers:jersey-container-servlet:2.31'
implementation 'org.glassfish.jersey.inject:jersey-hk2:2.31'
//implementation 'org.glassfish.jersey.bundles:jaxrs-ri:2.31'

// Required to serialize and deserialize data at the http API
//implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:2.31'
implementation 'org.glassfish.jersey.core:jersey-common:2.31'
//implementation 'com.fasterxml.jackson.core:jackson-core:2.11.2'
//implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.2'
//implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.2'

testImplementation 'io.github.classgraph:classgraph:4.8.89'
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine:5.6.2'
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,8 @@
requires com.h2database.mvstore;
requires lucene.queryparser;
requires lucene.core;
requires org.eclipse.jetty.server;
requires org.eclipse.jetty.servlet;
requires jersey.container.servlet.core;
requires java.ws.rs;
}
7 changes: 6 additions & 1 deletion src/main/java/org/jabref/gui/JabRefFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
import org.jabref.gui.importer.actions.OpenDatabaseAction;
import org.jabref.gui.importer.fetcher.LookupIdentifierAction;
import org.jabref.gui.integrity.IntegrityCheckAction;
import org.jabref.gui.jabmap.JabMapAction;
import org.jabref.gui.journals.AbbreviateAction;
import org.jabref.gui.journals.ManageJournalsAction;
import org.jabref.gui.keyboard.CustomizeKeyBindingAction;
Expand Down Expand Up @@ -869,7 +870,11 @@ private MenuBar createMenu() {
new SeparatorMenuItem(),

factory.createMenuItem(StandardActions.SEND_AS_EMAIL, new SendAsEMailAction(dialogService, stateManager)),
pushToApplicationMenuItem
pushToApplicationMenuItem,

new SeparatorMenuItem(),

factory.createMenuItem(StandardActions.LAUNCH_JABMAP, new JabMapAction(this))
);

SidePaneComponent webSearch = sidePaneManager.getComponent(SidePaneType.WEB_SEARCH);
Expand Down
55 changes: 49 additions & 6 deletions src/main/java/org/jabref/gui/JabRefMain.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.jabref.gui;

import java.net.Authenticator;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.stage.Stage;

import org.apache.commons.cli.ParseException;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.jabref.cli.ArgumentProcessor;
import org.jabref.cli.JabRefCLI;
import org.jabref.gui.remote.JabRefMessageHandler;
Expand All @@ -25,11 +26,12 @@
import org.jabref.migrations.PreferencesMigrations;
import org.jabref.model.database.BibDatabaseMode;
import org.jabref.preferences.JabRefPreferences;

import org.apache.commons.cli.ParseException;
import org.jabref.rest.resources.RootResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.Authenticator;

/**
* JabRef's main class to process command line options and to start the UI
*/
Expand Down Expand Up @@ -72,7 +74,15 @@ public void start(Stage mainStage) {
return;
}

// If not, start GUI
startHttpEndPoint();

// TODO: How and when to shut down the server
// Waits until server is finished.
// Will never happen, thus user has to press Ctrl+C.
// See also https://stackoverflow.com/a/14981621/873282.
// server.join();

// If there isn't a running JabRef instance or multiple instances are allowed, start GUI
new JabRefGUI(mainStage, argumentProcessor.getParserResults(), argumentProcessor.isBlank());
} catch (ParseException e) {
LOGGER.error("Problem parsing arguments", e);
Expand All @@ -86,6 +96,39 @@ public void start(Stage mainStage) {
}
}

private void startHttpEndPoint() {
Server server = this.createHttpServer();
//Starts server to http://localhost:9898/libraries/current/entries

try {
server.start();
} catch (Exception e) {
e.printStackTrace();
}
}

private Server createHttpServer() {
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");

Server server = new Server(9898);
server.setHandler(context);
this.addServlet(context);
return server;
}

private void addServlet(ServletContextHandler context) {
// this mirrors a webapp/WEB-INF/web.xml
ServletHolder jerseyServlet = context.addServlet(
org.glassfish.jersey.servlet.ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);

// Tells the Jersey Servlet which REST service/class to load.
jerseyServlet.setInitParameter(
"jersey.config.server.provider.classnames",
RootResource.class.getCanonicalName());
}

@Override
public void stop() {
Globals.stopBackgroundTasks();
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/jabref/gui/actions/StandardActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

public enum StandardActions implements Action {

LAUNCH_JABMAP(Localization.lang("Launch JabMap"), IconTheme.JabRefIcons.BOOK, KeyBinding.LAUNCH_JABMAP),
COPY_MORE(Localization.lang("Copy") + "..."),
COPY_TITLE(Localization.lang("Copy title"), KeyBinding.COPY_TITLE),
COPY_KEY(Localization.lang("Copy citation key"), KeyBinding.COPY_CITATION_KEY),
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/org/jabref/gui/jabmap/JabMapAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.jabref.gui.jabmap;

import org.jabref.gui.JabRefFrame;
import org.jabref.gui.actions.SimpleCommand;
import org.jabref.logic.jabmap.MindMapWriter;


public class JabMapAction extends SimpleCommand {

JabRefFrame jabRefFrame;

public JabMapAction(JabRefFrame jabRefFrame) {
this.jabRefFrame = jabRefFrame;
}

@Override
public void execute() {
new MindMapWriter(jabRefFrame);
}
}
1 change: 1 addition & 0 deletions src/main/java/org/jabref/gui/keyboard/KeyBinding.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public enum KeyBinding {
HELP("Help", Localization.lang("Help"), "F1", KeyBindingCategory.FILE),
IMPORT_INTO_CURRENT_DATABASE("Import into current library", Localization.lang("Import into current library"), "ctrl+I", KeyBindingCategory.FILE),
IMPORT_INTO_NEW_DATABASE("Import into new library", Localization.lang("Import into new library"), "ctrl+alt+I", KeyBindingCategory.FILE),
LAUNCH_JABMAP("Launch JabMap", Localization.lang("Launch JabMap"), "ctrl+j", KeyBindingCategory.TOOLS),
NEW_ARTICLE("New article", Localization.lang("New article"), "ctrl+shift+A", KeyBindingCategory.BIBTEX),
NEW_BOOK("New book", Localization.lang("New book"), "ctrl+shift+B", KeyBindingCategory.BIBTEX),
NEW_ENTRY("New entry", Localization.lang("New entry"), "ctrl+N", KeyBindingCategory.BIBTEX),
Expand Down
108 changes: 108 additions & 0 deletions src/main/java/org/jabref/logic/jabmap/BibtexMindMapAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.jabref.logic.jabmap;

import javafx.collections.ObservableList;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.field.Field;
import org.jabref.model.jabmap.EdgeDirection;
import org.jabref.model.jabmap.MindMap;
import org.jabref.model.jabmap.MindMapEdge;
import org.jabref.model.jabmap.MindMapNode;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.jabref.model.jabmap.MindMapEdge.*;
import static org.jabref.model.jabmap.MindMapNode.*;

/**
* This class handles converting data from BibTeX format, which is stored in the database, to MindMap to be sent to JapMap
* It also does the reverse, converting JSON to BibTeX to be stored.
*/
public class BibtexMindMapAdapter {

public static final String DEFAULT_MAP_NAME = "New Map";

/**
* Method for loading MindMap class from bibtex file. Returns the mindmap object if present, a blank map otherwise
*/
public MindMap bibtex2MindMap(BibDatabase database) {
ObservableList<BibEntry> observableList = database.getEntries();
// TODO: Where to handle/generate node & edge citation keys, which JabRef needs to read into database
// Retrieve map, nodes, and edges from list of bib entries
Optional<BibEntry> optionalMapEntry = observableList.stream().filter(o -> o.getType().getDisplayName().equals("Mapnode")).findFirst();
if (optionalMapEntry.isPresent()) {
// We know this file contains a mind map so...
MindMap map = new MindMap();
try {
for (BibEntry b : observableList) {
switch (b.getType().getDisplayName()) {
case MAP_NODE_ENTRY_NAME -> {
// Instantiate MindMapNode object and add to MindMap nodes
map.addNode(createNodeFromBibEntry(b));
}
case MAP_EDGE_ENTRY_NAME -> {
// Instantiate MindMapEdge object and add to MindMap edges
map.addEdge(createEdgeFromBibEntry(b));
}
}
}
return map;
} catch (IllegalArgumentException e) {
System.out.println("Error parsing map from bibtex, returning clean one instead");
}
}
//Return blank mind map
MindMap newMap = new MindMap();
newMap.addNode(new MindMapNode(DEFAULT_MAP_NAME));
return newMap;
}

/**
* Method to convert MindMap class to bibtex entries that can then be saved in the database
*/
public List<BibEntry> mindMap2Bibtex(MindMap mindMap) {
// Instantiate appropriate bib entries containing mind map, node, and edge data and return them all to be
// saved in the database
return null;
}

/**
* Helper method that takes a bib entry and iteratively converts the fields & values to those of a MindMapNode
*/
private MindMapNode createNodeFromBibEntry(BibEntry entry) throws IllegalArgumentException {
// TODO: there's definitely a cleaner way to do this
MindMapNode newNode = new MindMapNode();
for (Map.Entry<Field, String> field : entry.getFieldMap().entrySet()) {
Field fieldName = field.getKey();
String fieldValue = field.getValue();
switch (fieldName.getName()) {
case MAP_NODE_ID -> newNode.setId(Long.parseLong(fieldValue));
case MAP_NODE_NAME -> newNode.setName(fieldValue);
case MAP_NODE_BIBENTRY -> newNode.setBibEntry(fieldValue);
case MAP_NODE_XPOS -> newNode.setX_pos(Integer.parseInt(fieldValue));
case MAP_NODE_YPOS -> newNode.setY_pos(Integer.parseInt(fieldValue));
}
}
return newNode;
}

/**
* Helper method that takes a bib entry and iteratively converts the fields & values to those of a MindMapEdge
*/
private MindMapEdge createEdgeFromBibEntry(BibEntry entry) throws IllegalArgumentException {
MindMapEdge newEdge = new MindMapEdge();
for (Map.Entry<Field, String> field : entry.getFieldMap().entrySet()) {
Field fieldName = field.getKey();
String fieldValue = field.getValue();
switch (fieldName.getName()) {
case MAP_EDGE_NODE1_ID -> newEdge.setNode1_Id(Long.parseLong(fieldValue));
case MAP_EDGE_NODE2_ID -> newEdge.setNode2_Id(Long.parseLong(fieldValue));
case MAP_EDGE_LABEL -> newEdge.setLabel(fieldValue);
case MAP_EDGE_DIRECTION -> newEdge.setDirection(EdgeDirection.valueOf(fieldValue));
}
}
return newEdge;
}
}
Loading