mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-13 13:03:11 +00:00
Merge branch 'CST-5306' into CST-5669
This commit is contained in:
@@ -530,14 +530,6 @@
|
|||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>fontbox</artifactId>
|
<artifactId>fontbox</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>xalan</groupId>
|
|
||||||
<artifactId>xalan</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>xerces</groupId>
|
|
||||||
<artifactId>xercesImpl</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.ibm.icu</groupId>
|
<groupId>com.ibm.icu</groupId>
|
||||||
<artifactId>icu4j</artifactId>
|
<artifactId>icu4j</artifactId>
|
||||||
@@ -687,13 +679,6 @@
|
|||||||
<version>1.1.1</version>
|
<version>1.1.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Gson: Java to Json conversion -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
|
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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.access.status;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin interface for the access status calculation.
|
||||||
|
*/
|
||||||
|
public interface AccessStatusHelper {
|
||||||
|
/**
|
||||||
|
* Calculate the access status for the item.
|
||||||
|
*
|
||||||
|
* @param context the DSpace context
|
||||||
|
* @param item the item
|
||||||
|
* @return an access status value
|
||||||
|
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||||
|
*/
|
||||||
|
public String getAccessStatusFromItem(Context context, Item item, Date threshold)
|
||||||
|
throws SQLException;
|
||||||
|
}
|
@@ -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.access.status;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.dspace.access.status.service.AccessStatusService;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.core.service.PluginService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for the access status calculation service.
|
||||||
|
*/
|
||||||
|
public class AccessStatusServiceImpl implements AccessStatusService {
|
||||||
|
// Plugin implementation, set from the DSpace configuration by init().
|
||||||
|
protected AccessStatusHelper helper = null;
|
||||||
|
|
||||||
|
protected Date forever_date = null;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected ConfigurationService configurationService;
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
protected PluginService pluginService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the bean (after dependency injection has already taken place).
|
||||||
|
* Ensures the configurationService is injected, so that we can get the plugin
|
||||||
|
* and the forever embargo date threshold from the configuration.
|
||||||
|
* Called by "init-method" in Spring configuration.
|
||||||
|
*
|
||||||
|
* @throws Exception on generic exception
|
||||||
|
*/
|
||||||
|
public void init() throws Exception {
|
||||||
|
if (helper == null) {
|
||||||
|
helper = (AccessStatusHelper) pluginService.getSinglePlugin(AccessStatusHelper.class);
|
||||||
|
if (helper == null) {
|
||||||
|
throw new IllegalStateException("The AccessStatusHelper plugin was not defined in "
|
||||||
|
+ "DSpace configuration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defines the embargo forever date threshold for the access status.
|
||||||
|
// Look at EmbargoService.FOREVER for some improvements?
|
||||||
|
int year = configurationService.getIntProperty("access.status.embargo.forever.year");
|
||||||
|
int month = configurationService.getIntProperty("access.status.embargo.forever.month");
|
||||||
|
int day = configurationService.getIntProperty("access.status.embargo.forever.day");
|
||||||
|
|
||||||
|
forever_date = new LocalDate(year, month, day).toDate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessStatus(Context context, Item item) throws SQLException {
|
||||||
|
return helper.getAccessStatusFromItem(context, item, forever_date);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,159 @@
|
|||||||
|
/**
|
||||||
|
* 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.access.status;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
|
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.authorize.service.ResourcePolicyService;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default plugin implementation of the access status helper.
|
||||||
|
* The getAccessStatusFromItem method provides a simple logic to
|
||||||
|
* calculate the access status of an item based on the policies of
|
||||||
|
* the primary or the first bitstream in the original bundle.
|
||||||
|
* Users can override this method for enhanced functionality.
|
||||||
|
*/
|
||||||
|
public class DefaultAccessStatusHelper implements AccessStatusHelper {
|
||||||
|
public static final String EMBARGO = "embargo";
|
||||||
|
public static final String METADATA_ONLY = "metadata.only";
|
||||||
|
public static final String OPEN_ACCESS = "open.access";
|
||||||
|
public static final String RESTRICTED = "restricted";
|
||||||
|
public static final String UNKNOWN = "unknown";
|
||||||
|
|
||||||
|
protected ItemService itemService =
|
||||||
|
ContentServiceFactory.getInstance().getItemService();
|
||||||
|
protected ResourcePolicyService resourcePolicyService =
|
||||||
|
AuthorizeServiceFactory.getInstance().getResourcePolicyService();
|
||||||
|
protected AuthorizeService authorizeService =
|
||||||
|
AuthorizeServiceFactory.getInstance().getAuthorizeService();
|
||||||
|
|
||||||
|
public DefaultAccessStatusHelper() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look at the item's policies to determine an access status value.
|
||||||
|
* It is also considering a date threshold for embargos and restrictions.
|
||||||
|
*
|
||||||
|
* If the item is null, simply returns the "unknown" value.
|
||||||
|
*
|
||||||
|
* @param context the DSpace context
|
||||||
|
* @param item the item to embargo
|
||||||
|
* @param threshold the embargo threshold date
|
||||||
|
* @return an access status value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getAccessStatusFromItem(Context context, Item item, Date threshold)
|
||||||
|
throws SQLException {
|
||||||
|
if (item == null) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
// Consider only the original bundles.
|
||||||
|
List<Bundle> bundles = item.getBundles(Constants.DEFAULT_BUNDLE_NAME);
|
||||||
|
// Check for primary bitstreams first.
|
||||||
|
Bitstream bitstream = bundles.stream()
|
||||||
|
.map(bundle -> bundle.getPrimaryBitstream())
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (bitstream == null) {
|
||||||
|
// If there is no primary bitstream,
|
||||||
|
// take the first bitstream in the bundles.
|
||||||
|
bitstream = bundles.stream()
|
||||||
|
.map(bundle -> bundle.getBitstreams())
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
return caculateAccessStatusForDso(context, bitstream, threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look at the DSpace object's policies to determine an access status value.
|
||||||
|
*
|
||||||
|
* If the object is null, returns the "metadata.only" value.
|
||||||
|
* If any policy attached to the object is valid for the anonymous group,
|
||||||
|
* returns the "open.access" value.
|
||||||
|
* Otherwise, if the policy start date is before the embargo threshold date,
|
||||||
|
* returns the "embargo" value.
|
||||||
|
* Every other cases return the "restricted" value.
|
||||||
|
*
|
||||||
|
* @param context the DSpace context
|
||||||
|
* @param dso the DSpace object
|
||||||
|
* @param threshold the embargo threshold date
|
||||||
|
* @return an access status value
|
||||||
|
*/
|
||||||
|
private String caculateAccessStatusForDso(Context context, DSpaceObject dso, Date threshold)
|
||||||
|
throws SQLException {
|
||||||
|
if (dso == null) {
|
||||||
|
return METADATA_ONLY;
|
||||||
|
}
|
||||||
|
// Only consider read policies.
|
||||||
|
List<ResourcePolicy> policies = authorizeService
|
||||||
|
.getPoliciesActionFilter(context, dso, Constants.READ);
|
||||||
|
int openAccessCount = 0;
|
||||||
|
int embargoCount = 0;
|
||||||
|
int restrictedCount = 0;
|
||||||
|
int unknownCount = 0;
|
||||||
|
// Looks at all read policies.
|
||||||
|
for (ResourcePolicy policy : policies) {
|
||||||
|
boolean isValid = resourcePolicyService.isDateValid(policy);
|
||||||
|
Group group = policy.getGroup();
|
||||||
|
// The group must not be null here. However,
|
||||||
|
// if it is, consider this as an unexpected case.
|
||||||
|
if (group == null) {
|
||||||
|
unknownCount++;
|
||||||
|
} else if (StringUtils.equals(group.getName(), Group.ANONYMOUS)) {
|
||||||
|
// Only calculate the status for the anonymous group.
|
||||||
|
if (isValid) {
|
||||||
|
// If the policy is valid, the anonymous group have access
|
||||||
|
// to the bitstream.
|
||||||
|
openAccessCount++;
|
||||||
|
} else {
|
||||||
|
Date startDate = policy.getStartDate();
|
||||||
|
if (startDate != null && !startDate.before(threshold)) {
|
||||||
|
// If the policy start date have a value and if this value
|
||||||
|
// is equal or superior to the configured forever date, the
|
||||||
|
// access status is also restricted.
|
||||||
|
restrictedCount++;
|
||||||
|
} else {
|
||||||
|
// If the current date is not between the policy start date
|
||||||
|
// and end date, the access status is embargo.
|
||||||
|
embargoCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (openAccessCount > 0) {
|
||||||
|
return OPEN_ACCESS;
|
||||||
|
}
|
||||||
|
if (embargoCount > 0 && restrictedCount == 0) {
|
||||||
|
return EMBARGO;
|
||||||
|
}
|
||||||
|
if (unknownCount > 0) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
return RESTRICTED;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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.access.status.factory;
|
||||||
|
|
||||||
|
import org.dspace.access.status.service.AccessStatusService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract factory to get services for the access status package,
|
||||||
|
* use AccessStatusServiceFactory.getInstance() to retrieve an implementation.
|
||||||
|
*/
|
||||||
|
public abstract class AccessStatusServiceFactory {
|
||||||
|
|
||||||
|
public abstract AccessStatusService getAccessStatusService();
|
||||||
|
|
||||||
|
public static AccessStatusServiceFactory getInstance() {
|
||||||
|
return DSpaceServicesFactory.getInstance().getServiceManager()
|
||||||
|
.getServiceByName("accessStatusServiceFactory", AccessStatusServiceFactory.class);
|
||||||
|
}
|
||||||
|
}
|
@@ -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.access.status.factory;
|
||||||
|
|
||||||
|
import org.dspace.access.status.service.AccessStatusService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory implementation to get services for the access status package,
|
||||||
|
* use AccessStatusServiceFactory.getInstance() to retrieve an implementation.
|
||||||
|
*/
|
||||||
|
public class AccessStatusServiceFactoryImpl extends AccessStatusServiceFactory {
|
||||||
|
|
||||||
|
@Autowired(required = true)
|
||||||
|
private AccessStatusService accessStatusService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccessStatusService getAccessStatusService() {
|
||||||
|
return accessStatusService;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
* 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/
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Access status allows the users to view the bitstreams availability before
|
||||||
|
* browsing into the item itself.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* The access status is calculated through a pluggable class:
|
||||||
|
* {@link org.dspace.access.status.AccessStatusHelper}.
|
||||||
|
* The {@link org.dspace.access.status.AccessStatusServiceImpl}
|
||||||
|
* must be configured to specify this class, as well as a forever embargo date
|
||||||
|
* threshold year, month and day.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* See {@link org.dspace.access.status.DefaultAccessStatusHelper} for a simple calculation
|
||||||
|
* based on the primary or the first bitstream of the original bundle. You can
|
||||||
|
* supply your own class to implement more complex access statuses.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* For now, the access status is calculated when the item is shown in a list.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dspace.access.status;
|
@@ -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.access.status.service;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public interface to the access status subsystem.
|
||||||
|
* <p>
|
||||||
|
* Configuration properties: (with examples)
|
||||||
|
* {@code
|
||||||
|
* # values for the forever embargo date threshold
|
||||||
|
* # This threshold date is used in the default access status helper to dermine if an item is
|
||||||
|
* # restricted or embargoed based on the start date of the primary (or first) file policies.
|
||||||
|
* # In this case, if the policy start date is inferior to the threshold date, the status will
|
||||||
|
* # be embargo, else it will be restricted.
|
||||||
|
* # You might want to change this threshold based on your needs. For example: some databases
|
||||||
|
* # doesn't accept a date superior to 31 december 9999.
|
||||||
|
* access.status.embargo.forever.year = 10000
|
||||||
|
* access.status.embargo.forever.month = 1
|
||||||
|
* access.status.embargo.forever.day = 1
|
||||||
|
* # implementation of access status helper plugin - replace with local implementation if applicable
|
||||||
|
* # This default access status helper provides an item status based on the policies of the primary
|
||||||
|
* # bitstream (or first bitstream in the original bundles if no primary file is specified).
|
||||||
|
* plugin.single.org.dspace.access.status.AccessStatusHelper = org.dspace.access.status.DefaultAccessStatusHelper
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public interface AccessStatusService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the access status for an Item while considering the forever embargo date threshold.
|
||||||
|
*
|
||||||
|
* @param context the DSpace context
|
||||||
|
* @param item the item
|
||||||
|
* @throws SQLException An exception that provides information on a database access error or other errors.
|
||||||
|
*/
|
||||||
|
public String getAccessStatus(Context context, Item item) throws SQLException;
|
||||||
|
}
|
@@ -11,13 +11,16 @@ import java.io.IOException;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
import org.apache.commons.cli.DefaultParser;
|
import org.apache.commons.cli.DefaultParser;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
@@ -90,7 +93,7 @@ public class MetadataImporter {
|
|||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
throws ParseException, SQLException, IOException, TransformerException,
|
throws ParseException, SQLException, IOException, TransformerException,
|
||||||
ParserConfigurationException, AuthorizeException, SAXException,
|
ParserConfigurationException, AuthorizeException, SAXException,
|
||||||
NonUniqueMetadataException, RegistryImportException {
|
NonUniqueMetadataException, RegistryImportException, XPathExpressionException {
|
||||||
|
|
||||||
// create an options object and populate it
|
// create an options object and populate it
|
||||||
CommandLineParser parser = new DefaultParser();
|
CommandLineParser parser = new DefaultParser();
|
||||||
@@ -124,8 +127,8 @@ public class MetadataImporter {
|
|||||||
* @throws RegistryImportException if import fails
|
* @throws RegistryImportException if import fails
|
||||||
*/
|
*/
|
||||||
public static void loadRegistry(String file, boolean forceUpdate)
|
public static void loadRegistry(String file, boolean forceUpdate)
|
||||||
throws SQLException, IOException, TransformerException, ParserConfigurationException,
|
throws SQLException, IOException, TransformerException, ParserConfigurationException, AuthorizeException,
|
||||||
AuthorizeException, SAXException, NonUniqueMetadataException, RegistryImportException {
|
SAXException, NonUniqueMetadataException, RegistryImportException, XPathExpressionException {
|
||||||
Context context = null;
|
Context context = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -137,7 +140,9 @@ public class MetadataImporter {
|
|||||||
Document document = RegistryImporter.loadXML(file);
|
Document document = RegistryImporter.loadXML(file);
|
||||||
|
|
||||||
// Get the nodes corresponding to types
|
// Get the nodes corresponding to types
|
||||||
NodeList schemaNodes = XPathAPI.selectNodeList(document, "/dspace-dc-types/dc-schema");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList schemaNodes = (NodeList) xPath.compile("/dspace-dc-types/dc-schema")
|
||||||
|
.evaluate(document, XPathConstants.NODESET);
|
||||||
|
|
||||||
// Add each one as a new format to the registry
|
// Add each one as a new format to the registry
|
||||||
for (int i = 0; i < schemaNodes.getLength(); i++) {
|
for (int i = 0; i < schemaNodes.getLength(); i++) {
|
||||||
@@ -146,7 +151,8 @@ public class MetadataImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the nodes corresponding to types
|
// Get the nodes corresponding to types
|
||||||
NodeList typeNodes = XPathAPI.selectNodeList(document, "/dspace-dc-types/dc-type");
|
NodeList typeNodes = (NodeList) xPath.compile("/dspace-dc-types/dc-type")
|
||||||
|
.evaluate(document, XPathConstants.NODESET);
|
||||||
|
|
||||||
// Add each one as a new format to the registry
|
// Add each one as a new format to the registry
|
||||||
for (int i = 0; i < typeNodes.getLength(); i++) {
|
for (int i = 0; i < typeNodes.getLength(); i++) {
|
||||||
@@ -178,8 +184,8 @@ public class MetadataImporter {
|
|||||||
* @throws RegistryImportException if import fails
|
* @throws RegistryImportException if import fails
|
||||||
*/
|
*/
|
||||||
private static void loadSchema(Context context, Node node, boolean updateExisting)
|
private static void loadSchema(Context context, Node node, boolean updateExisting)
|
||||||
throws SQLException, IOException, TransformerException,
|
throws SQLException, AuthorizeException, NonUniqueMetadataException, RegistryImportException,
|
||||||
AuthorizeException, NonUniqueMetadataException, RegistryImportException {
|
XPathExpressionException {
|
||||||
// Get the values
|
// Get the values
|
||||||
String name = RegistryImporter.getElementData(node, "name");
|
String name = RegistryImporter.getElementData(node, "name");
|
||||||
String namespace = RegistryImporter.getElementData(node, "namespace");
|
String namespace = RegistryImporter.getElementData(node, "namespace");
|
||||||
@@ -236,8 +242,8 @@ public class MetadataImporter {
|
|||||||
* @throws RegistryImportException if import fails
|
* @throws RegistryImportException if import fails
|
||||||
*/
|
*/
|
||||||
private static void loadType(Context context, Node node)
|
private static void loadType(Context context, Node node)
|
||||||
throws SQLException, IOException, TransformerException,
|
throws SQLException, IOException, AuthorizeException, NonUniqueMetadataException, RegistryImportException,
|
||||||
AuthorizeException, NonUniqueMetadataException, RegistryImportException {
|
XPathExpressionException {
|
||||||
// Get the values
|
// Get the values
|
||||||
String schema = RegistryImporter.getElementData(node, "schema");
|
String schema = RegistryImporter.getElementData(node, "schema");
|
||||||
String element = RegistryImporter.getElementData(node, "element");
|
String element = RegistryImporter.getElementData(node, "element");
|
||||||
|
@@ -13,8 +13,11 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
@@ -72,9 +75,10 @@ public class RegistryImporter {
|
|||||||
* @throws TransformerException if error
|
* @throws TransformerException if error
|
||||||
*/
|
*/
|
||||||
public static String getElementData(Node parentElement, String childName)
|
public static String getElementData(Node parentElement, String childName)
|
||||||
throws TransformerException {
|
throws XPathExpressionException {
|
||||||
// Grab the child node
|
// Grab the child node
|
||||||
Node childNode = XPathAPI.selectSingleNode(parentElement, childName);
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
Node childNode = (Node) xPath.compile(childName).evaluate(parentElement, XPathConstants.NODE);
|
||||||
|
|
||||||
if (childNode == null) {
|
if (childNode == null) {
|
||||||
// No child node, so no values
|
// No child node, so no values
|
||||||
@@ -115,9 +119,10 @@ public class RegistryImporter {
|
|||||||
* @throws TransformerException if error
|
* @throws TransformerException if error
|
||||||
*/
|
*/
|
||||||
public static String[] getRepeatedElementData(Node parentElement,
|
public static String[] getRepeatedElementData(Node parentElement,
|
||||||
String childName) throws TransformerException {
|
String childName) throws XPathExpressionException {
|
||||||
// Grab the child node
|
// Grab the child node
|
||||||
NodeList childNodes = XPathAPI.selectNodeList(parentElement, childName);
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList childNodes = (NodeList) xPath.compile(childName).evaluate(parentElement, XPathConstants.NODESET);
|
||||||
|
|
||||||
String[] data = new String[childNodes.getLength()];
|
String[] data = new String[childNodes.getLength()];
|
||||||
|
|
||||||
|
@@ -16,9 +16,12 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.BitstreamFormat;
|
import org.dspace.content.BitstreamFormat;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
@@ -122,12 +125,13 @@ public class RegistryLoader {
|
|||||||
*/
|
*/
|
||||||
public static void loadBitstreamFormats(Context context, String filename)
|
public static void loadBitstreamFormats(Context context, String filename)
|
||||||
throws SQLException, IOException, ParserConfigurationException,
|
throws SQLException, IOException, ParserConfigurationException,
|
||||||
SAXException, TransformerException, AuthorizeException {
|
SAXException, TransformerException, AuthorizeException, XPathExpressionException {
|
||||||
Document document = loadXML(filename);
|
Document document = loadXML(filename);
|
||||||
|
|
||||||
// Get the nodes corresponding to formats
|
// Get the nodes corresponding to formats
|
||||||
NodeList typeNodes = XPathAPI.selectNodeList(document,
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
"dspace-bitstream-types/bitstream-type");
|
NodeList typeNodes = (NodeList) xPath.compile("dspace-bitstream-types/bitstream-type")
|
||||||
|
.evaluate(document, XPathConstants.NODESET);
|
||||||
|
|
||||||
// Add each one as a new format to the registry
|
// Add each one as a new format to the registry
|
||||||
for (int i = 0; i < typeNodes.getLength(); i++) {
|
for (int i = 0; i < typeNodes.getLength(); i++) {
|
||||||
@@ -151,8 +155,7 @@ public class RegistryLoader {
|
|||||||
* @throws AuthorizeException if authorization error
|
* @throws AuthorizeException if authorization error
|
||||||
*/
|
*/
|
||||||
private static void loadFormat(Context context, Node node)
|
private static void loadFormat(Context context, Node node)
|
||||||
throws SQLException, IOException, TransformerException,
|
throws SQLException, AuthorizeException, XPathExpressionException {
|
||||||
AuthorizeException {
|
|
||||||
// Get the values
|
// Get the values
|
||||||
String mimeType = getElementData(node, "mimetype");
|
String mimeType = getElementData(node, "mimetype");
|
||||||
String shortDesc = getElementData(node, "short_description");
|
String shortDesc = getElementData(node, "short_description");
|
||||||
@@ -231,9 +234,10 @@ public class RegistryLoader {
|
|||||||
* @throws TransformerException if transformer error
|
* @throws TransformerException if transformer error
|
||||||
*/
|
*/
|
||||||
private static String getElementData(Node parentElement, String childName)
|
private static String getElementData(Node parentElement, String childName)
|
||||||
throws TransformerException {
|
throws XPathExpressionException {
|
||||||
// Grab the child node
|
// Grab the child node
|
||||||
Node childNode = XPathAPI.selectSingleNode(parentElement, childName);
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
Node childNode = (Node) xPath.compile(childName).evaluate(parentElement, XPathConstants.NODE);
|
||||||
|
|
||||||
if (childNode == null) {
|
if (childNode == null) {
|
||||||
// No child node, so no values
|
// No child node, so no values
|
||||||
@@ -274,9 +278,10 @@ public class RegistryLoader {
|
|||||||
* @throws TransformerException if transformer error
|
* @throws TransformerException if transformer error
|
||||||
*/
|
*/
|
||||||
private static String[] getRepeatedElementData(Node parentElement,
|
private static String[] getRepeatedElementData(Node parentElement,
|
||||||
String childName) throws TransformerException {
|
String childName) throws XPathExpressionException {
|
||||||
// Grab the child node
|
// Grab the child node
|
||||||
NodeList childNodes = XPathAPI.selectNodeList(parentElement, childName);
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList childNodes = (NodeList) xPath.compile(childName).evaluate(parentElement, XPathConstants.NODESET);
|
||||||
|
|
||||||
String[] data = new String[childNodes.getLength()];
|
String[] data = new String[childNodes.getLength()];
|
||||||
|
|
||||||
|
@@ -30,6 +30,10 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.commons.cli.CommandLine;
|
import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.CommandLineParser;
|
import org.apache.commons.cli.CommandLineParser;
|
||||||
@@ -38,7 +42,6 @@ import org.apache.commons.cli.HelpFormatter;
|
|||||||
import org.apache.commons.cli.Option;
|
import org.apache.commons.cli.Option;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Collection;
|
import org.dspace.content.Collection;
|
||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
@@ -138,7 +141,7 @@ public class StructBuilder {
|
|||||||
*/
|
*/
|
||||||
public static void main(String[] argv)
|
public static void main(String[] argv)
|
||||||
throws ParserConfigurationException, SQLException,
|
throws ParserConfigurationException, SQLException,
|
||||||
FileNotFoundException, IOException, TransformerException {
|
IOException, TransformerException, XPathExpressionException {
|
||||||
// Define command line options.
|
// Define command line options.
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
|
|
||||||
@@ -240,7 +243,7 @@ public class StructBuilder {
|
|||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
static void importStructure(Context context, InputStream input, OutputStream output)
|
static void importStructure(Context context, InputStream input, OutputStream output)
|
||||||
throws IOException, ParserConfigurationException, SQLException, TransformerException {
|
throws IOException, ParserConfigurationException, SQLException, TransformerException, XPathExpressionException {
|
||||||
|
|
||||||
// load the XML
|
// load the XML
|
||||||
Document document = null;
|
Document document = null;
|
||||||
@@ -258,13 +261,15 @@ public class StructBuilder {
|
|||||||
// is properly structured.
|
// is properly structured.
|
||||||
try {
|
try {
|
||||||
validate(document);
|
validate(document);
|
||||||
} catch (TransformerException ex) {
|
} catch (XPathExpressionException ex) {
|
||||||
System.err.format("The input document is invalid: %s%n", ex.getMessage());
|
System.err.format("The input document is invalid: %s%n", ex.getMessage());
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for 'identifier' attributes -- possibly output by this class.
|
// Check for 'identifier' attributes -- possibly output by this class.
|
||||||
NodeList identifierNodes = XPathAPI.selectNodeList(document, "//*[@identifier]");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList identifierNodes = (NodeList) xPath.compile("//*[@identifier]")
|
||||||
|
.evaluate(document, XPathConstants.NODESET);
|
||||||
if (identifierNodes.getLength() > 0) {
|
if (identifierNodes.getLength() > 0) {
|
||||||
System.err.println("The input document has 'identifier' attributes, which will be ignored.");
|
System.err.println("The input document has 'identifier' attributes, which will be ignored.");
|
||||||
}
|
}
|
||||||
@@ -287,7 +292,8 @@ public class StructBuilder {
|
|||||||
Element[] elements = new Element[]{};
|
Element[] elements = new Element[]{};
|
||||||
try {
|
try {
|
||||||
// get the top level community list
|
// get the top level community list
|
||||||
NodeList first = XPathAPI.selectNodeList(document, "/import_structure/community");
|
NodeList first = (NodeList) xPath.compile("/import_structure/community")
|
||||||
|
.evaluate(document, XPathConstants.NODESET);
|
||||||
|
|
||||||
// run the import starting with the top level communities
|
// run the import starting with the top level communities
|
||||||
elements = handleCommunities(context, first, null);
|
elements = handleCommunities(context, first, null);
|
||||||
@@ -456,14 +462,16 @@ public class StructBuilder {
|
|||||||
* @throws TransformerException if transformer error
|
* @throws TransformerException if transformer error
|
||||||
*/
|
*/
|
||||||
private static void validate(org.w3c.dom.Document document)
|
private static void validate(org.w3c.dom.Document document)
|
||||||
throws TransformerException {
|
throws XPathExpressionException {
|
||||||
StringBuilder err = new StringBuilder();
|
StringBuilder err = new StringBuilder();
|
||||||
boolean trip = false;
|
boolean trip = false;
|
||||||
|
|
||||||
err.append("The following errors were encountered parsing the source XML.\n");
|
err.append("The following errors were encountered parsing the source XML.\n");
|
||||||
err.append("No changes have been made to the DSpace instance.\n\n");
|
err.append("No changes have been made to the DSpace instance.\n\n");
|
||||||
|
|
||||||
NodeList first = XPathAPI.selectNodeList(document, "/import_structure/community");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList first = (NodeList) xPath.compile("/import_structure/community")
|
||||||
|
.evaluate(document, XPathConstants.NODESET);
|
||||||
if (first.getLength() == 0) {
|
if (first.getLength() == 0) {
|
||||||
err.append("-There are no top level communities in the source document.");
|
err.append("-There are no top level communities in the source document.");
|
||||||
System.out.println(err.toString());
|
System.out.println(err.toString());
|
||||||
@@ -493,14 +501,15 @@ public class StructBuilder {
|
|||||||
* no errors.
|
* no errors.
|
||||||
*/
|
*/
|
||||||
private static String validateCommunities(NodeList communities, int level)
|
private static String validateCommunities(NodeList communities, int level)
|
||||||
throws TransformerException {
|
throws XPathExpressionException {
|
||||||
StringBuilder err = new StringBuilder();
|
StringBuilder err = new StringBuilder();
|
||||||
boolean trip = false;
|
boolean trip = false;
|
||||||
String errs = null;
|
String errs = null;
|
||||||
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
for (int i = 0; i < communities.getLength(); i++) {
|
for (int i = 0; i < communities.getLength(); i++) {
|
||||||
Node n = communities.item(i);
|
Node n = communities.item(i);
|
||||||
NodeList name = XPathAPI.selectNodeList(n, "name");
|
NodeList name = (NodeList) xPath.compile("name").evaluate(n, XPathConstants.NODESET);
|
||||||
if (name.getLength() != 1) {
|
if (name.getLength() != 1) {
|
||||||
String pos = Integer.toString(i + 1);
|
String pos = Integer.toString(i + 1);
|
||||||
err.append("-The level ").append(level)
|
err.append("-The level ").append(level)
|
||||||
@@ -510,7 +519,7 @@ public class StructBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validate sub communities
|
// validate sub communities
|
||||||
NodeList subCommunities = XPathAPI.selectNodeList(n, "community");
|
NodeList subCommunities = (NodeList) xPath.compile("community").evaluate(n, XPathConstants.NODESET);
|
||||||
String comErrs = validateCommunities(subCommunities, level + 1);
|
String comErrs = validateCommunities(subCommunities, level + 1);
|
||||||
if (comErrs != null) {
|
if (comErrs != null) {
|
||||||
err.append(comErrs);
|
err.append(comErrs);
|
||||||
@@ -518,7 +527,7 @@ public class StructBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validate collections
|
// validate collections
|
||||||
NodeList collections = XPathAPI.selectNodeList(n, "collection");
|
NodeList collections = (NodeList) xPath.compile("collection").evaluate(n, XPathConstants.NODESET);
|
||||||
String colErrs = validateCollections(collections, level + 1);
|
String colErrs = validateCollections(collections, level + 1);
|
||||||
if (colErrs != null) {
|
if (colErrs != null) {
|
||||||
err.append(colErrs);
|
err.append(colErrs);
|
||||||
@@ -542,14 +551,15 @@ public class StructBuilder {
|
|||||||
* @return the errors to be generated by the calling method, or null if none
|
* @return the errors to be generated by the calling method, or null if none
|
||||||
*/
|
*/
|
||||||
private static String validateCollections(NodeList collections, int level)
|
private static String validateCollections(NodeList collections, int level)
|
||||||
throws TransformerException {
|
throws XPathExpressionException {
|
||||||
StringBuilder err = new StringBuilder();
|
StringBuilder err = new StringBuilder();
|
||||||
boolean trip = false;
|
boolean trip = false;
|
||||||
String errs = null;
|
String errs = null;
|
||||||
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
for (int i = 0; i < collections.getLength(); i++) {
|
for (int i = 0; i < collections.getLength(); i++) {
|
||||||
Node n = collections.item(i);
|
Node n = collections.item(i);
|
||||||
NodeList name = XPathAPI.selectNodeList(n, "name");
|
NodeList name = (NodeList) xPath.compile("name").evaluate(n, XPathConstants.NODESET);
|
||||||
if (name.getLength() != 1) {
|
if (name.getLength() != 1) {
|
||||||
String pos = Integer.toString(i + 1);
|
String pos = Integer.toString(i + 1);
|
||||||
err.append("-The level ").append(level)
|
err.append("-The level ").append(level)
|
||||||
@@ -613,8 +623,9 @@ public class StructBuilder {
|
|||||||
* created communities (e.g. the handles they have been assigned)
|
* created communities (e.g. the handles they have been assigned)
|
||||||
*/
|
*/
|
||||||
private static Element[] handleCommunities(Context context, NodeList communities, Community parent)
|
private static Element[] handleCommunities(Context context, NodeList communities, Community parent)
|
||||||
throws TransformerException, SQLException, AuthorizeException {
|
throws TransformerException, SQLException, AuthorizeException, XPathExpressionException {
|
||||||
Element[] elements = new Element[communities.getLength()];
|
Element[] elements = new Element[communities.getLength()];
|
||||||
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
for (int i = 0; i < communities.getLength(); i++) {
|
for (int i = 0; i < communities.getLength(); i++) {
|
||||||
Community community;
|
Community community;
|
||||||
@@ -634,7 +645,7 @@ public class StructBuilder {
|
|||||||
// now update the metadata
|
// now update the metadata
|
||||||
Node tn = communities.item(i);
|
Node tn = communities.item(i);
|
||||||
for (Map.Entry<String, MetadataFieldName> entry : communityMap.entrySet()) {
|
for (Map.Entry<String, MetadataFieldName> entry : communityMap.entrySet()) {
|
||||||
NodeList nl = XPathAPI.selectNodeList(tn, entry.getKey());
|
NodeList nl = (NodeList) xPath.compile(entry.getKey()).evaluate(tn, XPathConstants.NODESET);
|
||||||
if (nl.getLength() == 1) {
|
if (nl.getLength() == 1) {
|
||||||
communityService.setMetadataSingleValue(context, community,
|
communityService.setMetadataSingleValue(context, community,
|
||||||
entry.getValue(), null, getStringValue(nl.item(0)));
|
entry.getValue(), null, getStringValue(nl.item(0)));
|
||||||
@@ -700,11 +711,11 @@ public class StructBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle sub communities
|
// handle sub communities
|
||||||
NodeList subCommunities = XPathAPI.selectNodeList(tn, "community");
|
NodeList subCommunities = (NodeList) xPath.compile("community").evaluate(tn, XPathConstants.NODESET);
|
||||||
Element[] subCommunityElements = handleCommunities(context, subCommunities, community);
|
Element[] subCommunityElements = handleCommunities(context, subCommunities, community);
|
||||||
|
|
||||||
// handle collections
|
// handle collections
|
||||||
NodeList collections = XPathAPI.selectNodeList(tn, "collection");
|
NodeList collections = (NodeList) xPath.compile("collection").evaluate(tn, XPathConstants.NODESET);
|
||||||
Element[] collectionElements = handleCollections(context, collections, community);
|
Element[] collectionElements = handleCollections(context, collections, community);
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
@@ -731,8 +742,9 @@ public class StructBuilder {
|
|||||||
* created collections (e.g. the handle)
|
* created collections (e.g. the handle)
|
||||||
*/
|
*/
|
||||||
private static Element[] handleCollections(Context context, NodeList collections, Community parent)
|
private static Element[] handleCollections(Context context, NodeList collections, Community parent)
|
||||||
throws TransformerException, SQLException, AuthorizeException {
|
throws SQLException, AuthorizeException, XPathExpressionException {
|
||||||
Element[] elements = new Element[collections.getLength()];
|
Element[] elements = new Element[collections.getLength()];
|
||||||
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
|
||||||
for (int i = 0; i < collections.getLength(); i++) {
|
for (int i = 0; i < collections.getLength(); i++) {
|
||||||
Element element = new Element("collection");
|
Element element = new Element("collection");
|
||||||
@@ -745,7 +757,7 @@ public class StructBuilder {
|
|||||||
// import the rest of the metadata
|
// import the rest of the metadata
|
||||||
Node tn = collections.item(i);
|
Node tn = collections.item(i);
|
||||||
for (Map.Entry<String, MetadataFieldName> entry : collectionMap.entrySet()) {
|
for (Map.Entry<String, MetadataFieldName> entry : collectionMap.entrySet()) {
|
||||||
NodeList nl = XPathAPI.selectNodeList(tn, entry.getKey());
|
NodeList nl = (NodeList) xPath.compile(entry.getKey()).evaluate(tn, XPathConstants.NODESET);
|
||||||
if (nl.getLength() == 1) {
|
if (nl.getLength() == 1) {
|
||||||
collectionService.setMetadataSingleValue(context, collection,
|
collectionService.setMetadataSingleValue(context, collection,
|
||||||
entry.getValue(), null, getStringValue(nl.item(0)));
|
entry.getValue(), null, getStringValue(nl.item(0)));
|
||||||
|
@@ -23,7 +23,6 @@ public class ResourceAlreadyExistsException extends RuntimeException {
|
|||||||
* existing resource.
|
* existing resource.
|
||||||
*
|
*
|
||||||
* @param message the error message
|
* @param message the error message
|
||||||
* @param resource the resource that caused the conflict
|
|
||||||
*/
|
*/
|
||||||
public ResourceAlreadyExistsException(String message) {
|
public ResourceAlreadyExistsException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@@ -51,6 +51,10 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.commons.collections4.ComparatorUtils;
|
import org.apache.commons.collections4.ComparatorUtils;
|
||||||
import org.apache.commons.io.FileDeleteStrategy;
|
import org.apache.commons.io.FileDeleteStrategy;
|
||||||
@@ -59,7 +63,6 @@ import org.apache.commons.lang3.RandomStringUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.dspace.app.itemimport.service.ItemImportService;
|
import org.dspace.app.itemimport.service.ItemImportService;
|
||||||
import org.dspace.app.util.LocalSchemaFilenameFilter;
|
import org.dspace.app.util.LocalSchemaFilenameFilter;
|
||||||
import org.dspace.app.util.RelationshipUtils;
|
import org.dspace.app.util.RelationshipUtils;
|
||||||
@@ -863,7 +866,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
// Load all metadata schemas into the item.
|
// Load all metadata schemas into the item.
|
||||||
protected void loadMetadata(Context c, Item myitem, String path)
|
protected void loadMetadata(Context c, Item myitem, String path)
|
||||||
throws SQLException, IOException, ParserConfigurationException,
|
throws SQLException, IOException, ParserConfigurationException,
|
||||||
SAXException, TransformerException, AuthorizeException {
|
SAXException, TransformerException, AuthorizeException, XPathExpressionException {
|
||||||
// Load the dublin core metadata
|
// Load the dublin core metadata
|
||||||
loadDublinCore(c, myitem, path + "dublin_core.xml");
|
loadDublinCore(c, myitem, path + "dublin_core.xml");
|
||||||
|
|
||||||
@@ -877,14 +880,15 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
|
|
||||||
protected void loadDublinCore(Context c, Item myitem, String filename)
|
protected void loadDublinCore(Context c, Item myitem, String filename)
|
||||||
throws SQLException, IOException, ParserConfigurationException,
|
throws SQLException, IOException, ParserConfigurationException,
|
||||||
SAXException, TransformerException, AuthorizeException {
|
SAXException, TransformerException, AuthorizeException, XPathExpressionException {
|
||||||
Document document = loadXML(filename);
|
Document document = loadXML(filename);
|
||||||
|
|
||||||
// Get the schema, for backward compatibility we will default to the
|
// Get the schema, for backward compatibility we will default to the
|
||||||
// dublin core schema if the schema name is not available in the import
|
// dublin core schema if the schema name is not available in the import
|
||||||
// file
|
// file
|
||||||
String schema;
|
String schema;
|
||||||
NodeList metadata = XPathAPI.selectNodeList(document, "/dublin_core");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList metadata = (NodeList) xPath.compile("/dublin_core").evaluate(document, XPathConstants.NODESET);
|
||||||
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem(
|
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem(
|
||||||
"schema");
|
"schema");
|
||||||
if (schemaAttr == null) {
|
if (schemaAttr == null) {
|
||||||
@@ -894,8 +898,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the nodes corresponding to formats
|
// Get the nodes corresponding to formats
|
||||||
NodeList dcNodes = XPathAPI.selectNodeList(document,
|
NodeList dcNodes = (NodeList) xPath.compile("/dublin_core/dcvalue").evaluate(document, XPathConstants.NODESET);
|
||||||
"/dublin_core/dcvalue");
|
|
||||||
|
|
||||||
if (!isQuiet) {
|
if (!isQuiet) {
|
||||||
System.out.println("\tLoading dublin core from " + filename);
|
System.out.println("\tLoading dublin core from " + filename);
|
||||||
|
@@ -27,10 +27,12 @@ import javax.xml.transform.TransformerConfigurationException;
|
|||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.MetadataField;
|
import org.dspace.content.MetadataField;
|
||||||
import org.dspace.content.MetadataSchema;
|
import org.dspace.content.MetadataSchema;
|
||||||
@@ -170,24 +172,21 @@ public class MetadataUtilities {
|
|||||||
* @param docBuilder DocumentBuilder
|
* @param docBuilder DocumentBuilder
|
||||||
* @param is - InputStream of dublin_core.xml
|
* @param is - InputStream of dublin_core.xml
|
||||||
* @return list of DtoMetadata representing the metadata fields relating to an Item
|
* @return list of DtoMetadata representing the metadata fields relating to an Item
|
||||||
* @throws SQLException if database error
|
|
||||||
* @throws IOException if IO error
|
* @throws IOException if IO error
|
||||||
* @throws ParserConfigurationException if parser config error
|
* @throws ParserConfigurationException if parser config error
|
||||||
* @throws SAXException if XML error
|
* @throws SAXException if XML error
|
||||||
* @throws TransformerException if transformer error
|
|
||||||
* @throws AuthorizeException if authorization error
|
|
||||||
*/
|
*/
|
||||||
public static List<DtoMetadata> loadDublinCore(DocumentBuilder docBuilder, InputStream is)
|
public static List<DtoMetadata> loadDublinCore(DocumentBuilder docBuilder, InputStream is)
|
||||||
throws SQLException, IOException, ParserConfigurationException,
|
throws IOException, XPathExpressionException, SAXException {
|
||||||
SAXException, TransformerException, AuthorizeException {
|
|
||||||
Document document = docBuilder.parse(is);
|
Document document = docBuilder.parse(is);
|
||||||
|
|
||||||
List<DtoMetadata> dtomList = new ArrayList<DtoMetadata>();
|
List<DtoMetadata> dtomList = new ArrayList<DtoMetadata>();
|
||||||
|
|
||||||
// Get the schema, for backward compatibility we will default to the
|
// Get the schema, for backward compatibility we will default to the
|
||||||
// dublin core schema if the schema name is not available in the import file
|
// dublin core schema if the schema name is not available in the import file
|
||||||
String schema = null;
|
String schema;
|
||||||
NodeList metadata = XPathAPI.selectNodeList(document, "/dublin_core");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList metadata = (NodeList) xPath.compile("/dublin_core").evaluate(document, XPathConstants.NODESET);
|
||||||
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem("schema");
|
Node schemaAttr = metadata.item(0).getAttributes().getNamedItem("schema");
|
||||||
if (schemaAttr == null) {
|
if (schemaAttr == null) {
|
||||||
schema = MetadataSchemaEnum.DC.getName();
|
schema = MetadataSchemaEnum.DC.getName();
|
||||||
@@ -196,7 +195,7 @@ public class MetadataUtilities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the nodes corresponding to formats
|
// Get the nodes corresponding to formats
|
||||||
NodeList dcNodes = XPathAPI.selectNodeList(document, "/dublin_core/dcvalue");
|
NodeList dcNodes = (NodeList) xPath.compile("/dublin_core/dcvalue").evaluate(document, XPathConstants.NODESET);
|
||||||
|
|
||||||
for (int i = 0; i < dcNodes.getLength(); i++) {
|
for (int i = 0; i < dcNodes.getLength(); i++) {
|
||||||
Node n = dcNodes.item(i);
|
Node n = dcNodes.item(i);
|
||||||
|
@@ -272,11 +272,6 @@ public class ResearcherProfileServiceImpl implements ResearcherProfileService {
|
|||||||
return empty();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indexableObjects.size() > 1) {
|
|
||||||
log.warn("Multiple " + profileType + " type collections were found during profile creation");
|
|
||||||
return empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ofNullable((Collection) indexableObjects.get(0).getIndexedObject());
|
return ofNullable((Collection) indexableObjects.get(0).getIndexedObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +291,7 @@ public class ResearcherProfileServiceImpl implements ResearcherProfileService {
|
|||||||
|
|
||||||
item = installItemService.installItem(context, workspaceItem);
|
item = installItemService.installItem(context, workspaceItem);
|
||||||
|
|
||||||
if (isNewProfilePrivateByDefault()) {
|
if (isNewProfileNotVisibleByDefault()) {
|
||||||
Group anonymous = groupService.findByName(context, ANONYMOUS);
|
Group anonymous = groupService.findByName(context, ANONYMOUS);
|
||||||
authorizeService.removeGroupPolicies(context, item, anonymous);
|
authorizeService.removeGroupPolicies(context, item, anonymous);
|
||||||
}
|
}
|
||||||
@@ -310,8 +305,8 @@ public class ResearcherProfileServiceImpl implements ResearcherProfileService {
|
|||||||
return configurationService.getBooleanProperty("researcher-profile.hard-delete.enabled");
|
return configurationService.getBooleanProperty("researcher-profile.hard-delete.enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNewProfilePrivateByDefault() {
|
private boolean isNewProfileNotVisibleByDefault() {
|
||||||
return configurationService.getBooleanProperty("researcher-profile.set-new-profile-private");
|
return !configurationService.getBooleanProperty("researcher-profile.set-new-profile-visible");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeOwnerMetadata(Context context, Item profileItem) throws SQLException {
|
private void removeOwnerMetadata(Context context, Item profileItem) throws SQLException {
|
||||||
|
@@ -67,7 +67,7 @@ public interface ResearcherProfileService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the visibility of the given profile using the given new visible
|
* Changes the visibility of the given profile using the given new visible
|
||||||
* value.
|
* value. The visiblity controls whether the Profile is Anonymous READ or not.
|
||||||
*
|
*
|
||||||
* @param context the relevant DSpace Context.
|
* @param context the relevant DSpace Context.
|
||||||
* @param profile the researcher profile to update
|
* @param profile the researcher profile to update
|
||||||
|
@@ -561,6 +561,15 @@ public class DCInput {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type bind list for use in determining whether
|
||||||
|
* to display this field in angular dynamic form building
|
||||||
|
* @return list of bound types
|
||||||
|
*/
|
||||||
|
public List<String> getTypeBindList() {
|
||||||
|
return typeBind;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify whether the current field contains an entity relationship
|
* Verify whether the current field contains an entity relationship
|
||||||
* This also implies a relationship type is defined for this field
|
* This also implies a relationship type is defined for this field
|
||||||
|
@@ -14,11 +14,12 @@ import java.util.Iterator;
|
|||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
@@ -62,36 +63,26 @@ public class XMLUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param xml The starting context (a Node or a Document, for example).
|
* @param xml The starting context (a Node or a Document, for example).
|
||||||
* @param NodeListXPath xpath
|
* @param nodeListXPath xpath
|
||||||
* @return A Node matches the NodeListXPath
|
* @return A Node matches the NodeListXPath
|
||||||
* null if nothing matches the NodeListXPath
|
* null if nothing matches the NodeListXPath
|
||||||
* @throws XPathExpressionException if xpath error
|
* @throws XPathExpressionException if xpath error
|
||||||
*/
|
*/
|
||||||
public static Node getNode(Node xml, String NodeListXPath) throws XPathExpressionException {
|
public static Node getNode(Node xml, String nodeListXPath) throws XPathExpressionException {
|
||||||
Node result = null;
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
try {
|
return (Node) xPath.compile(nodeListXPath).evaluate(xml, XPathConstants.NODE);
|
||||||
result = XPathAPI.selectSingleNode(xml, NodeListXPath);
|
|
||||||
} catch (TransformerException e) {
|
|
||||||
log.error("Error", e);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param xml The starting context (a Node or a Document, for example).
|
* @param xml The starting context (a Node or a Document, for example).
|
||||||
* @param NodeListXPath xpath
|
* @param nodeListXPath xpath
|
||||||
* @return A NodeList containing the nodes that match the NodeListXPath
|
* @return A NodeList containing the nodes that match the NodeListXPath
|
||||||
* null if nothing matches the NodeListXPath
|
* null if nothing matches the NodeListXPath
|
||||||
* @throws XPathExpressionException if xpath error
|
* @throws XPathExpressionException if xpath error
|
||||||
*/
|
*/
|
||||||
public static NodeList getNodeList(Node xml, String NodeListXPath) throws XPathExpressionException {
|
public static NodeList getNodeList(Node xml, String nodeListXPath) throws XPathExpressionException {
|
||||||
NodeList nodeList = null;
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
try {
|
return (NodeList) xPath.compile(nodeListXPath).evaluate(xml, XPathConstants.NODESET);
|
||||||
nodeList = XPathAPI.selectNodeList(xml, NodeListXPath);
|
|
||||||
} catch (TransformerException e) {
|
|
||||||
log.error("Error", e);
|
|
||||||
}
|
|
||||||
return nodeList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Iterator<Node> getNodeListIterator(Node xml, String NodeListXPath) throws XPathExpressionException {
|
public static Iterator<Node> getNodeListIterator(Node xml, String NodeListXPath) throws XPathExpressionException {
|
||||||
|
@@ -130,12 +130,6 @@ public abstract class XSLTCrosswalk extends SelfNamedPlugin {
|
|||||||
return aliasList.toArray(new String[aliasList.size()]);
|
return aliasList.toArray(new String[aliasList.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* We need to force this, because some dependency elsewhere interferes.
|
|
||||||
*/
|
|
||||||
private static final String TRANSFORMER_FACTORY_CLASS
|
|
||||||
= "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
|
|
||||||
|
|
||||||
private Transformer transformer = null;
|
private Transformer transformer = null;
|
||||||
private File transformFile = null;
|
private File transformFile = null;
|
||||||
private long transformLastModified = 0;
|
private long transformLastModified = 0;
|
||||||
@@ -181,8 +175,7 @@ public abstract class XSLTCrosswalk extends SelfNamedPlugin {
|
|||||||
Source transformSource
|
Source transformSource
|
||||||
= new StreamSource(new FileInputStream(transformFile));
|
= new StreamSource(new FileInputStream(transformFile));
|
||||||
TransformerFactory transformerFactory
|
TransformerFactory transformerFactory
|
||||||
= TransformerFactory.newInstance(
|
= TransformerFactory.newInstance();
|
||||||
TRANSFORMER_FACTORY_CLASS, null);
|
|
||||||
transformer = transformerFactory.newTransformer(transformSource);
|
transformer = transformerFactory.newTransformer(transformSource);
|
||||||
transformLastModified = transformFile.lastModified();
|
transformLastModified = transformFile.lastModified();
|
||||||
} catch (TransformerConfigurationException | FileNotFoundException e) {
|
} catch (TransformerConfigurationException | FileNotFoundException e) {
|
||||||
|
@@ -1174,7 +1174,7 @@ public class SolrServiceImpl implements SearchService, IndexingService {
|
|||||||
//DO NOT ESCAPE RANGE QUERIES !
|
//DO NOT ESCAPE RANGE QUERIES !
|
||||||
if (!value.matches("\\[.*TO.*\\]")) {
|
if (!value.matches("\\[.*TO.*\\]")) {
|
||||||
value = ClientUtils.escapeQueryChars(value);
|
value = ClientUtils.escapeQueryChars(value);
|
||||||
filterQuery.append("(").append(value).append(")");
|
filterQuery.append("\"").append(value).append("\"");
|
||||||
} else {
|
} else {
|
||||||
filterQuery.append(value);
|
filterQuery.append(value);
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@ public class CanvasCacheEvictService {
|
|||||||
CacheManager cacheManager;
|
CacheManager cacheManager;
|
||||||
|
|
||||||
public void evictSingleCacheValue(String cacheKey) {
|
public void evictSingleCacheValue(String cacheKey) {
|
||||||
Objects.requireNonNull(cacheManager.getCache(CACHE_NAME)).evict(cacheKey);
|
Objects.requireNonNull(cacheManager.getCache(CACHE_NAME)).evictIfPresent(cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -26,11 +26,11 @@ public class ManifestsCacheEvictService {
|
|||||||
CacheManager cacheManager;
|
CacheManager cacheManager;
|
||||||
|
|
||||||
public void evictSingleCacheValue(String cacheKey) {
|
public void evictSingleCacheValue(String cacheKey) {
|
||||||
Objects.requireNonNull(cacheManager.getCache(CACHE_NAME)).evict(cacheKey);
|
Objects.requireNonNull(cacheManager.getCache(CACHE_NAME)).evictIfPresent(cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void evictAllCacheValues() {
|
public void evictAllCacheValues() {
|
||||||
Objects.requireNonNull(cacheManager.getCache(CACHE_NAME)).clear();
|
Objects.requireNonNull(cacheManager.getCache(CACHE_NAME)).invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.statistics;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A neutral data object to hold data for statistics.
|
|
||||||
*/
|
|
||||||
public class DataTermsFacet {
|
|
||||||
private List<TermsFacet> terms;
|
|
||||||
|
|
||||||
public DataTermsFacet() {
|
|
||||||
terms = new ArrayList<TermsFacet>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addTermFacet(TermsFacet termsFacet) {
|
|
||||||
terms.add(termsFacet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render this data object into JSON format.
|
|
||||||
*
|
|
||||||
* An example of the output could be of the format:
|
|
||||||
* [{"term":"247166","count":10},{"term":"247168","count":6}]
|
|
||||||
*
|
|
||||||
* @return JSON-formatted data.
|
|
||||||
*/
|
|
||||||
public String toJson() {
|
|
||||||
Gson gson = new Gson();
|
|
||||||
return gson.toJson(terms);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class TermsFacet {
|
|
||||||
private String term;
|
|
||||||
private Integer count;
|
|
||||||
|
|
||||||
public TermsFacet(String term, Integer count) {
|
|
||||||
setTerm(term);
|
|
||||||
setCount(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTerm() {
|
|
||||||
return term;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTerm(String term) {
|
|
||||||
this.term = term;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getCount() {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCount(Integer count) {
|
|
||||||
this.count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -12,6 +12,7 @@ import java.io.IOException;
|
|||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
|
||||||
import org.dspace.administer.MetadataImporter;
|
import org.dspace.administer.MetadataImporter;
|
||||||
import org.dspace.administer.RegistryImportException;
|
import org.dspace.administer.RegistryImportException;
|
||||||
@@ -89,7 +90,7 @@ public class RegistryUpdater implements Callback {
|
|||||||
} catch (IOException | SQLException | ParserConfigurationException
|
} catch (IOException | SQLException | ParserConfigurationException
|
||||||
| TransformerException | RegistryImportException
|
| TransformerException | RegistryImportException
|
||||||
| AuthorizeException | NonUniqueMetadataException
|
| AuthorizeException | NonUniqueMetadataException
|
||||||
| SAXException e) {
|
| SAXException | XPathExpressionException e) {
|
||||||
log.error("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
log.error("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
||||||
throw new RuntimeException("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
throw new RuntimeException("Error attempting to update Bitstream Format and/or Metadata Registries", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@@ -64,12 +64,6 @@ public class SubmissionFormsMigration extends DSpaceRunnable<SubmissionFormsMigr
|
|||||||
"<!ELEMENT input-forms (form-map, form-definitions, form-value-pairs) >";
|
"<!ELEMENT input-forms (form-map, form-definitions, form-value-pairs) >";
|
||||||
private List<File> tempFiles = new ArrayList<>();
|
private List<File> tempFiles = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* We need to force this, because some dependency elsewhere interferes.
|
|
||||||
*/
|
|
||||||
private static final String TRANSFORMER_FACTORY_CLASS
|
|
||||||
= "org.apache.xalan.processor.TransformerFactoryImpl";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void internalRun() throws TransformerException {
|
public void internalRun() throws TransformerException {
|
||||||
if (help) {
|
if (help) {
|
||||||
@@ -101,8 +95,7 @@ public class SubmissionFormsMigration extends DSpaceRunnable<SubmissionFormsMigr
|
|||||||
Result result = new StreamResult(new File(outputPath));
|
Result result = new StreamResult(new File(outputPath));
|
||||||
|
|
||||||
// Create an instance of TransformerFactory
|
// Create an instance of TransformerFactory
|
||||||
TransformerFactory transformerFactory = TransformerFactory.newInstance(
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
TRANSFORMER_FACTORY_CLASS, null);
|
|
||||||
|
|
||||||
Transformer trans;
|
Transformer trans;
|
||||||
try {
|
try {
|
||||||
|
@@ -15,8 +15,11 @@ import javax.xml.parsers.DocumentBuilder;
|
|||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.apache.xpath.XPathAPI;
|
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
@@ -56,7 +59,7 @@ public class ControlledVocabulary {
|
|||||||
* TODO: add some caching !
|
* TODO: add some caching !
|
||||||
*/
|
*/
|
||||||
public static ControlledVocabulary loadVocabulary(String fileName)
|
public static ControlledVocabulary loadVocabulary(String fileName)
|
||||||
throws IOException, SAXException, ParserConfigurationException, TransformerException {
|
throws IOException, SAXException, ParserConfigurationException, XPathExpressionException {
|
||||||
StringBuilder filePath = new StringBuilder();
|
StringBuilder filePath = new StringBuilder();
|
||||||
ConfigurationService configurationService
|
ConfigurationService configurationService
|
||||||
= DSpaceServicesFactory.getInstance().getConfigurationService();
|
= DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
@@ -70,7 +73,9 @@ public class ControlledVocabulary {
|
|||||||
if (controlledVocFile.exists()) {
|
if (controlledVocFile.exists()) {
|
||||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
Document document = builder.parse(controlledVocFile);
|
Document document = builder.parse(controlledVocFile);
|
||||||
return loadVocabularyNode(XPathAPI.selectSingleNode(document, "node"), "");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
Node node = (Node) xPath.compile("node").evaluate(document, XPathConstants.NODE);
|
||||||
|
return loadVocabularyNode(node, "");
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -85,7 +90,8 @@ public class ControlledVocabulary {
|
|||||||
* @return a vocabulary node with all its children
|
* @return a vocabulary node with all its children
|
||||||
* @throws TransformerException should something go wrong with loading the xml
|
* @throws TransformerException should something go wrong with loading the xml
|
||||||
*/
|
*/
|
||||||
private static ControlledVocabulary loadVocabularyNode(Node node, String initialValue) throws TransformerException {
|
private static ControlledVocabulary loadVocabularyNode(Node node, String initialValue)
|
||||||
|
throws XPathExpressionException {
|
||||||
Node idNode = node.getAttributes().getNamedItem("id");
|
Node idNode = node.getAttributes().getNamedItem("id");
|
||||||
String id = null;
|
String id = null;
|
||||||
if (idNode != null) {
|
if (idNode != null) {
|
||||||
@@ -102,7 +108,9 @@ public class ControlledVocabulary {
|
|||||||
} else {
|
} else {
|
||||||
value = label;
|
value = label;
|
||||||
}
|
}
|
||||||
NodeList subNodes = XPathAPI.selectNodeList(node, "isComposedBy/node");
|
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||||
|
NodeList subNodes = (NodeList) xPath.compile("isComposedBy/node").evaluate(node,
|
||||||
|
XPathConstants.NODESET);
|
||||||
|
|
||||||
List<ControlledVocabulary> subVocabularies = new ArrayList<>(subNodes.getLength());
|
List<ControlledVocabulary> subVocabularies = new ArrayList<>(subNodes.getLength());
|
||||||
for (int i = 0; i < subNodes.getLength(); i++) {
|
for (int i = 0; i < subNodes.getLength(); i++) {
|
||||||
|
@@ -144,3 +144,5 @@ authentication-ip.Student = 6.6.6.6
|
|||||||
useProxies = true
|
useProxies = true
|
||||||
proxies.trusted.ipranges = 7.7.7.7
|
proxies.trusted.ipranges = 7.7.7.7
|
||||||
proxies.trusted.include_ui_ip = true
|
proxies.trusted.include_ui_ip = true
|
||||||
|
|
||||||
|
researcher-profile.entity-type = Person
|
@@ -140,6 +140,7 @@
|
|||||||
<dc-qualifier>ispartofseries</dc-qualifier>
|
<dc-qualifier>ispartofseries</dc-qualifier>
|
||||||
<repeatable>true</repeatable>
|
<repeatable>true</repeatable>
|
||||||
<label>Series/Report No.</label>
|
<label>Series/Report No.</label>
|
||||||
|
<type-bind>Technical Report</type-bind>
|
||||||
<input-type>series</input-type>
|
<input-type>series</input-type>
|
||||||
<hint>Enter the series and number assigned to this item by your community.</hint>
|
<hint>Enter the series and number assigned to this item by your community.</hint>
|
||||||
<required></required>
|
<required></required>
|
||||||
|
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* 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.access.status;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.AbstractUnitTest;
|
||||||
|
import org.dspace.access.status.factory.AccessStatusServiceFactory;
|
||||||
|
import org.dspace.access.status.service.AccessStatusService;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
|
import org.dspace.content.service.InstallItemService;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit Tests for access status service
|
||||||
|
*/
|
||||||
|
public class AccessStatusServiceTest extends AbstractUnitTest {
|
||||||
|
|
||||||
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(AccessStatusServiceTest.class);
|
||||||
|
|
||||||
|
private Collection collection;
|
||||||
|
private Community owningCommunity;
|
||||||
|
private Item item;
|
||||||
|
|
||||||
|
protected CommunityService communityService =
|
||||||
|
ContentServiceFactory.getInstance().getCommunityService();
|
||||||
|
protected CollectionService collectionService =
|
||||||
|
ContentServiceFactory.getInstance().getCollectionService();
|
||||||
|
protected ItemService itemService =
|
||||||
|
ContentServiceFactory.getInstance().getItemService();
|
||||||
|
protected WorkspaceItemService workspaceItemService =
|
||||||
|
ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||||
|
protected InstallItemService installItemService =
|
||||||
|
ContentServiceFactory.getInstance().getInstallItemService();
|
||||||
|
protected AccessStatusService accessStatusService =
|
||||||
|
AccessStatusServiceFactory.getInstance().getAccessStatusService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be run before every test as per @Before. It will
|
||||||
|
* initialize resources required for the tests.
|
||||||
|
*
|
||||||
|
* Other methods can be annotated with @Before here or in subclasses
|
||||||
|
* but no execution order is guaranteed
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
try {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
owningCommunity = communityService.create(null, context);
|
||||||
|
collection = collectionService.create(context, owningCommunity);
|
||||||
|
item = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
} catch (AuthorizeException ex) {
|
||||||
|
log.error("Authorization Error in init", ex);
|
||||||
|
fail("Authorization Error in init: " + ex.getMessage());
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
log.error("SQL Error in init", ex);
|
||||||
|
fail("SQL Error in init: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be run after every test as per @After. It will
|
||||||
|
* clean resources initialized by the @Before methods.
|
||||||
|
*
|
||||||
|
* Other methods can be annotated with @After here or in subclasses
|
||||||
|
* but no execution order is guaranteed
|
||||||
|
*/
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
try {
|
||||||
|
itemService.delete(context, item);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
collectionService.delete(context, collection);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
communityService.delete(context, owningCommunity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
item = null;
|
||||||
|
collection = null;
|
||||||
|
owningCommunity = null;
|
||||||
|
try {
|
||||||
|
super.destroy();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAccessStatus() throws Exception {
|
||||||
|
String status = accessStatusService.getAccessStatus(context, item);
|
||||||
|
assertNotEquals("testGetAccessStatus 0", status, DefaultAccessStatusHelper.UNKNOWN);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,423 @@
|
|||||||
|
/**
|
||||||
|
* 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.access.status;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.dspace.AbstractUnitTest;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
|
import org.dspace.authorize.ResourcePolicy;
|
||||||
|
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||||
|
import org.dspace.authorize.service.ResourcePolicyService;
|
||||||
|
import org.dspace.content.Bitstream;
|
||||||
|
import org.dspace.content.Bundle;
|
||||||
|
import org.dspace.content.Collection;
|
||||||
|
import org.dspace.content.Community;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.BitstreamService;
|
||||||
|
import org.dspace.content.service.BundleService;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
|
import org.dspace.content.service.CommunityService;
|
||||||
|
import org.dspace.content.service.InstallItemService;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.eperson.factory.EPersonServiceFactory;
|
||||||
|
import org.dspace.eperson.service.GroupService;
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DefaultAccessStatusHelperTest extends AbstractUnitTest {
|
||||||
|
|
||||||
|
private static final Logger log = LogManager.getLogger(DefaultAccessStatusHelperTest.class);
|
||||||
|
|
||||||
|
private Collection collection;
|
||||||
|
private Community owningCommunity;
|
||||||
|
private Item itemWithoutBundle;
|
||||||
|
private Item itemWithoutBitstream;
|
||||||
|
private Item itemWithBitstream;
|
||||||
|
private Item itemWithEmbargo;
|
||||||
|
private Item itemWithDateRestriction;
|
||||||
|
private Item itemWithGroupRestriction;
|
||||||
|
private Item itemWithoutPolicy;
|
||||||
|
private Item itemWithoutPrimaryBitstream;
|
||||||
|
private Item itemWithPrimaryAndMultipleBitstreams;
|
||||||
|
private Item itemWithoutPrimaryAndMultipleBitstreams;
|
||||||
|
private DefaultAccessStatusHelper helper;
|
||||||
|
private Date threshold;
|
||||||
|
|
||||||
|
protected CommunityService communityService =
|
||||||
|
ContentServiceFactory.getInstance().getCommunityService();
|
||||||
|
protected CollectionService collectionService =
|
||||||
|
ContentServiceFactory.getInstance().getCollectionService();
|
||||||
|
protected ItemService itemService =
|
||||||
|
ContentServiceFactory.getInstance().getItemService();
|
||||||
|
protected WorkspaceItemService workspaceItemService =
|
||||||
|
ContentServiceFactory.getInstance().getWorkspaceItemService();
|
||||||
|
protected InstallItemService installItemService =
|
||||||
|
ContentServiceFactory.getInstance().getInstallItemService();
|
||||||
|
protected BundleService bundleService =
|
||||||
|
ContentServiceFactory.getInstance().getBundleService();
|
||||||
|
protected BitstreamService bitstreamService =
|
||||||
|
ContentServiceFactory.getInstance().getBitstreamService();
|
||||||
|
protected ResourcePolicyService resourcePolicyService =
|
||||||
|
AuthorizeServiceFactory.getInstance().getResourcePolicyService();
|
||||||
|
protected GroupService groupService =
|
||||||
|
EPersonServiceFactory.getInstance().getGroupService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be run before every test as per @Before. It will
|
||||||
|
* initialize resources required for the tests.
|
||||||
|
*
|
||||||
|
* Other methods can be annotated with @Before here or in subclasses
|
||||||
|
* but no execution order is guaranteed
|
||||||
|
*/
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
super.init();
|
||||||
|
try {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
owningCommunity = communityService.create(null, context);
|
||||||
|
collection = collectionService.create(context, owningCommunity);
|
||||||
|
itemWithoutBundle = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithoutBitstream = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithBitstream = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithEmbargo = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithDateRestriction = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithGroupRestriction = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithoutPolicy = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithoutPrimaryBitstream = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithPrimaryAndMultipleBitstreams = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
itemWithoutPrimaryAndMultipleBitstreams = installItemService.installItem(context,
|
||||||
|
workspaceItemService.create(context, collection, true));
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
} catch (AuthorizeException ex) {
|
||||||
|
log.error("Authorization Error in init", ex);
|
||||||
|
fail("Authorization Error in init: " + ex.getMessage());
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
log.error("SQL Error in init", ex);
|
||||||
|
fail("SQL Error in init: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
helper = new DefaultAccessStatusHelper();
|
||||||
|
threshold = new LocalDate(10000, 1, 1).toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be run after every test as per @After. It will
|
||||||
|
* clean resources initialized by the @Before methods.
|
||||||
|
*
|
||||||
|
* Other methods can be annotated with @After here or in subclasses
|
||||||
|
* but no execution order is guaranteed
|
||||||
|
*/
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
try {
|
||||||
|
itemService.delete(context, itemWithoutBundle);
|
||||||
|
itemService.delete(context, itemWithoutBitstream);
|
||||||
|
itemService.delete(context, itemWithBitstream);
|
||||||
|
itemService.delete(context, itemWithEmbargo);
|
||||||
|
itemService.delete(context, itemWithDateRestriction);
|
||||||
|
itemService.delete(context, itemWithGroupRestriction);
|
||||||
|
itemService.delete(context, itemWithoutPolicy);
|
||||||
|
itemService.delete(context, itemWithoutPrimaryBitstream);
|
||||||
|
itemService.delete(context, itemWithPrimaryAndMultipleBitstreams);
|
||||||
|
itemService.delete(context, itemWithoutPrimaryAndMultipleBitstreams);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
collectionService.delete(context, collection);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
communityService.delete(context, owningCommunity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
itemWithoutBundle = null;
|
||||||
|
itemWithoutBitstream = null;
|
||||||
|
itemWithBitstream = null;
|
||||||
|
itemWithEmbargo = null;
|
||||||
|
itemWithDateRestriction = null;
|
||||||
|
itemWithGroupRestriction = null;
|
||||||
|
itemWithoutPolicy = null;
|
||||||
|
itemWithoutPrimaryBitstream = null;
|
||||||
|
itemWithPrimaryAndMultipleBitstreams = null;
|
||||||
|
itemWithoutPrimaryAndMultipleBitstreams = null;
|
||||||
|
collection = null;
|
||||||
|
owningCommunity = null;
|
||||||
|
helper = null;
|
||||||
|
threshold = null;
|
||||||
|
communityService = null;
|
||||||
|
collectionService = null;
|
||||||
|
itemService = null;
|
||||||
|
workspaceItemService = null;
|
||||||
|
installItemService = null;
|
||||||
|
bundleService = null;
|
||||||
|
bitstreamService = null;
|
||||||
|
resourcePolicyService = null;
|
||||||
|
groupService = null;
|
||||||
|
try {
|
||||||
|
super.destroy();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for a null item
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithNullItem() throws Exception {
|
||||||
|
String status = helper.getAccessStatusFromItem(context, null, threshold);
|
||||||
|
assertThat("testWithNullItem 0", status, equalTo(DefaultAccessStatusHelper.UNKNOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with no bundle
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithoutBundle() throws Exception {
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithoutBundle, threshold);
|
||||||
|
assertThat("testWithoutBundle 0", status, equalTo(DefaultAccessStatusHelper.METADATA_ONLY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with no bitstream
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithoutBitstream() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
bundleService.create(context, itemWithoutBitstream, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithoutBitstream, threshold);
|
||||||
|
assertThat("testWithoutBitstream 0", status, equalTo(DefaultAccessStatusHelper.METADATA_ONLY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with a basic bitstream (open access)
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithBitstream() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithBitstream, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bitstream.setName(context, "primary");
|
||||||
|
bundle.setPrimaryBitstreamID(bitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithBitstream, threshold);
|
||||||
|
assertThat("testWithBitstream 0", status, equalTo(DefaultAccessStatusHelper.OPEN_ACCESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with an embargo
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithEmbargo() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithEmbargo, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bitstream.setName(context, "primary");
|
||||||
|
bundle.setPrimaryBitstreamID(bitstream);
|
||||||
|
List<ResourcePolicy> policies = new ArrayList<>();
|
||||||
|
ResourcePolicy policy = resourcePolicyService.create(context);
|
||||||
|
policy.setRpName("Embargo");
|
||||||
|
Group group = groupService.findByName(context, Group.ANONYMOUS);
|
||||||
|
policy.setGroup(group);
|
||||||
|
policy.setAction(Constants.READ);
|
||||||
|
policy.setStartDate(new LocalDate(9999, 12, 31).toDate());
|
||||||
|
policies.add(policy);
|
||||||
|
authorizeService.removeAllPolicies(context, bitstream);
|
||||||
|
authorizeService.addPolicies(context, policies, bitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithEmbargo, threshold);
|
||||||
|
assertThat("testWithEmbargo 0", status, equalTo(DefaultAccessStatusHelper.EMBARGO));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with an anonymous date restriction
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithDateRestriction() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithDateRestriction, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bitstream.setName(context, "primary");
|
||||||
|
bundle.setPrimaryBitstreamID(bitstream);
|
||||||
|
List<ResourcePolicy> policies = new ArrayList<>();
|
||||||
|
ResourcePolicy policy = resourcePolicyService.create(context);
|
||||||
|
policy.setRpName("Restriction");
|
||||||
|
Group group = groupService.findByName(context, Group.ANONYMOUS);
|
||||||
|
policy.setGroup(group);
|
||||||
|
policy.setAction(Constants.READ);
|
||||||
|
policy.setStartDate(new LocalDate(10000, 1, 1).toDate());
|
||||||
|
policies.add(policy);
|
||||||
|
authorizeService.removeAllPolicies(context, bitstream);
|
||||||
|
authorizeService.addPolicies(context, policies, bitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithDateRestriction, threshold);
|
||||||
|
assertThat("testWithDateRestriction 0", status, equalTo(DefaultAccessStatusHelper.RESTRICTED));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with a group restriction
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithGroupRestriction() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithGroupRestriction, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bitstream.setName(context, "primary");
|
||||||
|
bundle.setPrimaryBitstreamID(bitstream);
|
||||||
|
List<ResourcePolicy> policies = new ArrayList<>();
|
||||||
|
ResourcePolicy policy = resourcePolicyService.create(context);
|
||||||
|
policy.setRpName("Restriction");
|
||||||
|
Group group = groupService.findByName(context, Group.ADMIN);
|
||||||
|
policy.setGroup(group);
|
||||||
|
policy.setAction(Constants.READ);
|
||||||
|
policies.add(policy);
|
||||||
|
authorizeService.removeAllPolicies(context, bitstream);
|
||||||
|
authorizeService.addPolicies(context, policies, bitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithGroupRestriction, threshold);
|
||||||
|
assertThat("testWithGroupRestriction 0", status, equalTo(DefaultAccessStatusHelper.RESTRICTED));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with no policy
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithoutPolicy() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithoutPolicy, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bitstream.setName(context, "primary");
|
||||||
|
bundle.setPrimaryBitstreamID(bitstream);
|
||||||
|
authorizeService.removeAllPolicies(context, bitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithoutPolicy, threshold);
|
||||||
|
assertThat("testWithoutPolicy 0", status, equalTo(DefaultAccessStatusHelper.RESTRICTED));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with no primary bitstream
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithoutPrimaryBitstream() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithoutPrimaryBitstream, Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
Bitstream bitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bitstream.setName(context, "first");
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithoutPrimaryBitstream, threshold);
|
||||||
|
assertThat("testWithoutPrimaryBitstream 0", status, equalTo(DefaultAccessStatusHelper.OPEN_ACCESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with an open access bitstream
|
||||||
|
* and another primary bitstream on embargo
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithPrimaryAndMultipleBitstreams() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithPrimaryAndMultipleBitstreams,
|
||||||
|
Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
Bitstream primaryBitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
bundle.setPrimaryBitstreamID(primaryBitstream);
|
||||||
|
List<ResourcePolicy> policies = new ArrayList<>();
|
||||||
|
ResourcePolicy policy = resourcePolicyService.create(context);
|
||||||
|
policy.setRpName("Embargo");
|
||||||
|
Group group = groupService.findByName(context, Group.ANONYMOUS);
|
||||||
|
policy.setGroup(group);
|
||||||
|
policy.setAction(Constants.READ);
|
||||||
|
policy.setStartDate(new LocalDate(9999, 12, 31).toDate());
|
||||||
|
policies.add(policy);
|
||||||
|
authorizeService.removeAllPolicies(context, primaryBitstream);
|
||||||
|
authorizeService.addPolicies(context, policies, primaryBitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithPrimaryAndMultipleBitstreams, threshold);
|
||||||
|
assertThat("testWithPrimaryAndMultipleBitstreams 0", status, equalTo(DefaultAccessStatusHelper.EMBARGO));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for an item with an open access bitstream
|
||||||
|
* and another bitstream on embargo
|
||||||
|
* @throws java.lang.Exception passed through.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWithNoPrimaryAndMultipleBitstreams() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Bundle bundle = bundleService.create(context, itemWithoutPrimaryAndMultipleBitstreams,
|
||||||
|
Constants.CONTENT_BUNDLE_NAME);
|
||||||
|
bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
Bitstream anotherBitstream = bitstreamService.create(context, bundle,
|
||||||
|
new ByteArrayInputStream("1".getBytes(StandardCharsets.UTF_8)));
|
||||||
|
List<ResourcePolicy> policies = new ArrayList<>();
|
||||||
|
ResourcePolicy policy = resourcePolicyService.create(context);
|
||||||
|
policy.setRpName("Embargo");
|
||||||
|
Group group = groupService.findByName(context, Group.ANONYMOUS);
|
||||||
|
policy.setGroup(group);
|
||||||
|
policy.setAction(Constants.READ);
|
||||||
|
policy.setStartDate(new LocalDate(9999, 12, 31).toDate());
|
||||||
|
policies.add(policy);
|
||||||
|
authorizeService.removeAllPolicies(context, anotherBitstream);
|
||||||
|
authorizeService.addPolicies(context, policies, anotherBitstream);
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
String status = helper.getAccessStatusFromItem(context, itemWithoutPrimaryAndMultipleBitstreams, threshold);
|
||||||
|
assertThat("testWithNoPrimaryAndMultipleBitstreams 0", status, equalTo(DefaultAccessStatusHelper.OPEN_ACCESS));
|
||||||
|
}
|
||||||
|
}
|
@@ -11,7 +11,8 @@ import java.sql.SQLException;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
@@ -26,7 +27,7 @@ import org.dspace.versioning.service.VersioningService;
|
|||||||
*/
|
*/
|
||||||
public class VersionBuilder extends AbstractBuilder<Version, VersioningService> {
|
public class VersionBuilder extends AbstractBuilder<Version, VersioningService> {
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger(VersionBuilder.class);
|
private static final Logger log = LogManager.getLogger(VersionBuilder.class);
|
||||||
|
|
||||||
private Version version;
|
private Version version;
|
||||||
|
|
||||||
|
@@ -12,14 +12,11 @@ import java.net.URLEncoder;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonArray;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import org.apache.commons.validator.routines.UrlValidator;
|
import org.apache.commons.validator.routines.UrlValidator;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
@@ -35,7 +32,6 @@ import org.dspace.app.iiif.model.generator.ContentAsTextGenerator;
|
|||||||
import org.dspace.app.iiif.model.generator.ManifestGenerator;
|
import org.dspace.app.iiif.model.generator.ManifestGenerator;
|
||||||
import org.dspace.app.iiif.model.generator.SearchResultGenerator;
|
import org.dspace.app.iiif.model.generator.SearchResultGenerator;
|
||||||
import org.dspace.app.iiif.service.utils.IIIFUtils;
|
import org.dspace.app.iiif.service.utils.IIIFUtils;
|
||||||
import org.dspace.discovery.SolrSearchCore;
|
|
||||||
import org.dspace.services.ConfigurationService;
|
import org.dspace.services.ConfigurationService;
|
||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -66,9 +62,6 @@ public class WordHighlightSolrSearch implements SearchAnnotationService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
SearchResultGenerator searchResult;
|
SearchResultGenerator searchResult;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
SolrSearchCore solrSearchCore;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
ManifestGenerator manifestGenerator;
|
ManifestGenerator manifestGenerator;
|
||||||
|
|
||||||
@@ -167,26 +160,49 @@ public class WordHighlightSolrSearch implements SearchAnnotationService {
|
|||||||
private String getAnnotationList(UUID uuid, String json, String query) {
|
private String getAnnotationList(UUID uuid, String json, String query) {
|
||||||
searchResult.setIdentifier(manifestId + "/search?q="
|
searchResult.setIdentifier(manifestId + "/search?q="
|
||||||
+ URLEncoder.encode(query, StandardCharsets.UTF_8));
|
+ URLEncoder.encode(query, StandardCharsets.UTF_8));
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
Gson gson = builder.create();
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
JsonObject body = gson.fromJson(json, JsonObject.class);
|
JsonNode body = null;
|
||||||
|
try {
|
||||||
|
body = mapper.readTree(json);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.error("Unable to process json response.", e);
|
||||||
|
}
|
||||||
|
// If error occurred or no body, return immediately
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
log.warn("Unable to process json response.");
|
|
||||||
return utils.asJson(searchResult.generateResource());
|
return utils.asJson(searchResult.generateResource());
|
||||||
}
|
}
|
||||||
// outer ocr highlight element
|
|
||||||
JsonObject highs = body.getAsJsonObject("ocrHighlighting");
|
// Example structure of Solr response available at
|
||||||
// highlight entries
|
// https://github.com/dbmdz/solr-ocrhighlighting/blob/main/docs/query.md
|
||||||
for (Map.Entry<String, JsonElement> ocrIds: highs.entrySet()) {
|
// Get the outer ocrHighlighting node
|
||||||
// ocr_text
|
JsonNode highs = body.get("ocrHighlighting");
|
||||||
JsonObject ocrObj = ocrIds.getValue().getAsJsonObject().getAsJsonObject("ocr_text");
|
if (highs != null) {
|
||||||
// snippets array
|
// Loop through each highlight entry under ocrHighlighting
|
||||||
if (ocrObj != null) {
|
for (final JsonNode highEntry : highs) {
|
||||||
for (JsonElement snippetArray : ocrObj.getAsJsonObject().get("snippets").getAsJsonArray()) {
|
// Get the ocr_text node under the entry
|
||||||
String pageId = getCanvasId(snippetArray.getAsJsonObject().get("pages"));
|
JsonNode ocrNode = highEntry.get("ocr_text");
|
||||||
for (JsonElement highlights : snippetArray.getAsJsonObject().getAsJsonArray("highlights")) {
|
if (ocrNode != null) {
|
||||||
for (JsonElement highlight : highlights.getAsJsonArray()) {
|
// Loop through the snippets array under that
|
||||||
searchResult.addResource(getAnnotation(highlight, pageId, uuid));
|
for (final JsonNode snippet : ocrNode.get("snippets")) {
|
||||||
|
if (snippet != null) {
|
||||||
|
// Get a canvas ID based on snippet's pages
|
||||||
|
String pageId = getCanvasId(snippet.get("pages"));
|
||||||
|
if (pageId != null) {
|
||||||
|
// Loop through array of highlights for each snippet.
|
||||||
|
for (final JsonNode highlights : snippet.get("highlights")) {
|
||||||
|
if (highlights != null) {
|
||||||
|
// May be multiple word highlights on a page, so loop through them.
|
||||||
|
for (int i = 0; i < highlights.size(); i++) {
|
||||||
|
// Add annotation associated with each highlight
|
||||||
|
AnnotationGenerator anno = getAnnotation(highlights.get(i), pageId, uuid);
|
||||||
|
if (anno != null) {
|
||||||
|
searchResult.addResource(anno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,22 +214,25 @@ public class WordHighlightSolrSearch implements SearchAnnotationService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the annotation generator for the highlight.
|
* Returns the annotation generator for the highlight.
|
||||||
* @param highlight highlight element from solor response
|
* @param highlight highlight node from Solr response
|
||||||
* @param pageId page id from solr response
|
* @param pageId page id from solr response
|
||||||
* @return generator for a single annotation
|
* @return generator for a single annotation
|
||||||
*/
|
*/
|
||||||
private AnnotationGenerator getAnnotation(JsonElement highlight, String pageId, UUID uuid) {
|
private AnnotationGenerator getAnnotation(JsonNode highlight, String pageId, UUID uuid) {
|
||||||
JsonObject hcoords = highlight.getAsJsonObject();
|
String text = highlight.get("text") != null ? highlight.get("text").asText() : null;
|
||||||
String text = (hcoords.get("text").getAsString());
|
int ulx = highlight.get("ulx") != null ? highlight.get("ulx").asInt() : -1;
|
||||||
int ulx = hcoords.get("ulx").getAsInt();
|
int uly = highlight.get("uly") != null ? highlight.get("uly").asInt() : -1;
|
||||||
int uly = hcoords.get("uly").getAsInt();
|
int lrx = highlight.get("lrx") != null ? highlight.get("lrx").asInt() : -1;
|
||||||
int lrx = hcoords.get("lrx").getAsInt();
|
int lry = highlight.get("lry") != null ? highlight.get("lry").asInt() : -1;
|
||||||
int lry = hcoords.get("lry").getAsInt();
|
String w = (lrx >= 0 && ulx >= 0) ? Integer.toString(lrx - ulx) : null;
|
||||||
String w = Integer.toString(lrx - ulx);
|
String h = (lry >= 0 && uly >= 0) ? Integer.toString(lry - uly) : null;
|
||||||
String h = Integer.toString(lry - uly);
|
|
||||||
|
if (text != null && w != null && h != null) {
|
||||||
String params = ulx + "," + uly + "," + w + "," + h;
|
String params = ulx + "," + uly + "," + w + "," + h;
|
||||||
return createSearchResultAnnotation(params, text, pageId, uuid);
|
return createSearchResultAnnotation(params, text, pageId, uuid);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns position of canvas. Uses the "pages" id attribute.
|
* Returns position of canvas. Uses the "pages" id attribute.
|
||||||
@@ -221,16 +240,23 @@ public class WordHighlightSolrSearch implements SearchAnnotationService {
|
|||||||
* delimited with a "." and that the integer corresponds to the
|
* delimited with a "." and that the integer corresponds to the
|
||||||
* canvas identifier in the manifest. For METS/ALTO documents, the page
|
* canvas identifier in the manifest. For METS/ALTO documents, the page
|
||||||
* order can be derived from the METS file when loading the solr index.
|
* order can be derived from the METS file when loading the solr index.
|
||||||
* @param element the pages element
|
* @param pagesNode the pages node
|
||||||
* @return canvas id
|
* @return canvas id or null if node was null
|
||||||
*/
|
*/
|
||||||
private String getCanvasId(JsonElement element) {
|
private String getCanvasId(JsonNode pagesNode) {
|
||||||
JsonArray pages = element.getAsJsonArray();
|
if (pagesNode != null) {
|
||||||
JsonObject page = pages.get(0).getAsJsonObject();
|
JsonNode page = pagesNode.get(0);
|
||||||
String[] identArr = page.get("id").getAsString().split("\\.");
|
if (page != null) {
|
||||||
|
JsonNode pageId = page.get("id");
|
||||||
|
if (pageId != null) {
|
||||||
|
String[] identArr = pageId.asText().split("\\.");
|
||||||
// the canvas id.
|
// the canvas id.
|
||||||
return "c" + identArr[1];
|
return "c" + identArr[1];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates annotation with word highlight coordinates.
|
* Creates annotation with word highlight coordinates.
|
||||||
|
@@ -82,10 +82,6 @@
|
|||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-all</artifactId>
|
<artifactId>mockito-all</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
|
||||||
<groupId>xml-apis</groupId>
|
|
||||||
<artifactId>xml-apis</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
@@ -22,6 +22,7 @@ import org.dspace.services.ConfigurationService;
|
|||||||
import org.dspace.services.factory.DSpaceServicesFactory;
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
public class DSpaceResourceResolver implements ResourceResolver {
|
public class DSpaceResourceResolver implements ResourceResolver {
|
||||||
|
// Requires usage of Saxon as OAI-PMH uses some XSLT 2 functions
|
||||||
private static final TransformerFactory transformerFactory = TransformerFactory
|
private static final TransformerFactory transformerFactory = TransformerFactory
|
||||||
.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
|
.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ import javax.xml.transform.stream.StreamSource;
|
|||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
public abstract class AbstractXSLTest {
|
public abstract class AbstractXSLTest {
|
||||||
|
// Requires usage of Saxon as OAI-PMH uses some XSLT 2 functions
|
||||||
private static final TransformerFactory factory = TransformerFactory
|
private static final TransformerFactory factory = TransformerFactory
|
||||||
.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
|
.newInstance("net.sf.saxon.TransformerFactoryImpl", null);
|
||||||
|
|
||||||
|
@@ -8,17 +8,20 @@
|
|||||||
package org.dspace.app.rest.authorization.impl;
|
package org.dspace.app.rest.authorization.impl;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.dspace.app.profile.service.ResearcherProfileService;
|
||||||
import org.dspace.app.rest.authorization.AuthorizationFeature;
|
import org.dspace.app.rest.authorization.AuthorizationFeature;
|
||||||
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
|
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
|
||||||
import org.dspace.app.rest.model.BaseObjectRest;
|
import org.dspace.app.rest.model.BaseObjectRest;
|
||||||
import org.dspace.app.rest.model.ItemRest;
|
import org.dspace.app.rest.model.ItemRest;
|
||||||
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -32,33 +35,41 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@AuthorizationFeatureDocumentation(name = CanClaimItemFeature.NAME,
|
@AuthorizationFeatureDocumentation(name = CanClaimItemFeature.NAME,
|
||||||
description = "Used to verify if the given user can request the claim of an item")
|
description = "Used to verify if the current user is able to claim this item as their profile. "
|
||||||
|
+ "Only available if the current item is not already claimed.")
|
||||||
public class CanClaimItemFeature implements AuthorizationFeature {
|
public class CanClaimItemFeature implements AuthorizationFeature {
|
||||||
|
|
||||||
public static final String NAME = "canClaimItem";
|
public static final String NAME = "canClaimItem";
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CanClaimItemFeature.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ItemService itemService;
|
private ItemService itemService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ShowClaimItemFeature showClaimItemFeature;
|
private ResearcherProfileService researcherProfileService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
|
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
|
||||||
|
|
||||||
if (!showClaimItemFeature.isAuthorized(context, object)) {
|
if (!(object instanceof ItemRest) || context.getCurrentUser() == null) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(object instanceof ItemRest) || Objects.isNull(context.getCurrentUser())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String id = ((ItemRest) object).getId();
|
String id = ((ItemRest) object).getId();
|
||||||
Item item = itemService.find(context, UUID.fromString(id));
|
Item item = itemService.find(context, UUID.fromString(id));
|
||||||
|
|
||||||
return hasNotOwner(item);
|
return researcherProfileService.hasProfileType(item) && hasNotOwner(item) && hasNotAlreadyAProfile(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasNotAlreadyAProfile(Context context) {
|
||||||
|
try {
|
||||||
|
return researcherProfileService.findById(context, context.getCurrentUser().getID()) == null;
|
||||||
|
} catch (SQLException | AuthorizeException e) {
|
||||||
|
LOG.warn("Error while checking if eperson has a ResearcherProfileAssociated: {}", e.getMessage(), e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNotOwner(Item item) {
|
private boolean hasNotOwner(Item item) {
|
||||||
|
@@ -1,80 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.authorization.impl;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.dspace.app.profile.service.ResearcherProfileService;
|
|
||||||
import org.dspace.app.rest.authorization.AuthorizationFeature;
|
|
||||||
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
|
|
||||||
import org.dspace.app.rest.model.BaseObjectRest;
|
|
||||||
import org.dspace.app.rest.model.ItemRest;
|
|
||||||
import org.dspace.authorize.AuthorizeException;
|
|
||||||
import org.dspace.content.Item;
|
|
||||||
import org.dspace.content.service.ItemService;
|
|
||||||
import org.dspace.core.Context;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the given user can request the claim of an item. Whether or not the
|
|
||||||
* user can then make the claim is determined by the feature
|
|
||||||
* {@link CanClaimItemFeature}.
|
|
||||||
*
|
|
||||||
* @author Corrado Lombardi (corrado.lombardi at 4science.it)
|
|
||||||
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@AuthorizationFeatureDocumentation(name = ShowClaimItemFeature.NAME,
|
|
||||||
description = "Used to verify if the given user can request the claim of an item")
|
|
||||||
public class ShowClaimItemFeature implements AuthorizationFeature {
|
|
||||||
|
|
||||||
public static final String NAME = "showClaimItem";
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ShowClaimItemFeature.class);
|
|
||||||
|
|
||||||
private final ItemService itemService;
|
|
||||||
private final ResearcherProfileService researcherProfileService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public ShowClaimItemFeature(ItemService itemService, ResearcherProfileService researcherProfileService) {
|
|
||||||
this.itemService = itemService;
|
|
||||||
this.researcherProfileService = researcherProfileService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
|
|
||||||
|
|
||||||
if (!(object instanceof ItemRest) || Objects.isNull(context.getCurrentUser())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String id = ((ItemRest) object).getId();
|
|
||||||
Item item = itemService.find(context, UUID.fromString(id));
|
|
||||||
|
|
||||||
return researcherProfileService.hasProfileType(item) && hasNotAlreadyAProfile(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasNotAlreadyAProfile(Context context) {
|
|
||||||
try {
|
|
||||||
return researcherProfileService.findById(context, context.getCurrentUser().getID()) == null;
|
|
||||||
} catch (SQLException | AuthorizeException e) {
|
|
||||||
LOG.warn("Error while checking if eperson has a ResearcherProfileAssociated: {}", e.getMessage(), e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getSupportedTypes() {
|
|
||||||
return new String[] {ItemRest.CATEGORY + "." + ItemRest.NAME};
|
|
||||||
}
|
|
||||||
}
|
|
@@ -155,6 +155,7 @@ public class SubmissionFormConverter implements DSpaceConverter<DCInputSet, Subm
|
|||||||
inputField.setInput(inputRest);
|
inputField.setInput(inputRest);
|
||||||
if (dcinput.isMetadataField()) {
|
if (dcinput.isMetadataField()) {
|
||||||
inputField.setSelectableMetadata(selectableMetadata);
|
inputField.setSelectableMetadata(selectableMetadata);
|
||||||
|
inputField.setTypeBind(dcinput.getTypeBindList());
|
||||||
}
|
}
|
||||||
if (dcinput.isRelationshipField()) {
|
if (dcinput.isRelationshipField()) {
|
||||||
selectableRelationship = getSelectableRelationships(dcinput);
|
selectableRelationship = getSelectableRelationships(dcinput);
|
||||||
|
@@ -116,7 +116,7 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH
|
|||||||
HttpServletResponse.SC_METHOD_NOT_ALLOWED);
|
HttpServletResponse.SC_METHOD_NOT_ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler( {UnprocessableEntityException.class})
|
@ExceptionHandler({ UnprocessableEntityException.class, ResourceAlreadyExistsException.class })
|
||||||
protected void handleUnprocessableEntityException(HttpServletRequest request, HttpServletResponse response,
|
protected void handleUnprocessableEntityException(HttpServletRequest request, HttpServletResponse response,
|
||||||
Exception ex) throws IOException {
|
Exception ex) throws IOException {
|
||||||
//422 is not defined in HttpServletResponse. Its meaning is "Unprocessable Entity".
|
//422 is not defined in HttpServletResponse. Its meaning is "Unprocessable Entity".
|
||||||
@@ -167,12 +167,6 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH
|
|||||||
HttpStatus.BAD_REQUEST.value());
|
HttpStatus.BAD_REQUEST.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(ResourceAlreadyExistsException.class)
|
|
||||||
protected void resourceConflictException(HttpServletRequest request, HttpServletResponse response,
|
|
||||||
ResourceAlreadyExistsException ex) throws IOException {
|
|
||||||
sendErrorResponse(request, response, null, ex.getMessage(), HttpStatus.UNPROCESSABLE_ENTITY.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExceptionHandler(MissingParameterException.class)
|
@ExceptionHandler(MissingParameterException.class)
|
||||||
protected void MissingParameterException(HttpServletRequest request, HttpServletResponse response, Exception ex)
|
protected void MissingParameterException(HttpServletRequest request, HttpServletResponse response, Exception ex)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
@@ -74,12 +74,12 @@ public class ResearcherProfileAutomaticClaim implements PostLoggedInAction {
|
|||||||
@Override
|
@Override
|
||||||
public void loggedIn(Context context) {
|
public void loggedIn(Context context) {
|
||||||
|
|
||||||
EPerson currentUser = context.getCurrentUser();
|
if (isBlank(researcherProfileService.getProfileType())) {
|
||||||
if (currentUser == null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBlank(researcherProfileService.getProfileType())) {
|
EPerson currentUser = context.getCurrentUser();
|
||||||
|
if (currentUser == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* 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 com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty.Access;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Access Status REST Resource.
|
||||||
|
*/
|
||||||
|
public class AccessStatusRest implements RestModel {
|
||||||
|
public static final String NAME = "accessStatus";
|
||||||
|
|
||||||
|
String status;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonProperty(access = Access.READ_ONLY)
|
||||||
|
public String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@JsonIgnore
|
||||||
|
public String getTypePlural() {
|
||||||
|
return getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccessStatusRest() {
|
||||||
|
setStatus(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccessStatusRest(String status) {
|
||||||
|
setStatus(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
* @author Andrea Bollini (andrea.bollini at 4science.it)
|
||||||
*/
|
*/
|
||||||
@LinksRest(links = {
|
@LinksRest(links = {
|
||||||
|
@LinkRest(
|
||||||
|
name = ItemRest.ACCESS_STATUS,
|
||||||
|
method = "getAccessStatus"
|
||||||
|
),
|
||||||
@LinkRest(
|
@LinkRest(
|
||||||
name = ItemRest.BUNDLES,
|
name = ItemRest.BUNDLES,
|
||||||
method = "getBundles"
|
method = "getBundles"
|
||||||
@@ -51,6 +55,7 @@ public class ItemRest extends DSpaceObjectRest {
|
|||||||
public static final String PLURAL_NAME = "items";
|
public static final String PLURAL_NAME = "items";
|
||||||
public static final String CATEGORY = RestAddressableModel.CORE;
|
public static final String CATEGORY = RestAddressableModel.CORE;
|
||||||
|
|
||||||
|
public static final String ACCESS_STATUS = "accessStatus";
|
||||||
public static final String BUNDLES = "bundles";
|
public static final String BUNDLES = "bundles";
|
||||||
public static final String MAPPED_COLLECTIONS = "mappedCollections";
|
public static final String MAPPED_COLLECTIONS = "mappedCollections";
|
||||||
public static final String OWNING_COLLECTION = "owningCollection";
|
public static final String OWNING_COLLECTION = "owningCollection";
|
||||||
|
@@ -83,6 +83,11 @@ public class SubmissionFormFieldRest {
|
|||||||
*/
|
*/
|
||||||
private List<LanguageFormField> languageCodes;
|
private List<LanguageFormField> languageCodes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of type bind value
|
||||||
|
*/
|
||||||
|
private List<String> typeBind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for {@link #selectableMetadata}
|
* Getter for {@link #selectableMetadata}
|
||||||
*
|
*
|
||||||
@@ -266,6 +271,14 @@ public class SubmissionFormFieldRest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getTypeBind() {
|
||||||
|
return typeBind;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypeBind(List<String> typeBind) {
|
||||||
|
this.typeBind = typeBind;
|
||||||
|
}
|
||||||
|
|
||||||
public SelectableRelationship getSelectableRelationship() {
|
public SelectableRelationship getSelectableRelationship() {
|
||||||
return selectableRelationship;
|
return selectableRelationship;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* 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 com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||||
|
import org.dspace.app.rest.model.AccessStatusRest;
|
||||||
|
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access Status Rest HAL Resource. The HAL Resource wraps the REST Resource
|
||||||
|
* adding support for the links and embedded resources
|
||||||
|
*/
|
||||||
|
@RelNameDSpaceResource(AccessStatusRest.NAME)
|
||||||
|
public class AccessStatusResource extends HALResource<AccessStatusRest> {
|
||||||
|
|
||||||
|
@JsonUnwrapped
|
||||||
|
private AccessStatusRest data;
|
||||||
|
|
||||||
|
public AccessStatusResource(AccessStatusRest entry) {
|
||||||
|
super(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccessStatusRest getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
@@ -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.repository;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.dspace.access.status.service.AccessStatusService;
|
||||||
|
import org.dspace.app.rest.model.AccessStatusRest;
|
||||||
|
import org.dspace.app.rest.model.ItemRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.content.Item;
|
||||||
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link repository for calculating the access status of an Item
|
||||||
|
*/
|
||||||
|
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.ACCESS_STATUS)
|
||||||
|
public class ItemAccessStatusLinkRepository extends AbstractDSpaceRestRepository
|
||||||
|
implements LinkRestRepository {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ItemService itemService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AccessStatusService accessStatusService;
|
||||||
|
|
||||||
|
@PreAuthorize("hasPermission(#itemId, 'ITEM', 'READ')")
|
||||||
|
public AccessStatusRest getAccessStatus(@Nullable HttpServletRequest request,
|
||||||
|
UUID itemId,
|
||||||
|
@Nullable Pageable optionalPageable,
|
||||||
|
Projection projection) {
|
||||||
|
try {
|
||||||
|
Context context = obtainContext();
|
||||||
|
Item item = itemService.find(context, itemId);
|
||||||
|
if (item == null) {
|
||||||
|
throw new ResourceNotFoundException("No such item: " + itemId);
|
||||||
|
}
|
||||||
|
AccessStatusRest accessStatusRest = new AccessStatusRest();
|
||||||
|
String accessStatus = accessStatusService.getAccessStatus(context, item);
|
||||||
|
accessStatusRest.setStatus(accessStatus);
|
||||||
|
return accessStatusRest;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -18,9 +18,9 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.dspace.app.rest.Parameter;
|
import org.dspace.app.rest.Parameter;
|
||||||
@@ -296,9 +296,14 @@ public class MetadataFieldRestRepository extends DSpaceRestRepository<MetadataFi
|
|||||||
protected MetadataFieldRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
protected MetadataFieldRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
||||||
Integer id, JsonNode jsonNode) throws SQLException, AuthorizeException {
|
Integer id, JsonNode jsonNode) throws SQLException, AuthorizeException {
|
||||||
|
|
||||||
MetadataFieldRest metadataFieldRest = new Gson().fromJson(jsonNode.toString(), MetadataFieldRest.class);
|
MetadataFieldRest metadataFieldRest;
|
||||||
|
try {
|
||||||
|
metadataFieldRest = new ObjectMapper().readValue(jsonNode.toString(), MetadataFieldRest.class);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new UnprocessableEntityException("Cannot parse JSON in request body", e);
|
||||||
|
}
|
||||||
|
|
||||||
if (isBlank(metadataFieldRest.getElement())) {
|
if (metadataFieldRest == null || isBlank(metadataFieldRest.getElement())) {
|
||||||
throw new UnprocessableEntityException("metadata element (in request body) cannot be blank");
|
throw new UnprocessableEntityException("metadata element (in request body) cannot be blank");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,9 +15,9 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.Gson;
|
|
||||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||||
import org.dspace.app.rest.model.MetadataSchemaRest;
|
import org.dspace.app.rest.model.MetadataSchemaRest;
|
||||||
@@ -138,9 +138,14 @@ public class MetadataSchemaRestRepository extends DSpaceRestRepository<MetadataS
|
|||||||
protected MetadataSchemaRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
protected MetadataSchemaRest put(Context context, HttpServletRequest request, String apiCategory, String model,
|
||||||
Integer id, JsonNode jsonNode) throws SQLException, AuthorizeException {
|
Integer id, JsonNode jsonNode) throws SQLException, AuthorizeException {
|
||||||
|
|
||||||
MetadataSchemaRest metadataSchemaRest = new Gson().fromJson(jsonNode.toString(), MetadataSchemaRest.class);
|
MetadataSchemaRest metadataSchemaRest;
|
||||||
|
try {
|
||||||
|
metadataSchemaRest = new ObjectMapper().readValue(jsonNode.toString(), MetadataSchemaRest.class);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new UnprocessableEntityException("Cannot parse JSON in request body", e);
|
||||||
|
}
|
||||||
|
|
||||||
if (isBlank(metadataSchemaRest.getPrefix())) {
|
if (metadataSchemaRest == null || isBlank(metadataSchemaRest.getPrefix())) {
|
||||||
throw new UnprocessableEntityException("metadata schema name cannot be blank");
|
throw new UnprocessableEntityException("metadata schema name cannot be blank");
|
||||||
}
|
}
|
||||||
if (isBlank(metadataSchemaRest.getNamespace())) {
|
if (isBlank(metadataSchemaRest.getNamespace())) {
|
||||||
|
@@ -137,7 +137,11 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
|
|||||||
output = createAuthentication(newContext);
|
output = createAuthentication(newContext);
|
||||||
|
|
||||||
for (PostLoggedInAction action : postLoggedInActions) {
|
for (PostLoggedInAction action : postLoggedInActions) {
|
||||||
|
try {
|
||||||
action.loggedIn(newContext);
|
action.loggedIn(newContext);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("An error occurs performing post logged in action", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@@ -306,7 +306,9 @@ public class SubmissionService {
|
|||||||
result.setRights(creativeCommonsService.getLicenseName(item));
|
result.setRights(creativeCommonsService.getLicenseName(item));
|
||||||
|
|
||||||
Bitstream licenseRdfBitstream = creativeCommonsService.getLicenseRdfBitstream(item);
|
Bitstream licenseRdfBitstream = creativeCommonsService.getLicenseRdfBitstream(item);
|
||||||
|
if (licenseRdfBitstream != null) {
|
||||||
result.setFile(converter.toRest(licenseRdfBitstream, Projection.DEFAULT));
|
result.setFile(converter.toRest(licenseRdfBitstream, Projection.DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,8 @@ import org.dspace.content.InProgressSubmission;
|
|||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.core.Utils;
|
import org.dspace.core.Utils;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
import org.dspace.services.factory.DSpaceServicesFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describe step for DSpace Spring Rest. Expose and allow patching of the in progress submission metadata. It is
|
* Describe step for DSpace Spring Rest. Expose and allow patching of the in progress submission metadata. It is
|
||||||
@@ -43,7 +45,11 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
|
|
||||||
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(DescribeStep.class);
|
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(DescribeStep.class);
|
||||||
|
|
||||||
|
// Input reader for form configuration
|
||||||
private DCInputsReader inputReader;
|
private DCInputsReader inputReader;
|
||||||
|
// Configuration service
|
||||||
|
private final ConfigurationService configurationService =
|
||||||
|
DSpaceServicesFactory.getInstance().getConfigurationService();
|
||||||
|
|
||||||
public DescribeStep() throws DCInputsReaderException {
|
public DescribeStep() throws DCInputsReaderException {
|
||||||
inputReader = new DCInputsReader();
|
inputReader = new DCInputsReader();
|
||||||
@@ -64,8 +70,17 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
|
|
||||||
private void readField(InProgressSubmission obj, SubmissionStepConfig config, DataDescribe data,
|
private void readField(InProgressSubmission obj, SubmissionStepConfig config, DataDescribe data,
|
||||||
DCInputSet inputConfig) throws DCInputsReaderException {
|
DCInputSet inputConfig) throws DCInputsReaderException {
|
||||||
|
String documentTypeValue = "";
|
||||||
|
List<MetadataValue> documentType = itemService.getMetadataByMetadataString(obj.getItem(),
|
||||||
|
configurationService.getProperty("submit.type-bind.field", "dc.type"));
|
||||||
|
if (documentType.size() > 0) {
|
||||||
|
documentTypeValue = documentType.get(0).getValue();
|
||||||
|
}
|
||||||
for (DCInput[] row : inputConfig.getFields()) {
|
for (DCInput[] row : inputConfig.getFields()) {
|
||||||
for (DCInput input : row) {
|
for (DCInput input : row) {
|
||||||
|
// Is this input allowed for the document type, as per type bind config? If there is no type
|
||||||
|
// bind set, this is always true
|
||||||
|
boolean allowed = input.isAllowedFor(documentTypeValue);
|
||||||
|
|
||||||
List<String> fieldsName = new ArrayList<String>();
|
List<String> fieldsName = new ArrayList<String>();
|
||||||
if (input.isQualdropValue()) {
|
if (input.isQualdropValue()) {
|
||||||
@@ -91,6 +106,9 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
String[] metadataToCheck = Utils.tokenize(md.getMetadataField().toString());
|
String[] metadataToCheck = Utils.tokenize(md.getMetadataField().toString());
|
||||||
if (data.getMetadata().containsKey(
|
if (data.getMetadata().containsKey(
|
||||||
Utils.standardize(metadataToCheck[0], metadataToCheck[1], metadataToCheck[2], "."))) {
|
Utils.standardize(metadataToCheck[0], metadataToCheck[1], metadataToCheck[2], "."))) {
|
||||||
|
// If field is allowed by type bind, add value to existing field set, otherwise remove
|
||||||
|
// all values for this field
|
||||||
|
if (allowed) {
|
||||||
data.getMetadata()
|
data.getMetadata()
|
||||||
.get(Utils.standardize(md.getMetadataField().getMetadataSchema().getName(),
|
.get(Utils.standardize(md.getMetadataField().getMetadataSchema().getName(),
|
||||||
md.getMetadataField().getElement(),
|
md.getMetadataField().getElement(),
|
||||||
@@ -98,6 +116,12 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
"."))
|
"."))
|
||||||
.add(dto);
|
.add(dto);
|
||||||
} else {
|
} else {
|
||||||
|
data.getMetadata().remove(Utils.standardize(metadataToCheck[0], metadataToCheck[1],
|
||||||
|
metadataToCheck[2], "."));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Add values only if allowed by type bind
|
||||||
|
if (allowed) {
|
||||||
List<MetadataValueRest> listDto = new ArrayList<>();
|
List<MetadataValueRest> listDto = new ArrayList<>();
|
||||||
listDto.add(dto);
|
listDto.add(dto);
|
||||||
data.getMetadata()
|
data.getMetadata()
|
||||||
@@ -111,6 +135,7 @@ public class DescribeStep extends AbstractProcessingStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doPatchProcessing(Context context, HttpServletRequest currentRequest, InProgressSubmission source,
|
public void doPatchProcessing(Context context, HttpServletRequest currentRequest, InProgressSubmission source,
|
||||||
|
@@ -16,6 +16,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import org.dspace.app.rest.model.ErrorRest;
|
import org.dspace.app.rest.model.ErrorRest;
|
||||||
import org.dspace.app.rest.repository.WorkspaceItemRestRepository;
|
import org.dspace.app.rest.repository.WorkspaceItemRestRepository;
|
||||||
import org.dspace.app.rest.submit.SubmissionService;
|
import org.dspace.app.rest.submit.SubmissionService;
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
import org.dspace.app.util.DCInput;
|
import org.dspace.app.util.DCInput;
|
||||||
import org.dspace.app.util.DCInputSet;
|
import org.dspace.app.util.DCInputSet;
|
||||||
import org.dspace.app.util.DCInputsReader;
|
import org.dspace.app.util.DCInputsReader;
|
||||||
@@ -25,6 +26,7 @@ import org.dspace.content.InProgressSubmission;
|
|||||||
import org.dspace.content.MetadataValue;
|
import org.dspace.content.MetadataValue;
|
||||||
import org.dspace.content.authority.service.MetadataAuthorityService;
|
import org.dspace.content.authority.service.MetadataAuthorityService;
|
||||||
import org.dspace.content.service.ItemService;
|
import org.dspace.content.service.ItemService;
|
||||||
|
import org.dspace.services.ConfigurationService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute three validation check on fields validation:
|
* Execute three validation check on fields validation:
|
||||||
@@ -50,12 +52,20 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
|
|
||||||
private MetadataAuthorityService metadataAuthorityService;
|
private MetadataAuthorityService metadataAuthorityService;
|
||||||
|
|
||||||
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ErrorRest> validate(SubmissionService submissionService, InProgressSubmission obj,
|
public List<ErrorRest> validate(SubmissionService submissionService, InProgressSubmission obj,
|
||||||
SubmissionStepConfig config) throws DCInputsReaderException, SQLException {
|
SubmissionStepConfig config) throws DCInputsReaderException, SQLException {
|
||||||
|
|
||||||
List<ErrorRest> errors = new ArrayList<>();
|
List<ErrorRest> errors = new ArrayList<>();
|
||||||
|
String documentTypeValue = "";
|
||||||
DCInputSet inputConfig = getInputReader().getInputsByFormName(config.getId());
|
DCInputSet inputConfig = getInputReader().getInputsByFormName(config.getId());
|
||||||
|
List<MetadataValue> documentType = itemService.getMetadataByMetadataString(obj.getItem(),
|
||||||
|
configurationService.getProperty("submit.type-bind.field", "dc.type"));
|
||||||
|
if (documentType.size() > 0) {
|
||||||
|
documentTypeValue = documentType.get(0).getValue();
|
||||||
|
}
|
||||||
for (DCInput[] row : inputConfig.getFields()) {
|
for (DCInput[] row : inputConfig.getFields()) {
|
||||||
for (DCInput input : row) {
|
for (DCInput input : row) {
|
||||||
String fieldKey =
|
String fieldKey =
|
||||||
@@ -71,12 +81,21 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
for (int i = 1; i < inputPairs.size(); i += 2) {
|
for (int i = 1; i < inputPairs.size(); i += 2) {
|
||||||
String fullFieldname = input.getFieldName() + "." + (String) inputPairs.get(i);
|
String fullFieldname = input.getFieldName() + "." + (String) inputPairs.get(i);
|
||||||
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fullFieldname);
|
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fullFieldname);
|
||||||
|
// If the input is not allowed for this type, strip it from item metadata.
|
||||||
|
if (!input.isAllowedFor(documentTypeValue)) {
|
||||||
|
itemService.removeMetadataValues(ContextUtil.obtainCurrentRequestContext(),
|
||||||
|
obj.getItem(), mdv);
|
||||||
|
} else {
|
||||||
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
||||||
if (mdv.size() > 0 && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
if (mdv.size() > 0 && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
||||||
foundResult = true;
|
foundResult = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (input.isRequired() && ! foundResult) {
|
}
|
||||||
|
// If the input is required but not allowed for this type, and we removed, don't throw
|
||||||
|
// an error - this way, a field can be required for "Book" to which it is bound, but not
|
||||||
|
// other types. A user may have switched between types before a final deposit
|
||||||
|
if (input.isRequired() && !foundResult && input.isAllowedFor(documentTypeValue)) {
|
||||||
// for this required qualdrop no value was found, add to the list of error fields
|
// for this required qualdrop no value was found, add to the list of error fields
|
||||||
addError(errors, ERROR_VALIDATION_REQUIRED,
|
addError(errors, ERROR_VALIDATION_REQUIRED,
|
||||||
"/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + config.getId() + "/" +
|
"/" + WorkspaceItemRestRepository.OPERATION_PATH_SECTIONS + "/" + config.getId() + "/" +
|
||||||
@@ -89,6 +108,12 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
|
|
||||||
for (String fieldName : fieldsName) {
|
for (String fieldName : fieldsName) {
|
||||||
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fieldName);
|
List<MetadataValue> mdv = itemService.getMetadataByMetadataString(obj.getItem(), fieldName);
|
||||||
|
if (!input.isAllowedFor(documentTypeValue)) {
|
||||||
|
itemService.removeMetadataValues(ContextUtil.obtainCurrentRequestContext(), obj.getItem(), mdv);
|
||||||
|
// Continue here, this skips the required check since we've just removed values that previously
|
||||||
|
// appeared, and the configuration already indicates this field shouldn't be included
|
||||||
|
continue;
|
||||||
|
}
|
||||||
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
validateMetadataValues(mdv, input, config, isAuthorityControlled, fieldKey, errors);
|
||||||
if ((input.isRequired() && mdv.size() == 0) && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
if ((input.isRequired() && mdv.size() == 0) && input.isVisible(DCInput.SUBMISSION_SCOPE)) {
|
||||||
// since this field is missing add to list of error
|
// since this field is missing add to list of error
|
||||||
@@ -124,6 +149,10 @@ public class MetadataValidation extends AbstractValidation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setConfigurationService(ConfigurationService configurationService) {
|
||||||
|
this.configurationService = configurationService;
|
||||||
|
}
|
||||||
|
|
||||||
public void setItemService(ItemService itemService) {
|
public void setItemService(ItemService itemService) {
|
||||||
this.itemService = itemService;
|
this.itemService = itemService;
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
<bean name="metadataValidation" class="org.dspace.app.rest.submit.step.validation.MetadataValidation"
|
<bean name="metadataValidation" class="org.dspace.app.rest.submit.step.validation.MetadataValidation"
|
||||||
scope="prototype">
|
scope="prototype">
|
||||||
<property name="name" value="submission-form"/>
|
<property name="name" value="submission-form"/>
|
||||||
|
<property name="configurationService" ref="org.dspace.services.ConfigurationService"/>
|
||||||
<property name="itemService" ref="org.dspace.content.ItemServiceImpl"/>
|
<property name="itemService" ref="org.dspace.content.ItemServiceImpl"/>
|
||||||
<property name="metadataAuthorityService" ref="org.dspace.content.authority.MetadataAuthorityServiceImpl"/>
|
<property name="metadataAuthorityService" ref="org.dspace.content.authority.MetadataAuthorityServiceImpl"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -10,7 +10,7 @@ package org.dspace.app.rest;
|
|||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
@@ -118,7 +118,11 @@ public class CCLicenseAddPatchOperationIT extends AbstractControllerIntegrationT
|
|||||||
.content(patchBody)
|
.content(patchBody)
|
||||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.sections", not(hasJsonPath("cclicense"))));
|
.andExpect(jsonPath("$.sections.cclicense", allOf(
|
||||||
|
hasJsonPath("$.uri", nullValue()),
|
||||||
|
hasJsonPath("$.rights",nullValue()),
|
||||||
|
hasJsonPath("$.file", nullValue())
|
||||||
|
)));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,7 @@ package org.dspace.app.rest;
|
|||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.not;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
@@ -95,7 +95,11 @@ public class CCLicenseRemovePatchOperationIT extends AbstractControllerIntegrati
|
|||||||
.content(removePatch)
|
.content(removePatch)
|
||||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.sections", not(hasJsonPath("cclicense"))));
|
.andExpect(jsonPath("$.sections.cclicense", allOf(
|
||||||
|
hasJsonPath("$.uri", nullValue()),
|
||||||
|
hasJsonPath("$.rights",nullValue()),
|
||||||
|
hasJsonPath("$.file", nullValue())
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* 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.dspace.app.rest.matcher.VocabularyMatcher.matchVocabularyEntry;
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||||
|
import org.dspace.builder.EPersonBuilder;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Integration tests for {@link EPersonAuthority}.
|
||||||
|
*
|
||||||
|
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EPersonAuthorityIT extends AbstractControllerIntegrationTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEPersonAuthorityWithFirstName() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
String firstEPersonId = createEPerson("Luca", "Giamminonni");
|
||||||
|
String secondEPersonId = createEPerson("Andrea", "Bollini");
|
||||||
|
String thirdEPersonId = createEPerson("Luca", "Bollini");
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(token).perform(get("/api/submission/vocabularies/EPersonAuthority/entries")
|
||||||
|
.param("filter", "Luca"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$._embedded.entries", containsInAnyOrder(
|
||||||
|
matchVocabularyEntry("Luca Giamminonni", "Luca Giamminonni", "vocabularyEntry", firstEPersonId),
|
||||||
|
matchVocabularyEntry("Luca Bollini", "Luca Bollini", "vocabularyEntry", thirdEPersonId))))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", Matchers.is(2)));
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/submission/vocabularies/EPersonAuthority/entries")
|
||||||
|
.param("filter", "Andrea"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$._embedded.entries", containsInAnyOrder(
|
||||||
|
matchVocabularyEntry("Andrea Bollini", "Andrea Bollini", "vocabularyEntry", secondEPersonId))))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEPersonAuthorityWithLastName() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
String firstEPersonId = createEPerson("Luca", "Giamminonni");
|
||||||
|
String secondEPersonId = createEPerson("Andrea", "Bollini");
|
||||||
|
String thirdEPersonId = createEPerson("Luca", "Bollini");
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(token).perform(get("/api/submission/vocabularies/EPersonAuthority/entries")
|
||||||
|
.param("filter", "Giamminonni"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$._embedded.entries", containsInAnyOrder(
|
||||||
|
matchVocabularyEntry("Luca Giamminonni", "Luca Giamminonni", "vocabularyEntry", firstEPersonId))))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/submission/vocabularies/EPersonAuthority/entries")
|
||||||
|
.param("filter", "Bollini"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$._embedded.entries", containsInAnyOrder(
|
||||||
|
matchVocabularyEntry("Andrea Bollini", "Andrea Bollini", "vocabularyEntry", secondEPersonId),
|
||||||
|
matchVocabularyEntry("Luca Bollini", "Luca Bollini", "vocabularyEntry", thirdEPersonId))))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", Matchers.is(2)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEPersonAuthorityWithId() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
String firstEPersonId = createEPerson("Luca", "Giamminonni");
|
||||||
|
String secondEPersonId = createEPerson("Andrea", "Bollini");
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(token).perform(get("/api/submission/vocabularies/EPersonAuthority/entries")
|
||||||
|
.param("filter", firstEPersonId))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$._embedded.entries", containsInAnyOrder(
|
||||||
|
matchVocabularyEntry("Luca Giamminonni", "Luca Giamminonni", "vocabularyEntry", firstEPersonId))))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/submission/vocabularies/EPersonAuthority/entries")
|
||||||
|
.param("filter", secondEPersonId))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$._embedded.entries", containsInAnyOrder(
|
||||||
|
matchVocabularyEntry("Andrea Bollini", "Andrea Bollini", "vocabularyEntry", secondEPersonId))))
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", Matchers.is(1)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createEPerson(String firstName, String lastName) throws SQLException {
|
||||||
|
return EPersonBuilder.createEPerson(context)
|
||||||
|
.withNameInMetadata(firstName, lastName)
|
||||||
|
.build()
|
||||||
|
.getID()
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -12,6 +12,7 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
|||||||
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
|
||||||
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataDoesNotExist;
|
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadataDoesNotExist;
|
||||||
import static org.dspace.core.Constants.WRITE;
|
import static org.dspace.core.Constants.WRITE;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.emptyOrNullString;
|
import static org.hamcrest.Matchers.emptyOrNullString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
@@ -3861,6 +3862,8 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(jsonPath("$.inArchive", Matchers.is(false)))
|
.andExpect(jsonPath("$.inArchive", Matchers.is(false)))
|
||||||
.andExpect(jsonPath("$._links.self.href",
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$._links.accessStatus.href",
|
||||||
|
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/accessStatus")))
|
||||||
.andExpect(jsonPath("$._links.bundles.href",
|
.andExpect(jsonPath("$._links.bundles.href",
|
||||||
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/bundles")))
|
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/bundles")))
|
||||||
.andExpect(jsonPath("$._links.mappedCollections.href",
|
.andExpect(jsonPath("$._links.mappedCollections.href",
|
||||||
@@ -3893,6 +3896,8 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(jsonPath("$.inArchive", Matchers.is(false)))
|
.andExpect(jsonPath("$.inArchive", Matchers.is(false)))
|
||||||
.andExpect(jsonPath("$._links.self.href",
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$._links.accessStatus.href",
|
||||||
|
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/accessStatus")))
|
||||||
.andExpect(jsonPath("$._links.bundles.href",
|
.andExpect(jsonPath("$._links.bundles.href",
|
||||||
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/bundles")))
|
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/bundles")))
|
||||||
.andExpect(jsonPath("$._links.mappedCollections.href",
|
.andExpect(jsonPath("$._links.mappedCollections.href",
|
||||||
@@ -3926,6 +3931,8 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
||||||
.andExpect(jsonPath("$._links.self.href",
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
Matchers.containsString("/api/core/items/" + item.getID().toString())))
|
||||||
|
.andExpect(jsonPath("$._links.accessStatus.href",
|
||||||
|
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/accessStatus")))
|
||||||
.andExpect(jsonPath("$._links.bundles.href",
|
.andExpect(jsonPath("$._links.bundles.href",
|
||||||
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/bundles")))
|
Matchers.containsString("/api/core/items/" + item.getID().toString() + "/bundles")))
|
||||||
.andExpect(jsonPath("$._links.mappedCollections.href",
|
.andExpect(jsonPath("$._links.mappedCollections.href",
|
||||||
@@ -4376,4 +4383,35 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(status().isUnauthorized());
|
.andExpect(status().isUnauthorized());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAccessStatusForItemBadRequestTest() throws Exception {
|
||||||
|
getClient().perform(get("/api/core/items/{uuid}/accessStatus", "1"))
|
||||||
|
.andExpect(status().isBadRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAccessStatusForItemNotFoundTest() throws Exception {
|
||||||
|
UUID fakeUUID = UUID.randomUUID();
|
||||||
|
getClient().perform(get("/api/core/items/{uuid}/accessStatus", fakeUUID))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findAccessStatusForItemTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Collection owningCollection = CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Owning Collection")
|
||||||
|
.build();
|
||||||
|
Item item = ItemBuilder.createItem(context, owningCollection)
|
||||||
|
.withTitle("Test item")
|
||||||
|
.build();
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
getClient().perform(get("/api/core/items/{uuid}/accessStatus", item.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.status", notNullValue()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -35,7 +36,6 @@ import java.util.UUID;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.solr.client.solrj.SolrQuery;
|
import org.apache.solr.client.solrj.SolrQuery;
|
||||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||||
@@ -566,13 +566,14 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.andExpect(jsonPath("$.leftwardValue", is(nullValue())))
|
.andExpect(jsonPath("$.leftwardValue", is(nullValue())))
|
||||||
.andExpect(jsonPath("$.rightwardValue", is(nullValue())));
|
.andExpect(jsonPath("$.rightwardValue", is(nullValue())));
|
||||||
|
|
||||||
JsonObject contentObj = new JsonObject();
|
Map<String, String> map = new HashMap<>();
|
||||||
contentObj.addProperty("leftwardValue", leftwardValue);
|
map.put("leftwardValue", leftwardValue);
|
||||||
|
String json = new ObjectMapper().writeValueAsString(map);
|
||||||
|
|
||||||
// Add leftwardValue
|
// Add leftwardValue
|
||||||
getClient(token).perform(put("/api/core/relationships/" + idRef)
|
getClient(token).perform(put("/api/core/relationships/" + idRef)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.content(contentObj.toString()))
|
.content(json))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// Verify leftwardValue is present and rightwardValue not
|
// Verify leftwardValue is present and rightwardValue not
|
||||||
@@ -624,14 +625,15 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.andExpect(jsonPath("$.leftwardValue", is(nullValue())))
|
.andExpect(jsonPath("$.leftwardValue", is(nullValue())))
|
||||||
.andExpect(jsonPath("$.rightwardValue", is(nullValue())));
|
.andExpect(jsonPath("$.rightwardValue", is(nullValue())));
|
||||||
|
|
||||||
JsonObject contentObj = new JsonObject();
|
Map<String, String> map = new HashMap<>();
|
||||||
contentObj.addProperty("leftwardValue", leftwardValue);
|
map.put("leftwardValue", leftwardValue);
|
||||||
contentObj.addProperty("rightwardValue", rightwardValue);
|
map.put("rightwardValue", rightwardValue);
|
||||||
|
String json = new ObjectMapper().writeValueAsString(map);
|
||||||
|
|
||||||
// Add leftwardValue and rightwardValue
|
// Add leftwardValue and rightwardValue
|
||||||
getClient(token).perform(put("/api/core/relationships/" + idRef)
|
getClient(token).perform(put("/api/core/relationships/" + idRef)
|
||||||
.contentType("application/json")
|
.contentType("application/json")
|
||||||
.content(contentObj.toString()))
|
.content(json))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// Verify leftwardValue and rightwardValue are present
|
// Verify leftwardValue and rightwardValue are present
|
||||||
|
@@ -275,7 +275,7 @@ public class ResearcherProfileRestRepositoryIT extends AbstractControllerIntegra
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateAndReturnWithPublicProfile() throws Exception {
|
public void testCreateAndReturnWithPublicProfile() throws Exception {
|
||||||
|
|
||||||
configurationService.setProperty("researcher-profile.set-new-profile-private", false);
|
configurationService.setProperty("researcher-profile.set-new-profile-visible", true);
|
||||||
String id = user.getID().toString();
|
String id = user.getID().toString();
|
||||||
|
|
||||||
String authToken = getAuthToken(user.getEmail(), password);
|
String authToken = getAuthToken(user.getEmail(), password);
|
||||||
@@ -338,6 +338,30 @@ public class ResearcherProfileRestRepositoryIT extends AbstractControllerIntegra
|
|||||||
.andExpect(jsonPath("$", matchLinks("http://localhost/api/eperson/profiles/" + id, "item", "eperson")));
|
.andExpect(jsonPath("$", matchLinks("http://localhost/api/eperson/profiles/" + id, "item", "eperson")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateAndReturnWithoutCollectionIdSet() throws Exception {
|
||||||
|
|
||||||
|
String id = user.getID().toString();
|
||||||
|
|
||||||
|
configurationService.setProperty("researcher-profile.collection.uuid", null);
|
||||||
|
|
||||||
|
String authToken = getAuthToken(user.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(authToken).perform(post("/api/eperson/profiles/")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_VALUE))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andExpect(jsonPath("$.id", is(id)))
|
||||||
|
.andExpect(jsonPath("$.visible", is(false)))
|
||||||
|
.andExpect(jsonPath("$.type", is("profile")))
|
||||||
|
.andExpect(jsonPath("$", matchLinks("http://localhost/api/eperson/profiles/" + id, "item", "eperson")));
|
||||||
|
|
||||||
|
String itemId = getItemIdByProfileId(authToken, id);
|
||||||
|
Item profileItem = itemService.find(context, UUIDUtils.fromString(itemId));
|
||||||
|
assertThat(profileItem, notNullValue());
|
||||||
|
assertThat(profileItem.getOwningCollection(), is(personCollection));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that a standard user can't call the createAndReturn endpoint to store
|
* Verify that a standard user can't call the createAndReturn endpoint to store
|
||||||
* a new researcher profile related to another user.
|
* a new researcher profile related to another user.
|
||||||
@@ -587,6 +611,11 @@ public class ResearcherProfileRestRepositoryIT extends AbstractControllerIntegra
|
|||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.visible", is(false)));
|
.andExpect(jsonPath("$.visible", is(false)));
|
||||||
|
|
||||||
|
String itemId = getItemIdByProfileId(authToken, id);
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/items/{id}", itemId))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
// change the visibility to true
|
// change the visibility to true
|
||||||
List<Operation> operations = asList(new ReplaceOperation("/visible", true));
|
List<Operation> operations = asList(new ReplaceOperation("/visible", true));
|
||||||
|
|
||||||
@@ -600,6 +629,9 @@ public class ResearcherProfileRestRepositoryIT extends AbstractControllerIntegra
|
|||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.visible", is(true)));
|
.andExpect(jsonPath("$.visible", is(true)));
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/items/{id}", itemId))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
// change the visibility to false
|
// change the visibility to false
|
||||||
operations = asList(new ReplaceOperation("/visible", false));
|
operations = asList(new ReplaceOperation("/visible", false));
|
||||||
|
|
||||||
@@ -613,6 +645,9 @@ public class ResearcherProfileRestRepositoryIT extends AbstractControllerIntegra
|
|||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.visible", is(false)));
|
.andExpect(jsonPath("$.visible", is(false)));
|
||||||
|
|
||||||
|
getClient().perform(get("/api/core/items/{id}", itemId))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -30,7 +30,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
||||||
import org.dspace.app.rest.matcher.BitstreamMatcher;
|
import org.dspace.app.rest.matcher.BitstreamMatcher;
|
||||||
@@ -277,7 +277,7 @@ public class ScriptRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
try {
|
try {
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/mock-script/processes")
|
.perform(multipart("/api/system/scripts/mock-script/processes")
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("mock-script",
|
ProcessMatcher.matchProcess("mock-script",
|
||||||
@@ -321,7 +321,7 @@ public class ScriptRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
try {
|
try {
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/mock-script/processes")
|
.perform(multipart("/api/system/scripts/mock-script/processes")
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("mock-script",
|
ProcessMatcher.matchProcess("mock-script",
|
||||||
@@ -358,7 +358,7 @@ public class ScriptRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
try {
|
try {
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/mock-script/processes")
|
.perform(multipart("/api/system/scripts/mock-script/processes")
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("mock-script",
|
ProcessMatcher.matchProcess("mock-script",
|
||||||
@@ -466,7 +466,7 @@ public class ScriptRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.perform(multipart("/api/system/scripts/mock-script/processes")
|
.perform(multipart("/api/system/scripts/mock-script/processes")
|
||||||
.file(bitstreamFile)
|
.file(bitstreamFile)
|
||||||
.characterEncoding("UTF-8")
|
.characterEncoding("UTF-8")
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("mock-script",
|
ProcessMatcher.matchProcess("mock-script",
|
||||||
|
@@ -11,6 +11,7 @@ import static org.hamcrest.Matchers.contains;
|
|||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.hasSize;
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
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.content;
|
||||||
@@ -113,20 +114,20 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
// check the first two rows
|
// check the first two rows
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(
|
.andExpect(jsonPath("$.rows[0].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author", null,
|
||||||
null, true,"Add an author", "dc.contributor.author"))))
|
null, true,"Add an author", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(
|
.andExpect(jsonPath("$.rows[1].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title", null,
|
||||||
"You must enter a main title for this item.", false,
|
"You must enter a main title for this item.", false,
|
||||||
"Enter the main title of the item.", "dc.title"))))
|
"Enter the main title of the item.", "dc.title"))))
|
||||||
// check a row with multiple fields
|
// check a row with multiple fields
|
||||||
.andExpect(jsonPath("$.rows[3].fields",
|
.andExpect(jsonPath("$.rows[3].fields",
|
||||||
contains(
|
contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue",
|
||||||
"You must enter at least the year.", false,
|
null, "You must enter at least the year.", false,
|
||||||
"Please give the date", "col-sm-4",
|
"Please give the date", "col-sm-4",
|
||||||
"dc.date.issued"),
|
"dc.date.issued"),
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher", null,
|
||||||
null, false,"Enter the name of",
|
null, false,"Enter the name of",
|
||||||
"col-sm-8","dc.publisher"))))
|
"col-sm-8","dc.publisher"))))
|
||||||
;
|
;
|
||||||
@@ -144,18 +145,18 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(
|
.andExpect(jsonPath("$.rows[0].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("name", "Author", null,
|
||||||
null, true,"Add an author", "dc.contributor.author"))))
|
null, true,"Add an author", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(
|
.andExpect(jsonPath("$.rows[1].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Title", null,
|
||||||
"You must enter a main title for this item.", false,
|
"You must enter a main title for this item.", false,
|
||||||
"Enter the main title of the item.", "dc.title"))))
|
"Enter the main title of the item.", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[3].fields",contains(
|
.andExpect(jsonPath("$.rows[3].fields",contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("date", "Date of Issue", null,
|
||||||
"You must enter at least the year.", false,
|
"You must enter at least the year.", false,
|
||||||
"Please give the date", "col-sm-4",
|
"Please give the date", "col-sm-4",
|
||||||
"dc.date.issued"),
|
"dc.date.issued"),
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Publisher", null,
|
||||||
null, false,"Enter the name of",
|
null, false,"Enter the name of",
|
||||||
"col-sm-8","dc.publisher"))));
|
"col-sm-8","dc.publisher"))));
|
||||||
}
|
}
|
||||||
@@ -220,20 +221,20 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
// dc.subject fields with in separate rows all linked to an authority with different
|
// dc.subject fields with in separate rows all linked to an authority with different
|
||||||
// presentation modes (suggestion, name-lookup, lookup)
|
// presentation modes (suggestion, name-lookup, lookup)
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(
|
.andExpect(jsonPath("$.rows[0].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Author",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("onebox", "Author", null,
|
||||||
null, true,
|
null, true,
|
||||||
"Author field that can be associated with an authority providing suggestion",
|
"Author field that can be associated with an authority providing suggestion",
|
||||||
null, "dc.contributor.author", "SolrAuthorAuthority")
|
null, "dc.contributor.author", "SolrAuthorAuthority")
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(
|
.andExpect(jsonPath("$.rows[1].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup-name", "Editor",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup-name", "Editor", null,
|
||||||
null, false,
|
null, false,
|
||||||
"Editor field that can be associated with an authority "
|
"Editor field that can be associated with an authority "
|
||||||
+ "providing the special name lookup",
|
+ "providing the special name lookup",
|
||||||
null, "dc.contributor.editor", "SolrEditorAuthority")
|
null, "dc.contributor.editor", "SolrEditorAuthority")
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(
|
.andExpect(jsonPath("$.rows[2].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup", "Subject",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("lookup", "Subject", null,
|
||||||
null, true,
|
null, true,
|
||||||
"Subject field that can be associated with an authority providing lookup",
|
"Subject field that can be associated with an authority providing lookup",
|
||||||
null, "dc.subject", "SolrSubjectAuthority")
|
null, "dc.subject", "SolrSubjectAuthority")
|
||||||
@@ -266,7 +267,7 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
// our test configuration include the dc.type field with a value pair in the 8th row
|
// our test configuration include the dc.type field with a value pair in the 8th row
|
||||||
.andExpect(jsonPath("$.rows[7].fields", contains(
|
.andExpect(jsonPath("$.rows[7].fields", contains(
|
||||||
SubmissionFormFieldMatcher.matchFormFieldDefinition("dropdown", "Type",
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("dropdown", "Type", null,
|
||||||
null, true,
|
null, true,
|
||||||
"Select the type(s) of content of the item. To select more than one value in the " +
|
"Select the type(s) of content of the item. To select more than one value in the " +
|
||||||
"list, you may have to hold down the \"CTRL\" or \"Shift\" key.",
|
"list, you may have to hold down the \"CTRL\" or \"Shift\" key.",
|
||||||
@@ -275,6 +276,35 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findFieldWithTypeBindConfig() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissionforms/traditionalpageone"))
|
||||||
|
// The status has to be 200 OK
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
// We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
// Check that the JSON root matches the expected "traditionalpageone" input forms
|
||||||
|
.andExpect(jsonPath("$.id", is("traditionalpageone")))
|
||||||
|
.andExpect(jsonPath("$.name", is("traditionalpageone")))
|
||||||
|
.andExpect(jsonPath("$.type", is("submissionform")))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
|
.startsWith(REST_SERVER_URL + "config/submissionforms/traditionalpageone")))
|
||||||
|
// check a row with type-bind 'Technical Report'
|
||||||
|
.andExpect(jsonPath("$.rows[5].fields", contains(
|
||||||
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("series", "Series/Report No.",
|
||||||
|
"Technical Report", null, true,
|
||||||
|
"Enter the series and number assigned to this item by your community.",
|
||||||
|
"dc.relation.ispartofseries"))))
|
||||||
|
// check the same row with a NON-matching type-bind 'Article' (expect false)
|
||||||
|
.andExpect(((jsonPath("$.rows[5].fields", not(contains(
|
||||||
|
SubmissionFormFieldMatcher.matchFormFieldDefinition("series", "Series/Report No.",
|
||||||
|
"Article", null, true,
|
||||||
|
"Enter the series and number assigned to this item by your community.",
|
||||||
|
"dc.relation.ispartofseries")))))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findOpenRelationshipConfig() throws Exception {
|
public void findOpenRelationshipConfig() throws Exception {
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
@@ -352,14 +382,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8" + " richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null,
|
||||||
|
"\u00C8" + " richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))))
|
"Inserisci titolo principale di questo item", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Lingua", null, false,
|
.matchFormFieldDefinition("dropdown", "Lingua", null, null, false,
|
||||||
"Selezionare la lingua del contenuto principale dell'item."
|
"Selezionare la lingua del contenuto principale dell'item."
|
||||||
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
||||||
+ " Se il contenuto non ha davvero una lingua"
|
+ " Se il contenuto non ha davvero una lingua"
|
||||||
@@ -376,14 +407,14 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Автор", "Потрібно ввести хочаб одного автора!",
|
.matchFormFieldDefinition("name", "Автор", null, "Потрібно ввести хочаб одного автора!",
|
||||||
true, "Додати автора", "dc.contributor.author"))))
|
true, "Додати автора", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Заголовок",
|
.matchFormFieldDefinition("onebox", "Заголовок", null,
|
||||||
"Заговолок файла обов'язковий !", false,
|
"Заговолок файла обов'язковий !", false,
|
||||||
"Ввести основний заголовок файла", "dc.title"))))
|
"Ввести основний заголовок файла", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Мова", null, false,
|
.matchFormFieldDefinition("dropdown", "Мова", null, null, false,
|
||||||
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
||||||
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
||||||
null, "dc.language.iso", "common_iso_languages"))));
|
null, "dc.language.iso", "common_iso_languages"))));
|
||||||
@@ -431,14 +462,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8" + " richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null,
|
||||||
|
"\u00C8" + " richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))))
|
"Inserisci titolo principale di questo item", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Lingua", null, false,
|
.matchFormFieldDefinition("dropdown", "Lingua", null, null, false,
|
||||||
"Selezionare la lingua del contenuto principale dell'item."
|
"Selezionare la lingua del contenuto principale dell'item."
|
||||||
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
||||||
+ " Se il contenuto non ha davvero una lingua"
|
+ " Se il contenuto non ha davvero una lingua"
|
||||||
@@ -455,14 +487,14 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Автор", "Потрібно ввести хочаб одного автора!",
|
.matchFormFieldDefinition("name", "Автор", null, "Потрібно ввести хочаб одного автора!",
|
||||||
true, "Додати автора", "dc.contributor.author"))))
|
true, "Додати автора", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Заголовок",
|
.matchFormFieldDefinition("onebox", "Заголовок", null,
|
||||||
"Заговолок файла обов'язковий !", false,
|
"Заговолок файла обов'язковий !", false,
|
||||||
"Ввести основний заголовок файла", "dc.title"))))
|
"Ввести основний заголовок файла", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Мова", null, false,
|
.matchFormFieldDefinition("dropdown", "Мова", null, null, false,
|
||||||
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
"Виберiть мову головного змiсту файлу, як що мови немає у списку, вибрати (Iнша)."
|
||||||
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
|
||||||
null, "dc.language.iso", "common_iso_languages"))));
|
null, "dc.language.iso", "common_iso_languages"))));
|
||||||
@@ -505,14 +537,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8" + " richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null,
|
||||||
|
"\u00C8" + " richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
"\u00C8" + " necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))))
|
"Inserisci titolo principale di questo item", "dc.title"))))
|
||||||
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[2].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("dropdown", "Lingua", null, false,
|
.matchFormFieldDefinition("dropdown", "Lingua", null, null, false,
|
||||||
"Selezionare la lingua del contenuto principale dell'item."
|
"Selezionare la lingua del contenuto principale dell'item."
|
||||||
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
+ " Se la lingua non compare nell'elenco, selezionare (Altro)."
|
||||||
+ " Se il contenuto non ha davvero una lingua"
|
+ " Se il contenuto non ha davvero una lingua"
|
||||||
@@ -547,10 +580,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8 richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null, "\u00C8 richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))));
|
"Inserisci titolo principale di questo item", "dc.title"))));
|
||||||
resetLocalesConfiguration();
|
resetLocalesConfiguration();
|
||||||
@@ -582,10 +615,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers
|
.andExpect(jsonPath("$._links.self.href", Matchers
|
||||||
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
.startsWith(REST_SERVER_URL + "config/submissionforms/languagetest")))
|
||||||
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[0].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("name", "Autore", "\u00C8 richiesto almeno un autore", true,
|
.matchFormFieldDefinition("name", "Autore", null, "\u00C8 richiesto almeno un autore", true,
|
||||||
"Aggiungi un autore", "dc.contributor.author"))))
|
"Aggiungi un autore", "dc.contributor.author"))))
|
||||||
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
.andExpect(jsonPath("$.rows[1].fields", contains(SubmissionFormFieldMatcher
|
||||||
.matchFormFieldDefinition("onebox", "Titolo",
|
.matchFormFieldDefinition("onebox", "Titolo", null,
|
||||||
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
"\u00C8 necessario inserire un titolo principale per questo item", false,
|
||||||
"Inserisci titolo principale di questo item", "dc.title"))));
|
"Inserisci titolo principale di questo item", "dc.title"))));
|
||||||
|
|
||||||
|
@@ -1935,6 +1935,141 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
/**
|
||||||
|
* Test the update of metadata for fields configured with type-bind
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void patchUpdateMetadataWithBindTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and two collections.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
|
||||||
|
.withTitle("Workspace Item 1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.grantLicense()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//disable file upload mandatory
|
||||||
|
configurationService.setProperty("webui.submit.upload.required", false);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
// Try to add isPartOfSeries (type bound to technical report) - this should not work and instead we'll get
|
||||||
|
// no JSON path for that field
|
||||||
|
List<Operation> updateSeries = new ArrayList<Operation>();
|
||||||
|
List<Map<String, String>> seriesValues = new ArrayList<>();
|
||||||
|
Map<String, String> value = new HashMap<String, String>();
|
||||||
|
value.put("value", "New Series");
|
||||||
|
seriesValues.add(value);
|
||||||
|
updateSeries.add(new AddOperation("/sections/traditionalpageone/dc.relation.ispartofseries", seriesValues));
|
||||||
|
|
||||||
|
String patchBody = getPatchContent(updateSeries);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with no series or type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, null, null))));
|
||||||
|
|
||||||
|
// Verify that the metadata isn't in the workspace item
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with no series or type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, null, null))));
|
||||||
|
|
||||||
|
// Set the type to Technical Report confirm it worked
|
||||||
|
List<Operation> updateType = new ArrayList<>();
|
||||||
|
List<Map<String, String>> typeValues = new ArrayList<>();
|
||||||
|
value = new HashMap<String, String>();
|
||||||
|
value.put("value", "Technical Report");
|
||||||
|
typeValues.add(value);
|
||||||
|
updateType.add(new AddOperation("/sections/traditionalpageone/dc.type", typeValues));
|
||||||
|
patchBody = getPatchContent(updateType);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should now match an item with the expected type and series
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Technical Report",
|
||||||
|
null))));
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Technical Report",
|
||||||
|
null))));
|
||||||
|
|
||||||
|
// Another test, this time adding the series value should be successful and we'll see the value
|
||||||
|
patchBody = getPatchContent(updateSeries);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with the expected series and type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem,
|
||||||
|
"Technical Report", "New Series"))));
|
||||||
|
|
||||||
|
// Verify that the metadata isn't in the workspace item
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should match an item with the expected series and type
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem,
|
||||||
|
"Technical Report", "New Series"))));
|
||||||
|
|
||||||
|
// One final update, to a different type, this should lose the series as we're back to a non-matching type
|
||||||
|
updateType = new ArrayList<>();
|
||||||
|
typeValues = new ArrayList<>();
|
||||||
|
value = new HashMap<String, String>();
|
||||||
|
value.put("value", "Article");
|
||||||
|
typeValues.add(value);
|
||||||
|
updateType.add(new AddOperation("/sections/traditionalpageone/dc.type", typeValues));
|
||||||
|
patchBody = getPatchContent(updateType);
|
||||||
|
|
||||||
|
getClient(authToken).perform(patch("/api/submission/workspaceitems/" + witem.getID())
|
||||||
|
.content(patchBody)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
// Check this - we should NOT match an item with the series "New Series"
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Article",
|
||||||
|
null))));
|
||||||
|
|
||||||
|
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$",
|
||||||
|
Matchers.is(WorkspaceItemMatcher.matchItemWithTypeAndSeries(witem, "Article",
|
||||||
|
null))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void patchUpdateMetadataForbiddenTest() throws Exception {
|
public void patchUpdateMetadataForbiddenTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
@@ -1,177 +0,0 @@
|
|||||||
/**
|
|
||||||
* 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.authorization;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
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.authorization.impl.ShowClaimItemFeature;
|
|
||||||
import org.dspace.app.rest.converter.ItemConverter;
|
|
||||||
import org.dspace.app.rest.model.ItemRest;
|
|
||||||
import org.dspace.app.rest.projection.Projection;
|
|
||||||
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
|
||||||
import org.dspace.app.rest.utils.Utils;
|
|
||||||
import org.dspace.builder.CollectionBuilder;
|
|
||||||
import org.dspace.builder.CommunityBuilder;
|
|
||||||
import org.dspace.builder.ItemBuilder;
|
|
||||||
import org.dspace.content.Collection;
|
|
||||||
import org.dspace.content.Item;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of Show Claim Item Authorization Feature implementation.
|
|
||||||
*
|
|
||||||
* @author Corrado Lombardi (corrado.lombardi at 4science.it)
|
|
||||||
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
|
|
||||||
*/
|
|
||||||
public class ShowClaimItemFeatureIT extends AbstractControllerIntegrationTest {
|
|
||||||
|
|
||||||
private Item collectionAProfile;
|
|
||||||
private Item collectionBProfile;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ItemConverter itemConverter;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private Utils utils;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AuthorizationFeatureService authorizationFeatureService;
|
|
||||||
|
|
||||||
private AuthorizationFeature showClaimProfileFeature;
|
|
||||||
|
|
||||||
private Collection personCollection;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
parentCommunity = CommunityBuilder.createCommunity(context).withName("Community").build();
|
|
||||||
personCollection =
|
|
||||||
CollectionBuilder.createCollection(context, parentCommunity).withEntityType("Person")
|
|
||||||
.withName("claimableA").build();
|
|
||||||
final Collection claimableCollectionB =
|
|
||||||
CollectionBuilder.createCollection(context, parentCommunity).withEntityType("Person")
|
|
||||||
.withName("claimableB").build();
|
|
||||||
|
|
||||||
collectionAProfile = ItemBuilder.createItem(context, personCollection).build();
|
|
||||||
collectionBProfile = ItemBuilder.createItem(context, claimableCollectionB).build();
|
|
||||||
|
|
||||||
context.restoreAuthSystemState();
|
|
||||||
|
|
||||||
showClaimProfileFeature = authorizationFeatureService.find(ShowClaimItemFeature.NAME);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCanClaimAProfile() throws Exception {
|
|
||||||
|
|
||||||
String token = getAuthToken(context.getCurrentUser().getEmail(), password);
|
|
||||||
getClient(token).perform(get("/api/authz/authorizations/search/object")
|
|
||||||
.param("uri", uri(collectionAProfile))
|
|
||||||
.param("eperson", context.getCurrentUser().getID().toString())
|
|
||||||
.param("feature", showClaimProfileFeature.getName()))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$._embedded").exists())
|
|
||||||
.andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1)));
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/authz/authorizations/search/object")
|
|
||||||
.param("uri", uri(collectionBProfile))
|
|
||||||
.param("eperson", context.getCurrentUser().getID().toString())
|
|
||||||
.param("feature", showClaimProfileFeature.getName()))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$._embedded").exists())
|
|
||||||
.andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1)));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNotClaimableEntity() throws Exception {
|
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
Collection publicationCollection = CollectionBuilder
|
|
||||||
.createCollection(context, parentCommunity)
|
|
||||||
.withEntityType("Publication")
|
|
||||||
.withName("notClaimable")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
Item publication = ItemBuilder.createItem(context, publicationCollection).build();
|
|
||||||
|
|
||||||
String token = getAuthToken(context.getCurrentUser().getEmail(), password);
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/authz/authorizations/search/object")
|
|
||||||
.param("uri", uri(publication))
|
|
||||||
.param("eperson", context.getCurrentUser().getID().toString())
|
|
||||||
.param("feature", showClaimProfileFeature.getName()))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$._embedded").doesNotExist())
|
|
||||||
.andExpect(jsonPath("$.page.totalElements", equalTo(0)));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testItemAlreadyInARelation() throws Exception {
|
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
Item ownedItem = ItemBuilder.createItem(context, personCollection)
|
|
||||||
.withDspaceObjectOwner("owner", "ownerAuthority").build();
|
|
||||||
context.restoreAuthSystemState();
|
|
||||||
|
|
||||||
String token = getAuthToken(context.getCurrentUser().getEmail(), password);
|
|
||||||
|
|
||||||
getClient(token).perform(get("/api/authz/authorizations/search/object")
|
|
||||||
.param("uri", uri(ownedItem))
|
|
||||||
.param("eperson", context.getCurrentUser().getID().toString())
|
|
||||||
.param("feature", showClaimProfileFeature.getName()))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$._embedded").exists())
|
|
||||||
.andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1)));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUserWithProfile() throws Exception {
|
|
||||||
|
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
|
|
||||||
ItemBuilder.createItem(context, personCollection)
|
|
||||||
.withTitle("User")
|
|
||||||
.withDspaceObjectOwner("User", context.getCurrentUser().getID().toString())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
context.restoreAuthSystemState();
|
|
||||||
|
|
||||||
getClient(getAuthToken(context.getCurrentUser().getEmail(), password))
|
|
||||||
.perform(get("/api/authz/authorizations/search/object")
|
|
||||||
.param("uri", uri(collectionAProfile))
|
|
||||||
.param("eperson", context.getCurrentUser().getID().toString())
|
|
||||||
.param("feature", showClaimProfileFeature.getName()))
|
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$._embedded").doesNotExist())
|
|
||||||
.andExpect(jsonPath("$.page.totalElements", equalTo(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String uri(Item item) {
|
|
||||||
ItemRest itemRest = itemConverter.convert(item, Projection.DEFAULT);
|
|
||||||
String itemRestURI = utils.linkToSingleResource(itemRest, "self").getHref();
|
|
||||||
return itemRestURI;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -18,7 +18,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
||||||
import org.dspace.app.rest.matcher.ProcessMatcher;
|
import org.dspace.app.rest.matcher.ProcessMatcher;
|
||||||
import org.dspace.app.rest.model.ParameterValueRest;
|
import org.dspace.app.rest.model.ParameterValueRest;
|
||||||
@@ -77,7 +77,7 @@ public class CsvExportIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/metadata-export/processes")
|
.perform(multipart("/api/system/scripts/metadata-export/processes")
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("metadata-export",
|
ProcessMatcher.matchProcess("metadata-export",
|
||||||
@@ -128,7 +128,7 @@ public class CsvExportIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/metadata-export/processes")
|
.perform(multipart("/api/system/scripts/metadata-export/processes")
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("metadata-export",
|
ProcessMatcher.matchProcess("metadata-export",
|
||||||
|
@@ -30,7 +30,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
||||||
import org.dspace.app.rest.matcher.ProcessMatcher;
|
import org.dspace.app.rest.matcher.ProcessMatcher;
|
||||||
import org.dspace.app.rest.matcher.RelationshipMatcher;
|
import org.dspace.app.rest.matcher.RelationshipMatcher;
|
||||||
@@ -285,8 +285,7 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
|
|||||||
|
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/metadata-import/processes").file(bitstreamFile)
|
.perform(multipart("/api/system/scripts/metadata-import/processes").file(bitstreamFile)
|
||||||
.param("properties",
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
new Gson().toJson(list)))
|
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andDo(result -> idRef
|
.andDo(result -> idRef
|
||||||
.set(read(result.getResponse().getContentAsString(), "$.processId")));
|
.set(read(result.getResponse().getContentAsString(), "$.processId")));
|
||||||
@@ -345,8 +344,7 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
|
|||||||
|
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart("/api/system/scripts/metadata-import/processes").file(bitstreamFile)
|
.perform(multipart("/api/system/scripts/metadata-import/processes").file(bitstreamFile)
|
||||||
.param("properties",
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
new Gson().toJson(list)))
|
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("metadata-import",
|
ProcessMatcher.matchProcess("metadata-import",
|
||||||
|
@@ -50,6 +50,7 @@ public class ItemMatcher {
|
|||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFullEmbeds() {
|
public static Matcher<? super Object> matchFullEmbeds() {
|
||||||
return matchEmbeds(
|
return matchEmbeds(
|
||||||
|
"accessStatus",
|
||||||
"bundles[]",
|
"bundles[]",
|
||||||
"mappedCollections[]",
|
"mappedCollections[]",
|
||||||
"owningCollection",
|
"owningCollection",
|
||||||
@@ -65,6 +66,7 @@ public class ItemMatcher {
|
|||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchLinks(UUID uuid) {
|
public static Matcher<? super Object> matchLinks(UUID uuid) {
|
||||||
return HalMatcher.matchLinks(REST_SERVER_URL + "core/items/" + uuid,
|
return HalMatcher.matchLinks(REST_SERVER_URL + "core/items/" + uuid,
|
||||||
|
"accessStatus",
|
||||||
"bundles",
|
"bundles",
|
||||||
"mappedCollections",
|
"mappedCollections",
|
||||||
"owningCollection",
|
"owningCollection",
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest.matcher;
|
|||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath;
|
||||||
import static org.hamcrest.Matchers.allOf;
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
@@ -28,13 +29,15 @@ public class SubmissionFormFieldMatcher {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for the
|
* Shortcut for the
|
||||||
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, boolean, String, String, String, String)}
|
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, String, boolean, String, String, String, String)}
|
||||||
* with a null style and vocabulary name
|
* with a null style and vocabulary name
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* the expected input type
|
* the expected input type
|
||||||
* @param label
|
* @param label
|
||||||
* the expected label
|
* the expected label
|
||||||
|
* @param typeBind
|
||||||
|
* the expected type-bind field(s)
|
||||||
* @param mandatoryMessage
|
* @param mandatoryMessage
|
||||||
* the expected mandatoryMessage, can be null. If not empty the fiedl is expected to be flagged as
|
* the expected mandatoryMessage, can be null. If not empty the fiedl is expected to be flagged as
|
||||||
* mandatory
|
* mandatory
|
||||||
@@ -46,21 +49,23 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* the expected metadata
|
* the expected metadata
|
||||||
* @return a Matcher for all the condition above
|
* @return a Matcher for all the condition above
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String mandatoryMessage,
|
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String typeBind,
|
||||||
boolean repeatable,
|
String mandatoryMessage, boolean repeatable,
|
||||||
String hints, String metadata) {
|
String hints, String metadata) {
|
||||||
return matchFormFieldDefinition(type, label, mandatoryMessage, repeatable, hints, null, metadata);
|
return matchFormFieldDefinition(type, label, typeBind, mandatoryMessage, repeatable, hints, null, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for the
|
* Shortcut for the
|
||||||
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, boolean, String, String, String, String)}
|
* {@link SubmissionFormFieldMatcher#matchFormFieldDefinition(String, String, String, String, boolean, String, String, String, String)}
|
||||||
* with a null controlled vocabulary
|
* with a null controlled vocabulary
|
||||||
*
|
*
|
||||||
* @param type
|
* @param type
|
||||||
* the expected input type
|
* the expected input type
|
||||||
* @param label
|
* @param label
|
||||||
* the expected label
|
* the expected label
|
||||||
|
* @param typeBind
|
||||||
|
* the expected type-bind field(s)
|
||||||
* @param mandatoryMessage
|
* @param mandatoryMessage
|
||||||
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
||||||
* mandatory
|
* mandatory
|
||||||
@@ -75,10 +80,10 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* the expected metadata
|
* the expected metadata
|
||||||
* @return a Matcher for all the condition above
|
* @return a Matcher for all the condition above
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String mandatoryMessage,
|
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String typeBind,
|
||||||
boolean repeatable,
|
String mandatoryMessage, boolean repeatable, String hints, String style, String metadata) {
|
||||||
String hints, String style, String metadata) {
|
return matchFormFieldDefinition(type, label, typeBind, mandatoryMessage, repeatable, hints, style, metadata,
|
||||||
return matchFormFieldDefinition(type, label, mandatoryMessage, repeatable, hints, style, metadata, null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,6 +93,8 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* the expected input type
|
* the expected input type
|
||||||
* @param label
|
* @param label
|
||||||
* the expected label
|
* the expected label
|
||||||
|
* @param typeBind
|
||||||
|
* the expected type-bind field(s)
|
||||||
* @param mandatoryMessage
|
* @param mandatoryMessage
|
||||||
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
* the expected mandatoryMessage, can be null. If not empty the field is expected to be flagged as
|
||||||
* mandatory
|
* mandatory
|
||||||
@@ -100,18 +107,20 @@ public class SubmissionFormFieldMatcher {
|
|||||||
* missing
|
* missing
|
||||||
* @param metadata
|
* @param metadata
|
||||||
* the expected metadata
|
* the expected metadata
|
||||||
* @param controlled vocabulary
|
* @param controlledVocabulary
|
||||||
* the expected controlled vocabulary, can be null. If null the corresponding json path is expected to be
|
* the expected controlled vocabulary, can be null. If null the corresponding json path is expected to be
|
||||||
* missing
|
* missing
|
||||||
* @return a Matcher for all the condition above
|
* @return a Matcher for all the condition above
|
||||||
*/
|
*/
|
||||||
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String mandatoryMessage,
|
public static Matcher<? super Object> matchFormFieldDefinition(String type, String label, String typeBind,
|
||||||
boolean repeatable, String hints, String style,
|
String mandatoryMessage, boolean repeatable,
|
||||||
String metadata, String controlledVocabulary) {
|
String hints, String style, String metadata,
|
||||||
|
String controlledVocabulary) {
|
||||||
return allOf(
|
return allOf(
|
||||||
// check each field definition
|
// check each field definition
|
||||||
hasJsonPath("$.input.type", is(type)),
|
hasJsonPath("$.input.type", is(type)),
|
||||||
hasJsonPath("$.label", containsString(label)),
|
hasJsonPath("$.label", containsString(label)),
|
||||||
|
typeBind != null ? hasJsonPath("$.typeBind", contains(typeBind)) : hasNoJsonPath("$.typeBind[0]"),
|
||||||
hasJsonPath("$.selectableMetadata[0].metadata", is(metadata)),
|
hasJsonPath("$.selectableMetadata[0].metadata", is(metadata)),
|
||||||
controlledVocabulary != null ? hasJsonPath("$.selectableMetadata[0].controlledVocabulary",
|
controlledVocabulary != null ? hasJsonPath("$.selectableMetadata[0].controlledVocabulary",
|
||||||
is(controlledVocabulary)) : hasNoJsonPath("$.selectableMetadata[0].controlledVocabulary"),
|
is(controlledVocabulary)) : hasNoJsonPath("$.selectableMetadata[0].controlledVocabulary"),
|
||||||
@@ -166,7 +175,7 @@ public class SubmissionFormFieldMatcher {
|
|||||||
hasJsonPath("$.selectableRelationship.filter", is(filter)),
|
hasJsonPath("$.selectableRelationship.filter", is(filter)),
|
||||||
hasJsonPath("$.selectableRelationship.searchConfiguration", is(searchConfiguration)),
|
hasJsonPath("$.selectableRelationship.searchConfiguration", is(searchConfiguration)),
|
||||||
hasJsonPath("$.selectableRelationship.nameVariants", is(String.valueOf(nameVariants))),
|
hasJsonPath("$.selectableRelationship.nameVariants", is(String.valueOf(nameVariants))),
|
||||||
matchFormFieldDefinition(type, label, mandatoryMessage, repeatable, hints, metadata));
|
matchFormFieldDefinition(type, label, null, mandatoryMessage, repeatable, hints, metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -41,4 +41,14 @@ public class VocabularyMatcher {
|
|||||||
hasJsonPath("$.type", is(type))
|
hasJsonPath("$.type", is(type))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Matcher<? super Object> matchVocabularyEntry(String display, String value, String type,
|
||||||
|
String authority) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.display", is(display)),
|
||||||
|
hasJsonPath("$.value", is(value)),
|
||||||
|
hasJsonPath("$.type", is(type)),
|
||||||
|
hasJsonPath("$.authority", is(authority))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -82,6 +82,30 @@ public class WorkspaceItemMatcher {
|
|||||||
matchLinks(witem));
|
matchLinks(witem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that the workspace item has the expected type and series values
|
||||||
|
* (used in type bind evaluation)
|
||||||
|
* @param witem the workspace item
|
||||||
|
* @param type the dc.type value eg. Technical Report
|
||||||
|
* @param series the series value eg. 11-23
|
||||||
|
* @return Matcher result
|
||||||
|
*/
|
||||||
|
public static Matcher matchItemWithTypeAndSeries(WorkspaceItem witem, String type, String series) {
|
||||||
|
return allOf(
|
||||||
|
// Check workspaceitem properties
|
||||||
|
matchProperties(witem),
|
||||||
|
// Check type appears or is null
|
||||||
|
type != null ?
|
||||||
|
hasJsonPath("$.sections.traditionalpageone['dc.type'][0].value", is(type)) :
|
||||||
|
hasNoJsonPath("$.sections.traditionalpageone['dc.type'][0].value"),
|
||||||
|
// Check series as it appears (for type bind testing)
|
||||||
|
series != null ?
|
||||||
|
hasJsonPath("$.sections.traditionalpageone['dc.relation.ispartofseries'][0].value", is(series)) :
|
||||||
|
hasNoJsonPath("$.sections.traditionalpageone['dc.relation.ispartofseries'][0].value"),
|
||||||
|
matchLinks(witem)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that the id and type are exposed
|
* Check that the id and type are exposed
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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 static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
import org.dspace.access.status.DefaultAccessStatusHelper;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the AccessStatusRestTest class
|
||||||
|
*/
|
||||||
|
public class AccessStatusRestTest {
|
||||||
|
|
||||||
|
AccessStatusRest accessStatusRest;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
accessStatusRest = new AccessStatusRest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAccessStatusIsNullBeforeStatusSet() throws Exception {
|
||||||
|
assertNull(accessStatusRest.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAccessStatusIsNotNullAfterStatusSet() throws Exception {
|
||||||
|
accessStatusRest.setStatus(DefaultAccessStatusHelper.UNKNOWN);
|
||||||
|
assertNotNull(accessStatusRest.getStatus());
|
||||||
|
}
|
||||||
|
}
|
@@ -19,7 +19,7 @@ import java.util.List;
|
|||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
import org.dspace.app.rest.converter.DSpaceRunnableParameterConverter;
|
||||||
import org.dspace.app.rest.matcher.ProcessMatcher;
|
import org.dspace.app.rest.matcher.ProcessMatcher;
|
||||||
import org.dspace.app.rest.model.ParameterValueRest;
|
import org.dspace.app.rest.model.ParameterValueRest;
|
||||||
@@ -88,7 +88,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
// Request with -t <invalidTaskOption>
|
// Request with -t <invalidTaskOption>
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
// Illegal Argument Exception
|
// Illegal Argument Exception
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
// Request with missing required -i <handle>
|
// Request with missing required -i <handle>
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
// Illegal Argument Exception
|
// Illegal Argument Exception
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
// Request with missing required -i <handle>
|
// Request with missing required -i <handle>
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
// Illegal Argument Exception
|
// Illegal Argument Exception
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
@@ -171,7 +171,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
// Request without -t <task> or -T <taskFile> (and no -q <queue>)
|
// Request without -t <task> or -T <taskFile> (and no -q <queue>)
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
// Illegal Argument Exception
|
// Illegal Argument Exception
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
@@ -193,7 +193,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
// Request with invalid -s <scope>; must be object, curation or open
|
// Request with invalid -s <scope>; must be object, curation or open
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
// Illegal Argument Exception
|
// Illegal Argument Exception
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
// Request with invalid -s <scope>; must be object, curation or open
|
// Request with invalid -s <scope>; must be object, curation or open
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
// Illegal Argument Exception
|
// Illegal Argument Exception
|
||||||
.andExpect(status().isBadRequest());
|
.andExpect(status().isBadRequest());
|
||||||
}
|
}
|
||||||
@@ -257,7 +257,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
try {
|
try {
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("curate",
|
ProcessMatcher.matchProcess("curate",
|
||||||
@@ -308,7 +308,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
try {
|
try {
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(status().isAccepted())
|
.andExpect(status().isAccepted())
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("curate",
|
ProcessMatcher.matchProcess("curate",
|
||||||
@@ -359,7 +359,7 @@ public class CurationScriptIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
getClient(token)
|
getClient(token)
|
||||||
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
.perform(multipart(CURATE_SCRIPT_ENDPOINT)
|
||||||
.param("properties", new Gson().toJson(list)))
|
.param("properties", new ObjectMapper().writeValueAsString(list)))
|
||||||
.andExpect(jsonPath("$", is(
|
.andExpect(jsonPath("$", is(
|
||||||
ProcessMatcher.matchProcess("curate",
|
ProcessMatcher.matchProcess("curate",
|
||||||
String.valueOf(admin.getID()), parameters,
|
String.valueOf(admin.getID()), parameters,
|
||||||
|
@@ -61,10 +61,6 @@
|
|||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
<exclusion>
|
|
||||||
<groupId>xml-apis</groupId>
|
|
||||||
<artifactId>xml-apis</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -127,7 +123,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>xom</groupId>
|
<groupId>xom</groupId>
|
||||||
<artifactId>xom</artifactId>
|
<artifactId>xom</artifactId>
|
||||||
<version>1.2.5</version>
|
<version>1.3.7</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
|
@@ -806,6 +806,22 @@ plugin.single.org.dspace.embargo.EmbargoSetter = org.dspace.embargo.DefaultEmbar
|
|||||||
# implementation of embargo lifter plugin - - replace with local implementation if applicable
|
# implementation of embargo lifter plugin - - replace with local implementation if applicable
|
||||||
plugin.single.org.dspace.embargo.EmbargoLifter = org.dspace.embargo.DefaultEmbargoLifter
|
plugin.single.org.dspace.embargo.EmbargoLifter = org.dspace.embargo.DefaultEmbargoLifter
|
||||||
|
|
||||||
|
# values for the forever embargo date threshold
|
||||||
|
# This threshold date is used in the default access status helper to dermine if an item is
|
||||||
|
# restricted or embargoed based on the start date of the primary (or first) file policies.
|
||||||
|
# In this case, if the policy start date is inferior to the threshold date, the status will
|
||||||
|
# be embargo, else it will be restricted.
|
||||||
|
# You might want to change this threshold based on your needs. For example: some databases
|
||||||
|
# doesn't accept a date superior to 31 december 9999.
|
||||||
|
access.status.embargo.forever.year = 10000
|
||||||
|
access.status.embargo.forever.month = 1
|
||||||
|
access.status.embargo.forever.day = 1
|
||||||
|
|
||||||
|
# implementation of access status helper plugin - replace with local implementation if applicable
|
||||||
|
# This default access status helper provides an item status based on the policies of the primary
|
||||||
|
# bitstream (or first bitstream in the original bundles if no primary file is specified).
|
||||||
|
plugin.single.org.dspace.access.status.AccessStatusHelper = org.dspace.access.status.DefaultAccessStatusHelper
|
||||||
|
|
||||||
#### Checksum Checker Settings ####
|
#### Checksum Checker Settings ####
|
||||||
# Default dispatcher in case none specified
|
# Default dispatcher in case none specified
|
||||||
plugin.single.org.dspace.checker.BitstreamDispatcher=org.dspace.checker.SimpleDispatcher
|
plugin.single.org.dspace.checker.BitstreamDispatcher=org.dspace.checker.SimpleDispatcher
|
||||||
@@ -924,6 +940,11 @@ metadata.hide.eperson.orcid.refresh-token = true
|
|||||||
# Defaults to true; If set to 'false', submitter has option to skip upload
|
# Defaults to true; If set to 'false', submitter has option to skip upload
|
||||||
#webui.submit.upload.required = true
|
#webui.submit.upload.required = true
|
||||||
|
|
||||||
|
# Which field should be used for type-bind
|
||||||
|
# Defaults to 'dc.type'; If changing this value, you must also update the related
|
||||||
|
# dspace-angular environment configuration property submission.typeBind.field
|
||||||
|
#submit.type-bind.field = dc.type
|
||||||
|
|
||||||
#### Creative Commons settings ######
|
#### Creative Commons settings ######
|
||||||
|
|
||||||
# The url to the web service API
|
# The url to the web service API
|
||||||
@@ -1514,6 +1535,11 @@ request.item.type = all
|
|||||||
# Should all Request Copy emails go to the helpdesk instead of the item submitter?
|
# Should all Request Copy emails go to the helpdesk instead of the item submitter?
|
||||||
request.item.helpdesk.override = false
|
request.item.helpdesk.override = false
|
||||||
|
|
||||||
|
#------------------------------------------------------------------#
|
||||||
|
#------------------SUBMISSION CONFIGURATION------------------------#
|
||||||
|
#------------------------------------------------------------------#
|
||||||
|
# Field to use for type binding, default dc.type
|
||||||
|
submit.type-bind.field = dc.type
|
||||||
|
|
||||||
#------------------------------------------------------------------#
|
#------------------------------------------------------------------#
|
||||||
#-------------------MODULE CONFIGURATIONS--------------------------#
|
#-------------------MODULE CONFIGURATIONS--------------------------#
|
||||||
|
@@ -1,3 +1,16 @@
|
|||||||
|
## E-mail sent to a restricted Item's author when a user requests a copy.
|
||||||
|
##
|
||||||
|
## Parameters: 0 requester's name
|
||||||
|
## 1 requester's address
|
||||||
|
## 2 name of a single bitstream, or "all"
|
||||||
|
## 3 item Handle
|
||||||
|
## 4 item title
|
||||||
|
## 5 message from requester
|
||||||
|
## 6 link back to DSpace for action
|
||||||
|
## 7 corresponding author name
|
||||||
|
## 8 corresponding author email
|
||||||
|
## 9 configuration property "dspace.name"
|
||||||
|
## 10 configuration property "mail.helpdesk"
|
||||||
#set($subject = 'Request copy of document')
|
#set($subject = 'Request copy of document')
|
||||||
|
|
||||||
Dear ${params[7]},
|
Dear ${params[7]},
|
||||||
|
@@ -1,13 +0,0 @@
|
|||||||
Subject: Request copy of document
|
|
||||||
|
|
||||||
Dear Administrator,
|
|
||||||
|
|
||||||
A user of {7}, named {0} and using the email {1}, requested a copy of the file(s) associated with the document: "{4}" ({3}).
|
|
||||||
|
|
||||||
This request came along with the following message:
|
|
||||||
|
|
||||||
"{5}"
|
|
||||||
|
|
||||||
To answer, click {6}.
|
|
||||||
|
|
||||||
PLEASE REDIRECT THIS MESSAGE TO THE AUTHOR(S).
|
|
@@ -1,26 +0,0 @@
|
|||||||
## E-mail sent with the information filled out in a suggest form.
|
|
||||||
##
|
|
||||||
## Parameters: {0} recipient name
|
|
||||||
## {1} sender name
|
|
||||||
## {2} repository name
|
|
||||||
## {3} item title
|
|
||||||
## {4} item handle URI
|
|
||||||
## {5} item local URL - may be used in lieu of {4} if not using handle server
|
|
||||||
## {6} collection name
|
|
||||||
## {7} sender message
|
|
||||||
## See org.dspace.core.Email for information on the format of this file.
|
|
||||||
##
|
|
||||||
#set($subject = 'An item of interest from DSpace')
|
|
||||||
|
|
||||||
Hello ${params[0]}:
|
|
||||||
|
|
||||||
${params[1]} requested we send you this email regarding an item available in ${params[2]}.
|
|
||||||
|
|
||||||
Title: ${params[3]}
|
|
||||||
Location: ${params[5]}
|
|
||||||
In Collection: ${params[6]}
|
|
||||||
Personal Message: ${params[7]}
|
|
||||||
|
|
||||||
The DSpace digital repository system captures, stores, indexes, preserves, and distributes digital material.
|
|
||||||
For more information, visit www.dspace.org
|
|
||||||
|
|
@@ -81,6 +81,8 @@ authority.minconfidence = ambiguous
|
|||||||
plugin.named.org.dspace.content.authority.ChoiceAuthority = \
|
plugin.named.org.dspace.content.authority.ChoiceAuthority = \
|
||||||
org.dspace.content.authority.EPersonAuthority = EPersonAuthority
|
org.dspace.content.authority.EPersonAuthority = EPersonAuthority
|
||||||
|
|
||||||
|
# Configuration settings required for Researcher Profiles
|
||||||
|
# These settings ensure "dspace.object.owner" field are indexed by Authority Control
|
||||||
choices.plugin.dspace.object.owner = EPersonAuthority
|
choices.plugin.dspace.object.owner = EPersonAuthority
|
||||||
choices.presentation.dspace.object.owner = suggest
|
choices.presentation.dspace.object.owner = suggest
|
||||||
authority.controlled.dspace.object.owner = true
|
authority.controlled.dspace.object.owner = true
|
@@ -2,14 +2,16 @@
|
|||||||
#------------------- PROFILE CONFIGURATIONS --------------------#
|
#------------------- PROFILE CONFIGURATIONS --------------------#
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
|
|
||||||
#the entity type of the researcher profile
|
# The Entity Type to use for the Researcher Profile. Defaults to "Person" as this is the recommended Entity Type to use
|
||||||
researcher-profile.entity-type = Person
|
#researcher-profile.entity-type = Person
|
||||||
|
|
||||||
# the uuid of the collection where store the researcher profiles created from scratch
|
# The UUID of the default Collection where newly created Entities will be stored. If unspecified, the first Collection which supports "entity-type" will be used.
|
||||||
researcher-profile.collection.uuid =
|
#researcher-profile.collection.uuid =
|
||||||
|
|
||||||
# if true when the profile is deleted even the related item is deleted, if false only the link between profile and item is removed
|
# Whether or not to delete the Entity (Item) when a Profile is deleted. Default value is "false" which means that when a user deletes their profile,
|
||||||
|
# the Entity remains (retaining its data and relationships). When set to "true", the Entity (and its relationships) will be deleted if a user deletes their Profile.
|
||||||
researcher-profile.hard-delete.enabled = false
|
researcher-profile.hard-delete.enabled = false
|
||||||
|
|
||||||
#true if the new profiles should be private (without anonymous read policy), false otherwise
|
# Whether a newly created profile should be visible by default. Default value is "false" which means a newly created profile is not readable to
|
||||||
researcher-profile.set-new-profile-private = true
|
# anonymous users. Setting to "true" means a newly created profile is immediately readable to anonymous users.
|
||||||
|
researcher-profile.set-new-profile-visible = false
|
@@ -38,6 +38,7 @@ rest.properties.exposed = orcid.application-client-id
|
|||||||
rest.properties.exposed = orcid.authorize-url
|
rest.properties.exposed = orcid.authorize-url
|
||||||
rest.properties.exposed = orcid.scope
|
rest.properties.exposed = orcid.scope
|
||||||
rest.properties.exposed = orcid.disconnection.allowed-users
|
rest.properties.exposed = orcid.disconnection.allowed-users
|
||||||
|
rest.properties.exposed = submit.type-bind.field
|
||||||
|
|
||||||
#---------------------------------------------------------------#
|
#---------------------------------------------------------------#
|
||||||
# These configs are used by the deprecated REST (v4-6) module #
|
# These configs are used by the deprecated REST (v4-6) module #
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
<bean id="coreServiceFactory" class="org.dspace.core.factory.CoreServiceFactoryImpl"/>
|
<bean id="coreServiceFactory" class="org.dspace.core.factory.CoreServiceFactoryImpl"/>
|
||||||
|
|
||||||
|
|
||||||
|
<bean id="accessStatusServiceFactory" class="org.dspace.access.status.factory.AccessStatusServiceFactoryImpl"/>
|
||||||
<bean id="disseminateServiceFactory" class="org.dspace.disseminate.factory.DisseminateServiceFactoryImpl"/>
|
<bean id="disseminateServiceFactory" class="org.dspace.disseminate.factory.DisseminateServiceFactoryImpl"/>
|
||||||
<bean id="embargoServiceFactory" class="org.dspace.embargo.factory.EmbargoServiceFactoryImpl"/>
|
<bean id="embargoServiceFactory" class="org.dspace.embargo.factory.EmbargoServiceFactoryImpl"/>
|
||||||
<bean id="ePersonServiceFactory" class="org.dspace.eperson.factory.EPersonServiceFactoryImpl"/>
|
<bean id="ePersonServiceFactory" class="org.dspace.eperson.factory.EPersonServiceFactoryImpl"/>
|
||||||
|
@@ -90,8 +90,9 @@
|
|||||||
|
|
||||||
<bean class="org.dspace.disseminate.CitationDocumentServiceImpl"/>
|
<bean class="org.dspace.disseminate.CitationDocumentServiceImpl"/>
|
||||||
|
|
||||||
<!-- Ensure EmbargoService is initialized properly via init() method -->
|
<!-- Ensure EmbargoService and AccessStatusService are initialized properly via init() method -->
|
||||||
<bean class="org.dspace.embargo.EmbargoServiceImpl" init-method="init"/>
|
<bean class="org.dspace.embargo.EmbargoServiceImpl" init-method="init"/>
|
||||||
|
<bean class="org.dspace.access.status.AccessStatusServiceImpl" init-method="init"/>
|
||||||
|
|
||||||
<bean class="org.dspace.eperson.AccountServiceImpl"/>
|
<bean class="org.dspace.eperson.AccountServiceImpl"/>
|
||||||
<bean class="org.dspace.eperson.EPersonServiceImpl"/>
|
<bean class="org.dspace.eperson.EPersonServiceImpl"/>
|
||||||
|
@@ -1438,7 +1438,7 @@
|
|||||||
<list>
|
<list>
|
||||||
<!--Only find items into claimable collection defined in cfg-->
|
<!--Only find items into claimable collection defined in cfg-->
|
||||||
<value>search.resourcetype:Item</value>
|
<value>search.resourcetype:Item</value>
|
||||||
<value>search.entitytype:${researcher-profile.entity-type}</value>
|
<value>search.entitytype:${researcher-profile.entity-type:Person}</value>
|
||||||
</list>
|
</list>
|
||||||
</property>
|
</property>
|
||||||
<!--Default result per page -->
|
<!--Default result per page -->
|
||||||
|
20
pom.xml
20
pom.xml
@@ -29,8 +29,9 @@
|
|||||||
|
|
||||||
<ehcache.version>3.4.0</ehcache.version>
|
<ehcache.version>3.4.0</ehcache.version>
|
||||||
<errorprone.version>2.10.0</errorprone.version>
|
<errorprone.version>2.10.0</errorprone.version>
|
||||||
<!-- NOTE: when updating jackson.version, also sync jackson-databind dependency below -->
|
<!-- NOTE: when updating jackson.version, also sync jackson-databind.version below -->
|
||||||
<jackson.version>2.12.3</jackson.version>
|
<jackson.version>2.12.6</jackson.version>
|
||||||
|
<jackson-databind.version>2.12.6.1</jackson-databind.version>
|
||||||
<javax-annotation.version>1.3.2</javax-annotation.version>
|
<javax-annotation.version>1.3.2</javax-annotation.version>
|
||||||
<jaxb-api.version>2.3.1</jaxb-api.version>
|
<jaxb-api.version>2.3.1</jaxb-api.version>
|
||||||
<jaxb-runtime.version>2.3.1</jaxb-runtime.version>
|
<jaxb-runtime.version>2.3.1</jaxb-runtime.version>
|
||||||
@@ -1542,16 +1543,13 @@
|
|||||||
<artifactId>fontbox</artifactId>
|
<artifactId>fontbox</artifactId>
|
||||||
<version>${pdfbox-version}</version>
|
<version>${pdfbox-version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<!-- Tika and Jena disagree on version of Xerces to use. Select latest -->
|
||||||
<groupId>xalan</groupId>
|
|
||||||
<artifactId>xalan</artifactId>
|
|
||||||
<version>2.7.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>xerces</groupId>
|
<groupId>xerces</groupId>
|
||||||
<artifactId>xercesImpl</artifactId>
|
<artifactId>xercesImpl</artifactId>
|
||||||
<version>2.12.2</version>
|
<version>2.12.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- SWORDv1 and SWORDv2 modules both pull in various versions of xml-apis. Select latest version -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>xml-apis</groupId>
|
<groupId>xml-apis</groupId>
|
||||||
<artifactId>xml-apis</artifactId>
|
<artifactId>xml-apis</artifactId>
|
||||||
@@ -1648,12 +1646,6 @@
|
|||||||
<version>2.1.210</version>
|
<version>2.1.210</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
<version>2.8.6</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- Google Analytics -->
|
<!-- Google Analytics -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.apis</groupId>
|
<groupId>com.google.apis</groupId>
|
||||||
@@ -1724,7 +1716,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson.version}</version>
|
<version>${jackson-databind.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
|
Reference in New Issue
Block a user