70404: CC license (REST): Patch submission (Add)

This commit is contained in:
Yana De Pauw
2020-04-20 12:57:49 +02:00
parent 5800bef325
commit 0920de7b21
8 changed files with 296 additions and 18 deletions

View File

@@ -7,8 +7,11 @@
*/
package org.dspace.license;
import java.io.IOException;
import java.util.Map;
import org.jdom.Document;
/**
* Service interface class for the Creative commons license connector service.
* The implementation of this class is responsible for all the calls to the CC license API and parsing the response
@@ -27,6 +30,7 @@ public interface CCLicenseConnectorService {
/**
* Retrieve the CC License URI based on the provided license id, language and answers to the field questions from
* the CC License API
*
* @param licenseId - the ID of the license
* @param language - the language for which to retrieve the full answerMap
* @param answerMap - the answers to the different field questions
@@ -36,4 +40,21 @@ public interface CCLicenseConnectorService {
String language,
Map<String, String> answerMap);
/**
* Retrieve the license RDF document based on the license URI
*
* @param licenseURI - The license URI for which to retrieve the license RDF document
* @return the license RDF document
* @throws IOException
*/
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException;
/**
* Retrieve the license Name from the license document
*
* @param doc - The license document from which to retrieve the license name
* @return the license name
*/
public String retrieveLicenseName(final Document doc);
}

View File

@@ -8,7 +8,11 @@
package org.dspace.license;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashMap;
@@ -31,6 +35,7 @@ import org.dspace.services.ConfigurationService;
import org.jaxen.JaxenException;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
@@ -237,6 +242,7 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
/**
* Retrieve the CC License URI based on the provided license id, language and answers to the field questions from
* the CC License API
*
* @param licenseId - the ID of the license
* @param language - the language for which to retrieve the full answerMap
* @param answerMap - the answers to the different field questions
@@ -273,7 +279,7 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
/**
* Parse the response for the CC License URI request and return the corresponding CC License URI
*
* @param response for a specific CC License URI response
* @param response for a specific CC License URI response
* @return the corresponding CC License URI as a string
* @throws IOException
* @throws JaxenException
@@ -314,5 +320,52 @@ public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService,
return sb.toString();
}
/**
* Retrieve the license RDF document based on the license URI
*
* @param licenseURI - The license URI for which to retrieve the license RDF document
* @return the license RDF document
* @throws IOException
*/
@Override
public Document retrieveLicenseRDFDoc(String licenseURI) throws IOException {
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
String issueUrl = ccLicenseUrl + "/details?license-uri=" + licenseURI;
URL request_url;
try {
request_url = new URL(issueUrl);
} catch (MalformedURLException e) {
return null;
}
URLConnection connection = request_url.openConnection();
connection.setDoOutput(true);
try {
// parsing document from input stream
InputStream stream = connection.getInputStream();
Document doc = parser.build(stream);
return doc;
} catch (Exception e) {
log.error("Error while retrieving the license document for URI: " + licenseURI, e);
}
return null;
}
/**
* Retrieve the license Name from the license document
*
* @param doc - The license document from which to retrieve the license name
* @return the license name
*/
public String retrieveLicenseName(final Document doc) {
try {
return getSingleNodeValue(doc, "//result/license-uri");
} catch (JaxenException e) {
log.error("Error while retrieving the license name from the license document", e);
}
return null;
}
}

View File

