mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge remote-tracking branch 'dspace-origin/main' into issue-8140_create-citation-page-once_main
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -20,7 +20,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@@ -290,20 +289,13 @@ public class ShibAuthentication implements AuthenticationMethod {
|
||||
try {
|
||||
// User has not successfuly authenticated via shibboleth.
|
||||
if (request == null ||
|
||||
context.getCurrentUser() == null ||
|
||||
request.getSession().getAttribute("shib.authenticated") == null) {
|
||||
context.getCurrentUser() == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
// If we have already calculated the special groups then return them.
|
||||
if (request.getSession().getAttribute("shib.specialgroup") != null) {
|
||||
if (context.getSpecialGroups().size() > 0 ) {
|
||||
log.debug("Returning cached special groups.");
|
||||
List<UUID> sessionGroupIds = (List<UUID>) request.getSession().getAttribute("shib.specialgroup");
|
||||
List<Group> result = new ArrayList<>();
|
||||
for (UUID uuid : sessionGroupIds) {
|
||||
result.add(groupService.find(context, uuid));
|
||||
}
|
||||
return result;
|
||||
return context.getSpecialGroups();
|
||||
}
|
||||
|
||||
log.debug("Starting to determine special groups");
|
||||
@@ -396,16 +388,8 @@ public class ShibAuthentication implements AuthenticationMethod {
|
||||
|
||||
log.info("Added current EPerson to special groups: " + groups);
|
||||
|
||||
List<UUID> groupIds = new ArrayList<>();
|
||||
for (Group group : groups) {
|
||||
groupIds.add(group.getID());
|
||||
}
|
||||
|
||||
// Cache the special groups, so we don't have to recalculate them again
|
||||
// for this session.
|
||||
request.setAttribute("shib.specialgroup", groupIds);
|
||||
|
||||
return new ArrayList<>(groups);
|
||||
|
||||
} catch (Throwable t) {
|
||||
log.error("Unable to validate any sepcial groups this user may belong too because of an exception.", t);
|
||||
return Collections.EMPTY_LIST;
|
||||
|
@@ -243,67 +243,64 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
|
||||
|
||||
boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField);
|
||||
boolean authorityRequired = metadataAuthorityService.isAuthorityRequired(metadataField);
|
||||
List<MetadataValue> newMetadata = new ArrayList<>(values.size());
|
||||
List<MetadataValue> newMetadata = new ArrayList<>();
|
||||
// We will not verify that they are valid entries in the registry
|
||||
// until update() is called.
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
|
||||
if (authorities != null && authorities.size() >= i) {
|
||||
if (StringUtils.startsWith(authorities.get(i), Constants.VIRTUAL_AUTHORITY_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
|
||||
newMetadata.add(metadataValue);
|
||||
|
||||
metadataValue.setPlace(placeSupplier.get());
|
||||
|
||||
metadataValue.setLanguage(lang == null ? null : lang.trim());
|
||||
|
||||
// Logic to set Authority and Confidence:
|
||||
// - normalize an empty string for authority to NULL.
|
||||
// - if authority key is present, use given confidence or NOVALUE if not given
|
||||
// - otherwise, preserve confidence if meaningful value was given since it may document a failed
|
||||
// authority lookup
|
||||
// - CF_UNSET signifies no authority nor meaningful confidence.
|
||||
// - it's possible to have empty authority & CF_ACCEPTED if e.g. user deletes authority key
|
||||
if (authorityControlled) {
|
||||
if (authorities != null && authorities.get(i) != null && authorities.get(i).length() > 0) {
|
||||
metadataValue.setAuthority(authorities.get(i));
|
||||
metadataValue.setConfidence(confidences == null ? Choices.CF_NOVALUE : confidences.get(i));
|
||||
} else {
|
||||
metadataValue.setAuthority(null);
|
||||
metadataValue.setConfidence(confidences == null ? Choices.CF_UNSET : confidences.get(i));
|
||||
}
|
||||
// authority sanity check: if authority is required, was it supplied?
|
||||
// XXX FIXME? can't throw a "real" exception here without changing all the callers to expect it, so
|
||||
// use a runtime exception
|
||||
if (authorityRequired && (metadataValue.getAuthority() == null || metadataValue.getAuthority()
|
||||
.length() == 0)) {
|
||||
throw new IllegalArgumentException("The metadata field \"" + metadataField
|
||||
.toString() + "\" requires an authority key but none was provided. Value=\"" + values
|
||||
.get(i) + "\"");
|
||||
}
|
||||
}
|
||||
if (values.get(i) != null) {
|
||||
if (authorities != null && authorities.size() >= i) {
|
||||
if (StringUtils.startsWith(authorities.get(i), Constants.VIRTUAL_AUTHORITY_PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
|
||||
newMetadata.add(metadataValue);
|
||||
|
||||
metadataValue.setPlace(placeSupplier.get());
|
||||
|
||||
metadataValue.setLanguage(lang == null ? null : lang.trim());
|
||||
|
||||
// Logic to set Authority and Confidence:
|
||||
// - normalize an empty string for authority to NULL.
|
||||
// - if authority key is present, use given confidence or NOVALUE if not given
|
||||
// - otherwise, preserve confidence if meaningful value was given since it may document a failed
|
||||
// authority lookup
|
||||
// - CF_UNSET signifies no authority nor meaningful confidence.
|
||||
// - it's possible to have empty authority & CF_ACCEPTED if e.g. user deletes authority key
|
||||
if (authorityControlled) {
|
||||
if (authorities != null && authorities.get(i) != null && authorities.get(i).length() > 0) {
|
||||
metadataValue.setAuthority(authorities.get(i));
|
||||
metadataValue.setConfidence(confidences == null ? Choices.CF_NOVALUE : confidences.get(i));
|
||||
} else {
|
||||
metadataValue.setAuthority(null);
|
||||
metadataValue.setConfidence(confidences == null ? Choices.CF_UNSET : confidences.get(i));
|
||||
}
|
||||
// authority sanity check: if authority is required, was it supplied?
|
||||
// XXX FIXME? can't throw a "real" exception here without changing all the callers to expect it, so
|
||||
// use a runtime exception
|
||||
if (authorityRequired && (metadataValue.getAuthority() == null || metadataValue.getAuthority()
|
||||
.length() == 0)) {
|
||||
throw new IllegalArgumentException("The metadata field \"" + metadataField
|
||||
.toString() + "\" requires an authority key but none was provided. Value=\"" + values
|
||||
.get(i) + "\"");
|
||||
}
|
||||
}
|
||||
// remove control unicode char
|
||||
String temp = values.get(i).trim();
|
||||
char[] dcvalue = temp.toCharArray();
|
||||
for (int charPos = 0; charPos < dcvalue.length; charPos++) {
|
||||
if (Character.isISOControl(dcvalue[charPos]) &&
|
||||
!String.valueOf(dcvalue[charPos]).equals("\u0009") &&
|
||||
!String.valueOf(dcvalue[charPos]).equals("\n") &&
|
||||
!String.valueOf(dcvalue[charPos]).equals("\r")) {
|
||||
!String.valueOf(dcvalue[charPos]).equals("\u0009") &&
|
||||
!String.valueOf(dcvalue[charPos]).equals("\n") &&
|
||||
!String.valueOf(dcvalue[charPos]).equals("\r")) {
|
||||
dcvalue[charPos] = ' ';
|
||||
}
|
||||
}
|
||||
metadataValue.setValue(String.valueOf(dcvalue));
|
||||
} else {
|
||||
metadataValue.setValue(null);
|
||||
}
|
||||
//An update here isn't needed, this is persited upon the merge of the owning object
|
||||
//An update here isn't needed, this is persited upon the merge of the owning object
|
||||
// metadataValueService.update(context, metadataValue);
|
||||
dso.addDetails(metadataField.toString());
|
||||
dso.addDetails(metadataField.toString());
|
||||
}
|
||||
}
|
||||
setMetadataModified(dso);
|
||||
return newMetadata;
|
||||
|
@@ -911,6 +911,12 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl<Item> implements It
|
||||
@Override
|
||||
public void move(Context context, Item item, Collection from, Collection to)
|
||||
throws SQLException, AuthorizeException, IOException {
|
||||
|
||||
// If the two collections are the same, do nothing.
|
||||
if (from.equals(to)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the normal move method, and default to not inherit permissions
|
||||
this.move(context, item, from, to, false);
|
||||
}
|
||||
|
@@ -201,7 +201,7 @@ public class Group extends DSpaceObject implements DSpaceObjectLegacySupport {
|
||||
void setName(String name) throws SQLException {
|
||||
if (!StringUtils.equals(this.name, name) && !isPermanent()) {
|
||||
this.name = name;
|
||||
groupsChanged = true;
|
||||
setMetadataModified();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -34,8 +34,6 @@ public class DOI
|
||||
implements Identifier, ReloadableEntity<Integer> {
|
||||
public static final String SCHEME = "doi:";
|
||||
|
||||
public static final String RESOLVER = "http://dx.doi.org";
|
||||
|
||||
@Id
|
||||
@Column(name = "doi_id")
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "doi_seq")
|
||||
|
@@ -1028,7 +1028,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider {
|
||||
Item item = (Item) dso;
|
||||
|
||||
List<MetadataValue> metadata = itemService.getMetadata(item, MD_SCHEMA, DOI_ELEMENT, DOI_QUALIFIER, null);
|
||||
String leftPart = DOI.RESOLVER + SLASH + getPrefix() + SLASH + getNamespaceSeparator();
|
||||
String leftPart = doiService.getResolver() + SLASH + getPrefix() + SLASH + getNamespaceSeparator();
|
||||
for (MetadataValue id : metadata) {
|
||||
if (id.getValue().startsWith(leftPart)) {
|
||||
return doiService.DOIFromExternalFormat(id.getValue());
|
||||
|
@@ -17,11 +17,13 @@ import org.dspace.core.Context;
|
||||
import org.dspace.identifier.dao.DOIDAO;
|
||||
import org.dspace.identifier.doi.DOIIdentifierException;
|
||||
import org.dspace.identifier.service.DOIService;
|
||||
import org.dspace.services.ConfigurationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* Service implementation for the DOI object.
|
||||
* This class is responsible for all business logic calls for the DOI object and is autowired by spring.
|
||||
* Service implementation for the {@link DOI} object.
|
||||
* This class is responsible for all business logic calls for the DOI object
|
||||
* and is autowired by Spring.
|
||||
* This class should never be accessed directly.
|
||||
*
|
||||
* @author kevinvandevelde at atmire.com
|
||||
@@ -31,6 +33,16 @@ public class DOIServiceImpl implements DOIService {
|
||||
@Autowired(required = true)
|
||||
protected DOIDAO doiDAO;
|
||||
|
||||
@Autowired(required = true)
|
||||
protected ConfigurationService configurationService;
|
||||
|
||||
private static final Pattern DOI_URL_PATTERN
|
||||
= Pattern.compile("http(s)?://([a-z0-9-.]+)?doi.org(?<path>/.*)",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
private static final String DOI_URL_PATTERN_PATH_GROUP = "path";
|
||||
|
||||
private static final String RESOLVER_DEFAULT = "https://doi.org";
|
||||
|
||||
protected DOIServiceImpl() {
|
||||
|
||||
}
|
||||
@@ -66,25 +78,46 @@ public class DOIServiceImpl implements DOIService {
|
||||
if (null == identifier) {
|
||||
throw new IllegalArgumentException("Identifier is null.", new NullPointerException());
|
||||
}
|
||||
|
||||
if (identifier.isEmpty()) {
|
||||
throw new IllegalArgumentException("Cannot format an empty identifier.");
|
||||
}
|
||||
if (identifier.startsWith(DOI.SCHEME)) {
|
||||
return DOI.RESOLVER + "/" + identifier.substring(DOI.SCHEME.length());
|
||||
|
||||
String resolver = getResolver();
|
||||
|
||||
if (identifier.startsWith(DOI.SCHEME)) { // doi:something
|
||||
StringBuilder result = new StringBuilder(resolver);
|
||||
if (!resolver.endsWith("/")) {
|
||||
result.append('/');
|
||||
}
|
||||
result.append(identifier.substring(DOI.SCHEME.length()));
|
||||
return result.toString();
|
||||
}
|
||||
if (identifier.startsWith("10.") && identifier.contains("/")) {
|
||||
return DOI.RESOLVER + "/" + identifier;
|
||||
|
||||
if (identifier.startsWith("10.") && identifier.contains("/")) { // 10.something
|
||||
StringBuilder result = new StringBuilder(resolver);
|
||||
if (!resolver.endsWith("/")) {
|
||||
result.append('/');
|
||||
}
|
||||
result.append(identifier);
|
||||
return result.toString();
|
||||
}
|
||||
if (identifier.startsWith(DOI.RESOLVER + "/10.")) {
|
||||
|
||||
if (identifier.startsWith(resolver + "/10.")) { // https://doi.org/10.something
|
||||
return identifier;
|
||||
}
|
||||
|
||||
Matcher matcher = DOI_URL_PATTERN.matcher(identifier);
|
||||
if (matcher.matches()) { // various old URL forms
|
||||
return resolver + matcher.group(DOI_URL_PATTERN_PATH_GROUP);
|
||||
}
|
||||
|
||||
throw new IdentifierException(identifier + "does not seem to be a DOI.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String DOIFromExternalFormat(String identifier) throws DOIIdentifierException {
|
||||
Pattern pattern = Pattern.compile("^" + DOI.RESOLVER + "/+(10\\..*)$");
|
||||
Pattern pattern = Pattern.compile("^" + getResolver() + "/+(10\\..*)$");
|
||||
Matcher matcher = pattern.matcher(identifier);
|
||||
if (matcher.find()) {
|
||||
return DOI.SCHEME + matcher.group(1);
|
||||
@@ -99,18 +132,29 @@ public class DOIServiceImpl implements DOIService {
|
||||
if (null == identifier) {
|
||||
throw new IllegalArgumentException("Identifier is null.", new NullPointerException());
|
||||
}
|
||||
if (identifier.startsWith(DOI.SCHEME)) {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
if (identifier.isEmpty()) {
|
||||
throw new IllegalArgumentException("Cannot format an empty identifier.");
|
||||
}
|
||||
if (identifier.startsWith("10.") && identifier.contains("/")) {
|
||||
|
||||
if (identifier.startsWith(DOI.SCHEME)) { // doi:something
|
||||
return identifier;
|
||||
}
|
||||
|
||||
if (identifier.startsWith("10.") && identifier.contains("/")) { // 10.something
|
||||
return DOI.SCHEME + identifier;
|
||||
}
|
||||
if (identifier.startsWith(DOI.RESOLVER + "/10.")) {
|
||||
return DOI.SCHEME + identifier.substring(18);
|
||||
|
||||
String resolver = getResolver();
|
||||
if (identifier.startsWith(resolver + "/10.")) { //https://doi.org/10.something
|
||||
return DOI.SCHEME + identifier.substring(resolver.length());
|
||||
}
|
||||
|
||||
Matcher matcher = DOI_URL_PATTERN.matcher(identifier);
|
||||
if (matcher.matches()) { // various old URL forms
|
||||
return DOI.SCHEME + matcher.group(DOI_URL_PATTERN_PATH_GROUP).substring(1);
|
||||
}
|
||||
|
||||
throw new DOIIdentifierException(identifier + "does not seem to be a DOI.",
|
||||
DOIIdentifierException.UNRECOGNIZED);
|
||||
}
|
||||
@@ -126,4 +170,14 @@ public class DOIServiceImpl implements DOIService {
|
||||
throws SQLException {
|
||||
return doiDAO.findSimilarNotInState(context, doiPattern, statuses, dsoIsNotNull);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResolver() {
|
||||
String resolver = configurationService.getProperty("identifier.doi.resolver",
|
||||
RESOLVER_DEFAULT);
|
||||
if (resolver.endsWith("/")) {
|
||||
resolver = resolver.substring(0, resolver.length() - 1);
|
||||
}
|
||||
return resolver;
|
||||
}
|
||||
}
|
||||
|
@@ -17,26 +17,65 @@ import org.dspace.identifier.IdentifierException;
|
||||
import org.dspace.identifier.doi.DOIIdentifierException;
|
||||
|
||||
/**
|
||||
* Service interface class for the DOI object.
|
||||
* The implementation of this class is responsible for all business logic calls for the DOI object and is autowired
|
||||
* by spring
|
||||
* Service interface class for the {@link DOI} object.
|
||||
* The implementation of this class is responsible for all business logic calls
|
||||
* for the {@link DOI} object and is autowired by Spring.
|
||||
*
|
||||
* @author kevinvandevelde at atmire.com
|
||||
*/
|
||||
public interface DOIService {
|
||||
|
||||
/**
|
||||
* Update a DOI in storage.
|
||||
*
|
||||
* @param context current DSpace session.
|
||||
* @param doi the DOI to persist.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
public void update(Context context, DOI doi) throws SQLException;
|
||||
|
||||
/**
|
||||
* Create a new DOI in storage.
|
||||
*
|
||||
* @param context current DSpace session.
|
||||
* @return the new DOI.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
public DOI create(Context context) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find a specific DOI in storage.
|
||||
*
|
||||
* @param context current DSpace session.
|
||||
* @param doi string representation of the DOI.
|
||||
* @return the DOI object found.
|
||||
* @throws SQLException passed through, can mean none found.
|
||||
*/
|
||||
public DOI findByDoi(Context context, String doi) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find the DOI assigned to a given DSpace Object.
|
||||
*
|
||||
* @param context current DSpace session.
|
||||
* @param dso The DSpace Object.
|
||||
* @return the DSO's DOI.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
public DOI findDOIByDSpaceObject(Context context, DSpaceObject dso) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find the DOI assigned to a given DSpace Object, unless it has one of a
|
||||
* given set of statuses.
|
||||
*
|
||||
* @param context current DSpace context.
|
||||
* @param dso the DSpace Object.
|
||||
* @param statusToExclude uninteresting statuses.
|
||||
* @return the DSO's DOI.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
public DOI findDOIByDSpaceObject(Context context, DSpaceObject dso, List<Integer> statusToExclude)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* This method helps to convert a DOI into a URL. It takes DOIs in one of
|
||||
* the following formats and returns it as URL (f.e.
|
||||
@@ -49,12 +88,18 @@ public interface DOIService {
|
||||
*
|
||||
* @param identifier A DOI that should be returned in external form.
|
||||
* @return A String containing a URL to the official DOI resolver.
|
||||
* @throws IllegalArgumentException If identifier is null or an empty String.
|
||||
* @throws org.dspace.identifier.IdentifierException If identifier could not be recognized as valid DOI.
|
||||
* @throws IllegalArgumentException If identifier is null or an empty String.
|
||||
* @throws IdentifierException If identifier could not be recognized as valid DOI.
|
||||
*/
|
||||
public String DOIToExternalForm(String identifier)
|
||||
throws IdentifierException;
|
||||
|
||||
/**
|
||||
* Convert an HTTP DOI URL (https://doi.org/10.something) to a "doi:" URI.
|
||||
* @param identifier HTTP URL
|
||||
* @return DOI URI
|
||||
* @throws DOIIdentifierException if {@link identifier} is not recognizable.
|
||||
*/
|
||||
public String DOIFromExternalFormat(String identifier)
|
||||
throws DOIIdentifierException;
|
||||
|
||||
@@ -64,16 +109,24 @@ public interface DOIService {
|
||||
* @param identifier Identifier to format, following format are accepted:
|
||||
* f.e. 10.123/456, doi:10.123/456, http://dx.doi.org/10.123/456.
|
||||
* @return Given Identifier with DOI-Scheme, f.e. doi:10.123/456.
|
||||
* @throws IllegalArgumentException If identifier is empty or null.
|
||||
* @throws org.dspace.identifier.doi.DOIIdentifierException If DOI could not be recognized.
|
||||
* @throws IllegalArgumentException If identifier is empty or null.
|
||||
* @throws DOIIdentifierException If DOI could not be recognized.
|
||||
*/
|
||||
public String formatIdentifier(String identifier)
|
||||
throws DOIIdentifierException;
|
||||
|
||||
/**
|
||||
* Find all DOIs that have one of a given set of statuses.
|
||||
* @param context current DSpace session.
|
||||
* @param statuses desired statuses.
|
||||
* @return all DOIs having any of the given statuses.
|
||||
* @throws SQLException passed through.
|
||||
*/
|
||||
public List<DOI> getDOIsByStatus(Context context, List<Integer> statuses) throws SQLException;
|
||||
|
||||
/**
|
||||
* Find all DOIs that are similar to the specified pattern ant not in the specified states.
|
||||
* Find all DOIs that are similar to the specified pattern and not in the
|
||||
* specified states.
|
||||
*
|
||||
* @param context DSpace context
|
||||
* @param doiPattern The pattern, e.g. "10.5072/123.%"
|
||||
@@ -85,4 +138,11 @@ public interface DOIService {
|
||||
public List<DOI> getSimilarDOIsNotInState(Context context, String doiPattern, List<Integer> statuses,
|
||||
boolean dsoIsNotNull)
|
||||
throws SQLException;
|
||||
|
||||
/**
|
||||
* Get the URL stem of the DOI resolver, e.g. "https://doi.org/".
|
||||
*
|
||||
* @return URL to the DOI resolver.
|
||||
*/
|
||||
public String getResolver();
|
||||
}
|
||||
|
@@ -286,51 +286,54 @@ public class RDFConsumer implements Consumer {
|
||||
@Override
|
||||
public void end(Context ctx) throws Exception {
|
||||
log.debug("Started processing of queued events.");
|
||||
// create a new context, to be sure to work as anonymous user
|
||||
// we don't want to store private data in a triplestore with public
|
||||
// SPARQL endpoint.
|
||||
ctx = new Context(Context.Mode.READ_ONLY);
|
||||
if (toDelete == null) {
|
||||
log.debug("Deletion queue does not exists, creating empty queue.");
|
||||
this.toDelete = new LinkedList<>();
|
||||
}
|
||||
if (toConvert != null) {
|
||||
log.debug("Starting conversion of DSpaceObjects.");
|
||||
// store the context mode, set context read only for performance reasons, and restore the old mode
|
||||
Context.Mode oldMode = ctx.getCurrentMode();
|
||||
try {
|
||||
ctx.setMode(Context.Mode.READ_ONLY);
|
||||
if (toDelete == null) {
|
||||
log.debug("Deletion queue does not exists, creating empty queue.");
|
||||
this.toDelete = new LinkedList<>();
|
||||
}
|
||||
if (toConvert != null) {
|
||||
log.debug("Starting conversion of DSpaceObjects.");
|
||||
while (true) {
|
||||
DSOIdentifier id;
|
||||
try {
|
||||
id = toConvert.removeFirst();
|
||||
} catch (NoSuchElementException ex) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (toDelete.contains(id)) {
|
||||
log.debug("Skipping " + Constants.typeText[id.type] + " "
|
||||
+ id.id.toString() + " as it is marked for "
|
||||
+ "deletion as well.");
|
||||
continue;
|
||||
}
|
||||
log.debug("Converting " + Constants.typeText[id.type] + " "
|
||||
+ id.id.toString() + ".");
|
||||
convert(ctx, id);
|
||||
}
|
||||
log.debug("Conversion ended.");
|
||||
}
|
||||
log.debug("Starting to delete data from the triple store...");
|
||||
while (true) {
|
||||
DSOIdentifier id;
|
||||
try {
|
||||
id = toConvert.removeFirst();
|
||||
id = toDelete.removeFirst();
|
||||
} catch (NoSuchElementException ex) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (toDelete.contains(id)) {
|
||||
log.debug("Skipping " + Constants.typeText[id.type] + " "
|
||||
+ id.id.toString() + " as it is marked for "
|
||||
+ "deletion as well.");
|
||||
continue;
|
||||
}
|
||||
log.debug("Converting " + Constants.typeText[id.type] + " "
|
||||
log.debug("Going to delete data from " +
|
||||
Constants.typeText[id.type] + " "
|
||||
+ id.id.toString() + ".");
|
||||
convert(ctx, id);
|
||||
delete(ctx, id);
|
||||
}
|
||||
log.debug("Conversion ended.");
|
||||
} finally {
|
||||
// restore context mode
|
||||
ctx.setMode(oldMode);
|
||||
}
|
||||
log.debug("Starting to delete data from the triple store...");
|
||||
while (true) {
|
||||
DSOIdentifier id;
|
||||
try {
|
||||
id = toDelete.removeFirst();
|
||||
} catch (NoSuchElementException ex) {
|
||||
break;
|
||||
}
|
||||
|
||||
log.debug("Going to delete data from " +
|
||||
Constants.typeText[id.type] + " "
|
||||
+ id.id.toString() + ".");
|
||||
delete(ctx, id);
|
||||
}
|
||||
ctx.abort();
|
||||
log.debug("Deletion finished.");
|
||||
}
|
||||
|
||||
|
@@ -206,6 +206,7 @@ public class BitstreamBuilder extends AbstractDSpaceObjectBuilder<Bitstream> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
bitstream = c.reloadEntity(bitstream);
|
||||
|
@@ -34,6 +34,7 @@ public class BitstreamFormatBuilder extends AbstractCRUDBuilder<BitstreamFormat>
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
bitstreamFormat = c.reloadEntity(bitstreamFormat);
|
||||
|
@@ -55,6 +55,7 @@ public class BundleBuilder extends AbstractDSpaceObjectBuilder<Bundle> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
bundle = c.reloadEntity(bundle);
|
||||
|
@@ -124,6 +124,7 @@ public class ClaimedTaskBuilder extends AbstractBuilder<ClaimedTask, ClaimedTask
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
workspaceItem = c.reloadEntity(workspaceItem);
|
||||
|
@@ -253,6 +253,7 @@ public class CollectionBuilder extends AbstractDSpaceObjectBuilder<Collection> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
collection = c.reloadEntity(collection);
|
||||
|
@@ -116,6 +116,7 @@ public class CommunityBuilder extends AbstractDSpaceObjectBuilder<Community> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
community = c.reloadEntity(community);
|
||||
|
@@ -32,6 +32,7 @@ public class EPersonBuilder extends AbstractDSpaceObjectBuilder<EPerson> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
ePerson = c.reloadEntity(ePerson);
|
||||
|
@@ -36,6 +36,7 @@ public class EntityTypeBuilder extends AbstractBuilder<EntityType, EntityTypeSer
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
entityType = c.reloadEntity(entityType);
|
||||
|
@@ -35,6 +35,7 @@ public class GroupBuilder extends AbstractDSpaceObjectBuilder<Group> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
group = c.reloadEntity(group);
|
||||
|
@@ -209,6 +209,7 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder<Item> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
item = c.reloadEntity(item);
|
||||
|
@@ -38,6 +38,7 @@ public class MetadataFieldBuilder extends AbstractBuilder<MetadataField, Metadat
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
metadataField = c.reloadEntity(metadataField);
|
||||
|
@@ -37,6 +37,7 @@ public class MetadataSchemaBuilder extends AbstractBuilder<MetadataSchema, Metad
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
metadataSchema = c.reloadEntity(metadataSchema);
|
||||
|
@@ -104,6 +104,7 @@ public class PoolTaskBuilder extends AbstractBuilder<PoolTask, PoolTaskService>
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
workspaceItem = c.reloadEntity(workspaceItem);
|
||||
|
@@ -60,6 +60,7 @@ public class ProcessBuilder extends AbstractBuilder<Process, ProcessService> {
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
process = c.reloadEntity(process);
|
||||
|
@@ -39,6 +39,7 @@ public class RelationshipBuilder extends AbstractBuilder<Relationship, Relations
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
relationship = c.reloadEntity(relationship);
|
||||
|
@@ -37,6 +37,7 @@ public class RelationshipTypeBuilder extends AbstractBuilder<RelationshipType, R
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
relationshipType = c.reloadEntity(relationshipType);
|
||||
|
@@ -117,6 +117,7 @@ public class RequestItemBuilder
|
||||
throws Exception {
|
||||
LOG.debug("cleanup()");
|
||||
try ( Context ctx = new Context(); ) {
|
||||
ctx.setDispatcher("noindex");
|
||||
ctx.turnOffAuthorisationSystem();
|
||||
requestItem = ctx.reloadEntity(requestItem);
|
||||
if (null != requestItem) {
|
||||
|
@@ -41,6 +41,7 @@ public class ResourcePolicyBuilder extends AbstractBuilder<ResourcePolicy, Resou
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
resourcePolicy = c.reloadEntity(resourcePolicy);
|
||||
@@ -81,6 +82,7 @@ public class ResourcePolicyBuilder extends AbstractBuilder<ResourcePolicy, Resou
|
||||
public void delete(ResourcePolicy rp) throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.turnOffAuthorisationSystem();
|
||||
c.setDispatcher("noindex");
|
||||
ResourcePolicy attachedDso = c.reloadEntity(rp);
|
||||
if (attachedDso != null) {
|
||||
getService().delete(c, attachedDso);
|
||||
|
@@ -85,6 +85,7 @@ public class VersionBuilder extends AbstractBuilder<Version, VersioningService>
|
||||
public void delete(Version version) throws Exception {
|
||||
try (Context context = new Context()) {
|
||||
context.turnOffAuthorisationSystem();
|
||||
context.setDispatcher("noindex");
|
||||
Version attachedTab = context.reloadEntity(version);
|
||||
if (attachedTab != null) {
|
||||
getService().delete(context, attachedTab);
|
||||
|
@@ -116,6 +116,7 @@ public class WorkflowItemBuilder extends AbstractBuilder<XmlWorkflowItem, XmlWor
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
workspaceItem = c.reloadEntity(workspaceItem);
|
||||
|
@@ -106,6 +106,7 @@ public class WorkspaceItemBuilder extends AbstractBuilder<WorkspaceItem, Workspa
|
||||
@Override
|
||||
public void cleanup() throws Exception {
|
||||
try (Context c = new Context()) {
|
||||
c.setDispatcher("noindex");
|
||||
c.turnOffAuthorisationSystem();
|
||||
// Ensure object and any related objects are reloaded before checking to see what needs cleanup
|
||||
workspaceItem = c.reloadEntity(workspaceItem);
|
||||
|
@@ -19,6 +19,8 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
@@ -41,6 +43,7 @@ import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.content.factory.ContentServiceFactory;
|
||||
import org.dspace.content.service.BitstreamFormatService;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.content.service.MetadataFieldService;
|
||||
import org.dspace.content.service.MetadataSchemaService;
|
||||
import org.dspace.core.Constants;
|
||||
@@ -1410,6 +1413,27 @@ public class ItemTest extends AbstractDSpaceObjectTest {
|
||||
assertThat("testMove 1", it.getOwningCollection(), equalTo(to));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of move method, of class Item, where both Collections are the same.
|
||||
*/
|
||||
@Test
|
||||
public void testMoveSameCollection() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
while (it.getCollections().size() > 1) {
|
||||
it.removeCollection(it.getCollections().get(0));
|
||||
}
|
||||
|
||||
Collection collection = it.getCollections().get(0);
|
||||
it.setOwningCollection(collection);
|
||||
ItemService itemServiceSpy = spy(itemService);
|
||||
|
||||
itemService.move(context, it, collection, collection);
|
||||
context.restoreAuthSystemState();
|
||||
assertThat("testMoveSameCollection 0", it.getOwningCollection(), notNullValue());
|
||||
assertThat("testMoveSameCollection 1", it.getOwningCollection(), equalTo(collection));
|
||||
verify(itemServiceSpy, times(0)).delete(context, it);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of hasUploadedFiles method, of class Item.
|
||||
*/
|
||||
|
@@ -191,7 +191,7 @@ public class DOIIdentifierProviderTest
|
||||
List<String> remainder = new ArrayList<>();
|
||||
|
||||
for (MetadataValue id : metadata) {
|
||||
if (!id.getValue().startsWith(DOI.RESOLVER)) {
|
||||
if (!id.getValue().startsWith(doiService.getResolver())) {
|
||||
remainder.add(id.getValue());
|
||||
}
|
||||
}
|
||||
@@ -278,11 +278,11 @@ public class DOIIdentifierProviderTest
|
||||
PREFIX + "/" + NAMESPACE_SEPARATOR + "lkjljasd1234",
|
||||
DOI.SCHEME + "10.5072/123abc-lkj/kljl",
|
||||
"http://dx.doi.org/10.5072/123abc-lkj/kljl",
|
||||
DOI.RESOLVER + "/10.5072/123abc-lkj/kljl"
|
||||
doiService.getResolver() + "/10.5072/123abc-lkj/kljl"
|
||||
};
|
||||
|
||||
for (String doi : validDOIs) {
|
||||
assertTrue("DOI should be supported", provider.supports(doi));
|
||||
assertTrue("DOI " + doi + " should be supported", provider.supports(doi));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-rest</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<name>DSpace (Deprecated) REST Webapp</name>
|
||||
<description>DSpace RESTful Web Services API. NOTE: this REST API is DEPRECATED.
|
||||
Please consider using the REST API in the dspace-server-webapp instead!</description>
|
||||
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -43,7 +43,6 @@ public class ResourcePolicyEndDateAddOperation<R> extends PatchOperation<R> {
|
||||
checkOperationValue(operation.getValue());
|
||||
if (this.supports(resource, operation)) {
|
||||
ResourcePolicy resourcePolicy = (ResourcePolicy) resource;
|
||||
resourcePolicyUtils.checkResourcePolicyForExistingEndDateValue(resourcePolicy, operation);
|
||||
resourcePolicyUtils.checkResourcePolicyForConsistentEndDateValue(resourcePolicy, operation);
|
||||
this.add(resourcePolicy, operation);
|
||||
return resource;
|
||||
|
@@ -1353,6 +1353,65 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
|
||||
hasJsonPath("$.startDate", is(formatDate.format(newDate))))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchAddEndDataTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
EPerson eperson1 = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("eperson1@mail.com")
|
||||
.withPassword("qwerty01")
|
||||
.build();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context).build();
|
||||
|
||||
Collection collection = CollectionBuilder.createCollection(context, community)
|
||||
.withAdminGroup(eperson1)
|
||||
.build();
|
||||
|
||||
Item publicItem1 = ItemBuilder.createItem(context, collection)
|
||||
.withTitle("Public item")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.READ)
|
||||
.withDspaceObject(publicItem1)
|
||||
.withGroup(
|
||||
EPersonServiceFactory.getInstance().getGroupService()
|
||||
.findByName(context,
|
||||
Group.ANONYMOUS))
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
Calendar newCalendar = Calendar.getInstance();
|
||||
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date newDate = new Date();
|
||||
|
||||
List<Operation> ops = new ArrayList<Operation>();
|
||||
AddOperation addOperation = new AddOperation("/endDate", formatDate.format(newDate));
|
||||
ops.add(addOperation);
|
||||
String patchBody = getPatchContent(ops);
|
||||
|
||||
String authToken = getAuthToken(eperson1.getEmail(), "qwerty01");
|
||||
getClient(authToken).perform(patch("/api/authz/resourcepolicies/" + resourcePolicy.getID())
|
||||
.content(patchBody)
|
||||
.contentType(MediaType.APPLICATION_JSON_PATCH_JSON))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.name", is(resourcePolicy.getRpName())),
|
||||
hasJsonPath("$.description", is(resourcePolicy.getRpDescription())),
|
||||
hasJsonPath("$.action", is(Constants.actionText[resourcePolicy.getAction()])),
|
||||
hasJsonPath("$.startDate", is(resourcePolicy.getStartDate())),
|
||||
hasJsonPath("$.endDate", is(formatDate.format(newDate))))));
|
||||
|
||||
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.action", is(Constants.actionText[resourcePolicy.getAction()])),
|
||||
hasJsonPath("$.endDate", is(formatDate.format(newDate))))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchRemoveStartDataTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
@@ -43,6 +43,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.jayway.jsonpath.matchers.JsonPathMatchers;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.dspace.app.rest.matcher.CollectionMatcher;
|
||||
@@ -2515,6 +2516,76 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
|
||||
;
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* Test the addition of metadata of a null value
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void patchAddMetadataNullValueTest() 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)
|
||||
.withIssueDate("2017-10-17")
|
||||
.withSubject("ExtraEntry")
|
||||
.build();
|
||||
|
||||
//disable file upload mandatory
|
||||
configurationService.setProperty("webui.submit.upload.required", false);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
// try to add the title
|
||||
List<Operation> operations = new ArrayList<Operation>();
|
||||
// create a list of values to use in add operation
|
||||
List<Map<String, String>> titelValues = new ArrayList<Map<String, String>>();
|
||||
List<Map<String, String>> uriValues = new ArrayList<Map<String, String>>();
|
||||
Map<String, String> value = new HashMap<String, String>();
|
||||
Map<String, String> value2 = new HashMap<String, String>();
|
||||
value.put("value", "New Title");
|
||||
value2.put("value", null);
|
||||
titelValues.add(value);
|
||||
uriValues.add(value2);
|
||||
operations.add(new AddOperation("/sections/traditionalpageone/dc.title", titelValues));
|
||||
operations.add(new AddOperation("/sections/traditionalpageone/dc.identifier.uri", uriValues));
|
||||
|
||||
String patchBody = getPatchContent(operations);
|
||||
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 if the new title if back and the other values untouched
|
||||
Matchers.is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem,
|
||||
"New Title", "2017-10-17", "ExtraEntry"))))
|
||||
.andExpect(jsonPath("$", JsonPathMatchers
|
||||
.hasNoJsonPath("$.sections.traditionalpageone['dc.identifier.uri']")));
|
||||
|
||||
|
||||
// verify that the patch changes have been persisted
|
||||
getClient(authToken).perform(get("/api/submission/workspaceitems/" + witem.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.errors").doesNotExist())
|
||||
.andExpect(jsonPath("$",
|
||||
Matchers.is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem,
|
||||
"New Title", "2017-10-17", "ExtraEntry"))))
|
||||
.andExpect(jsonPath("$", JsonPathMatchers
|
||||
.hasNoJsonPath("$.sections.traditionalpageone['dc.identifier.uri']")))
|
||||
;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchAddMetadataUpdateExistValueTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -56,7 +56,7 @@ or refer to the Web site http://dspace-dev.dsi.uminho.pt.
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="id" type="xs:ID" use="optional"/>
|
||||
<xs:attribute name="id" type="xs:ID" use="required"/>
|
||||
<xs:attribute name="label" type="xs:string" use="required"/>
|
||||
<xs:attribute name="selectable" type="xs:boolean" default="true"/>
|
||||
</xs:complexType>
|
||||
|
@@ -42,9 +42,14 @@ default.language = en_US
|
||||
|
||||
# Solr server/webapp.
|
||||
# DSpace uses Solr for all search/browse capability (and for usage statistics).
|
||||
# Since DSpace 7, SOLR must be installed as a stand-alone service
|
||||
# Since DSpace 7, SOLR must be installed as a stand-alone service.
|
||||
solr.server = http://localhost:8983/solr
|
||||
|
||||
# Solr core name prefix.
|
||||
# If you connect multiple instances of DSpace to a single Solr instance, you
|
||||
# can organize them with a common core name prefix.
|
||||
solr.multicorePrefix =
|
||||
|
||||
# Solr connection pool.
|
||||
# If you change these values, the changes are not effective until DSpace is
|
||||
# restarted.
|
||||
@@ -235,9 +240,14 @@ logging.server.max-payload-length = 10000
|
||||
# Credentials used to authenticate against the registration agency:
|
||||
identifier.doi.user = username
|
||||
identifier.doi.password = password
|
||||
|
||||
# URL for the DOI resolver. This will be the stem for generated DOIs.
|
||||
#identifier.doi.resolver = https://doi.org
|
||||
|
||||
# DOI prefix used to mint DOIs. All DOIs minted by DSpace will use this prefix.
|
||||
# The Prefix will be assigned by the registration agency.
|
||||
identifier.doi.prefix = 10.5072
|
||||
|
||||
# If you want to, you can further separate your namespace. Should all the
|
||||
# suffixes of all DOIs minted by DSpace start with a special string to separate
|
||||
# it from other services also minting DOIs under your prefix?
|
||||
@@ -1349,11 +1359,11 @@ sherpa.romeo.apikey =
|
||||
# org.dspace.content.authority.SampleAuthority = Sample, \
|
||||
# org.dspace.content.authority.SHERPARoMEOPublisher = SRPublisher, \
|
||||
# org.dspace.content.authority.SHERPARoMEOJournalTitle = SRJournalTitle, \
|
||||
# org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
|
||||
# org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
|
||||
|
||||
#Uncomment to enable ORCID authority control
|
||||
#plugin.named.org.dspace.content.authority.ChoiceAuthority = \
|
||||
# org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
|
||||
# org.dspace.content.authority.SolrAuthority = SolrAuthorAuthority
|
||||
|
||||
# URL of ORCID API
|
||||
# Defaults to using the Public API V3 (pub.orcid.org)
|
||||
@@ -1403,8 +1413,9 @@ plugin.selfnamed.org.dspace.content.authority.ChoiceAuthority = \
|
||||
## See manual or org.dspace.content.authority.Choices source for descriptions.
|
||||
authority.minconfidence = ambiguous
|
||||
|
||||
# Configuration settings for ORCID based authority control, uncomment the lines below to enable configuration
|
||||
#solr.authority.server=${solr.server}/authority
|
||||
# Configuration settings for ORCID based authority control.
|
||||
# Uncomment the lines below to enable configuration.
|
||||
#solr.authority.server=${solr.server}/${solr.multicorePrefix}authority
|
||||
#choices.plugin.dc.contributor.author = SolrAuthorAuthority
|
||||
#choices.presentation.dc.contributor.author = authorLookup
|
||||
#authority.controlled.dc.contributor.author = true
|
||||
|
@@ -59,6 +59,11 @@ dspace.name = DSpace at My University
|
||||
# Since DSpace 7, SOLR must be installed as a stand-alone service
|
||||
#solr.server = http://localhost:8983/solr
|
||||
|
||||
# Solr core name prefix.
|
||||
# If you connect multiple instances of DSpace to a single Solr instance, you
|
||||
# can organize them with a common core name prefix.
|
||||
#solr.multicorePrefix =
|
||||
|
||||
##########################
|
||||
# DATABASE CONFIGURATION #
|
||||
##########################
|
||||
|
@@ -5,7 +5,7 @@
|
||||
# faceted-search system. #
|
||||
#---------------------------------------------------------------#
|
||||
##### Search Indexing #####
|
||||
discovery.search.server = ${solr.server}/search
|
||||
discovery.search.server = ${solr.server}/${solr.multicorePrefix}search
|
||||
|
||||
#Enable the url validation of the search.server setting above.
|
||||
#Defaults to true: validation is enabled
|
||||
|
@@ -10,7 +10,7 @@ iiif.image.server = http://localhost:8182/iiif/2/
|
||||
# Base URL of the search service used to support the (experimental) IIIF Search
|
||||
# capability. The actual path will depend on how search is being supported.
|
||||
# This example uses the solr plugin https://dbmdz.github.io/solr-ocrhighlighting/
|
||||
# iiif.search.url = ${solr.server}/word_highlighting
|
||||
# iiif.search.url = ${solr.server}/${solr.multicorePrefix}word_highlighting
|
||||
|
||||
# The search plugin used to support (experimental) IIIF Search.
|
||||
# This is the class used with https://dbmdz.github.io/solr-ocrhighlighting/
|
||||
|
@@ -24,7 +24,7 @@ oai.storage=solr
|
||||
oai.url = ${dspace.server.url}/${oai.path}
|
||||
|
||||
# Base solr index
|
||||
oai.solr.url=${solr.server}/oai
|
||||
oai.solr.url=${solr.server}/${solr.multicorePrefix}oai
|
||||
|
||||
# OAI persistent identifier prefix
|
||||
# This field is used for two purposes:
|
||||
|
@@ -10,7 +10,7 @@
|
||||
# set this to be the port you run the dspace "solr" webapp
|
||||
# on, by default, we are assuming a test configuration with
|
||||
# tomcat still running on port 8080
|
||||
solr-statistics.server = ${solr.server}/statistics
|
||||
solr-statistics.server = ${solr.server}/${solr.multicorePrefix}statistics
|
||||
|
||||
# A comma-separated list that contains the bundles for which the bitstreams will be displayed
|
||||
solr-statistics.query.filter.bundles=ORIGINAL
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>modules</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>modules</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -13,7 +13,7 @@ just adding new jar in the classloader</description>
|
||||
<parent>
|
||||
<artifactId>modules</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
36
pom.xml
36
pom.xml
@@ -4,7 +4,7 @@
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<name>DSpace Parent Project</name>
|
||||
<description>
|
||||
DSpace open source software is a turnkey institutional repository application.
|
||||
@@ -24,7 +24,7 @@
|
||||
<spring-security.version>5.2.2.RELEASE</spring-security.version> <!-- sync with version used by spring-boot-->
|
||||
<hibernate.version>5.4.10.Final</hibernate.version>
|
||||
<hibernate-validator.version>6.0.18.Final</hibernate-validator.version>
|
||||
<postgresql.driver.version>42.2.25</postgresql.driver.version>
|
||||
<postgresql.driver.version>42.3.3</postgresql.driver.version>
|
||||
<solr.client.version>8.8.1</solr.client.version>
|
||||
|
||||
<axiom.version>1.2.22</axiom.version>
|
||||
@@ -868,14 +868,14 @@
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-rest</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<classifier>classes</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-rest</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -1026,69 +1026,69 @@
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
<type>test-jar</type>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace.modules</groupId>
|
||||
<artifactId>additions</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-sword</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-swordv2</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-services</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-server-webapp</artifactId>
|
||||
<type>test-jar</type>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-rdf</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-iiif</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-server-webapp</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
<classifier>classes</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-server-webapp</artifactId>
|
||||
<version>7.2</version>
|
||||
<version>7.3-SNAPSHOT</version>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<!-- DSpace API Localization Packages -->
|
||||
@@ -1570,7 +1570,7 @@
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<version>2.12.0</version>
|
||||
<version>2.12.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>xml-apis</groupId>
|
||||
@@ -1877,7 +1877,7 @@
|
||||
<connection>scm:git:git@github.com:DSpace/DSpace.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:DSpace/DSpace.git</developerConnection>
|
||||
<url>git@github.com:DSpace/DSpace.git</url>
|
||||
<tag>dspace-7.2</tag>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user