70213: Initial findAll endpoint & backend

This commit is contained in:
Yana De Pauw
2020-04-08 15:14:18 +02:00
parent 8bcbfd692d
commit 6e0396e6ad
22 changed files with 1121 additions and 71 deletions

View File

@@ -8,6 +8,8 @@
package org.dspace.license;
import java.util.List;
/**
* @author wbossons
*/
@@ -15,17 +17,17 @@ public class CCLicense {
private String licenseName;
private String licenseId;
private int order = 0;
private List<CCLicenseField> ccLicenseFieldList;
public CCLicense() {
super();
}
public CCLicense(String licenseId, String licenseName, int order) {
public CCLicense(String licenseId, String licenseName, List<CCLicenseField> ccLicenseFieldList) {
super();
this.licenseId = licenseId;
this.licenseName = licenseName;
this.order = order;
this.ccLicenseFieldList = ccLicenseFieldList;
}
public String getLicenseName() {
@@ -44,13 +46,19 @@ public class CCLicense {
this.licenseId = licenseId;
}
public int getOrder() {
return this.order;
/**
* Gets the list of CC License Fields
* @return the list of CC License Fields
*/
public List<CCLicenseField> getCcLicenseFieldList() {
return ccLicenseFieldList;
}
public void setOrder(int order) {
this.order = order;
/**
* Sets the list of CC License Fields
* @param ccLicenseFieldList
*/
public void setCcLicenseFieldList(final List<CCLicenseField> ccLicenseFieldList) {
this.ccLicenseFieldList = ccLicenseFieldList;
}
}

View File

@@ -0,0 +1,26 @@
/**
* 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.license;
import java.util.List;
/**
* 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
* The service is autowired by spring
*/
public interface CCLicenseConnectorService {
/**
* Retrieves the CC Licenses for the provided language from the CC License API
* @param language - the language to retrieve the licenses for
* @return a list of licenses obtained for the provided languages
*/
public List<CCLicense> retrieveLicenses(String language);
}

View File

@@ -0,0 +1,216 @@
/**
* 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.license;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.services.ConfigurationService;
import org.jaxen.JaxenException;
import org.jaxen.jdom.JDOMXPath;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.xml.sax.InputSource;
/**
* Implementation for the Creative commons license connector service.
* This class is responsible for all the calls to the CC license API and parsing the response
*/
public class CCLicenseConnectorServiceImpl implements CCLicenseConnectorService, InitializingBean {
private Logger log = org.apache.logging.log4j.LogManager.getLogger(CCLicenseConnectorServiceImpl.class);
private CloseableHttpClient client;
private SAXBuilder parser = new SAXBuilder();
@Autowired
private ConfigurationService configurationService;
@Override
public void afterPropertiesSet() throws Exception {
HttpClientBuilder builder = HttpClientBuilder.create();
client = builder
.disableAutomaticRetries()
.setMaxConnTotal(5)
.build();
}
/**
* Retrieves the CC Licenses for the provided language from the CC License API
* @param language - the language to retrieve the licenses for
* @return a list of licenses obtained for the provided languages
*/
public List<CCLicense> retrieveLicenses(String language) {
String ccLicenseUrl = configurationService.getProperty("cc.api.rooturl");
HttpGet httpGet = new HttpGet(ccLicenseUrl + "/?locale=" + language);
List<String> licenses;
try (CloseableHttpResponse response = client.execute(httpGet)) {
licenses = retrieveLicenses(response);
} catch (JDOMException | JaxenException | IOException e) {
log.error(e);
licenses = Collections.emptyList();
}
List<CCLicense> ccLicenses = new LinkedList<>();
for (String license : licenses) {
HttpGet licenseHttpGet = new HttpGet(ccLicenseUrl + "/license/" + license);
try (CloseableHttpResponse response = client.execute(licenseHttpGet)) {
CCLicense ccLicense = retrieveLicenseObject(response);
ccLicenses.add(ccLicense);
} catch (JaxenException | JDOMException | IOException e) {
log.error(e);
}
}
return ccLicenses;
}
/**
* Retrieve the list of licenses from the response from the CC License API and remove the licenses configured
* to be excluded
* @param response The response from the API
* @return a list of license identifiers for which details need to be retrieved
* @throws IOException
* @throws JaxenException
* @throws JDOMException
*/
private List<String> retrieveLicenses(CloseableHttpResponse response)
throws IOException, JaxenException, JDOMException {
List<String> domains = new LinkedList<>();
String[] excludedLicenses = configurationService.getArrayProperty("cc.license.classfilter");
String responseString = EntityUtils.toString(response.getEntity());
JDOMXPath licenseClassXpath = new JDOMXPath("//licenses/license");
InputSource is = new InputSource(new StringReader(responseString));
org.jdom.Document classDoc = this.parser.build(is);
List<Element> elements = licenseClassXpath.selectNodes(classDoc);
for (Element element : elements) {
String licenseId = getSingleNodeValue(element, "@id");
if (StringUtils.isNotBlank(licenseId) && !ArrayUtils.contains(excludedLicenses, licenseId)) {
domains.add(licenseId);
}
}
return domains;
}
/**
* Parse the response for a single CC License and return the corresponding CC License Object
* @param response for a specific CC License response
* @return the corresponding CC License Object
* @throws IOException
* @throws JaxenException
* @throws JDOMException
*/
private CCLicense retrieveLicenseObject(CloseableHttpResponse response)
throws IOException, JaxenException, JDOMException {
String responseString = EntityUtils.toString(response.getEntity());
JDOMXPath licenseClassXpath = new JDOMXPath("//licenseclass");
JDOMXPath licenseFieldXpath = new JDOMXPath("field");
InputSource is;
is = new InputSource(new StringReader(responseString));
org.jdom.Document classDoc = this.parser.build(is);
Object element = licenseClassXpath.selectSingleNode(classDoc);
String licenseId = getSingleNodeValue(element, "@id");
String licenseLabel = getSingleNodeValue(element, "label");
List<CCLicenseField> ccLicenseFields = new LinkedList<>();
List<Element> licenseFields = licenseFieldXpath.selectNodes(element);
for (Element licenseField : licenseFields) {
CCLicenseField ccLicenseField = parseLicenseField(licenseField);
ccLicenseFields.add(ccLicenseField);
}
return new CCLicense(licenseId, licenseLabel, ccLicenseFields);
}
private CCLicenseField parseLicenseField(final Element licenseField) throws JaxenException {
String id = getSingleNodeValue(licenseField, "@id");
String label = getSingleNodeValue(licenseField, "label");
String description = getSingleNodeValue(licenseField, "description");
JDOMXPath enumXpath = new JDOMXPath("enum");
List<Element> enums = enumXpath.selectNodes(licenseField);
List<CCLicenseFieldEnum> ccLicenseFieldEnumList = new LinkedList<>();
for (Element enumElement : enums) {
CCLicenseFieldEnum ccLicenseFieldEnum = parseEnum(enumElement);
ccLicenseFieldEnumList.add(ccLicenseFieldEnum);
}
return new CCLicenseField(id, label, description, ccLicenseFieldEnumList);
}
private CCLicenseFieldEnum parseEnum(final Element enumElement) throws JaxenException {
String id = getSingleNodeValue(enumElement, "@id");
String label = getSingleNodeValue(enumElement, "label");
String description = getSingleNodeValue(enumElement, "description");
return new CCLicenseFieldEnum(id, label, description);
}
private String getNodeValue(final Object el) {
if (el instanceof Element) {
return ((Element) el).getValue();
} else if (el instanceof Attribute) {
return ((Attribute) el).getValue();
} else if (el instanceof String) {
return (String) el;
} else {
return null;
}
}
private String getSingleNodeValue(final Object t, String query) throws JaxenException {
JDOMXPath xpath = new JDOMXPath(query);
Object singleNode = xpath.selectSingleNode(t);
return getNodeValue(singleNode);
}
}

View File

@@ -7,8 +7,7 @@
*/
package org.dspace.license;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
/**
* Wrapper class for representation of a license field declaration.
@@ -22,7 +21,7 @@ public class CCLicenseField {
private String description = "";
private String type = "";
private HashMap fieldEnum = null;
private List<CCLicenseFieldEnum> fieldEnum = null;
/**
* Construct a new LicenseField class. Note that after construction,
@@ -31,13 +30,11 @@ public class CCLicenseField {
* @param id The unique identifier for this field; this value will be used in constructing the answers XML.
* @param label The label to use when generating the user interface.
*/
public CCLicenseField(String id, String label) {
super();
this.fieldEnum = new HashMap();
public CCLicenseField(String id, String label, String description, List<CCLicenseFieldEnum> fieldEnum) {
this.id = id;
this.label = label;
this.description = description;
this.fieldEnum = fieldEnum;
}
/**
@@ -90,16 +87,12 @@ public class CCLicenseField {
}
/**
* @return Returns an instance implementing the Map interface;
* the instance contains a mapping from identifiers to
* labels for the enumeration values.
* @see Map
* Returns the list of enums of this field
* @return the list of enums of this field
*/
public Map<String, String> getEnum() {
return this.fieldEnum;
public List<CCLicenseFieldEnum> getFieldEnum() {
return fieldEnum;
}
}

View File

@@ -0,0 +1,82 @@
/**
* 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.license;
import org.apache.commons.lang3.StringUtils;
/**
* Wrapper class for representation of a license field enum declaration.
* A field enum is a single "answer" to the field question
*/
public class CCLicenseFieldEnum {
private String id = "";
private String label = "";
private String description = "";
public CCLicenseFieldEnum(String id, String label, String description) {
if (StringUtils.isNotBlank(id)) {
this.id = id;
}
if (StringUtils.isNotBlank(label)) {
this.label = label;
}
if (StringUtils.isNotBlank(description)) {
this.description = description;
}
}
/**
* Get the id of this enum
* @return the id of this enum
*/
public String getId() {
return id;
}
/**
* Set the id of this enum
* @param id
*/
public void setId(final String id) {
this.id = id;
}
/**
* Get the label of this enum
* @return the label of this enum
*/
public String getLabel() {
return label;
}
/**
* Set the label of this enum
* @param label
*/
public void setLabel(final String label) {
this.label = label;
}
/**
* Get the description of this enum
* @return the description of this enum
*/
public String getDescription() {
return description;
}
/**
* Set the description of this enum
* @param description
*/
public void setDescription(final String description) {
this.description = description;
}
}

View File

@@ -128,7 +128,7 @@ public class CCLookup {
// add if not filtered
String liD = ((Attribute) xp_LicenseID.selectSingleNode(license)).getValue();
if (!lcFilter.contains(liD)) {
this.licenses.add(new CCLicense(liD, license.getText(), i));
// this.licenses.add(new CCLicense(liD, license.getText(), i));
}
}
} catch (JaxenException jaxen_e) {
@@ -213,30 +213,30 @@ public class CCLookup {
for (int i = 0; i < results.size(); i++) {
Element field = (Element) results.get(i);
try {
// create the field object
CCLicenseField cclicensefield = new CCLicenseField(
((Attribute) xp_LicenseID.selectSingleNode(field)).getValue(),
((Element) xp_Label.selectSingleNode(field)).getText());
// extract additional properties
cclicensefield.setDescription(((Element) xp_Description.selectSingleNode(field)).getText());
cclicensefield.setType(((Element) xp_FieldType.selectSingleNode(field)).getText());
enumOptions = xp_Enum.selectNodes(field);
for (int j = 0; j < enumOptions.size(); j++) {
String id = ((Attribute) xp_LicenseID.selectSingleNode(enumOptions.get(j))).getValue();
String label = ((Element) xp_Label.selectSingleNode(enumOptions.get(j))).getText();
cclicensefield.getEnum().put(id, label);
} // for each enum option
this.licenseFields.add(cclicensefield);
} catch (JaxenException e) {
return null;
}
// try {
// // create the field object
// CCLicenseField cclicensefield = new CCLicenseField(
// ((Attribute) xp_LicenseID.selectSingleNode(field)).getValue(),
// ((Element) xp_Label.selectSingleNode(field)).getText());
//
// // extract additional properties
// cclicensefield.setDescription(((Element) xp_Description.selectSingleNode(field)).getText());
// cclicensefield.setType(((Element) xp_FieldType.selectSingleNode(field)).getText());
//
// enumOptions = xp_Enum.selectNodes(field);
//
// for (int j = 0; j < enumOptions.size(); j++) {
// String id = ((Attribute) xp_LicenseID.selectSingleNode(enumOptions.get(j))).getValue();
// String label = ((Element) xp_Label.selectSingleNode(enumOptions.get(j))).getText();
//
//// cclicensefield.getEnum().put(id, label);
//
// } // for each enum option
//
// this.licenseFields.add(cclicensefield);
// } catch (JaxenException e) {
// return null;
// }
}
return licenseFields;

View File

@@ -82,9 +82,13 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
protected BundleService bundleService;
@Autowired(required = true)
protected ItemService itemService;
@Autowired
protected CCLicenseConnectorService ccLicenseConnectorService;
protected ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
private List<CCLicense> ccLicenses;
protected CreativeCommonsServiceImpl() {
}
@@ -103,8 +107,8 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
try {
templates = TransformerFactory.newInstance().newTemplates(
new StreamSource(CreativeCommonsServiceImpl.class
.getResourceAsStream("CreativeCommons.xsl")));
new StreamSource(CreativeCommonsServiceImpl.class
.getResourceAsStream("CreativeCommons.xsl")));
} catch (TransformerConfigurationException e) {
throw new RuntimeException(e.getMessage(), e);
}
@@ -120,7 +124,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
// create the CC bundle if it doesn't exist
// If it does, remove it and create a new one.
protected Bundle getCcBundle(Context context, Item item)
throws SQLException, AuthorizeException, IOException {
throws SQLException, AuthorizeException, IOException {
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
if ((bundles.size() > 0) && (bundles.get(0) != null)) {
@@ -131,8 +135,8 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
@Override
public void setLicenseRDF(Context context, Item item, String licenseRdf)
throws SQLException, IOException,
AuthorizeException {
throws SQLException, IOException,
AuthorizeException {
Bundle bundle = getCcBundle(context, item);
// set the format
BitstreamFormat bs_rdf_format = bitstreamFormatService.findByShortDescription(context, "RDF XML");
@@ -144,7 +148,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
@Override
public void setLicense(Context context, Item item,
InputStream licenseStm, String mimeType)
throws SQLException, IOException, AuthorizeException {
throws SQLException, IOException, AuthorizeException {
Bundle bundle = getCcBundle(context, item);
// set the format
@@ -160,9 +164,9 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
Bitstream bs = bitstreamService.create(context, bundle, licenseStm);
bs.setSource(context, CC_BS_SOURCE);
bs.setName(context, (mimeType != null &&
(mimeType.equalsIgnoreCase("text/xml") ||
mimeType.equalsIgnoreCase("text/rdf"))) ?
BSN_LICENSE_RDF : BSN_LICENSE_TEXT);
(mimeType.equalsIgnoreCase("text/xml") ||
mimeType.equalsIgnoreCase("text/rdf"))) ?
BSN_LICENSE_RDF : BSN_LICENSE_TEXT);
bs.setFormat(context, bs_format);
bitstreamService.update(context, bs);
}
@@ -170,7 +174,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
@Override
public void removeLicense(Context context, Item item)
throws SQLException, IOException, AuthorizeException {
throws SQLException, IOException, AuthorizeException {
// remove CC license bundle if one exists
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
@@ -181,7 +185,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
@Override
public boolean hasLicense(Context context, Item item)
throws SQLException, IOException {
throws SQLException, IOException {
// try to find CC license bundle
List<Bundle> bundles = itemService.getBundles(item, CC_BUNDLE_NAME);
@@ -203,20 +207,20 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
@Override
public String getLicenseRDF(Context context, Item item) throws SQLException,
IOException, AuthorizeException {
IOException, AuthorizeException {
return getStringFromBitstream(context, item, BSN_LICENSE_RDF);
}
@Override
public Bitstream getLicenseRdfBitstream(Item item) throws SQLException,
IOException, AuthorizeException {
IOException, AuthorizeException {
return getBitstream(item, BSN_LICENSE_RDF);
}
@Deprecated
@Override
public Bitstream getLicenseTextBitstream(Item item) throws SQLException,
IOException, AuthorizeException {
IOException, AuthorizeException {
return getBitstream(item, BSN_LICENSE_TEXT);
}
@@ -237,8 +241,8 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
try {
templates.newTransformer().transform(
new JDOMSource(license),
new StreamResult(result)
new JDOMSource(license),
new StreamResult(result)
);
} catch (TransformerException e) {
throw new IllegalStateException(e.getMessage(), e);
@@ -267,7 +271,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
*/
protected void setBitstreamFromBytes(Context context, Item item, Bundle bundle,
String bitstream_name, BitstreamFormat format, byte[] bytes)
throws SQLException, IOException, AuthorizeException {
throws SQLException, IOException, AuthorizeException {
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
Bitstream bs = bitstreamService.create(context, bundle, bais);
@@ -297,7 +301,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
*/
protected String getStringFromBitstream(Context context, Item item,
String bitstream_name) throws SQLException, IOException,
AuthorizeException {
AuthorizeException {
byte[] bytes = getBytesFromBitstream(context, item, bitstream_name);
if (bytes == null) {
@@ -320,7 +324,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
* to perform a particular action.
*/
protected Bitstream getBitstream(Item item, String bitstream_name)
throws SQLException, IOException, AuthorizeException {
throws SQLException, IOException, AuthorizeException {
Bundle cc_bundle = null;
// look for the CC bundle
@@ -342,7 +346,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
}
protected byte[] getBytesFromBitstream(Context context, Item item, String bitstream_name)
throws SQLException, IOException, AuthorizeException {
throws SQLException, IOException, AuthorizeException {
Bitstream bs = getBitstream(item, bitstream_name);
// no such bitstream
@@ -368,7 +372,7 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
@Override
public void removeLicense(Context context, LicenseMetadataValue uriField,
LicenseMetadataValue nameField, Item item)
throws AuthorizeException, IOException, SQLException {
throws AuthorizeException, IOException, SQLException {
// only remove any previous licenses
String licenseUri = uriField.ccItemValue(item);
if (licenseUri != null) {
@@ -383,4 +387,26 @@ public class CreativeCommonsServiceImpl implements CreativeCommonsService, Initi
}
}
/**
* Find all CC Licenses using the default language found in the configuration
* @return A list of available CC Licenses
*/
public List<CCLicense> findAllCCLicenses() {
String language = configurationService.getProperty("cc.license.locale", "en");
return findAllCCLicenses(language);
}
/**
* Find all CC Licenses for the provided language
* @param language - the language for which to find the CC Licenses
* @return A list of available CC Licenses for the provided language
*/
public List<CCLicense> findAllCCLicenses(String language) {
if (ccLicenses == null || ccLicenses.isEmpty()) {
ccLicenses = ccLicenseConnectorService.retrieveLicenses(language);
}
return ccLicenses;
}
}

View File

@@ -10,11 +10,13 @@ package org.dspace.license.service;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.List;
import org.dspace.authorize.AuthorizeException;
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;
@@ -149,4 +151,19 @@ public interface CreativeCommonsService {
public void removeLicense(Context context, LicenseMetadataValue uriField,
LicenseMetadataValue nameField, Item item)
throws AuthorizeException, IOException, SQLException;
/**
* Find all CC Licenses using the default language found in the configuration
*
* @return A list of available CC Licenses
*/
public List<CCLicense> findAllCCLicenses();
/**
* Find all CC Licenses for the provided language
*
* @param language - the language for which to find the CC Licenses
* @return A list of available CC Licenses for the provided language
*/
public List<CCLicense> findAllCCLicenses(String language);
}

View File

@@ -0,0 +1,72 @@
/**
* 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.license;
import java.util.LinkedList;
import java.util.List;
/**
* Mock implementation for the Creative commons license connector service.
* This class will return a structure of CC Licenses similar to the CC License API but without having to contact it
*/
public class MockCCLicenseConnectorServiceImpl extends CCLicenseConnectorServiceImpl {
/**
* Retrieves mock CC Licenses for the provided language
* @param language - the language
* @return a list of mocked licenses
*/
public List<CCLicense> retrieveLicenses(String language) {
List<CCLicense> ccLicenses = new LinkedList<>();
ccLicenses.add(createMockLicense(1, new int[]{3, 2, 3}));
ccLicenses.add(createMockLicense(2, new int[]{2}));
ccLicenses.add(createMockLicense(3, new int[]{}));
return ccLicenses;
}
private CCLicense createMockLicense(int count, int[] amountOfFieldsAndEnums) {
String licenseId = "license" + count;
String licenseName = "License " + count + " - Name";
List<CCLicenseField> mockLicenseFields = createMockLicenseFields(count, amountOfFieldsAndEnums);
return new CCLicense(licenseId, licenseName, mockLicenseFields);
}
private List<CCLicenseField> createMockLicenseFields(int count, int[] amountOfFieldsAndEnums) {
List<CCLicenseField> ccLicenseFields = new LinkedList<>();
for (int index = 0; index < amountOfFieldsAndEnums.length; index++) {
String licenseFieldId = "license" + count + "-field" + index;
String licenseFieldLabel = "License " + count + " - Field " + index + " - Label";
String licenseFieldDescription = "License " + count + " - Field " + index + " - Description";
List<CCLicenseFieldEnum> mockLicenseFields = createMockLicenseFields(count,
index,
amountOfFieldsAndEnums[index]);
ccLicenseFields.add(new CCLicenseField(licenseFieldId,
licenseFieldLabel,
licenseFieldDescription,
mockLicenseFields));
}
return ccLicenseFields;
}
private List<CCLicenseFieldEnum> createMockLicenseFields(int count, int index, int amountOfEnums) {
List<CCLicenseFieldEnum> ccLicenseFieldEnumList = new LinkedList<>();
for (int i = 0; i < amountOfEnums; i++) {
String enumId = "license" + count + "-field" + index + "-enum" + i;
String enumLabel = "License " + count + " - Field " + index + " - Enum " + i + " - Label";
String enumDescription = "License " + count + " - Field " + index + " - Enum " + i + " - " +
"Description";
ccLicenseFieldEnumList.add(new CCLicenseFieldEnum(enumId, enumLabel, enumDescription));
}
return ccLicenseFieldEnumList;
}
}

View File

@@ -0,0 +1,59 @@
/**
* 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.converter;
import java.util.LinkedList;
import java.util.List;
import org.dspace.app.rest.model.SubmissionCCLicenseFieldRest;
import org.dspace.app.rest.model.SubmissionCCLicenseRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.license.CCLicense;
import org.dspace.license.CCLicenseField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* This converter is responsible for transforming the model representation of an CCLicense to the REST
* representation of an CCLicense and vice versa
**/
@Component
public class SubmissionCCLicenseConverter implements DSpaceConverter<CCLicense, SubmissionCCLicenseRest> {
@Autowired
private ConverterService converter;
/**
* Convert a CCLicense to its REST representation
* @param modelObject - the CCLicense to convert
* @param projection - the projection
* @return the corresponding SubmissionCCLicenseRest object
*/
@Override
public SubmissionCCLicenseRest convert(final CCLicense modelObject, final Projection projection) {
SubmissionCCLicenseRest submissionCCLicenseRest = new SubmissionCCLicenseRest();
submissionCCLicenseRest.setProjection(projection);
submissionCCLicenseRest.setId(modelObject.getLicenseId());
submissionCCLicenseRest.setName(modelObject.getLicenseName());
List<CCLicenseField> ccLicenseFieldList = modelObject.getCcLicenseFieldList();
List<SubmissionCCLicenseFieldRest> submissionCCLicenseFieldRests = new LinkedList<>();
if (ccLicenseFieldList != null) {
for (CCLicenseField ccLicenseField : ccLicenseFieldList) {
submissionCCLicenseFieldRests.add(converter.toRest(ccLicenseField, projection));
}
}
submissionCCLicenseRest.setFields(submissionCCLicenseFieldRests);
return submissionCCLicenseRest;
}
public Class<CCLicense> getModelClass() {
return CCLicense.class;
}
}

View File

@@ -0,0 +1,61 @@
/**
* 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.converter;
import java.util.LinkedList;
import java.util.List;
import org.dspace.app.rest.model.SubmissionCCLicenseFieldEnumRest;
import org.dspace.app.rest.model.SubmissionCCLicenseFieldRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.license.CCLicenseField;
import org.dspace.license.CCLicenseFieldEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* This converter is responsible for transforming the model representation of an CCLicenseField to the REST
* representation of an CCLicenseField and vice versa
* The CCLicenseField is a sub component of the CCLicense object
**/
@Component
public class SubmissionCCLicenseFieldConverter
implements DSpaceConverter<CCLicenseField, SubmissionCCLicenseFieldRest> {
@Autowired
private ConverterService converter;
/**
* Convert a CCLicenseField to its REST representation
* @param modelObject - the CCLicenseField to convert
* @param projection - the projection
* @return the corresponding SubmissionCCLicenseFieldRest object
*/
@Override
public SubmissionCCLicenseFieldRest convert(final CCLicenseField modelObject, final Projection projection) {
SubmissionCCLicenseFieldRest submissionCCLicenseFieldRest = new SubmissionCCLicenseFieldRest();
submissionCCLicenseFieldRest.setId(modelObject.getId());
submissionCCLicenseFieldRest.setLabel(modelObject.getLabel());
submissionCCLicenseFieldRest.setDescription(modelObject.getDescription());
List<CCLicenseFieldEnum> fieldEnum = modelObject.getFieldEnum();
List<SubmissionCCLicenseFieldEnumRest> submissionCCLicenseFieldEnumRests = new LinkedList<>();
if (fieldEnum != null) {
for (CCLicenseFieldEnum ccLicenseFieldEnum : fieldEnum) {
submissionCCLicenseFieldEnumRests.add(converter.toRest(ccLicenseFieldEnum, projection));
}
}
submissionCCLicenseFieldRest.setEnums(submissionCCLicenseFieldEnumRests);
return submissionCCLicenseFieldRest;
}
public Class<CCLicenseField> getModelClass() {
return CCLicenseField.class;
}
}

View File

@@ -0,0 +1,45 @@
/**
* 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.converter;
import org.dspace.app.rest.model.SubmissionCCLicenseFieldEnumRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.license.CCLicenseFieldEnum;
import org.springframework.stereotype.Component;
/**
* This converter is responsible for transforming the model representation of an CCLicenseFieldEnum to the REST
* representation of an CCLicenseFieldEnum and vice versa
* The CCLicenseFieldEnum is a sub component of the CCLicenseField object
**/
@Component
public class SubmissionCCLicenseFieldEnumConverter
implements DSpaceConverter<CCLicenseFieldEnum, SubmissionCCLicenseFieldEnumRest> {
/**
* Convert a CCLicenseFieldEnum to its REST representation
*
* @param modelObject - the CCLicenseField to convert
* @param projection - the projection
* @return the corresponding SubmissionCCLicenseFieldEnumRest object
*/
@Override
public SubmissionCCLicenseFieldEnumRest convert(final CCLicenseFieldEnum modelObject, final Projection projection) {
SubmissionCCLicenseFieldEnumRest submissionCCLicenseFieldEnumRest = new SubmissionCCLicenseFieldEnumRest();
submissionCCLicenseFieldEnumRest.setId(modelObject.getId());
submissionCCLicenseFieldEnumRest.setLabel(modelObject.getLabel());
submissionCCLicenseFieldEnumRest.setDescription(modelObject.getDescription());
return submissionCCLicenseFieldEnumRest;
}
public Class<CCLicenseFieldEnum> getModelClass() {
return CCLicenseFieldEnum.class;
}
}

View File

@@ -0,0 +1,44 @@
/**
* 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.model;
/**
* This class is the REST representation of the CCLicenseFieldEnum model object and acts as a data sub object
* for the SubmissionCCLicenseFieldRest class.
* Refer to {@link org.dspace.license.CCLicenseFieldEnum} for explanation of the properties
*/
public class SubmissionCCLicenseFieldEnumRest {
private String id;
private String label;
private String description;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(final String label) {
this.label = label;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
}

View File

@@ -0,0 +1,59 @@
/**
* 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.model;
import java.util.List;
/**
* This class is the REST representation of the CCLicenseField model object and acts as a data sub object
* for the SubmissionCCLicenseRest class.
* Refer to {@link org.dspace.license.CCLicenseField} for explanation of the properties
*/
public class SubmissionCCLicenseFieldRest {
private String id;
private String label;
private String description;
private List<SubmissionCCLicenseFieldEnumRest> enums;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(final String label) {
this.label = label;
}
public String getDescription() {
return description;
}
public void setDescription(final String description) {
this.description = description;
}
public List<SubmissionCCLicenseFieldEnumRest> getEnums() {
return enums;
}
public void setEnums(final List<SubmissionCCLicenseFieldEnumRest> enums) {
this.enums = enums;
}
}

View File

@@ -0,0 +1,73 @@
/**
* 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.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.dspace.app.rest.RestResourceController;
/**
* This class is the REST representation of the CCLicense model object and acts as a data object
* * for the SubmissionCCLicenseResource class.
* Refer to {@link org.dspace.license.CCLicense} for explanation of the properties
*/
public class SubmissionCCLicenseRest extends BaseObjectRest<String> {
public static final String NAME = "submissioncclicense";
public static final String CATEGORY = RestAddressableModel.CONFIGURATION;
private String id;
private String name;
private List<SubmissionCCLicenseFieldRest> fields;
public String getId() {
return id;
}
public void setId(final String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public List<SubmissionCCLicenseFieldRest> getFields() {
return fields;
}
public void setFields(final List<SubmissionCCLicenseFieldRest> fields) {
this.fields = fields;
}
@JsonIgnore
@Override
public String getCategory() {
return CATEGORY;
}
@Override
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public String getType() {
return NAME;
}
@Override
@JsonIgnore
public Class getController() {
return RestResourceController.class;
}
}

View File

@@ -0,0 +1,23 @@
/**
* 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.model.hateoas;
import org.dspace.app.rest.model.SubmissionCCLicenseRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* CCLicense HAL Resource. This resource adds the data from the REST object together with embedded objects
* and a set of links if applicable
*/
@RelNameDSpaceResource(SubmissionCCLicenseRest.NAME)
public class SubmissionCCLicenseResource extends DSpaceResource<SubmissionCCLicenseRest> {
public SubmissionCCLicenseResource(SubmissionCCLicenseRest submissionCCLicenseRest, Utils utils) {
super(submissionCCLicenseRest, utils);
}
}

View File

@@ -0,0 +1,44 @@
/**
* 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.repository;
import java.util.List;
import org.dspace.app.rest.model.SubmissionCCLicenseRest;
import org.dspace.core.Context;
import org.dspace.license.CCLicense;
import org.dspace.license.service.CreativeCommonsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
/**
* This is the repository that is responsible to manage CCLicense Rest objects
*/
@Component(SubmissionCCLicenseRest.CATEGORY + "." + SubmissionCCLicenseRest.NAME)
public class SubmissionCCLicenseRestRepository extends DSpaceRestRepository<SubmissionCCLicenseRest, String> {
@Autowired
protected CreativeCommonsService creativeCommonsService;
public SubmissionCCLicenseRest findOne(final Context context, final String s) {
return null;
}
public Page<SubmissionCCLicenseRest> findAll(final Context context, final Pageable pageable) {
List<CCLicense> allCCLicenses = creativeCommonsService.findAllCCLicenses();
return converter.toRestPage(utils.getPage(allCCLicenses, pageable), utils.obtainProjection());
}
public Class<SubmissionCCLicenseRest> getDomainClass() {
return null;
}
}

View File

@@ -6,4 +6,5 @@
<!-- Replace harvestCollectionService with a mocked service -->
<bean class="org.dspace.harvest.MockHarvestedCollectionServiceImpl" id="org.dspace.harvest.service.HarvestedCollectionService" primary="true"/>
<bean class="org.dspace.license.MockCCLicenseConnectorServiceImpl" id="org.dspace.license.CCLicenseConnectorService" primary="true"/>
</beans>

View File

@@ -0,0 +1,46 @@
/**
* 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;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.matcher.SubmissionCCLicenseMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.hamcrest.Matchers;
import org.junit.Test;
/**
* Class to the methods from the SubmissionCCLicenseRestRepository
* Since the CC Licenses are obtained from the CC License API, a mock service has been implemented
* This mock service will return a fixed set of CC Licenses using a similar structure to the ones obtained from the
* CC License API.
* Refer to {@link org.dspace.license.MockCCLicenseConnectorServiceImpl} for more information
*/
public class SubmissionCCLicenseRestRepositoryIT extends AbstractControllerIntegrationTest {
/**
* Test the findAll method form the SubmissionCCLicenseRestRepository
* @throws Exception
*/
@Test
public void findAllTest() throws Exception {
getClient().perform(get("/api/config/submissioncclicenses"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissioncclicenses", Matchers.containsInAnyOrder(
SubmissionCCLicenseMatcher.matchLicenseEntry(1, new int[]{3, 2, 3}),
SubmissionCCLicenseMatcher.matchLicenseEntry(2, new int[]{2}),
SubmissionCCLicenseMatcher.matchLicenseEntry(3, new int[]{})
)));
}
}

View File

@@ -0,0 +1,82 @@
/**
* 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.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import java.util.LinkedList;
import java.util.List;
import org.hamcrest.Matcher;
public class SubmissionCCLicenseMatcher {
private SubmissionCCLicenseMatcher() {
}
public static Matcher<? super Object> matchLicenseEntry(int count, int[] amountOfFieldsAndEnums) {
return allOf(
matchLicenseProperties(count),
matchFields(count, amountOfFieldsAndEnums)
);
}
private static Matcher<? super Object> matchFields(int count, int[] amountOfFieldsAndEnums) {
List<Matcher<? super Object>> matchers = new LinkedList<>();
for (int index = 0; index < amountOfFieldsAndEnums.length; index++) {
matchers.add(matchField(count, index, amountOfFieldsAndEnums[index]));
}
return hasJsonPath("$.fields", containsInAnyOrder(matchers));
}
private static Matcher<? super Object> matchField(int count, int fieldIndex, int amountOfEnums) {
return allOf(
matchLicenseFieldProperties(count, fieldIndex),
matchEnums(count, fieldIndex, amountOfEnums)
);
}
private static Matcher<? super Object> matchEnums(int count, int fieldIndex, int amountOfEnums) {
List<Matcher<? super Object>> matchers = new LinkedList<>();
for (int index = 0; index < amountOfEnums; index++) {
matchers.add(matchLicenseFieldEnumProperties(count, fieldIndex, index));
}
// return hasJsonPath("$.enums");
return hasJsonPath("$.enums", containsInAnyOrder(matchers));
}
public static Matcher<? super Object> matchLicenseProperties(int count) {
return allOf(
hasJsonPath("$.id", is("license" + count)),
hasJsonPath("$.name", is("License " + count + " - Name"))
);
}
public static Matcher<? super Object> matchLicenseFieldProperties(int count, int fieldIndex) {
return allOf(
hasJsonPath("$.id", is("license" + count + "-field" + fieldIndex)),
hasJsonPath("$.label", is("License " + count + " - Field " + fieldIndex + " - Label")),
hasJsonPath("$.description", is("License " + count + " - Field " + fieldIndex + " - Description"))
);
}
public static Matcher<? super Object> matchLicenseFieldEnumProperties(int count, int fieldIndex, int enumIndex) {
return allOf(
hasJsonPath("$.id", is("license" + count + "-field" + fieldIndex + "-enum" + enumIndex)),
hasJsonPath("$.label",
is("License " + count + " - Field " + fieldIndex + " - Enum " + enumIndex + " - Label")),
hasJsonPath("$.description",
is("License " + count + " - Field " + fieldIndex + " - Enum " + enumIndex + " - " + "Description"))
);
}
}

View File

@@ -0,0 +1,72 @@
/**
* 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.license;
import java.util.LinkedList;
import java.util.List;
/**
* Mock implementation for the Creative commons license connector service.
* This class will return a structure of CC Licenses similar to the CC License API but without having to contact it
*/
public class MockCCLicenseConnectorServiceImpl extends CCLicenseConnectorServiceImpl {
/**
* Retrieves mock CC Licenses for the provided language
* @param language - the language
* @return a list of mocked licenses
*/
public List<CCLicense> retrieveLicenses(String language) {
List<CCLicense> ccLicenses = new LinkedList<>();
ccLicenses.add(createMockLicense(1, new int[]{3, 2, 3}));
ccLicenses.add(createMockLicense(2, new int[]{2}));
ccLicenses.add(createMockLicense(3, new int[]{}));
return ccLicenses;
}
private CCLicense createMockLicense(int count, int[] amountOfFieldsAndEnums) {
String licenseId = "license" + count;
String licenseName = "License " + count + " - Name";
List<CCLicenseField> mockLicenseFields = createMockLicenseFields(count, amountOfFieldsAndEnums);
return new CCLicense(licenseId, licenseName, mockLicenseFields);
}
private List<CCLicenseField> createMockLicenseFields(int count, int[] amountOfFieldsAndEnums) {
List<CCLicenseField> ccLicenseFields = new LinkedList<>();
for (int index = 0; index < amountOfFieldsAndEnums.length; index++) {
String licenseFieldId = "license" + count + "-field" + index;
String licenseFieldLabel = "License " + count + " - Field " + index + " - Label";
String licenseFieldDescription = "License " + count + " - Field " + index + " - Description";
List<CCLicenseFieldEnum> mockLicenseFields = createMockLicenseFields(count,
index,
amountOfFieldsAndEnums[index]);
ccLicenseFields.add(new CCLicenseField(licenseFieldId,
licenseFieldLabel,
licenseFieldDescription,
mockLicenseFields));
}
return ccLicenseFields;
}
private List<CCLicenseFieldEnum> createMockLicenseFields(int count, int index, int amountOfEnums) {
List<CCLicenseFieldEnum> ccLicenseFieldEnumList = new LinkedList<>();
for (int i = 0; i < amountOfEnums; i++) {
String enumId = "license" + count + "-field" + index + "-enum" + i;
String enumLabel = "License " + count + " - Field " + index + " - Enum " + i + " - Label";
String enumDescription = "License " + count + " - Field " + index + " - Enum " + i + " - " +
"Description";
ccLicenseFieldEnumList.add(new CCLicenseFieldEnum(enumId, enumLabel, enumDescription));
}
return ccLicenseFieldEnumList;
}
}

View File

@@ -100,6 +100,7 @@
<bean class="org.dspace.identifier.DOIServiceImpl"/>
<bean class="org.dspace.license.CreativeCommonsServiceImpl"/>
<bean class="org.dspace.license.CCLicenseConnectorServiceImpl"/>
<bean id="spiderDetectorService" class="org.dspace.statistics.util.SpiderDetectorServiceImpl"/>
<bean id="clientInfoService" class="org.dspace.service.impl.ClientInfoServiceImpl"/>