@@ -181,8 +181,17 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
}
/**
* Removes the license file from the item
*
* @param context - The relevant DSpace Context
* @param item - The item from which the license file needs to be removed
* @throws SQLException
* @throws IOException
* @throws AuthorizeException
*/
@Override
public void removeLicense(Context context, Item item)
public void removeLicenseFile(Context context, Item item)
throws SQLException, IOException, AuthorizeException {
// remove CC license bundle if one exists
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
@@ -414,24 +423,49 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
return configurationService.getProperty("cc.license." + fieldId);
}
/**
* Remove license information, delete also the bitstream
*
* @param context - DSpace Context
* @param item - the item
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
* to perform a particular action.
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
@Override
public void removeLicense(Context context, LicenseMetadataValue uriField,
LicenseMetadataValue nameField, Item item)
public void removeLicense(Context context, Item item)
throws AuthorizeException, IOException, SQLException {
String uriField = getCCField("uri");
String nameField = getCCField("name");
String licenseUri = itemService.getMetadata(item, uriField);
// only remove any previous licenses
String licenseUri = uriField.ccItemValue(item);
if (licenseUri != null) {
uriField.removeItemValue(context, item, licenseUri);
removeLicenseField(context, item, uriField);
if (configurationService.getBooleanProperty("cc.submit.setname")) {
String licenseName = nameField.keyedItemValue(item, licenseUri);
nameField.removeItemValue(context, item, licenseName);
removeLicenseField(context, item, nameField);
}
if (configurationService.getBooleanProperty("cc.submit.addbitstream")) {
removeLicense(context, item);
removeLicenseFile(context, item);
}
}
}
private void removeLicenseField(Context context, Item item, String field) throws SQLException {
String[] params = splitField(field);
itemService.clearMetadata(context, item, params[0], params[1], params[2], params[3]);
}
private void addLicenseField(Context context, Item item, String field, String value) throws SQLException {
String[] params = splitField(field);
itemService.addMetadata(context, item, params[0], params[1], params[2], params[3], value);
}
/**
* Find all CC Licenses using the default language found in the configuration
*
@@ -623,4 +657,72 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
return null;
}
/**
* Update the license of the item with a new one based on the provided license URI
*
* @param context - The relevant DSpace context
* @param licenseUri - The license URI to be used in the update
* @param item - The item for which to update the license
* @return true when the update was successful, false when not
* @throws AuthorizeException
* @throws SQLException
*/
@Override
public boolean updateLicense(final Context context, final String licenseUri, final Item item)
throws AuthorizeException, SQLException {
try {
Document doc = ccLicenseConnectorService.retrieveLicenseRDFDoc(licenseUri);
String licenseName = ccLicenseConnectorService.retrieveLicenseName(doc);
if (StringUtils.isBlank(licenseName)) {
return false;
}
removeLicense(context, item);
addLicense(context, item, licenseUri, licenseName, doc);
return true;
} catch (IOException e) {
log.error("Error while updating the license of item: " + item.getID(), e);
}
return false;
}
/**
* Add a new license to the item
*
* @param context - The relevant Dspace context
* @param item - The item to which the license will be added
* @param licenseUri - The license URI to add
* @param licenseName - The license name to add
* @param doc - The license to document to add
* @throws SQLException
* @throws IOException
* @throws AuthorizeException
*/
@Override
public void addLicense(Context context, Item item, String licenseUri, String licenseName, Document doc)
throws SQLException, IOException, AuthorizeException {
String uriField = getCCField("uri");
String nameField = getCCField("name");
addLicenseField(context, item, uriField, licenseUri);
if (configurationService.getBooleanProperty("cc.submit.addbitstream")) {
setLicenseRDF(context, item, fetchLicenseRDF(doc));
}
if (configurationService.getBooleanProperty("cc.submit.setname")) {
addLicenseField(context, item, nameField, licenseName);
}
}
private String[] splitField(String fieldName) {
String[] params = new String[4];
String[] fParams = fieldName.split("\\.");
for (int i = 0; i < fParams.length; i++) {
params[i] = fParams[i];
}
params[3] = Item.ANY;
return params;
}
}

View File

@@ -18,7 +18,6 @@ import org.dspace.content.Bitstream;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.license.CCLicense;
import org.dspace.license.LicenseMetadataValue;
import org.jdom.Document;
/**
@@ -77,7 +76,16 @@ public interface CreativeCommonsService {
InputStream licenseStm, String mimeType)
throws SQLException, IOException, AuthorizeException;
public void removeLicense(Context context, Item item)
/**
* Removes the license file from the item
*
* @param context - The relevant DSpace Context
* @param item - The item from which the license file needs to be removed
* @throws SQLException
* @throws IOException
* @throws AuthorizeException
*/
public void removeLicenseFile(Context context, Item item)
throws SQLException, IOException, AuthorizeException;
public boolean hasLicense(Context context, Item item)
@@ -159,16 +167,13 @@ public interface CreativeCommonsService {
* Remove license information, delete also the bitstream
*
* @param context - DSpace Context
* @param uriField - the metadata field for license uri
* @param nameField - the metadata field for license name
* @param item - the item
* @throws AuthorizeException Exception indicating the current user of the context does not have permission
* to perform a particular action.
* @throws IOException A general class of exceptions produced by failed or interrupted I/O operations.
* @throws SQLException An exception that provides information on a database access error or other errors.
*/
public void removeLicense(Context context, LicenseMetadataValue uriField,
LicenseMetadataValue nameField, Item item)
public void removeLicense(Context context, Item item)
throws AuthorizeException, IOException, SQLException;
/**
@@ -265,4 +270,31 @@ public interface CreativeCommonsService {
*/
public boolean verifyLicenseInformation(String licenseId, String language, Map<String, String> fullAnswerMap);
/**
* Update the license of the item with a new one based on the provided license URI
*
* @param context - The relevant DSpace context
* @param licenseUri - The license URI to be used in the update
* @param item - The item for which to update the license
* @return true when the update was successful, false when not
* @throws AuthorizeException
* @throws SQLException
*/
public boolean updateLicense(final Context context, String licenseUri, final Item item)
throws AuthorizeException, SQLException;
/**
* Add a new license to the item
*
* @param context - The relevant Dspace context
* @param item - The item to which the license will be added
* @param licenseUri - The license URI to add
* @param licenseName - The license name to add
* @param doc - The license to document to add
* @throws SQLException
* @throws IOException
* @throws AuthorizeException
*/
public void addLicense(Context context, Item item, String licenseUri, String licenseName, Document doc)
throws SQLException, IOException, AuthorizeException;
}

