Skip to content

Commit

Permalink
add smartnames mode for orcid, see issue #8
Browse files Browse the repository at this point in the history
  • Loading branch information
codeforkjeff committed Nov 27, 2017
1 parent 91ef2d5 commit 683fa88
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ instructions.
For example, if you have a column containing Scopus EIDs, you can select the "Include?" checkbox
for it and enter "eid" in the "As Property" box on the reconciliation screen.

* By default, queries are keyword searches on the entire ORCID bios,
which can return odd results sometimes. The "smartnames" mode (see
the instructions below) splits up names and searches on the
given-names and family-name fields specifically; if there are no
results, it falls back to a keyword search.

### Open Library

* Open Library has rate limits on its API, so requests are not run in a
Expand Down Expand Up @@ -165,6 +171,12 @@ A docker image created by [tobinski](https://github.com/tobinski) is available h
http://localhost:8080/reconcile/orcid
```
To use ORCID with "smartnames" mode when reconciliing names:
```
http://localhost:8080/reconcile/orcid/smartnames
```
To use Open Library: (On the reconciliation screen, under the
"Also use relevant details from other columns" panel, you can
check the "Include?" box for columns to include in the query. Give
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.codefork.conciliator</groupId>
<artifactId>conciliator</artifactId>
<version>2.4.0</version>
<version>2.5.0</version>
<packaging>jar</packaging>

<name>conciliator</name>
Expand Down
73 changes: 71 additions & 2 deletions src/main/java/com/codefork/refine/orcid/Orcid.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,47 @@
import org.apache.commons.logging.LogFactory;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Orcid extends WebServiceDataSource {
public static String EXTRA_PARAM_MODE_FROM_PATH = "mode";
public static String MODE_SMART_NAMES = "smartnames";

Log log = LogFactory.getLog(Orcid.class);

private SAXParserFactory spf = SAXParserFactory.newInstance();

private static String createQueryString(SearchQuery query) {
StringBuffer buf = new StringBuffer();
buf.append(query.getQuery());
for(Map.Entry<String, PropertyValue> prop : query.getProperties().entrySet()) {
String fields = createSearchFieldsQueryString(query);
if(fields.length() > 0) {
buf.append(" ");
buf.append(fields);
}
return buf.toString();
}

/**
* creates Solr-style "field:value" query string from properties in SearchQuery
*/
private static String createSearchFieldsQueryString(SearchQuery query) {
StringBuffer buf = new StringBuffer();
boolean first = true;
for(Map.Entry<String, PropertyValue> prop : query.getProperties().entrySet()) {
if(!first) {
buf.append(" ");
}
buf.append(prop.getKey());
buf.append(":");
String val = prop.getValue().asString();
Expand All @@ -38,22 +60,69 @@ private static String createQueryString(SearchQuery query) {
} else {
buf.append(val);
}
first = false;
}
return buf.toString();
}

@Override
public ServiceMetaDataResponse createServiceMetaDataResponse(Map<String, String> extraParams) {
if(MODE_SMART_NAMES.equals(extraParams.get(EXTRA_PARAM_MODE_FROM_PATH))) {
return new OrcidMetaDataResponse(getName() + " - Smart Names Mode");
}
return new OrcidMetaDataResponse(getName());
}

@Override
public Map<String, String> parseRequestToExtraParams(HttpServletRequest request) {
String[] parts = request.getServletPath().split("/");
String dataSourceStr = parts[2];
String mode = null;
if (parts.length > 3) {
mode = parts[3];
}

Map<String, String> extraParams = new HashMap<String, String>();
extraParams.put(EXTRA_PARAM_MODE_FROM_PATH, mode);
return extraParams;
}

@Override
public List<Result> search(SearchQuery query) throws Exception {
List<Result> results = Collections.emptyList();

String q = createQueryString(query);
if(MODE_SMART_NAMES.equals(query.getExtraParams().get(EXTRA_PARAM_MODE_FROM_PATH))) {
String name = query.getQuery();
String[] namePieces = name.split("\\s+");
if(namePieces.length == 2) {
results = searchSmartNames(query, namePieces[0], namePieces[1]);
}
}
if(results.isEmpty()) {
results = searchKeyword(query);
}
return results;
}

private List<Result> searchSmartNames(SearchQuery query, String givenName, String familyName) throws Exception {
String q = String.format("given-names:%s AND family-name:%s", givenName, familyName);
String fields = createSearchFieldsQueryString(query);
if(fields.length() > 0) {
q += " " + fields;
}
String url = String.format("http://pub.orcid.org/v1.2/search/orcid-bio/?rows=%d&q=", query.getLimit()) +
UriUtils.encodeQueryParam(q, "UTF-8");
return doSearch(query, url);
}

private List<Result> searchKeyword(SearchQuery query) throws Exception {
String q = createQueryString(query);
String url = String.format("http://pub.orcid.org/v1.2/search/orcid-bio/?rows=%d&q=", query.getLimit()) +
UriUtils.encodeQueryParam(q, "UTF-8");
return doSearch(query, url);
}

private List<Result> doSearch(SearchQuery query, String url) throws Exception {
log.debug("Making request to " + url);
HttpURLConnection conn = getConnectionFactory().createConnection(url);

Expand Down

0 comments on commit 683fa88

Please sign in to comment.