diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickPdfThumbnailFilter.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickPdfThumbnailFilter.java
index 467303c3ca..afe1bb3d75 100644
--- a/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickPdfThumbnailFilter.java
+++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickPdfThumbnailFilter.java
@@ -22,7 +22,9 @@ public class ImageMagickPdfThumbnailFilter extends ImageMagickThumbnailFilter {
File f2 = null;
File f3 = null;
try {
- f2 = getImageFile(f, 0, verbose);
+ // Step 1: get an image from our PDF file, with PDF-specific processing options
+ f2 = getImageFile(f, verbose);
+ // Step 2: use the image above to create the final resized and rotated thumbnail
f3 = getThumbnailFile(f2, verbose);
byte[] bytes = Files.readAllBytes(f3.toPath());
return new ByteArrayInputStream(bytes);
diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickThumbnailFilter.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickThumbnailFilter.java
index d16243e3e3..408982d157 100644
--- a/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickThumbnailFilter.java
+++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/ImageMagickThumbnailFilter.java
@@ -116,9 +116,17 @@ public abstract class ImageMagickThumbnailFilter extends MediaFilter {
return f2;
}
- public File getImageFile(File f, int page, boolean verbose)
+ /**
+ * Return an image from a bitstream with specific processing options for
+ * PDFs. This is only used by ImageMagickPdfThumbnailFilter in order to
+ * generate an intermediate image file for use with getThumbnailFile.
+ */
+ public File getImageFile(File f, boolean verbose)
throws IOException, InterruptedException, IM4JavaException {
- File f2 = new File(f.getParentFile(), f.getName() + ".jpg");
+ // Writing an intermediate file to disk is inefficient, but since we're
+ // doing it anyway, we should use a lossless format. IM's internal MIFF
+ // is lossless like PNG and TIFF, but much faster.
+ File f2 = new File(f.getParentFile(), f.getName() + ".miff");
f2.deleteOnExit();
ConvertCmd cmd = new ConvertCmd();
IMOperation op = new IMOperation();
@@ -155,7 +163,7 @@ public abstract class ImageMagickThumbnailFilter extends MediaFilter {
op.define("pdf:use-cropbox=true");
}
- String s = "[" + page + "]";
+ String s = "[0]";
op.addImage(f.getAbsolutePath() + s);
if (configurationService.getBooleanProperty(PRE + ".flatten", true)) {
op.flatten();
@@ -208,20 +216,20 @@ public abstract class ImageMagickThumbnailFilter extends MediaFilter {
if (description != null) {
if (replaceRegex.matcher(description).matches()) {
if (verbose) {
- System.out.format("%s %s matches pattern and is replacable.%n",
- description, nsrc);
+ System.out.format("%s %s matches pattern and is replaceable.%n",
+ description, n);
}
continue;
}
if (description.equals(getDescription())) {
if (verbose) {
System.out.format("%s %s is replaceable.%n",
- getDescription(), nsrc);
+ getDescription(), n);
}
continue;
}
}
- System.out.format("Custom Thumbnail exists for %s for item %s. Thumbnail will not be generated.%n",
+ System.out.format("Custom thumbnail exists for %s for item %s. Thumbnail will not be generated.%n",
nsrc, item.getHandle());
return false;
}
diff --git a/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java b/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java
index 5506b3c23f..28d39d911b 100644
--- a/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java
+++ b/dspace-api/src/main/java/org/dspace/app/util/SubmissionStepConfig.java
@@ -11,6 +11,9 @@ import java.io.Serializable;
import java.util.Map;
import org.apache.commons.lang3.BooleanUtils;
+import org.dspace.content.InProgressSubmission;
+import org.dspace.content.WorkspaceItem;
+import org.hibernate.proxy.HibernateProxyHelper;
/**
* Class representing configuration for a single step within an Item Submission
@@ -173,6 +176,38 @@ public class SubmissionStepConfig implements Serializable {
return visibilityOutside;
}
+ /**
+ * Check if given submission section object is hidden for the current submission scope
+ *
+ * @param obj the InProgressSubmission to check
+ * @return true if the submission section is hidden, false otherwise
+ */
+ public boolean isHiddenForInProgressSubmission(InProgressSubmission obj) {
+
+ String scopeToCheck = getScope(obj);
+
+ if (scope == null || scopeToCheck == null) {
+ return false;
+ }
+
+ String visibility = getVisibility();
+ String visibilityOutside = getVisibilityOutside();
+
+ if (scope.equalsIgnoreCase(scopeToCheck)) {
+ return "hidden".equalsIgnoreCase(visibility);
+ } else {
+ return visibilityOutside == null || "hidden".equalsIgnoreCase(visibilityOutside);
+ }
+
+ }
+
+ private String getScope(InProgressSubmission obj) {
+ if (HibernateProxyHelper.getClassWithoutInitializingProxy(obj).equals(WorkspaceItem.class)) {
+ return "submission";
+ }
+ return "workflow";
+ }
+
/**
* Get the number of this step in the current Submission process config.
* Step numbers start with #0 (although step #0 is ALWAYS the special
diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedDOIIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedDOIIdentifierProvider.java
index 4ca186eaab..e5a90907c7 100644
--- a/dspace-api/src/main/java/org/dspace/identifier/VersionedDOIIdentifierProvider.java
+++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedDOIIdentifierProvider.java
@@ -27,13 +27,14 @@ import org.dspace.versioning.Version;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author Marsa Haoua
* @author Pascal-Nicolas Becker (dspace at pascal dash becker dot de)
*/
-public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
+public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider implements InitializingBean {
/**
* log4j category
*/
@@ -49,6 +50,19 @@ public class VersionedDOIIdentifierProvider extends DOIIdentifierProvider {
@Autowired(required = true)
protected VersionHistoryService versionHistoryService;
+ /**
+ * After all the properties are set check that the versioning is enabled
+ *
+ * @throws Exception throws an exception if this isn't the case
+ */
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ if (!configurationService.getBooleanProperty("versioning.enabled", true)) {
+ throw new RuntimeException("the " + VersionedDOIIdentifierProvider.class.getName() +
+ " is enabled, but the versioning is disabled.");
+ }
+ }
+
@Override
public String mint(Context context, DSpaceObject dso) throws IdentifierException {
return mint(context, dso, this.filter);
diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java
index b29d47f406..4f9efd2206 100644
--- a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java
+++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProvider.java
@@ -35,6 +35,7 @@ import org.dspace.versioning.Version;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@ import org.springframework.stereotype.Component;
* @author Pascal-Nicolas Becker (dspace at pascal dash becker dot de)
*/
@Component
-public class VersionedHandleIdentifierProvider extends IdentifierProvider {
+public class VersionedHandleIdentifierProvider extends IdentifierProvider implements InitializingBean {
/**
* log4j category
*/
@@ -71,6 +72,19 @@ public class VersionedHandleIdentifierProvider extends IdentifierProvider {
@Autowired(required = true)
protected ContentServiceFactory contentServiceFactory;
+ /**
+ * After all the properties are set check that the versioning is enabled
+ *
+ * @throws Exception throws an exception if this isn't the case
+ */
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ if (!configurationService.getBooleanProperty("versioning.enabled", true)) {
+ throw new RuntimeException("the " + VersionedHandleIdentifierProvider.class.getName() +
+ " is enabled, but the versioning is disabled.");
+ }
+ }
+
@Override
public boolean supports(Class extends Identifier> identifier) {
return Handle.class.isAssignableFrom(identifier);
diff --git a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java
index 0fac326ca1..78ad6b7b79 100644
--- a/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java
+++ b/dspace-api/src/main/java/org/dspace/identifier/VersionedHandleIdentifierProviderWithCanonicalHandles.java
@@ -30,6 +30,7 @@ import org.dspace.versioning.Version;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -39,7 +40,8 @@ import org.springframework.stereotype.Component;
* @author Ben Bosman (ben at atmire dot com)
*/
@Component
-public class VersionedHandleIdentifierProviderWithCanonicalHandles extends IdentifierProvider {
+public class VersionedHandleIdentifierProviderWithCanonicalHandles extends IdentifierProvider
+ implements InitializingBean {
/**
* log4j category
*/
@@ -65,6 +67,19 @@ public class VersionedHandleIdentifierProviderWithCanonicalHandles extends Ident
@Autowired(required = true)
private ItemService itemService;
+ /**
+ * After all the properties are set check that the versioning is enabled
+ *
+ * @throws Exception throws an exception if this isn't the case
+ */
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ if (!configurationService.getBooleanProperty("versioning.enabled", true)) {
+ throw new RuntimeException("the " + VersionedHandleIdentifierProviderWithCanonicalHandles.class.getName() +
+ " is enabled, but the versioning is disabled.");
+ }
+ }
+
@Override
public boolean supports(Class extends Identifier> identifier) {
return Handle.class.isAssignableFrom(identifier);
diff --git a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java
index dbbb7bbc5e..b29af4e773 100644
--- a/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java
+++ b/dspace-api/src/main/java/org/dspace/submit/model/AccessConditionOption.java
@@ -11,6 +11,8 @@ import java.text.ParseException;
import java.util.Date;
import java.util.Objects;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.authorize.service.AuthorizeService;
@@ -21,6 +23,7 @@ import org.dspace.core.Context;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.util.DateMathParser;
+import org.dspace.util.TimeHelpers;
import org.springframework.beans.factory.annotation.Autowired;
/**
@@ -28,9 +31,8 @@ import org.springframework.beans.factory.annotation.Autowired;
* set permission on a file. An option is defined by a name such as "open
* access", "embargo", "restricted access", etc. and some optional attributes to
* better clarify the constraints and input available to the user. For instance
- * an embargo option could allow to set a start date not longer than 3 years,
- * etc
- *
+ * an embargo option could allow to set a start date not longer than 3 years.
+ *
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
*/
public class AccessConditionOption {
@@ -44,9 +46,9 @@ public class AccessConditionOption {
@Autowired
private ResourcePolicyService resourcePolicyService;
- DateMathParser dateMathParser = new DateMathParser();
+ private static final Logger LOG = LogManager.getLogger();
- /** An unique name identifying the access contion option **/
+ /** A unique name identifying the access condition option. **/
private String name;
/**
@@ -147,6 +149,9 @@ public class AccessConditionOption {
* startDate should be null. Otherwise startDate may not be null.
* @param endDate end date of the resource policy. If {@link #getHasEndDate()} returns false,
* endDate should be null. Otherwise endDate may not be null.
+ * @throws SQLException passed through.
+ * @throws AuthorizeException passed through.
+ * @throws ParseException passed through (indicates problem with a date).
*/
public void createResourcePolicy(Context context, DSpaceObject obj, String name, String description,
Date startDate, Date endDate)
@@ -160,7 +165,7 @@ public class AccessConditionOption {
/**
* Validate ResourcePolicy and after update it
- *
+ *
* @param context DSpace context
* @param resourcePolicy ResourcePolicy to update
* @throws SQLException If database error
@@ -175,17 +180,25 @@ public class AccessConditionOption {
}
/**
- * Validate the policy properties, throws exceptions if any is not valid
- *
- * @param context DSpace context
- * @param name Name of the resource policy
- * @param startDate Start date of the resource policy. If {@link #getHasStartDate()}
- * returns false, startDate should be null. Otherwise startDate may not be null.
- * @param endDate End date of the resource policy. If {@link #getHasEndDate()}
- * returns false, endDate should be null. Otherwise endDate may not be null.
+ * Validate the policy properties, throws exceptions if any is not valid.
+ *
+ * @param context DSpace context.
+ * @param name Name of the resource policy.
+ * @param startDate Start date of the resource policy. If
+ * {@link #getHasStartDate()} returns false, startDate
+ * should be null. Otherwise startDate may not be null.
+ * @param endDate End date of the resource policy. If
+ * {@link #getHasEndDate()} returns false, endDate should
+ * be null. Otherwise endDate may not be null.
+ * @throws IllegalStateException if a date is required and absent,
+ * a date is not required and present, or a date exceeds its
+ * configured maximum.
+ * @throws ParseException passed through.
*/
private void validateResourcePolicy(Context context, String name, Date startDate, Date endDate)
- throws SQLException, AuthorizeException, ParseException {
+ throws IllegalStateException, ParseException {
+ LOG.debug("Validate policy dates: name '{}', startDate {}, endDate {}",
+ name, startDate, endDate);
if (getHasStartDate() && Objects.isNull(startDate)) {
throw new IllegalStateException("The access condition " + getName() + " requires a start date.");
}
@@ -199,29 +212,33 @@ public class AccessConditionOption {
throw new IllegalStateException("The access condition " + getName() + " cannot contain an end date.");
}
+ DateMathParser dateMathParser = new DateMathParser();
+
Date latestStartDate = null;
if (Objects.nonNull(getStartDateLimit())) {
- latestStartDate = dateMathParser.parseMath(getStartDateLimit());
+ latestStartDate = TimeHelpers.toMidnightUTC(dateMathParser.parseMath(getStartDateLimit()));
}
Date latestEndDate = null;
if (Objects.nonNull(getEndDateLimit())) {
- latestEndDate = dateMathParser.parseMath(getEndDateLimit());
+ latestEndDate = TimeHelpers.toMidnightUTC(dateMathParser.parseMath(getEndDateLimit()));
}
+ LOG.debug(" latestStartDate {}, latestEndDate {}",
+ latestStartDate, latestEndDate);
// throw if startDate after latestStartDate
if (Objects.nonNull(startDate) && Objects.nonNull(latestStartDate) && startDate.after(latestStartDate)) {
throw new IllegalStateException(String.format(
- "The start date of access condition %s should be earlier than %s from now.",
- getName(), getStartDateLimit()
+ "The start date of access condition %s should be earlier than %s from now (%s).",
+ getName(), getStartDateLimit(), dateMathParser.getNow()
));
}
// throw if endDate after latestEndDate
if (Objects.nonNull(endDate) && Objects.nonNull(latestEndDate) && endDate.after(latestEndDate)) {
throw new IllegalStateException(String.format(
- "The end date of access condition %s should be earlier than %s from now.",
- getName(), getEndDateLimit()
+ "The end date of access condition %s should be earlier than %s from now (%s).",
+ getName(), getEndDateLimit(), dateMathParser.getNow()
));
}
}
diff --git a/dspace-api/src/main/java/org/dspace/util/DateMathParser.java b/dspace-api/src/main/java/org/dspace/util/DateMathParser.java
index 7c3e13a28e..9ff252e8ce 100644
--- a/dspace-api/src/main/java/org/dspace/util/DateMathParser.java
+++ b/dspace-api/src/main/java/org/dspace/util/DateMathParser.java
@@ -26,12 +26,15 @@ import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Pattern;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
- * This class (Apache license) is copied from Apache Solr and add some tweaks to resolve unneeded dependency:
- * https://raw.githubusercontent.com/apache/lucene-solr/releases/lucene-solr/7.1.0/solr/core/src/java/org/apache/solr
- * /util/DateMathParser.java
+ * This class (Apache license) is copied from Apache Solr, adding some tweaks to
+ * resolve an unneeded dependency. See
+ * the original.
*
+ *
* A Simple Utility class for parsing "math" like strings relating to Dates.
*
*
@@ -78,7 +81,7 @@ import java.util.regex.Pattern;
* "setNow
" in the interim). The default value of 'now' is
* the time at the moment the DateMathParser
instance is
* constructed, unless overridden by the {@link CommonParams#NOW NOW}
- * request param.
+ * request parameter.
*
*
*
@@ -88,7 +91,7 @@ import java.util.regex.Pattern;
* cascades to rounding of HOUR, MIN, MONTH, YEAR as well. The default
* TimeZone
used is UTC
unless overridden by the
* {@link CommonParams#TZ TZ}
- * request param.
+ * request parameter.
*
*
*
@@ -102,6 +105,8 @@ import java.util.regex.Pattern;
*/
public class DateMathParser {
+ private static final Logger LOG = LogManager.getLogger();
+
public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
/**
@@ -119,12 +124,12 @@ public class DateMathParser {
/**
* A mapping from (uppercased) String labels identifying time units,
- * to the corresponding {@link ChronoUnit} enum (e.g. "YEARS") used to
+ * to the corresponding {@link ChronoUnit} value (e.g. "YEARS") used to
* set/add/roll that unit of measurement.
*
*
* A single logical unit of time might be represented by multiple labels
- * for convenience (ie: DATE==DAYS
,
+ * for convenience (i.e. DATE==DAYS
,
* MILLI==MILLIS
)
*
*
@@ -220,6 +225,7 @@ public class DateMathParser {
*
* @param now an optional fixed date to use as "NOW"
* @param val the string to parse
+ * @return result of applying the parsed expression to "NOW".
* @throws Exception
*/
public static Date parseMath(Date now, String val) throws Exception {
@@ -308,6 +314,7 @@ public class DateMathParser {
/**
* Defines this instance's concept of "now".
*
+ * @param n new value of "now".
* @see #getNow
*/
public void setNow(Date n) {
@@ -316,12 +323,12 @@ public class DateMathParser {
/**
* Returns a clone of this instance's concept of "now" (never null).
- *
* If setNow was never called (or if null was specified) then this method
* first defines 'now' as the value dictated by the SolrRequestInfo if it
* exists -- otherwise it uses a new Date instance at the moment getNow()
* is first called.
*
+ * @return "now".
* @see #setNow
* @see SolrRequestInfo#getNOW
*/
@@ -334,9 +341,12 @@ public class DateMathParser {
}
/**
- * Parses a string of commands relative "now" are returns the resulting Date.
+ * Parses a date expression relative to "now".
*
- * @throws ParseException positions in ParseExceptions are token positions, not character positions.
+ * @param math a date expression such as "+24MONTHS".
+ * @return the result of applying the expression to the current time.
+ * @throws ParseException positions in ParseExceptions are token positions,
+ * not character positions.
*/
public Date parseMath(String math) throws ParseException {
/* check for No-Op */
@@ -344,6 +354,8 @@ public class DateMathParser {
return getNow();
}
+ LOG.debug("parsing {}", math);
+
ZoneId zoneId = zone.toZoneId();
// localDateTime is a date and time local to the timezone specified
LocalDateTime localDateTime = ZonedDateTime.ofInstant(getNow().toInstant(), zoneId).toLocalDateTime();
@@ -394,11 +406,44 @@ public class DateMathParser {
}
}
+ LOG.debug("returning {}", localDateTime);
return Date.from(ZonedDateTime.of(localDateTime, zoneId).toInstant());
}
private static Pattern splitter = Pattern.compile("\\b|(?<=\\d)(?=\\D)");
+ /**
+ * For manual testing. With one argument, test one-argument parseMath.
+ * With two (or more) arguments, test two-argument parseMath.
+ *
+ * @param argv date math expressions.
+ * @throws java.lang.Exception passed through.
+ */
+ public static void main(String[] argv)
+ throws Exception {
+ DateMathParser parser = new DateMathParser();
+ try {
+ Date parsed;
+
+ if (argv.length <= 0) {
+ System.err.println("Date math expression(s) expected.");
+ }
+
+ if (argv.length > 0) {
+ parsed = parser.parseMath(argv[0]);
+ System.out.format("Applied %s to implicit current time: %s%n",
+ argv[0], parsed.toString());
+ }
+
+ if (argv.length > 1) {
+ parsed = DateMathParser.parseMath(new Date(), argv[1]);
+ System.out.format("Applied %s to explicit current time: %s%n",
+ argv[1], parsed.toString());
+ }
+ } catch (ParseException ex) {
+ System.err.format("Oops: %s%n", ex.getMessage());
+ }
+ }
}
diff --git a/dspace-api/src/main/java/org/dspace/util/TimeHelpers.java b/dspace-api/src/main/java/org/dspace/util/TimeHelpers.java
new file mode 100644
index 0000000000..87d354a7f6
--- /dev/null
+++ b/dspace-api/src/main/java/org/dspace/util/TimeHelpers.java
@@ -0,0 +1,42 @@
+/**
+ * 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.util;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+/**
+ * Various manipulations of dates and times.
+ *
+ * @author mwood
+ */
+public class TimeHelpers {
+ private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
+
+ /**
+ * Never instantiate this class.
+ */
+ private TimeHelpers() {}
+
+ /**
+ * Set a Date's time to midnight UTC.
+ *
+ * @param from some date-time.
+ * @return midnight UTC of the supplied date-time.
+ */
+ public static Date toMidnightUTC(Date from) {
+ GregorianCalendar calendar = new GregorianCalendar(UTC);
+ calendar.setTime(from);
+ calendar.set(GregorianCalendar.HOUR_OF_DAY, 0);
+ calendar.set(GregorianCalendar.MINUTE, 0);
+ calendar.set(GregorianCalendar.SECOND, 0);
+ calendar.set(GregorianCalendar.MILLISECOND, 0);
+ return calendar.getTime();
+ }
+}
diff --git a/dspace-api/src/test/data/dspaceFolder/config/item-submission.xml b/dspace-api/src/test/data/dspaceFolder/config/item-submission.xml
index 6d8ae0c2f0..452460501a 100644
--- a/dspace-api/src/test/data/dspaceFolder/config/item-submission.xml
+++ b/dspace-api/src/test/data/dspaceFolder/config/item-submission.xml
@@ -23,6 +23,7 @@
+
@@ -54,7 +55,6 @@
org.dspace.app.rest.submit.step.CollectionStep
collection
- submission
submit.progressbar.describe.stepone
@@ -149,6 +149,34 @@
org.dspace.app.rest.submit.step.ShowIdentifiersStep
identifiers
+
+
+ submit.progressbar.describe.stepone
+ org.dspace.app.rest.submit.step.DescribeStep
+ submission-form
+ workflow
+
+
+
+ submit.progressbar.describe.stepone
+ org.dspace.app.rest.submit.step.DescribeStep
+ submission-form
+ submission
+
+
+
+
+ org.dspace.app.rest.submit.step.CollectionStep
+ collection
+
+
+
+
+ org.dspace.app.rest.submit.step.CollectionStep
+ collection
+ submission
+
+
@@ -222,6 +250,13 @@
+
+
+
+
+
+
+
diff --git a/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml b/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml
index 7438fda852..6b7349616e 100644
--- a/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml
+++ b/dspace-api/src/test/data/dspaceFolder/config/submission-forms.xml
@@ -436,6 +436,35 @@ it, please enter the types and the actual numbers or codes.
+
+
+
+
+
diff --git a/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java
index 8b7bc2978b..9d786d4761 100644
--- a/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java
+++ b/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java
@@ -189,6 +189,10 @@ public class WorkspaceItemBuilder extends AbstractBuilder
+ */
+public class TimeHelpersTest {
+ /**
+ * Test of toMidnightUTC method, of class TimeHelpers.
+ */
+ @Test
+ public void testToMidnightUTC() {
+ System.out.println("toMidnightUTC");
+ Date from = Date.from(ZonedDateTime.of(1957, 01, 27, 04, 05, 06, 007, ZoneOffset.UTC).toInstant());
+ Date expResult = Date.from(ZonedDateTime.of(1957, 01, 27, 00, 00, 00, 000, ZoneOffset.UTC).toInstant());
+ Date result = TimeHelpers.toMidnightUTC(from);
+ assertEquals(expResult, result);
+ }
+}
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java
index ce7ca34918..fa1d145011 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/AInprogressItemConverter.java
@@ -86,6 +86,10 @@ public abstract class AInprogressItemConverter {
- DateMathParser dateMathParser = new DateMathParser();
-
@Override
public SubmissionAccessOptionRest convert(AccessConditionConfiguration config, Projection projection) {
SubmissionAccessOptionRest model = new SubmissionAccessOptionRest();
model.setId(config.getName());
model.setCanChangeDiscoverable(config.getCanChangeDiscoverable());
model.setProjection(projection);
+ DateMathParser dateMathParser = new DateMathParser();
for (AccessConditionOption option : config.getOptions()) {
AccessConditionOptionRest optionRest = new AccessConditionOptionRest();
optionRest.setHasStartDate(option.getHasStartDate());
optionRest.setHasEndDate(option.getHasEndDate());
if (StringUtils.isNotBlank(option.getStartDateLimit())) {
try {
- optionRest.setMaxStartDate(dateMathParser.parseMath(option.getStartDateLimit()));
+ Date requested = dateMathParser.parseMath(option.getStartDateLimit());
+ optionRest.setMaxStartDate(TimeHelpers.toMidnightUTC(requested));
} catch (ParseException e) {
throw new IllegalStateException("Wrong start date limit configuration for the access condition "
+ "option named " + option.getName());
@@ -49,7 +52,8 @@ public class SubmissionAccessOptionConverter
}
if (StringUtils.isNotBlank(option.getEndDateLimit())) {
try {
- optionRest.setMaxEndDate(dateMathParser.parseMath(option.getEndDateLimit()));
+ Date requested = dateMathParser.parseMath(option.getEndDateLimit());
+ optionRest.setMaxEndDate(TimeHelpers.toMidnightUTC(requested));
} catch (ParseException e) {
throw new IllegalStateException("Wrong end date limit configuration for the access condition "
+ "option named " + option.getName());
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java
index ffefd1daac..24b6b96961 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/SubmissionUploadRestRepository.java
@@ -10,6 +10,7 @@ package org.dspace.app.rest.repository;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
@@ -18,11 +19,11 @@ import org.dspace.app.rest.model.AccessConditionOptionRest;
import org.dspace.app.rest.model.SubmissionUploadRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.core.Context;
-import org.dspace.eperson.service.GroupService;
import org.dspace.submit.model.AccessConditionOption;
import org.dspace.submit.model.UploadConfiguration;
import org.dspace.submit.model.UploadConfigurationService;
import org.dspace.util.DateMathParser;
+import org.dspace.util.TimeHelpers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
@@ -47,11 +48,6 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository uploadConfigs = uploadConfigurationService.getMap().values();
Projection projection = utils.obtainProjection();
List results = new ArrayList<>();
- List configNames = new ArrayList();
+ List configNames = new ArrayList<>();
for (UploadConfiguration uploadConfig : uploadConfigs) {
if (!configNames.contains(uploadConfig.getName())) {
configNames.add(uploadConfig.getName());
@@ -92,13 +88,15 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository {
@@ -52,6 +55,18 @@ public class AccessConditionAddPatchOperation extends AddPatchOperation accessConditions = parseAccessConditions(path, value, absolutePath);
+ // Clamp access condition dates to midnight UTC
+ for (AccessConditionDTO condition : accessConditions) {
+ Date date = condition.getStartDate();
+ if (null != date) {
+ condition.setStartDate(TimeHelpers.toMidnightUTC(date));
+ }
+ date = condition.getEndDate();
+ if (null != date) {
+ condition.setEndDate(TimeHelpers.toMidnightUTC(date));
+ }
+ }
+
verifyAccessConditions(context, configuration, accessConditions);
if (absolutePath.length == 1) {
@@ -65,7 +80,7 @@ public class AccessConditionAddPatchOperation extends AddPatchOperation parseAccessConditions(String path, Object value, String[] split) {
- List accessConditions = new ArrayList();
+ List accessConditions = new ArrayList<>();
if (split.length == 1) {
accessConditions = evaluateArrayObject((LateObjectEvaluator) value);
} else if (split.length == 2) {
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/AccessConditionReplacePatchOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/AccessConditionReplacePatchOperation.java
index 0216628a6b..d2529cbca3 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/AccessConditionReplacePatchOperation.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/AccessConditionReplacePatchOperation.java
@@ -6,6 +6,7 @@
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.submit.factory.impl;
+
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -29,6 +30,7 @@ import org.dspace.core.Context;
import org.dspace.submit.model.AccessConditionConfiguration;
import org.dspace.submit.model.AccessConditionConfigurationService;
import org.dspace.submit.model.AccessConditionOption;
+import org.dspace.util.TimeHelpers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -106,7 +108,7 @@ public class AccessConditionReplacePatchOperation extends ReplacePatchOperation<
return null;
}
- private AccessConditionDTO createDTO(ResourcePolicy rpToReplace, String attributeReplace, String valueToReplare)
+ private AccessConditionDTO createDTO(ResourcePolicy rpToReplace, String attributeReplace, String valueToReplace)
throws ParseException {
AccessConditionDTO accessCondition = new AccessConditionDTO();
accessCondition.setName(rpToReplace.getRpName());
@@ -114,13 +116,13 @@ public class AccessConditionReplacePatchOperation extends ReplacePatchOperation<
accessCondition.setEndDate(rpToReplace.getEndDate());
switch (attributeReplace) {
case "name":
- accessCondition.setName(valueToReplare);
+ accessCondition.setName(valueToReplace);
return accessCondition;
case "startDate":
- accessCondition.setStartDate(parseDate(valueToReplare));
+ accessCondition.setStartDate(TimeHelpers.toMidnightUTC(parseDate(valueToReplace)));
return accessCondition;
case "endDate":
- accessCondition.setEndDate(parseDate(valueToReplare));
+ accessCondition.setEndDate(TimeHelpers.toMidnightUTC(parseDate(valueToReplace)));
return accessCondition;
default:
throw new UnprocessableEntityException("The provided attribute: "
@@ -128,17 +130,17 @@ public class AccessConditionReplacePatchOperation extends ReplacePatchOperation<
}
}
- private void updatePolicy(Context context, String valueToReplare, String attributeReplace,
+ private void updatePolicy(Context context, String valueToReplace, String attributeReplace,
ResourcePolicy rpToReplace) throws SQLException, AuthorizeException {
switch (attributeReplace) {
case "name":
- rpToReplace.setRpName(valueToReplare);
+ rpToReplace.setRpName(valueToReplace);
break;
case "startDate":
- rpToReplace.setStartDate(parseDate(valueToReplare));
+ rpToReplace.setStartDate(TimeHelpers.toMidnightUTC(parseDate(valueToReplace)));
break;
case "endDate":
- rpToReplace.setEndDate(parseDate(valueToReplare));
+ rpToReplace.setEndDate(TimeHelpers.toMidnightUTC(parseDate(valueToReplace)));
break;
default:
throw new IllegalArgumentException("Attribute to replace is not valid:" + attributeReplace);
diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java
index e7d43ec4d6..babb1fac23 100644
--- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java
+++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionDefinitionsControllerIT.java
@@ -257,10 +257,10 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
Matchers.containsString("page=1"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=6"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$.page.size", is(1)))
- .andExpect(jsonPath("$.page.totalElements", is(6)))
- .andExpect(jsonPath("$.page.totalPages", is(6)))
+ .andExpect(jsonPath("$.page.totalElements", is(7)))
+ .andExpect(jsonPath("$.page.totalPages", is(7)))
.andExpect(jsonPath("$.page.number", is(0)));
getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions")
@@ -268,7 +268,7 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
- .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("accessConditionNotDiscoverable")))
+ .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("test-hidden")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
Matchers.containsString("page=0"), Matchers.containsString("size=1"))))
@@ -285,8 +285,8 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
Matchers.containsString("/api/config/submissiondefinitions?"),
Matchers.containsString("page="), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$.page.size", is(1)))
- .andExpect(jsonPath("$.page.totalElements", is(6)))
- .andExpect(jsonPath("$.page.totalPages", is(6)))
+ .andExpect(jsonPath("$.page.totalElements", is(7)))
+ .andExpect(jsonPath("$.page.totalPages", is(7)))
.andExpect(jsonPath("$.page.number", is(1)));
getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions")
@@ -294,30 +294,56 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
.param("page", "2"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
- .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("languagetestprocess")))
+ .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("accessConditionNotDiscoverable")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
- Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=0"), Matchers.containsString("size=1"))))
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=0"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
- Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=1"), Matchers.containsString("size=1"))))
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=1"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf(
- Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=1"))))
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=3"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
- Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=2"), Matchers.containsString("size=1"))))
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=2"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
- Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=6"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$.page.size", is(1)))
- .andExpect(jsonPath("$.page.totalElements", is(6)))
- .andExpect(jsonPath("$.page.totalPages", is(6)))
+ .andExpect(jsonPath("$.page.totalElements", is(7)))
+ .andExpect(jsonPath("$.page.totalPages", is(7)))
.andExpect(jsonPath("$.page.number", is(2)));
+ getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions")
+ .param("size", "1")
+ .param("page", "3"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(contentType))
+ .andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("languagetestprocess")))
+ .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=0"), Matchers.containsString("size=1"))))
+ .andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=2"), Matchers.containsString("size=1"))))
+ .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=4"), Matchers.containsString("size=1"))))
+ .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=3"), Matchers.containsString("size=1"))))
+ .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=6"), Matchers.containsString("size=1"))))
+ .andExpect(jsonPath("$.page.size", is(1)))
+ .andExpect(jsonPath("$.page.totalElements", is(7)))
+ .andExpect(jsonPath("$.page.totalPages", is(7)))
+ .andExpect(jsonPath("$.page.number", is(3)));
+
getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions")
.param("size", "1")
- .param("page", "3"))
+ .param("page", "4"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("qualdroptest")))
@@ -326,24 +352,24 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
Matchers.containsString("page=0"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=2"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=3"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=4"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=4"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=6"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$.page.size", is(1)))
- .andExpect(jsonPath("$.page.totalElements", is(6)))
- .andExpect(jsonPath("$.page.totalPages", is(6)))
- .andExpect(jsonPath("$.page.number", is(3)));
+ .andExpect(jsonPath("$.page.totalElements", is(7)))
+ .andExpect(jsonPath("$.page.totalPages", is(7)))
+ .andExpect(jsonPath("$.page.number", is(4)));
getClient(tokenAdmin).perform(get("/api/config/submissiondefinitions")
.param("size", "1")
- .param("page", "4"))
+ .param("page", "5"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.submissiondefinitions[0].id", is("extractiontestprocess")))
@@ -352,20 +378,20 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
Matchers.containsString("page=0"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=1"))))
- .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
- Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=4"), Matchers.containsString("size=1"))))
+ .andExpect(jsonPath("$._links.next.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissiondefinitions?"),
+ Matchers.containsString("page=6"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=4"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissiondefinitions?"),
- Matchers.containsString("page=5"), Matchers.containsString("size=1"))))
+ Matchers.containsString("page=6"), Matchers.containsString("size=1"))))
.andExpect(jsonPath("$.page.size", is(1)))
- .andExpect(jsonPath("$.page.totalElements", is(6)))
- .andExpect(jsonPath("$.page.totalPages", is(6)))
- .andExpect(jsonPath("$.page.number", is(4)));
+ .andExpect(jsonPath("$.page.totalElements", is(7)))
+ .andExpect(jsonPath("$.page.totalPages", is(7)))
+ .andExpect(jsonPath("$.page.number", is(5)));
}
}
diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java
index 241bdefe21..cf1e0c7c76 100644
--- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java
+++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubmissionFormsControllerIT.java
@@ -67,13 +67,13 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.andExpect(content().contentType(contentType))
//The configuration file for the test env includes 6 forms
.andExpect(jsonPath("$.page.size", is(20)))
- .andExpect(jsonPath("$.page.totalElements", equalTo(8)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
.andExpect(jsonPath("$.page.totalPages", equalTo(1)))
.andExpect(jsonPath("$.page.number", is(0)))
.andExpect(
jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL + "config/submissionforms")))
//The array of submissionforms should have a size of 8
- .andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(8))))
+ .andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(10))))
;
}
@@ -84,12 +84,12 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.page.size", is(20)))
- .andExpect(jsonPath("$.page.totalElements", equalTo(8)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
.andExpect(jsonPath("$.page.totalPages", equalTo(1)))
.andExpect(jsonPath("$.page.number", is(0)))
.andExpect(jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL
+ "config/submissionforms")))
- .andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(8))));
+ .andExpect(jsonPath("$._embedded.submissionforms", hasSize(equalTo(10))));
}
@Test
@@ -696,10 +696,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=1"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
+ Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
- .andExpect(jsonPath("$.page.totalElements", equalTo(8)))
- .andExpect(jsonPath("$.page.totalPages", equalTo(4)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
+ .andExpect(jsonPath("$.page.totalPages", equalTo(5)))
.andExpect(jsonPath("$.page.number", is(0)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -707,8 +707,8 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
- .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("languagetest")))
- .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("qualdroptest")))
+ .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("test-outside-workflow-hidden")))
+ .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("languagetest")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
@@ -723,10 +723,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=2"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
+ Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
- .andExpect(jsonPath("$.page.totalElements", equalTo(8)))
- .andExpect(jsonPath("$.page.totalPages", equalTo(4)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
+ .andExpect(jsonPath("$.page.totalPages", equalTo(5)))
.andExpect(jsonPath("$.page.number", is(1)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -734,8 +734,8 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.param("page", "2"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
- .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("traditionalpagetwo")))
- .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("sampleauthority")))
+ .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("test-outside-submission-hidden")))
+ .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("qualdroptest")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
@@ -747,10 +747,10 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=2"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
+ Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
- .andExpect(jsonPath("$.page.totalElements", equalTo(8)))
- .andExpect(jsonPath("$.page.totalPages", equalTo(4)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
+ .andExpect(jsonPath("$.page.totalPages", equalTo(5)))
.andExpect(jsonPath("$.page.number", is(2)));
getClient(tokenAdmin).perform(get("/api/config/submissionforms")
@@ -758,7 +758,8 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
.param("page", "3"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
- .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("traditionalpageone")))
+ .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("traditionalpagetwo")))
+ .andExpect(jsonPath("$._embedded.submissionforms[1].id", is("sampleauthority")))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
@@ -770,10 +771,33 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/config/submissionforms?"),
- Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
+ Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
.andExpect(jsonPath("$.page.size", is(2)))
- .andExpect(jsonPath("$.page.totalElements", equalTo(8)))
- .andExpect(jsonPath("$.page.totalPages", equalTo(4)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
+ .andExpect(jsonPath("$.page.totalPages", equalTo(5)))
.andExpect(jsonPath("$.page.number", is(3)));
+
+ getClient(tokenAdmin).perform(get("/api/config/submissionforms")
+ .param("size", "2")
+ .param("page", "4"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(contentType))
+ .andExpect(jsonPath("$._embedded.submissionforms[0].id", is("traditionalpageone")))
+ .andExpect(jsonPath("$._links.first.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissionforms?"),
+ Matchers.containsString("page=0"), Matchers.containsString("size=2"))))
+ .andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissionforms?"),
+ Matchers.containsString("page=3"), Matchers.containsString("size=2"))))
+ .andExpect(jsonPath("$._links.self.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissionforms?"),
+ Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
+ .andExpect(jsonPath("$._links.last.href", Matchers.allOf(
+ Matchers.containsString("/api/config/submissionforms?"),
+ Matchers.containsString("page=4"), Matchers.containsString("size=2"))))
+ .andExpect(jsonPath("$.page.size", is(2)))
+ .andExpect(jsonPath("$.page.totalElements", equalTo(10)))
+ .andExpect(jsonPath("$.page.totalPages", equalTo(5)))
+ .andExpect(jsonPath("$.page.number", is(4)));
}
}
diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java
index c43821d4a0..72612fc5eb 100644
--- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java
+++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkflowItemRestRepositoryIT.java
@@ -2122,4 +2122,35 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
WorkflowItemBuilder.deleteWorkflowItem(idRef.get());
}
}
+
+ @Test
+ public void testWorkflowWithHiddenSections() throws Exception {
+
+ context.turnOffAuthorisationSystem();
+
+ parentCommunity = CommunityBuilder.createCommunity(context)
+ .withName("Parent Community")
+ .build();
+
+ Collection collection = CollectionBuilder.createCollection(context, parentCommunity, "123456789/test-hidden")
+ .withName("Collection 1")
+ .withWorkflowGroup(1, eperson)
+ .build();
+
+ XmlWorkflowItem workflowItem = WorkflowItemBuilder.createWorkflowItem(context, collection)
+ .withTitle("Workflow Item")
+ .build();
+
+ context.restoreAuthSystemState();
+
+ getClient(getAuthToken(admin.getEmail(), password))
+ .perform(get("/api/workflow/workflowitems/" + workflowItem.getID()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.sections.test-outside-workflow-hidden").exists())
+ .andExpect(jsonPath("$.sections.test-outside-submission-hidden").doesNotExist())
+ .andExpect(jsonPath("$.sections.test-never-hidden").exists())
+ .andExpect(jsonPath("$.sections.test-always-hidden").doesNotExist());
+
+ }
+
}
diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java
index 6c97526425..8b2f3f093a 100644
--- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java
+++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WorkspaceItemRestRepositoryIT.java
@@ -8566,4 +8566,41 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
)));
}
+ @Test
+ public void testSubmissionWithHiddenSections() throws Exception {
+
+ context.turnOffAuthorisationSystem();
+
+ parentCommunity = CommunityBuilder.createCommunity(context)
+ .withName("Parent Community")
+ .build();
+
+ Collection collection = CollectionBuilder.createCollection(context, parentCommunity, "123456789/test-hidden")
+ .withName("Collection 1")
+ .build();
+
+ WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
+ .withTitle("Workspace Item")
+ .withIssueDate("2023-01-01")
+ .withType("book")
+ .build();
+
+ context.restoreAuthSystemState();
+ String adminToken = getAuthToken(admin.getEmail(), password);
+
+ getClient(adminToken)
+ .perform(get("/api/submission/workspaceitems/" + workspaceItem.getID()))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.sections.test-outside-workflow-hidden").doesNotExist())
+ .andExpect(jsonPath("$.sections.test-outside-submission-hidden").exists())
+ .andExpect(jsonPath("$.sections.test-never-hidden").exists())
+ .andExpect(jsonPath("$.sections.test-always-hidden").doesNotExist());
+
+ // Deposit the item
+ getClient(adminToken).perform(post("/api/workflow/workflowitems")
+ .content("/api/submission/workspaceitems/" + workspaceItem.getID())
+ .contentType(textUriContentType))
+ .andExpect(status().isCreated());
+
+ }
}
diff --git a/dspace/config/item-submission.xml b/dspace/config/item-submission.xml
index 2ab26dcf57..9fbcb776d1 100644
--- a/dspace/config/item-submission.xml
+++ b/dspace/config/item-submission.xml
@@ -79,7 +79,6 @@
org.dspace.app.rest.submit.step.CollectionStep
collection
- submission