View File

@@ -35,7 +35,7 @@ public interface AbstractRestProcessingStep extends ListenerProcessingStep {
public static final String UPLOAD_STEP_MOVE_OPERATION_ENTRY = "bitstreammove";
public static final String UPLOAD_STEP_ACCESSCONDITIONS_OPERATION_ENTRY = "accessConditions";
public static final String LICENSE_STEP_OPERATION_ENTRY = "granted";
public static final String CCLICENSE_STEP_OPERATION_ENTRY = "ccLicense";
public static final String CCLICENSE_STEP_OPERATION_ENTRY = "cclicense/uri";
public static final String UPLOAD_STEP_METADATA_PATH = "metadata";

View File

@@ -0,0 +1,66 @@
/**
* 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.rest.submit.factory.impl;
import org.apache.commons.lang3.StringUtils;
import org.dspace.content.InProgressSubmission;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.license.service.CreativeCommonsService;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Submission "add" PATCH operation
*
* To add or update the Creative Commons License of a workspace item.
* When the item already has a Creative Commons License, the license will be replaced with a new one.
*
* Example: <code>
* curl -X PATCH http://${dspace.server.url}/api/submission/workspaceitems/31599 -H "Content-Type:
* application/json" -d '[{ "op": "add", "path": "/sections/cclicense/uri",
* "value":"http://creativecommons.org/licenses/by-nc-sa/3.0/us/"}]'
* </code>
*
*/
public class CCLicenseAddPatchOperation extends AddPatchOperation<String> {
@Autowired
CreativeCommonsService creativeCommonsService;
@Override
protected Class<String[]> getArrayClassForEvaluation() {
return String[].class;
}
@Override
protected Class<String> getClassForEvaluation() {
return String.class;
}
@Override
void add(Context context, Request currentRequest, InProgressSubmission source, String path, Object value)
throws Exception {
String licenseUri = null;
if (value instanceof String) {
licenseUri = (String) value;
}
if (StringUtils.isBlank(licenseUri)) {
throw new IllegalArgumentException(
"Value is not a valid license URI");
}
Item item = source.getItem();
creativeCommonsService.updateLicense(context, licenseUri, item);
}
}

View File

@@ -52,6 +52,10 @@
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamResourcePolicyAddPatchOperation"/>
</entry>
<entry key="cclicense/uri">
<bean
class="org.dspace.app.rest.submit.factory.impl.CCLicenseAddPatchOperation"/>
</entry>
</map>
</entry>
<entry key="remove">

View File

@@ -115,7 +115,7 @@
<!--Step will be to select a Creative Commons License -->
<!-- Uncomment this step to allow the user to select a Creative Commons
license -->
<step id="creative-commons"> <heading>submit.progressbar.CClicense</heading>
<step id="cclicense"> <heading>submit.progressbar.CClicense</heading>
<processing-class>org.dspace.app.rest.submit.step.CCLicenseStep</processing-class>
<type>cclicense</type> </step>
@@ -203,7 +203,7 @@
<!-- <step id="upload-with-embargo"/> -->
<!-- <step id="detect-duplicate"/> -->
<step id="creative-commons"/>
<step id="cclicense"/>
<!--Step will be to Sign off on the License -->
<step id="license"/>