Skip to content

Commit

Permalink
Merge pull request #12 from guenesaydin/grobid-request-server-async
Browse files Browse the repository at this point in the history
Grobid request server async
  • Loading branch information
obsluk authored Nov 15, 2019
2 parents 4c04ec8 + 5d24ded commit 8768e6e
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 68 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ dependencies {

compile group: 'org.apache.tika', name: 'tika-core', version: '1.22'

compile 'org.apache.httpcomponents:httpclient:4.5.10'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.10'
compile group: 'commons-io', name: 'commons-io', version: '2.6'

// required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package org.jabref.gui.entrybyplaintext;

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

import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;


import org.jabref.Globals;
import org.jabref.JabRefExecutorService;
import org.jabref.JabRefGUI;
import org.jabref.logic.plaintextparser.ParserPipeline;
import org.jabref.model.Defaults;
Expand All @@ -22,7 +27,7 @@ public class EntryByPlainTextViewModel {
private final BibDatabaseContext bibDatabaseContext;
private boolean directAdd;
private final BibDatabaseContext newDatabaseContext;

private List<BibEntry> extractedEntries;


public EntryByPlainTextViewModel(BibDatabaseContext bibDatabaseContext){
Expand All @@ -40,13 +45,18 @@ public StringProperty inputTextProperty(){

public void startParsing(boolean directAdd){
this.directAdd = directAdd;
executeParse();
this.extractedEntries = null;
JabRefExecutorService.INSTANCE.execute(() -> {
this.extractedEntries = ParserPipeline.parsePlainRefCit(inputText.getValue());
Platform.runLater(this::executeParse);
});
}

public void executeParse(){
if(ParserPipeline.parsePlainRefCit(inputText.getValue()).isPresent()){
BibEntry bibEntry = ParserPipeline.parsePlainRefCit(inputText.getValue()).get();
parsingSuccess(bibEntry);
if(extractedEntries.size() > 0){
for (BibEntry bibEntry: extractedEntries) {
parsingSuccess(bibEntry);
}
} else{
parsingFail(inputText.getValue());
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/jabref/gui/preferences/AdvancedTab.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
<RowConstraints minHeight="10.0" vgrow="SOMETIMES"/>
</rowConstraints>
<CheckBox fx:id="proxyUse" text="%Use custom proxy configuration" GridPane.columnSpan="3"
GridPane.rowIndex="0"/>
Expand All @@ -61,5 +63,9 @@
GridPane.rowIndex="5"/>
<Label fx:id="proxyAttentionLabel" styleClass="warning-message"
text="%Attention: Password is stored in plain text!" GridPane.columnIndex="2" GridPane.rowIndex="5"/>
<CheckBox fx:id="customGrobidServer" text="%Use custom GROBID server" GridPane.columnSpan="3"
GridPane.rowIndex="6"/>
<Label fx:id="grobidServerAddressLabel" text="%Server Address" GridPane.rowIndex="7"/>
<TextField fx:id="grobidServerAddress" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="7"/>
</GridPane>
</fx:root>
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/gui/preferences/AdvancedTabView.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ public class AdvancedTabView extends AbstractPreferenceTabView<AdvancedTabViewMo
@FXML private Label proxyPasswordLabel;
@FXML private CustomPasswordField proxyPassword;
@FXML private Label proxyAttentionLabel;
@FXML private CheckBox customGrobidServer;
@FXML private Label grobidServerAddressLabel;
@FXML private TextField grobidServerAddress;

private String proxyPasswordText = "";
private int proxyPasswordCaretPosition = 0;
Expand Down Expand Up @@ -109,6 +112,12 @@ public void initialize() {
validationVisualizer.initVisualization(viewModel.proxyUsernameValidationStatus(), proxyUsername);
validationVisualizer.initVisualization(viewModel.proxyPasswordValidationStatus(), proxyPassword);
});

customGrobidServer.selectedProperty().bindBidirectional(viewModel.useCustomGrobidServer());
customGrobidServer.selectedProperty().addListener(((observable, oldValue, newValue) -> grobidServerReset(newValue)));
grobidServerAddress.textProperty().bindBidirectional(viewModel.customGrobidServer());
grobidServerAddress.disableProperty().bind(viewModel.useCustomGrobidServer().not());
grobidServerAddressLabel.disableProperty().bind(viewModel.useCustomGrobidServer().not());
}

private void proxyPasswordReveal(MouseEvent event) {
Expand All @@ -127,4 +136,10 @@ private void proxyPasswordMask(MouseEvent event) {
proxyPasswordCaretPosition = 0;
}
}

private void grobidServerReset(boolean newObservedValue) {
if (!newObservedValue) {
grobidServerAddress.setText((String) preferences.defaults.get(JabRefPreferences.CUSTOM_GROBID_SERVER));
}
}
}
12 changes: 12 additions & 0 deletions src/main/java/org/jabref/gui/preferences/AdvancedTabViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public class AdvancedTabViewModel implements PreferenceTabViewModel {
private final BooleanProperty proxyUseAuthenticationProperty = new SimpleBooleanProperty();
private final StringProperty proxyUsernameProperty = new SimpleStringProperty("");
private final StringProperty proxyPasswordProperty = new SimpleStringProperty("");
private final BooleanProperty customGrobidServerProperty = new SimpleBooleanProperty();
private final StringProperty grobidServerProperty = new SimpleStringProperty("");

private FunctionBasedValidator remotePortValidator;
private FunctionBasedValidator proxyHostnameValidator;
Expand Down Expand Up @@ -121,6 +123,9 @@ public void setValues() {
proxyUseAuthenticationProperty.setValue(proxyPreferences.isUseAuthentication());
proxyUsernameProperty.setValue(proxyPreferences.getUsername());
proxyPasswordProperty.setValue(proxyPreferences.getPassword());

customGrobidServerProperty.setValue(preferences.getBoolean(JabRefPreferences.USE_CUSTOM_GROBID_SERVER));
grobidServerProperty.setValue(preferences.get(JabRefPreferences.CUSTOM_GROBID_SERVER));
}

public void storeSettings() {
Expand All @@ -137,6 +142,9 @@ public void storeSettings() {
preferences.putBoolean(JabRefPreferences.USE_UNIT_FORMATTER_ON_SEARCH, useUnitFormatterProperty.getValue());

storeProxySettings();

preferences.putBoolean(JabRefPreferences.USE_CUSTOM_GROBID_SERVER, customGrobidServerProperty.getValue());
preferences.put(JabRefPreferences.CUSTOM_GROBID_SERVER, grobidServerProperty.getValue());
}

private void storeRemoteSettings() {
Expand Down Expand Up @@ -248,4 +256,8 @@ public boolean validateSettings() {
public StringProperty proxyUsernameProperty() { return proxyUsernameProperty; }

public StringProperty proxyPasswordProperty() { return proxyPasswordProperty; }

public BooleanProperty useCustomGrobidServer() { return customGrobidServerProperty; }

public StringProperty customGrobidServer() { return grobidServerProperty; }
}
42 changes: 42 additions & 0 deletions src/main/java/org/jabref/logic/net/GrobidClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.jabref.logic.net;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.jabref.Globals;
import org.jabref.preferences.JabRefPreferences;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
* Implements an API to a GROBID server, as described at
* https://grobid.readthedocs.io/en/latest/Grobid-service/#grobid-web-services
*
* The methods are structured to match the GROBID server api.
* Each method corresponds to a GROBID service request. Only the ones already used are already implemented.
*/
public class GrobidClient {

public static String processCitation(String rawCitation, int consolidateCitations) throws GrobidClientException {
try {
if (consolidateCitations < 0 || consolidateCitations > 2) {
throw new GrobidClientException("");
}
HttpEntity httpResponse = HttpPostService.sendPostAndWait(
Globals.prefs.get(JabRefPreferences.CUSTOM_GROBID_SERVER),
"/api/processCitation",
Map.of("citations", rawCitation, "consolidateCitations", String.valueOf(consolidateCitations))
).getEntity();
if (httpResponse == null) {
throw new GrobidClientException("The GROBID server response does not contain anything.");
}
InputStream serverResponseAsStream = httpResponse.getContent();
return IOUtils.toString(serverResponseAsStream, StandardCharsets.UTF_8);
} catch (HttpPostServiceException | IOException e) {
throw new GrobidClientException();
}
}

}
30 changes: 30 additions & 0 deletions src/main/java/org/jabref/logic/net/GrobidClientException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.jabref.logic.net;

import org.jabref.JabRefException;

public class GrobidClientException extends JabRefException {

public GrobidClientException() {
super("An error occurred while processing your query.");
}

public GrobidClientException(String message) {
super(message);
}

public static GrobidClientException getNewGrobidClientExceptionByCode(int httpCode) {
switch(httpCode) {
case 204:
return new GrobidClientException("The GROBID service could not extract any Information from this String.");
case 400:
return new GrobidClientException("The generated Request was wrong.");
case 500:
return new GrobidClientException("An internal GROBID service error occured.");
case 503:
return new GrobidClientException("There are too many requests at a time, please try again later.");
default:
return new GrobidClientException("An error occured processing your GROBID request.");
}
}

}
48 changes: 19 additions & 29 deletions src/main/java/org/jabref/logic/net/HttpPostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,40 @@
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
//import org.apache.http.concurrent.FutureCallback;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.client.HttpClients;
//import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.message.BasicNameValuePair;
//import org.apache.http.nio.client.HttpAsyncClient;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
//import java.util.concurrent.Future;
import java.util.concurrent.Future;


/**
* Makes it easy to send http post requests
* HttpClients are reused.
*/
public class HttpPostService {

private static final HttpClient httpClient = HttpClients.createDefault();
//private static final HttpAsyncClient httpAsyncClient = HttpAsyncClients.createDefault();
private URI url;

public HttpPostService(String url) throws URISyntaxException {
this(new URI(url));
}

public HttpPostService(URI url) {
this.url = url;
}
private static final HttpClient HTTP_CLIENT = HttpClients.createSystem();

public HttpResponse sendPostAndWait(Map<String, String> params) throws IOException {
return httpClient.execute(prepareHttpPost(params));
public static HttpResponse sendPostAndWait(String url, String subUrl, Map<String, String> params) throws HttpPostServiceException {
try {
return HTTP_CLIENT.execute(prepareHttpPost(url, subUrl, params));
} catch (IOException e) {
throw new HttpPostServiceException();
}
}

/* sadly this does not work due to gradle compile errors
public Future<HttpResponse> sendPost(Map<String, String> params,
FutureCallback<HttpResponse> httpResponseHandler) throws IOException {
return httpAsyncClient.execute(prepareHttpPost(params), httpResponseHandler);
public static HttpResponse sendPostAndWait(String url, Map<String, String> params) throws HttpPostServiceException {
return sendPostAndWait(url, "", params);
}

public Future<HttpResponse> sendPost(Map<String, String> params) throws IOException {
return httpAsyncClient.execute(prepareHttpPost(params), null);
}*/

private HttpPost prepareHttpPost(Map<String, String> params) throws UnsupportedEncodingException {
HttpPost httpPost = new HttpPost(url);
private static HttpPost prepareHttpPost(String url, String urlSubPath, Map<String, String> params) throws UnsupportedEncodingException {
HttpPost httpPost = new HttpPost(url + urlSubPath);
List<BasicNameValuePair> parameterList = new ArrayList<>();
for (Map.Entry<String, String> e: params.entrySet()) {
parameterList.add(new BasicNameValuePair(e.getKey(), e.getValue()));
Expand All @@ -61,4 +46,9 @@ private HttpPost prepareHttpPost(Map<String, String> params) throws UnsupportedE
return httpPost;
}

private static HttpPost prepareHttpPost(String url, Map<String, String> params) throws UnsupportedEncodingException {
return prepareHttpPost(url, "", params);
}


}
15 changes: 15 additions & 0 deletions src/main/java/org/jabref/logic/net/HttpPostServiceException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.jabref.logic.net;

import org.jabref.JabRefException;

public class HttpPostServiceException extends JabRefException {

public HttpPostServiceException() {
super("An error occurred connecting to the external http server.");
}

public HttpPostServiceException(String message) {
super(message);
}

}
Loading

0 comments on commit 8768e6e

Please sign in to comment.