[DS-3940](master) Port base SHERPA v2 changes from 6.x version

This commit is contained in:
Kim Shepherd
2020-05-05 11:15:27 +12:00
parent 12ffc78452
commit dd10104661
13 changed files with 1065 additions and 25 deletions

View File

@@ -7,6 +7,9 @@
*/
package org.dspace.app.sherpa;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
@@ -16,10 +19,10 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.app.sherpa.v2.SHERPAResponse;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.springframework.beans.factory.annotation.Autowired;
public class SHERPAService {
private CloseableHttpClient client = null;
@@ -28,10 +31,11 @@ public class SHERPAService {
private long sleepBetweenTimeouts;
private int timeout = 5000;
/**
* log4j category
*/
private static final Logger log = LogManager.getLogger(SHERPAService.class);
/** log4j category */
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(SHERPAService.class);
@Autowired
ConfigurationService configurationService;
public SHERPAService() {
HttpClientBuilder builder = HttpClientBuilder.create();
@@ -45,11 +49,16 @@ public class SHERPAService {
public SHERPAResponse searchByJournalISSN(String query) {
ConfigurationService configurationService
= DSpaceServicesFactory.getInstance().getConfigurationService();
String endpoint = configurationService.getProperty("sherpa.romeo.url");
String endpoint = configurationService.getProperty("sherpa.romeo.url",
"https://v2.sherpa.ac.uk/cgi/retrieve");
String apiKey = configurationService.getProperty("sherpa.romeo.apikey");
// API Key is *required* for v2 API calls
if (null == apiKey) {
log.error("SHERPA ROMeO API Key missing: please register for an API key and set sherpa.romeo.apikey");
return new SHERPAResponse("SHERPA/RoMEO configuration invalid or missing");
}
HttpGet method = null;
SHERPAResponse sherpaResponse = null;
int numberOfTries = 0;
@@ -70,12 +79,16 @@ public class SHERPAService {
Thread.sleep(sleepBetweenTimeouts);
URIBuilder uriBuilder = new URIBuilder(endpoint);
uriBuilder.addParameter("issn", query);
uriBuilder.addParameter("versions", "all");
uriBuilder.addParameter("item-type", "publication");
uriBuilder.addParameter("filter", "[[\"issn\",\"equals\",\"" + query + "\"]]");
uriBuilder.addParameter("format", "Json");
if (StringUtils.isNotBlank(apiKey)) {
uriBuilder.addParameter("ak", apiKey);
uriBuilder.addParameter("api-key", apiKey);
}
log.debug("Searching SHERPA endpoint with " + uriBuilder.toString());
method = new HttpGet(uriBuilder.build());
method.setConfig(RequestConfig.custom()
.setConnectionRequestTimeout(timeout)
@@ -95,12 +108,22 @@ public class SHERPAService {
HttpEntity responseBody = response.getEntity();
if (null != responseBody) {
sherpaResponse = new SHERPAResponse(responseBody.getContent());
InputStream content = null;
try {
content = responseBody.getContent();
sherpaResponse = new SHERPAResponse(content, SHERPAResponse.SHERPAFormat.JSON);
} catch (IOException e) {
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
} finally {
if (content != null) {
content.close();
}
}
} else {
sherpaResponse = new SHERPAResponse("SHERPA/RoMEO returned no response");
}
} catch (Exception e) {
log.warn("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
log.error("Encountered exception while contacting SHERPA/RoMEO: " + e.getMessage(), e);
} finally {
if (method != null) {
method.releaseConnection();

View File

@@ -7,14 +7,15 @@
*/
package org.dspace.app.sherpa.submit;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.app.sherpa.SHERPAResponse;
import org.dspace.app.sherpa.SHERPAService;
import org.dspace.app.sherpa.v2.SHERPAResponse;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
@@ -37,12 +38,28 @@ public class SHERPASubmitService {
this.sherpaService = sherpaService;
}
public SHERPAResponse searchRelatedJournals(Context context, Item item) {
public List<SHERPAResponse> searchRelatedJournals(Context context, Item item) {
Set<String> issns = getISSNs(context, item);
if (issns == null || issns.size() == 0) {
return null;
} else {
return sherpaService.searchByJournalISSN(StringUtils.join(issns, ","));
// SHERPA v2 API no longer supports "OR'd" ISSN search, perform individual searches instead
Iterator<String> issnIterator = issns.iterator();
List<SHERPAResponse> responses = new LinkedList<>();
while (issnIterator.hasNext()) {
String issn = issnIterator.next();
SHERPAResponse response = sherpaService.searchByJournalISSN(issn);
if (response.isError()) {
// Continue with loop
log.warn("Failed to look up SHERPA ROMeO result for ISSN: " + issn);
}
// Store this response, even if it has an error (useful for UI reporting)
responses.add(response);
}
if (responses.isEmpty()) {
responses.add(new SHERPAResponse("SHERPA ROMeO lookup failed"));
}
return responses;
}
}

View File

@@ -5,7 +5,7 @@
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa;
package org.dspace.app.sherpa.v1;
/**
* POJO representation for a SHERPA journal

View File

@@ -5,7 +5,7 @@
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa;
package org.dspace.app.sherpa.v1;
import java.util.List;

View File

@@ -5,7 +5,7 @@
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa;
package org.dspace.app.sherpa.v1;
import java.io.InputStream;
import java.util.LinkedList;

View File

@@ -0,0 +1,99 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa.v2;
import java.util.List;
public class SHERPAJournal {
private List<String> titles;
private String url;
private List<String> issns;
private String romeoPub;
private String zetoPub;
private SHERPAPublisher publisher;
private List<SHERPAPublisher> publishers;
private List<SHERPAPublisherPolicy> policies;
private Boolean inDOAJ;
public SHERPAJournal() {
}
public List<String> getTitles() {
return titles;
}
public void setTitles(List<String> titles) {
this.titles = titles;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public List<String> getIssns() {
return issns;
}
public void setIssns(List<String> issns) {
this.issns = issns;
}
public String getRomeoPub() {
return romeoPub;
}
public void setRomeoPub(String romeoPub) {
this.romeoPub = romeoPub;
}
public String getZetoPub() {
return zetoPub;
}
public void setZetoPub(String zetoPub) {
this.zetoPub = zetoPub;
}
public SHERPAPublisher getPublisher() {
return publisher;
}
public void setPublisher(SHERPAPublisher publisher) {
this.publisher = publisher;
}
public List<SHERPAPublisher> getPublishers() {
return publishers;
}
public void setPublishers(List<SHERPAPublisher> publishers) {
this.publishers = publishers;
}
public List<SHERPAPublisherPolicy> getPolicies() {
return policies;
}
public void setPolicies(List<SHERPAPublisherPolicy> policies) {
this.policies = policies;
}
public Boolean getInDOAJ() {
return inDOAJ;
}
public void setInDOAJ(Boolean inDOAJ) {
this.inDOAJ = inDOAJ;
}
}

View File

@@ -0,0 +1,102 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa.v2;
import java.util.List;
public class SHERPAPermittedVersion {
// Version (submitted, accepted, published)
private String articleVersion;
// Version label
private String articleVersionLabel;
// Option number
private int option;
// General conditions
private List<String> conditions;
// Prerequisites (eg. if required by funder)
private List<String> prerequisites;
// Allowed locations
private List<String> locations;
// Required license(s)
private List<String> licenses;
// Embargo
private SHERPAEmbargo embargo;
protected class SHERPAEmbargo {
String units;
int amount;
}
public String getArticleVersion() {
return articleVersion;
}
public void setArticleVersion(String articleVersion) {
this.articleVersion = articleVersion;
}
public List<String> getConditions() {
return conditions;
}
public void setConditions(List<String> conditions) {
this.conditions = conditions;
}
public List<String> getPrerequisites() {
return prerequisites;
}
public void setPrerequisites(List<String> prerequisites) {
this.prerequisites = prerequisites;
}
public List<String> getLocations() {
return locations;
}
public void setLocations(List<String> locations) {
this.locations = locations;
}
public List<String> getLicenses() {
return licenses;
}
public void setLicenses(List<String> licenses) {
this.licenses = licenses;
}
public SHERPAEmbargo getEmbargo() {
return embargo;
}
public void setEmbargo(SHERPAEmbargo embargo) {
this.embargo = embargo;
}
public int getOption() {
return option;
}
public void setOption(int option) {
this.option = option;
}
public String getArticleVersionLabel() {
return articleVersionLabel;
}
public void setArticleVersionLabel(String articleVersionLabel) {
this.articleVersionLabel = articleVersionLabel;
}
}

View File

@@ -0,0 +1,81 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa.v2;
public class SHERPAPublisher {
private String name;
private String relationshipType;
private String country;
private String uri;
private int publicationCount;
// this is not technically in the same place in SHERPA data model but it makes more sense to apply it here
// is it is treated as a 'special case' - just for printing links to paid OA access policies
private String paidAccessDescription;
private String paidAccessUrl;
public SHERPAPublisher() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRelationshipType() {
return relationshipType;
}
public void setRelationshipType(String relationshipType) {
this.relationshipType = relationshipType;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public int getPublicationCount() {
return publicationCount;
}
public void setPublicationCount(int publicationCount) {
this.publicationCount = publicationCount;
}
public String getPaidAccessDescription() {
return paidAccessDescription;
}
public void setPaidAccessDescription(String paidAccessDescription) {
this.paidAccessDescription = paidAccessDescription;
}
public String getPaidAccessUrl() {
return paidAccessUrl;
}
public void setPaidAccessUrl(String paidAccessUrl) {
this.paidAccessUrl = paidAccessUrl;
}
}

View File

@@ -0,0 +1,116 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa.v2;
import java.util.List;
import java.util.Map;
public class SHERPAPublisherPolicy {
private int id;
private boolean openAccessPermitted;
private String uri;
private String internalMoniker;
private List<SHERPAPermittedVersion> permittedVersions;
private Map<String, String> urls;
private boolean openAccessProhibited;
private int publicationCount;
// The legacy "can" / "cannot" indicators
private String preArchiving = "cannot";
private String postArchiving = "cannot";
private String pubArchiving = "cannot";
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean isOpenAccessPermitted() {
return openAccessPermitted;
}
public void setOpenAccessPermitted(boolean openAccessPermitted) {
this.openAccessPermitted = openAccessPermitted;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getInternalMoniker() {
return internalMoniker;
}
public void setInternalMoniker(String internalMoniker) {
this.internalMoniker = internalMoniker;
}
public List<SHERPAPermittedVersion> getPermittedVersions() {
return permittedVersions;
}
public void setPermittedVersions(List<SHERPAPermittedVersion> permittedVersions) {
this.permittedVersions = permittedVersions;
}
public Map<String, String> getUrls() {
return urls;
}
public void setUrls(Map<String, String> urls) {
this.urls = urls;
}
public boolean isOpenAccessProhibited() {
return openAccessProhibited;
}
public void setOpenAccessProhibited(boolean openAccessProhibited) {
this.openAccessProhibited = openAccessProhibited;
}
public int getPublicationCount() {
return publicationCount;
}
public void setPublicationCount(int publicationCount) {
this.publicationCount = publicationCount;
}
public String getPreArchiving() {
return preArchiving;
}
public void setPreArchiving(String preArchiving) {
this.preArchiving = preArchiving;
}
public String getPostArchiving() {
return postArchiving;
}
public void setPostArchiving(String postArchiving) {
this.postArchiving = postArchiving;
}
public String getPubArchiving() {
return pubArchiving;
}
public void setPubArchiving(String pubArchiving) {
this.pubArchiving = pubArchiving;
}
}

View File

@@ -0,0 +1,533 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa.v2;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.log4j.Logger;
import org.dspace.core.I18nUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
/**
* Model class for the SHERPAv2 API (JSON) response
* The structure and approached used is quite different to the simple v1 API used previously
*
* @author Kim Shepherd
*
*/
public class SHERPAResponse {
// Is this response to be treated as an error?
private boolean error;
// Error message
private String message;
// Parsed system metadata from search results
private SHERPASystemMetadata metadata;
// List of parsed journal results
private List<SHERPAJournal> journals;
// Internal Sherpa ID
private int id;
// SHERPA URI (the human page version of this API response)
private String uri;
// Format enum - currently only JSON is supported
public enum SHERPAFormat {
JSON, XML
};
private static Logger log = Logger.getLogger(SHERPAResponse.class);
/**
* Parse SHERPA v2 API for a given format
* @param input - input stream from the HTTP response content
* @param format - requested format
* @throws IOException
*/
public SHERPAResponse(InputStream input, SHERPAFormat format) throws IOException {
if (format == SHERPAFormat.JSON) {
parseJSON(input);
}
}
/**
* Parse the SHERPA v2 API JSON and construct Romeo policy data for display
* This method does not return a value, but rather populates the metadata and journals objects
* with data parsed from the JSON.
* @param jsonData - the JSON input stream from the API result response body
*/
private void parseJSON(InputStream jsonData) throws IOException {
InputStreamReader streamReader = new InputStreamReader(jsonData);
JSONTokener jsonTokener = new JSONTokener(streamReader);
JSONObject httpResponse;
try {
httpResponse = new JSONObject(jsonTokener);
if (httpResponse.has("items")) {
JSONArray items = httpResponse.getJSONArray("items");
// items array is search results, *not* journals or publishers - they are listed for each item
// - however, we only ever want one result since we're passing an "equals ISSN" query
if (items.length() > 0) {
metadata = new SHERPASystemMetadata();
this.journals = new LinkedList<>();
// Iterate search result items
for (int itemIndex = 0; itemIndex < items.length(); itemIndex++) {
List<SHERPAPublisher> sherpaPublishers = new LinkedList<>();
List<SHERPAPublisherPolicy> policies = new ArrayList<>();
SHERPAPublisher sherpaPublisher = new SHERPAPublisher();
SHERPAJournal sherpaJournal = new SHERPAJournal();
JSONObject item = items.getJSONObject(0);
// Parse system metadata (per-item / result information)
if (item.has("system_metadata")) {
JSONObject systemMetadata = item.getJSONObject("system_metadata");
metadata = parseSystemMetadata(systemMetadata);
}
// Parse "publisher policy"
// note - most of the information that was previously under 'publisher' is now under here
if (item.has("publisher_policy")) {
// Parse main publisher policies node
JSONArray publisherPolicies = item.getJSONArray("publisher_policy");
for (int i = 0; i < publisherPolicies.length(); i++) {
JSONObject policy = publisherPolicies.getJSONObject(i);
// Special case - quickly check the policy for the 'paid access' option
// and continue if found, then parse the rest of the policy
String moniker = null;
if (policy.has("internal_moniker")) {
moniker = policy.getString("internal_moniker");
}
// This seems to be usually policy(ies) for the journal proper
// and then an "Open access option" which contains some of the info
// that the 'paidaccess' node in the old API used to contain
// Look for: internal_moniker = "Open access option"
// Check if this is OA options (Paid Access) or not
if ("Open access option".equalsIgnoreCase(moniker)) {
log.debug("This is the Open access options policy - a special case");
if (policy.has("urls")) {
JSONArray urls = policy.getJSONArray("urls");
for (int u = 0; u < urls.length(); u++) {
JSONObject url = urls.getJSONObject(u);
if (url.has("description") &&
"Open Access".equalsIgnoreCase(url.getString("description"))) {
log.debug("Found OA paid access url: " + url.getString("url"));
sherpaPublisher.setPaidAccessDescription(url.getString("description"));
sherpaPublisher.setPaidAccessUrl(url.getString("url"));
break;
}
}
}
// Continue the loop here - this "policy" is a bit different and we
// don't want to add irrelevant conditions to the policy
continue;
}
// Parse the main publisher policy object and add to the list
SHERPAPublisherPolicy sherpaPublisherPolicy = parsePublisherPolicy(policy);
policies.add(sherpaPublisherPolicy);
}
// set publisher name - note we're only looking for the first name here
// as per previous functionality (for simple display)
if (item.has("publishers")) {
JSONArray publishers = item.getJSONArray("publishers");
if (publishers.length() > 0) {
JSONObject publisherElement = publishers.getJSONObject(0);
if (publisherElement.has("publisher")) {
JSONObject publisher = publisherElement.getJSONObject("publisher");
sherpaPublisher.setName(parsePublisherName(publisher));
sherpaPublisher.setUri(parsePublisherURL(publisher));
}
}
}
// Parse journal data
sherpaJournal = parseJournal(item, sherpaPublisher.getName());
}
sherpaPublishers.add(sherpaPublisher);
sherpaJournal.setPublisher(sherpaPublisher);
sherpaJournal.setPublishers(sherpaPublishers);
sherpaJournal.setPolicies(policies);
this.journals.add(sherpaJournal);
}
} else {
error = true;
message = "No results found";
}
} else {
error = true;
message = "No results found";
}
} catch (JSONException e) {
log.error("Failed to parse SHERPA response", e);
error = true;
} finally {
streamReader.close();
}
}
/**
* Parse system metadata and return populated SHERPASystemMetadata object
* @param systemMetadata
*/
private SHERPASystemMetadata parseSystemMetadata(JSONObject systemMetadata) {
SHERPASystemMetadata metadata = new SHERPASystemMetadata();
if (systemMetadata.has("uri")) {
this.uri = systemMetadata.getString("uri");
metadata.setUri(this.uri);
} else {
log.error("SHERPA URI missing for API response item");
}
if (systemMetadata.has("id")) {
this.id = systemMetadata.getInt("id");
metadata.setId(this.id);
} else {
log.error("SHERPA internal ID missing for API response item");
}
// Get date created and added - DSpace expects this in the publisher object, though
if (systemMetadata.has("date_created")) {
metadata.setDateCreated(systemMetadata.getString("date_created"));
}
if (systemMetadata.has("date_modified")) {
metadata.setDateModified(systemMetadata.getString("date_modified"));
}
// Is this item publicly visible?
if (systemMetadata.has("publicly_visible")) {
metadata.setPubliclyVisible ("yes".equals(systemMetadata
.getString("publicly_visible")));
}
// Is this item listed in the DOAJ?
if (systemMetadata.has("listed_in_doaj")) {
metadata.setPubliclyVisible ("yes".equals(systemMetadata
.getString("listed_in_doaj")));
}
return metadata;
}
/**
* Parse journal JSON data and return populated bean
* This method also takes publisherName as a string to help construct some
* legacy labels
* @param item - the main result item JSON (which is the closest thing to an actual 'journal')
* @param publisherName - the parsed publisher name
* @return
*/
private SHERPAJournal parseJournal(JSONObject item, String publisherName) {
SHERPAJournal sherpaJournal = new SHERPAJournal();
// set journal title
if (item.has("title")) {
JSONArray titles = item.getJSONArray("title");
if (titles.length() > 0) {
List<String> titleList = new ArrayList<>();
for (int t = 0; t < titles.length(); t++) {
JSONObject title = titles.getJSONObject(t);
if (title.has("title")) {
titleList.add(title.getString("title").trim());
}
}
sherpaJournal.setTitles(titleList);
if (titleList.size() > 0) {
// Faking this a bit based on what I'd seen - not in the API v2 data
sherpaJournal.setRomeoPub(publisherName + ": "
+ titleList.get(0));
sherpaJournal.setZetoPub(publisherName + ": "
+ titleList.get(0));
}
}
}
// Journal URL
if (item.has("url")) {
sherpaJournal.setUrl(item.getString("url"));
}
// set ISSNs
if (item.has("issns")) {
JSONArray issns = item.getJSONArray("issns");
// just get first - DSpace data model only allows for one
List<String> issnList = new ArrayList<>();
for (int ii = 0; ii < issns.length(); ii++) {
JSONObject issn = issns.getJSONObject(ii);
issnList.add(issn.getString("issn").trim());
}
sherpaJournal.setIssns(issnList);
}
// Is the item in DOAJ?
if (item.has("listed_in_doaj")) {
sherpaJournal.setInDOAJ(("yes".equals(item.getString("listed_in_doaj"))));
}
return sherpaJournal;
}
/**
* Parse a publisher_policy JSON data and return a populated bean
* @param policy - each publisher policy node in the JSON array
* @return populated SHERPAPublisherPolicy object
*/
private SHERPAPublisherPolicy parsePublisherPolicy(JSONObject policy) {
SHERPAPublisherPolicy sherpaPublisherPolicy = new SHERPAPublisherPolicy();
// Get and set monikers
String moniker = null;
if (policy.has("internal_moniker")) {
moniker = policy.getString("internal_moniker");
sherpaPublisherPolicy.setInternalMoniker(moniker);
}
// URLs (used to be Copyright Links)
if (policy.has("urls")) {
JSONArray urls = policy.getJSONArray("urls");
Map<String, String> copyrightLinks = new TreeMap<>();
for (int u = 0; u < urls.length(); u++) {
JSONObject url = urls.getJSONObject(u);
if (url.has("description") && url.has("url")) {
log.debug("Setting copyright URL: " + url.getString("url"));
copyrightLinks.put(url.getString("url"), url.getString("description"));
}
}
sherpaPublisherPolicy.setUrls(copyrightLinks);
}
// Permitted OA options
int submittedOption = 0;
int acceptedOption = 0;
int publishedOption = 0;
int currentOption = 0;
if (policy.has("permitted_oa")) {
List<String> allowed = new ArrayList<>();
JSONArray permittedOA = policy.getJSONArray("permitted_oa");
List<SHERPAPermittedVersion> permittedVersions = new ArrayList<>();
// Iterate each permitted OA version / option
for (int p = 0; p < permittedOA.length(); p++) {
JSONObject permitted = permittedOA.getJSONObject(p);
SHERPAPermittedVersion permittedVersion = parsePermittedVersion(permitted);
// To determine which option # we are, inspect article versions and set
allowed.add(permittedVersion.getArticleVersion());
if ("submitted".equals(permittedVersion.getArticleVersion())) {
submittedOption++;
currentOption = submittedOption;
} else if ("accepted".equals(permittedVersion.getArticleVersion())) {
acceptedOption++;
currentOption = acceptedOption;
} else if ("published".equals(permittedVersion.getArticleVersion())) {
publishedOption++;
currentOption = publishedOption;
}
permittedVersion.setOption(currentOption);
permittedVersions.add(permittedVersion);
// Populate the old indicators into the publisher policy object
if (allowed.contains("submitted")) {
sherpaPublisherPolicy.setPreArchiving("can");
}
if (allowed.contains("accepted")) {
sherpaPublisherPolicy.setPostArchiving("can");
}
if (allowed.contains("published")) {
sherpaPublisherPolicy.setPubArchiving("can");
}
}
sherpaPublisherPolicy.setPermittedVersions(permittedVersions);
}
return sherpaPublisherPolicy;
}
/**
* Parse permitted version JSON and populate new bean from the data
* @param permitted - each 'permitted_oa' node in the JSON array
* @return populated SHERPAPermittedVersion object
*/
private SHERPAPermittedVersion parsePermittedVersion(JSONObject permitted) {
SHERPAPermittedVersion permittedVersion = new SHERPAPermittedVersion();
// Get the article version, which is ultimately used for the ticks / crosses
// in the UI display. My assumptions around translation:
// submitted = preprint
// accepted = postprint
// published = pdfversion
String articleVersion = "unknown";
String versionLabel = "Unknown";
if (permitted.has("article_version")) {
JSONArray versions = permitted.getJSONArray("article_version");
articleVersion = versions.getString(0);
permittedVersion.setArticleVersion(articleVersion);
log.debug("Added allowed version: " + articleVersion + " to list");
}
if ("submitted".equals(articleVersion)) {
versionLabel = I18nUtil.getMessage("jsp.sherpa.submitted-version-label");
} else if ("accepted".equals(articleVersion)) {
versionLabel = I18nUtil.getMessage("jsp.sherpa.accepted-version-label");
} else if ("published".equals(articleVersion)) {
versionLabel = I18nUtil.getMessage("jsp.sherpa.published-version-label");
}
// These are now child arrays, in old API they were explicit like
// "preprint restrictions", etc., and just contained text rather than data
if (permitted.has("conditions")) {
List<String> conditionList = new ArrayList<>();
JSONArray conditions = permitted.getJSONArray("conditions");
for (int c = 0; c < conditions.length(); c++) {
conditionList.add(conditions.getString(c).trim());
}
permittedVersion.setConditions(conditionList);
}
permittedVersion.setArticleVersionLabel(versionLabel);
// Any prerequisites for this option (eg required by funder)
List<String> prerequisites = new ArrayList<>();
if (permitted.has("prerequisites")) {
JSONObject prereqs = permitted.getJSONObject("prerequisites");
if (prereqs.has("prerequisites_phrases")) {
JSONArray phrases = prereqs.getJSONArray("prerequisites_phrases");
for (int pp = 0; pp < phrases.length(); pp++) {
JSONObject phrase = phrases.getJSONObject(pp);
if (phrase.has("phrase")) {
prerequisites.add(phrase.getString("phrase").trim());
}
}
}
}
permittedVersion.setPrerequisites(prerequisites);
// Locations where this version / option may be archived
List<String> sherpaLocations = new ArrayList<>();
if (permitted.has("location")) {
JSONObject locations = permitted.getJSONObject("location");
if (locations.has("location_phrases")) {
JSONArray locationPhrases = locations.getJSONArray("location_phrases");
if (locationPhrases.length() > 0) {
for (int l = 0; l < locationPhrases.length(); l++) {
JSONObject locationPhrase = locationPhrases.getJSONObject(l);
if (locationPhrase.has("phrase")) {
sherpaLocations.add(locationPhrase.getString("phrase").trim());
}
}
}
}
}
permittedVersion.setLocations(sherpaLocations);
List<String> sherpaLicenses = new ArrayList<>();
// required licences
if (permitted.has("license")) {
JSONArray licences = permitted.getJSONArray("license");
for (int l = 0; l < licences.length(); l++) {
JSONObject licence = licences.getJSONObject(l);
if (licence.has("license_phrases")) {
JSONArray phrases = licence.getJSONArray("license_phrases");
for (int ll = 0; ll < phrases.length(); ll++) {
JSONObject phrase = phrases.getJSONObject(ll);
if (phrase.has("phrase")) {
sherpaLicenses.add(phrase.getString("phrase").trim());
}
}
}
}
}
permittedVersion.setLicenses(sherpaLicenses);
return permittedVersion;
}
/**
* Parse publisher array and return the first name string found
* @param publisher - array of publisher JSON data
* @return first publisher name found (trimmed String)
*/
private String parsePublisherName(JSONObject publisher) {
String name = null;
if (publisher.has("name")) {
JSONArray publisherNames = publisher.getJSONArray("name");
if (publisherNames.length() > 0) {
JSONObject publisherName = publisherNames.getJSONObject(0);
if (publisherName.has("name")) {
name = publisherName.getString("name").trim();
}
}
}
return name;
}
/**
* Parse publisher URL from the json data
* @param publisher - publisher object (from JSON array)
* @return publisher URL as string
*/
private String parsePublisherURL(JSONObject publisher) {
if (publisher.has("url")) {
return publisher.getString("url");
}
return null;
}
/**
* Create new response object to be handled as an error
* @param message - the message to render in logs or error pages
*/
public SHERPAResponse(String message) {
this.message = message;
this.error = true;
}
public boolean isError() {
return error;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<SHERPAJournal> getJournals() {
return journals;
}
public SHERPASystemMetadata getMetadata() {
return metadata;
}
}

View File

@@ -0,0 +1,69 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.sherpa.v2;
public class SHERPASystemMetadata {
private int id;
private String uri;
private String dateCreated;
private String dateModified;
private boolean isPubliclyVisible = false;
private boolean inDOAJ = false;
public SHERPASystemMetadata() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getDateCreated() {
return dateCreated;
}
public void setDateCreated(String dateCreated) {
this.dateCreated = dateCreated;
}
public String getDateModified() {
return dateModified;
}
public void setDateModified(String dateModified) {
this.dateModified = dateModified;
}
public boolean isPubliclyVisible() {
return isPubliclyVisible;
}
public void setPubliclyVisible(boolean publiclyVisible) {
isPubliclyVisible = publiclyVisible;
}
public boolean isInDOAJ() {
return inDOAJ;
}
public void setInDOAJ(boolean inDOAJ) {
this.inDOAJ = inDOAJ;
}
}

View File

@@ -27,8 +27,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.Logger;
import org.dspace.app.sherpa.SHERPAJournal;
import org.dspace.app.sherpa.SHERPAResponse;
import org.dspace.app.sherpa.v1.SHERPAJournal;
import org.dspace.app.sherpa.v1.SHERPAResponse;
import org.dspace.content.dto.MetadataValueDTO;
import org.dspace.external.model.ExternalDataObject;
import org.dspace.external.provider.ExternalDataProvider;

View File

@@ -23,8 +23,8 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.logging.log4j.Logger;
import org.dspace.app.sherpa.SHERPAPublisher;
import org.dspace.app.sherpa.SHERPAResponse;
import org.dspace.app.sherpa.v1.SHERPAPublisher;
import org.dspace.app.sherpa.v1.SHERPAResponse;
import org.dspace.content.dto.MetadataValueDTO;
import org.dspace.external.model.ExternalDataObject;
import org.dspace.external.provider.ExternalDataProvider;