mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 18:14:26 +00:00
Merge remote-tracking branch 'origin/main' into w2p-97298_issue-3281_self-register-issue-main
This commit is contained in:
@@ -598,18 +598,19 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
|
|||||||
changes.add(whatHasChanged);
|
changes.add(whatHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change) {
|
if (change && (rowCount % configurationService.getIntProperty("bulkedit.change.commit.count", 100) == 0)) {
|
||||||
//only clear cache if changes have been made.
|
c.commit();
|
||||||
c.uncacheEntity(wsItem);
|
handler.logInfo(LogHelper.getHeader(c, "metadata_import_commit", "lineNumber=" + rowCount));
|
||||||
c.uncacheEntity(wfItem);
|
|
||||||
c.uncacheEntity(item);
|
|
||||||
}
|
}
|
||||||
populateRefAndRowMap(line, item == null ? null : item.getID());
|
populateRefAndRowMap(line, item == null ? null : item.getID());
|
||||||
// keep track of current rows processed
|
// keep track of current rows processed
|
||||||
rowCount++;
|
rowCount++;
|
||||||
}
|
}
|
||||||
|
if (change) {
|
||||||
|
c.commit();
|
||||||
|
}
|
||||||
|
|
||||||
c.setMode(originalMode);
|
c.setMode(Context.Mode.READ_ONLY);
|
||||||
|
|
||||||
|
|
||||||
// Return the changes
|
// Return the changes
|
||||||
|
@@ -67,6 +67,7 @@ public class ItemImport extends DSpaceRunnable<ItemImportScriptConfiguration> {
|
|||||||
protected String eperson = null;
|
protected String eperson = null;
|
||||||
protected String[] collections = null;
|
protected String[] collections = null;
|
||||||
protected boolean isTest = false;
|
protected boolean isTest = false;
|
||||||
|
protected boolean isExcludeContent = false;
|
||||||
protected boolean isResume = false;
|
protected boolean isResume = false;
|
||||||
protected boolean useWorkflow = false;
|
protected boolean useWorkflow = false;
|
||||||
protected boolean useWorkflowSendEmail = false;
|
protected boolean useWorkflowSendEmail = false;
|
||||||
@@ -119,6 +120,8 @@ public class ItemImport extends DSpaceRunnable<ItemImportScriptConfiguration> {
|
|||||||
handler.logInfo("**Test Run** - not actually importing items.");
|
handler.logInfo("**Test Run** - not actually importing items.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isExcludeContent = commandLine.hasOption('x');
|
||||||
|
|
||||||
if (commandLine.hasOption('p')) {
|
if (commandLine.hasOption('p')) {
|
||||||
template = true;
|
template = true;
|
||||||
}
|
}
|
||||||
@@ -204,6 +207,7 @@ public class ItemImport extends DSpaceRunnable<ItemImportScriptConfiguration> {
|
|||||||
.getItemImportService();
|
.getItemImportService();
|
||||||
try {
|
try {
|
||||||
itemImportService.setTest(isTest);
|
itemImportService.setTest(isTest);
|
||||||
|
itemImportService.setExcludeContent(isExcludeContent);
|
||||||
itemImportService.setResume(isResume);
|
itemImportService.setResume(isResume);
|
||||||
itemImportService.setUseWorkflow(useWorkflow);
|
itemImportService.setUseWorkflow(useWorkflow);
|
||||||
itemImportService.setUseWorkflowSendEmail(useWorkflowSendEmail);
|
itemImportService.setUseWorkflowSendEmail(useWorkflowSendEmail);
|
||||||
|
@@ -55,6 +55,9 @@ public class ItemImportCLIScriptConfiguration extends ItemImportScriptConfigurat
|
|||||||
options.addOption(Option.builder("v").longOpt("validate")
|
options.addOption(Option.builder("v").longOpt("validate")
|
||||||
.desc("test run - do not actually import items")
|
.desc("test run - do not actually import items")
|
||||||
.hasArg(false).required(false).build());
|
.hasArg(false).required(false).build());
|
||||||
|
options.addOption(Option.builder("x").longOpt("exclude-bitstreams")
|
||||||
|
.desc("do not load or expect content bitstreams")
|
||||||
|
.hasArg(false).required(false).build());
|
||||||
options.addOption(Option.builder("p").longOpt("template")
|
options.addOption(Option.builder("p").longOpt("template")
|
||||||
.desc("apply template")
|
.desc("apply template")
|
||||||
.hasArg(false).required(false).build());
|
.hasArg(false).required(false).build());
|
||||||
|
@@ -81,6 +81,9 @@ public class ItemImportScriptConfiguration<T extends ItemImport> extends ScriptC
|
|||||||
options.addOption(Option.builder("v").longOpt("validate")
|
options.addOption(Option.builder("v").longOpt("validate")
|
||||||
.desc("test run - do not actually import items")
|
.desc("test run - do not actually import items")
|
||||||
.hasArg(false).required(false).build());
|
.hasArg(false).required(false).build());
|
||||||
|
options.addOption(Option.builder("x").longOpt("exclude-bitstreams")
|
||||||
|
.desc("do not load or expect content bitstreams")
|
||||||
|
.hasArg(false).required(false).build());
|
||||||
options.addOption(Option.builder("p").longOpt("template")
|
options.addOption(Option.builder("p").longOpt("template")
|
||||||
.desc("apply template")
|
.desc("apply template")
|
||||||
.hasArg(false).required(false).build());
|
.hasArg(false).required(false).build());
|
||||||
|
@@ -62,6 +62,7 @@ import org.apache.commons.io.FileUtils;
|
|||||||
import org.apache.commons.lang3.RandomStringUtils;
|
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.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
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;
|
||||||
@@ -135,7 +136,7 @@ import org.xml.sax.SAXException;
|
|||||||
* allow the registration of files (bitstreams) into DSpace.
|
* allow the registration of files (bitstreams) into DSpace.
|
||||||
*/
|
*/
|
||||||
public class ItemImportServiceImpl implements ItemImportService, InitializingBean {
|
public class ItemImportServiceImpl implements ItemImportService, InitializingBean {
|
||||||
private final Logger log = org.apache.logging.log4j.LogManager.getLogger(ItemImportServiceImpl.class);
|
private final Logger log = LogManager.getLogger();
|
||||||
|
|
||||||
private DSpaceRunnableHandler handler;
|
private DSpaceRunnableHandler handler;
|
||||||
|
|
||||||
@@ -181,6 +182,7 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
protected String tempWorkDir;
|
protected String tempWorkDir;
|
||||||
|
|
||||||
protected boolean isTest = false;
|
protected boolean isTest = false;
|
||||||
|
protected boolean isExcludeContent = false;
|
||||||
protected boolean isResume = false;
|
protected boolean isResume = false;
|
||||||
protected boolean useWorkflow = false;
|
protected boolean useWorkflow = false;
|
||||||
protected boolean useWorkflowSendEmail = false;
|
protected boolean useWorkflowSendEmail = false;
|
||||||
@@ -1403,6 +1405,10 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
protected void processContentFileEntry(Context c, Item i, String path,
|
protected void processContentFileEntry(Context c, Item i, String path,
|
||||||
String fileName, String bundleName, boolean primary) throws SQLException,
|
String fileName, String bundleName, boolean primary) throws SQLException,
|
||||||
IOException, AuthorizeException {
|
IOException, AuthorizeException {
|
||||||
|
if (isExcludeContent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
String fullpath = path + File.separatorChar + fileName;
|
String fullpath = path + File.separatorChar + fileName;
|
||||||
|
|
||||||
// get an input stream
|
// get an input stream
|
||||||
@@ -2342,6 +2348,11 @@ public class ItemImportServiceImpl implements ItemImportService, InitializingBea
|
|||||||
this.isTest = isTest;
|
this.isTest = isTest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setExcludeContent(boolean isExcludeContent) {
|
||||||
|
this.isExcludeContent = isExcludeContent;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setResume(boolean isResume) {
|
public void setResume(boolean isResume) {
|
||||||
this.isResume = isResume;
|
this.isResume = isResume;
|
||||||
|
@@ -211,6 +211,13 @@ public interface ItemImportService {
|
|||||||
*/
|
*/
|
||||||
public void setTest(boolean isTest);
|
public void setTest(boolean isTest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set exclude-content flag.
|
||||||
|
*
|
||||||
|
* @param isExcludeContent true or false
|
||||||
|
*/
|
||||||
|
public void setExcludeContent(boolean isExcludeContent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set resume flag
|
* Set resume flag
|
||||||
*
|
*
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.util;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.regex.PatternSyntaxException;
|
import java.util.regex.PatternSyntaxException;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -131,10 +132,15 @@ public class DCInput {
|
|||||||
private boolean closedVocabulary = false;
|
private boolean closedVocabulary = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the regex to comply with, null if nothing
|
* the regex in ECMAScript standard format, usable also by rests.
|
||||||
*/
|
*/
|
||||||
private String regex = null;
|
private String regex = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the computed pattern, null if nothing
|
||||||
|
*/
|
||||||
|
private Pattern pattern = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* allowed document types
|
* allowed document types
|
||||||
*/
|
*/
|
||||||
@@ -178,7 +184,7 @@ public class DCInput {
|
|||||||
|
|
||||||
//check if the input have a language tag
|
//check if the input have a language tag
|
||||||
language = Boolean.valueOf(fieldMap.get("language"));
|
language = Boolean.valueOf(fieldMap.get("language"));
|
||||||
valueLanguageList = new ArrayList();
|
valueLanguageList = new ArrayList<>();
|
||||||
if (language) {
|
if (language) {
|
||||||
String languageNameTmp = fieldMap.get("value-pairs-name");
|
String languageNameTmp = fieldMap.get("value-pairs-name");
|
||||||
if (StringUtils.isBlank(languageNameTmp)) {
|
if (StringUtils.isBlank(languageNameTmp)) {
|
||||||
@@ -191,7 +197,7 @@ public class DCInput {
|
|||||||
repeatable = "true".equalsIgnoreCase(repStr)
|
repeatable = "true".equalsIgnoreCase(repStr)
|
||||||
|| "yes".equalsIgnoreCase(repStr);
|
|| "yes".equalsIgnoreCase(repStr);
|
||||||
String nameVariantsString = fieldMap.get("name-variants");
|
String nameVariantsString = fieldMap.get("name-variants");
|
||||||
nameVariants = (StringUtils.isNotBlank(nameVariantsString)) ?
|
nameVariants = StringUtils.isNotBlank(nameVariantsString) ?
|
||||||
nameVariantsString.equalsIgnoreCase("true") : false;
|
nameVariantsString.equalsIgnoreCase("true") : false;
|
||||||
label = fieldMap.get("label");
|
label = fieldMap.get("label");
|
||||||
inputType = fieldMap.get("input-type");
|
inputType = fieldMap.get("input-type");
|
||||||
@@ -203,17 +209,17 @@ public class DCInput {
|
|||||||
}
|
}
|
||||||
hint = fieldMap.get("hint");
|
hint = fieldMap.get("hint");
|
||||||
warning = fieldMap.get("required");
|
warning = fieldMap.get("required");
|
||||||
required = (warning != null && warning.length() > 0);
|
required = warning != null && warning.length() > 0;
|
||||||
visibility = fieldMap.get("visibility");
|
visibility = fieldMap.get("visibility");
|
||||||
readOnly = fieldMap.get("readonly");
|
readOnly = fieldMap.get("readonly");
|
||||||
vocabulary = fieldMap.get("vocabulary");
|
vocabulary = fieldMap.get("vocabulary");
|
||||||
regex = fieldMap.get("regex");
|
this.initRegex(fieldMap.get("regex"));
|
||||||
String closedVocabularyStr = fieldMap.get("closedVocabulary");
|
String closedVocabularyStr = fieldMap.get("closedVocabulary");
|
||||||
closedVocabulary = "true".equalsIgnoreCase(closedVocabularyStr)
|
closedVocabulary = "true".equalsIgnoreCase(closedVocabularyStr)
|
||||||
|| "yes".equalsIgnoreCase(closedVocabularyStr);
|
|| "yes".equalsIgnoreCase(closedVocabularyStr);
|
||||||
|
|
||||||
// parsing of the <type-bind> element (using the colon as split separator)
|
// parsing of the <type-bind> element (using the colon as split separator)
|
||||||
typeBind = new ArrayList<>();
|
typeBind = new ArrayList<String>();
|
||||||
String typeBindDef = fieldMap.get("type-bind");
|
String typeBindDef = fieldMap.get("type-bind");
|
||||||
if (typeBindDef != null && typeBindDef.trim().length() > 0) {
|
if (typeBindDef != null && typeBindDef.trim().length() > 0) {
|
||||||
String[] types = typeBindDef.split(",");
|
String[] types = typeBindDef.split(",");
|
||||||
@@ -238,6 +244,22 @@ public class DCInput {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void initRegex(String regex) {
|
||||||
|
this.regex = null;
|
||||||
|
this.pattern = null;
|
||||||
|
if (regex != null) {
|
||||||
|
try {
|
||||||
|
Optional.ofNullable(RegexPatternUtils.computePattern(regex))
|
||||||
|
.ifPresent(pattern -> {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.regex = regex;
|
||||||
|
});
|
||||||
|
} catch (PatternSyntaxException e) {
|
||||||
|
log.warn("The regex field of input {} with value {} is invalid!", this.label, regex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this DCInput for display in the given scope? The scope should be
|
* Is this DCInput for display in the given scope? The scope should be
|
||||||
* either "workflow" or "submit", as per the input forms definition. If the
|
* either "workflow" or "submit", as per the input forms definition. If the
|
||||||
@@ -248,7 +270,7 @@ public class DCInput {
|
|||||||
* @return whether the input should be displayed or not
|
* @return whether the input should be displayed or not
|
||||||
*/
|
*/
|
||||||
public boolean isVisible(String scope) {
|
public boolean isVisible(String scope) {
|
||||||
return (visibility == null || visibility.equals(scope));
|
return visibility == null || visibility.equals(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -512,8 +534,12 @@ public class DCInput {
|
|||||||
return visibility;
|
return visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Pattern getPattern() {
|
||||||
|
return this.pattern;
|
||||||
|
}
|
||||||
|
|
||||||
public String getRegex() {
|
public String getRegex() {
|
||||||
return regex;
|
return this.regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFieldName() {
|
public String getFieldName() {
|
||||||
@@ -546,8 +572,7 @@ public class DCInput {
|
|||||||
public boolean validate(String value) {
|
public boolean validate(String value) {
|
||||||
if (StringUtils.isNotBlank(value)) {
|
if (StringUtils.isNotBlank(value)) {
|
||||||
try {
|
try {
|
||||||
if (StringUtils.isNotBlank(regex)) {
|
if (this.pattern != null) {
|
||||||
Pattern pattern = Pattern.compile(regex);
|
|
||||||
if (!pattern.matcher(value).matches()) {
|
if (!pattern.matcher(value).matches()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -557,7 +582,6 @@ public class DCInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.util;
|
||||||
|
|
||||||
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class useful for check regex and patterns.
|
||||||
|
*
|
||||||
|
* @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RegexPatternUtils {
|
||||||
|
|
||||||
|
// checks input having the format /{pattern}/{flags}
|
||||||
|
// allowed flags are: g,i,m,s,u,y
|
||||||
|
public static final String REGEX_INPUT_VALIDATOR = "(/?)(.+)\\1([gimsuy]*)";
|
||||||
|
// flags usable inside regex definition using format (?i|m|s|u|y)
|
||||||
|
public static final String REGEX_FLAGS = "(?%s)";
|
||||||
|
public static final Pattern PATTERN_REGEX_INPUT_VALIDATOR =
|
||||||
|
Pattern.compile(REGEX_INPUT_VALIDATOR, CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes a pattern starting from a regex definition with flags that
|
||||||
|
* uses the standard format: <code>/{regex}/{flags}</code> (ECMAScript format).
|
||||||
|
* This method can transform an ECMAScript regex into a java {@code Pattern} object
|
||||||
|
* wich can be used to validate strings.
|
||||||
|
* <br/>
|
||||||
|
* If regex is null, empty or blank a null {@code Pattern} will be retrieved
|
||||||
|
* If it's a valid regex, then a non-null {@code Pattern} will be retrieved,
|
||||||
|
* an exception will be thrown otherwise.
|
||||||
|
*
|
||||||
|
* @param regex with format <code>/{regex}/{flags}</code>
|
||||||
|
* @return {@code Pattern} regex pattern instance
|
||||||
|
* @throws PatternSyntaxException
|
||||||
|
*/
|
||||||
|
public static final Pattern computePattern(String regex) throws PatternSyntaxException {
|
||||||
|
if (StringUtils.isBlank(regex)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Matcher inputMatcher = PATTERN_REGEX_INPUT_VALIDATOR.matcher(regex);
|
||||||
|
String regexPattern = regex;
|
||||||
|
String regexFlags = "";
|
||||||
|
if (inputMatcher.matches()) {
|
||||||
|
regexPattern =
|
||||||
|
Optional.of(inputMatcher.group(2))
|
||||||
|
.filter(StringUtils::isNotBlank)
|
||||||
|
.orElse(regex);
|
||||||
|
regexFlags =
|
||||||
|
Optional.ofNullable(inputMatcher.group(3))
|
||||||
|
.filter(StringUtils::isNotBlank)
|
||||||
|
.map(flags -> String.format(REGEX_FLAGS, flags))
|
||||||
|
.orElse("")
|
||||||
|
.replaceAll("g", "");
|
||||||
|
}
|
||||||
|
return Pattern.compile(regexFlags + regexPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RegexPatternUtils() {}
|
||||||
|
|
||||||
|
}
|
@@ -31,10 +31,12 @@ import org.dspace.content.DSpaceObject;
|
|||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.factory.ContentServiceFactory;
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
|
import org.dspace.content.service.CollectionService;
|
||||||
import org.dspace.content.service.WorkspaceItemService;
|
import org.dspace.content.service.WorkspaceItemService;
|
||||||
import org.dspace.core.Constants;
|
import org.dspace.core.Constants;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.discovery.DiscoverQuery;
|
import org.dspace.discovery.DiscoverQuery;
|
||||||
|
import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
||||||
import org.dspace.discovery.DiscoverResult;
|
import org.dspace.discovery.DiscoverResult;
|
||||||
import org.dspace.discovery.IndexableObject;
|
import org.dspace.discovery.IndexableObject;
|
||||||
import org.dspace.discovery.SearchService;
|
import org.dspace.discovery.SearchService;
|
||||||
@@ -830,7 +832,7 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
query = formatCustomQuery(query);
|
query = formatCustomQuery(query);
|
||||||
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
||||||
IndexableCommunity.TYPE,
|
IndexableCommunity.TYPE,
|
||||||
offset, limit);
|
offset, limit, null, null);
|
||||||
for (IndexableObject solrCollections : discoverResult.getIndexableObjects()) {
|
for (IndexableObject solrCollections : discoverResult.getIndexableObjects()) {
|
||||||
Community community = ((IndexableCommunity) solrCollections).getIndexedObject();
|
Community community = ((IndexableCommunity) solrCollections).getIndexedObject();
|
||||||
communities.add(community);
|
communities.add(community);
|
||||||
@@ -852,7 +854,7 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
query = formatCustomQuery(query);
|
query = formatCustomQuery(query);
|
||||||
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
||||||
IndexableCommunity.TYPE,
|
IndexableCommunity.TYPE,
|
||||||
null, null);
|
null, null, null, null);
|
||||||
return discoverResult.getTotalSearchResults();
|
return discoverResult.getTotalSearchResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,7 +879,7 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
query = formatCustomQuery(query);
|
query = formatCustomQuery(query);
|
||||||
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
||||||
IndexableCollection.TYPE,
|
IndexableCollection.TYPE,
|
||||||
offset, limit);
|
offset, limit, CollectionService.SOLR_SORT_FIELD, SORT_ORDER.asc);
|
||||||
for (IndexableObject solrCollections : discoverResult.getIndexableObjects()) {
|
for (IndexableObject solrCollections : discoverResult.getIndexableObjects()) {
|
||||||
Collection collection = ((IndexableCollection) solrCollections).getIndexedObject();
|
Collection collection = ((IndexableCollection) solrCollections).getIndexedObject();
|
||||||
collections.add(collection);
|
collections.add(collection);
|
||||||
@@ -899,7 +901,7 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
query = formatCustomQuery(query);
|
query = formatCustomQuery(query);
|
||||||
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
|
||||||
IndexableCollection.TYPE,
|
IndexableCollection.TYPE,
|
||||||
null, null);
|
null, null, null, null);
|
||||||
return discoverResult.getTotalSearchResults();
|
return discoverResult.getTotalSearchResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -919,7 +921,7 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DiscoverResult discoverResult = getDiscoverResult(context, query, null, null);
|
DiscoverResult discoverResult = getDiscoverResult(context, query, null, null, null, null);
|
||||||
if (discoverResult.getTotalSearchResults() > 0) {
|
if (discoverResult.getTotalSearchResults() > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -931,7 +933,8 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DiscoverResult getDiscoverResult(Context context, String query, Integer offset, Integer limit)
|
private DiscoverResult getDiscoverResult(Context context, String query, Integer offset, Integer limit,
|
||||||
|
String sortField, SORT_ORDER sortOrder)
|
||||||
throws SearchServiceException, SQLException {
|
throws SearchServiceException, SQLException {
|
||||||
String groupQuery = getGroupToQuery(groupService.allMemberGroups(context, context.getCurrentUser()));
|
String groupQuery = getGroupToQuery(groupService.allMemberGroups(context, context.getCurrentUser()));
|
||||||
|
|
||||||
@@ -947,7 +950,9 @@ public class AuthorizeServiceImpl implements AuthorizeService {
|
|||||||
if (limit != null) {
|
if (limit != null) {
|
||||||
discoverQuery.setMaxResults(limit);
|
discoverQuery.setMaxResults(limit);
|
||||||
}
|
}
|
||||||
|
if (sortField != null && sortOrder != null) {
|
||||||
|
discoverQuery.setSortField(sortField, sortOrder);
|
||||||
|
}
|
||||||
|
|
||||||
return searchService.search(context, discoverQuery);
|
return searchService.search(context, discoverQuery);
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
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.apache.solr.client.solrj.util.ClientUtils;
|
||||||
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
import org.dspace.authorize.factory.AuthorizeServiceFactory;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
@@ -206,7 +207,8 @@ public class SolrBrowseDAO implements BrowseDAO {
|
|||||||
query.addFilterQueries("{!field f=" + facetField + "_partial}" + value);
|
query.addFilterQueries("{!field f=" + facetField + "_partial}" + value);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(startsWith) && orderField != null) {
|
if (StringUtils.isNotBlank(startsWith) && orderField != null) {
|
||||||
query.addFilterQueries("bi_" + orderField + "_sort:" + startsWith + "*");
|
query.addFilterQueries(
|
||||||
|
"bi_" + orderField + "_sort:" + ClientUtils.escapeQueryChars(startsWith) + "*");
|
||||||
}
|
}
|
||||||
// filter on item to be sure to don't include any other object
|
// filter on item to be sure to don't include any other object
|
||||||
// indexed in the Discovery Search core
|
// indexed in the Discovery Search core
|
||||||
|
@@ -43,6 +43,7 @@ import org.dspace.core.I18nUtil;
|
|||||||
import org.dspace.core.LogHelper;
|
import org.dspace.core.LogHelper;
|
||||||
import org.dspace.core.service.LicenseService;
|
import org.dspace.core.service.LicenseService;
|
||||||
import org.dspace.discovery.DiscoverQuery;
|
import org.dspace.discovery.DiscoverQuery;
|
||||||
|
import org.dspace.discovery.DiscoverQuery.SORT_ORDER;
|
||||||
import org.dspace.discovery.DiscoverResult;
|
import org.dspace.discovery.DiscoverResult;
|
||||||
import org.dspace.discovery.IndexableObject;
|
import org.dspace.discovery.IndexableObject;
|
||||||
import org.dspace.discovery.SearchService;
|
import org.dspace.discovery.SearchService;
|
||||||
@@ -946,6 +947,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
||||||
discoverQuery.setStart(offset);
|
discoverQuery.setStart(offset);
|
||||||
discoverQuery.setMaxResults(limit);
|
discoverQuery.setMaxResults(limit);
|
||||||
|
discoverQuery.setSortField(SOLR_SORT_FIELD, SORT_ORDER.asc);
|
||||||
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery, null, community, q);
|
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery, null, community, q);
|
||||||
for (IndexableObject solrCollections : resp.getIndexableObjects()) {
|
for (IndexableObject solrCollections : resp.getIndexableObjects()) {
|
||||||
Collection c = ((IndexableCollection) solrCollections).getIndexedObject();
|
Collection c = ((IndexableCollection) solrCollections).getIndexedObject();
|
||||||
@@ -1025,6 +1027,7 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
|
|||||||
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
discoverQuery.setDSpaceObjectFilter(IndexableCollection.TYPE);
|
||||||
discoverQuery.setStart(offset);
|
discoverQuery.setStart(offset);
|
||||||
discoverQuery.setMaxResults(limit);
|
discoverQuery.setMaxResults(limit);
|
||||||
|
discoverQuery.setSortField(SOLR_SORT_FIELD, SORT_ORDER.asc);
|
||||||
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,
|
DiscoverResult resp = retrieveCollectionsWithSubmit(context, discoverQuery,
|
||||||
entityType, community, q);
|
entityType, community, q);
|
||||||
for (IndexableObject solrCollections : resp.getIndexableObjects()) {
|
for (IndexableObject solrCollections : resp.getIndexableObjects()) {
|
||||||
|
@@ -33,6 +33,11 @@ import org.dspace.eperson.Group;
|
|||||||
public interface CollectionService
|
public interface CollectionService
|
||||||
extends DSpaceObjectService<Collection>, DSpaceObjectLegacySupportService<Collection> {
|
extends DSpaceObjectService<Collection>, DSpaceObjectLegacySupportService<Collection> {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Field used to sort community and collection lists at solr
|
||||||
|
*/
|
||||||
|
public static final String SOLR_SORT_FIELD = "dc.title_sort";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new collection with a new ID.
|
* Create a new collection with a new ID.
|
||||||
* Once created the collection is added to the given community
|
* Once created the collection is added to the given community
|
||||||
@@ -46,7 +51,6 @@ public interface CollectionService
|
|||||||
public Collection create(Context context, Community community) throws SQLException,
|
public Collection create(Context context, Community community) throws SQLException,
|
||||||
AuthorizeException;
|
AuthorizeException;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new collection with the supplied handle and with a new ID.
|
* Create a new collection with the supplied handle and with a new ID.
|
||||||
* Once created the collection is added to the given community
|
* Once created the collection is added to the given community
|
||||||
|
@@ -9,6 +9,7 @@ package org.dspace.handle;
|
|||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@@ -211,17 +212,17 @@ public class HandleServiceImpl implements HandleService {
|
|||||||
@Override
|
@Override
|
||||||
public void unbindHandle(Context context, DSpaceObject dso)
|
public void unbindHandle(Context context, DSpaceObject dso)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
List<Handle> handles = getInternalHandles(context, dso);
|
Iterator<Handle> handles = dso.getHandles().iterator();
|
||||||
if (CollectionUtils.isNotEmpty(handles)) {
|
if (handles.hasNext()) {
|
||||||
for (Handle handle : handles) {
|
while (handles.hasNext()) {
|
||||||
|
final Handle handle = handles.next();
|
||||||
|
handles.remove();
|
||||||
//Only set the "resouce_id" column to null when unbinding a handle.
|
//Only set the "resouce_id" column to null when unbinding a handle.
|
||||||
// We want to keep around the "resource_type_id" value, so that we
|
// We want to keep around the "resource_type_id" value, so that we
|
||||||
// can verify during a restore whether the same *type* of resource
|
// can verify during a restore whether the same *type* of resource
|
||||||
// is reusing this handle!
|
// is reusing this handle!
|
||||||
handle.setDSpaceObject(null);
|
handle.setDSpaceObject(null);
|
||||||
|
|
||||||
//Also remove the handle from the DSO list to keep a consistent model
|
|
||||||
dso.getHandles().remove(handle);
|
|
||||||
|
|
||||||
handleDAO.save(context, handle);
|
handleDAO.save(context, handle);
|
||||||
|
|
||||||
@@ -256,7 +257,7 @@ public class HandleServiceImpl implements HandleService {
|
|||||||
@Override
|
@Override
|
||||||
public String findHandle(Context context, DSpaceObject dso)
|
public String findHandle(Context context, DSpaceObject dso)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
List<Handle> handles = getInternalHandles(context, dso);
|
List<Handle> handles = dso.getHandles();
|
||||||
if (CollectionUtils.isEmpty(handles)) {
|
if (CollectionUtils.isEmpty(handles)) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@@ -328,20 +329,6 @@ public class HandleServiceImpl implements HandleService {
|
|||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// Internal methods
|
// Internal methods
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the handle for an Object, or null if the Object has no handle.
|
|
||||||
*
|
|
||||||
* @param context DSpace context
|
|
||||||
* @param dso DSpaceObject for which we require our handles
|
|
||||||
* @return The handle for object, or null if the object has no handle.
|
|
||||||
* @throws SQLException If a database error occurs
|
|
||||||
*/
|
|
||||||
protected List<Handle> getInternalHandles(Context context, DSpaceObject dso)
|
|
||||||
throws SQLException {
|
|
||||||
return handleDAO.getHandlesByDSpaceObject(context, dso);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the database row corresponding to handle.
|
* Find the database row corresponding to handle.
|
||||||
*
|
*
|
||||||
|
@@ -0,0 +1,9 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX resourcepolicy_action_idx ON resourcepolicy(action_id);
|
@@ -0,0 +1,9 @@
|
|||||||
|
--
|
||||||
|
-- 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/
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX resourcepolicy_action_idx ON resourcepolicy(action_id);
|
@@ -0,0 +1,214 @@
|
|||||||
|
/**
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.PatternSyntaxException;
|
||||||
|
|
||||||
|
import org.dspace.AbstractUnitTest;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for RegexPatternUtils
|
||||||
|
*
|
||||||
|
* @author Vincenzo Mecca (vins01-4science - vincenzo.mecca at 4science.com)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RegexPatternUtilsTest extends AbstractUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidRegexWithFlag() {
|
||||||
|
final String insensitiveWord = "/[a-z]+/i";
|
||||||
|
Pattern computePattern = Pattern.compile(insensitiveWord);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
|
||||||
|
Matcher matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("DSpace");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Community");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/wrongpattern/i");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("001");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("?/'`}{][<>.,");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
computePattern = RegexPatternUtils.computePattern(insensitiveWord);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("DSpace");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Community");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/wrong-pattern/i");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("001");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("?/'`}{][<>.,");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRegexWithoutFlag() {
|
||||||
|
final String sensitiveWord = "[a-z]+";
|
||||||
|
Pattern computePattern = RegexPatternUtils.computePattern(sensitiveWord);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
|
||||||
|
Matcher matcher = computePattern.matcher("hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("dspace");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("community");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("DSpace");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Community");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/wrongpattern/i");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("001");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("?/'`}{][<>.,");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
|
||||||
|
final String sensitiveWordWithDelimiter = "/[a-z]+/";
|
||||||
|
computePattern = RegexPatternUtils.computePattern(sensitiveWordWithDelimiter);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
|
||||||
|
matcher = computePattern.matcher("hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("dspace");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("community");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("DSpace");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Community");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/wrongpattern/i");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("001");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("?/'`}{][<>.,");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithFuzzyRegex() {
|
||||||
|
String fuzzyRegex = "/[a-z]+";
|
||||||
|
Pattern computePattern = RegexPatternUtils.computePattern(fuzzyRegex);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
|
||||||
|
Matcher matcher = computePattern.matcher("/hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
|
||||||
|
fuzzyRegex = "[a-z]+/";
|
||||||
|
computePattern = RegexPatternUtils.computePattern(fuzzyRegex);
|
||||||
|
matcher = computePattern.matcher("hello/");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
|
||||||
|
// equals to pattern \\[a-z]+\\ -> searching for a word delimited by '\'
|
||||||
|
fuzzyRegex = "\\\\[a-z]+\\\\";
|
||||||
|
computePattern = RegexPatternUtils.computePattern(fuzzyRegex);
|
||||||
|
// equals to '\hello\'
|
||||||
|
matcher = computePattern.matcher("\\hello\\");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
|
||||||
|
// equals to pattern /[a-z]+/ -> searching for a string delimited by '/'
|
||||||
|
fuzzyRegex = "\\/[a-z]+\\/";
|
||||||
|
computePattern = RegexPatternUtils.computePattern(fuzzyRegex);
|
||||||
|
matcher = computePattern.matcher("/hello/");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("/hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertFalse(matcher.matches());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidRegex() {
|
||||||
|
String invalidSensitive = "[a-z+";
|
||||||
|
assertThrows(PatternSyntaxException.class, () -> RegexPatternUtils.computePattern(invalidSensitive));
|
||||||
|
|
||||||
|
String invalidRange = "a{1-";
|
||||||
|
assertThrows(PatternSyntaxException.class, () -> RegexPatternUtils.computePattern(invalidRange));
|
||||||
|
|
||||||
|
String invalidGroupPattern = "(abc";
|
||||||
|
assertThrows(PatternSyntaxException.class, () -> RegexPatternUtils.computePattern(invalidGroupPattern));
|
||||||
|
|
||||||
|
String emptyPattern = "";
|
||||||
|
Pattern computePattern = RegexPatternUtils.computePattern(emptyPattern);
|
||||||
|
assertNull(computePattern);
|
||||||
|
|
||||||
|
String blankPattern = " ";
|
||||||
|
computePattern = RegexPatternUtils.computePattern(blankPattern);
|
||||||
|
assertNull(computePattern);
|
||||||
|
|
||||||
|
String nullPattern = null;
|
||||||
|
computePattern = RegexPatternUtils.computePattern(nullPattern);
|
||||||
|
assertNull(computePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMultiFlagRegex() {
|
||||||
|
String multilineSensitive = "/[a-z]+/gi";
|
||||||
|
Pattern computePattern = RegexPatternUtils.computePattern(multilineSensitive);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
Matcher matcher = computePattern.matcher("hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("Hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
|
||||||
|
multilineSensitive = "/[a-z]+/gim";
|
||||||
|
computePattern = RegexPatternUtils.computePattern(multilineSensitive);
|
||||||
|
assertNotNull(computePattern);
|
||||||
|
matcher = computePattern.matcher("Hello" + System.lineSeparator() + "Everyone");
|
||||||
|
assertTrue(matcher.find());
|
||||||
|
assertEquals("Hello", matcher.group());
|
||||||
|
assertTrue(matcher.find());
|
||||||
|
assertEquals("Everyone", matcher.group());
|
||||||
|
|
||||||
|
matcher = computePattern.matcher("hello");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
matcher = computePattern.matcher("HELLO");
|
||||||
|
assertTrue(matcher.matches());
|
||||||
|
}
|
||||||
|
}
|
@@ -111,7 +111,7 @@ public class VersionRestRepository extends DSpaceRestRepository<VersionRest, Int
|
|||||||
}
|
}
|
||||||
|
|
||||||
EPerson submitter = item.getSubmitter();
|
EPerson submitter = item.getSubmitter();
|
||||||
boolean isAdmin = authorizeService.isAdmin(context);
|
boolean isAdmin = authorizeService.isAdmin(context, item);
|
||||||
boolean canCreateVersion = configurationService.getBooleanProperty("versioning.submitterCanCreateNewVersion");
|
boolean canCreateVersion = configurationService.getBooleanProperty("versioning.submitterCanCreateNewVersion");
|
||||||
|
|
||||||
if (!isAdmin && !(canCreateVersion && Objects.equals(submitter, context.getCurrentUser()))) {
|
if (!isAdmin && !(canCreateVersion && Objects.equals(submitter, context.getCurrentUser()))) {
|
||||||
|
@@ -1111,10 +1111,37 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe
|
|||||||
|
|
||||||
//We expect the totalElements to be the 1 item present in the collection
|
//We expect the totalElements to be the 1 item present in the collection
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(1)))
|
.andExpect(jsonPath("$.page.totalElements", is(1)))
|
||||||
//As this is is a small collection, we expect to go-to page 0
|
//As this is a small collection, we expect to go-to page 0
|
||||||
.andExpect(jsonPath("$.page.number", is(0)))
|
.andExpect(jsonPath("$.page.number", is(0)))
|
||||||
.andExpect(jsonPath("$._links.self.href", containsString("startsWith=Blade")))
|
.andExpect(jsonPath("$._links.self.href", containsString("startsWith=Blade")))
|
||||||
|
|
||||||
|
//Verify that the index jumps to the "Blade Runner" item.
|
||||||
|
.andExpect(jsonPath("$._embedded.items",
|
||||||
|
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item2,
|
||||||
|
"Blade Runner",
|
||||||
|
"1982-06-25")
|
||||||
|
)));
|
||||||
|
|
||||||
|
//Test filtering with spaces:
|
||||||
|
//** WHEN **
|
||||||
|
//An anonymous user browses the items in the Browse by Title endpoint
|
||||||
|
//with startsWith set to Blade Runner and scope set to Col 1
|
||||||
|
getClient().perform(get("/api/discover/browses/title/items?startsWith=Blade Runner")
|
||||||
|
.param("scope", col1.getID().toString())
|
||||||
|
.param("size", "2"))
|
||||||
|
|
||||||
|
//** THEN **
|
||||||
|
//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))
|
||||||
|
|
||||||
|
//We expect the totalElements to be the 1 item present in the collection
|
||||||
|
.andExpect(jsonPath("$.page.totalElements", is(1)))
|
||||||
|
//As this is a small collection, we expect to go-to page 0
|
||||||
|
.andExpect(jsonPath("$.page.number", is(0)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href", containsString("startsWith=Blade Runner")))
|
||||||
|
|
||||||
//Verify that the index jumps to the "Blade Runner" item.
|
//Verify that the index jumps to the "Blade Runner" item.
|
||||||
.andExpect(jsonPath("$._embedded.items",
|
.andExpect(jsonPath("$._embedded.items",
|
||||||
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item2,
|
contains(ItemMatcher.matchItemWithTitleAndDateIssued(item2,
|
||||||
|
@@ -850,6 +850,55 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(status().isUnauthorized());
|
.andExpect(status().isUnauthorized());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createNewVersionItemByCollectionAdminTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
Community rootCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
EPerson colAdmin = EPersonBuilder.createEPerson(context)
|
||||||
|
.withCanLogin(true)
|
||||||
|
.withEmail("coladmin@email.com")
|
||||||
|
.withPassword(password)
|
||||||
|
.withNameInMetadata("Collection", "Admin")
|
||||||
|
.build();
|
||||||
|
Collection col = CollectionBuilder
|
||||||
|
.createCollection(context, rootCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.withAdminGroup(colAdmin)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item item = ItemBuilder.createItem(context, col)
|
||||||
|
.withTitle("Public test item")
|
||||||
|
.withIssueDate("2022-12-19")
|
||||||
|
.withAuthor("Doe, John")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
item.setSubmitter(eperson);
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
AtomicReference<Integer> idRef = new AtomicReference<Integer>();
|
||||||
|
String token = getAuthToken(colAdmin.getEmail(), password);
|
||||||
|
try {
|
||||||
|
getClient(token).perform(post("/api/versioning/versions")
|
||||||
|
.param("summary", "test summary!")
|
||||||
|
.contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE))
|
||||||
|
.content("/api/core/items/" + item.getID()))
|
||||||
|
.andExpect(status().isCreated())
|
||||||
|
.andExpect(jsonPath("$", Matchers.allOf(
|
||||||
|
hasJsonPath("$.version", is(2)),
|
||||||
|
hasJsonPath("$.summary", is("test summary!")),
|
||||||
|
hasJsonPath("$.type", is("version"))
|
||||||
|
)))
|
||||||
|
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id")));
|
||||||
|
} finally {
|
||||||
|
VersionBuilder.delete(idRef.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void patchReplaceSummaryTest() throws Exception {
|
public void patchReplaceSummaryTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
@@ -32,3 +32,11 @@
|
|||||||
# By default, only 'dspace.agreements.end-user' can be deleted in bulk, as doing so allows
|
# By default, only 'dspace.agreements.end-user' can be deleted in bulk, as doing so allows
|
||||||
# an administrator to force all users to re-review the End User Agreement on their next login.
|
# an administrator to force all users to re-review the End User Agreement on their next login.
|
||||||
bulkedit.allow-bulk-deletion = dspace.agreements.end-user
|
bulkedit.allow-bulk-deletion = dspace.agreements.end-user
|
||||||
|
|
||||||
|
### metadata import script ###
|
||||||
|
# Set the number after which the changes should be committed while running the script
|
||||||
|
# After too much consecutive records everything starts to slow down because too many things are being loaded into memory
|
||||||
|
# If we commit these to the database these are cleared out of our memory and we don't lose as much performance
|
||||||
|
# By default this is set to 100
|
||||||
|
bulkedit.change.commit.count = 100
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user